nilfs2: switch to kmap_local for directory handling
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 27 Nov 2023 14:30:27 +0000 (23:30 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 11 Dec 2023 01:21:46 +0000 (17:21 -0800)
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]
Link: https://lkml.kernel.org/r/20231127143036.2425-9-konishi.ryusuke@gmail.com
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/nilfs2/dir.c
fs/nilfs2/namei.c
fs/nilfs2/nilfs.h

index 01900e84bddfd35b5dc5b3a5be0671e18205d288..89e8a248e571447ffcbc9c529fb401ab42c9f70a 100644 (file)
@@ -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 @@ got_it:
        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 @@ fail:
 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;
 }
 
index d179db8074c235d1094d2a38e163f65f09e4e53f..c08b1bf9fa7b43cd4a6be8961c973edc5f89b06e 100644 (file)
@@ -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;
index afd700f5dc4e4f229707230a45802b146e6aad9d..8046490cd7fea29e14c20d9b8ba6f58875cd68f1 100644 (file)
@@ -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);