Skip to content

Commit

Permalink
fs: Convert block_read_full_page() to block_read_full_folio()
Browse files Browse the repository at this point in the history
This function is NOT converted to handle large folios, so include
an assert that the filesystem isn't passing one in.  Otherwise, use
the folio functions instead of the page functions, where they exist.
Convert all filesystems which use block_read_full_page().

Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
  • Loading branch information
Matthew Wilcox (Oracle) committed May 9, 2022
1 parent 7479c50 commit 2c69e20
Show file tree
Hide file tree
Showing 24 changed files with 108 additions and 101 deletions.
6 changes: 3 additions & 3 deletions block/fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, blkdev_get_block, wbc);
}

static int blkdev_readpage(struct file * file, struct page * page)
static int blkdev_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, blkdev_get_block);
return block_read_full_folio(folio, blkdev_get_block);
}

static void blkdev_readahead(struct readahead_control *rac)
Expand Down Expand Up @@ -425,7 +425,7 @@ static int blkdev_writepages(struct address_space *mapping,
const struct address_space_operations def_blk_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = blkdev_readpage,
.read_folio = blkdev_read_folio,
.readahead = blkdev_readahead,
.writepage = blkdev_writepage,
.write_begin = blkdev_write_begin,
Expand Down
6 changes: 3 additions & 3 deletions fs/adfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ static int adfs_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, adfs_get_block, wbc);
}

static int adfs_readpage(struct file *file, struct page *page)
static int adfs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, adfs_get_block);
return block_read_full_folio(folio, adfs_get_block);
}

static void adfs_write_failed(struct address_space *mapping, loff_t to)
Expand Down Expand Up @@ -75,7 +75,7 @@ static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
static const struct address_space_operations adfs_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = adfs_readpage,
.read_folio = adfs_read_folio,
.writepage = adfs_writepage,
.write_begin = adfs_write_begin,
.write_end = generic_write_end,
Expand Down
6 changes: 3 additions & 3 deletions fs/affs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ static int affs_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, affs_get_block, wbc);
}

static int affs_readpage(struct file *file, struct page *page)
static int affs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, affs_get_block);
return block_read_full_folio(folio, affs_get_block);
}

static void affs_write_failed(struct address_space *mapping, loff_t to)
Expand Down Expand Up @@ -455,7 +455,7 @@ static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
const struct address_space_operations affs_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = affs_readpage,
.read_folio = affs_read_folio,
.writepage = affs_writepage,
.write_begin = affs_write_begin,
.write_end = affs_write_end,
Expand Down
10 changes: 5 additions & 5 deletions fs/befs/linuxvfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ MODULE_LICENSE("GPL");

static int befs_readdir(struct file *, struct dir_context *);
static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int);
static int befs_readpage(struct file *file, struct page *page);
static int befs_read_folio(struct file *file, struct folio *folio);
static sector_t befs_bmap(struct address_space *mapping, sector_t block);
static struct dentry *befs_lookup(struct inode *, struct dentry *,
unsigned int);
Expand Down Expand Up @@ -87,7 +87,7 @@ static const struct inode_operations befs_dir_inode_operations = {
};

static const struct address_space_operations befs_aops = {
.readpage = befs_readpage,
.read_folio = befs_read_folio,
.bmap = befs_bmap,
};

Expand All @@ -102,16 +102,16 @@ static const struct export_operations befs_export_operations = {
};

/*
* Called by generic_file_read() to read a page of data
* Called by generic_file_read() to read a folio of data
*
* In turn, simply calls a generic block read function and
* passes it the address of befs_get_block, for mapping file
* positions to disk blocks.
*/
static int
befs_readpage(struct file *file, struct page *page)
befs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, befs_get_block);
return block_read_full_folio(folio, befs_get_block);
}

static sector_t
Expand Down
6 changes: 3 additions & 3 deletions fs/bfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ static int bfs_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, bfs_get_block, wbc);
}

static int bfs_readpage(struct file *file, struct page *page)
static int bfs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, bfs_get_block);
return block_read_full_folio(folio, bfs_get_block);
}

static void bfs_write_failed(struct address_space *mapping, loff_t to)
Expand Down Expand Up @@ -189,7 +189,7 @@ static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
const struct address_space_operations bfs_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = bfs_readpage,
.read_folio = bfs_read_folio,
.writepage = bfs_writepage,
.write_begin = bfs_write_begin,
.write_end = generic_write_end,
Expand Down
53 changes: 28 additions & 25 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ static void decrypt_bh(struct work_struct *work)
}

