Commit 687b890a184fef263ebb773926e1f4aa69240d01

Authored by Christoph Hellwig
Committed by Lachlan McIlroy
1 parent 9eaead51be

[XFS] implement generic xfs_btree_lshift

Make the btree left shift code generic. Based on a patch from David
Chinner with lots of changes to follow the original btree implementations
more closely. While this loses some of the generic helper routines for
inserting/moving/removing records it also solves some of the one off bugs
in the original code and makes it easier to verify.

SGI-PV: 985583

SGI-Modid: xfs-linux-melb:xfs-kern:32197a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Bill O'Donnell <billodo@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>

Showing 5 changed files with 192 additions and 425 deletions Side-by-side Diff

fs/xfs/xfs_alloc_btree.c
... ... @@ -47,7 +47,6 @@
47 47 STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
48 48 STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
49 49 STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
50   -STATIC int xfs_alloc_lshift(xfs_btree_cur_t *, int, int *);
51 50 STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *);
52 51 STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
53 52 xfs_alloc_key_t *, xfs_btree_cur_t **, int *);
... ... @@ -326,7 +325,7 @@
326 325 */
327 326 if (be16_to_cpu(right->bb_numrecs) - 1 >=
328 327 XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
329   - if ((error = xfs_alloc_lshift(tcur, level, &i)))
  328 + if ((error = xfs_btree_lshift(tcur, level, &i)))
330 329 goto error0;
331 330 if (i) {
332 331 ASSERT(be16_to_cpu(block->bb_numrecs) >=
... ... @@ -691,7 +690,7 @@
691 690 * Next, try shifting an entry to the left neighbor.
692 691 */
693 692 else {
694   - if ((error = xfs_alloc_lshift(cur, level, &i)))
  693 + if ((error = xfs_btree_lshift(cur, level, &i)))
695 694 return error;
696 695 if (i)
697 696 optr = ptr = cur->bc_ptrs[level];
... ... @@ -933,147 +932,6 @@
933 932 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
934 933 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
935 934 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
936   -}
937   -
938   -/*
939   - * Move 1 record left from cur/level if possible.
940   - * Update cur to reflect the new path.
941   - */
942   -STATIC int /* error */
943   -xfs_alloc_lshift(
944   - xfs_btree_cur_t *cur, /* btree cursor */
945   - int level, /* level to shift record on */
946   - int *stat) /* success/failure */
947   -{
948   - int error; /* error return value */
949   -#ifdef DEBUG
950   - int i; /* loop index */
951   -#endif
952   - xfs_alloc_key_t key; /* key value for leaf level upward */
953   - xfs_buf_t *lbp; /* buffer for left neighbor block */
954   - xfs_alloc_block_t *left; /* left neighbor btree block */
955   - int nrec; /* new number of left block entries */
956   - xfs_buf_t *rbp; /* buffer for right (current) block */
957   - xfs_alloc_block_t *right; /* right (current) btree block */
958   - xfs_alloc_key_t *rkp=NULL; /* key pointer for right block */
959   - xfs_alloc_ptr_t *rpp=NULL; /* address pointer for right block */
960   - xfs_alloc_rec_t *rrp=NULL; /* record pointer for right block */
961   -
962   - /*
963   - * Set up variables for this block as "right".
964   - */
965   - rbp = cur->bc_bufs[level];
966   - right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
967   -#ifdef DEBUG
968   - if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
969   - return error;
970   -#endif
971   - /*
972   - * If we've got no left sibling then we can't shift an entry left.
973   - */
974   - if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
975   - *stat = 0;
976   - return 0;
977   - }
978   - /*
979   - * If the cursor entry is the one that would be moved, don't
980   - * do it... it's too complicated.
981   - */
982   - if (cur->bc_ptrs[level] <= 1) {
983   - *stat = 0;
984   - return 0;
985   - }
986   - /*
987   - * Set up the left neighbor as "left".
988   - */
989   - if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
990   - cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
991   - 0, &lbp, XFS_ALLOC_BTREE_REF)))
992   - return error;
993   - left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
994   - if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
995   - return error;
996   - /*
997   - * If it's full, it can't take another entry.
998   - */
999   - if (be16_to_cpu(left->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
1000   - *stat = 0;
1001   - return 0;
1002   - }
1003   - nrec = be16_to_cpu(left->bb_numrecs) + 1;
1004   - /*
1005   - * If non-leaf, copy a key and a ptr to the left block.
1006   - */
1007   - if (level > 0) {
1008   - xfs_alloc_key_t *lkp; /* key pointer for left block */
1009   - xfs_alloc_ptr_t *lpp; /* address pointer for left block */
1010   -
1011   - lkp = XFS_ALLOC_KEY_ADDR(left, nrec, cur);
1012   - rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
1013   - *lkp = *rkp;
1014   - xfs_alloc_log_keys(cur, lbp, nrec, nrec);
1015   - lpp = XFS_ALLOC_PTR_ADDR(left, nrec, cur);
1016   - rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
1017   -#ifdef DEBUG
1018   - if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
1019   - return error;
1020   -#endif
1021   - *lpp = *rpp;
1022   - xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
1023   - xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
1024   - }
1025   - /*
1026   - * If leaf, copy a record to the left block.
1027   - */
1028   - else {
1029   - xfs_alloc_rec_t *lrp; /* record pointer for left block */
1030   -
1031   - lrp = XFS_ALLOC_REC_ADDR(left, nrec, cur);
1032   - rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
1033   - *lrp = *rrp;
1034   - xfs_alloc_log_recs(cur, lbp, nrec, nrec);
1035   - xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
1036   - }
1037   - /*
1038   - * Bump and log left's numrecs, decrement and log right's numrecs.
1039   - */
1040   - be16_add_cpu(&left->bb_numrecs, 1);
1041   - xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
1042   - be16_add_cpu(&right->bb_numrecs, -1);
1043   - xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
1044   - /*
1045   - * Slide the contents of right down one entry.
1046   - */
1047   - if (level > 0) {
1048   -#ifdef DEBUG
1049   - for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1050   - if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
1051   - level)))
1052   - return error;
1053   - }
1054   -#endif
1055   - memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1056   - memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1057   - xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1058   - xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1059   - } else {
1060   - memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1061   - xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1062   - key.ar_startblock = rrp->ar_startblock;
1063   - key.ar_blockcount = rrp->ar_blockcount;
1064   - rkp = &key;
1065   - }
1066   - /*
1067   - * Update the parent key values of right.
1068   - */
1069   - if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
1070   - return error;
1071   - /*
1072   - * Slide the cursor value left one.
1073   - */
1074   - cur->bc_ptrs[level]--;
1075   - *stat = 1;
1076   - return 0;
1077 935 }
1078 936  
1079 937 /*
fs/xfs/xfs_bmap_btree.c
... ... @@ -52,7 +52,6 @@
52 52 STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *);
53 53 STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
54 54 STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
55   -STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
56 55 STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
57 56 __uint64_t *, xfs_btree_cur_t **, int *);
58 57  
... ... @@ -270,7 +269,7 @@
270 269 bno = be64_to_cpu(right->bb_leftsib);
271 270 if (be16_to_cpu(right->bb_numrecs) - 1 >=
272 271 XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
273   - if ((error = xfs_bmbt_lshift(tcur, level, &i))) {
  272 + if ((error = xfs_btree_lshift(tcur, level, &i))) {
274 273 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
275 274 goto error0;
276 275 }
... ... @@ -544,7 +543,7 @@
544 543 if (i) {
545 544 /* nothing */
546 545 } else {
547   - if ((error = xfs_bmbt_lshift(cur, level, &i))) {
  546 + if ((error = xfs_btree_lshift(cur, level, &i))) {
548 547 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
549 548 return error;
550 549 }
... ... @@ -808,139 +807,6 @@
808 807 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
809 808 }
810 809 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
811   -}
812   -
813   -/*
814   - * Move 1 record left from cur/level if possible.
815   - * Update cur to reflect the new path.
816   - */
817   -STATIC int /* error */
818   -xfs_bmbt_lshift(
819   - xfs_btree_cur_t *cur,
820   - int level,
821   - int *stat) /* success/failure */
822   -{
823   - int error; /* error return value */
824   -#ifdef DEBUG
825   - int i; /* loop counter */
826   -#endif
827   - xfs_bmbt_key_t key; /* bmap btree key */
828   - xfs_buf_t *lbp; /* left buffer pointer */
829   - xfs_bmbt_block_t *left; /* left btree block */
830   - xfs_bmbt_key_t *lkp=NULL; /* left btree key */
831   - xfs_bmbt_ptr_t *lpp; /* left address pointer */
832   - int lrecs; /* left record count */
833   - xfs_bmbt_rec_t *lrp=NULL; /* left record pointer */
834   - xfs_mount_t *mp; /* file system mount point */
835   - xfs_buf_t *rbp; /* right buffer pointer */
836   - xfs_bmbt_block_t *right; /* right btree block */
837   - xfs_bmbt_key_t *rkp=NULL; /* right btree key */
838   - xfs_bmbt_ptr_t *rpp=NULL; /* right address pointer */
839   - xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
840   - int rrecs; /* right record count */
841   -
842   - XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
843   - XFS_BMBT_TRACE_ARGI(cur, level);
844   - if (level == cur->bc_nlevels - 1) {
845   - XFS_BMBT_TRACE_CURSOR(cur, EXIT);
846   - *stat = 0;
847   - return 0;
848   - }
849   - rbp = cur->bc_bufs[level];
850   - right = XFS_BUF_TO_BMBT_BLOCK(rbp);
851   -#ifdef DEBUG
852   - if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
853   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
854   - return error;
855   - }
856   -#endif
857   - if (be64_to_cpu(right->bb_leftsib) == NULLDFSBNO) {
858   - XFS_BMBT_TRACE_CURSOR(cur, EXIT);
859   - *stat = 0;
860   - return 0;
861   - }
862   - if (cur->bc_ptrs[level] <= 1) {
863   - XFS_BMBT_TRACE_CURSOR(cur, EXIT);
864   - *stat = 0;
865   - return 0;
866   - }
867   - mp = cur->bc_mp;
868   - if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(right->bb_leftsib), 0,
869   - &lbp, XFS_BMAP_BTREE_REF))) {
870   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
871   - return error;
872   - }
873   - left = XFS_BUF_TO_BMBT_BLOCK(lbp);
874   - if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
875   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
876   - return error;
877   - }
878   - if (be16_to_cpu(left->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
879   - XFS_BMBT_TRACE_CURSOR(cur, EXIT);
880   - *stat = 0;
881   - return 0;
882   - }
883   - lrecs = be16_to_cpu(left->bb_numrecs) + 1;
884   - if (level > 0) {
885   - lkp = XFS_BMAP_KEY_IADDR(left, lrecs, cur);
886   - rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
887   - *lkp = *rkp;
888   - xfs_bmbt_log_keys(cur, lbp, lrecs, lrecs);
889   - lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
890   - rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
891   -#ifdef DEBUG
892   - if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
893   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
894   - return error;
895   - }
896   -#endif
897   - *lpp = *rpp;
898   - xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
899   - } else {
900   - lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
901   - rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
902   - *lrp = *rrp;
903   - xfs_bmbt_log_recs(cur, lbp, lrecs, lrecs);
904   - }
905   - left->bb_numrecs = cpu_to_be16(lrecs);
906   - xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
907   -#ifdef DEBUG
908   - if (level > 0)
909   - xfs_btree_check_key(XFS_BTNUM_BMAP, lkp - 1, lkp);
910   - else
911   - xfs_btree_check_rec(XFS_BTNUM_BMAP, lrp - 1, lrp);
912   -#endif
913   - rrecs = be16_to_cpu(right->bb_numrecs) - 1;
914   - right->bb_numrecs = cpu_to_be16(rrecs);
915   - xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
916   - if (level > 0) {
917   -#ifdef DEBUG
918   - for (i = 0; i < rrecs; i++) {
919   - if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
920   - level))) {
921   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
922   - return error;
923   - }
924   - }
925   -#endif
926   - memmove(rkp, rkp + 1, rrecs * sizeof(*rkp));
927   - memmove(rpp, rpp + 1, rrecs * sizeof(*rpp));
928   - xfs_bmbt_log_keys(cur, rbp, 1, rrecs);
929   - xfs_bmbt_log_ptrs(cur, rbp, 1, rrecs);
930   - } else {
931   - memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
932   - xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
933   - key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
934   - rkp = &key;
935   - }
936   - if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1))) {
937   - XFS_BMBT_TRACE_CURSOR(cur, ERROR);
938   - return error;
939   - }
940   - cur->bc_ptrs[level]--;
941   - XFS_BMBT_TRACE_CURSOR(cur, EXIT);
942   - *stat = 1;
943   - return 0;
944 810 }
945 811  
946 812 /*
... ... @@ -1841,6 +1841,191 @@
1841 1841 }
1842 1842  
1843 1843 /*
  1844 + * Move 1 record left from cur/level if possible.
  1845 + * Update cur to reflect the new path.
  1846 + */
  1847 +int /* error */
  1848 +xfs_btree_lshift(
  1849 + struct xfs_btree_cur *cur,
  1850 + int level,
  1851 + int *stat) /* success/failure */
  1852 +{
  1853 + union xfs_btree_key key; /* btree key */
  1854 + struct xfs_buf *lbp; /* left buffer pointer */
  1855 + struct xfs_btree_block *left; /* left btree block */
  1856 + int lrecs; /* left record count */
  1857 + struct xfs_buf *rbp; /* right buffer pointer */
  1858 + struct xfs_btree_block *right; /* right btree block */
  1859 + int rrecs; /* right record count */
  1860 + union xfs_btree_ptr lptr; /* left btree pointer */
  1861 + union xfs_btree_key *rkp = NULL; /* right btree key */
  1862 + union xfs_btree_ptr *rpp = NULL; /* right address pointer */
  1863 + union xfs_btree_rec *rrp = NULL; /* right record pointer */
  1864 + int error; /* error return value */
  1865 +
  1866 + XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
  1867 + XFS_BTREE_TRACE_ARGI(cur, level);
  1868 +
  1869 + if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
  1870 + level == cur->bc_nlevels - 1)
  1871 + goto out0;
  1872 +
  1873 + /* Set up variables for this block as "right". */
  1874 + right = xfs_btree_get_block(cur, level, &rbp);
  1875 +
  1876 +#ifdef DEBUG
  1877 + error = xfs_btree_check_block(cur, right, level, rbp);
  1878 + if (error)
  1879 + goto error0;
  1880 +#endif
  1881 +
  1882 + /* If we've got no left sibling then we can't shift an entry left. */
  1883 + xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
  1884 + if (xfs_btree_ptr_is_null(cur, &lptr))
  1885 + goto out0;
  1886 +
  1887 + /*
  1888 + * If the cursor entry is the one that would be moved, don't
  1889 + * do it... it's too complicated.
  1890 + */
  1891 + if (cur->bc_ptrs[level] <= 1)
  1892 + goto out0;
  1893 +
  1894 + /* Set up the left neighbor as "left". */
  1895 + error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp);
  1896 + if (error)
  1897 + goto error0;
  1898 +
  1899 + /* If it's full, it can't take another entry. */
  1900 + lrecs = xfs_btree_get_numrecs(left);
  1901 + if (lrecs == cur->bc_ops->get_maxrecs(cur, level))
  1902 + goto out0;
  1903 +
  1904 + rrecs = xfs_btree_get_numrecs(right);
  1905 +
  1906 + /*
  1907 + * We add one entry to the left side and remove one for the right side.
  1908 + * Accout for it here, the changes will be updated on disk and logged
  1909 + * later.
  1910 + */
  1911 + lrecs++;
  1912 + rrecs--;
  1913 +
  1914 + XFS_BTREE_STATS_INC(cur, lshift);
  1915 + XFS_BTREE_STATS_ADD(cur, moves, 1);
  1916 +
  1917 + /*
  1918 + * If non-leaf, copy a key and a ptr to the left block.
  1919 + * Log the changes to the left block.
  1920 + */
  1921 + if (level > 0) {
  1922 + /* It's a non-leaf. Move keys and pointers. */
  1923 + union xfs_btree_key *lkp; /* left btree key */
  1924 + union xfs_btree_ptr *lpp; /* left address pointer */
  1925 +
  1926 + lkp = xfs_btree_key_addr(cur, lrecs, left);
  1927 + rkp = xfs_btree_key_addr(cur, 1, right);
  1928 +
  1929 + lpp = xfs_btree_ptr_addr(cur, lrecs, left);
  1930 + rpp = xfs_btree_ptr_addr(cur, 1, right);
  1931 +#ifdef DEBUG
  1932 + error = xfs_btree_check_ptr(cur, rpp, 0, level);
  1933 + if (error)
  1934 + goto error0;
  1935 +#endif
  1936 + xfs_btree_copy_keys(cur, lkp, rkp, 1);
  1937 + xfs_btree_copy_ptrs(cur, lpp, rpp, 1);
  1938 +
  1939 + xfs_btree_log_keys(cur, lbp, lrecs, lrecs);
  1940 + xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs);
  1941 +
  1942 + xfs_btree_check_key(cur->bc_btnum,
  1943 + xfs_btree_key_addr(cur, lrecs - 1, left),
  1944 + lkp);
  1945 + } else {
  1946 + /* It's a leaf. Move records. */
  1947 + union xfs_btree_rec *lrp; /* left record pointer */
  1948 +
  1949 + lrp = xfs_btree_rec_addr(cur, lrecs, left);
  1950 + rrp = xfs_btree_rec_addr(cur, 1, right);
  1951 +
  1952 + xfs_btree_copy_recs(cur, lrp, rrp, 1);
  1953 + xfs_btree_log_recs(cur, lbp, lrecs, lrecs);
  1954 +
  1955 + xfs_btree_check_rec(cur->bc_btnum,
  1956 + xfs_btree_rec_addr(cur, lrecs - 1, left),
  1957 + lrp);
  1958 + }
  1959 +
  1960 + xfs_btree_set_numrecs(left, lrecs);
  1961 + xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
  1962 +
  1963 + xfs_btree_set_numrecs(right, rrecs);
  1964 + xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
  1965 +
  1966 + /*
  1967 + * Slide the contents of right down one entry.
  1968 + */
  1969 + XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1);
  1970 + if (level > 0) {
  1971 + /* It's a nonleaf. operate on keys and ptrs */
  1972 +#ifdef DEBUG
  1973 + int i; /* loop index */
  1974 +
  1975 + for (i = 0; i < rrecs; i++) {
  1976 + error = xfs_btree_check_ptr(cur, rpp, i + 1, level);
  1977 + if (error)
  1978 + goto error0;
  1979 + }
  1980 +#endif
  1981 + xfs_btree_shift_keys(cur,
  1982 + xfs_btree_key_addr(cur, 2, right),
  1983 + -1, rrecs);
  1984 + xfs_btree_shift_ptrs(cur,
  1985 + xfs_btree_ptr_addr(cur, 2, right),
  1986 + -1, rrecs);
  1987 +
  1988 + xfs_btree_log_keys(cur, rbp, 1, rrecs);
  1989 + xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
  1990 + } else {
  1991 + /* It's a leaf. operate on records */
  1992 + xfs_btree_shift_recs(cur,
  1993 + xfs_btree_rec_addr(cur, 2, right),
  1994 + -1, rrecs);
  1995 + xfs_btree_log_recs(cur, rbp, 1, rrecs);
  1996 +
  1997 + /*
  1998 + * If it's the first record in the block, we'll need a key
  1999 + * structure to pass up to the next level (updkey).
  2000 + */
  2001 + cur->bc_ops->init_key_from_rec(&key,
  2002 + xfs_btree_rec_addr(cur, 1, right));
  2003 + rkp = &key;
  2004 + }
  2005 +
  2006 + /* Update the parent key values of right. */
  2007 + error = xfs_btree_updkey(cur, rkp, level + 1);
  2008 + if (error)
  2009 + goto error0;
  2010 +
  2011 + /* Slide the cursor value left one. */
  2012 + cur->bc_ptrs[level]--;
  2013 +
  2014 + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
  2015 + *stat = 1;
  2016 + return 0;
  2017 +
  2018 +out0:
  2019 + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
  2020 + *stat = 0;
  2021 + return 0;
  2022 +
  2023 +error0:
  2024 + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
  2025 + return error;
  2026 +}
  2027 +
  2028 +/*
1844 2029 * Move 1 record right from cur/level if possible.
1845 2030 * Update cur to reflect the new path.
1846 2031 */
... ... @@ -533,6 +533,7 @@
533 533 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
534 534 int xfs_btree_updkey(struct xfs_btree_cur *, union xfs_btree_key *, int);
535 535 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
  536 +int xfs_btree_lshift(struct xfs_btree_cur *, int, int *);
536 537 int xfs_btree_rshift(struct xfs_btree_cur *, int, int *);
537 538  
538 539 /*
fs/xfs/xfs_ialloc_btree.c
... ... @@ -43,7 +43,6 @@
43 43 STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
44 44 STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
45 45 STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
46   -STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *);
47 46 STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
48 47 STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
49 48 xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
... ... @@ -276,7 +275,7 @@
276 275 */
277 276 if (be16_to_cpu(right->bb_numrecs) - 1 >=
278 277 XFS_INOBT_BLOCK_MINRECS(level, cur)) {
279   - if ((error = xfs_inobt_lshift(tcur, level, &i)))
  278 + if ((error = xfs_btree_lshift(tcur, level, &i)))
280 279 goto error0;
281 280 if (i) {
282 281 ASSERT(be16_to_cpu(block->bb_numrecs) >=
... ... @@ -616,7 +615,7 @@
616 615 * Next, try shifting an entry to the left neighbor.
617 616 */
618 617 else {
619   - if ((error = xfs_inobt_lshift(cur, level, &i)))
  618 + if ((error = xfs_btree_lshift(cur, level, &i)))
620 619 return error;
621 620 if (i) {
622 621 optr = ptr = cur->bc_ptrs[level];
... ... @@ -824,148 +823,6 @@
824 823 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
825 824 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
826 825 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
827   -}
828   -
829   -/*
830   - * Move 1 record left from cur/level if possible.
831   - * Update cur to reflect the new path.
832   - */
833   -STATIC int /* error */
834   -xfs_inobt_lshift(
835   - xfs_btree_cur_t *cur, /* btree cursor */
836   - int level, /* level to shift record on */
837   - int *stat) /* success/failure */
838   -{
839   - int error; /* error return value */
840   -#ifdef DEBUG
841   - int i; /* loop index */
842   -#endif
843   - xfs_inobt_key_t key; /* key value for leaf level upward */
844   - xfs_buf_t *lbp; /* buffer for left neighbor block */
845   - xfs_inobt_block_t *left; /* left neighbor btree block */
846   - xfs_inobt_key_t *lkp=NULL; /* key pointer for left block */
847   - xfs_inobt_ptr_t *lpp; /* address pointer for left block */
848   - xfs_inobt_rec_t *lrp=NULL; /* record pointer for left block */
849   - int nrec; /* new number of left block entries */
850   - xfs_buf_t *rbp; /* buffer for right (current) block */
851   - xfs_inobt_block_t *right; /* right (current) btree block */
852   - xfs_inobt_key_t *rkp=NULL; /* key pointer for right block */
853   - xfs_inobt_ptr_t *rpp=NULL; /* address pointer for right block */
854   - xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
855   -
856   - /*
857   - * Set up variables for this block as "right".
858   - */
859   - rbp = cur->bc_bufs[level];
860   - right = XFS_BUF_TO_INOBT_BLOCK(rbp);
861   -#ifdef DEBUG
862   - if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
863   - return error;
864   -#endif
865   - /*
866   - * If we've got no left sibling then we can't shift an entry left.
867   - */
868   - if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
869   - *stat = 0;
870   - return 0;
871   - }
872   - /*
873   - * If the cursor entry is the one that would be moved, don't
874   - * do it... it's too complicated.
875   - */
876   - if (cur->bc_ptrs[level] <= 1) {
877   - *stat = 0;
878   - return 0;
879   - }
880   - /*
881   - * Set up the left neighbor as "left".
882   - */
883   - if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
884   - cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
885   - 0, &lbp, XFS_INO_BTREE_REF)))
886   - return error;
887   - left = XFS_BUF_TO_INOBT_BLOCK(lbp);
888   - if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
889   - return error;
890   - /*
891   - * If it's full, it can't take another entry.
892   - */
893   - if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
894   - *stat = 0;
895   - return 0;
896   - }
897   - nrec = be16_to_cpu(left->bb_numrecs) + 1;
898   - /*
899   - * If non-leaf, copy a key and a ptr to the left block.
900   - */
901   - if (level > 0) {
902   - lkp = XFS_INOBT_KEY_ADDR(left, nrec, cur);
903   - rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
904   - *lkp = *rkp;
905   - xfs_inobt_log_keys(cur, lbp, nrec, nrec);
906   - lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
907   - rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
908   -#ifdef DEBUG
909   - if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
910   - return error;
911   -#endif
912   - *lpp = *rpp;
913   - xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
914   - }
915   - /*
916   - * If leaf, copy a record to the left block.
917   - */
918   - else {
919   - lrp = XFS_INOBT_REC_ADDR(left, nrec, cur);
920   - rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
921   - *lrp = *rrp;
922   - xfs_inobt_log_recs(cur, lbp, nrec, nrec);
923   - }
924   - /*
925   - * Bump and log left's numrecs, decrement and log right's numrecs.
926   - */
927   - be16_add_cpu(&left->bb_numrecs, 1);
928   - xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
929   -#ifdef DEBUG
930   - if (level > 0)
931   - xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
932   - else
933   - xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
934   -#endif
935   - be16_add_cpu(&right->bb_numrecs, -1);
936   - xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
937   - /*
938   - * Slide the contents of right down one entry.
939   - */
940   - if (level > 0) {
941   -#ifdef DEBUG
942   - for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
943   - if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
944   - level)))
945   - return error;
946   - }
947   -#endif
948   - memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
949   - memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
950   - xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
951   - xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
952   - } else {
953   - memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
954   - xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
955   - key.ir_startino = rrp->ir_startino;
956   - rkp = &key;
957   - }
958   - /*
959   - * Update the parent key values of right.
960   - */
961   - if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
962   - return error;
963   - /*
964   - * Slide the cursor value left one.
965   - */
966   - cur->bc_ptrs[level]--;
967   - *stat = 1;
968   - return 0;
969 826 }
970 827  
971 828 /*