aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sync.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-07-16 20:44:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 20:47:59 -0400
commit02c24a82187d5a628c68edfe71ae60dc135cd178 (patch)
treec8dbaba4d82e2b20ed4335910a564a1f7d90fcf6 /fs/sync.c
parent22735068d53c7115e384bc88dea95b17e76a6839 (diff)
fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
Btrfs needs to be able to control how filemap_write_and_wait_range() is called in fsync to make it less of a painful operation, so push down taking i_mutex and the calling of filemap_write_and_wait() down into the ->fsync() handlers. Some file systems can drop taking the i_mutex altogether it seems, like ext3 and ocfs2. For correctness sake I just pushed everything down in all cases to make sure that we keep the current behavior the same for everybody, and then each individual fs maintainer can make up their mind about what to do from there. Thanks, Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/sync.c')
-rw-r--r--fs/sync.c25
1 files changed, 3 insertions, 22 deletions
diff --git a/fs/sync.c b/fs/sync.c
index c38ec163da6c..c98a7477edfd 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -165,28 +165,9 @@ SYSCALL_DEFINE1(syncfs, int, fd)
165 */ 165 */
166int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) 166int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
167{ 167{
168 struct address_space *mapping = file->f_mapping; 168 if (!file->f_op || !file->f_op->fsync)
169 int err, ret; 169 return -EINVAL;
170 170 return file->f_op->fsync(file, start, end, datasync);
171 if (!file->f_op || !file->f_op->fsync) {
172 ret = -EINVAL;
173 goto out;
174 }
175
176 ret = filemap_write_and_wait_range(mapping, start, end);
177
178 /*
179 * We need to protect against concurrent writers, which could cause
180 * livelocks in fsync_buffers_list().
181 */
182 mutex_lock(&mapping->host->i_mutex);
183 err = file->f_op->fsync(file, datasync);
184 if (!ret)
185 ret = err;
186 mutex_unlock(&mapping->host->i_mutex);
187
188out:
189 return ret;
190} 171}
191EXPORT_SYMBOL(vfs_fsync_range); 172EXPORT_SYMBOL(vfs_fsync_range);
192 173