xfs: refactor ->diff_two_keys callsites
authorDarrick J. Wong <djwong@kernel.org>
Wed, 12 Apr 2023 02:00:10 +0000 (19:00 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 12 Apr 2023 02:00:10 +0000 (19:00 -0700)
Create wrapper functions around ->diff_two_keys so that we don't have to
remember what the return values mean, and adjust some of the code
comments to reflect the longtime code behavior.  We're going to
introduce more uses of ->diff_two_keys in the next patch, so reduce the
cognitive load for readers by doing this refactoring now.

Suggested-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h
fs/xfs/scrub/btree.c

index 5ea1c27e2be68dc4a0789471d6661a19058011c2..92c610850fac7b5508117f5cdd1e248574815e15 100644 (file)
@@ -2067,8 +2067,7 @@ xfs_btree_get_leaf_keys(
                for (n = 2; n <= xfs_btree_get_numrecs(block); n++) {
                        rec = xfs_btree_rec_addr(cur, n, block);
                        cur->bc_ops->init_high_key_from_rec(&hkey, rec);
-                       if (cur->bc_ops->diff_two_keys(cur, &hkey, &max_hkey)
-                                       > 0)
+                       if (xfs_btree_keycmp_gt(cur, &hkey, &max_hkey))
                                max_hkey = hkey;
                }
 
@@ -2096,7 +2095,7 @@ xfs_btree_get_node_keys(
                max_hkey = xfs_btree_high_key_addr(cur, 1, block);
                for (n = 2; n <= xfs_btree_get_numrecs(block); n++) {
                        hkey = xfs_btree_high_key_addr(cur, n, block);
-                       if (cur->bc_ops->diff_two_keys(cur, hkey, max_hkey) > 0)
+                       if (xfs_btree_keycmp_gt(cur, hkey, max_hkey))
                                max_hkey = hkey;
                }
 
@@ -2183,8 +2182,8 @@ __xfs_btree_updkeys(
                nlkey = xfs_btree_key_addr(cur, ptr, block);
                nhkey = xfs_btree_high_key_addr(cur, ptr, block);
                if (!force_all &&
-                   !(cur->bc_ops->diff_two_keys(cur, nlkey, lkey) != 0 ||
-                     cur->bc_ops->diff_two_keys(cur, nhkey, hkey) != 0))
+                   xfs_btree_keycmp_eq(cur, nlkey, lkey) &&
+                   xfs_btree_keycmp_eq(cur, nhkey, hkey))
                        break;
                xfs_btree_copy_keys(cur, nlkey, lkey, 1);
                xfs_btree_log_keys(cur, bp, ptr, ptr);
@@ -4716,7 +4715,6 @@ xfs_btree_simple_query_range(
 {
        union xfs_btree_rec             *recp;
        union xfs_btree_key             rec_key;
-       int64_t                         diff;
        int                             stat;
        bool                            firstrec = true;
        int                             error;
@@ -4746,20 +4744,17 @@ xfs_btree_simple_query_range(
                if (error || !stat)
                        break;
 
-               /* Skip if high_key(rec) < low_key. */
+               /* Skip if low_key > high_key(rec). */
                if (firstrec) {
                        cur->bc_ops->init_high_key_from_rec(&rec_key, recp);
                        firstrec = false;
-                       diff = cur->bc_ops->diff_two_keys(cur, low_key,
-                                       &rec_key);
-                       if (diff > 0)
+                       if (xfs_btree_keycmp_gt(cur, low_key, &rec_key))
                                goto advloop;
                }
 
-               /* Stop if high_key < low_key(rec). */
+               /* Stop if low_key(rec) > high_key. */
                cur->bc_ops->init_key_from_rec(&rec_key, recp);
-               diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key);
-               if (diff > 0)
+               if (xfs_btree_keycmp_gt(cur, &rec_key, high_key))
                        break;
 
                /* Callback */
@@ -4813,8 +4808,6 @@ xfs_btree_overlapped_query_range(
        union xfs_btree_key             *hkp;
        union xfs_btree_rec             *recp;
        struct xfs_btree_block          *block;
-       int64_t                         ldiff;
-       int64_t                         hdiff;
        int                             level;
        struct xfs_buf                  *bp;
        int                             i;
@@ -4854,25 +4847,23 @@ pop_up:
                                        block);
 
                        cur->bc_ops->init_high_key_from_rec(&rec_hkey, recp);
-                       ldiff = cur->bc_ops->diff_two_keys(cur, &rec_hkey,
-                                       low_key);
-
                        cur->bc_ops->init_key_from_rec(&rec_key, recp);
-                       hdiff = cur->bc_ops->diff_two_keys(cur, high_key,
-                                       &rec_key);
 
                        /*
+                        * If (query's high key < record's low key), then there
+                        * are no more interesting records in this block.  Pop
+                        * up to the leaf level to find more record blocks.
+                        *
                         * If (record's high key >= query's low key) and
                         *    (query's high key >= record's low key), then
                         * this record overlaps the query range; callback.
                         */
-                       if (ldiff >= 0 && hdiff >= 0) {
+                       if (xfs_btree_keycmp_lt(cur, high_key, &rec_key))
+                               goto pop_up;
+                       if (xfs_btree_keycmp_ge(cur, &rec_hkey, low_key)) {
                                error = fn(cur, recp, priv);
                                if (error)
                                        break;
-                       } else if (hdiff < 0) {
-                               /* Record is larger than high key; pop. */
-                               goto pop_up;
                        }
                        cur->bc_levels[level].ptr++;
                        continue;
@@ -4884,15 +4875,18 @@ pop_up:
                                block);
                pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block);
 
-               ldiff = cur->bc_ops->diff_two_keys(cur, hkp, low_key);
-               hdiff = cur->bc_ops->diff_two_keys(cur, high_key, lkp);
-
                /*
+                * If (query's high key < pointer's low key), then there are no
+                * more interesting keys in this block.  Pop up one leaf level
+                * to continue looking for records.
+                *
                 * If (pointer's high key >= query's low key) and
                 *    (query's high key >= pointer's low key), then
                 * this record overlaps the query range; follow pointer.
                 */
-               if (ldiff >= 0 && hdiff >= 0) {
+               if (xfs_btree_keycmp_lt(cur, high_key, lkp))
+                       goto pop_up;
+               if (xfs_btree_keycmp_ge(cur, hkp, low_key)) {
                        level--;
                        error = xfs_btree_lookup_get_block(cur, level, pp,
                                        &block);
@@ -4907,9 +4901,6 @@ pop_up:
 #endif
                        cur->bc_levels[level].ptr = 1;
                        continue;
-               } else if (hdiff < 0) {
-                       /* The low key is larger than the upper range; pop. */
-                       goto pop_up;
                }
                cur->bc_levels[level].ptr++;
        }
@@ -4971,8 +4962,8 @@ xfs_btree_query_range(
        xfs_btree_key_from_irec(cur, &high_key, high_rec);
        xfs_btree_key_from_irec(cur, &low_key, low_rec);
 
-       /* Enforce low key < high key. */
-       if (cur->bc_ops->diff_two_keys(cur, &low_key, &high_key) > 0)
+       /* Enforce low key <= high key. */
+       if (!xfs_btree_keycmp_le(cur, &low_key, &high_key))
                return -EINVAL;
 
        if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
index 29c4b4ccb909f5195dfd410c2beeb7a90558caaf..f5aa4b893ee775a96fe360be22725a4ff73303e1 100644 (file)
@@ -546,6 +546,61 @@ int xfs_btree_has_record(struct xfs_btree_cur *cur,
 bool xfs_btree_has_more_records(struct xfs_btree_cur *cur);
 struct xfs_ifork *xfs_btree_ifork_ptr(struct xfs_btree_cur *cur);
 
+/* Key comparison helpers */
+static inline bool
+xfs_btree_keycmp_lt(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return cur->bc_ops->diff_two_keys(cur, key1, key2) < 0;
+}
+
+static inline bool
+xfs_btree_keycmp_gt(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return cur->bc_ops->diff_two_keys(cur, key1, key2) > 0;
+}
+
+static inline bool
+xfs_btree_keycmp_eq(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return cur->bc_ops->diff_two_keys(cur, key1, key2) == 0;
+}
+
+static inline bool
+xfs_btree_keycmp_le(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return !xfs_btree_keycmp_gt(cur, key1, key2);
+}
+
+static inline bool
+xfs_btree_keycmp_ge(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return !xfs_btree_keycmp_lt(cur, key1, key2);
+}
+
+static inline bool
+xfs_btree_keycmp_ne(
+       struct xfs_btree_cur            *cur,
+       const union xfs_btree_key       *key1,
+       const union xfs_btree_key       *key2)
+{
+       return !xfs_btree_keycmp_eq(cur, key1, key2);
+}
+
 /* Does this cursor point to the last block in the given level? */
 static inline bool
 xfs_btree_islastblock(
index 4ec3b1cab01879bc5c901c2938baee2cd89ec57b..1165dc05a179cb11d026b4995ee996635a4be110 100644 (file)
@@ -161,20 +161,20 @@ xchk_btree_rec(
        if (cur->bc_nlevels == 1)
                return;
 
-       /* Is this at least as large as the parent low key? */
+       /* Is low_key(rec) at least as large as the parent low key? */
        cur->bc_ops->init_key_from_rec(&key, rec);
        keyblock = xfs_btree_get_block(cur, 1, &bp);
        keyp = xfs_btree_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
-       if (cur->bc_ops->diff_two_keys(cur, &key, keyp) < 0)
+       if (xfs_btree_keycmp_lt(cur, &key, keyp))
                xchk_btree_set_corrupt(bs->sc, cur, 1);
 
        if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
                return;
 
-       /* Is this no larger than the parent high key? */
+       /* Is high_key(rec) no larger than the parent high key? */
        cur->bc_ops->init_high_key_from_rec(&hkey, rec);
        keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
-       if (cur->bc_ops->diff_two_keys(cur, keyp, &hkey) < 0)
+       if (xfs_btree_keycmp_lt(cur, keyp, &hkey))
                xchk_btree_set_corrupt(bs->sc, cur, 1);
 }
 
@@ -209,20 +209,20 @@ xchk_btree_key(
        if (level + 1 >= cur->bc_nlevels)
                return;
 
-       /* Is this at least as large as the parent low key? */
+       /* Is this block's low key at least as large as the parent low key? */
        keyblock = xfs_btree_get_block(cur, level + 1, &bp);
        keyp = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr, keyblock);
-       if (cur->bc_ops->diff_two_keys(cur, key, keyp) < 0)
+       if (xfs_btree_keycmp_lt(cur, key, keyp))
                xchk_btree_set_corrupt(bs->sc, cur, level);
 
        if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
                return;
 
-       /* Is this no larger than the parent high key? */
+       /* Is this block's high key no larger than the parent high key? */
        key = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, block);
        keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr,
                        keyblock);
-       if (cur->bc_ops->diff_two_keys(cur, keyp, key) < 0)
+       if (xfs_btree_keycmp_lt(cur, keyp, key))
                xchk_btree_set_corrupt(bs->sc, cur, level);
 }
 
@@ -557,7 +557,7 @@ xchk_btree_block_check_keys(
        parent_block = xfs_btree_get_block(cur, level + 1, &bp);
        parent_low_key = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr,
                        parent_block);
-       if (cur->bc_ops->diff_two_keys(cur, &block_key, parent_low_key)) {
+       if (xfs_btree_keycmp_ne(cur, &block_key, parent_low_key)) {
                xchk_btree_set_corrupt(bs->sc, bs->cur, level);
                return;
        }
@@ -569,7 +569,7 @@ xchk_btree_block_check_keys(
        parent_high_key = xfs_btree_high_key_addr(cur,
                        cur->bc_levels[level + 1].ptr, parent_block);
        block_high_key = xfs_btree_high_key_from_key(cur, &block_key);
-       if (cur->bc_ops->diff_two_keys(cur, block_high_key, parent_high_key))
+       if (xfs_btree_keycmp_ne(cur, block_high_key, parent_high_key))
                xchk_btree_set_corrupt(bs->sc, bs->cur, level);
 }
 
@@ -661,7 +661,7 @@ xchk_btree_block_keys(
        parent_keys = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr,
                        parent_block);
 
-       if (cur->bc_ops->diff_two_keys(cur, &block_keys, parent_keys) != 0)
+       if (xfs_btree_keycmp_ne(cur, &block_keys, parent_keys))
                xchk_btree_set_corrupt(bs->sc, cur, 1);
 
        if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
@@ -672,7 +672,7 @@ xchk_btree_block_keys(
        high_pk = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr,
                        parent_block);
 
-       if (cur->bc_ops->diff_two_keys(cur, high_bk, high_pk) != 0)
+       if (xfs_btree_keycmp_ne(cur, high_bk, high_pk))
                xchk_btree_set_corrupt(bs->sc, cur, 1);
 }