aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/block_dev.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8bed0557d88c..6dcee88c2e5d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -246,7 +246,8 @@ struct super_block *freeze_bdev(struct block_device *bdev)
246 if (!sb) 246 if (!sb)
247 goto out; 247 goto out;
248 if (sb->s_flags & MS_RDONLY) { 248 if (sb->s_flags & MS_RDONLY) {
249 deactivate_locked_super(sb); 249 sb->s_frozen = SB_FREEZE_TRANS;
250 up_write(&sb->s_umount);
250 mutex_unlock(&bdev->bd_fsfreeze_mutex); 251 mutex_unlock(&bdev->bd_fsfreeze_mutex);
251 return sb; 252 return sb;
252 } 253 }
@@ -307,7 +308,7 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
307 BUG_ON(sb->s_bdev != bdev); 308 BUG_ON(sb->s_bdev != bdev);
308 down_write(&sb->s_umount); 309 down_write(&sb->s_umount);
309 if (sb->s_flags & MS_RDONLY) 310 if (sb->s_flags & MS_RDONLY)
310 goto out_deactivate; 311 goto out_unfrozen;
311 312
312 if (sb->s_op->unfreeze_fs) { 313 if (sb->s_op->unfreeze_fs) {
313 error = sb->s_op->unfreeze_fs(sb); 314 error = sb->s_op->unfreeze_fs(sb);
@@ -321,11 +322,11 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb)
321 } 322 }
322 } 323 }
323 324
325out_unfrozen:
324 sb->s_frozen = SB_UNFROZEN; 326 sb->s_frozen = SB_UNFROZEN;
325 smp_wmb(); 327 smp_wmb();
326 wake_up(&sb->s_wait_unfrozen); 328 wake_up(&sb->s_wait_unfrozen);
327 329
328out_deactivate:
329 if (sb) 330 if (sb)
330 deactivate_locked_super(sb); 331 deactivate_locked_super(sb);
331out_unlock: 332out_unlock:
@@ -403,10 +404,28 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
403 * NULL first argument is nfsd_sync_dir() and that's not a directory. 404 * NULL first argument is nfsd_sync_dir() and that's not a directory.
404 */ 405 */
405 406
406static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) 407int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
407{ 408{
408 return sync_blockdev(I_BDEV(filp->f_mapping->host)); 409 struct inode *bd_inode = filp->f_mapping->host;
410 struct block_device *bdev = I_BDEV(bd_inode);
411 int error;
412
413 /*
414 * There is no need to serialise calls to blkdev_issue_flush with
415 * i_mutex and doing so causes performance issues with concurrent
416 * O_SYNC writers to a block device.
417 */
418 mutex_unlock(&bd_inode->i_mutex);
419
420 error = blkdev_issue_flush(bdev, NULL);
421 if (error == -EOPNOTSUPP)
422 error = 0;
423
424 mutex_lock(&bd_inode->i_mutex);
425
426 return error;
409} 427}
428EXPORT_SYMBOL(blkdev_fsync);
410 429
411/* 430/*
412 * pseudo-fs 431 * pseudo-fs
@@ -1470,7 +1489,7 @@ const struct file_operations def_blk_fops = {
1470 .aio_read = generic_file_aio_read, 1489 .aio_read = generic_file_aio_read,
1471 .aio_write = blkdev_aio_write, 1490 .aio_write = blkdev_aio_write,
1472 .mmap = generic_file_mmap, 1491 .mmap = generic_file_mmap,
1473 .fsync = block_fsync, 1492 .fsync = blkdev_fsync,
1474 .unlocked_ioctl = block_ioctl, 1493 .unlocked_ioctl = block_ioctl,
1475#ifdef CONFIG_COMPAT 1494#ifdef CONFIG_COMPAT
1476 .compat_ioctl = compat_blkdev_ioctl, 1495 .compat_ioctl = compat_blkdev_ioctl,