]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm, swap: split locked entry duplicating into a standalone helper
authorKairui Song <kasong@tencent.com>
Fri, 19 Dec 2025 19:43:40 +0000 (03:43 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Sat, 31 Jan 2026 22:22:55 +0000 (14:22 -0800)
No feature change, split the common logic into a stand alone helper to be
reused later.

Link: https://lkml.kernel.org/r/20251220-swap-table-p2-v5-11-8862a265a033@tencent.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Reviewed-by: Baoquan He <bhe@redhat.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Chris Li <chrisl@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Cc: Yosry Ahmed <yosry.ahmed@linux.dev>
Cc: Deepanshu Kartikey <kartikey406@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kairui Song <ryncsn@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/swapfile.c

index ce8c75ede5c315b83a97e8ec12ef56a8a47aa67b..ced53aba3f4cd0a21ae3c689dc2a209b4fa06048 100644 (file)
@@ -3667,26 +3667,14 @@ void si_swapinfo(struct sysinfo *val)
  * - swap-cache reference is requested but the entry is not used. -> ENOENT
  * - swap-mapped reference requested but needs continued swap count. -> ENOMEM
  */
-static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
+static int swap_dup_entries(struct swap_info_struct *si,
+                           struct swap_cluster_info *ci,
+                           unsigned long offset,
+                           unsigned char usage, int nr)
 {
-       struct swap_info_struct *si;
-       struct swap_cluster_info *ci;
-       unsigned long offset;
-       unsigned char count;
-       unsigned char has_cache;
-       int err, i;
-
-       si = swap_entry_to_info(entry);
-       if (WARN_ON_ONCE(!si)) {
-               pr_err("%s%08lx\n", Bad_file, entry.val);
-               return -EINVAL;
-       }
-
-       offset = swp_offset(entry);
-       VM_WARN_ON(nr > SWAPFILE_CLUSTER - offset % SWAPFILE_CLUSTER);
-       ci = swap_cluster_lock(si, offset);
+       int i;
+       unsigned char count, has_cache;
 
-       err = 0;
        for (i = 0; i < nr; i++) {
                count = si->swap_map[offset + i];
 
@@ -3694,25 +3682,20 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
                 * For swapin out, allocator never allocates bad slots. for
                 * swapin, readahead is guarded by swap_entry_swapped.
                 */
-               if (WARN_ON(swap_count(count) == SWAP_MAP_BAD)) {
-                       err = -ENOENT;
-                       goto unlock_out;
-               }
+               if (WARN_ON(swap_count(count) == SWAP_MAP_BAD))
+                       return -ENOENT;
 
                has_cache = count & SWAP_HAS_CACHE;
                count &= ~SWAP_HAS_CACHE;
 
                if (!count && !has_cache) {
-                       err = -ENOENT;
+                       return -ENOENT;
                } else if (usage == SWAP_HAS_CACHE) {
                        if (has_cache)
-                               err = -EEXIST;
+                               return -EEXIST;
                } else if ((count & ~COUNT_CONTINUED) > SWAP_MAP_MAX) {
-                       err = -EINVAL;
+                       return -EINVAL;
                }
-
-               if (err)
-                       goto unlock_out;
        }
 
        for (i = 0; i < nr; i++) {
@@ -3731,14 +3714,31 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
                         * Don't need to rollback changes, because if
                         * usage == 1, there must be nr == 1.
                         */
-                       err = -ENOMEM;
-                       goto unlock_out;
+                       return -ENOMEM;
                }
 
                WRITE_ONCE(si->swap_map[offset + i], count | has_cache);
        }
 
-unlock_out:
+       return 0;
+}
+
+static int __swap_duplicate(swp_entry_t entry, unsigned char usage, int nr)
+{
+       int err;
+       struct swap_info_struct *si;
+       struct swap_cluster_info *ci;
+       unsigned long offset = swp_offset(entry);
+
+       si = swap_entry_to_info(entry);
+       if (WARN_ON_ONCE(!si)) {
+               pr_err("%s%08lx\n", Bad_file, entry.val);
+               return -EINVAL;
+       }
+
+       VM_WARN_ON(nr > SWAPFILE_CLUSTER - offset % SWAPFILE_CLUSTER);
+       ci = swap_cluster_lock(si, offset);
+       err = swap_dup_entries(si, ci, offset, usage, nr);
        swap_cluster_unlock(ci);
        return err;
 }