Skip to content

Commit

Permalink
fs: move inode_dio_done to the end_io handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Jul 21, 2011
1 parent aacfc19 commit 72c5052
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 3 deletions.
7 changes: 4 additions & 3 deletions fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,12 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, bool is
if (dio->end_io && dio->result) {
dio->end_io(dio->iocb, offset, transferred,
dio->map_bh.b_private, ret, is_async);
} else if (is_async) {
aio_complete(dio->iocb, ret, 0);
} else {
if (is_async)
aio_complete(dio->iocb, ret, 0);
inode_dio_done(dio->inode);
}

inode_dio_done(dio->inode);
return ret;
}

Expand Down
5 changes: 5 additions & 0 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3573,6 +3573,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
ssize_t size, void *private, int ret,
bool is_async)
{
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
ext4_io_end_t *io_end = iocb->private;
struct workqueue_struct *wq;
unsigned long flags;
Expand All @@ -3594,6 +3595,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
out:
if (is_async)
aio_complete(iocb, ret, 0);
inode_dio_done(inode);
return;
}

Expand All @@ -3614,6 +3616,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
/* queue the work to convert unwritten extents to written */
queue_work(wq, &io_end->work);
iocb->private = NULL;

/* XXX: probably should move into the real I/O completion handler */
inode_dio_done(inode);
}

static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
Expand Down
1 change: 1 addition & 0 deletions fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,

if (is_async)
aio_complete(iocb, ret, 0);
inode_dio_done(inode);
}

/*
Expand Down
3 changes: 3 additions & 0 deletions fs/xfs/linux-2.6/xfs_aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,9 @@ xfs_end_io_direct_write(
} else {
xfs_finish_ioend_sync(ioend);
}

/* XXX: probably should move into the real I/O completion handler */
inode_dio_done(ioend->io_inode);
}

STATIC ssize_t
Expand Down

0 comments on commit 72c5052

Please sign in to comment.