ARM: OMAP2+: Fix oops with LPAE and more than 2GB of memory
[firefly-linux-kernel-4.4.55.git] / fs / direct-io.c
index 745d2342651a0b87fcb9dd5b5b50e95b9129e117..11256291642e5df1f66fd1880109cf7c260796cc 100644 (file)
@@ -285,7 +285,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio);
 /*
  * Asynchronous IO callback. 
  */
-static void dio_bio_end_aio(struct bio *bio, int error)
+static void dio_bio_end_aio(struct bio *bio)
 {
        struct dio *dio = bio->bi_private;
        unsigned long remaining;
@@ -318,7 +318,7 @@ static void dio_bio_end_aio(struct bio *bio, int error)
  * During I/O bi_private points at the dio.  After I/O, bi_private is used to
  * implement a singly-linked list of completed BIOs, at dio->bio_list.
  */
-static void dio_bio_end_io(struct bio *bio, int error)
+static void dio_bio_end_io(struct bio *bio)
 {
        struct dio *dio = bio->bi_private;
        unsigned long flags;
@@ -345,9 +345,9 @@ void dio_end_io(struct bio *bio, int error)
        struct dio *dio = bio->bi_private;
 
        if (dio->is_async)
-               dio_bio_end_aio(bio, error);
+               dio_bio_end_aio(bio);
        else
-               dio_bio_end_io(bio, error);
+               dio_bio_end_io(bio);
 }
 EXPORT_SYMBOL_GPL(dio_end_io);
 
@@ -457,15 +457,16 @@ static struct bio *dio_await_one(struct dio *dio)
  */
 static int dio_bio_complete(struct dio *dio, struct bio *bio)
 {
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        struct bio_vec *bvec;
        unsigned i;
+       int err;
 
-       if (!uptodate)
+       if (bio->bi_error)
                dio->io_error = -EIO;
 
        if (dio->is_async && dio->rw == READ) {
                bio_check_pages_dirty(bio);     /* transfers ownership */
+               err = bio->bi_error;
        } else {
                bio_for_each_segment_all(bvec, bio, i) {
                        struct page *page = bvec->bv_page;
@@ -474,9 +475,10 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
                                set_page_dirty_lock(page);
                        page_cache_release(page);
                }
+               err = bio->bi_error;
                bio_put(bio);
        }
-       return uptodate ? 0 : -EIO;
+       return err;
 }
 
 /*
@@ -653,7 +655,7 @@ static inline int dio_new_bio(struct dio *dio, struct dio_submit *sdio,
        if (ret)
                goto out;
        sector = start_sector << (sdio->blkbits - 9);
-       nr_pages = min(sdio->pages_in_io, bio_get_nr_vecs(map_bh->b_bdev));
+       nr_pages = min(sdio->pages_in_io, BIO_MAX_PAGES);
        BUG_ON(nr_pages <= 0);
        dio_bio_alloc(dio, sdio, map_bh->b_bdev, sector, nr_pages);
        sdio->boundary = 0;