Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / fs / mpage.c
index 94a6ba0..0face1c 100644 (file)
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/kdev_t.h>
+#include <linux/gfp.h>
 #include <linux/bio.h>
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
@@ -26,7 +27,7 @@
 #include <linux/writeback.h>
 #include <linux/backing-dev.h>
 #include <linux/pagevec.h>
-#include <linux/precache.h>
+#include <linux/cleancache.h>
 
 /*
  * I/O completion handler for multipage BIOs.
@@ -40,7 +41,7 @@
  * status of that page is hard.  See end_buffer_async_read() for the details.
  * There is no point in duplicating all that complexity.
  */
-static void mpage_end_io_read(struct bio *bio, int err)
+static void mpage_end_io(struct bio *bio, int err)
 {
        const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
        struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
@@ -50,44 +51,29 @@ static void mpage_end_io_read(struct bio *bio, int err)
 
                if (--bvec >= bio->bi_io_vec)
                        prefetchw(&bvec->bv_page->flags);
-
-               if (uptodate) {
-                       SetPageUptodate(page);
-               } else {
-                       ClearPageUptodate(page);
-                       SetPageError(page);
-               }
-               unlock_page(page);
-       } while (bvec >= bio->bi_io_vec);
-       bio_put(bio);
-}
-
-static void mpage_end_io_write(struct bio *bio, int err)
-{
-       const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-
-       do {
-               struct page *page = bvec->bv_page;
-
-               if (--bvec >= bio->bi_io_vec)
-                       prefetchw(&bvec->bv_page->flags);
-
-               if (!uptodate){
-                       SetPageError(page);
-                       if (page->mapping)
-                               set_bit(AS_EIO, &page->mapping->flags);
+               if (bio_data_dir(bio) == READ) {
+                       if (uptodate) {
+                               SetPageUptodate(page);
+                       } else {
+                               ClearPageUptodate(page);
+                               SetPageError(page);
+                       }
+                       unlock_page(page);
+               } else { /* bio_data_dir(bio) == WRITE */
+                       if (!uptodate) {
+                               SetPageError(page);
+                               if (page->mapping)
+                                       set_bit(AS_EIO, &page->mapping->flags);
+                       }
+                       end_page_writeback(page);
                }
-               end_page_writeback(page);
        } while (bvec >= bio->bi_io_vec);
        bio_put(bio);
 }
 
 static struct bio *mpage_bio_submit(int rw, struct bio *bio)
 {
-       bio->bi_end_io = mpage_end_io_read;
-       if (rw == WRITE)
-               bio->bi_end_io = mpage_end_io_write;
+       bio->bi_end_io = mpage_end_io;
        submit_bio(rw, bio);
        return NULL;
 }
@@ -286,9 +272,8 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
                SetPageMappedToDisk(page);
        }
 
-       if (fully_mapped &&
-           blocks_per_page == 1 && !PageUptodate(page) &&
-           precache_get(page->mapping, page->index, page) == 1) {
+       if (fully_mapped && blocks_per_page == 1 && !PageUptodate(page) &&
+           cleancache_get_page(page) == 0) {
                SetPageUptodate(page);
                goto confused;
        }
@@ -569,7 +554,7 @@ page_is_mapped:
        if (page->index >= end_index) {
                /*
                 * The page straddles i_size.  It must be zeroed out on each
-                * and every writepage invokation because it may be mmapped.
+                * and every writepage invocation because it may be mmapped.
                 * "A file is mapped in multiples of the page size.  For a file
                 * that is not a multiple of the page size, the remaining memory
                 * is zeroed when mapped, and writes to that region are not
@@ -688,8 +673,11 @@ int
 mpage_writepages(struct address_space *mapping,
                struct writeback_control *wbc, get_block_t get_block)
 {
+       struct blk_plug plug;
        int ret;
 
+       blk_start_plug(&plug);
+
        if (!get_block)
                ret = generic_writepages(mapping, wbc);
        else {
@@ -704,6 +692,7 @@ mpage_writepages(struct address_space *mapping,
                if (mpd.bio)
                        mpage_bio_submit(WRITE, mpd.bio);
        }
+       blk_finish_plug(&plug);
        return ret;
 }
 EXPORT_SYMBOL(mpage_writepages);