* [PATCH 01/10] ufs: Convert ufs_get_page() to use a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-16 22:31 ` Al Viro
2024-07-09 3:30 ` [PATCH 02/10] ufs: Convert ufs_get_page() to ufs_get_folio() Matthew Wilcox (Oracle)
` (9 subsequent siblings)
10 siblings, 1 reply; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Remove a call to read_mapping_page().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 61f25d3cf3f7..0705848899c1 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -194,18 +194,19 @@ static bool ufs_check_page(struct page *page)
static struct page *ufs_get_page(struct inode *dir, unsigned long n)
{
struct address_space *mapping = dir->i_mapping;
- struct page *page = read_mapping_page(mapping, n, NULL);
- if (!IS_ERR(page)) {
- kmap(page);
- if (unlikely(!PageChecked(page))) {
- if (!ufs_check_page(page))
- goto fail;
- }
+ struct folio *folio = read_mapping_folio(mapping, n, NULL);
+
+ if (IS_ERR(folio))
+ return &folio->page;
+ kmap(&folio->page);
+ if (unlikely(!folio_test_checked(folio))) {
+ if (!ufs_check_page(&folio->page))
+ goto fail;
}
- return page;
+ return &folio->page;
fail:
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
return ERR_PTR(-EIO);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/10] ufs: Convert ufs_get_page() to ufs_get_folio()
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 01/10] ufs: Convert ufs_get_page() to use a folio Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 03/10] ufs: Convert ufs_check_page() to ufs_check_folio() Matthew Wilcox (Oracle)
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Use the same calling convention as ext2 (see commit 46022375abe8)
so that we can transition to kmap_local in a future patch.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 101 ++++++++++++++++++++++++---------------------------
1 file changed, 48 insertions(+), 53 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 0705848899c1..6c3235f426ed 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -191,19 +191,22 @@ static bool ufs_check_page(struct page *page)
return false;
}
-static struct page *ufs_get_page(struct inode *dir, unsigned long n)
+static void *ufs_get_folio(struct inode *dir, unsigned long n,
+ struct folio **foliop)
{
struct address_space *mapping = dir->i_mapping;
struct folio *folio = read_mapping_folio(mapping, n, NULL);
+ void *kaddr;
if (IS_ERR(folio))
- return &folio->page;
- kmap(&folio->page);
+ return ERR_CAST(folio);
+ kaddr = kmap(&folio->page);
if (unlikely(!folio_test_checked(folio))) {
if (!ufs_check_page(&folio->page))
goto fail;
}
- return &folio->page;
+ *foliop = folio;
+ return kaddr;
fail:
ufs_put_page(&folio->page);
@@ -234,14 +237,14 @@ ufs_next_entry(struct super_block *sb, struct ufs_dir_entry *p)
struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct page **p)
{
- struct page *page = ufs_get_page(dir, 0);
- struct ufs_dir_entry *de = NULL;
+ struct folio *folio;
+ struct ufs_dir_entry *de = ufs_get_folio(dir, 0, &folio);
+
+ if (IS_ERR(de))
+ return NULL;
+ de = ufs_next_entry(dir->i_sb, de);
+ *p = &folio->page;
- if (!IS_ERR(page)) {
- de = ufs_next_entry(dir->i_sb,
- (struct ufs_dir_entry *)page_address(page));
- *p = page;
- }
return de;
}
@@ -262,7 +265,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
unsigned reclen = UFS_DIR_REC_LEN(namelen);
unsigned long start, n;
unsigned long npages = dir_pages(dir);
- struct page *page = NULL;
+ struct folio *folio;
struct ufs_inode_info *ui = UFS_I(dir);
struct ufs_dir_entry *de;
@@ -280,18 +283,17 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
start = 0;
n = start;
do {
- char *kaddr;
- page = ufs_get_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
- de = (struct ufs_dir_entry *) kaddr;
+ char *kaddr = ufs_get_folio(dir, n, &folio);
+
+ if (!IS_ERR(kaddr)) {
+ de = (struct ufs_dir_entry *)kaddr;
kaddr += ufs_last_byte(dir, n) - reclen;
while ((char *) de <= kaddr) {
if (ufs_match(sb, namelen, name, de))
goto found;
de = ufs_next_entry(sb, de);
}
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
}
if (++n >= npages)
n = 0;
@@ -300,7 +302,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
return NULL;
found:
- *res_page = page;
+ *res_page = &folio->page;
ui->i_dir_start_lookup = n;
return de;
}
@@ -317,11 +319,10 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
unsigned reclen = UFS_DIR_REC_LEN(namelen);
const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
unsigned short rec_len, name_len;
- struct page *page = NULL;
+ struct folio *folio = NULL;
struct ufs_dir_entry *de;
unsigned long npages = dir_pages(dir);
unsigned long n;
- char *kaddr;
loff_t pos;
int err;
@@ -329,21 +330,19 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
/*
* 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 = ufs_get_folio(dir, n, &folio);
char *dir_end;
- page = ufs_get_page(dir, n);
- err = PTR_ERR(page);
- if (IS_ERR(page))
- goto out;
- lock_page(page);
- kaddr = page_address(page);
+ if (IS_ERR(kaddr))
+ return PTR_ERR(kaddr);
+ folio_lock(folio);
dir_end = kaddr + ufs_last_byte(dir, n);
de = (struct ufs_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 */
@@ -370,16 +369,15 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
goto got_it;
de = (struct ufs_dir_entry *) ((char *) de + rec_len);
}
- unlock_page(page);
- ufs_put_page(page);
+ folio_unlock(folio);
+ ufs_put_page(&folio->page);
}
BUG();
return -EINVAL;
got_it:
- pos = page_offset(page) +
- (char*)de - (char*)page_address(page);
- err = ufs_prepare_chunk(page, pos, rec_len);
+ pos = folio_pos(folio) + offset_in_folio(folio, de);
+ err = ufs_prepare_chunk(&folio->page, pos, rec_len);
if (err)
goto out_unlock;
if (de->d_ino) {
@@ -396,18 +394,17 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
ufs_set_de_type(sb, de, inode->i_mode);
- ufs_commit_chunk(page, pos, rec_len);
+ ufs_commit_chunk(&folio->page, pos, rec_len);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
mark_inode_dirty(dir);
err = ufs_handle_dirsync(dir);
/* OFFSET_CACHE */
out_put:
- ufs_put_page(page);
-out:
+ ufs_put_page(&folio->page);
return err;
out_unlock:
- unlock_page(page);
+ folio_unlock(folio);
goto out_put;
}
@@ -445,19 +442,18 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
return 0;
for ( ; n < npages; n++, offset = 0) {
- char *kaddr, *limit;
struct ufs_dir_entry *de;
+ struct folio *folio;
+ char *kaddr = ufs_get_folio(inode, n, &folio);
+ char *limit;
- struct page *page = ufs_get_page(inode, n);
-
- if (IS_ERR(page)) {
+ if (IS_ERR(kaddr)) {
ufs_error(sb, __func__,
"bad page in #%lu",
inode->i_ino);
ctx->pos += PAGE_SIZE - offset;
- return -EIO;
+ return PTR_ERR(kaddr);
}
- kaddr = page_address(page);
if (unlikely(need_revalidate)) {
if (offset) {
offset = ufs_validate_entry(sb, kaddr, offset, chunk_mask);
@@ -483,13 +479,13 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
ufs_get_de_namlen(sb, de),
fs32_to_cpu(sb, de->d_ino),
d_type)) {
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
return 0;
}
}
ctx->pos += fs16_to_cpu(sb, de->d_reclen);
}
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
}
return 0;
}
@@ -600,18 +596,17 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
int ufs_empty_dir(struct inode * inode)
{
struct super_block *sb = inode->i_sb;
- struct page *page = NULL;
+ struct folio *folio;
+ char *kaddr;
unsigned long i, npages = dir_pages(inode);
for (i = 0; i < npages; i++) {
- char *kaddr;
struct ufs_dir_entry *de;
- page = ufs_get_page(inode, i);
- if (IS_ERR(page))
+ kaddr = ufs_get_folio(inode, i, &folio);
+ if (IS_ERR(kaddr))
continue;
- kaddr = page_address(page);
de = (struct ufs_dir_entry *)kaddr;
kaddr += ufs_last_byte(inode, i) - UFS_DIR_REC_LEN(1);
@@ -638,12 +633,12 @@ int ufs_empty_dir(struct inode * inode)
}
de = ufs_next_entry(sb, de);
}
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
}
return 1;
not_empty:
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/10] ufs: Convert ufs_check_page() to ufs_check_folio()
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 01/10] ufs: Convert ufs_get_page() to use a folio Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 02/10] ufs: Convert ufs_get_page() to ufs_get_folio() Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 04/10] ufs: Convert ufs_find_entry() to take a folio Matthew Wilcox (Oracle)
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Includes large folio support in case we decide to support block size >
PAGE_SIZE (as with ext2, this support will be limited to machines
without HIGHMEM).
---
fs/ufs/dir.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 6c3235f426ed..287cab597cc1 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -112,20 +112,18 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
ufs_handle_dirsync(dir);
}
-
-static bool ufs_check_page(struct page *page)
+static bool ufs_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;
- char *kaddr = page_address(page);
unsigned offs, rec_len;
- unsigned limit = PAGE_SIZE;
+ unsigned limit = folio_size(folio);
const unsigned chunk_mask = UFS_SB(sb)->s_uspi->s_dirblksize - 1;
struct ufs_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 = offset_in_folio(folio, dir->i_size);
if (limit & chunk_mask)
goto Ebadsize;
if (!limit)
@@ -150,13 +148,13 @@ static bool ufs_check_page(struct page *page)
if (offs != limit)
goto Eend;
out:
- SetPageChecked(page);
+ folio_set_checked(folio);
return true;
/* Too bad, we had an error */
Ebadsize:
- ufs_error(sb, "ufs_check_page",
+ ufs_error(sb, __func__,
"size of directory #%lu is not a multiple of chunk size",
dir->i_ino
);
@@ -176,17 +174,17 @@ static bool ufs_check_page(struct page *page)
Einumber:
error = "inode out of bounds";
bad_entry:
- ufs_error (sb, "ufs_check_page", "bad entry in directory #%lu: %s - "
- "offset=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index<<PAGE_SHIFT)+offs,
+ ufs_error(sb, __func__, "bad entry in directory #%lu: %s - "
+ "offset=%llu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, folio_pos(folio) + offs,
rec_len, ufs_get_de_namlen(sb, p));
goto fail;
Eend:
p = (struct ufs_dir_entry *)(kaddr + offs);
ufs_error(sb, __func__,
"entry in directory #%lu spans the page boundary"
- "offset=%lu",
- dir->i_ino, (page->index<<PAGE_SHIFT)+offs);
+ "offset=%llu",
+ dir->i_ino, folio_pos(folio) + offs);
fail:
return false;
}
@@ -202,7 +200,7 @@ static void *ufs_get_folio(struct inode *dir, unsigned long n,
return ERR_CAST(folio);
kaddr = kmap(&folio->page);
if (unlikely(!folio_test_checked(folio))) {
- if (!ufs_check_page(&folio->page))
+ if (!ufs_check_folio(folio, kaddr))
goto fail;
}
*foliop = folio;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/10] ufs: Convert ufs_find_entry() to take a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (2 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 03/10] ufs: Convert ufs_check_page() to ufs_check_folio() Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 05/10] ufs: Convert ufs_set_link() and ufss_dotdot() " Matthew Wilcox (Oracle)
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
This matches ext2 and pushes the use of folios out by one layer.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 17 ++++++-----------
fs/ufs/namei.c | 22 +++++++++++-----------
fs/ufs/ufs.h | 20 +++++++++++---------
3 files changed, 28 insertions(+), 31 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 287cab597cc1..fb56a00b622c 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -76,12 +76,12 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
{
ino_t res = 0;
struct ufs_dir_entry *de;
- struct page *page;
+ struct folio *folio;
- de = ufs_find_entry(dir, qstr, &page);
+ de = ufs_find_entry(dir, qstr, &folio);
if (de) {
res = fs32_to_cpu(dir->i_sb, de->d_ino);
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
}
return res;
}
@@ -255,7 +255,7 @@ struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct page **p)
* Entry is guaranteed to be valid.
*/
struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
- struct page **res_page)
+ struct folio **foliop)
{
struct super_block *sb = dir->i_sb;
const unsigned char *name = qstr->name;
@@ -263,7 +263,6 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
unsigned reclen = UFS_DIR_REC_LEN(namelen);
unsigned long start, n;
unsigned long npages = dir_pages(dir);
- struct folio *folio;
struct ufs_inode_info *ui = UFS_I(dir);
struct ufs_dir_entry *de;
@@ -272,16 +271,13 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
if (npages == 0 || namelen > UFS_MAXNAMLEN)
goto out;
- /* OFFSET_CACHE */
- *res_page = NULL;
-
start = ui->i_dir_start_lookup;
if (start >= npages)
start = 0;
n = start;
do {
- char *kaddr = ufs_get_folio(dir, n, &folio);
+ char *kaddr = ufs_get_folio(dir, n, foliop);
if (!IS_ERR(kaddr)) {
de = (struct ufs_dir_entry *)kaddr;
@@ -291,7 +287,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
goto found;
de = ufs_next_entry(sb, de);
}
- ufs_put_page(&folio->page);
+ ufs_put_page(&(*foliop)->page);
}
if (++n >= npages)
n = 0;
@@ -300,7 +296,6 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
return NULL;
found:
- *res_page = &folio->page;
ui->i_dir_start_lookup = n;
return de;
}
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 9cad29463791..53e9bfad54df 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -209,14 +209,14 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode * inode = d_inode(dentry);
struct ufs_dir_entry *de;
- struct page *page;
+ struct folio *folio;
int err = -ENOENT;
- de = ufs_find_entry(dir, &dentry->d_name, &page);
+ de = ufs_find_entry(dir, &dentry->d_name, &folio);
if (!de)
goto out;
- err = ufs_delete_entry(dir, de, page);
+ err = ufs_delete_entry(dir, de, &folio->page);
if (err)
goto out;
@@ -251,14 +251,14 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
struct inode *new_inode = d_inode(new_dentry);
struct page *dir_page = NULL;
struct ufs_dir_entry * dir_de = NULL;
- struct page *old_page;
+ struct folio *old_folio;
struct ufs_dir_entry *old_de;
int err = -ENOENT;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
- old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
+ old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_folio);
if (!old_de)
goto out;
@@ -270,7 +270,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
}
if (new_inode) {
- struct page *new_page;
+ struct folio *new_folio;
struct ufs_dir_entry *new_de;
err = -ENOTEMPTY;
@@ -278,10 +278,10 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
goto out_dir;
err = -ENOENT;
- new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page);
+ new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_folio);
if (!new_de)
goto out_dir;
- ufs_set_link(new_dir, new_de, new_page, old_inode, 1);
+ ufs_set_link(new_dir, new_de, &new_folio->page, old_inode, 1);
inode_set_ctime_current(new_inode);
if (dir_de)
drop_nlink(new_inode);
@@ -300,7 +300,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
*/
inode_set_ctime_current(old_inode);
- ufs_delete_entry(old_dir, old_de, old_page);
+ ufs_delete_entry(old_dir, old_de, &old_folio->page);
mark_inode_dirty(old_inode);
if (dir_de) {
@@ -321,8 +321,8 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
put_page(dir_page);
}
out_old:
- kunmap(old_page);
- put_page(old_page);
+ kunmap(&old_folio->page);
+ folio_put(old_folio);
out:
return err;
}
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 6b499180643b..161fe0bb6fd1 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -99,15 +99,17 @@ extern void ufs_put_cylinder (struct super_block *, unsigned);
/* dir.c */
extern const struct inode_operations ufs_dir_inode_operations;
-extern int ufs_add_link (struct dentry *, struct inode *);
-extern ino_t ufs_inode_by_name(struct inode *, const struct qstr *);
-extern int ufs_make_empty(struct inode *, struct inode *);
-extern struct ufs_dir_entry *ufs_find_entry(struct inode *, const struct qstr *, struct page **);
-extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
-extern int ufs_empty_dir (struct inode *);
-extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
-extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode, bool update_times);
+
+int ufs_add_link(struct dentry *, struct inode *);
+ino_t ufs_inode_by_name(struct inode *, const struct qstr *);
+int ufs_make_empty(struct inode *, struct inode *);
+struct ufs_dir_entry *ufs_find_entry(struct inode *, const struct qstr *,
+ struct folio **);
+int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
+int ufs_empty_dir(struct inode *);
+struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
+void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
+ struct page *page, struct inode *inode, bool update_times);
/* file.c */
extern const struct inode_operations ufs_file_inode_operations;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/10] ufs: Convert ufs_set_link() and ufss_dotdot() to take a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (3 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 04/10] ufs: Convert ufs_find_entry() to take a folio Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 06/10] ufs: Convert ufs_delete_entry() to work on " Matthew Wilcox (Oracle)
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
This matches ext2 and removes a few hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 26 +++++++++++---------------
fs/ufs/namei.c | 16 ++++++++--------
fs/ufs/ufs.h | 4 ++--
3 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index fb56a00b622c..6fcca4dd064a 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -89,23 +89,22 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
/* Releases the page */
void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode,
+ struct folio *folio, struct inode *inode,
bool update_times)
{
- loff_t pos = page_offset(page) +
- (char *) de - (char *) page_address(page);
+ loff_t pos = folio_pos(folio) + offset_in_folio(folio, de);
unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen);
int err;
- lock_page(page);
- err = ufs_prepare_chunk(page, pos, len);
+ folio_lock(folio);
+ err = ufs_prepare_chunk(&folio->page, pos, len);
BUG_ON(err);
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
- ufs_commit_chunk(page, pos, len);
- ufs_put_page(page);
+ ufs_commit_chunk(&folio->page, pos, len);
+ ufs_put_page(&folio->page);
if (update_times)
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
mark_inode_dirty(dir);
@@ -233,17 +232,14 @@ ufs_next_entry(struct super_block *sb, struct ufs_dir_entry *p)
fs16_to_cpu(sb, p->d_reclen));
}
-struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct page **p)
+struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct folio **foliop)
{
- struct folio *folio;
- struct ufs_dir_entry *de = ufs_get_folio(dir, 0, &folio);
+ struct ufs_dir_entry *de = ufs_get_folio(dir, 0, foliop);
- if (IS_ERR(de))
- return NULL;
- de = ufs_next_entry(dir->i_sb, de);
- *p = &folio->page;
+ if (!IS_ERR(de))
+ return ufs_next_entry(dir->i_sb, de);
- return de;
+ return NULL;
}
/*
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 53e9bfad54df..1759b710d831 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -249,7 +249,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
{
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 ufs_dir_entry * dir_de = NULL;
struct folio *old_folio;
struct ufs_dir_entry *old_de;
@@ -264,7 +264,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
if (S_ISDIR(old_inode->i_mode)) {
err = -EIO;
- dir_de = ufs_dotdot(old_inode, &dir_page);
+ dir_de = ufs_dotdot(old_inode, &dir_folio);
if (!dir_de)
goto out_old;
}
@@ -281,7 +281,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_folio);
if (!new_de)
goto out_dir;
- ufs_set_link(new_dir, new_de, &new_folio->page, old_inode, 1);
+ ufs_set_link(new_dir, new_de, new_folio, old_inode, 1);
inode_set_ctime_current(new_inode);
if (dir_de)
drop_nlink(new_inode);
@@ -305,10 +305,10 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
if (dir_de) {
if (old_dir != new_dir)
- ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0);
+ ufs_set_link(old_inode, dir_de, dir_folio, new_dir, 0);
else {
- kunmap(dir_page);
- put_page(dir_page);
+ kunmap(&dir_folio->page);
+ folio_put(dir_folio);
}
inode_dec_link_count(old_dir);
}
@@ -317,8 +317,8 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
out_dir:
if (dir_de) {
- kunmap(dir_page);
- put_page(dir_page);
+ kunmap(&dir_folio->page);
+ folio_put(dir_folio);
}
out_old:
kunmap(&old_folio->page);
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 161fe0bb6fd1..1ad992ab2855 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -107,9 +107,9 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *, const struct qstr *,
struct folio **);
int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
int ufs_empty_dir(struct inode *);
-struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
+struct ufs_dir_entry *ufs_dotdot(struct inode *, struct folio **);
void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode, bool update_times);
+ struct folio *folio, struct inode *inode, bool update_times);
/* file.c */
extern const struct inode_operations ufs_file_inode_operations;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/10] ufs: Convert ufs_delete_entry() to work on a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (4 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 05/10] ufs: Convert ufs_set_link() and ufss_dotdot() " Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 07/10] ufs: Convert ufs_make_empty() to use " Matthew Wilcox (Oracle)
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Match ext2 and remove a few hidden calls to compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 29 ++++++++++++++++-------------
fs/ufs/namei.c | 4 ++--
fs/ufs/ufs.h | 2 +-
3 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 6fcca4dd064a..945fff87b385 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -485,19 +485,23 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
* previous entry.
*/
int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
- struct page * page)
+ struct folio *folio)
{
struct super_block *sb = inode->i_sb;
- char *kaddr = page_address(page);
- unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
- unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
+ size_t from, to;
+ char *kaddr;
loff_t pos;
- struct ufs_dir_entry *pde = NULL;
- struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
+ struct ufs_dir_entry *de, *pde = NULL;
int err;
UFSD("ENTER\n");
+ from = offset_in_folio(folio, dir);
+ to = from + fs16_to_cpu(sb, dir->d_reclen);
+ kaddr = (char *)dir - from;
+ from &= ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
+ de = (struct ufs_dir_entry *) (kaddr + from);
+
UFSD("ino %u, reclen %u, namlen %u, name %s\n",
fs32_to_cpu(sb, de->d_ino),
fs16_to_cpu(sb, de->d_reclen),
@@ -514,21 +518,20 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
de = ufs_next_entry(sb, de);
}
if (pde)
- from = (char*)pde - (char*)page_address(page);
-
- pos = page_offset(page) + from;
- lock_page(page);
- err = ufs_prepare_chunk(page, pos, to - from);
+ from = offset_in_folio(folio, pde);
+ pos = folio_pos(folio) + from;
+ folio_lock(folio);
+ err = ufs_prepare_chunk(&folio->page, pos, to - from);
BUG_ON(err);
if (pde)
pde->d_reclen = cpu_to_fs16(sb, to - from);
dir->d_ino = 0;
- ufs_commit_chunk(page, pos, to - from);
+ ufs_commit_chunk(&folio->page, pos, to - from);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
mark_inode_dirty(inode);
err = ufs_handle_dirsync(inode);
out:
- ufs_put_page(page);
+ ufs_put_page(&folio->page);
UFSD("EXIT\n");
return err;
}
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 1759b710d831..a9b0c15de067 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -216,7 +216,7 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry)
if (!de)
goto out;
- err = ufs_delete_entry(dir, de, &folio->page);
+ err = ufs_delete_entry(dir, de, folio);
if (err)
goto out;
@@ -300,7 +300,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
*/
inode_set_ctime_current(old_inode);
- ufs_delete_entry(old_dir, old_de, &old_folio->page);
+ ufs_delete_entry(old_dir, old_de, old_folio);
mark_inode_dirty(old_inode);
if (dir_de) {
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 1ad992ab2855..a2c762cb65a0 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -105,7 +105,7 @@ ino_t ufs_inode_by_name(struct inode *, const struct qstr *);
int ufs_make_empty(struct inode *, struct inode *);
struct ufs_dir_entry *ufs_find_entry(struct inode *, const struct qstr *,
struct folio **);
-int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
+int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct folio *);
int ufs_empty_dir(struct inode *);
struct ufs_dir_entry *ufs_dotdot(struct inode *, struct folio **);
void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/10] ufs: Convert ufs_make_empty() to use a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (5 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 06/10] ufs: Convert ufs_delete_entry() to work on " Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 08/10] ufs: Convert ufs_prepare_chunk() to take " Matthew Wilcox (Oracle)
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Removes a few hidden calls to compound_head() and uses kmap_local
instead of kmap.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 945fff87b385..6a2a6af38097 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -540,26 +540,25 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
{
struct super_block * sb = dir->i_sb;
struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct folio *folio = filemap_grab_folio(mapping, 0);
const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
struct ufs_dir_entry * de;
- char *base;
int err;
+ char *kaddr;
- if (!page)
- return -ENOMEM;
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
- err = ufs_prepare_chunk(page, 0, chunk_size);
+ err = ufs_prepare_chunk(&folio->page, 0, chunk_size);
if (err) {
- unlock_page(page);
+ folio_unlock(folio);
goto fail;
}
- kmap(page);
- base = (char*)page_address(page);
- memset(base, 0, PAGE_SIZE);
+ kaddr = kmap_local_folio(folio, 0);
+ memset(kaddr, 0, folio_size(folio));
- de = (struct ufs_dir_entry *) base;
+ de = (struct ufs_dir_entry *)kaddr;
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
ufs_set_de_type(sb, de, inode->i_mode);
@@ -573,12 +572,12 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1));
ufs_set_de_namlen(sb, de, 2);
strcpy (de->d_name, "..");
- kunmap(page);
+ kunmap_local(kaddr);
- ufs_commit_chunk(page, 0, chunk_size);
+ ufs_commit_chunk(&folio->page, 0, chunk_size);
err = ufs_handle_dirsync(inode);
fail:
- put_page(page);
+ folio_put(folio);
return err;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/10] ufs: Convert ufs_prepare_chunk() to take a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (6 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 07/10] ufs: Convert ufs_make_empty() to use " Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 09/10] ufs; Convert ufs_commit_chunk() " Matthew Wilcox (Oracle)
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
All callers now have a folio, so convert ufs_prepare_chunk() to take one.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 8 ++++----
fs/ufs/inode.c | 4 ++--
fs/ufs/util.h | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 6a2a6af38097..a20f66351c66 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -97,7 +97,7 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
int err;
folio_lock(folio);
- err = ufs_prepare_chunk(&folio->page, pos, len);
+ err = ufs_prepare_chunk(folio, pos, len);
BUG_ON(err);
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
@@ -366,7 +366,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
got_it:
pos = folio_pos(folio) + offset_in_folio(folio, de);
- err = ufs_prepare_chunk(&folio->page, pos, rec_len);
+ err = ufs_prepare_chunk(folio, pos, rec_len);
if (err)
goto out_unlock;
if (de->d_ino) {
@@ -521,7 +521,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
from = offset_in_folio(folio, pde);
pos = folio_pos(folio) + from;
folio_lock(folio);
- err = ufs_prepare_chunk(&folio->page, pos, to - from);
+ err = ufs_prepare_chunk(folio, pos, to - from);
BUG_ON(err);
if (pde)
pde->d_reclen = cpu_to_fs16(sb, to - from);
@@ -549,7 +549,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
if (IS_ERR(folio))
return PTR_ERR(folio);
- err = ufs_prepare_chunk(&folio->page, 0, chunk_size);
+ err = ufs_prepare_chunk(folio, 0, chunk_size);
if (err) {
folio_unlock(folio);
goto fail;
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index a7bb2e63cdde..0e608fc0d0fd 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -479,9 +479,9 @@ static int ufs_read_folio(struct file *file, struct folio *folio)
return block_read_full_folio(folio, ufs_getfrag_block);
}
-int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
+int ufs_prepare_chunk(struct folio *folio, loff_t pos, unsigned len)
{
- return __block_write_begin(page, pos, len, ufs_getfrag_block);
+ return __block_write_begin(&folio->page, pos, len, ufs_getfrag_block);
}
static void ufs_truncate_blocks(struct inode *);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 0ecd2ed792f5..bf708b68f150 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -250,9 +250,9 @@ ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
}
}
-extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
-extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
-extern int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len);
+dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
+void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
+int ufs_prepare_chunk(struct folio *folio, loff_t pos, unsigned len);
/*
* These functions manipulate ufs buffers
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/10] ufs; Convert ufs_commit_chunk() to take a folio
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (7 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 08/10] ufs: Convert ufs_prepare_chunk() to take " Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-09 3:30 ` [PATCH 10/10] ufs: Convert directory handling to kmap_local Matthew Wilcox (Oracle)
2024-07-16 22:46 ` [PATCH 00/10] Convert UFS directory handling to folios Al Viro
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
All callers now have a folio, so pass it in. Saves a call to
compound_head().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index a20f66351c66..71685491d5f6 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -42,18 +42,18 @@ static inline int ufs_match(struct super_block *sb, int len,
return !memcmp(name, de->d_name, len);
}
-static void ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
+static void ufs_commit_chunk(struct folio *folio, loff_t pos, unsigned len)
{
- struct address_space *mapping = page->mapping;
+ struct address_space *mapping = folio->mapping;
struct inode *dir = mapping->host;
inode_inc_iversion(dir);
- block_write_end(NULL, mapping, pos, len, len, page, NULL);
+ block_write_end(NULL, mapping, pos, len, len, &folio->page, NULL);
if (pos+len > dir->i_size) {
i_size_write(dir, pos+len);
mark_inode_dirty(dir);
}
- unlock_page(page);
+ folio_unlock(folio);
}
static int ufs_handle_dirsync(struct inode *dir)
@@ -103,7 +103,7 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
- ufs_commit_chunk(&folio->page, pos, len);
+ ufs_commit_chunk(folio, pos, len);
ufs_put_page(&folio->page);
if (update_times)
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
@@ -383,7 +383,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
ufs_set_de_type(sb, de, inode->i_mode);
- ufs_commit_chunk(&folio->page, pos, rec_len);
+ ufs_commit_chunk(folio, pos, rec_len);
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
mark_inode_dirty(dir);
@@ -526,7 +526,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
if (pde)
pde->d_reclen = cpu_to_fs16(sb, to - from);
dir->d_ino = 0;
- ufs_commit_chunk(&folio->page, pos, to - from);
+ ufs_commit_chunk(folio, pos, to - from);
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
mark_inode_dirty(inode);
err = ufs_handle_dirsync(inode);
@@ -574,7 +574,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
strcpy (de->d_name, "..");
kunmap_local(kaddr);
- ufs_commit_chunk(&folio->page, 0, chunk_size);
+ ufs_commit_chunk(folio, 0, chunk_size);
err = ufs_handle_dirsync(inode);
fail:
folio_put(folio);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/10] ufs: Convert directory handling to kmap_local
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (8 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 09/10] ufs; Convert ufs_commit_chunk() " Matthew Wilcox (Oracle)
@ 2024-07-09 3:30 ` Matthew Wilcox (Oracle)
2024-07-16 22:46 ` [PATCH 00/10] Convert UFS directory handling to folios Al Viro
10 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-07-09 3:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: Matthew Wilcox (Oracle), Al Viro, Christoph Hellwig
Remove kmap use and use folio_release_kmap() instead of ufs_put_page().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/ufs/dir.c | 30 ++++++++++++------------------
fs/ufs/namei.c | 15 +++++----------
2 files changed, 17 insertions(+), 28 deletions(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 71685491d5f6..3b3cd84f1f7f 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -66,12 +66,6 @@ static int ufs_handle_dirsync(struct inode *dir)
return err;
}
-static inline void ufs_put_page(struct page *page)
-{
- kunmap(page);
- put_page(page);
-}
-
ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
{
ino_t res = 0;
@@ -81,7 +75,7 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
de = ufs_find_entry(dir, qstr, &folio);
if (de) {
res = fs32_to_cpu(dir->i_sb, de->d_ino);
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, de);
}
return res;
}
@@ -104,7 +98,7 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
ufs_commit_chunk(folio, pos, len);
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, de);
if (update_times)
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
mark_inode_dirty(dir);
@@ -197,7 +191,7 @@ static void *ufs_get_folio(struct inode *dir, unsigned long n,
if (IS_ERR(folio))
return ERR_CAST(folio);
- kaddr = kmap(&folio->page);
+ kaddr = kmap_local_folio(folio, 0);
if (unlikely(!folio_test_checked(folio))) {
if (!ufs_check_folio(folio, kaddr))
goto fail;
@@ -206,7 +200,7 @@ static void *ufs_get_folio(struct inode *dir, unsigned long n,
return kaddr;
fail:
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
return ERR_PTR(-EIO);
}
@@ -283,7 +277,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
goto found;
de = ufs_next_entry(sb, de);
}
- ufs_put_page(&(*foliop)->page);
+ folio_release_kmap(*foliop, kaddr);
}
if (++n >= npages)
n = 0;
@@ -359,7 +353,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
de = (struct ufs_dir_entry *) ((char *) de + rec_len);
}
folio_unlock(folio);
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
}
BUG();
return -EINVAL;
@@ -390,7 +384,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
err = ufs_handle_dirsync(dir);
/* OFFSET_CACHE */
out_put:
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, de);
return err;
out_unlock:
folio_unlock(folio);
@@ -468,13 +462,13 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
ufs_get_de_namlen(sb, de),
fs32_to_cpu(sb, de->d_ino),
d_type)) {
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, de);
return 0;
}
}
ctx->pos += fs16_to_cpu(sb, de->d_reclen);
}
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
}
return 0;
}
@@ -531,7 +525,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
mark_inode_dirty(inode);
err = ufs_handle_dirsync(inode);
out:
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
UFSD("EXIT\n");
return err;
}
@@ -624,12 +618,12 @@ int ufs_empty_dir(struct inode * inode)
}
de = ufs_next_entry(sb, de);
}
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
}
return 1;
not_empty:
- ufs_put_page(&folio->page);
+ folio_release_kmap(folio, kaddr);
return 0;
}
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index a9b0c15de067..24bd12186647 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -306,23 +306,18 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
if (dir_de) {
if (old_dir != new_dir)
ufs_set_link(old_inode, dir_de, dir_folio, new_dir, 0);
- else {
- kunmap(&dir_folio->page);
- folio_put(dir_folio);
- }
+ else
+ folio_release_kmap(dir_folio, new_dir);
inode_dec_link_count(old_dir);
}
return 0;
out_dir:
- if (dir_de) {
- kunmap(&dir_folio->page);
- folio_put(dir_folio);
- }
+ if (dir_de)
+ folio_release_kmap(dir_folio, dir_de);
out_old:
- kunmap(&old_folio->page);
- folio_put(old_folio);
+ folio_release_kmap(old_folio, old_de);
out:
return err;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 00/10] Convert UFS directory handling to folios
2024-07-09 3:30 [PATCH 00/10] Convert UFS directory handling to folios Matthew Wilcox (Oracle)
` (9 preceding siblings ...)
2024-07-09 3:30 ` [PATCH 10/10] ufs: Convert directory handling to kmap_local Matthew Wilcox (Oracle)
@ 2024-07-16 22:46 ` Al Viro
10 siblings, 0 replies; 13+ messages in thread
From: Al Viro @ 2024-07-16 22:46 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-fsdevel, Christoph Hellwig
On Tue, Jul 09, 2024 at 04:30:17AM +0100, Matthew Wilcox (Oracle) wrote:
> This patch series mirrors the changes to ext2 directory handling.
> It combines three distinct series of ext2 patches -- using kmap_local,
> Al's refactoring of the xxx_get_page() interfaces and the folio patches,
> and it does them in an order which is slightly more logical when you
> know that you're going to be doing all three of those conversions.
>
> Compile tested only. I can't find a mkfs.ufs / mkfs.ffs. I found a
> Debian package called makefs, but couldn't figure out how to drive it
> the way that fstests wants to.
I can do testing; give me a day or two...
^ permalink raw reply [flat|nested] 13+ messages in thread