/*
* I/O completion handler for block_read_full_page() - pages
* I/O completion handler for block_read_full_folio() - pages
* which come unlocked at the end of I/O.
*/
static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate)
Expand Down Expand Up @@ -1060,8 +1060,8 @@ __getblk_slow(struct block_device *bdev, sector_t block,
* Also. When blockdev buffers are explicitly read with bread(), they
* individually become uptodate. But their backing page remains not
* uptodate - even if all of its buffers are uptodate. A subsequent
* block_read_full_page() against that page will discover all the uptodate
* buffers, will set the page uptodate and will perform no I/O.
* block_read_full_folio() against that folio will discover all the uptodate
* buffers, will set the folio uptodate and will perform no I/O.
*/

/**
Expand Down Expand Up @@ -2088,7 +2088,7 @@ static int __block_commit_write(struct inode *inode, struct page *page,

/*
* If this is a partial write which happened to make all buffers
* uptodate then we can optimize away a bogus readpage() for
* uptodate then we can optimize away a bogus read_folio() for
* the next read(). Here we 'discover' whether the page went
* uptodate as a result of this (potentially partial) write.
*/
Expand Down Expand Up @@ -2137,12 +2137,12 @@ int block_write_end(struct file *file, struct address_space *mapping,

if (unlikely(copied < len)) {
/*
* The buffers that were written will now be uptodate, so we
* don't have to worry about a readpage reading them and
* overwriting a partial write. However if we have encountered
* a short write and only partially written into a buffer, it
* will not be marked uptodate, so a readpage might come in and
* destroy our partial write.
* The buffers that were written will now be uptodate, so
* we don't have to worry about a read_folio reading them
* and overwriting a partial write. However if we have
* encountered a short write and only partially written
* into a buffer, it will not be marked uptodate, so a
* read_folio might come in and destroy our partial write.
*
* Do the simplest thing, and just treat any short write to a
* non uptodate page as a zero-length write, and force the
Expand Down Expand Up @@ -2245,26 +2245,28 @@ bool block_is_partially_uptodate(struct folio *folio, size_t from, size_t count)
EXPORT_SYMBOL(block_is_partially_uptodate);

/*
* Generic "read page" function for block devices that have the normal
* Generic "read_folio" function for block devices that have the normal
* get_block functionality. This is most of the block device filesystems.
* Reads the page asynchronously --- the unlock_buffer() and
* Reads the folio asynchronously --- the unlock_buffer() and
* set/clear_buffer_uptodate() functions propagate buffer state into the
* page struct once IO has completed.
* folio once IO has completed.
*/
int block_read_full_page(struct page *page, get_block_t *get_block)
int block_read_full_folio(struct folio *folio, get_block_t *get_block)
{
struct inode *inode = page->mapping->host;
struct inode *inode = folio->mapping->host;
sector_t iblock, lblock;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
unsigned int blocksize, bbits;
int nr, i;
int fully_mapped = 1;

head = create_page_buffers(page, inode, 0);
VM_BUG_ON_FOLIO(folio_test_large(folio), folio);

head = create_page_buffers(&folio->page, inode, 0);
blocksize = head->b_size;
bbits = block_size_bits(blocksize);

iblock = (sector_t)page->index << (PAGE_SHIFT - bbits);
iblock = (sector_t)folio->index << (PAGE_SHIFT - bbits);
lblock = (i_size_read(inode)+blocksize-1) >> bbits;
bh = head;
nr = 0;
Expand All @@ -2282,10 +2284,11 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
WARN_ON(bh->b_size != blocksize);
err = get_block(inode, iblock, bh, 0);
if (err)
SetPageError(page);
folio_set_error(folio);
}
if (!buffer_mapped(bh)) {
zero_user(page, i * blocksize, blocksize);
folio_zero_range(folio, i * blocksize,
blocksize);
if (!err)
set_buffer_uptodate(bh);
continue;
Expand All @@ -2301,16 +2304,16 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
} while (i++, iblock++, (bh = bh->b_this_page) != head);

if (fully_mapped)
SetPageMappedToDisk(page);
folio_set_mappedtodisk(folio);

if (!nr) {
/*
* All buffers are uptodate - we can set the page uptodate
* All buffers are uptodate - we can set the folio uptodate
* as well. But not if get_block() returned an error.
*/
if (!PageError(page))
SetPageUptodate(page);
unlock_page(page);
if (!folio_test_error(folio))
folio_mark_uptodate(folio);
folio_unlock(folio);
return 0;
}

Expand All @@ -2335,7 +2338,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
}
return 0;
}
EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_read_full_folio);

