aboutsummaryrefslogtreecommitdiffstats
path: root/fs/direct-io.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-09-04 09:04:40 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-09-04 09:23:46 -0400
commit02afc27faec94c9e068517a22acf55400976c698 (patch)
tree45de9689088ea99e1197c3f20f08cb9835a66410 /fs/direct-io.c
parent7b7a8665edd8db733980389b098530f9e4f630b2 (diff)
direct-io: Handle O_(D)SYNC AIO
Call generic_write_sync() from the deferred I/O completion handler if O_DSYNC is set for a write request. Also make sure various callers don't call generic_write_sync if the direct I/O code returns -EIOCBQUEUED. Based on an earlier patch from Jan Kara <jack@suse.cz> with updates from Jeff Moyer <jmoyer@redhat.com> and Darrick J. Wong <darrick.wong@oracle.com>. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r--fs/direct-io.c45
1 files changed, 36 insertions, 9 deletions
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;