aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/block_dev.c8
-rw-r--r--fs/btrfs/file.c7
-rw-r--r--fs/cifs/file.c7
-rw-r--r--fs/direct-io.c17
-rw-r--r--fs/ext4/file.c9
-rw-r--r--fs/f2fs/file.c9
-rw-r--r--fs/nfs/direct.c4
-rw-r--r--fs/ntfs/file.c7
-rw-r--r--fs/udf/file.c4
-rw-r--r--fs/xfs/xfs_file.c6
-rw-r--r--include/linux/fs.h24
-rw-r--r--mm/filemap.c9
12 files changed, 46 insertions, 65 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d8dc3512e927..a063d4d8ac39 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1660,12 +1660,8 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
1660 1660
1661 blk_start_plug(&plug); 1661 blk_start_plug(&plug);
1662 ret = __generic_file_write_iter(iocb, from); 1662 ret = __generic_file_write_iter(iocb, from);
1663 if (ret > 0) { 1663 if (ret > 0)
1664 ssize_t err; 1664 ret = generic_write_sync(iocb, ret);
1665 err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
1666 if (err < 0)
1667 ret = err;
1668 }
1669 blk_finish_plug(&plug); 1665 blk_finish_plug(&plug);
1670 return ret; 1666 return ret;
1671} 1667}
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 35ce146cceec..ea9f10bb089c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1851,11 +1851,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
1851 spin_lock(&BTRFS_I(inode)->lock); 1851 spin_lock(&BTRFS_I(inode)->lock);
1852 BTRFS_I(inode)->last_sub_trans = root->log_transid; 1852 BTRFS_I(inode)->last_sub_trans = root->log_transid;
1853 spin_unlock(&BTRFS_I(inode)->lock); 1853 spin_unlock(&BTRFS_I(inode)->lock);
1854 if (num_written > 0) { 1854 if (num_written > 0)
1855 err = generic_write_sync(iocb, pos, num_written); 1855 num_written = generic_write_sync(iocb, num_written);
1856 if (err < 0)
1857 num_written = err;
1858 }
1859 1856
1860 if (sync) 1857 if (sync)
1861 atomic_dec(&BTRFS_I(inode)->sync_writers); 1858 atomic_dec(&BTRFS_I(inode)->sync_writers);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index b22b68ccfbe5..9b51d4936a29 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2687,11 +2687,8 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
2687out: 2687out:
2688 inode_unlock(inode); 2688 inode_unlock(inode);
2689 2689
2690 if (rc > 0) { 2690 if (rc > 0)
2691 ssize_t err = generic_write_sync(iocb, iocb->ki_pos - rc, rc); 2691 rc = generic_write_sync(iocb, rc);
2692 if (err < 0)
2693 rc = err;
2694 }
2695 up_read(&cinode->lock_sem); 2692 up_read(&cinode->lock_sem);
2696 return rc; 2693 return rc;
2697} 2694}
diff --git a/fs/direct-io.c b/fs/direct-io.c
index f7bcc0193dee..3bf3f20f8ecc 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -256,6 +256,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
256 if (dio->end_io) { 256 if (dio->end_io) {
257 int err; 257 int err;
258 258
259 // XXX: ki_pos??
259 err = dio->end_io(dio->iocb, offset, ret, dio->private); 260 err = dio->end_io(dio->iocb, offset, ret, dio->private);
260 if (err) 261 if (err)
261 ret = err; 262 ret = err;
@@ -265,15 +266,15 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
265 inode_dio_end(dio->inode); 266 inode_dio_end(dio->inode);
266 267
267 if (is_async) { 268 if (is_async) {
268 if (dio->rw & WRITE) { 269 /*
269 int err; 270 * generic_write_sync expects ki_pos to have been updated
270 271 * already, but the submission path only does this for
271 err = generic_write_sync(dio->iocb, offset, 272 * synchronous I/O.
272 transferred); 273 */
273 if (err < 0 && ret > 0) 274 dio->iocb->ki_pos += transferred;
274 ret = err;
275 }
276 275
276 if (dio->rw & WRITE)
277 ret = generic_write_sync(dio->iocb, transferred);
277 dio->iocb->ki_complete(dio->iocb, ret, 0); 278 dio->iocb->ki_complete(dio->iocb, ret, 0);
278 } 279 }
279 280
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 1417e129be51..00ff6912adb3 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -169,13 +169,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
169 ret = __generic_file_write_iter(iocb, from); 169 ret = __generic_file_write_iter(iocb, from);
170 inode_unlock(inode); 170 inode_unlock(inode);
171 171
172 if (ret > 0) { 172 if (ret > 0)
173 ssize_t err; 173 ret = generic_write_sync(iocb, ret);
174
175 err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
176 if (err < 0)
177 ret = err;
178 }
179 if (o_direct) 174 if (o_direct)
180 blk_finish_plug(&plug); 175 blk_finish_plug(&plug);
181 176
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 51ed8388e66c..28f75a1fe4a7 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1882,13 +1882,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1882 } 1882 }
1883 inode_unlock(inode); 1883 inode_unlock(inode);
1884 1884
1885 if (ret > 0) { 1885 if (ret > 0)
1886 ssize_t err; 1886 ret = generic_write_sync(iocb, ret);
1887
1888 err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
1889 if (err < 0)
1890 ret = err;
1891 }
1892 return ret; 1887 return ret;
1893} 1888}
1894 1889
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index be86de9a77d7..0b9fca040b0c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -1054,7 +1054,9 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
1054 if (i_size_read(inode) < iocb->ki_pos) 1054 if (i_size_read(inode) < iocb->ki_pos)
1055 i_size_write(inode, iocb->ki_pos); 1055 i_size_write(inode, iocb->ki_pos);
1056 spin_unlock(&inode->i_lock); 1056 spin_unlock(&inode->i_lock);
1057 generic_write_sync(iocb, pos, result); 1057
1058 /* XXX: should check the generic_write_sync retval */
1059 generic_write_sync(iocb, result);
1058 } 1060 }
1059 } 1061 }
1060 nfs_direct_req_release(dreq); 1062 nfs_direct_req_release(dreq);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 10dc38cc02bb..5622ed5a201e 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1952,12 +1952,9 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1952 written = ntfs_perform_write(file, from, iocb->ki_pos); 1952 written = ntfs_perform_write(file, from, iocb->ki_pos);
1953 current->backing_dev_info = NULL; 1953 current->backing_dev_info = NULL;
1954 inode_unlock(vi); 1954 inode_unlock(vi);
1955 if (likely(written > 0)) {
1956 err = generic_write_sync(iocb, iocb->ki_pos, written);
1957 if (err < 0)
1958 written = 0;
1959 }
1960 iocb->ki_pos += written; 1955 iocb->ki_pos += written;
1956 if (likely(written > 0))
1957 written = generic_write_sync(iocb, written);
1961 return written ? written : err; 1958 return written ? written : err;
1962} 1959}
1963 1960
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 8e3d1ae53b11..632570617327 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -152,9 +152,7 @@ out:
152 152
153 if (retval > 0) { 153 if (retval > 0) {
154 mark_inode_dirty(inode); 154 mark_inode_dirty(inode);
155 err = generic_write_sync(iocb, iocb->ki_pos - retval, retval); 155 retval = generic_write_sync(iocb, retval);
156 if (err < 0)
157 retval = err;
158 } 156 }
159 157
160 return retval; 158 return retval;
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index b5d70e77195d..cd3540997d65 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -903,14 +903,10 @@ xfs_file_write_iter(
903 ret = xfs_file_buffered_aio_write(iocb, from); 903 ret = xfs_file_buffered_aio_write(iocb, from);
904 904
905 if (ret > 0) { 905 if (ret > 0) {
906 ssize_t err;
907
908 XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret); 906 XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret);
909 907
910 /* Handle various SYNC-type writes */ 908 /* Handle various SYNC-type writes */
911 err = generic_write_sync(iocb, iocb->ki_pos - ret, ret); 909 ret = generic_write_sync(iocb, ret);
912 if (err < 0)
913 ret = err;
914 } 910 }
915 return ret; 911 return ret;
916} 912}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 310ca1ed9293..f6a8ed864651 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2487,13 +2487,25 @@ extern int filemap_fdatawrite_range(struct address_space *mapping,
2487extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end, 2487extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
2488 int datasync); 2488 int datasync);
2489extern int vfs_fsync(struct file *file, int datasync); 2489extern int vfs_fsync(struct file *file, int datasync);
2490static inline int generic_write_sync(struct kiocb *iocb, loff_t pos, loff_t count) 2490
2491{ 2491/*
2492 if (!(iocb->ki_flags & IOCB_DSYNC)) 2492 * Sync the bytes written if this was a synchronous write. Expect ki_pos
2493 return 0; 2493 * to already be updated for the write, and will return either the amount
2494 return vfs_fsync_range(iocb->ki_filp, pos, pos + count - 1, 2494 * of bytes passed in, or an error if syncing the file failed.
2495 (iocb->ki_flags & IOCB_SYNC) ? 0 : 1); 2495 */
2496static inline ssize_t generic_write_sync(struct kiocb *iocb, ssize_t count)
2497{
2498 if (iocb->ki_flags & IOCB_DSYNC) {
2499 int ret = vfs_fsync_range(iocb->ki_filp,
2500 iocb->ki_pos - count, iocb->ki_pos - 1,
2501 (iocb->ki_flags & IOCB_SYNC) ? 0 : 1);
2502 if (ret)
2503 return ret;
2504 }
2505
2506 return count;
2496} 2507}
2508
2497extern void emergency_sync(void); 2509extern void emergency_sync(void);
2498extern void emergency_remount(void); 2510extern void emergency_remount(void);
2499#ifdef CONFIG_BLOCK 2511#ifdef CONFIG_BLOCK
diff --git a/mm/filemap.c b/mm/filemap.c
index 8345d6d3436a..182b21825255 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2791,13 +2791,8 @@ ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
2791 ret = __generic_file_write_iter(iocb, from); 2791 ret = __generic_file_write_iter(iocb, from);
2792 inode_unlock(inode); 2792 inode_unlock(inode);
2793 2793
2794 if (ret > 0) { 2794 if (ret > 0)
2795 ssize_t err; 2795 ret = generic_write_sync(iocb, ret);
2796
2797 err = generic_write_sync(iocb, iocb->ki_pos - ret, ret);
2798 if (err < 0)
2799 ret = err;
2800 }
2801 return ret; 2796 return ret;
2802} 2797}
2803EXPORT_SYMBOL(generic_file_write_iter); 2798EXPORT_SYMBOL(generic_file_write_iter);