summaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-04-29 09:36:24 +0200
committerJens Axboe <jens.axboe@oracle.com>2010-04-29 09:36:24 +0200
commit7407cf355fdf5500430be966dbbde84a27293bad (patch)
tree922861288ff38558ed721a79653f52b17b13bb95 /fs/block_dev.c
parentnilfs: fix breakage caused by barrier flag changes (diff)
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jba... (diff)
downloadlinux-7407cf355fdf5500430be966dbbde84a27293bad.tar.xz
linux-7407cf355fdf5500430be966dbbde84a27293bad.zip
Merge branch 'master' into for-2.6.35
Conflicts: fs/block_dev.c Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c20
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)
int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
- struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+ struct inode *bd_inode = filp->f_mapping->host;
+ struct block_device *bdev = I_BDEV(bd_inode);
int error;
- error = sync_blockdev(bdev);
- if (error)
- return error;
-
- error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL,
- (BLKDEV_IFL_WAIT));
+ /*
+ * There is no need to serialise calls to blkdev_issue_flush with
+ * i_mutex and doing so causes performance issues with concurrent
+ * O_SYNC writers to a block device.
+ */
+ mutex_unlock(&bd_inode->i_mutex);
+
+ error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL, BLKDEV_IFL_WAIT);
if (error == -EOPNOTSUPP)
error = 0;
+
+ mutex_lock(&bd_inode->i_mutex);
+
return error;
}
EXPORT_SYMBOL(blkdev_fsync);