From 263cf578049708a115b3ca58e46b7e5d20763866 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:53 +0100 Subject: [PATCH 01/16] befs: Convert befs_symlink_read_folio() to use folio_end_read() This is slightly more efficient than separate calls to folio_mark_uptodate() and folio_unlock(), and it's easier to read. Get rid of the call to folio_set_error() as nobody will check this flag. Cc: Luis de Bethencourt Cc: Salah Triki Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-2-willy@infradead.org Signed-off-by: Christian Brauner --- fs/befs/linuxvfs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index d76f406d3b2e..f92f108840f5 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -475,6 +475,7 @@ static int befs_symlink_read_folio(struct file *unused, struct folio *folio) befs_data_stream *data = &befs_ino->i_data.ds; befs_off_t len = data->size; char *link = folio_address(folio); + int err = -EIO; if (len == 0 || len > PAGE_SIZE) { befs_error(sb, "Long symlink with illegal length"); @@ -487,13 +488,10 @@ static int befs_symlink_read_folio(struct file *unused, struct folio *folio) goto fail; } link[len - 1] = '\0'; - folio_mark_uptodate(folio); - folio_unlock(folio); - return 0; + err = 0; fail: - folio_set_error(folio); - folio_unlock(folio); - return -EIO; + folio_end_read(folio, err == 0); + return err; } /* From 8c30a7344abedf25002baed6196cf41b6fb75c0e Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:54 +0100 Subject: [PATCH 02/16] coda: Convert coda_symlink_filler() to use folio_end_read() This is slightly more efficient than separate calls to folio_mark_uptodate() and folio_unlock(), and it's easier to read. Get rid of the call to folio_set_error() as nobody will check this flag. Cc: Jan Harkes Cc: coda@cs.cmu.edu Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-3-willy@infradead.org Signed-off-by: Christian Brauner --- fs/coda/symlink.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index ccdbec388091..40f84d014524 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c @@ -31,15 +31,7 @@ static int coda_symlink_filler(struct file *file, struct folio *folio) cii = ITOC(inode); error = venus_readlink(inode->i_sb, &cii->c_fid, p, &len); - if (error) - goto fail; - folio_mark_uptodate(folio); - folio_unlock(folio); - return 0; - -fail: - folio_set_error(folio); - folio_unlock(folio); + folio_end_read(folio, error == 0); return error; } From def27a20542044b9322d65ffc206722c159f7c7d Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:55 +0100 Subject: [PATCH 03/16] cramfs: Convert cramfs_read_folio to use a folio Remove the conversion back into a page and use the folio APIs throughout. Remove the setting of PG_error instead of converting it; it is unused by core code or by the rest of cramfs, so it serves no purpose here. Use folio_end_read() to save an atomic operation and unify the two exit paths. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-4-willy@infradead.org Signed-off-by: Christian Brauner --- fs/cramfs/inode.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 460690ca0174..547b703cf6d3 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -811,19 +811,19 @@ out: static int cramfs_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - struct inode *inode = page->mapping->host; + struct inode *inode = folio->mapping->host; u32 maxblock; int bytes_filled; void *pgdata; + bool success = false; maxblock = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT; bytes_filled = 0; - pgdata = kmap_local_page(page); + pgdata = kmap_local_folio(folio, 0); - if (page->index < maxblock) { + if (folio->index < maxblock) { struct super_block *sb = inode->i_sb; - u32 blkptr_offset = OFFSET(inode) + page->index * 4; + u32 blkptr_offset = OFFSET(inode) + folio->index * 4; u32 block_ptr, block_start, block_len; bool uncompressed, direct; @@ -844,7 +844,7 @@ static int cramfs_read_folio(struct file *file, struct folio *folio) if (uncompressed) { block_len = PAGE_SIZE; /* if last block: cap to file length */ - if (page->index == maxblock - 1) + if (folio->index == maxblock - 1) block_len = offset_in_page(inode->i_size); } else { @@ -861,7 +861,7 @@ static int cramfs_read_folio(struct file *file, struct folio *folio) * from the previous block's pointer. */ block_start = OFFSET(inode) + maxblock * 4; - if (page->index) + if (folio->index) block_start = *(u32 *) cramfs_read(sb, blkptr_offset - 4, 4); /* Beware... previous ptr might be a direct ptr */ @@ -906,17 +906,12 @@ static int cramfs_read_folio(struct file *file, struct folio *folio) } memset(pgdata + bytes_filled, 0, PAGE_SIZE - bytes_filled); - flush_dcache_page(page); - kunmap_local(pgdata); - SetPageUptodate(page); - unlock_page(page); - return 0; + flush_dcache_folio(folio); + success = true; err: kunmap_local(pgdata); - ClearPageUptodate(page); - SetPageError(page); - unlock_page(page); + folio_end_read(folio, success); return 0; } From 09da047e554d46885c5ab038373473c19ff2fd12 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:56 +0100 Subject: [PATCH 04/16] efs: Convert efs_symlink_read_folio to use a folio Remove the conversion back into a page and use the folio APIs throughout. Remove the setting of PG_error instead of converting it; it is unused by core code or by the rest of EFS, so it serves no purpose here. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-5-willy@infradead.org Signed-off-by: Christian Brauner --- fs/efs/symlink.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 3b03a573cb1a..7749feded722 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -14,10 +14,9 @@ static int efs_symlink_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - char *link = page_address(page); - struct buffer_head * bh; - struct inode * inode = page->mapping->host; + char *link = folio_address(folio); + struct buffer_head *bh; + struct inode *inode = folio->mapping->host; efs_block_t size = inode->i_size; int err; @@ -40,12 +39,9 @@ static int efs_symlink_read_folio(struct file *file, struct folio *folio) brelse(bh); } link[size] = '\0'; - SetPageUptodate(page); - unlock_page(page); - return 0; + err = 0; fail: - SetPageError(page); - unlock_page(page); + folio_end_read(folio, err == 0); return err; } From 4c59e914ef1a39d7a20d58723ceeff31e50e7292 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:57 +0100 Subject: [PATCH 05/16] hpfs: Convert hpfs_symlink_read_folio to use a folio Remove the conversion back into a page and use the folio APIs throughout. Remove the setting of PG_error instead of converting it; it is unused by core code or by the rest of HPFS, so it serves no purpose here. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-6-willy@infradead.org Signed-off-by: Christian Brauner --- fs/hpfs/namei.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 9184b4584b01..d0edf9ed33b6 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -472,9 +472,8 @@ out: static int hpfs_symlink_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - char *link = page_address(page); - struct inode *i = page->mapping->host; + char *link = folio_address(folio); + struct inode *i = folio->mapping->host; struct fnode *fnode; struct buffer_head *bh; int err; @@ -485,17 +484,9 @@ static int hpfs_symlink_read_folio(struct file *file, struct folio *folio) goto fail; err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE); brelse(bh); - if (err) - goto fail; - hpfs_unlock(i->i_sb); - SetPageUptodate(page); - unlock_page(page); - return 0; - fail: hpfs_unlock(i->i_sb); - SetPageError(page); - unlock_page(page); + folio_end_read(folio, err == 0); return err; } From 4df37c5f0882b211694598ff1fa1c69ccd0c1320 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:58 +0100 Subject: [PATCH 06/16] isofs: Convert rock_ridge_symlink_read_folio to use a folio Remove the conversion back into a page and use the folio APIs throughout. Remove the setting of PG_error instead of converting it; it is unused by core code or by the rest of isofs, so it serves no purpose here. Use folio_end_read() to save an atomic operation and unify the two exit paths. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-7-willy@infradead.org Signed-off-by: Christian Brauner --- fs/isofs/rock.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index d6c17ad69dee..dbf911126e61 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -688,11 +688,10 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, */ static int rock_ridge_symlink_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - struct inode *inode = page->mapping->host; + struct inode *inode = folio->mapping->host; struct iso_inode_info *ei = ISOFS_I(inode); struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); - char *link = page_address(page); + char *link = folio_address(folio); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); struct buffer_head *bh; char *rpnt = link; @@ -779,9 +778,10 @@ repeat: goto fail; brelse(bh); *rpnt = '\0'; - SetPageUptodate(page); - unlock_page(page); - return 0; + ret = 0; +end: + folio_end_read(folio, ret == 0); + return ret; /* error exit from macro */ out: @@ -795,9 +795,8 @@ out_bad_span: fail: brelse(bh); error: - SetPageError(page); - unlock_page(page); - return -EIO; + ret = -EIO; + goto end; } const struct address_space_operations isofs_symlink_aops = { From e3ec0fe944d243968c6f33305e5d195efb501c0b Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:20:59 +0100 Subject: [PATCH 07/16] hostfs: Convert hostfs_read_folio() to use a folio Remove the use of page APIs, including setting/clearing the error flag which is never checked on hostfs folios. This does not include support for large folios as kmap_local_folio() maps only one page at a time. Cc: Richard Weinberger Cc: Anton Ivanov Cc: Johannes Berg Cc: linux-um@lists.infradead.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-8-willy@infradead.org Signed-off-by: Christian Brauner --- fs/hostfs/hostfs_kern.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index a73d27c4dd58..e7c72f2634f6 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -432,31 +432,20 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc) static int hostfs_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; char *buffer; - loff_t start = page_offset(page); + loff_t start = folio_pos(folio); int bytes_read, ret = 0; - buffer = kmap_local_page(page); + buffer = kmap_local_folio(folio, 0); bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, PAGE_SIZE); - if (bytes_read < 0) { - ClearPageUptodate(page); - SetPageError(page); + if (bytes_read < 0) ret = bytes_read; - goto out; - } - - memset(buffer + bytes_read, 0, PAGE_SIZE - bytes_read); - - ClearPageError(page); - SetPageUptodate(page); - - out: - flush_dcache_page(page); + else + buffer = folio_zero_tail(folio, bytes_read, buffer); kunmap_local(buffer); - unlock_page(page); + folio_end_read(folio, ret == 0); return ret; } From d15b00b1e588ea88a747bd70f6e360870088f5d2 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:00 +0100 Subject: [PATCH 08/16] jffs2: Remove calls to set/clear the folio error flag Nobody checks the error flag on jffs2 folios, so stop setting and clearing it. We can also remove the call to clear the uptodate flag; it will already be clear. Convert one of these into a call to mapping_set_error() which will actually be checked by other parts of the kernel. Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-9-willy@infradead.org Tested-by: Zhihao Cheng Acked-by: Richard Weinberger Reviewed-by: Zhihao Cheng Signed-off-by: Christian Brauner --- fs/jffs2/file.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 62ea76da7fdf..e12cb145147e 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -95,13 +95,8 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_SHIFT, PAGE_SIZE); - if (ret) { - ClearPageUptodate(pg); - SetPageError(pg); - } else { + if (!ret) SetPageUptodate(pg); - ClearPageError(pg); - } flush_dcache_page(pg); kunmap(pg); @@ -304,10 +299,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, kunmap(pg); - if (ret) { - /* There was an error writing. */ - SetPageError(pg); - } + if (ret) + mapping_set_error(mapping, ret); /* Adjust writtenlen for the padding we did, so we don't confuse our caller */ writtenlen -= min(writtenlen, (start - aligned_start)); @@ -330,7 +323,6 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, it gets reread */ jffs2_dbg(1, "%s(): Not all bytes written. Marking page !uptodate\n", __func__); - SetPageError(pg); ClearPageUptodate(pg); } From 8f3ab6e4bebe789f23690cf57fb1a648c4422b9d Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:01 +0100 Subject: [PATCH 09/16] nfs: Remove calls to folio_set_error Common code doesn't test the error flag, so we don't need to set it in nfs. We can use folio_end_read() to combine the setting (or not) of the uptodate flag and clearing the lock flag. Cc: Trond Myklebust Cc: Anna Schumaker Cc: linux-nfs@vger.kernel.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-10-willy@infradead.org Signed-off-by: Christian Brauner --- fs/nfs/read.c | 2 -- fs/nfs/symlink.c | 12 ++---------- fs/nfs/write.c | 1 - 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/fs/nfs/read.c b/fs/nfs/read.c index a142287d86f6..cca80b5f54e0 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -122,8 +122,6 @@ static void nfs_readpage_release(struct nfs_page *req, int error) { struct folio *folio = nfs_page_to_folio(req); - if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT) - folio_set_error(folio); if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) if (nfs_netfs_folio_unlock(folio)) folio_unlock(folio); diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 0e27a2e4e68b..1c62a5a9f51d 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -32,16 +32,8 @@ static int nfs_symlink_filler(struct file *file, struct folio *folio) int error; error = NFS_PROTO(inode)->readlink(inode, &folio->page, 0, PAGE_SIZE); - if (error < 0) - goto error; - folio_mark_uptodate(folio); - folio_unlock(folio); - return 0; - -error: - folio_set_error(folio); - folio_unlock(folio); - return -EIO; + folio_end_read(folio, error == 0); + return error; } static const char *nfs_get_link(struct dentry *dentry, diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2329cbb0e446..a91463ab87a0 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -311,7 +311,6 @@ static void nfs_mapping_set_error(struct folio *folio, int error) { struct address_space *mapping = folio_file_mapping(folio); - folio_set_error(folio); filemap_set_wb_err(mapping, error); if (mapping->host) errseq_set(&mapping->host->i_sb->s_wb_err, From 86b3d5f6df0e60e87702a3991b09e56dfe6b0484 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:02 +0100 Subject: [PATCH 10/16] orangefs: Remove calls to set/clear the error flag Nobody checks the error flag on orangefs folios, so stop setting and clearing it. We can also use folio_end_read() to simplify orangefs_read_folio(). Cc: Martin Brandenburg Cc: devel@lists.orangefs.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-11-willy@infradead.org Tested-by: Mike Marshall Signed-off-by: Christian Brauner --- fs/orangefs/inode.c | 13 +++---------- fs/orangefs/orangefs-bufmap.c | 4 +--- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 085912268442..fdb9b65db1de 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -56,7 +56,6 @@ static int orangefs_writepage_locked(struct page *page, ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen, len, wr, NULL, NULL); if (ret < 0) { - SetPageError(page); mapping_set_error(page->mapping, ret); } else { ret = 0; @@ -119,7 +118,6 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow, 0, &wr, NULL, NULL); if (ret < 0) { for (i = 0; i < ow->npages; i++) { - SetPageError(ow->pages[i]); mapping_set_error(ow->pages[i]->mapping, ret); if (PagePrivate(ow->pages[i])) { wrp = (struct orangefs_write_range *) @@ -303,15 +301,10 @@ static int orangefs_read_folio(struct file *file, struct folio *folio) iov_iter_zero(~0U, &iter); /* takes care of potential aliasing */ flush_dcache_folio(folio); - if (ret < 0) { - folio_set_error(folio); - } else { - folio_mark_uptodate(folio); + if (ret > 0) ret = 0; - } - /* unlock the folio after the ->read_folio() routine completes */ - folio_unlock(folio); - return ret; + folio_end_read(folio, ret == 0); + return ret; } static int orangefs_write_begin(struct file *file, diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index b501dc07f922..edcca4beb765 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -274,10 +274,8 @@ orangefs_bufmap_map(struct orangefs_bufmap *bufmap, gossip_err("orangefs error: asked for %d pages, only got %d.\n", bufmap->page_count, ret); - for (i = 0; i < ret; i++) { - SetPageError(bufmap->page_array[i]); + for (i = 0; i < ret; i++) unpin_user_page(bufmap->page_array[i]); - } return -ENOMEM; } From f4c51473d22a9c2847f5dde401cd15f29cee6708 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:03 +0100 Subject: [PATCH 11/16] reiserfs: Remove call to folio_set_error() The error flag is never tested for reiserfs folios, so stop setting it. Cc: reiserfs-devel@vger.kernel.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-12-willy@infradead.org Signed-off-by: Christian Brauner --- fs/reiserfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index c1daedc50f4c..9b43a81a6488 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2699,7 +2699,6 @@ fail: } bh = bh->b_this_page; } while (bh != head); - folio_set_error(folio); BUG_ON(folio_test_writeback(folio)); folio_start_writeback(folio); folio_unlock(folio); From d86f2de026c57e1503259f39abdfa1659c51d900 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:04 +0100 Subject: [PATCH 12/16] romfs: Convert romfs_read_folio() to use a folio Remove the conversion back to struct page and use the folio APIs instead of the page APIs. It's probably more trouble than it's worth to support large folios in romfs, so there are still PAGE_SIZE assumptions in this function. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-13-willy@infradead.org Signed-off-by: Christian Brauner --- fs/romfs/super.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 2cbb92462074..68758b6fed94 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -101,19 +101,15 @@ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos); */ static int romfs_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; - struct inode *inode = page->mapping->host; + struct inode *inode = folio->mapping->host; loff_t offset, size; unsigned long fillsize, pos; void *buf; int ret; - buf = kmap(page); - if (!buf) - return -ENOMEM; + buf = kmap_local_folio(folio, 0); - /* 32 bit warning -- but not for us :) */ - offset = page_offset(page); + offset = folio_pos(folio); size = i_size_read(inode); fillsize = 0; ret = 0; @@ -125,20 +121,14 @@ static int romfs_read_folio(struct file *file, struct folio *folio) ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize); if (ret < 0) { - SetPageError(page); fillsize = 0; ret = -EIO; } } - if (fillsize < PAGE_SIZE) - memset(buf + fillsize, 0, PAGE_SIZE - fillsize); - if (ret == 0) - SetPageUptodate(page); - - flush_dcache_page(page); - kunmap(page); - unlock_page(page); + buf = folio_zero_tail(folio, fillsize, buf); + kunmap_local(buf); + folio_end_read(folio, ret == 0); return ret; } From ca7d585639b597e838882faa3c7a959d13aaa533 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:05 +0100 Subject: [PATCH 13/16] ufs: Remove call to set the folio error flag Nobody checks the error flag on ufs folios, so stop setting it. Cc: Evgeniy Dushistov Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-14-willy@infradead.org Signed-off-by: Christian Brauner --- fs/ufs/dir.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 27c85d92d1dc..61f25d3cf3f7 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c @@ -188,7 +188,6 @@ Eend: "offset=%lu", dir->i_ino, (page->index< Date: Thu, 30 May 2024 21:21:06 +0100 Subject: [PATCH 14/16] vboxsf: Convert vboxsf_read_folio() to use a folio Remove conversion to a page and use folio APIs throughout. This includes a removal of setting the error flag as nobody checks the error flag on vboxsf folios. This does not include large folio support as we would have to map each page individually. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-15-willy@infradead.org Tested-by: Hans de Goede Reviewed-by: Hans de Goede Signed-off-by: Christian Brauner --- fs/vboxsf/file.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c index 118dedef8ebe..fdb4da24d662 100644 --- a/fs/vboxsf/file.c +++ b/fs/vboxsf/file.c @@ -228,26 +228,19 @@ const struct inode_operations vboxsf_reg_iops = { static int vboxsf_read_folio(struct file *file, struct folio *folio) { - struct page *page = &folio->page; struct vboxsf_handle *sf_handle = file->private_data; - loff_t off = page_offset(page); + loff_t off = folio_pos(folio); u32 nread = PAGE_SIZE; u8 *buf; int err; - buf = kmap(page); + buf = kmap_local_folio(folio, 0); err = vboxsf_read(sf_handle->root, sf_handle->handle, off, &nread, buf); - if (err == 0) { - memset(&buf[nread], 0, PAGE_SIZE - nread); - flush_dcache_page(page); - SetPageUptodate(page); - } else { - SetPageError(page); - } + buf = folio_zero_tail(folio, nread, buf + nread); - kunmap(page); - unlock_page(page); + kunmap_local(buf); + folio_end_read(folio, err == 0); return err; } @@ -295,7 +288,6 @@ static int vboxsf_writepage(struct page *page, struct writeback_control *wbc) kref_put(&sf_handle->refcount, vboxsf_handle_release); if (err == 0) { - ClearPageError(page); /* mtime changed */ sf_i->force_restat = 1; } else { From 1f56eedf7ff76b71f88f80d8b539f254ecbce561 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:07 +0100 Subject: [PATCH 15/16] iomap: Remove calls to set and clear folio error flag The folio error flag is not checked anywhere, so we can remove the calls to set and clear it. Cc: Christian Brauner Cc: linux-xfs@vger.kernel.org Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-16-willy@infradead.org Reviewed-by: Darrick J. Wong Signed-off-by: Christian Brauner --- fs/iomap/buffered-io.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 41c8f0c68ef5..4175578aeeed 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -306,8 +306,6 @@ static void iomap_finish_folio_read(struct folio *folio, size_t off, spin_unlock_irqrestore(&ifs->state_lock, flags); } - if (error) - folio_set_error(folio); if (finished) folio_end_read(folio, uptodate); } @@ -460,9 +458,6 @@ int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops) while ((ret = iomap_iter(&iter, ops)) > 0) iter.processed = iomap_readpage_iter(&iter, &ctx, 0); - if (ret < 0) - folio_set_error(folio); - if (ctx.bio) { submit_bio(ctx.bio); WARN_ON_ONCE(!ctx.cur_folio_in_bio); @@ -697,7 +692,6 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos, if (folio_test_uptodate(folio)) return 0; - folio_clear_error(folio); do { iomap_adjust_read_range(iter->inode, folio, &block_start, @@ -1543,8 +1537,6 @@ iomap_finish_ioend(struct iomap_ioend *ioend, int error) /* walk all folios in bio, ending page IO on them */ bio_for_each_folio_all(fi, bio) { - if (error) - folio_set_error(fi.folio); iomap_finish_folio_write(inode, fi.folio, fi.length); folio_count++; } From 7ad635ea82704a64c40aba67a7d04293d4780f0f Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 30 May 2024 21:21:08 +0100 Subject: [PATCH 16/16] buffer: Remove calls to set and clear the folio error flag The folio error flag is not tested anywhere, so we can stop setting and clearing it. Signed-off-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20240530202110.2653630-17-willy@infradead.org Signed-off-by: Christian Brauner --- fs/buffer.c | 7 +------ fs/mpage.c | 13 +++---------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 8c19e705b9c3..dbe8f411ce52 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -258,7 +258,6 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) } else { clear_buffer_uptodate(bh); buffer_io_error(bh, ", async page read"); - folio_set_error(folio); } /* @@ -391,7 +390,6 @@ static void end_buffer_async_write(struct buffer_head *bh, int uptodate) buffer_io_error(bh, ", lost async page write"); mark_buffer_write_io_error(bh); clear_buffer_uptodate(bh); - folio_set_error(folio); } first = folio_buffers(folio); @@ -1960,7 +1958,6 @@ recover: clear_buffer_dirty(bh); } } while ((bh = bh->b_this_page) != head); - folio_set_error(folio); BUG_ON(folio_test_writeback(folio)); mapping_set_error(folio->mapping, err); folio_start_writeback(folio); @@ -2405,10 +2402,8 @@ int block_read_full_folio(struct folio *folio, get_block_t *get_block) if (iblock < lblock) { WARN_ON(bh->b_size != blocksize); err = get_block(inode, iblock, bh, 0); - if (err) { - folio_set_error(folio); + if (err) page_error = true; - } } if (!buffer_mapped(bh)) { folio_zero_range(folio, i * blocksize, diff --git a/fs/mpage.c b/fs/mpage.c index fa8b99a199fa..b5b5ddf9d513 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -48,13 +48,8 @@ static void mpage_read_end_io(struct bio *bio) struct folio_iter fi; int err = blk_status_to_errno(bio->bi_status); - bio_for_each_folio_all(fi, bio) { - if (err) - folio_set_error(fi.folio); - else - folio_mark_uptodate(fi.folio); - folio_unlock(fi.folio); - } + bio_for_each_folio_all(fi, bio) + folio_end_read(fi.folio, err == 0); bio_put(bio); } @@ -65,10 +60,8 @@ static void mpage_write_end_io(struct bio *bio) int err = blk_status_to_errno(bio->bi_status); bio_for_each_folio_all(fi, bio) { - if (err) { - folio_set_error(fi.folio); + if (err) mapping_set_error(fi.folio->mapping, err); - } folio_end_writeback(fi.folio); }