diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-08-02 21:03:38 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-08-02 21:03:38 -0400 |
commit | 70b2265935544c2ba64619172fd757bd0ca91800 (patch) | |
tree | 630e69695904ef6a9d5476f8f74291b4ec64ed0c | |
parent | e5821e57af54abc36ea299bde6c101a804cfac27 (diff) |
xfs: add function pointers for get/update keys to the btree
Add some function pointers to bc_ops to get the btree keys for
leaf and node blocks, and to update parent keys of a block.
Convert the _btree_updkey calls to use our new pointer, and
modify the tree shape changing code to call the appropriate
get_*_keys pointer instead of _btree_copy_keys because the
overlapping btree has to calculate high key values.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc_btree.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 164 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.h | 19 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 8 |
5 files changed, 135 insertions, 64 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 5ba2dac5e67c..c60eeb826b9d 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c | |||
@@ -403,6 +403,10 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { | |||
403 | .keys_inorder = xfs_allocbt_keys_inorder, | 403 | .keys_inorder = xfs_allocbt_keys_inorder, |
404 | .recs_inorder = xfs_allocbt_recs_inorder, | 404 | .recs_inorder = xfs_allocbt_recs_inorder, |
405 | #endif | 405 | #endif |
406 | |||
407 | .get_leaf_keys = xfs_btree_get_leaf_keys, | ||
408 | .get_node_keys = xfs_btree_get_node_keys, | ||
409 | .update_keys = xfs_btree_update_keys, | ||
406 | }; | 410 | }; |
407 | 411 | ||
408 | /* | 412 | /* |
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 714b387e11ad..4f1a98e6fb54 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c | |||
@@ -757,6 +757,10 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { | |||
757 | .keys_inorder = xfs_bmbt_keys_inorder, | 757 | .keys_inorder = xfs_bmbt_keys_inorder, |
758 | .recs_inorder = xfs_bmbt_recs_inorder, | 758 | .recs_inorder = xfs_bmbt_recs_inorder, |
759 | #endif | 759 | #endif |
760 | |||
761 | .get_leaf_keys = xfs_btree_get_leaf_keys, | ||
762 | .get_node_keys = xfs_btree_get_node_keys, | ||
763 | .update_keys = xfs_btree_update_keys, | ||
760 | }; | 764 | }; |
761 | 765 | ||
762 | /* | 766 | /* |
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 8d8e3625c365..405442d8e780 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
@@ -1879,24 +1879,73 @@ error0: | |||
1879 | return error; | 1879 | return error; |
1880 | } | 1880 | } |
1881 | 1881 | ||
1882 | /* Determine the low key of a leaf block (simple) */ | ||
1883 | void | ||
1884 | xfs_btree_get_leaf_keys( | ||
1885 | struct xfs_btree_cur *cur, | ||
1886 | struct xfs_btree_block *block, | ||
1887 | union xfs_btree_key *key) | ||
1888 | { | ||
1889 | union xfs_btree_rec *rec; | ||
1890 | |||
1891 | rec = xfs_btree_rec_addr(cur, 1, block); | ||
1892 | cur->bc_ops->init_key_from_rec(key, rec); | ||
1893 | } | ||
1894 | |||
1895 | /* Determine the low key of a node block (simple) */ | ||
1896 | void | ||
1897 | xfs_btree_get_node_keys( | ||
1898 | struct xfs_btree_cur *cur, | ||
1899 | struct xfs_btree_block *block, | ||
1900 | union xfs_btree_key *key) | ||
1901 | { | ||
1902 | memcpy(key, xfs_btree_key_addr(cur, 1, block), cur->bc_ops->key_len); | ||
1903 | } | ||
1904 | |||
1905 | /* Derive the keys for any btree block. */ | ||
1906 | STATIC void | ||
1907 | xfs_btree_get_keys( | ||
1908 | struct xfs_btree_cur *cur, | ||
1909 | struct xfs_btree_block *block, | ||
1910 | union xfs_btree_key *key) | ||
1911 | { | ||
1912 | if (be16_to_cpu(block->bb_level) == 0) | ||
1913 | cur->bc_ops->get_leaf_keys(cur, block, key); | ||
1914 | else | ||
1915 | cur->bc_ops->get_node_keys(cur, block, key); | ||
1916 | } | ||
1917 | |||
1882 | /* | 1918 | /* |
1883 | * Update keys at all levels from here to the root along the cursor's path. | 1919 | * Decide if we need to update the parent keys of a btree block. For |
1920 | * a standard btree this is only necessary if we're updating the first | ||
1921 | * record/key. | ||
1884 | */ | 1922 | */ |
1885 | STATIC int | 1923 | static inline bool |
1886 | xfs_btree_updkey( | 1924 | xfs_btree_needs_key_update( |
1925 | struct xfs_btree_cur *cur, | ||
1926 | int ptr) | ||
1927 | { | ||
1928 | return ptr == 1; | ||
1929 | } | ||
1930 | |||
1931 | /* | ||
1932 | * Update the parent keys of the given level, progressing towards the root. | ||
1933 | */ | ||
1934 | int | ||
1935 | xfs_btree_update_keys( | ||
1887 | struct xfs_btree_cur *cur, | 1936 | struct xfs_btree_cur *cur, |
1888 | union xfs_btree_key *keyp, | ||
1889 | int level) | 1937 | int level) |
1890 | { | 1938 | { |
1891 | struct xfs_btree_block *block; | 1939 | struct xfs_btree_block *block; |
1892 | struct xfs_buf *bp; | 1940 | struct xfs_buf *bp; |
1893 | union xfs_btree_key *kp; | 1941 | union xfs_btree_key *kp; |
1942 | union xfs_btree_key key; | ||
1894 | int ptr; | 1943 | int ptr; |
1895 | 1944 | ||
1896 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); | 1945 | XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); |
1897 | XFS_BTREE_TRACE_ARGIK(cur, level, keyp); | 1946 | XFS_BTREE_TRACE_ARGIK(cur, level, keyp); |
1898 | 1947 | ||
1899 | ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1); | 1948 | ASSERT(level >= 0); |
1900 | 1949 | ||
1901 | /* | 1950 | /* |
1902 | * Go up the tree from this level toward the root. | 1951 | * Go up the tree from this level toward the root. |
@@ -1904,7 +1953,9 @@ xfs_btree_updkey( | |||
1904 | * Stop when we reach a level where the cursor isn't pointing | 1953 | * Stop when we reach a level where the cursor isn't pointing |
1905 | * at the first entry in the block. | 1954 | * at the first entry in the block. |
1906 | */ | 1955 | */ |
1907 | for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) { | 1956 | block = xfs_btree_get_block(cur, level, &bp); |
1957 | xfs_btree_get_keys(cur, block, &key); | ||
1958 | for (level++, ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) { | ||
1908 | #ifdef DEBUG | 1959 | #ifdef DEBUG |
1909 | int error; | 1960 | int error; |
1910 | #endif | 1961 | #endif |
@@ -1918,7 +1969,7 @@ xfs_btree_updkey( | |||
1918 | #endif | 1969 | #endif |
1919 | ptr = cur->bc_ptrs[level]; | 1970 | ptr = cur->bc_ptrs[level]; |
1920 | kp = xfs_btree_key_addr(cur, ptr, block); | 1971 | kp = xfs_btree_key_addr(cur, ptr, block); |
1921 | xfs_btree_copy_keys(cur, kp, keyp, 1); | 1972 | xfs_btree_copy_keys(cur, kp, &key, 1); |
1922 | xfs_btree_log_keys(cur, bp, ptr, ptr); | 1973 | xfs_btree_log_keys(cur, bp, ptr, ptr); |
1923 | } | 1974 | } |
1924 | 1975 | ||
@@ -1971,11 +2022,8 @@ xfs_btree_update( | |||
1971 | } | 2022 | } |
1972 | 2023 | ||
1973 | /* Updating first rec in leaf. Pass new key value up to our parent. */ | 2024 | /* Updating first rec in leaf. Pass new key value up to our parent. */ |
1974 | if (ptr == 1) { | 2025 | if (xfs_btree_needs_key_update(cur, ptr)) { |
1975 | union xfs_btree_key key; | 2026 | error = cur->bc_ops->update_keys(cur, 0); |
1976 | |||
1977 | cur->bc_ops->init_key_from_rec(&key, rec); | ||
1978 | error = xfs_btree_updkey(cur, &key, 1); | ||
1979 | if (error) | 2027 | if (error) |
1980 | goto error0; | 2028 | goto error0; |
1981 | } | 2029 | } |
@@ -2146,11 +2194,10 @@ xfs_btree_lshift( | |||
2146 | */ | 2194 | */ |
2147 | cur->bc_ops->init_key_from_rec(&key, | 2195 | cur->bc_ops->init_key_from_rec(&key, |
2148 | xfs_btree_rec_addr(cur, 1, right)); | 2196 | xfs_btree_rec_addr(cur, 1, right)); |
2149 | rkp = &key; | ||
2150 | } | 2197 | } |
2151 | 2198 | ||
2152 | /* Update the parent key values of right. */ | 2199 | /* Update the parent keys of the right block. */ |
2153 | error = xfs_btree_updkey(cur, rkp, level + 1); | 2200 | error = cur->bc_ops->update_keys(cur, level); |
2154 | if (error) | 2201 | if (error) |
2155 | goto error0; | 2202 | goto error0; |
2156 | 2203 | ||
@@ -2292,7 +2339,6 @@ xfs_btree_rshift( | |||
2292 | xfs_btree_log_recs(cur, rbp, 1, rrecs + 1); | 2339 | xfs_btree_log_recs(cur, rbp, 1, rrecs + 1); |
2293 | 2340 | ||
2294 | cur->bc_ops->init_key_from_rec(&key, rrp); | 2341 | cur->bc_ops->init_key_from_rec(&key, rrp); |
2295 | rkp = &key; | ||
2296 | 2342 | ||
2297 | ASSERT(cur->bc_ops->recs_inorder(cur, rrp, | 2343 | ASSERT(cur->bc_ops->recs_inorder(cur, rrp, |
2298 | xfs_btree_rec_addr(cur, 2, right))); | 2344 | xfs_btree_rec_addr(cur, 2, right))); |
@@ -2321,7 +2367,8 @@ xfs_btree_rshift( | |||
2321 | if (error) | 2367 | if (error) |
2322 | goto error1; | 2368 | goto error1; |
2323 | 2369 | ||
2324 | error = xfs_btree_updkey(tcur, rkp, level + 1); | 2370 | /* Update the parent keys of the right block. */ |
2371 | error = cur->bc_ops->update_keys(tcur, level); | ||
2325 | if (error) | 2372 | if (error) |
2326 | goto error1; | 2373 | goto error1; |
2327 | 2374 | ||
@@ -2422,6 +2469,11 @@ __xfs_btree_split( | |||
2422 | 2469 | ||
2423 | XFS_BTREE_STATS_ADD(cur, moves, rrecs); | 2470 | XFS_BTREE_STATS_ADD(cur, moves, rrecs); |
2424 | 2471 | ||
2472 | /* Adjust numrecs for the later get_*_keys() calls. */ | ||
2473 | lrecs -= rrecs; | ||
2474 | xfs_btree_set_numrecs(left, lrecs); | ||
2475 | xfs_btree_set_numrecs(right, xfs_btree_get_numrecs(right) + rrecs); | ||
2476 | |||
2425 | /* | 2477 | /* |
2426 | * Copy btree block entries from the left block over to the | 2478 | * Copy btree block entries from the left block over to the |
2427 | * new block, the right. Update the right block and log the | 2479 | * new block, the right. Update the right block and log the |
@@ -2447,14 +2499,15 @@ __xfs_btree_split( | |||
2447 | } | 2499 | } |
2448 | #endif | 2500 | #endif |
2449 | 2501 | ||
2502 | /* Copy the keys & pointers to the new block. */ | ||
2450 | xfs_btree_copy_keys(cur, rkp, lkp, rrecs); | 2503 | xfs_btree_copy_keys(cur, rkp, lkp, rrecs); |
2451 | xfs_btree_copy_ptrs(cur, rpp, lpp, rrecs); | 2504 | xfs_btree_copy_ptrs(cur, rpp, lpp, rrecs); |
2452 | 2505 | ||
2453 | xfs_btree_log_keys(cur, rbp, 1, rrecs); | 2506 | xfs_btree_log_keys(cur, rbp, 1, rrecs); |
2454 | xfs_btree_log_ptrs(cur, rbp, 1, rrecs); | 2507 | xfs_btree_log_ptrs(cur, rbp, 1, rrecs); |
2455 | 2508 | ||
2456 | /* Grab the keys to the entries moved to the right block */ | 2509 | /* Stash the keys of the new block for later insertion. */ |
2457 | xfs_btree_copy_keys(cur, key, rkp, 1); | 2510 | cur->bc_ops->get_node_keys(cur, right, key); |
2458 | } else { | 2511 | } else { |
2459 | /* It's a leaf. Move records. */ | 2512 | /* It's a leaf. Move records. */ |
2460 | union xfs_btree_rec *lrp; /* left record pointer */ | 2513 | union xfs_btree_rec *lrp; /* left record pointer */ |
@@ -2463,27 +2516,23 @@ __xfs_btree_split( | |||
2463 | lrp = xfs_btree_rec_addr(cur, src_index, left); | 2516 | lrp = xfs_btree_rec_addr(cur, src_index, left); |
2464 | rrp = xfs_btree_rec_addr(cur, 1, right); | 2517 | rrp = xfs_btree_rec_addr(cur, 1, right); |
2465 | 2518 | ||
2519 | /* Copy records to the new block. */ | ||
2466 | xfs_btree_copy_recs(cur, rrp, lrp, rrecs); | 2520 | xfs_btree_copy_recs(cur, rrp, lrp, rrecs); |
2467 | xfs_btree_log_recs(cur, rbp, 1, rrecs); | 2521 | xfs_btree_log_recs(cur, rbp, 1, rrecs); |
2468 | 2522 | ||
2469 | cur->bc_ops->init_key_from_rec(key, | 2523 | /* Stash the keys of the new block for later insertion. */ |
2470 | xfs_btree_rec_addr(cur, 1, right)); | 2524 | cur->bc_ops->get_leaf_keys(cur, right, key); |
2471 | } | 2525 | } |
2472 | 2526 | ||
2473 | |||
2474 | /* | 2527 | /* |
2475 | * Find the left block number by looking in the buffer. | 2528 | * Find the left block number by looking in the buffer. |
2476 | * Adjust numrecs, sibling pointers. | 2529 | * Adjust sibling pointers. |
2477 | */ | 2530 | */ |
2478 | xfs_btree_get_sibling(cur, left, &rrptr, XFS_BB_RIGHTSIB); | 2531 | xfs_btree_get_sibling(cur, left, &rrptr, XFS_BB_RIGHTSIB); |
2479 | xfs_btree_set_sibling(cur, right, &rrptr, XFS_BB_RIGHTSIB); | 2532 | xfs_btree_set_sibling(cur, right, &rrptr, XFS_BB_RIGHTSIB); |
2480 | xfs_btree_set_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); | 2533 | xfs_btree_set_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); |
2481 | xfs_btree_set_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB); | 2534 | xfs_btree_set_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB); |
2482 | 2535 | ||
2483 | lrecs -= rrecs; | ||
2484 | xfs_btree_set_numrecs(left, lrecs); | ||
2485 | xfs_btree_set_numrecs(right, xfs_btree_get_numrecs(right) + rrecs); | ||
2486 | |||
2487 | xfs_btree_log_block(cur, rbp, XFS_BB_ALL_BITS); | 2536 | xfs_btree_log_block(cur, rbp, XFS_BB_ALL_BITS); |
2488 | xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); | 2537 | xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); |
2489 | 2538 | ||
@@ -2802,6 +2851,7 @@ xfs_btree_new_root( | |||
2802 | bp = lbp; | 2851 | bp = lbp; |
2803 | nptr = 2; | 2852 | nptr = 2; |
2804 | } | 2853 | } |
2854 | |||
2805 | /* Fill in the new block's btree header and log it. */ | 2855 | /* Fill in the new block's btree header and log it. */ |
2806 | xfs_btree_init_block_cur(cur, nbp, cur->bc_nlevels, 2); | 2856 | xfs_btree_init_block_cur(cur, nbp, cur->bc_nlevels, 2); |
2807 | xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); | 2857 | xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); |
@@ -2810,19 +2860,24 @@ xfs_btree_new_root( | |||
2810 | 2860 | ||
2811 | /* Fill in the key data in the new root. */ | 2861 | /* Fill in the key data in the new root. */ |
2812 | if (xfs_btree_get_level(left) > 0) { | 2862 | if (xfs_btree_get_level(left) > 0) { |
2813 | xfs_btree_copy_keys(cur, | 2863 | /* |
2814 | xfs_btree_key_addr(cur, 1, new), | 2864 | * Get the keys for the left block's keys and put them directly |
2815 | xfs_btree_key_addr(cur, 1, left), 1); | 2865 | * in the parent block. Do the same for the right block. |
2816 | xfs_btree_copy_keys(cur, | 2866 | */ |
2817 | xfs_btree_key_addr(cur, 2, new), | 2867 | cur->bc_ops->get_node_keys(cur, left, |
2818 | xfs_btree_key_addr(cur, 1, right), 1); | 2868 | xfs_btree_key_addr(cur, 1, new)); |
2869 | cur->bc_ops->get_node_keys(cur, right, | ||
2870 | xfs_btree_key_addr(cur, 2, new)); | ||
2819 | } else { | 2871 | } else { |
2820 | cur->bc_ops->init_key_from_rec( | 2872 | /* |
2821 | xfs_btree_key_addr(cur, 1, new), | 2873 | * Get the keys for the left block's records and put them |
2822 | xfs_btree_rec_addr(cur, 1, left)); | 2874 | * directly in the parent block. Do the same for the right |
2823 | cur->bc_ops->init_key_from_rec( | 2875 | * block. |
2824 | xfs_btree_key_addr(cur, 2, new), | 2876 | */ |
2825 | xfs_btree_rec_addr(cur, 1, right)); | 2877 | cur->bc_ops->get_leaf_keys(cur, left, |
2878 | xfs_btree_key_addr(cur, 1, new)); | ||
2879 | cur->bc_ops->get_leaf_keys(cur, right, | ||
2880 | xfs_btree_key_addr(cur, 2, new)); | ||
2826 | } | 2881 | } |
2827 | xfs_btree_log_keys(cur, nbp, 1, 2); | 2882 | xfs_btree_log_keys(cur, nbp, 1, 2); |
2828 | 2883 | ||
@@ -2858,7 +2913,7 @@ xfs_btree_make_block_unfull( | |||
2858 | int *index, /* new tree index */ | 2913 | int *index, /* new tree index */ |
2859 | union xfs_btree_ptr *nptr, /* new btree ptr */ | 2914 | union xfs_btree_ptr *nptr, /* new btree ptr */ |
2860 | struct xfs_btree_cur **ncur, /* new btree cursor */ | 2915 | struct xfs_btree_cur **ncur, /* new btree cursor */ |
2861 | union xfs_btree_key *key, /* key of new block */ | 2916 | union xfs_btree_key *key, /* key of new block */ |
2862 | int *stat) | 2917 | int *stat) |
2863 | { | 2918 | { |
2864 | int error = 0; | 2919 | int error = 0; |
@@ -3086,8 +3141,8 @@ xfs_btree_insrec( | |||
3086 | xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); | 3141 | xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); |
3087 | 3142 | ||
3088 | /* If we inserted at the start of a block, update the parents' keys. */ | 3143 | /* If we inserted at the start of a block, update the parents' keys. */ |
3089 | if (optr == 1) { | 3144 | if (xfs_btree_needs_key_update(cur, optr)) { |
3090 | error = xfs_btree_updkey(cur, key, level + 1); | 3145 | error = cur->bc_ops->update_keys(cur, level); |
3091 | if (error) | 3146 | if (error) |
3092 | goto error0; | 3147 | goto error0; |
3093 | } | 3148 | } |
@@ -3107,7 +3162,7 @@ xfs_btree_insrec( | |||
3107 | */ | 3162 | */ |
3108 | *ptrp = nptr; | 3163 | *ptrp = nptr; |
3109 | if (!xfs_btree_ptr_is_null(cur, &nptr)) { | 3164 | if (!xfs_btree_ptr_is_null(cur, &nptr)) { |
3110 | *key = nkey; | 3165 | xfs_btree_copy_keys(cur, key, &nkey, 1); |
3111 | *curp = ncur; | 3166 | *curp = ncur; |
3112 | } | 3167 | } |
3113 | 3168 | ||
@@ -3386,8 +3441,6 @@ xfs_btree_delrec( | |||
3386 | struct xfs_buf *bp; /* buffer for block */ | 3441 | struct xfs_buf *bp; /* buffer for block */ |
3387 | int error; /* error return value */ | 3442 | int error; /* error return value */ |
3388 | int i; /* loop counter */ | 3443 | int i; /* loop counter */ |
3389 | union xfs_btree_key key; /* storage for keyp */ | ||
3390 | union xfs_btree_key *keyp = &key; /* passed to the next level */ | ||
3391 | union xfs_btree_ptr lptr; /* left sibling block ptr */ | 3444 | union xfs_btree_ptr lptr; /* left sibling block ptr */ |
3392 | struct xfs_buf *lbp; /* left buffer pointer */ | 3445 | struct xfs_buf *lbp; /* left buffer pointer */ |
3393 | struct xfs_btree_block *left; /* left btree block */ | 3446 | struct xfs_btree_block *left; /* left btree block */ |
@@ -3458,13 +3511,6 @@ xfs_btree_delrec( | |||
3458 | xfs_btree_log_keys(cur, bp, ptr, numrecs - 1); | 3511 | xfs_btree_log_keys(cur, bp, ptr, numrecs - 1); |
3459 | xfs_btree_log_ptrs(cur, bp, ptr, numrecs - 1); | 3512 | xfs_btree_log_ptrs(cur, bp, ptr, numrecs - 1); |
3460 | } | 3513 | } |
3461 | |||
3462 | /* | ||
3463 | * If it's the first record in the block, we'll need to pass a | ||
3464 | * key up to the next level (updkey). | ||
3465 | */ | ||
3466 | if (ptr == 1) | ||
3467 | keyp = xfs_btree_key_addr(cur, 1, block); | ||
3468 | } else { | 3514 | } else { |
3469 | /* It's a leaf. operate on records */ | 3515 | /* It's a leaf. operate on records */ |
3470 | if (ptr < numrecs) { | 3516 | if (ptr < numrecs) { |
@@ -3473,16 +3519,6 @@ xfs_btree_delrec( | |||
3473 | -1, numrecs - ptr); | 3519 | -1, numrecs - ptr); |
3474 | xfs_btree_log_recs(cur, bp, ptr, numrecs - 1); | 3520 | xfs_btree_log_recs(cur, bp, ptr, numrecs - 1); |
3475 | } | 3521 | } |
3476 | |||
3477 | /* | ||
3478 | * If it's the first record in the block, we'll need a key | ||
3479 | * structure to pass up to the next level (updkey). | ||
3480 | */ | ||
3481 | if (ptr == 1) { | ||
3482 | cur->bc_ops->init_key_from_rec(&key, | ||
3483 | xfs_btree_rec_addr(cur, 1, block)); | ||
3484 | keyp = &key; | ||
3485 | } | ||
3486 | } | 3522 | } |
3487 | 3523 | ||
3488 | /* | 3524 | /* |
@@ -3549,8 +3585,8 @@ xfs_btree_delrec( | |||
3549 | * If we deleted the leftmost entry in the block, update the | 3585 | * If we deleted the leftmost entry in the block, update the |
3550 | * key values above us in the tree. | 3586 | * key values above us in the tree. |
3551 | */ | 3587 | */ |
3552 | if (ptr == 1) { | 3588 | if (xfs_btree_needs_key_update(cur, ptr)) { |
3553 | error = xfs_btree_updkey(cur, keyp, level + 1); | 3589 | error = cur->bc_ops->update_keys(cur, level); |
3554 | if (error) | 3590 | if (error) |
3555 | goto error0; | 3591 | goto error0; |
3556 | } | 3592 | } |
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index b4f3035ae05e..e097e60400d8 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h | |||
@@ -180,6 +180,19 @@ struct xfs_btree_ops { | |||
180 | union xfs_btree_rec *r1, | 180 | union xfs_btree_rec *r1, |
181 | union xfs_btree_rec *r2); | 181 | union xfs_btree_rec *r2); |
182 | #endif | 182 | #endif |
183 | |||
184 | /* derive the low & high keys from the records in a leaf block */ | ||
185 | void (*get_leaf_keys)(struct xfs_btree_cur *cur, | ||
186 | struct xfs_btree_block *block, | ||
187 | union xfs_btree_key *key); | ||
188 | |||
189 | /* derive the low & high keys from the keys in a node block */ | ||
190 | void (*get_node_keys)(struct xfs_btree_cur *cur, | ||
191 | struct xfs_btree_block *block, | ||
192 | union xfs_btree_key *key); | ||
193 | |||
194 | /* update the parent keys of given btree level */ | ||
195 | int (*update_keys)(struct xfs_btree_cur *cur, int level); | ||
183 | }; | 196 | }; |
184 | 197 | ||
185 | /* | 198 | /* |
@@ -475,4 +488,10 @@ bool xfs_btree_sblock_verify(struct xfs_buf *bp, unsigned int max_recs); | |||
475 | uint xfs_btree_compute_maxlevels(struct xfs_mount *mp, uint *limits, | 488 | uint xfs_btree_compute_maxlevels(struct xfs_mount *mp, uint *limits, |
476 | unsigned long len); | 489 | unsigned long len); |
477 | 490 | ||
491 | void xfs_btree_get_leaf_keys(struct xfs_btree_cur *cur, | ||
492 | struct xfs_btree_block *block, union xfs_btree_key *key); | ||
493 | void xfs_btree_get_node_keys(struct xfs_btree_cur *cur, | ||
494 | struct xfs_btree_block *block, union xfs_btree_key *key); | ||
495 | int xfs_btree_update_keys(struct xfs_btree_cur *cur, int level); | ||
496 | |||
478 | #endif /* __XFS_BTREE_H__ */ | 497 | #endif /* __XFS_BTREE_H__ */ |
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 88da2ad939d4..a48f4482004c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -314,6 +314,10 @@ static const struct xfs_btree_ops xfs_inobt_ops = { | |||
314 | .keys_inorder = xfs_inobt_keys_inorder, | 314 | .keys_inorder = xfs_inobt_keys_inorder, |
315 | .recs_inorder = xfs_inobt_recs_inorder, | 315 | .recs_inorder = xfs_inobt_recs_inorder, |
316 | #endif | 316 | #endif |
317 | |||
318 | .get_leaf_keys = xfs_btree_get_leaf_keys, | ||
319 | .get_node_keys = xfs_btree_get_node_keys, | ||
320 | .update_keys = xfs_btree_update_keys, | ||
317 | }; | 321 | }; |
318 | 322 | ||
319 | static const struct xfs_btree_ops xfs_finobt_ops = { | 323 | static const struct xfs_btree_ops xfs_finobt_ops = { |
@@ -335,6 +339,10 @@ static const struct xfs_btree_ops xfs_finobt_ops = { | |||
335 | .keys_inorder = xfs_inobt_keys_inorder, | 339 | .keys_inorder = xfs_inobt_keys_inorder, |
336 | .recs_inorder = xfs_inobt_recs_inorder, | 340 | .recs_inorder = xfs_inobt_recs_inorder, |
337 | #endif | 341 | #endif |
342 | |||
343 | .get_leaf_keys = xfs_btree_get_leaf_keys, | ||
344 | .get_node_keys = xfs_btree_get_node_keys, | ||
345 | .update_keys = xfs_btree_update_keys, | ||
338 | }; | 346 | }; |
339 | 347 | ||
340 | /* | 348 | /* |