aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,