aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/direct-io.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 27f3e787faca..235ed8d1f11e 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -129,6 +129,7 @@ struct dio {
129 /* AIO related stuff */ 129 /* AIO related stuff */
130 struct kiocb *iocb; /* kiocb */ 130 struct kiocb *iocb; /* kiocb */
131 int is_async; /* is IO async ? */ 131 int is_async; /* is IO async ? */
132 int io_error; /* IO error in completion path */
132 ssize_t result; /* IO result */ 133 ssize_t result; /* IO result */
133}; 134};
134 135
@@ -250,6 +251,10 @@ static void finished_one_bio(struct dio *dio)
250 ((offset + transferred) > dio->i_size)) 251 ((offset + transferred) > dio->i_size))
251 transferred = dio->i_size - offset; 252 transferred = dio->i_size - offset;
252 253
254 /* check for error in completion path */
255 if (dio->io_error)
256 transferred = dio->io_error;
257
253 dio_complete(dio, offset, transferred); 258 dio_complete(dio, offset, transferred);
254 259
255 /* Complete AIO later if falling back to buffered i/o */ 260 /* Complete AIO later if falling back to buffered i/o */
@@ -406,7 +411,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
406 int page_no; 411 int page_no;
407 412
408 if (!uptodate) 413 if (!uptodate)
409 dio->result = -EIO; 414 dio->io_error = -EIO;
410 415
411 if (dio->is_async && dio->rw == READ) { 416 if (dio->is_async && dio->rw == READ) {
412 bio_check_pages_dirty(bio); /* transfers ownership */ 417 bio_check_pages_dirty(bio); /* transfers ownership */
@@ -971,6 +976,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
971 dio->next_block_for_io = -1; 976 dio->next_block_for_io = -1;
972 977
973 dio->page_errors = 0; 978 dio->page_errors = 0;
979 dio->io_error = 0;
974 dio->result = 0; 980 dio->result = 0;
975 dio->iocb = iocb; 981 dio->iocb = iocb;
976 dio->i_size = i_size_read(inode); 982 dio->i_size = i_size_read(inode);