aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/filesystems/Locking6
-rw-r--r--Documentation/filesystems/porting7
-rw-r--r--Documentation/filesystems/vfs.txt2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c11
-rw-r--r--drivers/char/ps3flash.c9
-rw-r--r--drivers/mtd/ubi/cdev.c10
-rw-r--r--drivers/staging/pohmelfs/inode.c11
-rw-r--r--drivers/usb/gadget/printer.c5
-rw-r--r--drivers/video/fb_defio.c11
-rw-r--r--fs/9p/v9fs_vfs.h3
-rw-r--r--fs/9p/vfs_file.c22
-rw-r--r--fs/affs/affs.h2
-rw-r--r--fs/affs/file.c8
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/afs/write.c18
-rw-r--r--fs/bad_inode.c3
-rw-r--r--fs/block_dev.c6
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/file.c21
-rw-r--r--fs/ceph/caps.c6
-rw-r--r--fs/ceph/dir.c10
-rw-r--r--fs/ceph/super.h3
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/file.c18
-rw-r--r--fs/coda/coda_int.h2
-rw-r--r--fs/coda/file.c8
-rw-r--r--fs/ecryptfs/file.c7
-rw-r--r--fs/exofs/file.c10
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/file.c4
-rw-r--r--fs/ext3/fsync.c18
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/fsync.c38
-rw-r--r--fs/fat/fat.h3
-rw-r--r--fs/fat/file.c4
-rw-r--r--fs/fuse/dir.c5
-rw-r--r--fs/fuse/file.c24
-rw-r--r--fs/fuse/fuse_i.h3
-rw-r--r--fs/gfs2/file.c17
-rw-r--r--fs/hfs/inode.c9
-rw-r--r--fs/hfsplus/hfsplus_fs.h3
-rw-r--r--fs/hfsplus/inode.c10
-rw-r--r--fs/hostfs/hostfs_kern.c15
-rw-r--r--fs/hpfs/file.c7
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/hppfs/hppfs.c5
-rw-r--r--fs/jffs2/file.c9
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jfs/file.c9
-rw-r--r--fs/jfs/jfs_inode.h2
-rw-r--r--fs/libfs.c16
-rw-r--r--fs/logfs/file.c11
-rw-r--r--fs/logfs/logfs.h2
-rw-r--r--fs/ncpfs/file.c4
-rw-r--r--fs/nfs/dir.c8
-rw-r--r--fs/nfs/file.c11
-rw-r--r--fs/nilfs2/file.c12
-rw-r--r--fs/nilfs2/nilfs.h2
-rw-r--r--fs/ntfs/dir.c10
-rw-r--r--fs/ntfs/file.c10
-rw-r--r--fs/ocfs2/file.c14
-rw-r--r--fs/reiserfs/dir.c13
-rw-r--r--fs/reiserfs/file.c9
-rw-r--r--fs/sync.c25
-rw-r--r--fs/ubifs/file.c21
-rw-r--r--fs/ubifs/ubifs.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c17
-rw-r--r--include/linux/ext3_fs.h2
-rw-r--r--include/linux/fb.h3
-rw-r--r--include/linux/fs.h9
-rw-r--r--ipc/shm.c4
71 files changed, 462 insertions, 164 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 9b6ed7c9f34f..ca7e25292542 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -412,7 +412,7 @@ prototypes:
412 int (*open) (struct inode *, struct file *); 412 int (*open) (struct inode *, struct file *);
413 int (*flush) (struct file *); 413 int (*flush) (struct file *);
414 int (*release) (struct inode *, struct file *); 414 int (*release) (struct inode *, struct file *);
415 int (*fsync) (struct file *, int datasync); 415 int (*fsync) (struct file *, loff_t start, loff_t end, int datasync);
416 int (*aio_fsync) (struct kiocb *, int datasync); 416 int (*aio_fsync) (struct kiocb *, int datasync);
417 int (*fasync) (int, struct file *, int); 417 int (*fasync) (int, struct file *, int);
418 int (*lock) (struct file *, int, struct file_lock *); 418 int (*lock) (struct file *, int, struct file_lock *);
@@ -438,9 +438,7 @@ prototypes:
438 438
439locking rules: 439locking rules:
440 All may block except for ->setlease. 440 All may block except for ->setlease.
441 No VFS locks held on entry except for ->fsync and ->setlease. 441 No VFS locks held on entry except for ->setlease.
442
443->fsync() has i_mutex on inode.
444 442
445->setlease has the file_list_lock held and must not sleep. 443->setlease has the file_list_lock held and must not sleep.
446 444
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 6b96773e27cb..7f8861d341ea 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -421,3 +421,10 @@ data and there is a virtual hole at the end of the file. So if the provided
421offset is less than i_size and SEEK_DATA is specified, return the same offset. 421offset is less than i_size and SEEK_DATA is specified, return the same offset.
422If the above is true for the offset and you are given SEEK_HOLE, return the end 422If the above is true for the offset and you are given SEEK_HOLE, return the end
423of the file. If the offset is i_size or greater return -ENXIO in either case. 423of the file. If the offset is i_size or greater return -ENXIO in either case.
424
425[mandatory]
426 If you have your own ->fsync() you must make sure to call
427filemap_write_and_wait_range() so that all dirty pages are synced out properly.
428You must also keep in mind that ->fsync() is not called with i_mutex held
429anymore, so if you require i_mutex locking you must make sure to take it and
430release it yourself.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 6bf85b78cfea..eff6617c9a0f 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -777,7 +777,7 @@ struct file_operations {
777 int (*open) (struct inode *, struct file *); 777 int (*open) (struct inode *, struct file *);
778 int (*flush) (struct file *); 778 int (*flush) (struct file *);
779 int (*release) (struct inode *, struct file *); 779 int (*release) (struct inode *, struct file *);
780 int (*fsync) (struct file *, int datasync); 780 int (*fsync) (struct file *, loff_t, loff_t, int datasync);
781 int (*aio_fsync) (struct kiocb *, int datasync); 781 int (*aio_fsync) (struct kiocb *, int datasync);
782 int (*fasync) (int, struct file *, int); 782 int (*fasync) (int, struct file *, int);
783 int (*lock) (struct file *, int, struct file_lock *); 783 int (*lock) (struct file *, int, struct file_lock *);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 3c7c3f82d842..fb59c46e9e9e 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1850,9 +1850,16 @@ out:
1850 return ret; 1850 return ret;
1851} 1851}
1852 1852
1853static int spufs_mfc_fsync(struct file *file, int datasync) 1853static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1854{ 1854{
1855 return spufs_mfc_flush(file, NULL); 1855 struct inode *inode = file->f_path.dentry->d_inode;
1856 int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
1857 if (!err) {
1858 mutex_lock(&inode->i_mutex);
1859 err = spufs_mfc_flush(file, NULL);
1860 mutex_unlock(&inode->i_mutex);
1861 }
1862 return err;
1856} 1863}
1857 1864
1858static int spufs_mfc_fasync(int fd, struct file *file, int on) 1865static int spufs_mfc_fasync(int fd, struct file *file, int on)
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 5a06787e5be3..d0c57c2e2909 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -309,9 +309,14 @@ static int ps3flash_flush(struct file *file, fl_owner_t id)
309 return ps3flash_writeback(ps3flash_dev); 309 return ps3flash_writeback(ps3flash_dev);
310} 310}
311 311
312static int ps3flash_fsync(struct file *file, int datasync) 312static int ps3flash_fsync(struct file *file, loff_t start, loff_t end, int datasync)
313{ 313{
314 return ps3flash_writeback(ps3flash_dev); 314 struct inode *inode = file->f_path.dentry->d_inode;
315 int err;
316 mutex_lock(&inode->i_mutex);
317 err = ps3flash_writeback(ps3flash_dev);
318 mutex_unlock(&inode->i_mutex);
319 return err;
315} 320}
316 321
317static irqreturn_t ps3flash_interrupt(int irq, void *data) 322static irqreturn_t ps3flash_interrupt(int irq, void *data)
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 191f3bb3c41a..3320a50ba4f0 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -189,12 +189,16 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
189 return new_offset; 189 return new_offset;
190} 190}
191 191
192static int vol_cdev_fsync(struct file *file, int datasync) 192static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync)
193{ 193{
194 struct ubi_volume_desc *desc = file->private_data; 194 struct ubi_volume_desc *desc = file->private_data;
195 struct ubi_device *ubi = desc->vol->ubi; 195 struct ubi_device *ubi = desc->vol->ubi;
196 196 struct inode *inode = file->f_path.dentry->d_inode;
197 return ubi_sync(ubi->ubi_num); 197 int err;
198 mutex_lock(&inode->i_mutex);
199 err = ubi_sync(ubi->ubi_num);
200 mutex_unlock(&inode->i_mutex);
201 return err;
198} 202}
199 203
200 204
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index c0f0ac7c1cdb..f3c6060c96b8 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -887,11 +887,16 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
887/* 887/*
888 * We want fsync() to work on POHMELFS. 888 * We want fsync() to work on POHMELFS.
889 */ 889 */
890static int pohmelfs_fsync(struct file *file, int datasync) 890static int pohmelfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
891{ 891{
892 struct inode *inode = file->f_mapping->host; 892 struct inode *inode = file->f_mapping->host;
893 893 int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
894 return sync_inode_metadata(inode, 1); 894 if (!err) {
895 mutex_lock(&inode->i_mutex);
896 err = sync_inode_metadata(inode, 1);
897 mutex_unlock(&inode->i_mutex);
898 }
899 return err;
895} 900}
896 901
897ssize_t pohmelfs_write(struct file *file, const char __user *buf, 902ssize_t pohmelfs_write(struct file *file, const char __user *buf,
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 271ef94668e7..978e6a101bf2 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -795,12 +795,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
795} 795}
796 796
797static int 797static int
798printer_fsync(struct file *fd, int datasync) 798printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
799{ 799{
800 struct printer_dev *dev = fd->private_data; 800 struct printer_dev *dev = fd->private_data;
801 struct inode *inode = fd->f_path.dentry->d_inode;
801 unsigned long flags; 802 unsigned long flags;
802 int tx_list_empty; 803 int tx_list_empty;
803 804
805 mutex_lock(&inode->i_mutex);
804 spin_lock_irqsave(&dev->lock, flags); 806 spin_lock_irqsave(&dev->lock, flags);
805 tx_list_empty = (likely(list_empty(&dev->tx_reqs))); 807 tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
806 spin_unlock_irqrestore(&dev->lock, flags); 808 spin_unlock_irqrestore(&dev->lock, flags);
@@ -810,6 +812,7 @@ printer_fsync(struct file *fd, int datasync)
810 wait_event_interruptible(dev->tx_flush_wait, 812 wait_event_interruptible(dev->tx_flush_wait,
811 (likely(list_empty(&dev->tx_reqs_active)))); 813 (likely(list_empty(&dev->tx_reqs_active))));
812 } 814 }
815 mutex_unlock(&inode->i_mutex);
813 816
814 return 0; 817 return 0;
815} 818}
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 804000183c5e..32814e8800e0 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -66,19 +66,26 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
66 return 0; 66 return 0;
67} 67}
68 68
69int fb_deferred_io_fsync(struct file *file, int datasync) 69int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasync)
70{ 70{
71 struct fb_info *info = file->private_data; 71 struct fb_info *info = file->private_data;
72 struct inode *inode = file->f_path.dentry->d_inode;
73 int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
74 if (err)
75 return err;
72 76
73 /* Skip if deferred io is compiled-in but disabled on this fbdev */ 77 /* Skip if deferred io is compiled-in but disabled on this fbdev */
74 if (!info->fbdefio) 78 if (!info->fbdefio)
75 return 0; 79 return 0;
76 80
81 mutex_lock(&inode->i_mutex);
77 /* Kill off the delayed work */ 82 /* Kill off the delayed work */
78 cancel_delayed_work_sync(&info->deferred_work); 83 cancel_delayed_work_sync(&info->deferred_work);
79 84
80 /* Run it immediately */ 85 /* Run it immediately */
81 return schedule_delayed_work(&info->deferred_work, 0); 86 err = schedule_delayed_work(&info->deferred_work, 0);
87 mutex_unlock(&inode->i_mutex);
88 return err;
82} 89}
83EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); 90EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
84 91
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 4014160903a9..46ce357ca1ab 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -70,7 +70,8 @@ ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
70ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64); 70ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
71void v9fs_blank_wstat(struct p9_wstat *wstat); 71void v9fs_blank_wstat(struct p9_wstat *wstat);
72int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *); 72int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
73int v9fs_file_fsync_dotl(struct file *filp, int datasync); 73int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
74 int datasync);
74ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *, 75ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *,
75 const char __user *, size_t, loff_t *, int); 76 const char __user *, size_t, loff_t *, int);
76int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode); 77int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index ffed55817f0c..3c173fcc2c5a 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -519,32 +519,50 @@ out:
519} 519}
520 520
521 521
522static int v9fs_file_fsync(struct file *filp, int datasync) 522static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
523 int datasync)
523{ 524{
524 struct p9_fid *fid; 525 struct p9_fid *fid;
526 struct inode *inode = filp->f_mapping->host;
525 struct p9_wstat wstat; 527 struct p9_wstat wstat;
526 int retval; 528 int retval;
527 529
530 retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
531 if (retval)
532 return retval;
533
534 mutex_lock(&inode->i_mutex);
528 P9_DPRINTK(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 535 P9_DPRINTK(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
529 536
530 fid = filp->private_data; 537 fid = filp->private_data;
531 v9fs_blank_wstat(&wstat); 538 v9fs_blank_wstat(&wstat);
532 539
533 retval = p9_client_wstat(fid, &wstat); 540 retval = p9_client_wstat(fid, &wstat);
541 mutex_unlock(&inode->i_mutex);
542
534 return retval; 543 return retval;
535} 544}
536 545
537int v9fs_file_fsync_dotl(struct file *filp, int datasync) 546int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
547 int datasync)
538{ 548{
539 struct p9_fid *fid; 549 struct p9_fid *fid;
550 struct inode *inode = filp->f_mapping->host;
540 int retval; 551 int retval;
541 552
553 retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
554 if (retval)
555 return retval;
556
557 mutex_lock(&inode->i_mutex);
542 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_file_fsync_dotl: filp %p datasync %x\n", 558 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_file_fsync_dotl: filp %p datasync %x\n",
543 filp, datasync); 559 filp, datasync);
544 560
545 fid = filp->private_data; 561 fid = filp->private_data;
546 562
547 retval = p9_client_fsync(fid, datasync); 563 retval = p9_client_fsync(fid, datasync);
564 mutex_unlock(&inode->i_mutex);
565
548 return retval; 566 return retval;
549} 567}
550 568
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index 0e95f73a7023..c2b9c79eb64e 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -182,7 +182,7 @@ extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dent
182 182
183void affs_free_prealloc(struct inode *inode); 183void affs_free_prealloc(struct inode *inode);
184extern void affs_truncate(struct inode *); 184extern void affs_truncate(struct inode *);
185int affs_file_fsync(struct file *, int); 185int affs_file_fsync(struct file *, loff_t, loff_t, int);
186 186
187/* dir.c */ 187/* dir.c */
188 188
diff --git a/fs/affs/file.c b/fs/affs/file.c
index acf321b70fcd..2f4c935cb327 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -923,14 +923,20 @@ affs_truncate(struct inode *inode)
923 affs_free_prealloc(inode); 923 affs_free_prealloc(inode);
924} 924}
925 925
926int affs_file_fsync(struct file *filp, int datasync) 926int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
927{ 927{
928 struct inode *inode = filp->f_mapping->host; 928 struct inode *inode = filp->f_mapping->host;
929 int ret, err; 929 int ret, err;
930 930
931 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
932 if (err)
933 return err;
934
935 mutex_lock(&inode->i_mutex);
931 ret = write_inode_now(inode, 0); 936 ret = write_inode_now(inode, 0);
932 err = sync_blockdev(inode->i_sb->s_bdev); 937 err = sync_blockdev(inode->i_sb->s_bdev);
933 if (!ret) 938 if (!ret)
934 ret = err; 939 ret = err;
940 mutex_unlock(&inode->i_mutex);
935 return ret; 941 return ret;
936} 942}
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index f396d337b817..d2b0888126d4 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -750,7 +750,7 @@ extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
750extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, 750extern ssize_t afs_file_write(struct kiocb *, const struct iovec *,
751 unsigned long, loff_t); 751 unsigned long, loff_t);
752extern int afs_writeback_all(struct afs_vnode *); 752extern int afs_writeback_all(struct afs_vnode *);
753extern int afs_fsync(struct file *, int); 753extern int afs_fsync(struct file *, loff_t, loff_t, int);
754 754
755 755
756/*****************************************************************************/ 756/*****************************************************************************/
diff --git a/fs/afs/write.c b/fs/afs/write.c
index b806285ff853..9aa52d93c73c 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -681,9 +681,10 @@ int afs_writeback_all(struct afs_vnode *vnode)
681 * - the return status from this call provides a reliable indication of 681 * - the return status from this call provides a reliable indication of
682 * whether any write errors occurred for this process. 682 * whether any write errors occurred for this process.
683 */ 683 */
684int afs_fsync(struct file *file, int datasync) 684int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
685{ 685{
686 struct dentry *dentry = file->f_path.dentry; 686 struct dentry *dentry = file->f_path.dentry;
687 struct inode *inode = file->f_mapping->host;
687 struct afs_writeback *wb, *xwb; 688 struct afs_writeback *wb, *xwb;
688 struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); 689 struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
689 int ret; 690 int ret;
@@ -692,12 +693,19 @@ int afs_fsync(struct file *file, int datasync)
692 vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, 693 vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name,
693 datasync); 694 datasync);
694 695
696 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
697 if (ret)
698 return ret;
699 mutex_lock(&inode->i_mutex);
700
695 /* use a writeback record as a marker in the queue - when this reaches 701 /* use a writeback record as a marker in the queue - when this reaches
696 * the front of the queue, all the outstanding writes are either 702 * the front of the queue, all the outstanding writes are either
697 * completed or rejected */ 703 * completed or rejected */
698 wb = kzalloc(sizeof(*wb), GFP_KERNEL); 704 wb = kzalloc(sizeof(*wb), GFP_KERNEL);
699 if (!wb) 705 if (!wb) {
700 return -ENOMEM; 706 ret = -ENOMEM;
707 goto out;
708 }
701 wb->vnode = vnode; 709 wb->vnode = vnode;
702 wb->first = 0; 710 wb->first = 0;
703 wb->last = -1; 711 wb->last = -1;
@@ -720,7 +728,7 @@ int afs_fsync(struct file *file, int datasync)
720 if (ret < 0) { 728 if (ret < 0) {
721 afs_put_writeback(wb); 729 afs_put_writeback(wb);
722 _leave(" = %d [wb]", ret); 730 _leave(" = %d [wb]", ret);
723 return ret; 731 goto out;
724 } 732 }
725 733
726 /* wait for the preceding writes to actually complete */ 734 /* wait for the preceding writes to actually complete */
@@ -729,6 +737,8 @@ int afs_fsync(struct file *file, int datasync)
729 vnode->writebacks.next == &wb->link); 737 vnode->writebacks.next == &wb->link);
730 afs_put_writeback(wb); 738 afs_put_writeback(wb);
731 _leave(" = %d", ret); 739 _leave(" = %d", ret);
740out:
741 mutex_unlock(&inode->i_mutex);
732 return ret; 742 return ret;
733} 743}
734 744
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index f024d8aaddef..9205cf25f1c6 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -87,7 +87,8 @@ static int bad_file_release(struct inode *inode, struct file *filp)
87 return -EIO; 87 return -EIO;
88} 88}
89 89
90static int bad_file_fsync(struct file *file, int datasync) 90static int bad_file_fsync(struct file *file, loff_t start, loff_t end,
91 int datasync)
91{ 92{
92 return -EIO; 93 return -EIO;
93} 94}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 966617a422d9..9fb0b15331d3 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -378,7 +378,7 @@ out:
378 return retval; 378 return retval;
379} 379}
380 380
381int blkdev_fsync(struct file *filp, int datasync) 381int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
382{ 382{
383 struct inode *bd_inode = filp->f_mapping->host; 383 struct inode *bd_inode = filp->f_mapping->host;
384 struct block_device *bdev = I_BDEV(bd_inode); 384 struct block_device *bdev = I_BDEV(bd_inode);
@@ -389,14 +389,10 @@ int blkdev_fsync(struct file *filp, int datasync)
389 * i_mutex and doing so causes performance issues with concurrent 389 * i_mutex and doing so causes performance issues with concurrent
390 * O_SYNC writers to a block device. 390 * O_SYNC writers to a block device.
391 */ 391 */
392 mutex_unlock(&bd_inode->i_mutex);
393
394 error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL); 392 error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL);
395 if (error == -EOPNOTSUPP) 393 if (error == -EOPNOTSUPP)
396 error = 0; 394 error = 0;
397 395
398 mutex_lock(&bd_inode->i_mutex);
399
400 return error; 396 return error;
401} 397}
402EXPORT_SYMBOL(blkdev_fsync); 398EXPORT_SYMBOL(blkdev_fsync);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f1ff62bff1b3..82be74efbb26 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2605,7 +2605,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
2605int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, 2605int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
2606 struct inode *inode); 2606 struct inode *inode);
2607int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info); 2607int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info);
2608int btrfs_sync_file(struct file *file, int datasync); 2608int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
2609int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, 2609int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
2610 int skip_pinned); 2610 int skip_pinned);
2611extern const struct file_operations btrfs_file_operations; 2611extern const struct file_operations btrfs_file_operations;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index bd4d061c6e4d..59cbdb120ad0 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1452,7 +1452,7 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
1452 * important optimization for directories because holding the mutex prevents 1452 * important optimization for directories because holding the mutex prevents
1453 * new operations on the dir while we write to disk. 1453 * new operations on the dir while we write to disk.
1454 */ 1454 */
1455int btrfs_sync_file(struct file *file, int datasync) 1455int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1456{ 1456{
1457 struct dentry *dentry = file->f_path.dentry; 1457 struct dentry *dentry = file->f_path.dentry;
1458 struct inode *inode = dentry->d_inode; 1458 struct inode *inode = dentry->d_inode;
@@ -1462,9 +1462,13 @@ int btrfs_sync_file(struct file *file, int datasync)
1462 1462
1463 trace_btrfs_sync_file(file, datasync); 1463 trace_btrfs_sync_file(file, datasync);
1464 1464
1465 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
1466 if (ret)
1467 return ret;
1468 mutex_lock(&inode->i_mutex);
1469
1465 /* we wait first, since the writeback may change the inode */ 1470 /* we wait first, since the writeback may change the inode */
1466 root->log_batch++; 1471 root->log_batch++;
1467 /* the VFS called filemap_fdatawrite for us */
1468 btrfs_wait_ordered_range(inode, 0, (u64)-1); 1472 btrfs_wait_ordered_range(inode, 0, (u64)-1);
1469 root->log_batch++; 1473 root->log_batch++;
1470 1474
@@ -1472,8 +1476,10 @@ int btrfs_sync_file(struct file *file, int datasync)
1472 * check the transaction that last modified this inode 1476 * check the transaction that last modified this inode
1473 * and see if its already been committed 1477 * and see if its already been committed
1474 */ 1478 */
1475 if (!BTRFS_I(inode)->last_trans) 1479 if (!BTRFS_I(inode)->last_trans) {
1480 mutex_unlock(&inode->i_mutex);
1476 goto out; 1481 goto out;
1482 }
1477 1483
1478 /* 1484 /*
1479 * if the last transaction that changed this file was before 1485 * if the last transaction that changed this file was before
@@ -1484,6 +1490,7 @@ int btrfs_sync_file(struct file *file, int datasync)
1484 if (BTRFS_I(inode)->last_trans <= 1490 if (BTRFS_I(inode)->last_trans <=
1485 root->fs_info->last_trans_committed) { 1491 root->fs_info->last_trans_committed) {
1486 BTRFS_I(inode)->last_trans = 0; 1492 BTRFS_I(inode)->last_trans = 0;
1493 mutex_unlock(&inode->i_mutex);
1487 goto out; 1494 goto out;
1488 } 1495 }
1489 1496
@@ -1496,12 +1503,15 @@ int btrfs_sync_file(struct file *file, int datasync)
1496 trans = btrfs_start_transaction(root, 0); 1503 trans = btrfs_start_transaction(root, 0);
1497 if (IS_ERR(trans)) { 1504 if (IS_ERR(trans)) {
1498 ret = PTR_ERR(trans); 1505 ret = PTR_ERR(trans);
1506 mutex_unlock(&inode->i_mutex);
1499 goto out; 1507 goto out;
1500 } 1508 }
1501 1509
1502 ret = btrfs_log_dentry_safe(trans, root, dentry); 1510 ret = btrfs_log_dentry_safe(trans, root, dentry);
1503 if (ret < 0) 1511 if (ret < 0) {
1512 mutex_unlock(&inode->i_mutex);
1504 goto out; 1513 goto out;
1514 }
1505 1515
1506 /* we've logged all the items and now have a consistent 1516 /* we've logged all the items and now have a consistent
1507 * version of the file in the log. It is possible that 1517 * version of the file in the log. It is possible that
@@ -1513,7 +1523,7 @@ int btrfs_sync_file(struct file *file, int datasync)
1513 * file again, but that will end up using the synchronization 1523 * file again, but that will end up using the synchronization
1514 * inside btrfs_sync_log to keep things safe. 1524 * inside btrfs_sync_log to keep things safe.
1515 */ 1525 */
1516 mutex_unlock(&dentry->d_inode->i_mutex); 1526 mutex_unlock(&inode->i_mutex);
1517 1527
1518 if (ret != BTRFS_NO_LOG_SYNC) { 1528 if (ret != BTRFS_NO_LOG_SYNC) {
1519 if (ret > 0) { 1529 if (ret > 0) {
@@ -1528,7 +1538,6 @@ int btrfs_sync_file(struct file *file, int datasync)
1528 } else { 1538 } else {
1529 ret = btrfs_end_transaction(trans, root); 1539 ret = btrfs_end_transaction(trans, root);
1530 } 1540 }
1531 mutex_lock(&dentry->d_inode->i_mutex);
1532out: 1541out:
1533 return ret > 0 ? -EIO : ret; 1542 return ret > 0 ? -EIO : ret;
1534} 1543}
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index f605753c8fe9..8d74ad7ba556 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1811,7 +1811,7 @@ out:
1811 spin_unlock(&ci->i_unsafe_lock); 1811 spin_unlock(&ci->i_unsafe_lock);
1812} 1812}
1813 1813
1814int ceph_fsync(struct file *file, int datasync) 1814int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1815{ 1815{
1816 struct inode *inode = file->f_mapping->host; 1816 struct inode *inode = file->f_mapping->host;
1817 struct ceph_inode_info *ci = ceph_inode(inode); 1817 struct ceph_inode_info *ci = ceph_inode(inode);
@@ -1822,9 +1822,10 @@ int ceph_fsync(struct file *file, int datasync)
1822 dout("fsync %p%s\n", inode, datasync ? " datasync" : ""); 1822 dout("fsync %p%s\n", inode, datasync ? " datasync" : "");
1823 sync_write_wait(inode); 1823 sync_write_wait(inode);
1824 1824
1825 ret = filemap_write_and_wait(inode->i_mapping); 1825 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
1826 if (ret < 0) 1826 if (ret < 0)
1827 return ret; 1827 return ret;
1828 mutex_lock(&inode->i_mutex);
1828 1829
1829 dirty = try_flush_caps(inode, NULL, &flush_tid); 1830 dirty = try_flush_caps(inode, NULL, &flush_tid);
1830 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty)); 1831 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
@@ -1841,6 +1842,7 @@ int ceph_fsync(struct file *file, int datasync)
1841 } 1842 }
1842 1843
1843 dout("fsync %p%s done\n", inode, datasync ? " datasync" : ""); 1844 dout("fsync %p%s done\n", inode, datasync ? " datasync" : "");
1845 mutex_unlock(&inode->i_mutex);
1844 return ret; 1846 return ret;
1845} 1847}
1846 1848
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 0972b457a03f..1065ac779840 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1118,7 +1118,8 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
1118 * an fsync() on a dir will wait for any uncommitted directory 1118 * an fsync() on a dir will wait for any uncommitted directory
1119 * operations to commit. 1119 * operations to commit.
1120 */ 1120 */
1121static int ceph_dir_fsync(struct file *file, int datasync) 1121static int ceph_dir_fsync(struct file *file, loff_t start, loff_t end,
1122 int datasync)
1122{ 1123{
1123 struct inode *inode = file->f_path.dentry->d_inode; 1124 struct inode *inode = file->f_path.dentry->d_inode;
1124 struct ceph_inode_info *ci = ceph_inode(inode); 1125 struct ceph_inode_info *ci = ceph_inode(inode);
@@ -1128,6 +1129,11 @@ static int ceph_dir_fsync(struct file *file, int datasync)
1128 int ret = 0; 1129 int ret = 0;
1129 1130
1130 dout("dir_fsync %p\n", inode); 1131 dout("dir_fsync %p\n", inode);
1132 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
1133 if (ret)
1134 return ret;
1135 mutex_lock(&inode->i_mutex);
1136
1131 spin_lock(&ci->i_unsafe_lock); 1137 spin_lock(&ci->i_unsafe_lock);
1132 if (list_empty(head)) 1138 if (list_empty(head))
1133 goto out; 1139 goto out;
@@ -1161,6 +1167,8 @@ static int ceph_dir_fsync(struct file *file, int datasync)
1161 } while (req->r_tid < last_tid); 1167 } while (req->r_tid < last_tid);
1162out: 1168out:
1163 spin_unlock(&ci->i_unsafe_lock); 1169 spin_unlock(&ci->i_unsafe_lock);
1170 mutex_unlock(&inode->i_mutex);
1171
1164 return ret; 1172 return ret;
1165} 1173}
1166 1174
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 56c41ef47cad..30446b144e3d 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -728,7 +728,8 @@ extern void ceph_put_cap(struct ceph_mds_client *mdsc,
728 728
729extern void ceph_queue_caps_release(struct inode *inode); 729extern void ceph_queue_caps_release(struct inode *inode);
730extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc); 730extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc);
731extern int ceph_fsync(struct file *file, int datasync); 731extern int ceph_fsync(struct file *file, loff_t start, loff_t end,
732 int datasync);
732extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, 733extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
733 struct ceph_mds_session *session); 734 struct ceph_mds_session *session);
734extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci, 735extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 036ca83e5f46..fbd050c8d52a 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -91,8 +91,8 @@ extern ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
91extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, 91extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
92 unsigned long nr_segs, loff_t pos); 92 unsigned long nr_segs, loff_t pos);
93extern int cifs_lock(struct file *, int, struct file_lock *); 93extern int cifs_lock(struct file *, int, struct file_lock *);
94extern int cifs_fsync(struct file *, int); 94extern int cifs_fsync(struct file *, loff_t, loff_t, int);
95extern int cifs_strict_fsync(struct file *, int); 95extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
96extern int cifs_flush(struct file *, fl_owner_t id); 96extern int cifs_flush(struct file *, fl_owner_t id);
97extern int cifs_file_mmap(struct file * , struct vm_area_struct *); 97extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
98extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *); 98extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index bb71471a4d9d..cef584451113 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1401,7 +1401,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1401 return rc; 1401 return rc;
1402} 1402}
1403 1403
1404int cifs_strict_fsync(struct file *file, int datasync) 1404int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
1405 int datasync)
1405{ 1406{
1406 int xid; 1407 int xid;
1407 int rc = 0; 1408 int rc = 0;
@@ -1410,6 +1411,11 @@ int cifs_strict_fsync(struct file *file, int datasync)
1410 struct inode *inode = file->f_path.dentry->d_inode; 1411 struct inode *inode = file->f_path.dentry->d_inode;
1411 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1412 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1412 1413
1414 rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
1415 if (rc)
1416 return rc;
1417 mutex_lock(&inode->i_mutex);
1418
1413 xid = GetXid(); 1419 xid = GetXid();
1414 1420
1415 cFYI(1, "Sync file - name: %s datasync: 0x%x", 1421 cFYI(1, "Sync file - name: %s datasync: 0x%x",
@@ -1428,16 +1434,23 @@ int cifs_strict_fsync(struct file *file, int datasync)
1428 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1434 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1429 1435
1430 FreeXid(xid); 1436 FreeXid(xid);
1437 mutex_unlock(&inode->i_mutex);
1431 return rc; 1438 return rc;
1432} 1439}
1433 1440
1434int cifs_fsync(struct file *file, int datasync) 1441int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1435{ 1442{
1436 int xid; 1443 int xid;
1437 int rc = 0; 1444 int rc = 0;
1438 struct cifs_tcon *tcon; 1445 struct cifs_tcon *tcon;
1439 struct cifsFileInfo *smbfile = file->private_data; 1446 struct cifsFileInfo *smbfile = file->private_data;
1440 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1447 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1448 struct inode *inode = file->f_mapping->host;
1449
1450 rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
1451 if (rc)
1452 return rc;
1453 mutex_lock(&inode->i_mutex);
1441 1454
1442 xid = GetXid(); 1455 xid = GetXid();
1443 1456
@@ -1449,6 +1462,7 @@ int cifs_fsync(struct file *file, int datasync)
1449 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1462 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1450 1463
1451 FreeXid(xid); 1464 FreeXid(xid);
1465 mutex_unlock(&inode->i_mutex);
1452 return rc; 1466 return rc;
1453} 1467}
1454 1468
diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h
index 6b443ff43a19..b7143cf783ac 100644
--- a/fs/coda/coda_int.h
+++ b/fs/coda/coda_int.h
@@ -11,7 +11,7 @@ extern int coda_fake_statfs;
11 11
12void coda_destroy_inodecache(void); 12void coda_destroy_inodecache(void);
13int coda_init_inodecache(void); 13int coda_init_inodecache(void);
14int coda_fsync(struct file *coda_file, int datasync); 14int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync);
15void coda_sysctl_init(void); 15void coda_sysctl_init(void);
16void coda_sysctl_clean(void); 16void coda_sysctl_clean(void);
17 17
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 0433057be330..8edd404e6419 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -199,7 +199,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
199 return 0; 199 return 0;
200} 200}
201 201
202int coda_fsync(struct file *coda_file, int datasync) 202int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
203{ 203{
204 struct file *host_file; 204 struct file *host_file;
205 struct inode *coda_inode = coda_file->f_path.dentry->d_inode; 205 struct inode *coda_inode = coda_file->f_path.dentry->d_inode;
@@ -210,6 +210,11 @@ int coda_fsync(struct file *coda_file, int datasync)
210 S_ISLNK(coda_inode->i_mode))) 210 S_ISLNK(coda_inode->i_mode)))
211 return -EINVAL; 211 return -EINVAL;
212 212
213 err = filemap_write_and_wait_range(coda_inode->i_mapping, start, end);
214 if (err)
215 return err;
216 mutex_lock(&coda_inode->i_mutex);
217
213 cfi = CODA_FTOC(coda_file); 218 cfi = CODA_FTOC(coda_file);
214 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 219 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
215 host_file = cfi->cfi_container; 220 host_file = cfi->cfi_container;
@@ -217,6 +222,7 @@ int coda_fsync(struct file *coda_file, int datasync)
217 err = vfs_fsync(host_file, datasync); 222 err = vfs_fsync(host_file, datasync);
218 if (!err && !datasync) 223 if (!err && !datasync)
219 err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); 224 err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
225 mutex_unlock(&coda_inode->i_mutex);
220 226
221 return err; 227 return err;
222} 228}
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 4ec9eb00a241..c6ac98cf9baa 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -270,14 +270,15 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
270} 270}
271 271
272static int 272static int
273ecryptfs_fsync(struct file *file, int datasync) 273ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
274{ 274{
275 int rc = 0; 275 int rc = 0;
276 276
277 rc = generic_file_fsync(file, datasync); 277 rc = generic_file_fsync(file, start, end, datasync);
278 if (rc) 278 if (rc)
279 goto out; 279 goto out;
280 rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync); 280 rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end,
281 datasync);
281out: 282out:
282 return rc; 283 return rc;
283} 284}
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
index 45ca323d8363..491c6c078e7f 100644
--- a/fs/exofs/file.c
+++ b/fs/exofs/file.c
@@ -42,11 +42,19 @@ static int exofs_release_file(struct inode *inode, struct file *filp)
42 * Note, in exofs all metadata is written as part of inode, regardless. 42 * Note, in exofs all metadata is written as part of inode, regardless.
43 * The writeout is synchronous 43 * The writeout is synchronous
44 */ 44 */
45static int exofs_file_fsync(struct file *filp, int datasync) 45static int exofs_file_fsync(struct file *filp, loff_t start, loff_t end,
46 int datasync)
46{ 47{
48 struct inode *inode = filp->f_mapping->host;
47 int ret; 49 int ret;
48 50
51 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
52 if (ret)
53 return ret;
54
55 mutex_lock(&inode->i_mutex);
49 ret = sync_inode_metadata(filp->f_mapping->host, 1); 56 ret = sync_inode_metadata(filp->f_mapping->host, 1);
57 mutex_unlock(&inode->i_mutex);
50 return ret; 58 return ret;
51} 59}
52 60
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 645be9e7ee47..af9fc89b1b2d 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -150,7 +150,8 @@ extern void ext2_write_super (struct super_block *);
150extern const struct file_operations ext2_dir_operations; 150extern const struct file_operations ext2_dir_operations;
151 151
152/* file.c */ 152/* file.c */
153extern int ext2_fsync(struct file *file, int datasync); 153extern int ext2_fsync(struct file *file, loff_t start, loff_t end,
154 int datasync);
154extern const struct inode_operations ext2_file_inode_operations; 155extern const struct inode_operations ext2_file_inode_operations;
155extern const struct file_operations ext2_file_operations; 156extern const struct file_operations ext2_file_operations;
156extern const struct file_operations ext2_xip_file_operations; 157extern const struct file_operations ext2_xip_file_operations;
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 49eec9456c5b..82e06321de35 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
40 return 0; 40 return 0;
41} 41}
42 42
43int ext2_fsync(struct file *file, int datasync) 43int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
44{ 44{
45 int ret; 45 int ret;
46 struct super_block *sb = file->f_mapping->host->i_sb; 46 struct super_block *sb = file->f_mapping->host->i_sb;
47 struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; 47 struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
48 48
49 ret = generic_file_fsync(file, datasync); 49 ret = generic_file_fsync(file, start, end, datasync);
50 if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { 50 if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) {
51 /* We don't really know where the IO error happened... */ 51 /* We don't really know where the IO error happened... */
52 ext2_error(sb, __func__, 52 ext2_error(sb, __func__,
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index 09b13bb34c94..0bcf63adb80a 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -43,7 +43,7 @@
43 * inode to disk. 43 * inode to disk.
44 */ 44 */
45 45
46int ext3_sync_file(struct file *file, int datasync) 46int ext3_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
47{ 47{
48 struct inode *inode = file->f_mapping->host; 48 struct inode *inode = file->f_mapping->host;
49 struct ext3_inode_info *ei = EXT3_I(inode); 49 struct ext3_inode_info *ei = EXT3_I(inode);
@@ -54,6 +54,17 @@ int ext3_sync_file(struct file *file, int datasync)
54 if (inode->i_sb->s_flags & MS_RDONLY) 54 if (inode->i_sb->s_flags & MS_RDONLY)
55 return 0; 55 return 0;
56 56
57 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
58 if (ret)
59 return ret;
60
61 /*
62 * Taking the mutex here just to keep consistent with how fsync was
63 * called previously, however it looks like we don't need to take
64 * i_mutex at all.
65 */
66 mutex_lock(&inode->i_mutex);
67
57 J_ASSERT(ext3_journal_current_handle() == NULL); 68 J_ASSERT(ext3_journal_current_handle() == NULL);
58 69
59 /* 70 /*
@@ -70,8 +81,10 @@ int ext3_sync_file(struct file *file, int datasync)
70 * (they were dirtied by commit). But that's OK - the blocks are 81 * (they were dirtied by commit). But that's OK - the blocks are
71 * safe in-journal, which is all fsync() needs to ensure. 82 * safe in-journal, which is all fsync() needs to ensure.
72 */ 83 */
73 if (ext3_should_journal_data(inode)) 84 if (ext3_should_journal_data(inode)) {
85 mutex_unlock(&inode->i_mutex);
74 return ext3_force_commit(inode->i_sb); 86 return ext3_force_commit(inode->i_sb);
87 }
75 88
76 if (datasync) 89 if (datasync)
77 commit_tid = atomic_read(&ei->i_datasync_tid); 90 commit_tid = atomic_read(&ei->i_datasync_tid);
@@ -91,5 +104,6 @@ int ext3_sync_file(struct file *file, int datasync)
91 */ 104 */
92 if (needs_barrier) 105 if (needs_barrier)
93 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 106 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
107 mutex_unlock(&inode->i_mutex);
94 return ret; 108 return ret;
95} 109}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 1921392cd708..fa44df879711 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1758,7 +1758,7 @@ extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
1758extern void ext4_htree_free_dir_info(struct dir_private_info *p); 1758extern void ext4_htree_free_dir_info(struct dir_private_info *p);
1759 1759
1760/* fsync.c */ 1760/* fsync.c */
1761extern int ext4_sync_file(struct file *, int); 1761extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
1762extern int ext4_flush_completed_IO(struct inode *); 1762extern int ext4_flush_completed_IO(struct inode *);
1763 1763
1764/* hash.c */ 1764/* hash.c */
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index ce66d2fe826c..da3bed3e0c29 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -151,6 +151,32 @@ static int ext4_sync_parent(struct inode *inode)
151 return ret; 151 return ret;
152} 152}
153 153
154/**
155 * __sync_file - generic_file_fsync without the locking and filemap_write
156 * @inode: inode to sync
157 * @datasync: only sync essential metadata if true
158 *
159 * This is just generic_file_fsync without the locking. This is needed for
160 * nojournal mode to make sure this inodes data/metadata makes it to disk
161 * properly. The i_mutex should be held already.
162 */
163static int __sync_inode(struct inode *inode, int datasync)
164{
165 int err;
166 int ret;
167
168 ret = sync_mapping_buffers(inode->i_mapping);
169 if (!(inode->i_state & I_DIRTY))
170 return ret;
171 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
172 return ret;
173
174 err = sync_inode_metadata(inode, 1);
175 if (ret == 0)
176 ret = err;
177 return ret;
178}
179
154/* 180/*
155 * akpm: A new design for ext4_sync_file(). 181 * akpm: A new design for ext4_sync_file().
156 * 182 *
@@ -165,7 +191,7 @@ static int ext4_sync_parent(struct inode *inode)
165 * i_mutex lock is held when entering and exiting this function 191 * i_mutex lock is held when entering and exiting this function
166 */ 192 */
167 193
168int ext4_sync_file(struct file *file, int datasync) 194int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
169{ 195{
170 struct inode *inode = file->f_mapping->host; 196 struct inode *inode = file->f_mapping->host;
171 struct ext4_inode_info *ei = EXT4_I(inode); 197 struct ext4_inode_info *ei = EXT4_I(inode);
@@ -178,15 +204,20 @@ int ext4_sync_file(struct file *file, int datasync)
178 204
179 trace_ext4_sync_file_enter(file, datasync); 205 trace_ext4_sync_file_enter(file, datasync);
180 206
207 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
208 if (ret)
209 return ret;
210 mutex_lock(&inode->i_mutex);
211
181 if (inode->i_sb->s_flags & MS_RDONLY) 212 if (inode->i_sb->s_flags & MS_RDONLY)
182 return 0; 213 goto out;
183 214
184 ret = ext4_flush_completed_IO(inode); 215 ret = ext4_flush_completed_IO(inode);
185 if (ret < 0) 216 if (ret < 0)
186 goto out; 217 goto out;
187 218
188 if (!journal) { 219 if (!journal) {
189 ret = generic_file_fsync(file, datasync); 220 ret = __sync_inode(inode, datasync);
190 if (!ret && !list_empty(&inode->i_dentry)) 221 if (!ret && !list_empty(&inode->i_dentry))
191 ret = ext4_sync_parent(inode); 222 ret = ext4_sync_parent(inode);
192 goto out; 223 goto out;
@@ -220,6 +251,7 @@ int ext4_sync_file(struct file *file, int datasync)
220 if (needs_barrier) 251 if (needs_barrier)
221 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 252 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
222 out: 253 out:
254 mutex_unlock(&inode->i_mutex);
223 trace_ext4_sync_file_exit(inode, ret); 255 trace_ext4_sync_file_exit(inode, ret);
224 return ret; 256 return ret;
225} 257}
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index a975b4147e91..a5d3853822e0 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -310,7 +310,8 @@ extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
310extern void fat_truncate_blocks(struct inode *inode, loff_t offset); 310extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
311extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, 311extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
312 struct kstat *stat); 312 struct kstat *stat);
313extern int fat_file_fsync(struct file *file, int datasync); 313extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
314 int datasync);
314 315
315/* fat/inode.c */ 316/* fat/inode.c */
316extern void fat_attach(struct inode *inode, loff_t i_pos); 317extern void fat_attach(struct inode *inode, loff_t i_pos);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index e1587c54d3c1..c118acf16e43 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -149,12 +149,12 @@ static int fat_file_release(struct inode *inode, struct file *filp)
149 return 0; 149 return 0;
150} 150}
151 151
152int fat_file_fsync(struct file *filp, int datasync) 152int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
153{ 153{
154 struct inode *inode = filp->f_mapping->host; 154 struct inode *inode = filp->f_mapping->host;
155 int res, err; 155 int res, err;
156 156
157 res = generic_file_fsync(filp, datasync); 157 res = generic_file_fsync(filp, start, end, datasync);
158 err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); 158 err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
159 159
160 return res ? res : err; 160 return res ? res : err;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 02063dde2728..9f63e493a9b6 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1176,9 +1176,10 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
1176 return 0; 1176 return 0;
1177} 1177}
1178 1178
1179static int fuse_dir_fsync(struct file *file, int datasync) 1179static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1180 int datasync)
1180{ 1181{
1181 return fuse_fsync_common(file, datasync, 1); 1182 return fuse_fsync_common(file, start, end, datasync, 1);
1182} 1183}
1183 1184
1184static bool update_mtime(unsigned ivalid) 1185static bool update_mtime(unsigned ivalid)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 73b89df20851..7bb685cdd00c 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -400,7 +400,8 @@ static void fuse_sync_writes(struct inode *inode)
400 fuse_release_nowrite(inode); 400 fuse_release_nowrite(inode);
401} 401}
402 402
403int fuse_fsync_common(struct file *file, int datasync, int isdir) 403int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
404 int datasync, int isdir)
404{ 405{
405 struct inode *inode = file->f_mapping->host; 406 struct inode *inode = file->f_mapping->host;
406 struct fuse_conn *fc = get_fuse_conn(inode); 407 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -412,9 +413,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
412 if (is_bad_inode(inode)) 413 if (is_bad_inode(inode))
413 return -EIO; 414 return -EIO;
414 415
416 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
417 if (err)
418 return err;
419
415 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) 420 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
416 return 0; 421 return 0;
417 422
423 mutex_lock(&inode->i_mutex);
424
418 /* 425 /*
419 * Start writeback against all dirty pages of the inode, then 426 * Start writeback against all dirty pages of the inode, then
420 * wait for all outstanding writes, before sending the FSYNC 427 * wait for all outstanding writes, before sending the FSYNC
@@ -422,13 +429,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
422 */ 429 */
423 err = write_inode_now(inode, 0); 430 err = write_inode_now(inode, 0);
424 if (err) 431 if (err)
425 return err; 432 goto out;
426 433
427 fuse_sync_writes(inode); 434 fuse_sync_writes(inode);
428 435
429 req = fuse_get_req(fc); 436 req = fuse_get_req(fc);
430 if (IS_ERR(req)) 437 if (IS_ERR(req)) {
431 return PTR_ERR(req); 438 err = PTR_ERR(req);
439 goto out;
440 }
432 441
433 memset(&inarg, 0, sizeof(inarg)); 442 memset(&inarg, 0, sizeof(inarg));
434 inarg.fh = ff->fh; 443 inarg.fh = ff->fh;
@@ -448,12 +457,15 @@ int fuse_fsync_common(struct file *file, int datasync, int isdir)
448 fc->no_fsync = 1; 457 fc->no_fsync = 1;
449 err = 0; 458 err = 0;
450 } 459 }
460out:
461 mutex_unlock(&inode->i_mutex);
451 return err; 462 return err;
452} 463}
453 464
454static int fuse_fsync(struct file *file, int datasync) 465static int fuse_fsync(struct file *file, loff_t start, loff_t end,
466 int datasync)
455{ 467{
456 return fuse_fsync_common(file, datasync, 0); 468 return fuse_fsync_common(file, start, end, datasync, 0);
457} 469}
458 470
459void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, 471void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index b788becada76..c6aa2d4b8517 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -589,7 +589,8 @@ void fuse_release_common(struct file *file, int opcode);
589/** 589/**
590 * Send FSYNC or FSYNCDIR request 590 * Send FSYNC or FSYNCDIR request
591 */ 591 */
592int fuse_fsync_common(struct file *file, int datasync, int isdir); 592int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
593 int datasync, int isdir);
593 594
594/** 595/**
595 * Notify poll wakeup 596 * Notify poll wakeup
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 89c39e53760d..f82cb5e1cb6b 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -544,7 +544,9 @@ static int gfs2_close(struct inode *inode, struct file *file)
544 544
545/** 545/**
546 * gfs2_fsync - sync the dirty data for a file (across the cluster) 546 * gfs2_fsync - sync the dirty data for a file (across the cluster)
547 * @file: the file that points to the dentry (we ignore this) 547 * @file: the file that points to the dentry
548 * @start: the start position in the file to sync
549 * @end: the end position in the file to sync
548 * @datasync: set if we can ignore timestamp changes 550 * @datasync: set if we can ignore timestamp changes
549 * 551 *
550 * The VFS will flush data for us. We only need to worry 552 * The VFS will flush data for us. We only need to worry
@@ -553,23 +555,32 @@ static int gfs2_close(struct inode *inode, struct file *file)
553 * Returns: errno 555 * Returns: errno
554 */ 556 */
555 557
556static int gfs2_fsync(struct file *file, int datasync) 558static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
559 int datasync)
557{ 560{
558 struct inode *inode = file->f_mapping->host; 561 struct inode *inode = file->f_mapping->host;
559 int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); 562 int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
560 struct gfs2_inode *ip = GFS2_I(inode); 563 struct gfs2_inode *ip = GFS2_I(inode);
561 int ret; 564 int ret;
562 565
566 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
567 if (ret)
568 return ret;
569 mutex_lock(&inode->i_mutex);
570
563 if (datasync) 571 if (datasync)
564 sync_state &= ~I_DIRTY_SYNC; 572 sync_state &= ~I_DIRTY_SYNC;
565 573
566 if (sync_state) { 574 if (sync_state) {
567 ret = sync_inode_metadata(inode, 1); 575 ret = sync_inode_metadata(inode, 1);
568 if (ret) 576 if (ret) {
577 mutex_unlock(&inode->i_mutex);
569 return ret; 578 return ret;
579 }
570 gfs2_ail_flush(ip->i_gl); 580 gfs2_ail_flush(ip->i_gl);
571 } 581 }
572 582
583 mutex_unlock(&inode->i_mutex);
573 return 0; 584 return 0;
574} 585}
575 586
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 5e7c3f309617..96a1b625fc74 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -627,12 +627,18 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
627 return 0; 627 return 0;
628} 628}
629 629
630static int hfs_file_fsync(struct file *filp, int datasync) 630static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
631 int datasync)
631{ 632{
632 struct inode *inode = filp->f_mapping->host; 633 struct inode *inode = filp->f_mapping->host;
633 struct super_block * sb; 634 struct super_block * sb;
634 int ret, err; 635 int ret, err;
635 636
637 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
638 if (ret)
639 return ret;
640 mutex_lock(&inode->i_mutex);
641
636 /* sync the inode to buffers */ 642 /* sync the inode to buffers */
637 ret = write_inode_now(inode, 0); 643 ret = write_inode_now(inode, 0);
638 644
@@ -649,6 +655,7 @@ static int hfs_file_fsync(struct file *filp, int datasync)
649 err = sync_blockdev(sb->s_bdev); 655 err = sync_blockdev(sb->s_bdev);
650 if (!ret) 656 if (!ret)
651 ret = err; 657 ret = err;
658 mutex_unlock(&inode->i_mutex);
652 return ret; 659 return ret;
653} 660}
654 661
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index d6857523336d..38184e360932 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -392,7 +392,8 @@ int hfsplus_cat_read_inode(struct inode *, struct hfs_find_data *);
392int hfsplus_cat_write_inode(struct inode *); 392int hfsplus_cat_write_inode(struct inode *);
393struct inode *hfsplus_new_inode(struct super_block *, int); 393struct inode *hfsplus_new_inode(struct super_block *, int);
394void hfsplus_delete_inode(struct inode *); 394void hfsplus_delete_inode(struct inode *);
395int hfsplus_file_fsync(struct file *file, int datasync); 395int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
396 int datasync);
396 397
397/* ioctl.c */ 398/* ioctl.c */
398long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 399long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 5b1cb98741cc..30486e01d003 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -308,13 +308,19 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
308 return 0; 308 return 0;
309} 309}
310 310
311int hfsplus_file_fsync(struct file *file, int datasync) 311int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
312 int datasync)
312{ 313{
313 struct inode *inode = file->f_mapping->host; 314 struct inode *inode = file->f_mapping->host;
314 struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 315 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
315 struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); 316 struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
316 int error = 0, error2; 317 int error = 0, error2;
317 318
319 error = filemap_write_and_wait_range(inode->i_mapping, start, end);
320 if (error)
321 return error;
322 mutex_lock(&inode->i_mutex);
323
318 /* 324 /*
319 * Sync inode metadata into the catalog and extent trees. 325 * Sync inode metadata into the catalog and extent trees.
320 */ 326 */
@@ -342,6 +348,8 @@ int hfsplus_file_fsync(struct file *file, int datasync)
342 if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) 348 if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
343 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 349 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
344 350
351 mutex_unlock(&inode->i_mutex);
352
345 return error; 353 return error;
346} 354}
347 355
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 6e449c599b9d..0d22afdd4611 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -362,9 +362,20 @@ retry:
362 return 0; 362 return 0;
363} 363}
364 364
365int hostfs_fsync(struct file *file, int datasync) 365int hostfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
366{ 366{
367 return fsync_file(HOSTFS_I(file->f_mapping->host)->fd, datasync); 367 struct inode *inode = file->f_mapping->host;
368 int ret;
369
370 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
371 if (ret)
372 return ret;
373
374 mutex_lock(&inode->i_mutex);
375 ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
376 mutex_unlock(&inode->i_mutex);
377
378 return ret;
368} 379}
369 380
370static const struct file_operations hostfs_file_fops = { 381static const struct file_operations hostfs_file_fops = {
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 89c500ee5213..89d2a5803ae3 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -18,9 +18,14 @@ static int hpfs_file_release(struct inode *inode, struct file *file)
18 return 0; 18 return 0;
19} 19}
20 20
21int hpfs_file_fsync(struct file *file, int datasync) 21int hpfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
22{ 22{
23 struct inode *inode = file->f_mapping->host; 23 struct inode *inode = file->f_mapping->host;
24 int ret;
25
26 ret = filemap_write_and_wait_range(file->f_mapping, start, end);
27 if (ret)
28 return ret;
24 return sync_blockdev(inode->i_sb->s_bdev); 29 return sync_blockdev(inode->i_sb->s_bdev);
25} 30}
26 31
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index dd552f862c8f..331b5e234ef3 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -258,7 +258,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, const char *,
258 258
259/* file.c */ 259/* file.c */
260 260
261int hpfs_file_fsync(struct file *, int); 261int hpfs_file_fsync(struct file *, loff_t, loff_t, int);
262extern const struct file_operations hpfs_file_ops; 262extern const struct file_operations hpfs_file_ops;
263extern const struct inode_operations hpfs_file_iops; 263extern const struct inode_operations hpfs_file_iops;
264extern const struct address_space_operations hpfs_aops; 264extern const struct address_space_operations hpfs_aops;
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index 85c098a499f3..8635be5ffd97 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -573,9 +573,10 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
573 return err; 573 return err;
574} 574}
575 575
576static int hppfs_fsync(struct file *file, int datasync) 576static int hppfs_fsync(struct file *file, loff_t start, loff_t end,
577 int datasync)
577{ 578{
578 return 0; 579 return filemap_write_and_wait_range(file->f_mapping, start, end);
579} 580}
580 581
581static const struct file_operations hppfs_dir_fops = { 582static const struct file_operations hppfs_dir_fops = {
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 1c0a08d711aa..3989f7e09f7f 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -27,13 +27,20 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
27 struct page **pagep, void **fsdata); 27 struct page **pagep, void **fsdata);
28static int jffs2_readpage (struct file *filp, struct page *pg); 28static int jffs2_readpage (struct file *filp, struct page *pg);
29 29
30int jffs2_fsync(struct file *filp, int datasync) 30int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
31{ 31{
32 struct inode *inode = filp->f_mapping->host; 32 struct inode *inode = filp->f_mapping->host;
33 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 33 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
34 int ret;
35
36 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
37 if (ret)
38 return ret;
34 39
40 mutex_lock(&inode->i_mutex);
35 /* Trigger GC to flush any pending writes for this inode */ 41 /* Trigger GC to flush any pending writes for this inode */
36 jffs2_flush_wbuf_gc(c, inode->i_ino); 42 jffs2_flush_wbuf_gc(c, inode->i_ino);
43 mutex_unlock(&inode->i_mutex);
37 44
38 return 0; 45 return 0;
39} 46}
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 65c6c43ca482..9c252835e8e5 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -158,7 +158,7 @@ extern const struct inode_operations jffs2_dir_inode_operations;
158extern const struct file_operations jffs2_file_operations; 158extern const struct file_operations jffs2_file_operations;
159extern const struct inode_operations jffs2_file_inode_operations; 159extern const struct inode_operations jffs2_file_inode_operations;
160extern const struct address_space_operations jffs2_file_address_operations; 160extern const struct address_space_operations jffs2_file_address_operations;
161int jffs2_fsync(struct file *, int); 161int jffs2_fsync(struct file *, loff_t, loff_t, int);
162int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); 162int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
163 163
164/* ioctl.c */ 164/* ioctl.c */
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 9f32315acef1..7527855b5cc6 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -28,19 +28,26 @@
28#include "jfs_acl.h" 28#include "jfs_acl.h"
29#include "jfs_debug.h" 29#include "jfs_debug.h"
30 30
31int jfs_fsync(struct file *file, int datasync) 31int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
32{ 32{
33 struct inode *inode = file->f_mapping->host; 33 struct inode *inode = file->f_mapping->host;
34 int rc = 0; 34 int rc = 0;
35 35
36 rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
37 if (rc)
38 return rc;
39
40 mutex_lock(&inode->i_mutex);
36 if (!(inode->i_state & I_DIRTY) || 41 if (!(inode->i_state & I_DIRTY) ||
37 (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) { 42 (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) {
38 /* Make sure committed changes hit the disk */ 43 /* Make sure committed changes hit the disk */
39 jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1); 44 jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1);
45 mutex_unlock(&inode->i_mutex);
40 return rc; 46 return rc;
41 } 47 }
42 48
43 rc |= jfs_commit_inode(inode, 1); 49 rc |= jfs_commit_inode(inode, 1);
50 mutex_unlock(&inode->i_mutex);
44 51
45 return rc ? -EIO : 0; 52 return rc ? -EIO : 0;
46} 53}
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index ec2fb8b945fc..9271cfe4a149 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -21,7 +21,7 @@
21struct fid; 21struct fid;
22 22
23extern struct inode *ialloc(struct inode *, umode_t); 23extern struct inode *ialloc(struct inode *, umode_t);
24extern int jfs_fsync(struct file *, int); 24extern int jfs_fsync(struct file *, loff_t, loff_t, int);
25extern long jfs_ioctl(struct file *, unsigned int, unsigned long); 25extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
26extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); 26extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
27extern struct inode *jfs_iget(struct super_block *, unsigned long); 27extern struct inode *jfs_iget(struct super_block *, unsigned long);
diff --git a/fs/libfs.c b/fs/libfs.c
index bd50b11f92da..8f2271a5df53 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -905,21 +905,29 @@ EXPORT_SYMBOL_GPL(generic_fh_to_parent);
905 * filesystems which track all non-inode metadata in the buffers list 905 * filesystems which track all non-inode metadata in the buffers list
906 * hanging off the address_space structure. 906 * hanging off the address_space structure.
907 */ 907 */
908int generic_file_fsync(struct file *file, int datasync) 908int generic_file_fsync(struct file *file, loff_t start, loff_t end,
909 int datasync)
909{ 910{
910 struct inode *inode = file->f_mapping->host; 911 struct inode *inode = file->f_mapping->host;
911 int err; 912 int err;
912 int ret; 913 int ret;
913 914
915 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
916 if (err)
917 return err;
918
919 mutex_lock(&inode->i_mutex);
914 ret = sync_mapping_buffers(inode->i_mapping); 920 ret = sync_mapping_buffers(inode->i_mapping);
915 if (!(inode->i_state & I_DIRTY)) 921 if (!(inode->i_state & I_DIRTY))
916 return ret; 922 goto out;
917 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 923 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
918 return ret; 924 goto out;
919 925
920 err = sync_inode_metadata(inode, 1); 926 err = sync_inode_metadata(inode, 1);
921 if (ret == 0) 927 if (ret == 0)
922 ret = err; 928 ret = err;
929out:
930 mutex_unlock(&inode->i_mutex);
923 return ret; 931 return ret;
924} 932}
925EXPORT_SYMBOL(generic_file_fsync); 933EXPORT_SYMBOL(generic_file_fsync);
@@ -956,7 +964,7 @@ EXPORT_SYMBOL(generic_check_addressable);
956/* 964/*
957 * No-op implementation of ->fsync for in-memory filesystems. 965 * No-op implementation of ->fsync for in-memory filesystems.
958 */ 966 */
959int noop_fsync(struct file *file, int datasync) 967int noop_fsync(struct file *file, loff_t start, loff_t end, int datasync)
960{ 968{
961 return 0; 969 return 0;
962} 970}
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
index c2ad7028def4..b548c87a86f1 100644
--- a/fs/logfs/file.c
+++ b/fs/logfs/file.c
@@ -219,11 +219,20 @@ long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
219 } 219 }
220} 220}
221 221
222int logfs_fsync(struct file *file, int datasync) 222int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
223{ 223{
224 struct super_block *sb = file->f_mapping->host->i_sb; 224 struct super_block *sb = file->f_mapping->host->i_sb;
225 struct inode *inode = file->f_mapping->host;
226 int ret;
227
228 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
229 if (ret)
230 return ret;
225 231
232 mutex_lock(&inode->i_mutex);
226 logfs_write_anchor(sb); 233 logfs_write_anchor(sb);
234 mutex_unlock(&inode->i_mutex);
235
227 return 0; 236 return 0;
228} 237}
229 238
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h
index 57afd4a6fabb..f22d108bfa5d 100644
--- a/fs/logfs/logfs.h
+++ b/fs/logfs/logfs.h
@@ -506,7 +506,7 @@ extern const struct file_operations logfs_reg_fops;
506extern const struct address_space_operations logfs_reg_aops; 506extern const struct address_space_operations logfs_reg_aops;
507int logfs_readpage(struct file *file, struct page *page); 507int logfs_readpage(struct file *file, struct page *page);
508long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 508long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
509int logfs_fsync(struct file *file, int datasync); 509int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
510 510
511/* gc.c */ 511/* gc.c */
512u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec); 512u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec);
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 0ed65e0c3dfe..64a326418aa2 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -20,9 +20,9 @@
20 20
21#include "ncp_fs.h" 21#include "ncp_fs.h"
22 22
23static int ncp_fsync(struct file *file, int datasync) 23static int ncp_fsync(struct file *file, loff_t start, loff_t end, int datasync)
24{ 24{
25 return 0; 25 return filemap_write_and_wait_range(file->f_mapping, start, end);
26} 26}
27 27
28/* 28/*
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8a45e6d1f6a4..57f578e2560a 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -56,7 +56,7 @@ static int nfs_link(struct dentry *, struct inode *, struct dentry *);
56static int nfs_mknod(struct inode *, struct dentry *, int, dev_t); 56static int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
57static int nfs_rename(struct inode *, struct dentry *, 57static int nfs_rename(struct inode *, struct dentry *,
58 struct inode *, struct dentry *); 58 struct inode *, struct dentry *);
59static int nfs_fsync_dir(struct file *, int); 59static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
60static loff_t nfs_llseek_dir(struct file *, loff_t, int); 60static loff_t nfs_llseek_dir(struct file *, loff_t, int);
61static void nfs_readdir_clear_array(struct page*); 61static void nfs_readdir_clear_array(struct page*);
62 62
@@ -945,15 +945,19 @@ out:
945 * All directory operations under NFS are synchronous, so fsync() 945 * All directory operations under NFS are synchronous, so fsync()
946 * is a dummy operation. 946 * is a dummy operation.
947 */ 947 */
948static int nfs_fsync_dir(struct file *filp, int datasync) 948static int nfs_fsync_dir(struct file *filp, loff_t start, loff_t end,
949 int datasync)
949{ 950{
950 struct dentry *dentry = filp->f_path.dentry; 951 struct dentry *dentry = filp->f_path.dentry;
952 struct inode *inode = dentry->d_inode;
951 953
952 dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n", 954 dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n",
953 dentry->d_parent->d_name.name, dentry->d_name.name, 955 dentry->d_parent->d_name.name, dentry->d_name.name,
954 datasync); 956 datasync);
955 957
958 mutex_lock(&inode->i_mutex);
956 nfs_inc_stats(dentry->d_inode, NFSIOS_VFSFSYNC); 959 nfs_inc_stats(dentry->d_inode, NFSIOS_VFSFSYNC);
960 mutex_unlock(&inode->i_mutex);
957 return 0; 961 return 0;
958} 962}
959 963
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 2c1705b6acd7..28b8c3f3cda3 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -55,7 +55,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
55static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 55static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
56 unsigned long nr_segs, loff_t pos); 56 unsigned long nr_segs, loff_t pos);
57static int nfs_file_flush(struct file *, fl_owner_t id); 57static int nfs_file_flush(struct file *, fl_owner_t id);
58static int nfs_file_fsync(struct file *, int datasync); 58static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync);
59static int nfs_check_flags(int flags); 59static int nfs_check_flags(int flags);
60static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 60static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
61static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 61static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
@@ -308,7 +308,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
308 * fall back to doing a synchronous write. 308 * fall back to doing a synchronous write.
309 */ 309 */
310static int 310static int
311nfs_file_fsync(struct file *file, int datasync) 311nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
312{ 312{
313 struct dentry *dentry = file->f_path.dentry; 313 struct dentry *dentry = file->f_path.dentry;
314 struct nfs_open_context *ctx = nfs_file_open_context(file); 314 struct nfs_open_context *ctx = nfs_file_open_context(file);
@@ -316,11 +316,15 @@ nfs_file_fsync(struct file *file, int datasync)
316 int have_error, status; 316 int have_error, status;
317 int ret = 0; 317 int ret = 0;
318 318
319
320 dprintk("NFS: fsync file(%s/%s) datasync %d\n", 319 dprintk("NFS: fsync file(%s/%s) datasync %d\n",
321 dentry->d_parent->d_name.name, dentry->d_name.name, 320 dentry->d_parent->d_name.name, dentry->d_name.name,
322 datasync); 321 datasync);
323 322
323 ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
324 if (ret)
325 return ret;
326 mutex_lock(&inode->i_mutex);
327
324 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 328 nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
325 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags); 329 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
326 status = nfs_commit_inode(inode, FLUSH_SYNC); 330 status = nfs_commit_inode(inode, FLUSH_SYNC);
@@ -332,6 +336,7 @@ nfs_file_fsync(struct file *file, int datasync)
332 if (!ret && !datasync) 336 if (!ret && !datasync)
333 /* application has asked for meta-data sync */ 337 /* application has asked for meta-data sync */
334 ret = pnfs_layoutcommit_inode(inode, true); 338 ret = pnfs_layoutcommit_inode(inode, true);
339 mutex_unlock(&inode->i_mutex);
335 return ret; 340 return ret;
336} 341}
337 342
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index d7eeca62febd..26601529dc17 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -27,7 +27,7 @@
27#include "nilfs.h" 27#include "nilfs.h"
28#include "segment.h" 28#include "segment.h"
29 29
30int nilfs_sync_file(struct file *file, int datasync) 30int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
31{ 31{
32 /* 32 /*
33 * Called from fsync() system call 33 * Called from fsync() system call
@@ -40,8 +40,15 @@ int nilfs_sync_file(struct file *file, int datasync)
40 struct inode *inode = file->f_mapping->host; 40 struct inode *inode = file->f_mapping->host;
41 int err; 41 int err;
42 42
43 if (!nilfs_inode_dirty(inode)) 43 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
44 if (err)
45 return err;
46 mutex_lock(&inode->i_mutex);
47
48 if (!nilfs_inode_dirty(inode)) {
49 mutex_unlock(&inode->i_mutex);
44 return 0; 50 return 0;
51 }
45 52
46 if (datasync) 53 if (datasync)
47 err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0, 54 err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0,
@@ -49,6 +56,7 @@ int nilfs_sync_file(struct file *file, int datasync)
49 else 56 else
50 err = nilfs_construct_segment(inode->i_sb); 57 err = nilfs_construct_segment(inode->i_sb);
51 58
59 mutex_unlock(&inode->i_mutex);
52 return err; 60 return err;
53} 61}
54 62
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 6fb7511c0328..255d5e1c03b7 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -235,7 +235,7 @@ extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
235 struct page *, struct inode *); 235 struct page *, struct inode *);
236 236
237/* file.c */ 237/* file.c */
238extern int nilfs_sync_file(struct file *, int); 238extern int nilfs_sync_file(struct file *, loff_t, loff_t, int);
239 239
240/* ioctl.c */ 240/* ioctl.c */
241long nilfs_ioctl(struct file *, unsigned int, unsigned long); 241long nilfs_ioctl(struct file *, unsigned int, unsigned long);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 0f48e7c5d9e1..99e36107ff60 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1527,13 +1527,20 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp)
1527 * this problem for now. We do write the $BITMAP attribute if it is present 1527 * this problem for now. We do write the $BITMAP attribute if it is present
1528 * which is the important one for a directory so things are not too bad. 1528 * which is the important one for a directory so things are not too bad.
1529 */ 1529 */
1530static int ntfs_dir_fsync(struct file *filp, int datasync) 1530static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
1531 int datasync)
1531{ 1532{
1532 struct inode *bmp_vi, *vi = filp->f_mapping->host; 1533 struct inode *bmp_vi, *vi = filp->f_mapping->host;
1533 int err, ret; 1534 int err, ret;
1534 ntfs_attr na; 1535 ntfs_attr na;
1535 1536
1536 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); 1537 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
1538
1539 err = filemap_write_and_wait_range(vi->i_mapping, start, end);
1540 if (err)
1541 return err;
1542 mutex_lock(&vi->i_mutex);
1543
1537 BUG_ON(!S_ISDIR(vi->i_mode)); 1544 BUG_ON(!S_ISDIR(vi->i_mode));
1538 /* If the bitmap attribute inode is in memory sync it, too. */ 1545 /* If the bitmap attribute inode is in memory sync it, too. */
1539 na.mft_no = vi->i_ino; 1546 na.mft_no = vi->i_ino;
@@ -1555,6 +1562,7 @@ static int ntfs_dir_fsync(struct file *filp, int datasync)
1555 else 1562 else
1556 ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " 1563 ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error "
1557 "%u.", datasync ? "data" : "", vi->i_ino, -ret); 1564 "%u.", datasync ? "data" : "", vi->i_ino, -ret);
1565 mutex_unlock(&vi->i_mutex);
1558 return ret; 1566 return ret;
1559} 1567}
1560 1568
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index b59f5ac26bef..c587e2d27183 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2152,12 +2152,19 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2152 * with this inode but since we have no simple way of getting to them we ignore 2152 * with this inode but since we have no simple way of getting to them we ignore
2153 * this problem for now. 2153 * this problem for now.
2154 */ 2154 */
2155static int ntfs_file_fsync(struct file *filp, int datasync) 2155static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end,
2156 int datasync)
2156{ 2157{
2157 struct inode *vi = filp->f_mapping->host; 2158 struct inode *vi = filp->f_mapping->host;
2158 int err, ret = 0; 2159 int err, ret = 0;
2159 2160
2160 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); 2161 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
2162
2163 err = filemap_write_and_wait_range(vi->i_mapping, start, end);
2164 if (err)
2165 return err;
2166 mutex_lock(&vi->i_mutex);
2167
2161 BUG_ON(S_ISDIR(vi->i_mode)); 2168 BUG_ON(S_ISDIR(vi->i_mode));
2162 if (!datasync || !NInoNonResident(NTFS_I(vi))) 2169 if (!datasync || !NInoNonResident(NTFS_I(vi)))
2163 ret = __ntfs_write_inode(vi, 1); 2170 ret = __ntfs_write_inode(vi, 1);
@@ -2175,6 +2182,7 @@ static int ntfs_file_fsync(struct file *filp, int datasync)
2175 else 2182 else
2176 ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " 2183 ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error "
2177 "%u.", datasync ? "data" : "", vi->i_ino, -ret); 2184 "%u.", datasync ? "data" : "", vi->i_ino, -ret);
2185 mutex_unlock(&vi->i_mutex);
2178 return ret; 2186 return ret;
2179} 2187}
2180 2188
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 22d604601957..0fc2bd34039d 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -171,7 +171,8 @@ static int ocfs2_dir_release(struct inode *inode, struct file *file)
171 return 0; 171 return 0;
172} 172}
173 173
174static int ocfs2_sync_file(struct file *file, int datasync) 174static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end,
175 int datasync)
175{ 176{
176 int err = 0; 177 int err = 0;
177 journal_t *journal; 178 journal_t *journal;
@@ -184,6 +185,16 @@ static int ocfs2_sync_file(struct file *file, int datasync)
184 file->f_path.dentry->d_name.name, 185 file->f_path.dentry->d_name.name,
185 (unsigned long long)datasync); 186 (unsigned long long)datasync);
186 187
188 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
189 if (err)
190 return err;
191
192 /*
193 * Probably don't need the i_mutex at all in here, just putting it here
194 * to be consistent with how fsync used to be called, someone more
195 * familiar with the fs could possibly remove it.
196 */
197 mutex_lock(&inode->i_mutex);
187 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { 198 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) {
188 /* 199 /*
189 * We still have to flush drive's caches to get data to the 200 * We still have to flush drive's caches to get data to the
@@ -200,6 +211,7 @@ static int ocfs2_sync_file(struct file *file, int datasync)
200bail: 211bail:
201 if (err) 212 if (err)
202 mlog_errno(err); 213 mlog_errno(err);
214 mutex_unlock(&inode->i_mutex);
203 215
204 return (err < 0) ? -EIO : 0; 216 return (err < 0) ? -EIO : 0;
205} 217}
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 198dabf1b2bb..133e9355dc6f 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -14,7 +14,8 @@
14extern const struct reiserfs_key MIN_KEY; 14extern const struct reiserfs_key MIN_KEY;
15 15
16static int reiserfs_readdir(struct file *, void *, filldir_t); 16static int reiserfs_readdir(struct file *, void *, filldir_t);
17static int reiserfs_dir_fsync(struct file *filp, int datasync); 17static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
18 int datasync);
18 19
19const struct file_operations reiserfs_dir_operations = { 20const struct file_operations reiserfs_dir_operations = {
20 .llseek = generic_file_llseek, 21 .llseek = generic_file_llseek,
@@ -27,13 +28,21 @@ const struct file_operations reiserfs_dir_operations = {
27#endif 28#endif
28}; 29};
29 30
30static int reiserfs_dir_fsync(struct file *filp, int datasync) 31static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
32 int datasync)
31{ 33{
32 struct inode *inode = filp->f_mapping->host; 34 struct inode *inode = filp->f_mapping->host;
33 int err; 35 int err;
36
37 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
38 if (err)
39 return err;
40
41 mutex_lock(&inode->i_mutex);
34 reiserfs_write_lock(inode->i_sb); 42 reiserfs_write_lock(inode->i_sb);
35 err = reiserfs_commit_for_inode(inode); 43 err = reiserfs_commit_for_inode(inode);
36 reiserfs_write_unlock(inode->i_sb); 44 reiserfs_write_unlock(inode->i_sb);
45 mutex_unlock(&inode->i_mutex);
37 if (err < 0) 46 if (err < 0)
38 return err; 47 return err;
39 return 0; 48 return 0;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index bbf31003d308..c7156dc39ce7 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -140,12 +140,18 @@ static void reiserfs_vfs_truncate_file(struct inode *inode)
140 * be removed... 140 * be removed...
141 */ 141 */
142 142
143static int reiserfs_sync_file(struct file *filp, int datasync) 143static int reiserfs_sync_file(struct file *filp, loff_t start, loff_t end,
144 int datasync)
144{ 145{
145 struct inode *inode = filp->f_mapping->host; 146 struct inode *inode = filp->f_mapping->host;
146 int err; 147 int err;
147 int barrier_done; 148 int barrier_done;
148 149
150 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
151 if (err)
152 return err;
153
154 mutex_lock(&inode->i_mutex);
149 BUG_ON(!S_ISREG(inode->i_mode)); 155 BUG_ON(!S_ISREG(inode->i_mode));
150 err = sync_mapping_buffers(inode->i_mapping); 156 err = sync_mapping_buffers(inode->i_mapping);
151 reiserfs_write_lock(inode->i_sb); 157 reiserfs_write_lock(inode->i_sb);
@@ -153,6 +159,7 @@ static int reiserfs_sync_file(struct file *filp, int datasync)
153 reiserfs_write_unlock(inode->i_sb); 159 reiserfs_write_unlock(inode->i_sb);
154 if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb)) 160 if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb))
155 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 161 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
162 mutex_unlock(&inode->i_mutex);
156 if (barrier_done < 0) 163 if (barrier_done < 0)
157 return barrier_done; 164 return barrier_done;
158 return (err < 0) ? -EIO : 0; 165 return (err < 0) ? -EIO : 0;
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
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 5e7fccfc4b29..89ef9a2f7837 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1304,7 +1304,7 @@ static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd)
1304 return NULL; 1304 return NULL;
1305} 1305}
1306 1306
1307int ubifs_fsync(struct file *file, int datasync) 1307int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1308{ 1308{
1309 struct inode *inode = file->f_mapping->host; 1309 struct inode *inode = file->f_mapping->host;
1310 struct ubifs_info *c = inode->i_sb->s_fs_info; 1310 struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -1319,14 +1319,16 @@ int ubifs_fsync(struct file *file, int datasync)
1319 */ 1319 */
1320 return 0; 1320 return 0;
1321 1321
1322 /* 1322 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
1323 * VFS has already synchronized dirty pages for this inode. Synchronize 1323 if (err)
1324 * the inode unless this is a 'datasync()' call. 1324 return err;
1325 */ 1325 mutex_lock(&inode->i_mutex);
1326
1327 /* Synchronize the inode unless this is a 'datasync()' call. */
1326 if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) { 1328 if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) {
1327 err = inode->i_sb->s_op->write_inode(inode, NULL); 1329 err = inode->i_sb->s_op->write_inode(inode, NULL);
1328 if (err) 1330 if (err)
1329 return err; 1331 goto out;
1330 } 1332 }
1331 1333
1332 /* 1334 /*
@@ -1334,10 +1336,9 @@ int ubifs_fsync(struct file *file, int datasync)
1334 * them. 1336 * them.
1335 */ 1337 */
1336 err = ubifs_sync_wbufs_by_inode(c, inode); 1338 err = ubifs_sync_wbufs_by_inode(c, inode);
1337 if (err) 1339out:
1338 return err; 1340 mutex_unlock(&inode->i_mutex);
1339 1341 return err;
1340 return 0;
1341} 1342}
1342 1343
1343/** 1344/**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index f79983d6f860..4cd648501fa4 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1720,7 +1720,7 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);
1720int ubifs_calc_dark(const struct ubifs_info *c, int spc); 1720int ubifs_calc_dark(const struct ubifs_info *c, int spc);
1721 1721
1722/* file.c */ 1722/* file.c */
1723int ubifs_fsync(struct file *file, int datasync); 1723int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
1724int ubifs_setattr(struct dentry *dentry, struct iattr *attr); 1724int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
1725 1725
1726/* dir.c */ 1726/* dir.c */
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 7f782af286bf..fbbf657df0cd 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -127,6 +127,8 @@ xfs_iozero(
127STATIC int 127STATIC int
128xfs_file_fsync( 128xfs_file_fsync(
129 struct file *file, 129 struct file *file,
130 loff_t start,
131 loff_t end,
130 int datasync) 132 int datasync)
131{ 133{
132 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
@@ -138,6 +140,10 @@ xfs_file_fsync(
138 140
139 trace_xfs_file_fsync(ip); 141 trace_xfs_file_fsync(ip);
140 142
143 error = filemap_write_and_wait_range(inode->i_mapping, start, end);
144 if (error)
145 return error;
146
141 if (XFS_FORCED_SHUTDOWN(mp)) 147 if (XFS_FORCED_SHUTDOWN(mp))
142 return -XFS_ERROR(EIO); 148 return -XFS_ERROR(EIO);
143 149
@@ -875,18 +881,11 @@ xfs_file_aio_write(
875 /* Handle various SYNC-type writes */ 881 /* Handle various SYNC-type writes */
876 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 882 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
877 loff_t end = pos + ret - 1; 883 loff_t end = pos + ret - 1;
878 int error, error2;
879 884
880 xfs_rw_iunlock(ip, iolock); 885 xfs_rw_iunlock(ip, iolock);
881 error = filemap_write_and_wait_range(mapping, pos, end); 886 ret = -xfs_file_fsync(file, pos, end,
887 (file->f_flags & __O_SYNC) ? 0 : 1);
882 xfs_rw_ilock(ip, iolock); 888 xfs_rw_ilock(ip, iolock);
883
884 error2 = -xfs_file_fsync(file,
885 (file->f_flags & __O_SYNC) ? 0 : 1);
886 if (error)
887 ret = error;
888 else if (error2)
889 ret = error2;
890 } 889 }
891 890
892out_unlock: 891out_unlock:
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 5e06acf95d0f..0c473fd79acb 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -877,7 +877,7 @@ extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
877extern void ext3_htree_free_dir_info(struct dir_private_info *p); 877extern void ext3_htree_free_dir_info(struct dir_private_info *p);
878 878
879/* fsync.c */ 879/* fsync.c */
880extern int ext3_sync_file(struct file *, int); 880extern int ext3_sync_file(struct file *, loff_t, loff_t, int);
881 881
882/* hash.c */ 882/* hash.c */
883extern int ext3fs_dirhash(const char *name, int len, struct 883extern int ext3fs_dirhash(const char *name, int len, struct
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 6a8274877171..1d6836c498dd 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1043,7 +1043,8 @@ extern void fb_deferred_io_open(struct fb_info *info,
1043 struct inode *inode, 1043 struct inode *inode,
1044 struct file *file); 1044 struct file *file);
1045extern void fb_deferred_io_cleanup(struct fb_info *info); 1045extern void fb_deferred_io_cleanup(struct fb_info *info);
1046extern int fb_deferred_io_fsync(struct file *file, int datasync); 1046extern int fb_deferred_io_fsync(struct file *file, loff_t start,
1047 loff_t end, int datasync);
1047 1048
1048static inline bool fb_be_math(struct fb_info *info) 1049static inline bool fb_be_math(struct fb_info *info)
1049{ 1050{
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4a61f98823a6..9cd2075c4a39 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1572,7 +1572,7 @@ struct file_operations {
1572 int (*open) (struct inode *, struct file *); 1572 int (*open) (struct inode *, struct file *);
1573 int (*flush) (struct file *, fl_owner_t id); 1573 int (*flush) (struct file *, fl_owner_t id);
1574 int (*release) (struct inode *, struct file *); 1574 int (*release) (struct inode *, struct file *);
1575 int (*fsync) (struct file *, int datasync); 1575 int (*fsync) (struct file *, loff_t, loff_t, int datasync);
1576 int (*aio_fsync) (struct kiocb *, int datasync); 1576 int (*aio_fsync) (struct kiocb *, int datasync);
1577 int (*fasync) (int, struct file *, int); 1577 int (*fasync) (int, struct file *, int);
1578 int (*lock) (struct file *, int, struct file_lock *); 1578 int (*lock) (struct file *, int, struct file_lock *);
@@ -2360,7 +2360,8 @@ extern int generic_segment_checks(const struct iovec *iov,
2360/* fs/block_dev.c */ 2360/* fs/block_dev.c */
2361extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, 2361extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
2362 unsigned long nr_segs, loff_t pos); 2362 unsigned long nr_segs, loff_t pos);
2363extern int blkdev_fsync(struct file *filp, int datasync); 2363extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
2364 int datasync);
2364 2365
2365/* fs/splice.c */ 2366/* fs/splice.c */
2366extern ssize_t generic_file_splice_read(struct file *, loff_t *, 2367extern ssize_t generic_file_splice_read(struct file *, loff_t *,
@@ -2490,7 +2491,7 @@ extern int simple_link(struct dentry *, struct inode *, struct dentry *);
2490extern int simple_unlink(struct inode *, struct dentry *); 2491extern int simple_unlink(struct inode *, struct dentry *);
2491extern int simple_rmdir(struct inode *, struct dentry *); 2492extern int simple_rmdir(struct inode *, struct dentry *);
2492extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); 2493extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
2493extern int noop_fsync(struct file *, int); 2494extern int noop_fsync(struct file *, loff_t, loff_t, int);
2494extern int simple_empty(struct dentry *); 2495extern int simple_empty(struct dentry *);
2495extern int simple_readpage(struct file *file, struct page *page); 2496extern int simple_readpage(struct file *file, struct page *page);
2496extern int simple_write_begin(struct file *file, struct address_space *mapping, 2497extern int simple_write_begin(struct file *file, struct address_space *mapping,
@@ -2515,7 +2516,7 @@ extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
2515extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, 2516extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
2516 const void __user *from, size_t count); 2517 const void __user *from, size_t count);
2517 2518
2518extern int generic_file_fsync(struct file *, int); 2519extern int generic_file_fsync(struct file *, loff_t, loff_t, int);
2519 2520
2520extern int generic_check_addressable(unsigned, u64); 2521extern int generic_check_addressable(unsigned, u64);
2521 2522
diff --git a/ipc/shm.c b/ipc/shm.c
index ab3385a21b27..27884adb1a90 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -277,13 +277,13 @@ static int shm_release(struct inode *ino, struct file *file)
277 return 0; 277 return 0;
278} 278}
279 279
280static int shm_fsync(struct file *file, int datasync) 280static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync)
281{ 281{
282 struct shm_file_data *sfd = shm_file_data(file); 282 struct shm_file_data *sfd = shm_file_data(file);
283 283
284 if (!sfd->file->f_op->fsync) 284 if (!sfd->file->f_op->fsync)
285 return -EINVAL; 285 return -EINVAL;
286 return sfd->file->f_op->fsync(sfd->file, datasync); 286 return sfd->file->f_op->fsync(sfd->file, start, end, datasync);
287} 287}
288 288
289static unsigned long shm_get_unmapped_area(struct file *file, 289static unsigned long shm_get_unmapped_area(struct file *file,