]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/direct-io.c
[PATCH] direct-io: bug fix in dio handling write error
[karo-tx-linux.git] / fs / direct-io.c
index 27f3e787facaff34b29f28ed6830148a843ffbdb..235ed8d1f11e3b41cb332713108ca53ca063245a 100644 (file)
@@ -129,6 +129,7 @@ struct dio {
        /* AIO related stuff */
        struct kiocb *iocb;             /* kiocb */
        int is_async;                   /* is IO async ? */
+       int io_error;                   /* IO error in completion path */
        ssize_t result;                 /* IO result */
 };
 
@@ -250,6 +251,10 @@ static void finished_one_bio(struct dio *dio)
                            ((offset + transferred) > dio->i_size))
                                transferred = dio->i_size - offset;
 
+                       /* check for error in completion path */
+                       if (dio->io_error)
+                               transferred = dio->io_error;
+
                        dio_complete(dio, offset, transferred);
 
                        /* 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)
        int page_no;
 
        if (!uptodate)
-               dio->result = -EIO;
+               dio->io_error = -EIO;
 
        if (dio->is_async && dio->rw == READ) {
                bio_check_pages_dirty(bio);     /* transfers ownership */
@@ -971,6 +976,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
        dio->next_block_for_io = -1;
 
        dio->page_errors = 0;
+       dio->io_error = 0;
        dio->result = 0;
        dio->iocb = iocb;
        dio->i_size = i_size_read(inode);