* [PATCH 00/35] nilfs2: Folio conversions
@ 2023-11-06 17:38 Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 01/35] nilfs2: Add nilfs_end_folio_io() Matthew Wilcox (Oracle)
` (35 more replies)
0 siblings, 36 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
This patch series does most of the page->folio conversions needed in
nilfs2. I haven't done the work to support large folios in nilfs2;
I don't know if that conversion will be worth the effort. There are
still a few page uses left, but the infrastructure isn't quite there to
get rid of them yet.
Arguably, this is two separate series; the first takes care of the file
paths and the second takes care of directories. I've tried my best to
include large folio support in the directory code because it'll be needed
for large block size devices. It also tries to stay as close as possible
to the current ext2 code (so it also includes kmap_local support).
These patches are only compile-tested. xfstests doesn't seem to know
about nilfs2.
Matthew Wilcox (Oracle) (35):
nilfs2: Add nilfs_end_folio_io()
nilfs2: Convert nilfs_abort_logs to use folios
nilfs2: Convert nilfs_segctor_complete_write to use folios
nilfs2: Convert nilfs_forget_buffer to use a folio
nilfs2: Convert to nilfs_folio_buffers_clean()
nilfs2: Convert nilfs_writepage() to use a folio
nilfs2: Convert nilfs_mdt_write_page() to use a folio
nilfs2: Convert to nilfs_clear_folio_dirty()
nilfs2: Convert to __nilfs_clear_folio_dirty()
nilfs2: Convert nilfs_segctor_prepare_write to use folios
nilfs2: Convert nilfs_page_mkwrite() to use a folio
nilfs2: Convert nilfs_mdt_create_block to use a folio
nilfs2: Convert nilfs_mdt_submit_block to use a folio
nilfs2: Convert nilfs_gccache_submit_read_data to use a folio
nilfs2: Convert nilfs_btnode_create_block to use a folio
nilfs2: Convert nilfs_btnode_submit_block to use a folio
nilfs2: Convert nilfs_btnode_delete to use a folio
nilfs2: Convert nilfs_btnode_prepare_change_key to use a folio
nilfs2: Convert nilfs_btnode_commit_change_key to use a folio
nilfs2: Convert nilfs_btnode_abort_change_key to use a folio
nilfs2: Remove page_address() from nilfs_set_link
nilfs2: Remove page_address() from nilfs_add_link
nilfs2: Remove page_address() from nilfs_delete_entry
nilfs2: Return the mapped address from nilfs_get_page()
nilfs2: Pass the mapped address to nilfs_check_page()
nilfs2: Switch to kmap_local for directory handling
nilfs2: Add nilfs_get_folio()
nilfs2: Convert nilfs_readdir to use a folio
nilfs2: Convert nilfs_find_entry to use a folio
nilfs2: Convert nilfs_rename() to use folios
nilfs2: Convert nilfs_add_link() to use a folio
nilfs2: Convert nilfs_empty_dir() to use a folio
nilfs2: Convert nilfs_make_empty() to use a folio
nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to
folios
nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
fs/nilfs2/btnode.c | 62 +++++------
fs/nilfs2/dir.c | 248 ++++++++++++++++++++------------------------
fs/nilfs2/file.c | 28 ++---
fs/nilfs2/gcinode.c | 4 +-
fs/nilfs2/inode.c | 11 +-
fs/nilfs2/mdt.c | 23 ++--
fs/nilfs2/namei.c | 33 +++---
fs/nilfs2/nilfs.h | 20 ++--
fs/nilfs2/page.c | 93 +++++++++--------
fs/nilfs2/page.h | 12 +--
fs/nilfs2/segment.c | 157 ++++++++++++++--------------
11 files changed, 338 insertions(+), 353 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 01/35] nilfs2: Add nilfs_end_folio_io()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 02/35] nilfs2: Convert nilfs_abort_logs to use folios Matthew Wilcox (Oracle)
` (34 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
This is the folio counterpart of the existing nilfs_end_page_io()
which is retained as a wrapper of nilfs_end_folio_io(). Replaces
nine hidden calls to compound_head() with one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/segment.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 55e31cc903d1..1df03d0895be 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1739,17 +1739,18 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci,
return ret;
}
-static void nilfs_end_page_io(struct page *page, int err)
+static void nilfs_end_folio_io(struct folio *folio, int err)
{
- if (!page)
+ if (!folio)
return;
- if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
+ if (buffer_nilfs_node(folio_buffers(folio)) &&
+ !folio_test_writeback(folio)) {
/*
* For b-tree node pages, this function may be called twice
* or more because they might be split in a segment.
*/
- if (PageDirty(page)) {
+ if (folio_test_dirty(folio)) {
/*
* For pages holding split b-tree node buffers, dirty
* flag on the buffers may be cleared discretely.
@@ -1757,24 +1758,31 @@ static void nilfs_end_page_io(struct page *page, int err)
* remaining buffers, and it must be cancelled if
* all the buffers get cleaned later.
*/
- lock_page(page);
- if (nilfs_page_buffers_clean(page))
- __nilfs_clear_page_dirty(page);
- unlock_page(page);
+ folio_lock(folio);
+ if (nilfs_page_buffers_clean(&folio->page))
+ __nilfs_clear_page_dirty(&folio->page);
+ folio_unlock(folio);
}
return;
}
if (!err) {
- if (!nilfs_page_buffers_clean(page))
- __set_page_dirty_nobuffers(page);
- ClearPageError(page);
+ if (!nilfs_page_buffers_clean(&folio->page))
+ filemap_dirty_folio(folio->mapping, folio);
+ folio_clear_error(folio);
} else {
- __set_page_dirty_nobuffers(page);
- SetPageError(page);
+ filemap_dirty_folio(folio->mapping, folio);
+ folio_set_error(folio);
}
- end_page_writeback(page);
+ folio_end_writeback(folio);
+}
+
+static void nilfs_end_page_io(struct page *page, int err)
+{
+ if (!page)
+ return;
+ nilfs_end_folio_io(page_folio(page), err);
}
static void nilfs_abort_logs(struct list_head *logs, int err)
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 02/35] nilfs2: Convert nilfs_abort_logs to use folios
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 01/35] nilfs2: Add nilfs_end_folio_io() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 03/35] nilfs2: Convert nilfs_segctor_complete_write " Matthew Wilcox (Oracle)
` (33 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Use the new folio APIs, saving five hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/segment.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 1df03d0895be..730062e79bfc 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1788,7 +1788,7 @@ static void nilfs_end_page_io(struct page *page, int err)
static void nilfs_abort_logs(struct list_head *logs, int err)
{
struct nilfs_segment_buffer *segbuf;
- struct page *bd_page = NULL, *fs_page = NULL;
+ struct folio *bd_folio = NULL, *fs_folio = NULL;
struct buffer_head *bh;
if (list_empty(logs))
@@ -1798,10 +1798,10 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
b_assoc_buffers) {
clear_buffer_uptodate(bh);
- if (bh->b_page != bd_page) {
- if (bd_page)
- end_page_writeback(bd_page);
- bd_page = bh->b_page;
+ if (bh->b_folio != bd_folio) {
+ if (bd_folio)
+ folio_end_writeback(bd_folio);
+ bd_folio = bh->b_folio;
}
}
@@ -1810,22 +1810,22 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
clear_buffer_async_write(bh);
if (bh == segbuf->sb_super_root) {
clear_buffer_uptodate(bh);
- if (bh->b_page != bd_page) {
- end_page_writeback(bd_page);
- bd_page = bh->b_page;
+ if (bh->b_folio != bd_folio) {
+ folio_end_writeback(bd_folio);
+ bd_folio = bh->b_folio;
}
break;
}
- if (bh->b_page != fs_page) {
- nilfs_end_page_io(fs_page, err);
- fs_page = bh->b_page;
+ if (bh->b_folio != fs_folio) {
+ nilfs_end_folio_io(fs_folio, err);
+ fs_folio = bh->b_folio;
}
}
}
- if (bd_page)
- end_page_writeback(bd_page);
+ if (bd_folio)
+ folio_end_writeback(bd_folio);
- nilfs_end_page_io(fs_page, err);
+ nilfs_end_folio_io(fs_folio, err);
}
static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 03/35] nilfs2: Convert nilfs_segctor_complete_write to use folios
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 01/35] nilfs2: Add nilfs_end_folio_io() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 02/35] nilfs2: Convert nilfs_abort_logs to use folios Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 04/35] nilfs2: Convert nilfs_forget_buffer to use a folio Matthew Wilcox (Oracle)
` (32 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Use the new folio APIs, saving five calls to compound_head().
This includes the last callers of nilfs_end_page_io(), so
remove that too.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/segment.c | 49 +++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 730062e79bfc..2a058aad5c2d 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1778,13 +1778,6 @@ static void nilfs_end_folio_io(struct folio *folio, int err)
folio_end_writeback(folio);
}
-static void nilfs_end_page_io(struct page *page, int err)
-{
- if (!page)
- return;
- nilfs_end_folio_io(page_folio(page), err);
-}
-
static void nilfs_abort_logs(struct list_head *logs, int err)
{
struct nilfs_segment_buffer *segbuf;
@@ -1867,7 +1860,7 @@ static void nilfs_set_next_segment(struct the_nilfs *nilfs,
static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
{
struct nilfs_segment_buffer *segbuf;
- struct page *bd_page = NULL, *fs_page = NULL;
+ struct folio *bd_folio = NULL, *fs_folio = NULL;
struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
int update_sr = false;
@@ -1878,21 +1871,21 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
b_assoc_buffers) {
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
- if (bh->b_page != bd_page) {
- if (bd_page)
- end_page_writeback(bd_page);
- bd_page = bh->b_page;
+ if (bh->b_folio != bd_folio) {
+ if (bd_folio)
+ folio_end_writeback(bd_folio);
+ bd_folio = bh->b_folio;
}
}
/*
- * We assume that the buffers which belong to the same page
+ * We assume that the buffers which belong to the same folio
* continue over the buffer list.
- * Under this assumption, the last BHs of pages is
- * identifiable by the discontinuity of bh->b_page
- * (page != fs_page).
+ * Under this assumption, the last BHs of folios is
+ * identifiable by the discontinuity of bh->b_folio
+ * (folio != fs_folio).
*
* For B-tree node blocks, however, this assumption is not
- * guaranteed. The cleanup code of B-tree node pages needs
+ * guaranteed. The cleanup code of B-tree node folios needs
* special care.
*/
list_for_each_entry(bh, &segbuf->sb_payload_buffers,
@@ -1905,16 +1898,16 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
set_mask_bits(&bh->b_state, clear_bits, set_bits);
if (bh == segbuf->sb_super_root) {
- if (bh->b_page != bd_page) {
- end_page_writeback(bd_page);
- bd_page = bh->b_page;
+ if (bh->b_folio != bd_folio) {
+ folio_end_writeback(bd_folio);
+ bd_folio = bh->b_folio;
}
update_sr = true;
break;
}
- if (bh->b_page != fs_page) {
- nilfs_end_page_io(fs_page, 0);
- fs_page = bh->b_page;
+ if (bh->b_folio != fs_folio) {
+ nilfs_end_folio_io(fs_folio, 0);
+ fs_folio = bh->b_folio;
}
}
@@ -1928,13 +1921,13 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
}
}
/*
- * Since pages may continue over multiple segment buffers,
- * end of the last page must be checked outside of the loop.
+ * Since folios may continue over multiple segment buffers,
+ * end of the last folio must be checked outside of the loop.
*/
- if (bd_page)
- end_page_writeback(bd_page);
+ if (bd_folio)
+ folio_end_writeback(bd_folio);
- nilfs_end_page_io(fs_page, 0);
+ nilfs_end_folio_io(fs_folio, 0);
nilfs_drop_collected_inodes(&sci->sc_dirty_files);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 04/35] nilfs2: Convert nilfs_forget_buffer to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (2 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 03/35] nilfs2: Convert nilfs_segctor_complete_write " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 05/35] nilfs2: Convert to nilfs_folio_buffers_clean() Matthew Wilcox (Oracle)
` (31 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Save two hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 06b04758f289..3882acde1b3e 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -73,7 +73,7 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode,
*/
void nilfs_forget_buffer(struct buffer_head *bh)
{
- struct page *page = bh->b_page;
+ struct folio *folio = bh->b_folio;
const unsigned long clear_bits =
(BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) |
BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
@@ -81,12 +81,12 @@ void nilfs_forget_buffer(struct buffer_head *bh)
lock_buffer(bh);
set_mask_bits(&bh->b_state, clear_bits, 0);
- if (nilfs_page_buffers_clean(page))
- __nilfs_clear_page_dirty(page);
+ if (nilfs_page_buffers_clean(&folio->page))
+ __nilfs_clear_page_dirty(&folio->page);
bh->b_blocknr = -1;
- ClearPageUptodate(page);
- ClearPageMappedToDisk(page);
+ folio_clear_uptodate(folio);
+ folio_clear_mappedtodisk(folio);
unlock_buffer(bh);
brelse(bh);
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 05/35] nilfs2: Convert to nilfs_folio_buffers_clean()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (3 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 04/35] nilfs2: Convert nilfs_forget_buffer to use a folio Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 06/35] nilfs2: Convert nilfs_writepage() to use a folio Matthew Wilcox (Oracle)
` (30 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
All callers of nilfs_page_buffers_clean() now have a folio, so convert
it to take a folio. While I'm at it, make it return a bool.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.c | 18 +++++++++---------
fs/nilfs2/page.h | 2 +-
fs/nilfs2/segment.c | 4 ++--
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 3882acde1b3e..29799a49c234 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -81,7 +81,7 @@ void nilfs_forget_buffer(struct buffer_head *bh)
lock_buffer(bh);
set_mask_bits(&bh->b_state, clear_bits, 0);
- if (nilfs_page_buffers_clean(&folio->page))
+ if (nilfs_folio_buffers_clean(folio))
__nilfs_clear_page_dirty(&folio->page);
bh->b_blocknr = -1;
@@ -131,23 +131,23 @@ void nilfs_copy_buffer(struct buffer_head *dbh, struct buffer_head *sbh)
}
/**
- * nilfs_page_buffers_clean - check if a page has dirty buffers or not.
- * @page: page to be checked
+ * nilfs_folio_buffers_clean - Check if a folio has dirty buffers or not.
+ * @folio: Folio to be checked.
*
- * nilfs_page_buffers_clean() returns zero if the page has dirty buffers.
- * Otherwise, it returns non-zero value.
+ * nilfs_folio_buffers_clean() returns false if the folio has dirty buffers.
+ * Otherwise, it returns true.
*/
-int nilfs_page_buffers_clean(struct page *page)
+bool nilfs_folio_buffers_clean(struct folio *folio)
{
struct buffer_head *bh, *head;
- bh = head = page_buffers(page);
+ bh = head = folio_buffers(folio);
do {
if (buffer_dirty(bh))
- return 0;
+ return false;
bh = bh->b_this_page;
} while (bh != head);
- return 1;
+ return true;
}
void nilfs_page_bug(struct page *page)
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index d249ea1cefff..a8ab800e689c 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -36,7 +36,7 @@ struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *,
unsigned long, unsigned long);
void nilfs_forget_buffer(struct buffer_head *);
void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *);
-int nilfs_page_buffers_clean(struct page *);
+bool nilfs_folio_buffers_clean(struct folio *);
void nilfs_page_bug(struct page *);
int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 2a058aad5c2d..888b8606a1e8 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1759,7 +1759,7 @@ static void nilfs_end_folio_io(struct folio *folio, int err)
* all the buffers get cleaned later.
*/
folio_lock(folio);
- if (nilfs_page_buffers_clean(&folio->page))
+ if (nilfs_folio_buffers_clean(folio))
__nilfs_clear_page_dirty(&folio->page);
folio_unlock(folio);
}
@@ -1767,7 +1767,7 @@ static void nilfs_end_folio_io(struct folio *folio, int err)
}
if (!err) {
- if (!nilfs_page_buffers_clean(&folio->page))
+ if (!nilfs_folio_buffers_clean(folio))
filemap_dirty_folio(folio->mapping, folio);
folio_clear_error(folio);
} else {
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 06/35] nilfs2: Convert nilfs_writepage() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (4 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 05/35] nilfs2: Convert to nilfs_folio_buffers_clean() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 07/35] nilfs2: Convert nilfs_mdt_write_page() " Matthew Wilcox (Oracle)
` (29 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Convert the incoming page to a folio. Replaces three calls to
compound_head() with one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/inode.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index f861f3a0bf5c..c7ec56358a79 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -175,7 +175,8 @@ static int nilfs_writepages(struct address_space *mapping,
static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
{
- struct inode *inode = page->mapping->host;
+ struct folio *folio = page_folio(page);
+ struct inode *inode = folio->mapping->host;
int err;
if (sb_rdonly(inode->i_sb)) {
@@ -186,12 +187,12 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
* So, here we simply discard this dirty page.
*/
nilfs_clear_dirty_page(page, false);
- unlock_page(page);
+ folio_unlock(folio);
return -EROFS;
}
- redirty_page_for_writepage(wbc, page);
- unlock_page(page);
+ folio_redirty_for_writepage(wbc, folio);
+ folio_unlock(folio);
if (wbc->sync_mode == WB_SYNC_ALL) {
err = nilfs_construct_segment(inode->i_sb);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 07/35] nilfs2: Convert nilfs_mdt_write_page() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (5 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 06/35] nilfs2: Convert nilfs_writepage() to use a folio Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 08/35] nilfs2: Convert to nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
` (28 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Convert the incoming page to a folio. Replaces three calls to
compound_head() with one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/mdt.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index c97c77a39668..327408512b86 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -399,7 +399,8 @@ int nilfs_mdt_fetch_dirty(struct inode *inode)
static int
nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
{
- struct inode *inode = page->mapping->host;
+ struct folio *folio = page_folio(page);
+ struct inode *inode = folio->mapping->host;
struct super_block *sb;
int err = 0;
@@ -407,16 +408,16 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
/*
* It means that filesystem was remounted in read-only
* mode because of error or metadata corruption. But we
- * have dirty pages that try to be flushed in background.
- * So, here we simply discard this dirty page.
+ * have dirty folios that try to be flushed in background.
+ * So, here we simply discard this dirty folio.
*/
nilfs_clear_dirty_page(page, false);
- unlock_page(page);
+ folio_unlock(folio);
return -EROFS;
}
- redirty_page_for_writepage(wbc, page);
- unlock_page(page);
+ folio_redirty_for_writepage(wbc, folio);
+ folio_unlock(folio);
if (!inode)
return 0;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 08/35] nilfs2: Convert to nilfs_clear_folio_dirty()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (6 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 07/35] nilfs2: Convert nilfs_mdt_write_page() " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 09/35] nilfs2: Convert to __nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
` (27 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
All callers of nilfs_clear_dirty_page() now have a folio, so rename
the function and pass in the folio. Saves three hidden calls to
compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/inode.c | 2 +-
fs/nilfs2/mdt.c | 2 +-
fs/nilfs2/page.c | 27 ++++++++++++++-------------
fs/nilfs2/page.h | 2 +-
4 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index c7ec56358a79..8fe784f62720 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -186,7 +186,7 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
* have dirty pages that try to be flushed in background.
* So, here we simply discard this dirty page.
*/
- nilfs_clear_dirty_page(page, false);
+ nilfs_clear_folio_dirty(folio, false);
folio_unlock(folio);
return -EROFS;
}
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 327408512b86..2e7952ac2f67 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -411,7 +411,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
* have dirty folios that try to be flushed in background.
* So, here we simply discard this dirty folio.
*/
- nilfs_clear_dirty_page(page, false);
+ nilfs_clear_folio_dirty(folio, false);
folio_unlock(folio);
return -EROFS;
}
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 29799a49c234..48a91ff059f5 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -379,7 +379,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
* was acquired. Skip processing in that case.
*/
if (likely(folio->mapping == mapping))
- nilfs_clear_dirty_page(&folio->page, silent);
+ nilfs_clear_folio_dirty(folio, silent);
folio_unlock(folio);
}
@@ -389,32 +389,33 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
}
/**
- * nilfs_clear_dirty_page - discard dirty page
- * @page: dirty page that will be discarded
+ * nilfs_clear_folio_dirty - discard dirty folio
+ * @folio: dirty folio that will be discarded
* @silent: suppress [true] or print [false] warning messages
*/
-void nilfs_clear_dirty_page(struct page *page, bool silent)
+void nilfs_clear_folio_dirty(struct folio *folio, bool silent)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = folio->mapping->host;
struct super_block *sb = inode->i_sb;
+ struct buffer_head *bh, *head;
- BUG_ON(!PageLocked(page));
+ BUG_ON(!folio_test_locked(folio));
if (!silent)
nilfs_warn(sb, "discard dirty page: offset=%lld, ino=%lu",
- page_offset(page), inode->i_ino);
+ folio_pos(folio), inode->i_ino);
- ClearPageUptodate(page);
- ClearPageMappedToDisk(page);
+ folio_clear_uptodate(folio);
+ folio_clear_mappedtodisk(folio);
- if (page_has_buffers(page)) {
- struct buffer_head *bh, *head;
+ head = folio_buffers(folio);
+ if (head) {
const unsigned long clear_bits =
(BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) |
BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected));
- bh = head = page_buffers(page);
+ bh = head;
do {
lock_buffer(bh);
if (!silent)
@@ -427,7 +428,7 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
} while (bh = bh->b_this_page, bh != head);
}
- __nilfs_clear_page_dirty(page);
+ __nilfs_clear_page_dirty(&folio->page);
}
unsigned int nilfs_page_count_clean_buffers(struct page *page,
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index a8ab800e689c..c419bb1f5b7d 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -41,7 +41,7 @@ void nilfs_page_bug(struct page *);
int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
void nilfs_copy_back_pages(struct address_space *, struct address_space *);
-void nilfs_clear_dirty_page(struct page *, bool);
+void nilfs_clear_folio_dirty(struct folio *, bool);
void nilfs_clear_dirty_pages(struct address_space *, bool);
unsigned int nilfs_page_count_clean_buffers(struct page *, unsigned int,
unsigned int);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 09/35] nilfs2: Convert to __nilfs_clear_folio_dirty()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (7 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 08/35] nilfs2: Convert to nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 10/35] nilfs2: Convert nilfs_segctor_prepare_write to use folios Matthew Wilcox (Oracle)
` (26 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
All callers now have a folio, so convert to pass a folio. No caller
uses the return value, so make it return void. Removes a couple of
hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/page.c | 19 ++++++++++---------
fs/nilfs2/page.h | 2 +-
fs/nilfs2/segment.c | 2 +-
3 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 48a91ff059f5..94e11bcee05b 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -82,7 +82,7 @@ void nilfs_forget_buffer(struct buffer_head *bh)
lock_buffer(bh);
set_mask_bits(&bh->b_state, clear_bits, 0);
if (nilfs_folio_buffers_clean(folio))
- __nilfs_clear_page_dirty(&folio->page);
+ __nilfs_clear_folio_dirty(folio);
bh->b_blocknr = -1;
folio_clear_uptodate(folio);
@@ -428,7 +428,7 @@ void nilfs_clear_folio_dirty(struct folio *folio, bool silent)
} while (bh = bh->b_this_page, bh != head);
}
- __nilfs_clear_page_dirty(&folio->page);
+ __nilfs_clear_folio_dirty(folio);
}
unsigned int nilfs_page_count_clean_buffers(struct page *page,
@@ -458,22 +458,23 @@ unsigned int nilfs_page_count_clean_buffers(struct page *page,
* 2) Some B-tree operations like insertion or deletion may dispose buffers
* in dirty state, and this needs to cancel the dirty state of their pages.
*/
-int __nilfs_clear_page_dirty(struct page *page)
+void __nilfs_clear_folio_dirty(struct folio *folio)
{
- struct address_space *mapping = page->mapping;
+ struct address_space *mapping = folio->mapping;
if (mapping) {
xa_lock_irq(&mapping->i_pages);
- if (test_bit(PG_dirty, &page->flags)) {
- __xa_clear_mark(&mapping->i_pages, page_index(page),
+ if (folio_test_dirty(folio)) {
+ __xa_clear_mark(&mapping->i_pages, folio->index,
PAGECACHE_TAG_DIRTY);
xa_unlock_irq(&mapping->i_pages);
- return clear_page_dirty_for_io(page);
+ folio_clear_dirty_for_io(folio);
+ return;
}
xa_unlock_irq(&mapping->i_pages);
- return 0;
+ return;
}
- return TestClearPageDirty(page);
+ folio_clear_dirty(folio);
}
/**
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index c419bb1f5b7d..968b311d265b 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -30,7 +30,7 @@ BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */
BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy */
-int __nilfs_clear_page_dirty(struct page *);
+void __nilfs_clear_folio_dirty(struct folio *);
struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *,
unsigned long, unsigned long);
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 888b8606a1e8..8c675c118c66 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1760,7 +1760,7 @@ static void nilfs_end_folio_io(struct folio *folio, int err)
*/
folio_lock(folio);
if (nilfs_folio_buffers_clean(folio))
- __nilfs_clear_page_dirty(&folio->page);
+ __nilfs_clear_folio_dirty(folio);
folio_unlock(folio);
}
return;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 10/35] nilfs2: Convert nilfs_segctor_prepare_write to use folios
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (8 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 09/35] nilfs2: Convert to __nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
` (25 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Use the new folio APIs, saving 17 hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/segment.c | 58 ++++++++++++++++++++++-----------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 8c675c118c66..52995838f2de 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1665,39 +1665,39 @@ static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode)
return 0;
}
-static void nilfs_begin_page_io(struct page *page)
+static void nilfs_begin_folio_io(struct folio *folio)
{
- if (!page || PageWriteback(page))
+ if (!folio || folio_test_writeback(folio))
/*
* For split b-tree node pages, this function may be called
* twice. We ignore the 2nd or later calls by this check.
*/
return;
- lock_page(page);
- clear_page_dirty_for_io(page);
- set_page_writeback(page);
- unlock_page(page);
+ folio_lock(folio);
+ folio_clear_dirty_for_io(folio);
+ folio_start_writeback(folio);
+ folio_unlock(folio);
}
static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
{
struct nilfs_segment_buffer *segbuf;
- struct page *bd_page = NULL, *fs_page = NULL;
+ struct folio *bd_folio = NULL, *fs_folio = NULL;
list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
struct buffer_head *bh;
list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
b_assoc_buffers) {
- if (bh->b_page != bd_page) {
- if (bd_page) {
- lock_page(bd_page);
- clear_page_dirty_for_io(bd_page);
- set_page_writeback(bd_page);
- unlock_page(bd_page);
+ if (bh->b_folio != bd_folio) {
+ if (bd_folio) {
+ folio_lock(bd_folio);
+ folio_clear_dirty_for_io(bd_folio);
+ folio_start_writeback(bd_folio);
+ folio_unlock(bd_folio);
}
- bd_page = bh->b_page;
+ bd_folio = bh->b_folio;
}
}
@@ -1705,28 +1705,28 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
b_assoc_buffers) {
set_buffer_async_write(bh);
if (bh == segbuf->sb_super_root) {
- if (bh->b_page != bd_page) {
- lock_page(bd_page);
- clear_page_dirty_for_io(bd_page);
- set_page_writeback(bd_page);
- unlock_page(bd_page);
- bd_page = bh->b_page;
+ if (bh->b_folio != bd_folio) {
+ folio_lock(bd_folio);
+ folio_clear_dirty_for_io(bd_folio);
+ folio_start_writeback(bd_folio);
+ folio_unlock(bd_folio);
+ bd_folio = bh->b_folio;
}
break;
}
- if (bh->b_page != fs_page) {
- nilfs_begin_page_io(fs_page);
- fs_page = bh->b_page;
+ if (bh->b_folio != fs_folio) {
+ nilfs_begin_folio_io(fs_folio);
+ fs_folio = bh->b_folio;
}
}
}
- if (bd_page) {
- lock_page(bd_page);
- clear_page_dirty_for_io(bd_page);
- set_page_writeback(bd_page);
- unlock_page(bd_page);
+ if (bd_folio) {
+ folio_lock(bd_folio);
+ folio_clear_dirty_for_io(bd_folio);
+ folio_start_writeback(bd_folio);
+ folio_unlock(bd_folio);
}
- nilfs_begin_page_io(fs_page);
+ nilfs_begin_folio_io(fs_folio);
}
static int nilfs_segctor_write(struct nilfs_sc_info *sci,
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (9 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 10/35] nilfs2: Convert nilfs_segctor_prepare_write to use folios Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-09 13:11 ` Ryusuke Konishi
2023-11-06 17:38 ` [PATCH 12/35] nilfs2: Convert nilfs_mdt_create_block " Matthew Wilcox (Oracle)
` (24 subsequent siblings)
35 siblings, 1 reply; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Using the new folio APIs saves seven hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/file.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 740ce26d1e76..bec33b89a075 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -45,34 +45,36 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
- struct page *page = vmf->page;
+ struct folio *folio = page_folio(vmf->page);
struct inode *inode = file_inode(vma->vm_file);
struct nilfs_transaction_info ti;
+ struct buffer_head *bh, *head;
int ret = 0;
if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
return VM_FAULT_SIGBUS; /* -ENOSPC */
sb_start_pagefault(inode->i_sb);
- lock_page(page);
- if (page->mapping != inode->i_mapping ||
- page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) {
- unlock_page(page);
+ folio_lock(folio);
+ if (folio->mapping != inode->i_mapping ||
+ folio_pos(folio) >= i_size_read(inode) ||
+ !folio_test_uptodate(folio)) {
+ folio_unlock(folio);
ret = -EFAULT; /* make the VM retry the fault */
goto out;
}
/*
- * check to see if the page is mapped already (no holes)
+ * check to see if the folio is mapped already (no holes)
*/
- if (PageMappedToDisk(page))
+ if (folio_test_mappedtodisk(folio))
goto mapped;
- if (page_has_buffers(page)) {
- struct buffer_head *bh, *head;
+ head = folio_buffers(folio);
+ if (head) {
int fully_mapped = 1;
- bh = head = page_buffers(page);
+ bh = head;
do {
if (!buffer_mapped(bh)) {
fully_mapped = 0;
@@ -81,11 +83,11 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
} while (bh = bh->b_this_page, bh != head);
if (fully_mapped) {
- SetPageMappedToDisk(page);
+ folio_set_mappedtodisk(folio);
goto mapped;
}
}
- unlock_page(page);
+ folio_unlock(folio);
/*
* fill hole blocks
@@ -105,7 +107,7 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
nilfs_transaction_commit(inode->i_sb);
mapped:
- wait_for_stable_page(page);
+ folio_wait_stable(folio);
out:
sb_end_pagefault(inode->i_sb);
return vmf_fs_error(ret);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 12/35] nilfs2: Convert nilfs_mdt_create_block to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (10 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 13/35] nilfs2: Convert nilfs_mdt_submit_block " Matthew Wilcox (Oracle)
` (23 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves two calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/mdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 2e7952ac2f67..7e4dcff2c94b 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -97,8 +97,8 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
}
failed_bh:
- unlock_page(bh->b_page);
- put_page(bh->b_page);
+ folio_unlock(bh->b_folio);
+ folio_put(bh->b_folio);
brelse(bh);
failed_unlock:
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 13/35] nilfs2: Convert nilfs_mdt_submit_block to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (11 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 12/35] nilfs2: Convert nilfs_mdt_create_block " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 14/35] nilfs2: Convert nilfs_gccache_submit_read_data " Matthew Wilcox (Oracle)
` (22 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves two calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/mdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 7e4dcff2c94b..e45c01a559c0 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -158,8 +158,8 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, blk_opf_t opf,
*out_bh = bh;
failed_bh:
- unlock_page(bh->b_page);
- put_page(bh->b_page);
+ folio_unlock(bh->b_folio);
+ folio_put(bh->b_folio);
brelse(bh);
failed:
return ret;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 14/35] nilfs2: Convert nilfs_gccache_submit_read_data to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (12 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 13/35] nilfs2: Convert nilfs_mdt_submit_block " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 15/35] nilfs2: Convert nilfs_btnode_create_block " Matthew Wilcox (Oracle)
` (21 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves two calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/gcinode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index 8beb2730929d..bf9a11d58817 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -98,8 +98,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
*out_bh = bh;
failed:
- unlock_page(bh->b_page);
- put_page(bh->b_page);
+ folio_unlock(bh->b_folio);
+ folio_put(bh->b_folio);
if (unlikely(err))
brelse(bh);
return err;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 15/35] nilfs2: Convert nilfs_btnode_create_block to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (13 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 14/35] nilfs2: Convert nilfs_gccache_submit_read_data " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 16/35] nilfs2: Convert nilfs_btnode_submit_block " Matthew Wilcox (Oracle)
` (20 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves two calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 5710833ac1cc..691a50410ea9 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -64,8 +64,8 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
set_buffer_mapped(bh);
set_buffer_uptodate(bh);
- unlock_page(bh->b_page);
- put_page(bh->b_page);
+ folio_unlock(bh->b_folio);
+ folio_put(bh->b_folio);
return bh;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 16/35] nilfs2: Convert nilfs_btnode_submit_block to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (14 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 15/35] nilfs2: Convert nilfs_btnode_create_block " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 17/35] nilfs2: Convert nilfs_btnode_delete " Matthew Wilcox (Oracle)
` (19 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves two calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 691a50410ea9..5ef9eebd8d2e 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -75,7 +75,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
{
struct buffer_head *bh;
struct inode *inode = btnc->host;
- struct page *page;
+ struct folio *folio;
int err;
bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node));
@@ -83,7 +83,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
return -ENOMEM;
err = -EEXIST; /* internal code */
- page = bh->b_page;
+ folio = bh->b_folio;
if (buffer_uptodate(bh) || buffer_dirty(bh))
goto found;
@@ -130,8 +130,8 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
*pbh = bh;
out_locked:
- unlock_page(page);
- put_page(page);
+ folio_unlock(folio);
+ folio_put(folio);
return err;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 17/35] nilfs2: Convert nilfs_btnode_delete to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (15 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 16/35] nilfs2: Convert nilfs_btnode_submit_block " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 18/35] nilfs2: Convert nilfs_btnode_prepare_change_key " Matthew Wilcox (Oracle)
` (18 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves six calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 5ef9eebd8d2e..e077d4a7a11c 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -145,19 +145,19 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
void nilfs_btnode_delete(struct buffer_head *bh)
{
struct address_space *mapping;
- struct page *page = bh->b_page;
- pgoff_t index = page_index(page);
+ struct folio *folio = bh->b_folio;
+ pgoff_t index = folio->index;
int still_dirty;
- get_page(page);
- lock_page(page);
- wait_on_page_writeback(page);
+ folio_get(folio);
+ folio_lock(folio);
+ folio_wait_writeback(folio);
nilfs_forget_buffer(bh);
- still_dirty = PageDirty(page);
- mapping = page->mapping;
- unlock_page(page);
- put_page(page);
+ still_dirty = folio_test_dirty(folio);
+ mapping = folio->mapping;
+ folio_unlock(folio);
+ folio_put(folio);
if (!still_dirty && mapping)
invalidate_inode_pages2_range(mapping, index, index);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 18/35] nilfs2: Convert nilfs_btnode_prepare_change_key to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (16 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 17/35] nilfs2: Convert nilfs_btnode_delete " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 19/35] nilfs2: Convert nilfs_btnode_commit_change_key " Matthew Wilcox (Oracle)
` (17 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves three calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index e077d4a7a11c..da3e4366625f 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -185,23 +185,23 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
ctxt->newbh = NULL;
if (inode->i_blkbits == PAGE_SHIFT) {
- struct page *opage = obh->b_page;
- lock_page(opage);
+ struct folio *ofolio = obh->b_folio;
+ folio_lock(ofolio);
retry:
/* BUG_ON(oldkey != obh->b_folio->index); */
- if (unlikely(oldkey != opage->index))
- NILFS_PAGE_BUG(opage,
+ if (unlikely(oldkey != ofolio->index))
+ NILFS_PAGE_BUG(&ofolio->page,
"invalid oldkey %lld (newkey=%lld)",
(unsigned long long)oldkey,
(unsigned long long)newkey);
xa_lock_irq(&btnc->i_pages);
- err = __xa_insert(&btnc->i_pages, newkey, opage, GFP_NOFS);
+ err = __xa_insert(&btnc->i_pages, newkey, ofolio, GFP_NOFS);
xa_unlock_irq(&btnc->i_pages);
/*
- * Note: page->index will not change to newkey until
+ * Note: folio->index will not change to newkey until
* nilfs_btnode_commit_change_key() will be called.
- * To protect the page in intermediate state, the page lock
+ * To protect the folio in intermediate state, the folio lock
* is held.
*/
if (!err)
@@ -213,7 +213,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
if (!err)
goto retry;
/* fallback to copy mode */
- unlock_page(opage);
+ folio_unlock(ofolio);
}
nbh = nilfs_btnode_create_block(btnc, newkey);
@@ -225,7 +225,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
return 0;
failed_unlock:
- unlock_page(obh->b_page);
+ folio_unlock(obh->b_folio);
return err;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 19/35] nilfs2: Convert nilfs_btnode_commit_change_key to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (17 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 18/35] nilfs2: Convert nilfs_btnode_prepare_change_key " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 20/35] nilfs2: Convert nilfs_btnode_abort_change_key " Matthew Wilcox (Oracle)
` (16 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves one call to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index da3e4366625f..fb1638765d54 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -238,15 +238,15 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
{
struct buffer_head *obh = ctxt->bh, *nbh = ctxt->newbh;
__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
- struct page *opage;
+ struct folio *ofolio;
if (oldkey == newkey)
return;
if (nbh == NULL) { /* blocksize == pagesize */
- opage = obh->b_page;
- if (unlikely(oldkey != opage->index))
- NILFS_PAGE_BUG(opage,
+ ofolio = obh->b_folio;
+ if (unlikely(oldkey != ofolio->index))
+ NILFS_PAGE_BUG(&ofolio->page,
"invalid oldkey %lld (newkey=%lld)",
(unsigned long long)oldkey,
(unsigned long long)newkey);
@@ -257,8 +257,8 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
__xa_set_mark(&btnc->i_pages, newkey, PAGECACHE_TAG_DIRTY);
xa_unlock_irq(&btnc->i_pages);
- opage->index = obh->b_blocknr = newkey;
- unlock_page(opage);
+ ofolio->index = obh->b_blocknr = newkey;
+ folio_unlock(ofolio);
} else {
nilfs_copy_buffer(nbh, obh);
mark_buffer_dirty(nbh);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 20/35] nilfs2: Convert nilfs_btnode_abort_change_key to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (18 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 19/35] nilfs2: Convert nilfs_btnode_commit_change_key " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 21/35] nilfs2: Remove page_address() from nilfs_set_link Matthew Wilcox (Oracle)
` (15 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Saves one call to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index fb1638765d54..1204dd06ead8 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -284,7 +284,7 @@ void nilfs_btnode_abort_change_key(struct address_space *btnc,
if (nbh == NULL) { /* blocksize == pagesize */
xa_erase_irq(&btnc->i_pages, newkey);
- unlock_page(ctxt->bh->b_page);
+ folio_unlock(ctxt->bh->b_folio);
} else {
/*
* When canceling a buffer that a prepare operation has
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 21/35] nilfs2: Remove page_address() from nilfs_set_link
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (19 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 20/35] nilfs2: Convert nilfs_btnode_abort_change_key " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 22/35] nilfs2: Remove page_address() from nilfs_add_link Matthew Wilcox (Oracle)
` (14 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
In preparation for removing kmap from directory handling, use
offset_in_page() to calculate 'from'. Matches ext2.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index de2073c47651..683101dcbddf 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -417,7 +417,7 @@ ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
struct page *page, struct inode *inode)
{
- unsigned int from = (char *)de - (char *)page_address(page);
+ unsigned int from = offset_in_page(de);
unsigned int to = from + nilfs_rec_len_from_disk(de->rec_len);
struct address_space *mapping = page->mapping;
int err;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 22/35] nilfs2: Remove page_address() from nilfs_add_link
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (20 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 21/35] nilfs2: Remove page_address() from nilfs_set_link Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 23/35] nilfs2: Remove page_address() from nilfs_delete_entry Matthew Wilcox (Oracle)
` (13 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
In preparation for removing kmap from directory handling, use
offset_in_page() to calculate 'from'. Matches ext2.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 683101dcbddf..0cf4fe91aebe 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -501,7 +501,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
return -EINVAL;
got_it:
- from = (char *)de - (char *)page_address(page);
+ from = offset_in_page(de);
to = from + rec_len;
err = nilfs_prepare_chunk(page, from, to);
if (err)
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 23/35] nilfs2: Remove page_address() from nilfs_delete_entry
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (21 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 22/35] nilfs2: Remove page_address() from nilfs_add_link Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 24/35] nilfs2: Return the mapped address from nilfs_get_page() Matthew Wilcox (Oracle)
` (12 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
In preparation for removing kmap from directory handling, mask
the directory entry pointer to discover the start address of the
page. Matches ext2.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 0cf4fe91aebe..07a906d0c786 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -539,7 +539,7 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
{
struct address_space *mapping = page->mapping;
struct inode *inode = mapping->host;
- char *kaddr = page_address(page);
+ char *kaddr = (char *)((unsigned long)dir & PAGE_MASK);
unsigned int from, to;
struct nilfs_dir_entry *de, *pde = NULL;
int err;
@@ -559,7 +559,7 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
de = nilfs_next_entry(de);
}
if (pde)
- from = (char *)pde - (char *)page_address(page);
+ from = (char *)pde - kaddr;
lock_page(page);
err = nilfs_prepare_chunk(page, from, to);
BUG_ON(err);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 24/35] nilfs2: Return the mapped address from nilfs_get_page()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (22 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 23/35] nilfs2: Remove page_address() from nilfs_delete_entry Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 25/35] nilfs2: Pass the mapped address to nilfs_check_page() Matthew Wilcox (Oracle)
` (11 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
In prepartion for switching from kmap() to kmap_local(), return
the kmap address from nilfs_get_page() instead of having the caller
look up page_address().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 58 +++++++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 31 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 07a906d0c786..0308b618fb87 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -186,19 +186,24 @@ static bool nilfs_check_page(struct page *page)
return false;
}
-static struct page *nilfs_get_page(struct inode *dir, unsigned long n)
+static void *nilfs_get_page(struct inode *dir, unsigned long n,
+ struct page **pagep)
{
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
+ void *kaddr;
- if (!IS_ERR(page)) {
- kmap(page);
- if (unlikely(!PageChecked(page))) {
- if (!nilfs_check_page(page))
- goto fail;
- }
+ if (IS_ERR(page))
+ return page;
+
+ kaddr = kmap(page);
+ if (unlikely(!PageChecked(page))) {
+ if (!nilfs_check_page(page))
+ goto fail;
}
- return page;
+
+ *pagep = page;
+ return kaddr;
fail:
nilfs_put_page(page);
@@ -275,14 +280,14 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
for ( ; n < npages; n++, offset = 0) {
char *kaddr, *limit;
struct nilfs_dir_entry *de;
- struct page *page = nilfs_get_page(inode, n);
+ struct page *page;
- if (IS_ERR(page)) {
+ kaddr = nilfs_get_page(inode, n, &page);
+ if (IS_ERR(kaddr)) {
nilfs_error(sb, "bad page in #%lu", inode->i_ino);
ctx->pos += PAGE_SIZE - offset;
return -EIO;
}
- kaddr = page_address(page);
de = (struct nilfs_dir_entry *)(kaddr + offset);
limit = kaddr + nilfs_last_byte(inode, n) -
NILFS_DIR_REC_LEN(1);
@@ -345,11 +350,8 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
start = 0;
n = start;
do {
- char *kaddr;
-
- page = nilfs_get_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
+ char *kaddr = nilfs_get_page(dir, n, &page);
+ if (!IS_ERR(kaddr)) {
de = (struct nilfs_dir_entry *)kaddr;
kaddr += nilfs_last_byte(dir, n) - reclen;
while ((char *) de <= kaddr) {
@@ -387,15 +389,11 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p)
{
- struct page *page = nilfs_get_page(dir, 0);
- struct nilfs_dir_entry *de = NULL;
+ struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p);
- if (!IS_ERR(page)) {
- de = nilfs_next_entry(
- (struct nilfs_dir_entry *)page_address(page));
- *p = page;
- }
- return de;
+ if (IS_ERR(de))
+ return NULL;
+ return nilfs_next_entry(de);
}
ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
@@ -459,12 +457,11 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
for (n = 0; n <= npages; n++) {
char *dir_end;
- page = nilfs_get_page(dir, n);
- err = PTR_ERR(page);
- if (IS_ERR(page))
+ kaddr = nilfs_get_page(dir, n, &page);
+ err = PTR_ERR(kaddr);
+ if (IS_ERR(kaddr))
goto out;
lock_page(page);
- kaddr = page_address(page);
dir_end = kaddr + nilfs_last_byte(dir, n);
de = (struct nilfs_dir_entry *)kaddr;
kaddr += PAGE_SIZE - reclen;
@@ -627,11 +624,10 @@ int nilfs_empty_dir(struct inode *inode)
char *kaddr;
struct nilfs_dir_entry *de;
- page = nilfs_get_page(inode, i);
- if (IS_ERR(page))
+ kaddr = nilfs_get_page(inode, i, &page);
+ if (IS_ERR(kaddr))
continue;
- kaddr = page_address(page);
de = (struct nilfs_dir_entry *)kaddr;
kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 25/35] nilfs2: Pass the mapped address to nilfs_check_page()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (23 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 24/35] nilfs2: Return the mapped address from nilfs_get_page() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 26/35] nilfs2: Switch to kmap_local for directory handling Matthew Wilcox (Oracle)
` (10 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Remove another use of page_address() as part of preparing for
the kmap to kmap_local transition.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 0308b618fb87..1ae370521249 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -113,12 +113,11 @@ static void nilfs_commit_chunk(struct page *page,
unlock_page(page);
}
-static bool nilfs_check_page(struct page *page)
+static bool nilfs_check_page(struct page *page, char *kaddr)
{
struct inode *dir = page->mapping->host;
struct super_block *sb = dir->i_sb;
unsigned int chunk_size = nilfs_chunk_size(dir);
- char *kaddr = page_address(page);
unsigned int offs, rec_len;
unsigned int limit = PAGE_SIZE;
struct nilfs_dir_entry *p;
@@ -198,7 +197,7 @@ static void *nilfs_get_page(struct inode *dir, unsigned long n,
kaddr = kmap(page);
if (unlikely(!PageChecked(page))) {
- if (!nilfs_check_page(page))
+ if (!nilfs_check_page(page, kaddr))
goto fail;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 26/35] nilfs2: Switch to kmap_local for directory handling
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (24 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 25/35] nilfs2: Pass the mapped address to nilfs_check_page() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 27/35] nilfs2: Add nilfs_get_folio() Matthew Wilcox (Oracle)
` (9 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Match ext2 by using kmap_local() instead of kmap(). This is more
efficient. Also use unmap_and_put_page() instead of duplicating
it as a nilfs function.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 37 +++++++++++++++----------------------
fs/nilfs2/namei.c | 9 +++------
2 files changed, 18 insertions(+), 28 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 1ae370521249..01c57573211e 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -64,12 +64,6 @@ static inline unsigned int nilfs_chunk_size(struct inode *inode)
return inode->i_sb->s_blocksize;
}
-static inline void nilfs_put_page(struct page *page)
-{
- kunmap(page);
- put_page(page);
-}
-
/*
* Return the offset into page `page_nr' of the last valid
* byte in that page, plus one.
@@ -195,7 +189,7 @@ static void *nilfs_get_page(struct inode *dir, unsigned long n,
if (IS_ERR(page))
return page;
- kaddr = kmap(page);
+ kaddr = kmap_local_page(page);
if (unlikely(!PageChecked(page))) {
if (!nilfs_check_page(page, kaddr))
goto fail;
@@ -205,7 +199,7 @@ static void *nilfs_get_page(struct inode *dir, unsigned long n,
return kaddr;
fail:
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
return ERR_PTR(-EIO);
}
@@ -293,7 +287,7 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
for ( ; (char *)de <= limit; de = nilfs_next_entry(de)) {
if (de->rec_len == 0) {
nilfs_error(sb, "zero-length directory entry");
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
return -EIO;
}
if (de->inode) {
@@ -306,13 +300,13 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
if (!dir_emit(ctx, de->name, de->name_len,
le64_to_cpu(de->inode), t)) {
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
return 0;
}
}
ctx->pos += nilfs_rec_len_from_disk(de->rec_len);
}
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
}
return 0;
}
@@ -357,14 +351,14 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
if (de->rec_len == 0) {
nilfs_error(dir->i_sb,
"zero-length directory entry");
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
goto out;
}
if (nilfs_match(namelen, name, de))
goto found;
de = nilfs_next_entry(de);
}
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
}
if (++n >= npages)
n = 0;
@@ -404,8 +398,7 @@ ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
de = nilfs_find_entry(dir, qstr, &page);
if (de) {
res = le64_to_cpu(de->inode);
- kunmap(page);
- put_page(page);
+ unmap_and_put_page(page, de);
}
return res;
}
@@ -425,7 +418,7 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
nilfs_commit_chunk(page, mapping, from, to);
- nilfs_put_page(page);
+ unmap_and_put_page(page, de);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -491,7 +484,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
de = (struct nilfs_dir_entry *)((char *)de + rec_len);
}
unlock_page(page);
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
}
BUG();
return -EINVAL;
@@ -519,7 +512,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
nilfs_mark_inode_dirty(dir);
/* OFFSET_CACHE */
out_put:
- nilfs_put_page(page);
+ unmap_and_put_page(page, de);
out:
return err;
out_unlock:
@@ -565,7 +558,7 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
nilfs_commit_chunk(page, mapping, from, to);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
out:
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
return err;
}
@@ -617,10 +610,10 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
int nilfs_empty_dir(struct inode *inode)
{
struct page *page = NULL;
+ char *kaddr;
unsigned long i, npages = dir_pages(inode);
for (i = 0; i < npages; i++) {
- char *kaddr;
struct nilfs_dir_entry *de;
kaddr = nilfs_get_page(inode, i, &page);
@@ -652,12 +645,12 @@ int nilfs_empty_dir(struct inode *inode)
}
de = nilfs_next_entry(de);
}
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
}
return 1;
not_empty:
- nilfs_put_page(page);
+ unmap_and_put_page(page, kaddr);
return 0;
}
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 2a4e7f4a8102..8eebd8a464d8 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -421,13 +421,10 @@ static int nilfs_rename(struct mnt_idmap *idmap,
return err;
out_dir:
- if (dir_de) {
- kunmap(dir_page);
- put_page(dir_page);
- }
+ if (dir_de)
+ unmap_and_put_page(dir_page, dir_de);
out_old:
- kunmap(old_page);
- put_page(old_page);
+ unmap_and_put_page(old_page, old_de);
out:
nilfs_transaction_abort(old_dir->i_sb);
return err;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 27/35] nilfs2: Add nilfs_get_folio()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (25 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 26/35] nilfs2: Switch to kmap_local for directory handling Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 28/35] nilfs2: Convert nilfs_readdir to use a folio Matthew Wilcox (Oracle)
` (8 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Convert nilfs_get_page() to be a wrapper.
Also convert nilfs_check_page() to nilfs_check_folio().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 53 +++++++++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 01c57573211e..9e3339123d89 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -107,18 +107,18 @@ static void nilfs_commit_chunk(struct page *page,
unlock_page(page);
}
-static bool nilfs_check_page(struct page *page, char *kaddr)
+static bool nilfs_check_folio(struct folio *folio, char *kaddr)
{
- struct inode *dir = page->mapping->host;
+ struct inode *dir = folio->mapping->host;
struct super_block *sb = dir->i_sb;
unsigned int chunk_size = nilfs_chunk_size(dir);
- unsigned int offs, rec_len;
- unsigned int limit = PAGE_SIZE;
+ size_t offs, rec_len;
+ size_t limit = folio_size(folio);
struct nilfs_dir_entry *p;
char *error;
- if ((dir->i_size >> PAGE_SHIFT) == page->index) {
- limit = dir->i_size & ~PAGE_MASK;
+ if (dir->i_size < folio_pos(folio) + limit) {
+ limit = dir->i_size - folio_pos(folio);
if (limit & (chunk_size - 1))
goto Ebadsize;
if (!limit)
@@ -140,7 +140,7 @@ static bool nilfs_check_page(struct page *page, char *kaddr)
if (offs != limit)
goto Eend;
out:
- SetPageChecked(page);
+ folio_set_checked(folio);
return true;
/* Too bad, we had an error */
@@ -163,8 +163,8 @@ static bool nilfs_check_page(struct page *page, char *kaddr)
error = "directory entry across blocks";
bad_entry:
nilfs_error(sb,
- "bad entry in directory #%lu: %s - offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index << PAGE_SHIFT) + offs,
+ "bad entry in directory #%lu: %s - offset=%lu, inode=%lu, rec_len=%zd, name_len=%d",
+ dir->i_ino, error, (folio->index << PAGE_SHIFT) + offs,
(unsigned long)le64_to_cpu(p->inode),
rec_len, p->name_len);
goto fail;
@@ -172,37 +172,48 @@ static bool nilfs_check_page(struct page *page, char *kaddr)
p = (struct nilfs_dir_entry *)(kaddr + offs);
nilfs_error(sb,
"entry in directory #%lu spans the page boundary offset=%lu, inode=%lu",
- dir->i_ino, (page->index << PAGE_SHIFT) + offs,
+ dir->i_ino, (folio->index << PAGE_SHIFT) + offs,
(unsigned long)le64_to_cpu(p->inode));
fail:
- SetPageError(page);
+ folio_set_error(folio);
return false;
}
-static void *nilfs_get_page(struct inode *dir, unsigned long n,
- struct page **pagep)
+static void *nilfs_get_folio(struct inode *dir, unsigned long n,
+ struct folio **foliop)
{
struct address_space *mapping = dir->i_mapping;
- struct page *page = read_mapping_page(mapping, n, NULL);
+ struct folio *folio = read_mapping_folio(mapping, n, NULL);
void *kaddr;
- if (IS_ERR(page))
- return page;
+ if (IS_ERR(folio))
+ return folio;
- kaddr = kmap_local_page(page);
- if (unlikely(!PageChecked(page))) {
- if (!nilfs_check_page(page, kaddr))
+ kaddr = kmap_local_folio(folio, 0);
+ if (unlikely(!folio_test_checked(folio))) {
+ if (!nilfs_check_folio(folio, kaddr))
goto fail;
}
- *pagep = page;
+ *foliop = folio;
return kaddr;
fail:
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
return ERR_PTR(-EIO);
}
+static void *nilfs_get_page(struct inode *dir, unsigned long n,
+ struct page **pagep)
+{
+ struct folio *folio;
+ void *kaddr = nilfs_get_folio(dir, n, &folio);
+
+ if (!IS_ERR(kaddr))
+ *pagep = &folio->page;
+ return kaddr;
+}
+
/*
* NOTE! unlike strncmp, nilfs_match returns 1 for success, 0 for failure.
*
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 28/35] nilfs2: Convert nilfs_readdir to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (26 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 27/35] nilfs2: Add nilfs_get_folio() Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 29/35] nilfs2: Convert nilfs_find_entry " Matthew Wilcox (Oracle)
` (7 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Use the new folio APIs to remove calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 9e3339123d89..8d74f1d9bb62 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -284,9 +284,9 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
for ( ; n < npages; n++, offset = 0) {
char *kaddr, *limit;
struct nilfs_dir_entry *de;
- struct page *page;
+ struct folio *folio;
- kaddr = nilfs_get_page(inode, n, &page);
+ kaddr = nilfs_get_folio(inode, n, &folio);
if (IS_ERR(kaddr)) {
nilfs_error(sb, "bad page in #%lu", inode->i_ino);
ctx->pos += PAGE_SIZE - offset;
@@ -298,7 +298,7 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
for ( ; (char *)de <= limit; de = nilfs_next_entry(de)) {
if (de->rec_len == 0) {
nilfs_error(sb, "zero-length directory entry");
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
return -EIO;
}
if (de->inode) {
@@ -311,13 +311,13 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
if (!dir_emit(ctx, de->name, de->name_len,
le64_to_cpu(de->inode), t)) {
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
return 0;
}
}
ctx->pos += nilfs_rec_len_from_disk(de->rec_len);
}
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
}
return 0;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 29/35] nilfs2: Convert nilfs_find_entry to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (27 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 28/35] nilfs2: Convert nilfs_readdir to use a folio Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 30/35] nilfs2: Convert nilfs_rename() to use folios Matthew Wilcox (Oracle)
` (6 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Use the new folio APIs to remove calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 8d74f1d9bb62..9f2a02b71ddc 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -339,7 +339,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
unsigned int reclen = NILFS_DIR_REC_LEN(namelen);
unsigned long start, n;
unsigned long npages = dir_pages(dir);
- struct page *page = NULL;
+ struct folio *folio = NULL;
struct nilfs_inode_info *ei = NILFS_I(dir);
struct nilfs_dir_entry *de;
@@ -354,7 +354,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
start = 0;
n = start;
do {
- char *kaddr = nilfs_get_page(dir, n, &page);
+ char *kaddr = nilfs_get_folio(dir, n, &folio);
if (!IS_ERR(kaddr)) {
de = (struct nilfs_dir_entry *)kaddr;
kaddr += nilfs_last_byte(dir, n) - reclen;
@@ -362,18 +362,18 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
if (de->rec_len == 0) {
nilfs_error(dir->i_sb,
"zero-length directory entry");
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
goto out;
}
if (nilfs_match(namelen, name, de))
goto found;
de = nilfs_next_entry(de);
}
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
}
if (++n >= npages)
n = 0;
- /* next page is past the blocks we've got */
+ /* next folio is past the blocks we've got */
if (unlikely(n > (dir->i_blocks >> (PAGE_SHIFT - 9)))) {
nilfs_error(dir->i_sb,
"dir %lu size %lld exceeds block count %llu",
@@ -386,7 +386,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
return NULL;
found:
- *res_page = page;
+ *res_page = &folio->page;
ei->i_dir_start_lookup = n;
return de;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 30/35] nilfs2: Convert nilfs_rename() to use folios
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (28 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 29/35] nilfs2: Convert nilfs_find_entry " Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 31/35] nilfs2: Convert nilfs_add_link() to use a folio Matthew Wilcox (Oracle)
` (5 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
This involves converting nilfs_find_entry(), nilfs_dotdot(),
nilfs_set_link(), nilfs_delete_entry() and nilfs_do_unlink()
to use folios as well.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 74 ++++++++++++++++++++++-------------------------
fs/nilfs2/namei.c | 28 +++++++++---------
fs/nilfs2/nilfs.h | 20 ++++++-------
3 files changed, 59 insertions(+), 63 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 9f2a02b71ddc..25a468dda0f3 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -323,38 +323,35 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
}
/*
- * nilfs_find_entry()
+ * nilfs_find_entry()
*
- * finds an entry in the specified directory with the wanted name. It
- * returns the page in which the entry was found, and the entry itself
- * (as a parameter - res_dir). Page is returned mapped and unlocked.
- * Entry is guaranteed to be valid.
+ * Finds an entry in the specified directory with the wanted name. It
+ * returns the folio in which the entry was found, and the entry itself.
+ * The folio is mapped and unlocked. When the caller is finished with
+ * the entry, it should call folio_release_kmap().
+ *
+ * On failure, returns NULL and the caller should ignore foliop.
*/
-struct nilfs_dir_entry *
-nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
- struct page **res_page)
+struct nilfs_dir_entry *nilfs_find_entry(struct inode *dir,
+ const struct qstr *qstr, struct folio **foliop)
{
const unsigned char *name = qstr->name;
int namelen = qstr->len;
unsigned int reclen = NILFS_DIR_REC_LEN(namelen);
unsigned long start, n;
unsigned long npages = dir_pages(dir);
- struct folio *folio = NULL;
struct nilfs_inode_info *ei = NILFS_I(dir);
struct nilfs_dir_entry *de;
if (npages == 0)
goto out;
- /* OFFSET_CACHE */
- *res_page = NULL;
-
start = ei->i_dir_start_lookup;
if (start >= npages)
start = 0;
n = start;
do {
- char *kaddr = nilfs_get_folio(dir, n, &folio);
+ char *kaddr = nilfs_get_folio(dir, n, foliop);
if (!IS_ERR(kaddr)) {
de = (struct nilfs_dir_entry *)kaddr;
kaddr += nilfs_last_byte(dir, n) - reclen;
@@ -362,14 +359,14 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
if (de->rec_len == 0) {
nilfs_error(dir->i_sb,
"zero-length directory entry");
- folio_release_kmap(folio, kaddr);
+ folio_release_kmap(*foliop, kaddr);
goto out;
}
if (nilfs_match(namelen, name, de))
goto found;
de = nilfs_next_entry(de);
}
- folio_release_kmap(folio, kaddr);
+ folio_release_kmap(*foliop, kaddr);
}
if (++n >= npages)
n = 0;
@@ -386,14 +383,13 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
return NULL;
found:
- *res_page = &folio->page;
ei->i_dir_start_lookup = n;
return de;
}
-struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p)
+struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct folio **foliop)
{
- struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p);
+ struct nilfs_dir_entry *de = nilfs_get_folio(dir, 0, foliop);
if (IS_ERR(de))
return NULL;
@@ -404,32 +400,32 @@ ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
{
ino_t res = 0;
struct nilfs_dir_entry *de;
- struct page *page;
+ struct folio *folio;
- de = nilfs_find_entry(dir, qstr, &page);
+ de = nilfs_find_entry(dir, qstr, &folio);
if (de) {
res = le64_to_cpu(de->inode);
- unmap_and_put_page(page, de);
+ folio_release_kmap(folio, de);
}
return res;
}
-/* Releases the page */
+/* Releases the folio */
void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
- struct page *page, struct inode *inode)
+ struct folio *folio, struct inode *inode)
{
- unsigned int from = offset_in_page(de);
- unsigned int to = from + nilfs_rec_len_from_disk(de->rec_len);
- struct address_space *mapping = page->mapping;
+ size_t from = offset_in_folio(folio, de);
+ size_t to = from + nilfs_rec_len_from_disk(de->rec_len);
+ struct address_space *mapping = folio->mapping;
int err;
- lock_page(page);
- err = nilfs_prepare_chunk(page, from, to);
+ folio_lock(folio);
+ err = nilfs_prepare_chunk(&folio->page, from, to);
BUG_ON(err);
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
- nilfs_commit_chunk(page, mapping, from, to);
- unmap_and_put_page(page, de);
+ nilfs_commit_chunk(&folio->page, mapping, from, to);
+ folio_release_kmap(folio, de);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -533,14 +529,14 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
/*
* nilfs_delete_entry deletes a directory entry by merging it with the
- * previous entry. Page is up-to-date. Releases the page.
+ * previous entry. Folio is up-to-date. Releases the folio.
*/
-int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
+int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct folio *folio)
{
- struct address_space *mapping = page->mapping;
+ struct address_space *mapping = folio->mapping;
struct inode *inode = mapping->host;
- char *kaddr = (char *)((unsigned long)dir & PAGE_MASK);
- unsigned int from, to;
+ char *kaddr = (char *)((unsigned long)dir & ~(folio_size(folio) - 1));
+ size_t from, to;
struct nilfs_dir_entry *de, *pde = NULL;
int err;
@@ -560,16 +556,16 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
}
if (pde)
from = (char *)pde - kaddr;
- lock_page(page);
- err = nilfs_prepare_chunk(page, from, to);
+ folio_lock(folio);
+ err = nilfs_prepare_chunk(&folio->page, from, to);
BUG_ON(err);
if (pde)
pde->rec_len = nilfs_rec_len_to_disk(to - from);
dir->inode = 0;
- nilfs_commit_chunk(page, mapping, from, to);
+ nilfs_commit_chunk(&folio->page, mapping, from, to);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
out:
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
return err;
}
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 8eebd8a464d8..d9d23f3cc4d7 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -260,11 +260,11 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode;
struct nilfs_dir_entry *de;
- struct page *page;
+ struct folio *folio;
int err;
err = -ENOENT;
- de = nilfs_find_entry(dir, &dentry->d_name, &page);
+ de = nilfs_find_entry(dir, &dentry->d_name, &folio);
if (!de)
goto out;
@@ -279,7 +279,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
inode->i_ino, inode->i_nlink);
set_nlink(inode, 1);
}
- err = nilfs_delete_entry(de, page);
+ err = nilfs_delete_entry(de, folio);
if (err)
goto out;
@@ -347,9 +347,9 @@ static int nilfs_rename(struct mnt_idmap *idmap,
{
struct inode *old_inode = d_inode(old_dentry);
struct inode *new_inode = d_inode(new_dentry);
- struct page *dir_page = NULL;
+ struct folio *dir_folio = NULL;
struct nilfs_dir_entry *dir_de = NULL;
- struct page *old_page;
+ struct folio *old_folio;
struct nilfs_dir_entry *old_de;
struct nilfs_transaction_info ti;
int err;
@@ -362,19 +362,19 @@ static int nilfs_rename(struct mnt_idmap *idmap,
return err;
err = -ENOENT;
- old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
+ old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_folio);
if (!old_de)
goto out;
if (S_ISDIR(old_inode->i_mode)) {
err = -EIO;
- dir_de = nilfs_dotdot(old_inode, &dir_page);
+ dir_de = nilfs_dotdot(old_inode, &dir_folio);
if (!dir_de)
goto out_old;
}
if (new_inode) {
- struct page *new_page;
+ struct folio *new_folio;
struct nilfs_dir_entry *new_de;
err = -ENOTEMPTY;
@@ -382,10 +382,10 @@ static int nilfs_rename(struct mnt_idmap *idmap,
goto out_dir;
err = -ENOENT;
- new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page);
+ new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_folio);
if (!new_de)
goto out_dir;
- nilfs_set_link(new_dir, new_de, new_page, old_inode);
+ nilfs_set_link(new_dir, new_de, new_folio, old_inode);
nilfs_mark_inode_dirty(new_dir);
inode_set_ctime_current(new_inode);
if (dir_de)
@@ -408,10 +408,10 @@ static int nilfs_rename(struct mnt_idmap *idmap,
*/
inode_set_ctime_current(old_inode);
- nilfs_delete_entry(old_de, old_page);
+ nilfs_delete_entry(old_de, old_folio);
if (dir_de) {
- nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
+ nilfs_set_link(old_inode, dir_de, dir_folio, new_dir);
drop_nlink(old_dir);
}
nilfs_mark_inode_dirty(old_dir);
@@ -422,9 +422,9 @@ static int nilfs_rename(struct mnt_idmap *idmap,
out_dir:
if (dir_de)
- unmap_and_put_page(dir_page, dir_de);
+ folio_release_kmap(dir_folio, dir_de);
out_old:
- unmap_and_put_page(old_page, old_de);
+ folio_release_kmap(old_folio, old_de);
out:
nilfs_transaction_abort(old_dir->i_sb);
return err;
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 8046490cd7fe..98cffaf0ac12 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -226,16 +226,16 @@ static inline __u32 nilfs_mask_flags(umode_t mode, __u32 flags)
}
/* dir.c */
-extern int nilfs_add_link(struct dentry *, struct inode *);
-extern ino_t nilfs_inode_by_name(struct inode *, const struct qstr *);
-extern int nilfs_make_empty(struct inode *, struct inode *);
-extern struct nilfs_dir_entry *
-nilfs_find_entry(struct inode *, const struct qstr *, struct page **);
-extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *);
-extern int nilfs_empty_dir(struct inode *);
-extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **);
-extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
- struct page *, struct inode *);
+int nilfs_add_link(struct dentry *, struct inode *);
+ino_t nilfs_inode_by_name(struct inode *, const struct qstr *);
+int nilfs_make_empty(struct inode *, struct inode *);
+struct nilfs_dir_entry *nilfs_find_entry(struct inode *, const struct qstr *,
+ struct folio **);
+int nilfs_delete_entry(struct nilfs_dir_entry *, struct folio *);
+int nilfs_empty_dir(struct inode *);
+struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct folio **);
+void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
+ struct folio *, struct inode *);
/* file.c */
extern int nilfs_sync_file(struct file *, loff_t, loff_t, int);
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 31/35] nilfs2: Convert nilfs_add_link() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (29 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 30/35] nilfs2: Convert nilfs_rename() to use folios Matthew Wilcox (Oracle)
@ 2023-11-06 17:38 ` Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 32/35] nilfs2: Convert nilfs_empty_dir() " Matthew Wilcox (Oracle)
` (4 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:38 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Remove six calls to compound_head() by using the folio API.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 25a468dda0f3..fd4f99a7f402 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -440,30 +440,28 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
unsigned int chunk_size = nilfs_chunk_size(dir);
unsigned int reclen = NILFS_DIR_REC_LEN(namelen);
unsigned short rec_len, name_len;
- struct page *page = NULL;
+ struct folio *folio = NULL;
struct nilfs_dir_entry *de;
unsigned long npages = dir_pages(dir);
unsigned long n;
- char *kaddr;
- unsigned int from, to;
+ size_t from, to;
int err;
/*
* We take care of directory expansion in the same loop.
- * This code plays outside i_size, so it locks the page
+ * This code plays outside i_size, so it locks the folio
* to protect that region.
*/
for (n = 0; n <= npages; n++) {
+ char *kaddr = nilfs_get_folio(dir, n, &folio);
char *dir_end;
- kaddr = nilfs_get_page(dir, n, &page);
- err = PTR_ERR(kaddr);
if (IS_ERR(kaddr))
- goto out;
- lock_page(page);
+ return PTR_ERR(kaddr);
+ folio_lock(folio);
dir_end = kaddr + nilfs_last_byte(dir, n);
de = (struct nilfs_dir_entry *)kaddr;
- kaddr += PAGE_SIZE - reclen;
+ kaddr += folio_size(folio) - reclen;
while ((char *)de <= kaddr) {
if ((char *)de == dir_end) {
/* We hit i_size */
@@ -490,16 +488,16 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
goto got_it;
de = (struct nilfs_dir_entry *)((char *)de + rec_len);
}
- unlock_page(page);
- unmap_and_put_page(page, kaddr);
+ folio_unlock(folio);
+ folio_release_kmap(folio, kaddr);
}
BUG();
return -EINVAL;
got_it:
- from = offset_in_page(de);
+ from = offset_in_folio(folio, de);
to = from + rec_len;
- err = nilfs_prepare_chunk(page, from, to);
+ err = nilfs_prepare_chunk(&folio->page, from, to);
if (err)
goto out_unlock;
if (de->inode) {
@@ -514,16 +512,15 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
memcpy(de->name, name, namelen);
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
- nilfs_commit_chunk(page, page->mapping, from, to);
+ nilfs_commit_chunk(&folio->page, folio->mapping, from, to);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
nilfs_mark_inode_dirty(dir);
/* OFFSET_CACHE */
out_put:
- unmap_and_put_page(page, de);
-out:
+ folio_release_kmap(folio, de);
return err;
out_unlock:
- unlock_page(page);
+ folio_unlock(folio);
goto out_put;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 32/35] nilfs2: Convert nilfs_empty_dir() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (30 preceding siblings ...)
2023-11-06 17:38 ` [PATCH 31/35] nilfs2: Convert nilfs_add_link() to use a folio Matthew Wilcox (Oracle)
@ 2023-11-06 17:39 ` Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 33/35] nilfs2: Convert nilfs_make_empty() " Matthew Wilcox (Oracle)
` (3 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:39 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Remove three calls to compound_head() by using the folio API.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index fd4f99a7f402..e598431516fc 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -203,17 +203,6 @@ static void *nilfs_get_folio(struct inode *dir, unsigned long n,
return ERR_PTR(-EIO);
}
-static void *nilfs_get_page(struct inode *dir, unsigned long n,
- struct page **pagep)
-{
- struct folio *folio;
- void *kaddr = nilfs_get_folio(dir, n, &folio);
-
- if (!IS_ERR(kaddr))
- *pagep = &folio->page;
- return kaddr;
-}
-
/*
* NOTE! unlike strncmp, nilfs_match returns 1 for success, 0 for failure.
*
@@ -613,14 +602,14 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
*/
int nilfs_empty_dir(struct inode *inode)
{
- struct page *page = NULL;
+ struct folio *folio = NULL;
char *kaddr;
unsigned long i, npages = dir_pages(inode);
for (i = 0; i < npages; i++) {
struct nilfs_dir_entry *de;
- kaddr = nilfs_get_page(inode, i, &page);
+ kaddr = nilfs_get_folio(inode, i, &folio);
if (IS_ERR(kaddr))
continue;
@@ -649,12 +638,12 @@ int nilfs_empty_dir(struct inode *inode)
}
de = nilfs_next_entry(de);
}
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
}
return 1;
not_empty:
- unmap_and_put_page(page, kaddr);
+ folio_release_kmap(folio, kaddr);
return 0;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 33/35] nilfs2: Convert nilfs_make_empty() to use a folio
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (31 preceding siblings ...)
2023-11-06 17:39 ` [PATCH 32/35] nilfs2: Convert nilfs_empty_dir() " Matthew Wilcox (Oracle)
@ 2023-11-06 17:39 ` Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 34/35] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios Matthew Wilcox (Oracle)
` (2 subsequent siblings)
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:39 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
Remove two calls to compound_head() and switch from kmap_atomic to
kmap_local.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index e598431516fc..1085e9a5b84e 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -561,21 +561,21 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct folio *folio)
int nilfs_make_empty(struct inode *inode, struct inode *parent)
{
struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct folio *folio = filemap_grab_folio(mapping, 0);
unsigned int chunk_size = nilfs_chunk_size(inode);
struct nilfs_dir_entry *de;
int err;
void *kaddr;
- if (!page)
- return -ENOMEM;
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
- err = nilfs_prepare_chunk(page, 0, chunk_size);
+ err = nilfs_prepare_chunk(&folio->page, 0, chunk_size);
if (unlikely(err)) {
- unlock_page(page);
+ folio_unlock(folio);
goto fail;
}
- kaddr = kmap_atomic(page);
+ kaddr = kmap_local_folio(folio, 0);
memset(kaddr, 0, chunk_size);
de = (struct nilfs_dir_entry *)kaddr;
de->name_len = 1;
@@ -590,10 +590,10 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
de->inode = cpu_to_le64(parent->i_ino);
memcpy(de->name, "..\0", 4);
nilfs_set_de_type(de, inode);
- kunmap_atomic(kaddr);
- nilfs_commit_chunk(page, mapping, 0, chunk_size);
+ kunmap_local(kaddr);
+ nilfs_commit_chunk(&folio->page, mapping, 0, chunk_size);
fail:
- put_page(page);
+ folio_put(folio);
return err;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 34/35] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (32 preceding siblings ...)
2023-11-06 17:39 ` [PATCH 33/35] nilfs2: Convert nilfs_make_empty() " Matthew Wilcox (Oracle)
@ 2023-11-06 17:39 ` Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 35/35] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug() Matthew Wilcox (Oracle)
2023-11-07 1:49 ` [PATCH 00/35] nilfs2: Folio conversions Ryusuke Konishi
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:39 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
All callers now have a folio, so convert these two functions.
Saves one call to compound_head() in unlock_page().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 1085e9a5b84e..85db5772795b 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -78,33 +78,32 @@ static unsigned int nilfs_last_byte(struct inode *inode, unsigned long page_nr)
return last_byte;
}
-static int nilfs_prepare_chunk(struct page *page, unsigned int from,
+static int nilfs_prepare_chunk(struct folio *folio, unsigned int from,
unsigned int to)
{
- loff_t pos = page_offset(page) + from;
+ loff_t pos = folio_pos(folio) + from;
- return __block_write_begin(page, pos, to - from, nilfs_get_block);
+ return __block_write_begin(&folio->page, pos, to - from, nilfs_get_block);
}
-static void nilfs_commit_chunk(struct page *page,
- struct address_space *mapping,
- unsigned int from, unsigned int to)
+static void nilfs_commit_chunk(struct folio *folio,
+ struct address_space *mapping, size_t from, size_t to)
{
struct inode *dir = mapping->host;
- loff_t pos = page_offset(page) + from;
- unsigned int len = to - from;
- unsigned int nr_dirty, copied;
+ loff_t pos = folio_pos(folio) + from;
+ size_t copied, len = to - from;
+ unsigned int nr_dirty;
int err;
- nr_dirty = nilfs_page_count_clean_buffers(page, from, to);
- copied = block_write_end(NULL, mapping, pos, len, len, page, NULL);
+ nr_dirty = nilfs_page_count_clean_buffers(&folio->page, from, to);
+ copied = block_write_end(NULL, mapping, pos, len, len, &folio->page, NULL);
if (pos + copied > dir->i_size)
i_size_write(dir, pos + copied);
if (IS_DIRSYNC(dir))
nilfs_set_transaction_flag(NILFS_TI_SYNC);
err = nilfs_set_file_dirty(dir, nr_dirty);
WARN_ON(err); /* do not happen */
- unlock_page(page);
+ folio_unlock(folio);
}
static bool nilfs_check_folio(struct folio *folio, char *kaddr)
@@ -409,11 +408,11 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
int err;
folio_lock(folio);
- err = nilfs_prepare_chunk(&folio->page, from, to);
+ err = nilfs_prepare_chunk(folio, from, to);
BUG_ON(err);
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
- nilfs_commit_chunk(&folio->page, mapping, from, to);
+ nilfs_commit_chunk(folio, mapping, from, to);
folio_release_kmap(folio, de);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -486,7 +485,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
got_it:
from = offset_in_folio(folio, de);
to = from + rec_len;
- err = nilfs_prepare_chunk(&folio->page, from, to);
+ err = nilfs_prepare_chunk(folio, from, to);
if (err)
goto out_unlock;
if (de->inode) {
@@ -501,7 +500,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
memcpy(de->name, name, namelen);
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
- nilfs_commit_chunk(&folio->page, folio->mapping, from, to);
+ nilfs_commit_chunk(folio, folio->mapping, from, to);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
nilfs_mark_inode_dirty(dir);
/* OFFSET_CACHE */
@@ -543,12 +542,12 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct folio *folio)
if (pde)
from = (char *)pde - kaddr;
folio_lock(folio);
- err = nilfs_prepare_chunk(&folio->page, from, to);
+ err = nilfs_prepare_chunk(folio, from, to);
BUG_ON(err);
if (pde)
pde->rec_len = nilfs_rec_len_to_disk(to - from);
dir->inode = 0;
- nilfs_commit_chunk(&folio->page, mapping, from, to);
+ nilfs_commit_chunk(folio, mapping, from, to);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
out:
folio_release_kmap(folio, kaddr);
@@ -570,7 +569,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
if (IS_ERR(folio))
return PTR_ERR(folio);
- err = nilfs_prepare_chunk(&folio->page, 0, chunk_size);
+ err = nilfs_prepare_chunk(folio, 0, chunk_size);
if (unlikely(err)) {
folio_unlock(folio);
goto fail;
@@ -591,7 +590,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
memcpy(de->name, "..\0", 4);
nilfs_set_de_type(de, inode);
kunmap_local(kaddr);
- nilfs_commit_chunk(&folio->page, mapping, 0, chunk_size);
+ nilfs_commit_chunk(folio, mapping, 0, chunk_size);
fail:
folio_put(folio);
return err;
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 35/35] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (33 preceding siblings ...)
2023-11-06 17:39 ` [PATCH 34/35] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios Matthew Wilcox (Oracle)
@ 2023-11-06 17:39 ` Matthew Wilcox (Oracle)
2023-11-07 1:49 ` [PATCH 00/35] nilfs2: Folio conversions Ryusuke Konishi
35 siblings, 0 replies; 42+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-11-06 17:39 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Matthew Wilcox (Oracle), linux-nilfs, linux-fsdevel
All callers have a folio now, so convert it.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/btnode.c | 4 ++--
fs/nilfs2/page.c | 25 +++++++++++++------------
fs/nilfs2/page.h | 6 +++---
3 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 1204dd06ead8..0131d83b912d 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -190,7 +190,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
retry:
/* BUG_ON(oldkey != obh->b_folio->index); */
if (unlikely(oldkey != ofolio->index))
- NILFS_PAGE_BUG(&ofolio->page,
+ NILFS_FOLIO_BUG(ofolio,
"invalid oldkey %lld (newkey=%lld)",
(unsigned long long)oldkey,
(unsigned long long)newkey);
@@ -246,7 +246,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
if (nbh == NULL) { /* blocksize == pagesize */
ofolio = obh->b_folio;
if (unlikely(oldkey != ofolio->index))
- NILFS_PAGE_BUG(&ofolio->page,
+ NILFS_FOLIO_BUG(ofolio,
"invalid oldkey %lld (newkey=%lld)",
(unsigned long long)oldkey,
(unsigned long long)newkey);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 94e11bcee05b..5c2eba1987bd 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -150,29 +150,30 @@ bool nilfs_folio_buffers_clean(struct folio *folio)
return true;
}
-void nilfs_page_bug(struct page *page)
+void nilfs_folio_bug(struct folio *folio)
{
+ struct buffer_head *bh, *head;
struct address_space *m;
unsigned long ino;
- if (unlikely(!page)) {
- printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n");
+ if (unlikely(!folio)) {
+ printk(KERN_CRIT "NILFS_FOLIO_BUG(NULL)\n");
return;
}
- m = page->mapping;
+ m = folio->mapping;
ino = m ? m->host->i_ino : 0;
- printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx "
+ printk(KERN_CRIT "NILFS_FOLIO_BUG(%p): cnt=%d index#=%llu flags=0x%lx "
"mapping=%p ino=%lu\n",
- page, page_ref_count(page),
- (unsigned long long)page->index, page->flags, m, ino);
+ folio, folio_ref_count(folio),
+ (unsigned long long)folio->index, folio->flags, m, ino);
- if (page_has_buffers(page)) {
- struct buffer_head *bh, *head;
+ head = folio_buffers(folio);
+ if (head) {
int i = 0;
- bh = head = page_buffers(page);
+ bh = head;
do {
printk(KERN_CRIT
" BH[%d] %p: cnt=%d block#=%llu state=0x%lx\n",
@@ -258,7 +259,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
folio_lock(folio);
if (unlikely(!folio_test_dirty(folio)))
- NILFS_PAGE_BUG(&folio->page, "inconsistent dirty state");
+ NILFS_FOLIO_BUG(folio, "inconsistent dirty state");
dfolio = filemap_grab_folio(dmap, folio->index);
if (unlikely(IS_ERR(dfolio))) {
@@ -268,7 +269,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
break;
}
if (unlikely(!folio_buffers(folio)))
- NILFS_PAGE_BUG(&folio->page,
+ NILFS_FOLIO_BUG(folio,
"found empty page in dat page cache");
nilfs_copy_folio(dfolio, folio, true);
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index 968b311d265b..7e1a2c455a10 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -37,7 +37,7 @@ struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *,
void nilfs_forget_buffer(struct buffer_head *);
void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *);
bool nilfs_folio_buffers_clean(struct folio *);
-void nilfs_page_bug(struct page *);
+void nilfs_folio_bug(struct folio *);
int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
void nilfs_copy_back_pages(struct address_space *, struct address_space *);
@@ -49,7 +49,7 @@ unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
sector_t start_blk,
sector_t *blkoff);
-#define NILFS_PAGE_BUG(page, m, a...) \
- do { nilfs_page_bug(page); BUG(); } while (0)
+#define NILFS_FOLIO_BUG(folio, m, a...) \
+ do { nilfs_folio_bug(folio); BUG(); } while (0)
#endif /* _NILFS_PAGE_H */
--
2.42.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH 00/35] nilfs2: Folio conversions
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
` (34 preceding siblings ...)
2023-11-06 17:39 ` [PATCH 35/35] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug() Matthew Wilcox (Oracle)
@ 2023-11-07 1:49 ` Ryusuke Konishi
2023-11-12 0:10 ` Ryusuke Konishi
35 siblings, 1 reply; 42+ messages in thread
From: Ryusuke Konishi @ 2023-11-07 1:49 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-nilfs, linux-fsdevel
On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
>
> This patch series does most of the page->folio conversions needed in
> nilfs2. I haven't done the work to support large folios in nilfs2;
> I don't know if that conversion will be worth the effort. There are
> still a few page uses left, but the infrastructure isn't quite there to
> get rid of them yet.
>
> Arguably, this is two separate series; the first takes care of the file
> paths and the second takes care of directories. I've tried my best to
> include large folio support in the directory code because it'll be needed
> for large block size devices. It also tries to stay as close as possible
> to the current ext2 code (so it also includes kmap_local support).
>
> These patches are only compile-tested. xfstests doesn't seem to know
> about nilfs2.
>
> Matthew Wilcox (Oracle) (35):
> nilfs2: Add nilfs_end_folio_io()
> nilfs2: Convert nilfs_abort_logs to use folios
> nilfs2: Convert nilfs_segctor_complete_write to use folios
> nilfs2: Convert nilfs_forget_buffer to use a folio
> nilfs2: Convert to nilfs_folio_buffers_clean()
> nilfs2: Convert nilfs_writepage() to use a folio
> nilfs2: Convert nilfs_mdt_write_page() to use a folio
> nilfs2: Convert to nilfs_clear_folio_dirty()
> nilfs2: Convert to __nilfs_clear_folio_dirty()
> nilfs2: Convert nilfs_segctor_prepare_write to use folios
> nilfs2: Convert nilfs_page_mkwrite() to use a folio
> nilfs2: Convert nilfs_mdt_create_block to use a folio
> nilfs2: Convert nilfs_mdt_submit_block to use a folio
> nilfs2: Convert nilfs_gccache_submit_read_data to use a folio
> nilfs2: Convert nilfs_btnode_create_block to use a folio
> nilfs2: Convert nilfs_btnode_submit_block to use a folio
> nilfs2: Convert nilfs_btnode_delete to use a folio
> nilfs2: Convert nilfs_btnode_prepare_change_key to use a folio
> nilfs2: Convert nilfs_btnode_commit_change_key to use a folio
> nilfs2: Convert nilfs_btnode_abort_change_key to use a folio
> nilfs2: Remove page_address() from nilfs_set_link
> nilfs2: Remove page_address() from nilfs_add_link
> nilfs2: Remove page_address() from nilfs_delete_entry
> nilfs2: Return the mapped address from nilfs_get_page()
> nilfs2: Pass the mapped address to nilfs_check_page()
> nilfs2: Switch to kmap_local for directory handling
> nilfs2: Add nilfs_get_folio()
> nilfs2: Convert nilfs_readdir to use a folio
> nilfs2: Convert nilfs_find_entry to use a folio
> nilfs2: Convert nilfs_rename() to use folios
> nilfs2: Convert nilfs_add_link() to use a folio
> nilfs2: Convert nilfs_empty_dir() to use a folio
> nilfs2: Convert nilfs_make_empty() to use a folio
> nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to
> folios
> nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
>
> fs/nilfs2/btnode.c | 62 +++++------
> fs/nilfs2/dir.c | 248 ++++++++++++++++++++------------------------
> fs/nilfs2/file.c | 28 ++---
> fs/nilfs2/gcinode.c | 4 +-
> fs/nilfs2/inode.c | 11 +-
> fs/nilfs2/mdt.c | 23 ++--
> fs/nilfs2/namei.c | 33 +++---
> fs/nilfs2/nilfs.h | 20 ++--
> fs/nilfs2/page.c | 93 +++++++++--------
> fs/nilfs2/page.h | 12 +--
> fs/nilfs2/segment.c | 157 ++++++++++++++--------------
> 11 files changed, 338 insertions(+), 353 deletions(-)
>
> --
> 2.42.0
>
Matthew, thank you so much for this hard work.
Even if full support for large folios cannot be achieved at this time
due to limitations in the nilfs2 implementation, I appreciate that you
are moving forward with the conversion work that should be done.
I haven't reviewed each patch yet, but at least this series can be
built without problems in my environment too, and so far it is working
fine including GC and stress tests.
I will review all the patches, but since there are so many, I will not
add LGTM replies to each one, but will only reply to those that have
comments (if any).
Many thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio
2023-11-06 17:38 ` [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
@ 2023-11-09 13:11 ` Ryusuke Konishi
2023-11-09 13:37 ` Matthew Wilcox
0 siblings, 1 reply; 42+ messages in thread
From: Ryusuke Konishi @ 2023-11-09 13:11 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-nilfs, linux-fsdevel
On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
>
> Using the new folio APIs saves seven hidden calls to compound_head().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> fs/nilfs2/file.c | 28 +++++++++++++++-------------
> 1 file changed, 15 insertions(+), 13 deletions(-)
I'm still in the middle of reviewing this series, but I had one
question in a relevant part outside of this patch, so I'd like to ask
you a question.
In block_page_mkwrite() that nilfs_page_mkwrite() calls,
__block_write_begin_int() was called with the range using
folio_size(), as shown below:
end = folio_size(folio);
/* folio is wholly or partially inside EOF */
if (folio_pos(folio) + end > size)
end = size - folio_pos(folio);
ret = __block_write_begin_int(folio, 0, end, get_block, NULL);
...
On the other hand, __block_write_begin_int() takes a folio as an
argument, but uses a PAGE_SIZE-based remainder calculation and BUG_ON
checks:
int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
get_block_t *get_block, const struct iomap *iomap)
{
unsigned from = pos & (PAGE_SIZE - 1);
unsigned to = from + len;
...
BUG_ON(from > PAGE_SIZE);
BUG_ON(to > PAGE_SIZE);
...
So, it looks like this function causes a kernel BUG if it's called
from block_page_mkwrite() and folio_size() exceeds PAGE_SIZE.
Is this constraint intentional or temporary in folio conversions ?
Regards,
Ryusuke Konishi
>
> diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
> index 740ce26d1e76..bec33b89a075 100644
> --- a/fs/nilfs2/file.c
> +++ b/fs/nilfs2/file.c
> @@ -45,34 +45,36 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
> static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
> {
> struct vm_area_struct *vma = vmf->vma;
> - struct page *page = vmf->page;
> + struct folio *folio = page_folio(vmf->page);
> struct inode *inode = file_inode(vma->vm_file);
> struct nilfs_transaction_info ti;
> + struct buffer_head *bh, *head;
> int ret = 0;
>
> if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
> return VM_FAULT_SIGBUS; /* -ENOSPC */
>
> sb_start_pagefault(inode->i_sb);
> - lock_page(page);
> - if (page->mapping != inode->i_mapping ||
> - page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) {
> - unlock_page(page);
> + folio_lock(folio);
> + if (folio->mapping != inode->i_mapping ||
> + folio_pos(folio) >= i_size_read(inode) ||
> + !folio_test_uptodate(folio)) {
> + folio_unlock(folio);
> ret = -EFAULT; /* make the VM retry the fault */
> goto out;
> }
>
> /*
> - * check to see if the page is mapped already (no holes)
> + * check to see if the folio is mapped already (no holes)
> */
> - if (PageMappedToDisk(page))
> + if (folio_test_mappedtodisk(folio))
> goto mapped;
>
> - if (page_has_buffers(page)) {
> - struct buffer_head *bh, *head;
> + head = folio_buffers(folio);
> + if (head) {
> int fully_mapped = 1;
>
> - bh = head = page_buffers(page);
> + bh = head;
> do {
> if (!buffer_mapped(bh)) {
> fully_mapped = 0;
> @@ -81,11 +83,11 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
> } while (bh = bh->b_this_page, bh != head);
>
> if (fully_mapped) {
> - SetPageMappedToDisk(page);
> + folio_set_mappedtodisk(folio);
> goto mapped;
> }
> }
> - unlock_page(page);
> + folio_unlock(folio);
>
> /*
> * fill hole blocks
> @@ -105,7 +107,7 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
> nilfs_transaction_commit(inode->i_sb);
>
> mapped:
> - wait_for_stable_page(page);
> + folio_wait_stable(folio);
> out:
> sb_end_pagefault(inode->i_sb);
> return vmf_fs_error(ret);
> --
> 2.42.0
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio
2023-11-09 13:11 ` Ryusuke Konishi
@ 2023-11-09 13:37 ` Matthew Wilcox
2023-11-09 14:22 ` Ryusuke Konishi
0 siblings, 1 reply; 42+ messages in thread
From: Matthew Wilcox @ 2023-11-09 13:37 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: linux-nilfs, linux-fsdevel
On Thu, Nov 09, 2023 at 10:11:27PM +0900, Ryusuke Konishi wrote:
> On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
> >
> > Using the new folio APIs saves seven hidden calls to compound_head().
> >
> > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> > ---
> > fs/nilfs2/file.c | 28 +++++++++++++++-------------
> > 1 file changed, 15 insertions(+), 13 deletions(-)
>
> I'm still in the middle of reviewing this series, but I had one
> question in a relevant part outside of this patch, so I'd like to ask
> you a question.
>
> In block_page_mkwrite() that nilfs_page_mkwrite() calls,
> __block_write_begin_int() was called with the range using
> folio_size(), as shown below:
>
> end = folio_size(folio);
> /* folio is wholly or partially inside EOF */
> if (folio_pos(folio) + end > size)
> end = size - folio_pos(folio);
>
> ret = __block_write_begin_int(folio, 0, end, get_block, NULL);
> ...
>
> On the other hand, __block_write_begin_int() takes a folio as an
> argument, but uses a PAGE_SIZE-based remainder calculation and BUG_ON
> checks:
>
> int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
> get_block_t *get_block, const struct iomap *iomap)
> {
> unsigned from = pos & (PAGE_SIZE - 1);
> unsigned to = from + len;
> ...
> BUG_ON(from > PAGE_SIZE);
> BUG_ON(to > PAGE_SIZE);
> ...
>
> So, it looks like this function causes a kernel BUG if it's called
> from block_page_mkwrite() and folio_size() exceeds PAGE_SIZE.
>
> Is this constraint intentional or temporary in folio conversions ?
Good catch!
At the time I converted __block_write_begin_int() to take a folio
(over two years ago), the plan was that filesystems would convert to
the iomap infrastructure in order to take advantage of large folios.
The needs of the Large Block Size project mean that may not happen;
filesystems want to add support for, eg, 16kB hardware block sizes
without converting to iomap. So we shoud fix up
__block_write_begin_int(). I'll submit a patch along these lines:
diff --git a/fs/buffer.c b/fs/buffer.c
index cd114110b27f..24a5694f9b41 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2080,25 +2080,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
get_block_t *get_block, const struct iomap *iomap)
{
- unsigned from = pos & (PAGE_SIZE - 1);
- unsigned to = from + len;
+ size_t from = offset_in_folio(folio, pos);
+ size_t to = from + len;
struct inode *inode = folio->mapping->host;
- unsigned block_start, block_end;
+ size_t block_start, block_end;
sector_t block;
int err = 0;
unsigned blocksize, bbits;
struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
BUG_ON(!folio_test_locked(folio));
- BUG_ON(from > PAGE_SIZE);
- BUG_ON(to > PAGE_SIZE);
+ BUG_ON(to > folio_size(folio));
BUG_ON(from > to);
head = folio_create_buffers(folio, inode, 0);
blocksize = head->b_size;
bbits = block_size_bits(blocksize);
- block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
+ block = ((loff_t)folio->index * PAGE_SIZE) >> bbits;
for(bh = head, block_start = 0; bh != head || !block_start;
block++, block_start=block_end, bh = bh->b_this_page) {
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio
2023-11-09 13:37 ` Matthew Wilcox
@ 2023-11-09 14:22 ` Ryusuke Konishi
0 siblings, 0 replies; 42+ messages in thread
From: Ryusuke Konishi @ 2023-11-09 14:22 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: linux-nilfs, linux-fsdevel
On Thu, Nov 9, 2023 at 10:37 PM Matthew Wilcox wrote:
>
> On Thu, Nov 09, 2023 at 10:11:27PM +0900, Ryusuke Konishi wrote:
> > On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
> > >
> > > Using the new folio APIs saves seven hidden calls to compound_head().
> > >
> > > Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> > > ---
> > > fs/nilfs2/file.c | 28 +++++++++++++++-------------
> > > 1 file changed, 15 insertions(+), 13 deletions(-)
> >
> > I'm still in the middle of reviewing this series, but I had one
> > question in a relevant part outside of this patch, so I'd like to ask
> > you a question.
> >
> > In block_page_mkwrite() that nilfs_page_mkwrite() calls,
> > __block_write_begin_int() was called with the range using
> > folio_size(), as shown below:
> >
> > end = folio_size(folio);
> > /* folio is wholly or partially inside EOF */
> > if (folio_pos(folio) + end > size)
> > end = size - folio_pos(folio);
> >
> > ret = __block_write_begin_int(folio, 0, end, get_block, NULL);
> > ...
> >
> > On the other hand, __block_write_begin_int() takes a folio as an
> > argument, but uses a PAGE_SIZE-based remainder calculation and BUG_ON
> > checks:
> >
> > int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
> > get_block_t *get_block, const struct iomap *iomap)
> > {
> > unsigned from = pos & (PAGE_SIZE - 1);
> > unsigned to = from + len;
> > ...
> > BUG_ON(from > PAGE_SIZE);
> > BUG_ON(to > PAGE_SIZE);
> > ...
> >
> > So, it looks like this function causes a kernel BUG if it's called
> > from block_page_mkwrite() and folio_size() exceeds PAGE_SIZE.
> >
> > Is this constraint intentional or temporary in folio conversions ?
>
> Good catch!
>
> At the time I converted __block_write_begin_int() to take a folio
> (over two years ago), the plan was that filesystems would convert to
> the iomap infrastructure in order to take advantage of large folios.
>
> The needs of the Large Block Size project mean that may not happen;
> filesystems want to add support for, eg, 16kB hardware block sizes
> without converting to iomap. So we shoud fix up
> __block_write_begin_int(). I'll submit a patch along these lines:
>
> diff --git a/fs/buffer.c b/fs/buffer.c
> index cd114110b27f..24a5694f9b41 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -2080,25 +2080,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
> int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
> get_block_t *get_block, const struct iomap *iomap)
> {
> - unsigned from = pos & (PAGE_SIZE - 1);
> - unsigned to = from + len;
> + size_t from = offset_in_folio(folio, pos);
> + size_t to = from + len;
> struct inode *inode = folio->mapping->host;
> - unsigned block_start, block_end;
> + size_t block_start, block_end;
> sector_t block;
> int err = 0;
> unsigned blocksize, bbits;
> struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
>
> BUG_ON(!folio_test_locked(folio));
> - BUG_ON(from > PAGE_SIZE);
> - BUG_ON(to > PAGE_SIZE);
> + BUG_ON(to > folio_size(folio));
> BUG_ON(from > to);
>
> head = folio_create_buffers(folio, inode, 0);
> blocksize = head->b_size;
> bbits = block_size_bits(blocksize);
>
> - block = (sector_t)folio->index << (PAGE_SHIFT - bbits);
> + block = ((loff_t)folio->index * PAGE_SIZE) >> bbits;
>
> for(bh = head, block_start = 0; bh != head || !block_start;
> block++, block_start=block_end, bh = bh->b_this_page) {
I got it.
We may have to look at the entire function, but if this change is
applied, it seems to be fine, at least for my question.
Thank you for your prompt correction!
Regards,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 00/35] nilfs2: Folio conversions
2023-11-07 1:49 ` [PATCH 00/35] nilfs2: Folio conversions Ryusuke Konishi
@ 2023-11-12 0:10 ` Ryusuke Konishi
2023-11-21 17:43 ` Ryusuke Konishi
0 siblings, 1 reply; 42+ messages in thread
From: Ryusuke Konishi @ 2023-11-12 0:10 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-nilfs, linux-fsdevel
On Tue, Nov 7, 2023 at 10:49 AM Ryusuke Konishi wrote:
>
> On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
> >
> > This patch series does most of the page->folio conversions needed in
> > nilfs2. I haven't done the work to support large folios in nilfs2;
> > I don't know if that conversion will be worth the effort. There are
> > still a few page uses left, but the infrastructure isn't quite there to
> > get rid of them yet.
> >
> > Arguably, this is two separate series; the first takes care of the file
> > paths and the second takes care of directories. I've tried my best to
> > include large folio support in the directory code because it'll be needed
> > for large block size devices. It also tries to stay as close as possible
> > to the current ext2 code (so it also includes kmap_local support).
> >
> > These patches are only compile-tested. xfstests doesn't seem to know
> > about nilfs2.
> >
> > Matthew Wilcox (Oracle) (35):
> > nilfs2: Add nilfs_end_folio_io()
> > nilfs2: Convert nilfs_abort_logs to use folios
> > nilfs2: Convert nilfs_segctor_complete_write to use folios
> > nilfs2: Convert nilfs_forget_buffer to use a folio
> > nilfs2: Convert to nilfs_folio_buffers_clean()
> > nilfs2: Convert nilfs_writepage() to use a folio
> > nilfs2: Convert nilfs_mdt_write_page() to use a folio
> > nilfs2: Convert to nilfs_clear_folio_dirty()
> > nilfs2: Convert to __nilfs_clear_folio_dirty()
> > nilfs2: Convert nilfs_segctor_prepare_write to use folios
> > nilfs2: Convert nilfs_page_mkwrite() to use a folio
> > nilfs2: Convert nilfs_mdt_create_block to use a folio
> > nilfs2: Convert nilfs_mdt_submit_block to use a folio
> > nilfs2: Convert nilfs_gccache_submit_read_data to use a folio
> > nilfs2: Convert nilfs_btnode_create_block to use a folio
> > nilfs2: Convert nilfs_btnode_submit_block to use a folio
> > nilfs2: Convert nilfs_btnode_delete to use a folio
> > nilfs2: Convert nilfs_btnode_prepare_change_key to use a folio
> > nilfs2: Convert nilfs_btnode_commit_change_key to use a folio
> > nilfs2: Convert nilfs_btnode_abort_change_key to use a folio
> > nilfs2: Remove page_address() from nilfs_set_link
> > nilfs2: Remove page_address() from nilfs_add_link
> > nilfs2: Remove page_address() from nilfs_delete_entry
> > nilfs2: Return the mapped address from nilfs_get_page()
> > nilfs2: Pass the mapped address to nilfs_check_page()
> > nilfs2: Switch to kmap_local for directory handling
> > nilfs2: Add nilfs_get_folio()
> > nilfs2: Convert nilfs_readdir to use a folio
> > nilfs2: Convert nilfs_find_entry to use a folio
> > nilfs2: Convert nilfs_rename() to use folios
> > nilfs2: Convert nilfs_add_link() to use a folio
> > nilfs2: Convert nilfs_empty_dir() to use a folio
> > nilfs2: Convert nilfs_make_empty() to use a folio
> > nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to
> > folios
> > nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
> >
> > fs/nilfs2/btnode.c | 62 +++++------
> > fs/nilfs2/dir.c | 248 ++++++++++++++++++++------------------------
> > fs/nilfs2/file.c | 28 ++---
> > fs/nilfs2/gcinode.c | 4 +-
> > fs/nilfs2/inode.c | 11 +-
> > fs/nilfs2/mdt.c | 23 ++--
> > fs/nilfs2/namei.c | 33 +++---
> > fs/nilfs2/nilfs.h | 20 ++--
> > fs/nilfs2/page.c | 93 +++++++++--------
> > fs/nilfs2/page.h | 12 +--
> > fs/nilfs2/segment.c | 157 ++++++++++++++--------------
> > 11 files changed, 338 insertions(+), 353 deletions(-)
> >
> > --
> > 2.42.0
> >
>
> Matthew, thank you so much for this hard work.
> Even if full support for large folios cannot be achieved at this time
> due to limitations in the nilfs2 implementation, I appreciate that you
> are moving forward with the conversion work that should be done.
>
> I haven't reviewed each patch yet, but at least this series can be
> built without problems in my environment too, and so far it is working
> fine including GC and stress tests.
>
> I will review all the patches, but since there are so many, I will not
> add LGTM replies to each one, but will only reply to those that have
> comments (if any).
>
> Many thanks,
> Ryusuke Konishi
The following WARNING was detected during stress testing on a 32-bit VM:
[ 270.894814][ T5828] ------------[ cut here ]------------
[ 270.895409][ T5828] WARNING: CPU: 1 PID: 5828 at mm/highmem.c:611
kunmap_local_indexed+0xd4/0xfc
<snip>
[ 270.904260][ T5828] EIP: kunmap_local_indexed+0xd4/0xfc
[ 270.904940][ T5828] Code: 00 02 8b 80 5c 0e 00 00 85 c0 78 26 b8 01
00 00 00 e8 80 22 df ff 64 a1 84 29 33 c2 85 c0 74 1a e8 75 f4 df ff
5b 5e 5d c3 90 <0f> 0b eb 95 8d 74 26 00 0f 0b 8d b6 00 00 00 00 e8 13
8a 80 00 eb
[ 270.907264][ T5828] EAX: 00000024 EBX: fff99000 ECX: 00068000 EDX: fff97000
[ 270.908140][ T5828] ESI: 00000003 EDI: f6cc76c0 EBP: e353fda8 ESP: e353fda0
[ 270.909020][ T5828] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
EFLAGS: 00010206
[ 270.910043][ T5828] CR0: 80050033 CR2: b145b49c CR3: 23570000 CR4: 00350ed0
[ 270.910927][ T5828] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
[ 270.911799][ T5828] DR6: fffe0ff0 DR7: 00000400
[ 270.912369][ T5828] Call Trace:
[ 270.912771][ T5828] ? show_regs+0x50/0x58
[ 270.913287][ T5828] ? kunmap_local_indexed+0xd4/0xfc
[ 270.913908][ T5828] ? __warn+0x6f/0x184
[ 270.914420][ T5828] ? kunmap_local_indexed+0xd4/0xfc
[ 270.915063][ T5828] ? report_bug+0x1b2/0x22c
[ 270.915610][ T5828] ? timers_dead_cpu+0x12b/0x268
[ 270.916249][ T5828] ? exc_overflow+0x38/0x38
[ 270.916826][ T5828] ? handle_bug+0x2a/0x48
[ 270.917353][ T5828] ? exc_invalid_op+0x1b/0x58
[ 270.917929][ T5828] ? handle_exception+0x130/0x130
[ 270.918513][ T5828] ? shrink_dentry_list+0x73/0x2bc
[ 270.919121][ T5828] ? exc_overflow+0x38/0x38
[ 270.919728][ T5828] ? kunmap_local_indexed+0xd4/0xfc
[ 270.920369][ T5828] ? exc_overflow+0x38/0x38
[ 270.920913][ T5828] ? kunmap_local_indexed+0xd4/0xfc
[ 270.921545][ T5828] nilfs_delete_entry+0xa7/0x1ec [nilfs2]
[ 270.922255][ T5828] nilfs_rename+0x359/0x374 [nilfs2]
[ 270.922899][ T5828] ? find_held_lock+0x24/0x70
[ 270.923457][ T5828] ? down_write_nested+0x6d/0xd0
[ 270.924043][ T5828] vfs_rename+0x525/0xaa8
[ 270.924572][ T5828] ? vfs_rename+0x525/0xaa8
[ 270.925156][ T5828] ? security_path_rename+0x54/0x7c
[ 270.925794][ T5828] do_renameat2+0x496/0x504
[ 270.926380][ T5828] __ia32_sys_rename+0x34/0x3c
[ 270.926973][ T5828] __do_fast_syscall_32+0x56/0xc8
[ 270.927598][ T5828] do_fast_syscall_32+0x29/0x58
[ 270.928257][ T5828] do_SYSENTER_32+0x15/0x18
[ 270.928871][ T5828] entry_SYSENTER_32+0x98/0xf1
[ 270.929582][ T5828] EIP: 0xb146f579
[ 270.930064][ T5828] Code: b8 01 10 06 03 74 b4 01 10 07 03 74 b0 01
10 08 03 74 d8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 51 52 55 89
e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d 76 00 58 b8 77 00 00 00 cd
80 90 8d 76
[ 270.932584][ T5828] EAX: ffffffda EBX: 03ac7650 ECX: 03ac76f0 EDX: b1456ff4
[ 270.933446][ T5828] ESI: 02aae2c3 EDI: b14a4b80 EBP: bffd8638 ESP: bffd7de8
[ 270.934311][ T5828] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b
EFLAGS: 00000292
[ 270.935245][ T5828] Kernel panic - not syncing: kernel: panic_on_warn set ...
This issue is reproducible and the result of bisect was the following patch:
> > nilfs2: Switch to kmap_local for directory handling
It seems that the problem was introduced in the conversion of
"nilfs_rename() -> nilfs_delete_entry()" to kmap_local.
For the first part of this series (PATH 01/35 - 20/35), my review is
already finished, and I believe nothing breaks existing behavior.
So I'm thinking of sending that part to the -mm tree first (on Monday
or Tuesday), but if you have any opinions, please let me know.
For the rest, I would like to continue problem analysis and review.
Thanks,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 00/35] nilfs2: Folio conversions
2023-11-12 0:10 ` Ryusuke Konishi
@ 2023-11-21 17:43 ` Ryusuke Konishi
0 siblings, 0 replies; 42+ messages in thread
From: Ryusuke Konishi @ 2023-11-21 17:43 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-nilfs, linux-fsdevel
On Sun, Nov 12, 2023 at 9:10 AM Ryusuke Konishi wrote:
>
> On Tue, Nov 7, 2023 at 10:49 AM Ryusuke Konishi wrote:
> >
> > On Tue, Nov 7, 2023 at 2:39 AM Matthew Wilcox (Oracle) wrote:
> > >
> > > This patch series does most of the page->folio conversions needed in
> > > nilfs2. I haven't done the work to support large folios in nilfs2;
> > > I don't know if that conversion will be worth the effort. There are
> > > still a few page uses left, but the infrastructure isn't quite there to
> > > get rid of them yet.
> > >
> > > Arguably, this is two separate series; the first takes care of the file
> > > paths and the second takes care of directories. I've tried my best to
> > > include large folio support in the directory code because it'll be needed
> > > for large block size devices. It also tries to stay as close as possible
> > > to the current ext2 code (so it also includes kmap_local support).
> > >
> > > These patches are only compile-tested. xfstests doesn't seem to know
> > > about nilfs2.
> > >
> > > Matthew Wilcox (Oracle) (35):
> > > nilfs2: Add nilfs_end_folio_io()
> > > nilfs2: Convert nilfs_abort_logs to use folios
> > > nilfs2: Convert nilfs_segctor_complete_write to use folios
> > > nilfs2: Convert nilfs_forget_buffer to use a folio
> > > nilfs2: Convert to nilfs_folio_buffers_clean()
> > > nilfs2: Convert nilfs_writepage() to use a folio
> > > nilfs2: Convert nilfs_mdt_write_page() to use a folio
> > > nilfs2: Convert to nilfs_clear_folio_dirty()
> > > nilfs2: Convert to __nilfs_clear_folio_dirty()
> > > nilfs2: Convert nilfs_segctor_prepare_write to use folios
> > > nilfs2: Convert nilfs_page_mkwrite() to use a folio
> > > nilfs2: Convert nilfs_mdt_create_block to use a folio
> > > nilfs2: Convert nilfs_mdt_submit_block to use a folio
> > > nilfs2: Convert nilfs_gccache_submit_read_data to use a folio
> > > nilfs2: Convert nilfs_btnode_create_block to use a folio
> > > nilfs2: Convert nilfs_btnode_submit_block to use a folio
> > > nilfs2: Convert nilfs_btnode_delete to use a folio
> > > nilfs2: Convert nilfs_btnode_prepare_change_key to use a folio
> > > nilfs2: Convert nilfs_btnode_commit_change_key to use a folio
> > > nilfs2: Convert nilfs_btnode_abort_change_key to use a folio
> > > nilfs2: Remove page_address() from nilfs_set_link
> > > nilfs2: Remove page_address() from nilfs_add_link
> > > nilfs2: Remove page_address() from nilfs_delete_entry
> > > nilfs2: Return the mapped address from nilfs_get_page()
> > > nilfs2: Pass the mapped address to nilfs_check_page()
> > > nilfs2: Switch to kmap_local for directory handling
> > > nilfs2: Add nilfs_get_folio()
> > > nilfs2: Convert nilfs_readdir to use a folio
> > > nilfs2: Convert nilfs_find_entry to use a folio
> > > nilfs2: Convert nilfs_rename() to use folios
> > > nilfs2: Convert nilfs_add_link() to use a folio
> > > nilfs2: Convert nilfs_empty_dir() to use a folio
> > > nilfs2: Convert nilfs_make_empty() to use a folio
> > > nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to
> > > folios
> > > nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
> > >
> > > fs/nilfs2/btnode.c | 62 +++++------
> > > fs/nilfs2/dir.c | 248 ++++++++++++++++++++------------------------
> > > fs/nilfs2/file.c | 28 ++---
> > > fs/nilfs2/gcinode.c | 4 +-
> > > fs/nilfs2/inode.c | 11 +-
> > > fs/nilfs2/mdt.c | 23 ++--
> > > fs/nilfs2/namei.c | 33 +++---
> > > fs/nilfs2/nilfs.h | 20 ++--
> > > fs/nilfs2/page.c | 93 +++++++++--------
> > > fs/nilfs2/page.h | 12 +--
> > > fs/nilfs2/segment.c | 157 ++++++++++++++--------------
> > > 11 files changed, 338 insertions(+), 353 deletions(-)
> > >
> > > --
> > > 2.42.0
> > >
> >
> > Matthew, thank you so much for this hard work.
> > Even if full support for large folios cannot be achieved at this time
> > due to limitations in the nilfs2 implementation, I appreciate that you
> > are moving forward with the conversion work that should be done.
> >
> > I haven't reviewed each patch yet, but at least this series can be
> > built without problems in my environment too, and so far it is working
> > fine including GC and stress tests.
> >
> > I will review all the patches, but since there are so many, I will not
> > add LGTM replies to each one, but will only reply to those that have
> > comments (if any).
> >
> > Many thanks,
> > Ryusuke Konishi
>
> The following WARNING was detected during stress testing on a 32-bit VM:
>
> [ 270.894814][ T5828] ------------[ cut here ]------------
> [ 270.895409][ T5828] WARNING: CPU: 1 PID: 5828 at mm/highmem.c:611
> kunmap_local_indexed+0xd4/0xfc
> <snip>
> [ 270.904260][ T5828] EIP: kunmap_local_indexed+0xd4/0xfc
> [ 270.904940][ T5828] Code: 00 02 8b 80 5c 0e 00 00 85 c0 78 26 b8 01
> 00 00 00 e8 80 22 df ff 64 a1 84 29 33 c2 85 c0 74 1a e8 75 f4 df ff
> 5b 5e 5d c3 90 <0f> 0b eb 95 8d 74 26 00 0f 0b 8d b6 00 00 00 00 e8 13
> 8a 80 00 eb
> [ 270.907264][ T5828] EAX: 00000024 EBX: fff99000 ECX: 00068000 EDX: fff97000
> [ 270.908140][ T5828] ESI: 00000003 EDI: f6cc76c0 EBP: e353fda8 ESP: e353fda0
> [ 270.909020][ T5828] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> EFLAGS: 00010206
> [ 270.910043][ T5828] CR0: 80050033 CR2: b145b49c CR3: 23570000 CR4: 00350ed0
> [ 270.910927][ T5828] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
> [ 270.911799][ T5828] DR6: fffe0ff0 DR7: 00000400
> [ 270.912369][ T5828] Call Trace:
> [ 270.912771][ T5828] ? show_regs+0x50/0x58
> [ 270.913287][ T5828] ? kunmap_local_indexed+0xd4/0xfc
> [ 270.913908][ T5828] ? __warn+0x6f/0x184
> [ 270.914420][ T5828] ? kunmap_local_indexed+0xd4/0xfc
> [ 270.915063][ T5828] ? report_bug+0x1b2/0x22c
> [ 270.915610][ T5828] ? timers_dead_cpu+0x12b/0x268
> [ 270.916249][ T5828] ? exc_overflow+0x38/0x38
> [ 270.916826][ T5828] ? handle_bug+0x2a/0x48
> [ 270.917353][ T5828] ? exc_invalid_op+0x1b/0x58
> [ 270.917929][ T5828] ? handle_exception+0x130/0x130
> [ 270.918513][ T5828] ? shrink_dentry_list+0x73/0x2bc
> [ 270.919121][ T5828] ? exc_overflow+0x38/0x38
> [ 270.919728][ T5828] ? kunmap_local_indexed+0xd4/0xfc
> [ 270.920369][ T5828] ? exc_overflow+0x38/0x38
> [ 270.920913][ T5828] ? kunmap_local_indexed+0xd4/0xfc
> [ 270.921545][ T5828] nilfs_delete_entry+0xa7/0x1ec [nilfs2]
> [ 270.922255][ T5828] nilfs_rename+0x359/0x374 [nilfs2]
> [ 270.922899][ T5828] ? find_held_lock+0x24/0x70
> [ 270.923457][ T5828] ? down_write_nested+0x6d/0xd0
> [ 270.924043][ T5828] vfs_rename+0x525/0xaa8
> [ 270.924572][ T5828] ? vfs_rename+0x525/0xaa8
> [ 270.925156][ T5828] ? security_path_rename+0x54/0x7c
> [ 270.925794][ T5828] do_renameat2+0x496/0x504
> [ 270.926380][ T5828] __ia32_sys_rename+0x34/0x3c
> [ 270.926973][ T5828] __do_fast_syscall_32+0x56/0xc8
> [ 270.927598][ T5828] do_fast_syscall_32+0x29/0x58
> [ 270.928257][ T5828] do_SYSENTER_32+0x15/0x18
> [ 270.928871][ T5828] entry_SYSENTER_32+0x98/0xf1
> [ 270.929582][ T5828] EIP: 0xb146f579
> [ 270.930064][ T5828] Code: b8 01 10 06 03 74 b4 01 10 07 03 74 b0 01
> 10 08 03 74 d8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 51 52 55 89
> e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d 76 00 58 b8 77 00 00 00 cd
> 80 90 8d 76
> [ 270.932584][ T5828] EAX: ffffffda EBX: 03ac7650 ECX: 03ac76f0 EDX: b1456ff4
> [ 270.933446][ T5828] ESI: 02aae2c3 EDI: b14a4b80 EBP: bffd8638 ESP: bffd7de8
> [ 270.934311][ T5828] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b
> EFLAGS: 00000292
> [ 270.935245][ T5828] Kernel panic - not syncing: kernel: panic_on_warn set ...
>
> This issue is reproducible and the result of bisect was the following patch:
>
> > > nilfs2: Switch to kmap_local for directory handling
>
> It seems that the problem was introduced in the conversion of
> "nilfs_rename() -> nilfs_delete_entry()" to kmap_local.
>
> For the first part of this series (PATH 01/35 - 20/35), my review is
> already finished, and I believe nothing breaks existing behavior.
> So I'm thinking of sending that part to the -mm tree first (on Monday
> or Tuesday), but if you have any opinions, please let me know.
>
> For the rest, I would like to continue problem analysis and review.
>
> Thanks,
> Ryusuke Konishi
The cause of this issue was that in the current implementation of the
rename function, there was a hidden part where the use of kmap-kunmap
pairs for two pages was not nested.
Other than that, there were no problems with the second half of the
patchset in the review, so I would like to insert a preparation patch
to resolve the order reversal of kunmap (more precisely,
nilfs_put_page) calls, so that they can be converted directly to
unmap_and_put_page (and then to folio_release_kmap) calls, and send
the remaining patches together to the mm tree with only minor
adjustments.
Regards,
Ryusuke Konishi
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2023-11-21 17:43 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-06 17:38 [PATCH 00/35] nilfs2: Folio conversions Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 01/35] nilfs2: Add nilfs_end_folio_io() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 02/35] nilfs2: Convert nilfs_abort_logs to use folios Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 03/35] nilfs2: Convert nilfs_segctor_complete_write " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 04/35] nilfs2: Convert nilfs_forget_buffer to use a folio Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 05/35] nilfs2: Convert to nilfs_folio_buffers_clean() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 06/35] nilfs2: Convert nilfs_writepage() to use a folio Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 07/35] nilfs2: Convert nilfs_mdt_write_page() " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 08/35] nilfs2: Convert to nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 09/35] nilfs2: Convert to __nilfs_clear_folio_dirty() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 10/35] nilfs2: Convert nilfs_segctor_prepare_write to use folios Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 11/35] nilfs2: Convert nilfs_page_mkwrite() to use a folio Matthew Wilcox (Oracle)
2023-11-09 13:11 ` Ryusuke Konishi
2023-11-09 13:37 ` Matthew Wilcox
2023-11-09 14:22 ` Ryusuke Konishi
2023-11-06 17:38 ` [PATCH 12/35] nilfs2: Convert nilfs_mdt_create_block " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 13/35] nilfs2: Convert nilfs_mdt_submit_block " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 14/35] nilfs2: Convert nilfs_gccache_submit_read_data " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 15/35] nilfs2: Convert nilfs_btnode_create_block " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 16/35] nilfs2: Convert nilfs_btnode_submit_block " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 17/35] nilfs2: Convert nilfs_btnode_delete " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 18/35] nilfs2: Convert nilfs_btnode_prepare_change_key " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 19/35] nilfs2: Convert nilfs_btnode_commit_change_key " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 20/35] nilfs2: Convert nilfs_btnode_abort_change_key " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 21/35] nilfs2: Remove page_address() from nilfs_set_link Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 22/35] nilfs2: Remove page_address() from nilfs_add_link Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 23/35] nilfs2: Remove page_address() from nilfs_delete_entry Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 24/35] nilfs2: Return the mapped address from nilfs_get_page() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 25/35] nilfs2: Pass the mapped address to nilfs_check_page() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 26/35] nilfs2: Switch to kmap_local for directory handling Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 27/35] nilfs2: Add nilfs_get_folio() Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 28/35] nilfs2: Convert nilfs_readdir to use a folio Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 29/35] nilfs2: Convert nilfs_find_entry " Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 30/35] nilfs2: Convert nilfs_rename() to use folios Matthew Wilcox (Oracle)
2023-11-06 17:38 ` [PATCH 31/35] nilfs2: Convert nilfs_add_link() to use a folio Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 32/35] nilfs2: Convert nilfs_empty_dir() " Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 33/35] nilfs2: Convert nilfs_make_empty() " Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 34/35] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios Matthew Wilcox (Oracle)
2023-11-06 17:39 ` [PATCH 35/35] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug() Matthew Wilcox (Oracle)
2023-11-07 1:49 ` [PATCH 00/35] nilfs2: Folio conversions Ryusuke Konishi
2023-11-12 0:10 ` Ryusuke Konishi
2023-11-21 17:43 ` Ryusuke Konishi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).