fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
[deliverable/linux.git] / fs / libfs.c
index bd50b11f92da754cd3b2f3c7532ea3fb2c02cf5d..8f2271a5df53c119eb05b86fa9834652ede9c57b 100644 (file)
@@ -905,21 +905,29 @@ EXPORT_SYMBOL_GPL(generic_fh_to_parent);
  * filesystems which track all non-inode metadata in the buffers list
  * hanging off the address_space structure.
  */
-int generic_file_fsync(struct file *file, int datasync)
+int generic_file_fsync(struct file *file, loff_t start, loff_t end,
+                      int datasync)
 {
        struct inode *inode = file->f_mapping->host;
        int err;
        int ret;
 
+       err = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       if (err)
+               return err;
+
+       mutex_lock(&inode->i_mutex);
        ret = sync_mapping_buffers(inode->i_mapping);
        if (!(inode->i_state & I_DIRTY))
-               return ret;
+               goto out;
        if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
-               return ret;
+               goto out;
 
        err = sync_inode_metadata(inode, 1);
        if (ret == 0)
                ret = err;
+out:
+       mutex_unlock(&inode->i_mutex);
        return ret;
 }
 EXPORT_SYMBOL(generic_file_fsync);
@@ -956,7 +964,7 @@ EXPORT_SYMBOL(generic_check_addressable);
 /*
  * No-op implementation of ->fsync for in-memory filesystems.
  */
-int noop_fsync(struct file *file, int datasync)
+int noop_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
        return 0;
 }
This page took 0.028002 seconds and 5 git commands to generate.