* [PATCH 01/17] nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 17:08 ` Matthew Wilcox
2023-11-27 14:30 ` [PATCH 02/17] nilfs2: eliminate staggered calls to kunmap in nilfs_rename Ryusuke Konishi
` (15 subsequent siblings)
16 siblings, 1 reply; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
In a few directory operations, the call to nilfs_put_page() for a page
obtained using nilfs_find_entry() or nilfs_dotdot() is hidden in
nilfs_set_link() and nilfs_delete_entry(), making it difficult to track
page release and preventing change of its call position.
By moving nilfs_put_page() out of these functions, this makes the page
get/put correspondence clearer and makes it easier to swap
nilfs_put_page() calls (and kunmap calls within them) when modifying
multiple directory entries simultaneously in nilfs_rename().
Also, update comments for nilfs_set_link() and nilfs_delete_entry() to
reflect changes in their behavior.
To make nilfs_put_page() visible from namei.c, this moves its definition
to nilfs.h and replaces existing equivalents to use it, but the exposure
of that definition is temporary and will be removed on a later
kmap -> kmap_local conversion.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/dir.c | 11 +----------
fs/nilfs2/namei.c | 13 +++++++------
fs/nilfs2/nilfs.h | 6 ++++++
3 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index de2073c47651..b9f13bdf8fba 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.
@@ -413,7 +407,6 @@ ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
return res;
}
-/* Releases the page */
void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
struct page *page, struct inode *inode)
{
@@ -428,7 +421,6 @@ 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);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -533,7 +525,7 @@ 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. Page is up-to-date.
*/
int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
{
@@ -569,7 +561,6 @@ 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);
return err;
}
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 2a4e7f4a8102..99255694cbe9 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -280,6 +280,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
set_nlink(inode, 1);
}
err = nilfs_delete_entry(de, page);
+ nilfs_put_page(page);
if (err)
goto out;
@@ -386,6 +387,7 @@ static int nilfs_rename(struct mnt_idmap *idmap,
if (!new_de)
goto out_dir;
nilfs_set_link(new_dir, new_de, new_page, old_inode);
+ nilfs_put_page(new_page);
nilfs_mark_inode_dirty(new_dir);
inode_set_ctime_current(new_inode);
if (dir_de)
@@ -409,9 +411,11 @@ static int nilfs_rename(struct mnt_idmap *idmap,
inode_set_ctime_current(old_inode);
nilfs_delete_entry(old_de, old_page);
+ nilfs_put_page(old_page);
if (dir_de) {
nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
+ nilfs_put_page(dir_page);
drop_nlink(old_dir);
}
nilfs_mark_inode_dirty(old_dir);
@@ -421,13 +425,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)
+ nilfs_put_page(dir_page);
out_old:
- kunmap(old_page);
- put_page(old_page);
+ nilfs_put_page(old_page);
out:
nilfs_transaction_abort(old_dir->i_sb);
return err;
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 8046490cd7fe..afd700f5dc4e 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -237,6 +237,12 @@ 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 *);
+static inline void nilfs_put_page(struct page *page)
+{
+ kunmap(page);
+ put_page(page);
+}
+
/* file.c */
extern int nilfs_sync_file(struct file *, loff_t, loff_t, int);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 01/17] nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link
2023-11-27 14:30 ` [PATCH 01/17] nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link Ryusuke Konishi
@ 2023-11-27 17:08 ` Matthew Wilcox
0 siblings, 0 replies; 20+ messages in thread
From: Matthew Wilcox @ 2023-11-27 17:08 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Andrew Morton, linux-nilfs, linux-kernel
On Mon, Nov 27, 2023 at 11:30:20PM +0900, Ryusuke Konishi wrote:
> In a few directory operations, the call to nilfs_put_page() for a page
> obtained using nilfs_find_entry() or nilfs_dotdot() is hidden in
> nilfs_set_link() and nilfs_delete_entry(), making it difficult to track
> page release and preventing change of its call position.
>
> By moving nilfs_put_page() out of these functions, this makes the page
> get/put correspondence clearer and makes it easier to swap
> nilfs_put_page() calls (and kunmap calls within them) when modifying
> multiple directory entries simultaneously in nilfs_rename().
>
> Also, update comments for nilfs_set_link() and nilfs_delete_entry() to
> reflect changes in their behavior.
>
> To make nilfs_put_page() visible from namei.c, this moves its definition
> to nilfs.h and replaces existing equivalents to use it, but the exposure
> of that definition is temporary and will be removed on a later
> kmap -> kmap_local conversion.
>
> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Ah; I see. This makes it more like ext2, so I approve!
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 02/17] nilfs2: eliminate staggered calls to kunmap in nilfs_rename
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 01/17] nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 17:08 ` Matthew Wilcox
2023-11-27 14:30 ` [PATCH 03/17] nilfs2: Remove page_address() from nilfs_set_link Ryusuke Konishi
` (14 subsequent siblings)
16 siblings, 1 reply; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
In nilfs_rename(), calls to nilfs_put_page() to release pages obtained
with nilfs_find_entry() or nilfs_dotdot() are alternated in the normal
path.
When replacing the kernel memory mapping method from kmap to
kmap_local_{page,folio}, this violates the constraint on the calling
order of kunmap_local().
Swap the order of nilfs_put_page calls where the kmap sections of
multiple pages overlap so that they are nested, allowing direct
replacement of nilfs_put_page() -> unmap_and_put_page().
Without this reordering, that replacement will cause a kernel WARNING
in kunmap_local_indexed() on architectures with high memory mapping.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/nilfs2/namei.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 99255694cbe9..d179db8074c2 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -411,13 +411,14 @@ static int nilfs_rename(struct mnt_idmap *idmap,
inode_set_ctime_current(old_inode);
nilfs_delete_entry(old_de, old_page);
- nilfs_put_page(old_page);
if (dir_de) {
nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
nilfs_put_page(dir_page);
drop_nlink(old_dir);
}
+ nilfs_put_page(old_page);
+
nilfs_mark_inode_dirty(old_dir);
nilfs_mark_inode_dirty(old_inode);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 02/17] nilfs2: eliminate staggered calls to kunmap in nilfs_rename
2023-11-27 14:30 ` [PATCH 02/17] nilfs2: eliminate staggered calls to kunmap in nilfs_rename Ryusuke Konishi
@ 2023-11-27 17:08 ` Matthew Wilcox
0 siblings, 0 replies; 20+ messages in thread
From: Matthew Wilcox @ 2023-11-27 17:08 UTC (permalink / raw)
To: Ryusuke Konishi; +Cc: Andrew Morton, linux-nilfs, linux-kernel
On Mon, Nov 27, 2023 at 11:30:21PM +0900, Ryusuke Konishi wrote:
> In nilfs_rename(), calls to nilfs_put_page() to release pages obtained
> with nilfs_find_entry() or nilfs_dotdot() are alternated in the normal
> path.
>
> When replacing the kernel memory mapping method from kmap to
> kmap_local_{page,folio}, this violates the constraint on the calling
> order of kunmap_local().
>
> Swap the order of nilfs_put_page calls where the kmap sections of
> multiple pages overlap so that they are nested, allowing direct
> replacement of nilfs_put_page() -> unmap_and_put_page().
>
> Without this reordering, that replacement will cause a kernel WARNING
> in kunmap_local_indexed() on architectures with high memory mapping.
>
> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Thanks for catching this!
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 03/17] nilfs2: Remove page_address() from nilfs_set_link
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 01/17] nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 02/17] nilfs2: eliminate staggered calls to kunmap in nilfs_rename Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 04/17] nilfs2: Remove page_address() from nilfs_add_link Ryusuke Konishi
` (13 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 b9f13bdf8fba..9c0513245a3b 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -410,7 +410,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 04/17] nilfs2: Remove page_address() from nilfs_add_link
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (2 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 03/17] nilfs2: Remove page_address() from nilfs_set_link Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 05/17] nilfs2: Remove page_address() from nilfs_delete_entry Ryusuke Konishi
` (12 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 9c0513245a3b..73f135290288 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -493,7 +493,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 05/17] nilfs2: Remove page_address() from nilfs_delete_entry
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (3 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 04/17] nilfs2: Remove page_address() from nilfs_add_link Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 06/17] nilfs2: Return the mapped address from nilfs_get_page() Ryusuke Konishi
` (11 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 73f135290288..385e47eda99f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -531,7 +531,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;
@@ -551,7 +551,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 06/17] nilfs2: Return the mapped address from nilfs_get_page()
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (4 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 05/17] nilfs2: Remove page_address() from nilfs_delete_entry Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 07/17] nilfs2: Pass the mapped address to nilfs_check_page() Ryusuke Konishi
` (10 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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().
[ konishi.ryusuke: fixed a missing blank line after declaration ]
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
fs/nilfs2/dir.c | 57 +++++++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 30 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 385e47eda99f..45f75d4c4522 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -180,19 +180,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);
@@ -269,14 +274,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);
@@ -339,11 +344,9 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
start = 0;
n = start;
do {
- char *kaddr;
+ char *kaddr = nilfs_get_page(dir, n, &page);
- page = nilfs_get_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
+ if (!IS_ERR(kaddr)) {
de = (struct nilfs_dir_entry *)kaddr;
kaddr += nilfs_last_byte(dir, n) - reclen;
while ((char *) de <= kaddr) {
@@ -381,15 +384,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)
@@ -451,12 +450,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;
@@ -618,11 +616,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 07/17] nilfs2: Pass the mapped address to nilfs_check_page()
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (5 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 06/17] nilfs2: Return the mapped address from nilfs_get_page() Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 08/17] nilfs2: Switch to kmap_local for directory handling Ryusuke Konishi
` (9 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 45f75d4c4522..01900e84bddf 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -107,12 +107,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;
@@ -192,7 +191,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 08/17] nilfs2: Switch to kmap_local for directory handling
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (6 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 07/17] nilfs2: Pass the mapped address to nilfs_check_page() Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 09/17] nilfs2: Add nilfs_get_folio() Ryusuke Konishi
` (8 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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.
[ konishi.ryusuke: followed the change of page release helper call sites ]
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
fs/nilfs2/dir.c | 27 +++++++++++++--------------
fs/nilfs2/namei.c | 12 ++++++------
fs/nilfs2/nilfs.h | 6 ------
3 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 01900e84bddf..89e8a248e571 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -189,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;
@@ -199,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);
}
@@ -287,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) {
@@ -300,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;
}
@@ -352,14 +352,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;
@@ -399,8 +399,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;
}
@@ -484,7 +483,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;
@@ -512,7 +511,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:
@@ -609,10 +608,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);
@@ -644,12 +643,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 d179db8074c2..c08b1bf9fa7b 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -280,7 +280,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
set_nlink(inode, 1);
}
err = nilfs_delete_entry(de, page);
- nilfs_put_page(page);
+ unmap_and_put_page(page, de);
if (err)
goto out;
@@ -387,7 +387,7 @@ static int nilfs_rename(struct mnt_idmap *idmap,
if (!new_de)
goto out_dir;
nilfs_set_link(new_dir, new_de, new_page, old_inode);
- nilfs_put_page(new_page);
+ unmap_and_put_page(new_page, new_de);
nilfs_mark_inode_dirty(new_dir);
inode_set_ctime_current(new_inode);
if (dir_de)
@@ -414,10 +414,10 @@ static int nilfs_rename(struct mnt_idmap *idmap,
if (dir_de) {
nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
- nilfs_put_page(dir_page);
+ unmap_and_put_page(dir_page, dir_de);
drop_nlink(old_dir);
}
- nilfs_put_page(old_page);
+ unmap_and_put_page(old_page, old_de);
nilfs_mark_inode_dirty(old_dir);
nilfs_mark_inode_dirty(old_inode);
@@ -427,9 +427,9 @@ static int nilfs_rename(struct mnt_idmap *idmap,
out_dir:
if (dir_de)
- nilfs_put_page(dir_page);
+ unmap_and_put_page(dir_page, dir_de);
out_old:
- nilfs_put_page(old_page);
+ unmap_and_put_page(old_page, 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 afd700f5dc4e..8046490cd7fe 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -237,12 +237,6 @@ 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 *);
-static inline void nilfs_put_page(struct page *page)
-{
- kunmap(page);
- put_page(page);
-}
-
/* file.c */
extern int nilfs_sync_file(struct file *, loff_t, loff_t, int);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 09/17] nilfs2: Add nilfs_get_folio()
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (7 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 08/17] nilfs2: Switch to kmap_local for directory handling Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 10/17] nilfs2: Convert nilfs_readdir to use a folio Ryusuke Konishi
` (7 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
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>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 89e8a248e571..5c9ca3f0d7f4 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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 10/17] nilfs2: Convert nilfs_readdir to use a folio
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (8 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 09/17] nilfs2: Add nilfs_get_folio() Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 11/17] nilfs2: Convert nilfs_find_entry " Ryusuke Konishi
` (6 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Use the new folio APIs to remove calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 5c9ca3f0d7f4..c7b046589877 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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 11/17] nilfs2: Convert nilfs_find_entry to use a folio
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (9 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 10/17] nilfs2: Convert nilfs_readdir to use a folio Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 12/17] nilfs2: Convert nilfs_rename() to use folios Ryusuke Konishi
` (5 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Use the new folio APIs to remove calls to compound_head().
[ konishi.ryusuke: resolved a conflict due to style warning correction ]
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 c7b046589877..a79726182867 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;
@@ -363,18 +363,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",
@@ -387,7 +387,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 12/17] nilfs2: Convert nilfs_rename() to use folios
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (10 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 11/17] nilfs2: Convert nilfs_find_entry " Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 13/17] nilfs2: Convert nilfs_add_link() to use a folio Ryusuke Konishi
` (4 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
This involves converting nilfs_find_entry(), nilfs_dotdot(),
nilfs_set_link(), nilfs_delete_entry() and nilfs_do_unlink()
to use folios as well.
[ konishi.ryusuke: followed the change of page release helper call sites ]
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
fs/nilfs2/dir.c | 68 ++++++++++++++++++++++-------------------------
fs/nilfs2/namei.c | 36 ++++++++++++-------------
fs/nilfs2/nilfs.h | 20 +++++++-------
3 files changed, 60 insertions(+), 64 deletions(-)
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index a79726182867..2a759598801b 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;
@@ -363,14 +360,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;
@@ -387,14 +384,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;
@@ -405,30 +401,30 @@ 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;
}
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);
+ nilfs_commit_chunk(&folio->page, mapping, from, to);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -532,14 +528,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.
+ * previous entry. Folio is up-to-date.
*/
-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;
@@ -559,13 +555,13 @@ 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:
return err;
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index c08b1bf9fa7b..959bd9fb3d81 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,8 +279,8 @@ 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);
- unmap_and_put_page(page, de);
+ err = nilfs_delete_entry(de, folio);
+ folio_release_kmap(folio, de);
if (err)
goto out;
@@ -348,9 +348,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;
@@ -363,19 +363,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;
@@ -383,11 +383,11 @@ 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);
- unmap_and_put_page(new_page, new_de);
+ nilfs_set_link(new_dir, new_de, new_folio, old_inode);
+ folio_release_kmap(new_folio, new_de);
nilfs_mark_inode_dirty(new_dir);
inode_set_ctime_current(new_inode);
if (dir_de)
@@ -410,14 +410,14 @@ 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);
- unmap_and_put_page(dir_page, dir_de);
+ nilfs_set_link(old_inode, dir_de, dir_folio, new_dir);
+ folio_release_kmap(dir_folio, dir_de);
drop_nlink(old_dir);
}
- unmap_and_put_page(old_page, old_de);
+ folio_release_kmap(old_folio, old_de);
nilfs_mark_inode_dirty(old_dir);
nilfs_mark_inode_dirty(old_inode);
@@ -427,9 +427,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 13/17] nilfs2: Convert nilfs_add_link() to use a folio
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (11 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 12/17] nilfs2: Convert nilfs_rename() to use folios Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 14/17] nilfs2: Convert nilfs_empty_dir() " Ryusuke Konishi
` (3 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Remove six calls to compound_head() by using the folio API.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 2a759598801b..8d8c42e34148 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -439,30 +439,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 */
@@ -489,16 +487,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) {
@@ -513,16 +511,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 14/17] nilfs2: Convert nilfs_empty_dir() to use a folio
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (12 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 13/17] nilfs2: Convert nilfs_add_link() to use a folio Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 15/17] nilfs2: Convert nilfs_make_empty() " Ryusuke Konishi
` (2 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Remove three calls to compound_head() by using the folio API.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 8d8c42e34148..919936d9ec27 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.
*
@@ -611,14 +600,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;
@@ -647,12 +636,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 15/17] nilfs2: Convert nilfs_make_empty() to use a folio
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (13 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 14/17] nilfs2: Convert nilfs_empty_dir() " Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 16/17] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 17/17] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug() Ryusuke Konishi
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Remove two calls to compound_head() and switch from kmap_atomic to
kmap_local.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 919936d9ec27..ff0a009a292f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -559,21 +559,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;
@@ -588,10 +588,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 16/17] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (14 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 15/17] nilfs2: Convert nilfs_make_empty() " Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
2023-11-27 14:30 ` [PATCH 17/17] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug() Ryusuke Konishi
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
All callers now have a folio, so convert these two functions.
Saves one call to compound_head() in unlock_page().
[ konishi.ryusuke: resolved conflicts in nilfs_{set_link,delete_entry} ]
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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 ff0a009a292f..bc846b904b68 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);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
}
@@ -485,7 +484,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) {
@@ -500,7 +499,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 */
@@ -542,12 +541,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:
return err;
@@ -568,7 +567,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;
@@ -589,7 +588,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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 17/17] nilfs2: Convert nilfs_page_bug() to nilfs_folio_bug()
2023-11-27 14:30 [PATCH 00/17] nilfs2: Folio conversions for directory paths Ryusuke Konishi
` (15 preceding siblings ...)
2023-11-27 14:30 ` [PATCH 16/17] nilfs2: Convert nilfs_prepare_chunk() and nilfs_commit_chunk() to folios Ryusuke Konishi
@ 2023-11-27 14:30 ` Ryusuke Konishi
16 siblings, 0 replies; 20+ messages in thread
From: Ryusuke Konishi @ 2023-11-27 14:30 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-nilfs, Matthew Wilcox, linux-kernel
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
All callers have a folio now, so convert it.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
---
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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread