Merge tag 'folio-6.0' of git://git.infradead.org/users/willy/pagecache
[linux-2.6-microblaze.git] / fs / mpage.c
index c6d8bf8..0f8ae95 100644 (file)
@@ -75,26 +75,28 @@ static struct bio *mpage_bio_submit(struct bio *bio)
  * them.  So when the buffer is up to date and the page size == block size,
  * this marks the page up to date instead of adding new buffers.
  */
-static void 
-map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block) 
+static void map_buffer_to_folio(struct folio *folio, struct buffer_head *bh,
+               int page_block)
 {
-       struct inode *inode = page->mapping->host;
+       struct inode *inode = folio->mapping->host;
        struct buffer_head *page_bh, *head;
        int block = 0;
 
-       if (!page_has_buffers(page)) {
+       head = folio_buffers(folio);
+       if (!head) {
                /*
                 * don't make any buffers if there is only one buffer on
-                * the page and the page just needs to be set up to date
+                * the folio and the folio just needs to be set up to date
                 */
                if (inode->i_blkbits == PAGE_SHIFT &&
                    buffer_uptodate(bh)) {
-                       SetPageUptodate(page);    
+                       folio_mark_uptodate(folio);
                        return;
                }
-               create_empty_buffers(page, i_blocksize(inode), 0);
+               create_empty_buffers(&folio->page, i_blocksize(inode), 0);
+               head = folio_buffers(folio);
        }
-       head = page_buffers(page);
+
        page_bh = head;
        do {
                if (block == page_block) {
@@ -110,7 +112,7 @@ map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block)
 
 struct mpage_readpage_args {
        struct bio *bio;
-       struct page *page;
+       struct folio *folio;
        unsigned int nr_pages;
        bool is_readahead;
        sector_t last_block_in_bio;
@@ -130,8 +132,8 @@ struct mpage_readpage_args {
  */
 static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
 {
-       struct page *page = args->page;
-       struct inode *inode = page->mapping->host;
+       struct folio *folio = args->folio;
+       struct inode *inode = folio->mapping->host;
        const unsigned blkbits = inode->i_blkbits;
        const unsigned blocks_per_page = PAGE_SIZE >> blkbits;
        const unsigned blocksize = 1 << blkbits;
@@ -148,17 +150,20 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
        blk_opf_t opf = REQ_OP_READ;
        unsigned nblocks;
        unsigned relative_block;
-       gfp_t gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL);
+       gfp_t gfp = mapping_gfp_constraint(folio->mapping, GFP_KERNEL);
+
+       /* MAX_BUF_PER_PAGE, for example */
+       VM_BUG_ON_FOLIO(folio_test_large(folio), folio);
 
        if (args->is_readahead) {
                opf |= REQ_RAHEAD;
                gfp |= __GFP_NORETRY | __GFP_NOWARN;
        }
 
-       if (page_has_buffers(page))
+       if (folio_buffers(folio))
                goto confused;
 
-       block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits);
+       block_in_file = (sector_t)folio->index << (PAGE_SHIFT - blkbits);
        last_block = block_in_file + args->nr_pages * blocks_per_page;
        last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits;
        if (last_block > last_block_in_file)
@@ -191,9 +196,9 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
        }
 
        /*
-        * Then do more get_blocks calls until we are done with this page.
+        * Then do more get_blocks calls until we are done with this folio.
         */
-       map_bh->b_page = page;
+       map_bh->b_page = &folio->page;
        while (page_block < blocks_per_page) {
                map_bh->b_state = 0;
                map_bh->b_size = 0;
@@ -216,12 +221,12 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
 
                /* some filesystems will copy data into the page during
                 * the get_block call, in which case we don't want to
-                * read it again.  map_buffer_to_page copies the data
-                * we just collected from get_block into the page's buffers
-                * so readpage doesn't have to repeat the get_block call
+                * read it again.  map_buffer_to_folio copies the data
+                * we just collected from get_block into the folio's buffers
+                * so read_folio doesn't have to repeat the get_block call
                 */
                if (buffer_uptodate(map_bh)) {
-                       map_buffer_to_page(page, map_bh, page_block);
+                       map_buffer_to_folio(folio, map_bh, page_block);
                        goto confused;
                }
        
@@ -246,18 +251,18 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
        }
 
        if (first_hole != blocks_per_page) {
-               zero_user_segment(page, first_hole << blkbits, PAGE_SIZE);
+               folio_zero_segment(folio, first_hole << blkbits, PAGE_SIZE);
                if (first_hole == 0) {
-                       SetPageUptodate(page);
-                       unlock_page(page);
+                       folio_mark_uptodate(folio);
+                       folio_unlock(folio);
                        goto out;
                }
        } else if (fully_mapped) {
-               SetPageMappedToDisk(page);
+               folio_set_mappedtodisk(folio);
        }
 
        /*
-        * This page will go to BIO.  Do we need to send this BIO off first?
+        * This folio will go to BIO.  Do we need to send this BIO off first?
         */
        if (args->bio && (args->last_block_in_bio != blocks[0] - 1))
                args->bio = mpage_bio_submit(args->bio);
@@ -266,7 +271,7 @@ alloc_new:
        if (args->bio == NULL) {
                if (first_hole == blocks_per_page) {
                        if (!bdev_read_page(bdev, blocks[0] << (blkbits - 9),
-                                                               page))
+                                                               &folio->page))
                                goto out;
                }
                args->bio = bio_alloc(bdev, bio_max_segs(args->nr_pages), opf,
@@ -277,7 +282,7 @@ alloc_new:
        }
 
        length = first_hole << blkbits;
-       if (bio_add_page(args->bio, page, length, 0) < length) {
+       if (!bio_add_folio(args->bio, folio, length, 0)) {
                args->bio = mpage_bio_submit(args->bio);
                goto alloc_new;
        }
@@ -295,10 +300,10 @@ out:
 confused:
        if (args->bio)
                args->bio = mpage_bio_submit(args->bio);
-       if (!PageUptodate(page))
-               block_read_full_folio(page_folio(page), args->get_block);
+       if (!folio_test_uptodate(folio))
+               block_read_full_folio(folio, args->get_block);
        else
-               unlock_page(page);
+               folio_unlock(folio);
        goto out;
 }
 
@@ -343,18 +348,17 @@ confused:
  */
 void mpage_readahead(struct readahead_control *rac, get_block_t get_block)
 {
-       struct page *page;
+       struct folio *folio;
        struct mpage_readpage_args args = {
                .get_block = get_block,
                .is_readahead = true,
        };
 
-       while ((page = readahead_page(rac))) {
-               prefetchw(&page->flags);
-               args.page = page;
+       while ((folio = readahead_folio(rac))) {
+               prefetchw(&folio->flags);
+               args.folio = folio;
                args.nr_pages = readahead_count(rac);
                args.bio = do_mpage_readpage(&args);
-               put_page(page);
        }
        if (args.bio)
                mpage_bio_submit(args.bio);
@@ -367,13 +371,11 @@ EXPORT_SYMBOL(mpage_readahead);
 int mpage_read_folio(struct folio *folio, get_block_t get_block)
 {
        struct mpage_readpage_args args = {
-               .page = &folio->page,
+               .folio = folio,
                .nr_pages = 1,
                .get_block = get_block,
        };
 
-       VM_BUG_ON_FOLIO(folio_test_large(folio), folio);
-
        args.bio = do_mpage_readpage(&args);
        if (args.bio)
                mpage_bio_submit(args.bio);
@@ -402,7 +404,6 @@ struct mpage_data {
        struct bio *bio;
        sector_t last_block_in_bio;
        get_block_t *get_block;
-       unsigned use_writepage;
 };
 
 /*
@@ -622,15 +623,10 @@ confused:
        if (bio)
                bio = mpage_bio_submit(bio);
 
-       if (mpd->use_writepage) {
-               ret = mapping->a_ops->writepage(page, wbc);
-       } else {
-               ret = -EAGAIN;
-               goto out;
-       }
        /*
         * The caller has a ref on the inode, so *mapping is stable
         */
+       ret = block_write_full_page(page, mpd->get_block, wbc);
        mapping_set_error(mapping, ret);
 out:
        mpd->bio = bio;
@@ -642,8 +638,6 @@ out:
  * @mapping: address space structure to write
  * @wbc: subtract the number of written pages from *@wbc->nr_to_write
  * @get_block: the filesystem's block mapper function.
- *             If this is NULL then use a_ops->writepage.  Otherwise, go
- *             direct-to-BIO.
  *
  * This is a library function, which implements the writepages()
  * address_space_operation.
@@ -660,42 +654,17 @@ int
 mpage_writepages(struct address_space *mapping,
                struct writeback_control *wbc, get_block_t get_block)
 {
+       struct mpage_data mpd = {
+               .get_block      = get_block,
+       };
        struct blk_plug plug;
        int ret;
 
        blk_start_plug(&plug);
-
-       if (!get_block)
-               ret = generic_writepages(mapping, wbc);
-       else {
-               struct mpage_data mpd = {
-                       .bio = NULL,
-                       .last_block_in_bio = 0,
-                       .get_block = get_block,
-                       .use_writepage = 1,
-               };
-
-               ret = write_cache_pages(mapping, wbc, __mpage_writepage, &mpd);
-               if (mpd.bio)
-                       mpage_bio_submit(mpd.bio);
-       }
-       blk_finish_plug(&plug);
-       return ret;
-}
-EXPORT_SYMBOL(mpage_writepages);
-
-int mpage_writepage(struct page *page, get_block_t get_block,
-       struct writeback_control *wbc)
-{
-       struct mpage_data mpd = {
-               .bio = NULL,
-               .last_block_in_bio = 0,
-               .get_block = get_block,
-               .use_writepage = 0,
-       };
-       int ret = __mpage_writepage(page, wbc, &mpd);
+       ret = write_cache_pages(mapping, wbc, __mpage_writepage, &mpd);
        if (mpd.bio)
                mpage_bio_submit(mpd.bio);
+       blk_finish_plug(&plug);
        return ret;
 }
-EXPORT_SYMBOL(mpage_writepage);
+EXPORT_SYMBOL(mpage_writepages);