nilfs2: convert persistent object allocator to use kmap_local
authorRyusuke Konishi <konishi.ryusuke@gmail.com>
Mon, 22 Jan 2024 14:01:53 +0000 (23:01 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 22 Feb 2024 23:38:53 +0000 (15:38 -0800)
Regarding the allocator code that is commonly used in the ondisk inode
metadata file ifile and the disk address translation metadata file DAT,
convert the parts that use the deprecated kmap_atomic() and kmap() to use
kmap_local.

Most can be converted directly, but only
nilfs_palloc_prepare_alloc_entry() needs to be rewritten to change mapping
sections so that multiple kmap_local/kunmap_local calls are nested and
disk I/O can be avoided within the mapping sections.

Link: https://lkml.kernel.org/r/20240122140202.6950-7-konishi.ryusuke@gmail.com
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/nilfs2/alloc.c

index 7342de296ec3c6a8486da9f6bb0b16eeded7ca5c..89caef7513db3509b1a83090324b47536a3f8e5e 100644 (file)
@@ -525,54 +525,55 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
                ret = nilfs_palloc_get_desc_block(inode, group, 1, &desc_bh);
                if (ret < 0)
                        return ret;
-               desc_kaddr = kmap(desc_bh->b_page);
+               desc_kaddr = kmap_local_page(desc_bh->b_page);
                desc = nilfs_palloc_block_get_group_desc(
                        inode, group, desc_bh, desc_kaddr);
                n = nilfs_palloc_rest_groups_in_desc_block(inode, group,
                                                           maxgroup);
-               for (j = 0; j < n; j++, desc++, group++) {
+               for (j = 0; j < n; j++, desc++, group++, group_offset = 0) {
                        lock = nilfs_mdt_bgl_lock(inode, group);
-                       if (nilfs_palloc_group_desc_nfrees(desc, lock) > 0) {
-                               ret = nilfs_palloc_get_bitmap_block(
-                                       inode, group, 1, &bitmap_bh);
-                               if (ret < 0)
-                                       goto out_desc;
-                               bitmap_kaddr = kmap(bitmap_bh->b_page);
-                               bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
-                               pos = nilfs_palloc_find_available_slot(
-                                       bitmap, group_offset,
-                                       entries_per_group, lock);
-                               if (pos >= 0) {
-                                       /* found a free entry */
-                                       nilfs_palloc_group_desc_add_entries(
-                                               desc, lock, -1);
-                                       req->pr_entry_nr =
-                                               entries_per_group * group + pos;
-                                       kunmap(desc_bh->b_page);
-                                       kunmap(bitmap_bh->b_page);
-
-                                       req->pr_desc_bh = desc_bh;
-                                       req->pr_bitmap_bh = bitmap_bh;
-                                       return 0;
-                               }
-                               kunmap(bitmap_bh->b_page);
-                               brelse(bitmap_bh);
+                       if (nilfs_palloc_group_desc_nfrees(desc, lock) == 0)
+                               continue;
+
+                       kunmap_local(desc_kaddr);
+                       ret = nilfs_palloc_get_bitmap_block(inode, group, 1,
+                                                           &bitmap_bh);
+                       if (unlikely(ret < 0)) {
+                               brelse(desc_bh);
+                               return ret;
                        }
 
-                       group_offset = 0;
+                       desc_kaddr = kmap_local_page(desc_bh->b_page);
+                       desc = nilfs_palloc_block_get_group_desc(
+                               inode, group, desc_bh, desc_kaddr);
+
+                       bitmap_kaddr = kmap_local_page(bitmap_bh->b_page);
+                       bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
+                       pos = nilfs_palloc_find_available_slot(
+                               bitmap, group_offset, entries_per_group, lock);
+                       kunmap_local(bitmap_kaddr);
+                       if (pos >= 0)
+                               goto found;
+
+                       brelse(bitmap_bh);
                }
 
-               kunmap(desc_bh->b_page);
+               kunmap_local(desc_kaddr);
                brelse(desc_bh);
        }
 
        /* no entries left */
        return -ENOSPC;
 
- out_desc:
-       kunmap(desc_bh->b_page);
-       brelse(desc_bh);
-       return ret;
+found:
+       /* found a free entry */
+       nilfs_palloc_group_desc_add_entries(desc, lock, -1);
+       req->pr_entry_nr = entries_per_group * group + pos;
+       kunmap_local(desc_kaddr);
+
+       req->pr_desc_bh = desc_bh;
+       req->pr_bitmap_bh = bitmap_bh;
+       return 0;
 }
 
 /**
@@ -606,10 +607,10 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
        spinlock_t *lock;
 
        group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
-       desc_kaddr = kmap(req->pr_desc_bh->b_page);
+       desc_kaddr = kmap_local_page(req->pr_desc_bh->b_page);
        desc = nilfs_palloc_block_get_group_desc(inode, group,
                                                 req->pr_desc_bh, desc_kaddr);
-       bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
+       bitmap_kaddr = kmap_local_page(req->pr_bitmap_bh->b_page);
        bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
        lock = nilfs_mdt_bgl_lock(inode, group);
 
@@ -621,8 +622,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
        else
                nilfs_palloc_group_desc_add_entries(desc, lock, 1);
 
-       kunmap(req->pr_bitmap_bh->b_page);
-       kunmap(req->pr_desc_bh->b_page);
+       kunmap_local(bitmap_kaddr);
+       kunmap_local(desc_kaddr);
 
        mark_buffer_dirty(req->pr_desc_bh);
        mark_buffer_dirty(req->pr_bitmap_bh);
@@ -647,10 +648,10 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        spinlock_t *lock;
 
        group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
-       desc_kaddr = kmap(req->pr_desc_bh->b_page);
+       desc_kaddr = kmap_local_page(req->pr_desc_bh->b_page);
        desc = nilfs_palloc_block_get_group_desc(inode, group,
                                                 req->pr_desc_bh, desc_kaddr);
-       bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
+       bitmap_kaddr = kmap_local_page(req->pr_bitmap_bh->b_page);
        bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
        lock = nilfs_mdt_bgl_lock(inode, group);
 
@@ -662,8 +663,8 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        else
                nilfs_palloc_group_desc_add_entries(desc, lock, 1);
 
-       kunmap(req->pr_bitmap_bh->b_page);
-       kunmap(req->pr_desc_bh->b_page);
+       kunmap_local(bitmap_kaddr);
+       kunmap_local(desc_kaddr);
 
        brelse(req->pr_bitmap_bh);
        brelse(req->pr_desc_bh);
@@ -755,7 +756,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
                /* Get the first entry number of the group */
                group_min_nr = (__u64)group * epg;
 
-               bitmap_kaddr = kmap(bitmap_bh->b_page);
+               bitmap_kaddr = kmap_local_page(bitmap_bh->b_page);
                bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
                lock = nilfs_mdt_bgl_lock(inode, group);
 
@@ -801,7 +802,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
                        entry_start = rounddown(group_offset, epb);
                } while (true);
 
-               kunmap(bitmap_bh->b_page);
+               kunmap_local(bitmap_kaddr);
                mark_buffer_dirty(bitmap_bh);
                brelse(bitmap_bh);
 
@@ -815,11 +816,11 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
                                           inode->i_ino);
                }
 
-               desc_kaddr = kmap_atomic(desc_bh->b_page);
+               desc_kaddr = kmap_local_page(desc_bh->b_page);
                desc = nilfs_palloc_block_get_group_desc(
                        inode, group, desc_bh, desc_kaddr);
                nfree = nilfs_palloc_group_desc_add_entries(desc, lock, n);
-               kunmap_atomic(desc_kaddr);
+               kunmap_local(desc_kaddr);
                mark_buffer_dirty(desc_bh);
                nilfs_mdt_mark_dirty(inode);
                brelse(desc_bh);