aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-06-24 14:29:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 20:47:50 -0400
commit72c5052ddc3956d847f21c2b8d55c93664a51b2c (patch)
tree47b381f3f746cdc1612f432bd902278f8901f84a /fs
parentaacfc19c626ebd3daa675652457d71019a1f583f (diff)
fs: move inode_dio_done to the end_io handler
For filesystems that delay their end_io processing we should keep our i_dio_count until the the processing is done. Enable this by moving the inode_dio_done call to the end_io handler if one exist. Note that the actual move to the workqueue for ext4 and XFS is not done in this patch yet, but left to the filesystem maintainers. At least for XFS it's not needed yet either as XFS has an internal equivalent to i_dio_count. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/direct-io.c7
-rw-r--r--fs/ext4/inode.c5
-rw-r--r--fs/ocfs2/aops.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c3
4 files changed, 13 insertions, 3 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 0a073c7125a6..01d2d9ef609c 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -293,11 +293,12 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, bool is
293 if (dio->end_io && dio->result) { 293 if (dio->end_io && dio->result) {
294 dio->end_io(dio->iocb, offset, transferred, 294 dio->end_io(dio->iocb, offset, transferred,
295 dio->map_bh.b_private, ret, is_async); 295 dio->map_bh.b_private, ret, is_async);
296 } else if (is_async) { 296 } else {
297 aio_complete(dio->iocb, ret, 0); 297 if (is_async)
298 aio_complete(dio->iocb, ret, 0);
299 inode_dio_done(dio->inode);
298 } 300 }
299 301
300 inode_dio_done(dio->inode);
301 return ret; 302 return ret;
302} 303}
303 304
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1f35573a34e1..678cde834f19 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3573,6 +3573,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
3573 ssize_t size, void *private, int ret, 3573 ssize_t size, void *private, int ret,
3574 bool is_async) 3574 bool is_async)
3575{ 3575{
3576 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
3576 ext4_io_end_t *io_end = iocb->private; 3577 ext4_io_end_t *io_end = iocb->private;
3577 struct workqueue_struct *wq; 3578 struct workqueue_struct *wq;
3578 unsigned long flags; 3579 unsigned long flags;
@@ -3594,6 +3595,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
3594out: 3595out:
3595 if (is_async) 3596 if (is_async)
3596 aio_complete(iocb, ret, 0); 3597 aio_complete(iocb, ret, 0);
3598 inode_dio_done(inode);
3597 return; 3599 return;
3598 } 3600 }
3599 3601
@@ -3614,6 +3616,9 @@ out:
3614 /* queue the work to convert unwritten extents to written */ 3616 /* queue the work to convert unwritten extents to written */
3615 queue_work(wq, &io_end->work); 3617 queue_work(wq, &io_end->work);
3616 iocb->private = NULL; 3618 iocb->private = NULL;
3619
3620 /* XXX: probably should move into the real I/O completion handler */
3621 inode_dio_done(inode);
3617} 3622}
3618 3623
3619static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) 3624static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 524d6167fb63..c1efe939c774 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -577,6 +577,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
577 577
578 if (is_async) 578 if (is_async)
579 aio_complete(iocb, ret, 0); 579 aio_complete(iocb, ret, 0);
580 inode_dio_done(inode);
580} 581}
581 582
582/* 583/*
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 79ce38be15a1..b3b418f519f3 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1339,6 +1339,9 @@ xfs_end_io_direct_write(
1339 } else { 1339 } else {
1340 xfs_finish_ioend_sync(ioend); 1340 xfs_finish_ioend_sync(ioend);
1341 } 1341 }
1342
1343 /* XXX: probably should move into the real I/O completion handler */
1344 inode_dio_done(ioend->io_inode);
1342} 1345}
1343 1346
1344STATIC ssize_t 1347STATIC ssize_t