diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index dd769304382e..55dcb7884f4d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -406,17 +406,23 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
406 | 406 | ||
407 | int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) | 407 | int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) |
408 | { | 408 | { |
409 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 409 | struct inode *bd_inode = filp->f_mapping->host; |
410 | struct block_device *bdev = I_BDEV(bd_inode); | ||
410 | int error; | 411 | int error; |
411 | 412 | ||
412 | error = sync_blockdev(bdev); | 413 | /* |
413 | if (error) | 414 | * There is no need to serialise calls to blkdev_issue_flush with |
414 | return error; | 415 | * i_mutex and doing so causes performance issues with concurrent |
415 | 416 | * O_SYNC writers to a block device. | |
416 | error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL, | 417 | */ |
417 | (BLKDEV_IFL_WAIT)); | 418 | mutex_unlock(&bd_inode->i_mutex); |
419 | |||
420 | error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL, BLKDEV_IFL_WAIT); | ||
418 | if (error == -EOPNOTSUPP) | 421 | if (error == -EOPNOTSUPP) |
419 | error = 0; | 422 | error = 0; |
423 | |||
424 | mutex_lock(&bd_inode->i_mutex); | ||
425 | |||
420 | return error; | 426 | return error; |
421 | } | 427 | } |
422 | EXPORT_SYMBOL(blkdev_fsync); | 428 | EXPORT_SYMBOL(blkdev_fsync); |