summaryrefslogtreecommitdiff
path: root/fs/direct-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r--fs/direct-io.c17
1 files changed, 9 insertions, 8 deletions
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)
if (dio->end_io) {
int err;
+ // XXX: ki_pos??
err = dio->end_io(dio->iocb, offset, ret, dio->private);
if (err)
ret = err;
@@ -265,15 +266,15 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
inode_dio_end(dio->inode);
if (is_async) {
- if (dio->rw & WRITE) {
- int err;
-
- err = generic_write_sync(dio->iocb, offset,
- transferred);
- if (err < 0 && ret > 0)
- ret = err;
- }
+ /*
+ * generic_write_sync expects ki_pos to have been updated
+ * already, but the submission path only does this for
+ * synchronous I/O.
+ */
+ dio->iocb->ki_pos += transferred;
+ if (dio->rw & WRITE)
+ ret = generic_write_sync(dio->iocb, transferred);
dio->iocb->ki_complete(dio->iocb, ret, 0);
}