aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/btrfs/file.c2
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/direct-io.c45
-rw-r--r--fs/ext4/file.c2
-rw-r--r--mm/filemap.c2
6 files changed, 41 insertions, 14 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index c7bda5cd3da7..1173a4ee0830 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1519,7 +1519,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
1519 1519
1520 blk_start_plug(&plug); 1520 blk_start_plug(&plug);
1521 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 1521 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
1522 if (ret > 0 || ret == -EIOCBQUEUED) { 1522 if (ret > 0) {
1523 ssize_t err; 1523 ssize_t err;
1524 1524
1525 err = generic_write_sync(file, pos, ret); 1525 err = generic_write_sync(file, pos, ret);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 8e686a427ce2..4d2eb6417145 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1727,7 +1727,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1727 */ 1727 */
1728 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; 1728 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
1729 BTRFS_I(inode)->last_sub_trans = root->log_transid; 1729 BTRFS_I(inode)->last_sub_trans = root->log_transid;
1730 if (num_written > 0 || num_written == -EIOCBQUEUED) { 1730 if (num_written > 0) {
1731 err = generic_write_sync(file, pos, num_written); 1731 err = generic_write_sync(file, pos, num_written);
1732 if (err < 0 && num_written > 0) 1732 if (err < 0 && num_written > 0)
1733 num_written = err; 1733 num_written = err;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7e36ae34e947..9d0dd952ad79 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2553,7 +2553,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
2553 mutex_unlock(&inode->i_mutex); 2553 mutex_unlock(&inode->i_mutex);
2554 } 2554 }
2555 2555
2556 if (rc > 0 || rc == -EIOCBQUEUED) { 2556 if (rc > 0) {
2557 ssize_t err; 2557 ssize_t err;
2558 2558
2559 err = generic_write_sync(file, pos, rc); 2559 err = generic_write_sync(file, pos, rc);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 8b31b9f449f4..1782023bd68a 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -266,8 +266,18 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret,
266 dio->end_io(dio->iocb, offset, transferred, dio->private); 266 dio->end_io(dio->iocb, offset, transferred, dio->private);
267 267
268 inode_dio_done(dio->inode); 268 inode_dio_done(dio->inode);
269 if (is_async) 269 if (is_async) {
270 if (dio->rw & WRITE) {
271 int err;
272
273 err = generic_write_sync(dio->iocb->ki_filp, offset,
274 transferred);
275 if (err < 0 && ret > 0)
276 ret = err;
277 }
278
270 aio_complete(dio->iocb, ret, 0); 279 aio_complete(dio->iocb, ret, 0);
280 }
271 281
272 kmem_cache_free(dio_cache, dio); 282 kmem_cache_free(dio_cache, dio);
273 return ret; 283 return ret;
@@ -1183,11 +1193,6 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1183 } 1193 }
1184 1194
1185 /* 1195 /*
1186 * Will be decremented at I/O completion time.
1187 */
1188 atomic_inc(&inode->i_dio_count);
1189
1190 /*
1191 * For file extending writes updating i_size before data 1196 * For file extending writes updating i_size before data
1192 * writeouts complete can expose uninitialized blocks. So 1197 * writeouts complete can expose uninitialized blocks. So
1193 * even for AIO, we need to wait for i/o to complete before 1198 * even for AIO, we need to wait for i/o to complete before
@@ -1195,11 +1200,33 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1195 */ 1200 */
1196 dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) && 1201 dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) &&
1197 (end > i_size_read(inode))); 1202 (end > i_size_read(inode)));
1198
1199 retval = 0;
1200
1201 dio->inode = inode; 1203 dio->inode = inode;
1202 dio->rw = rw; 1204 dio->rw = rw;
1205
1206 /*
1207 * For AIO O_(D)SYNC writes we need to defer completions to a workqueue
1208 * so that we can call ->fsync.
1209 */
1210 if (dio->is_async && (rw & WRITE) &&
1211 ((iocb->ki_filp->f_flags & O_DSYNC) ||
1212 IS_SYNC(iocb->ki_filp->f_mapping->host))) {
1213 retval = dio_set_defer_completion(dio);
1214 if (retval) {
1215 /*
1216 * We grab i_mutex only for reads so we don't have
1217 * to release it here
1218 */
1219 kmem_cache_free(dio_cache, dio);
1220 goto out;
1221 }
1222 }
1223
1224 /*
1225 * Will be decremented at I/O completion time.
1226 */
1227 atomic_inc(&inode->i_dio_count);
1228
1229 retval = 0;
1203 sdio.blkbits = blkbits; 1230 sdio.blkbits = blkbits;
1204 sdio.blkfactor = i_blkbits - blkbits; 1231 sdio.blkfactor = i_blkbits - blkbits;
1205 sdio.block_in_file = offset >> blkbits; 1232 sdio.block_in_file = offset >> blkbits;
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 319c9d26279a..3da21945ff1f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -149,7 +149,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
149 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 149 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
150 mutex_unlock(&inode->i_mutex); 150 mutex_unlock(&inode->i_mutex);
151 151
152 if (ret > 0 || ret == -EIOCBQUEUED) { 152 if (ret > 0) {
153 ssize_t err; 153 ssize_t err;
154 154
155 err = generic_write_sync(file, pos, ret); 155 err = generic_write_sync(file, pos, ret);
diff --git a/mm/filemap.c b/mm/filemap.c
index 4b51ac1acae7..731a2c24532d 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2550,7 +2550,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2550 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); 2550 ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
2551 mutex_unlock(&inode->i_mutex); 2551 mutex_unlock(&inode->i_mutex);
2552 2552
2553 if (ret > 0 || ret == -EIOCBQUEUED) { 2553 if (ret > 0) {
2554 ssize_t err; 2554 ssize_t err;
2555 2555
2556 err = generic_write_sync(file, pos, ret); 2556 err = generic_write_sync(file, pos, ret);