/* utility function for filesystems that need to do work on expanding
* truncates. Uses filesystem pagecache writes to allow the filesystem to
Expand Down
8 changes: 5 additions & 3 deletions fs/efs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@
#include "efs.h"
#include <linux/efs_fs_sb.h>

static int efs_readpage(struct file *file, struct page *page)
static int efs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page,efs_get_block);
return block_read_full_folio(folio, efs_get_block);
}

static sector_t _efs_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,efs_get_block);
}

static const struct address_space_operations efs_aops = {
.readpage = efs_readpage,
.read_folio = efs_read_folio,
.bmap = _efs_bmap
};

Expand Down
4 changes: 2 additions & 2 deletions fs/ext4/readpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static bool bio_post_read_required(struct bio *bio)
*
* The mpage code never puts partial pages into a BIO (except for end-of-file).
* If a page does not map to a contiguous run of blocks then it simply falls
* back to block_read_full_page().
* back to block_read_full_folio().
*
* Why is this? If a page's completion depends on a number of different BIOs
* which can complete in any order (or at the same time) then determining the
Expand Down Expand Up @@ -394,7 +394,7 @@ int ext4_mpage_readpages(struct inode *inode,
bio = NULL;
}
if (!PageUptodate(page))
block_read_full_page(page, ext4_get_block);
block_read_full_folio(page_folio(page), ext4_get_block);
else
unlock_page(page);
next_page:
Expand Down
17 changes: 8 additions & 9 deletions fs/freevxfs/vxfs_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
#include "vxfs_extern.h"


static int vxfs_readpage(struct file *, struct page *);
static int vxfs_read_folio(struct file *, struct folio *);
static sector_t vxfs_bmap(struct address_space *, sector_t);

const struct address_space_operations vxfs_aops = {
.readpage = vxfs_readpage,
.read_folio = vxfs_read_folio,
.bmap = vxfs_bmap,
};

Expand Down Expand Up @@ -141,24 +141,23 @@ vxfs_getblk(struct inode *ip, sector_t iblock,
}

/**
* vxfs_readpage - read one page synchronously into the pagecache
* vxfs_read_folio - read one page synchronously into the pagecache
* @file: file context (unused)
* @page: page frame to fill in.
* @folio: folio to fill in.
*
* Description:
* The vxfs_readpage routine reads @page synchronously into the
* The vxfs_read_folio routine reads @folio synchronously into the
* pagecache.
*
* Returns:
* Zero on success, else a negative error code.
*
* Locking status:
* @page is locked and will be unlocked.
* @folio is locked and will be unlocked.
*/
static int
vxfs_readpage(struct file *file, struct page *page)
static int vxfs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, vxfs_getblk);
return block_read_full_folio(folio, vxfs_getblk);
}

/**
Expand Down
8 changes: 4 additions & 4 deletions fs/hfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ static int hfs_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, hfs_get_block, wbc);
}

static int hfs_readpage(struct file *file, struct page *page)
static int hfs_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, hfs_get_block);
return block_read_full_folio(folio, hfs_get_block);
}

static void hfs_write_failed(struct address_space *mapping, loff_t to)
Expand Down Expand Up @@ -160,7 +160,7 @@ static int hfs_writepages(struct address_space *mapping,
const struct address_space_operations hfs_btree_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = hfs_readpage,
.read_folio = hfs_read_folio,
.writepage = hfs_writepage,
.write_begin = hfs_write_begin,
.write_end = generic_write_end,
Expand All @@ -171,7 +171,7 @@ const struct address_space_operations hfs_btree_aops = {
const struct address_space_operations hfs_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = hfs_readpage,
.read_folio = hfs_read_folio,
.writepage = hfs_writepage,
.write_begin = hfs_write_begin,
.write_end = generic_write_end,
Expand Down
8 changes: 4 additions & 4 deletions fs/hfsplus/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#include "hfsplus_raw.h"
#include "xattr.h"

static int hfsplus_readpage(struct file *file, struct page *page)
static int hfsplus_read_folio(struct file *file, struct folio *folio)
{
return block_read_full_page(page, hfsplus_get_block);
return block_read_full_folio(folio, hfsplus_get_block);
}

static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
Expand Down Expand Up @@ -157,7 +157,7 @@ static int hfsplus_writepages(struct address_space *mapping,
const struct address_space_operations hfsplus_btree_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = hfsplus_readpage,
.read_folio = hfsplus_read_folio,
.writepage = hfsplus_writepage,
.write_begin = hfsplus_write_begin,
.write_end = generic_write_end,
Expand All @@ -168,7 +168,7 @@ const struct address_space_operations hfsplus_btree_aops = {
const struct address_space_operations hfsplus_aops = {
.dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio,
.readpage = hfsplus_readpage,
.read_folio = hfsplus_read_folio,
.writepage = hfsplus_writepage,
.write_begin = hfsplus_write_begin,
.write_end = generic_write_end,
Expand Down
Loading

0 comments on commit 2c69e20

Please sign in to comment.