diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 01:56:53 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 01:56:53 -0400 |
commit | 687b890a184fef263ebb773926e1f4aa69240d01 (patch) | |
tree | b8f80c134ff994927225367d148ee63f4d76506b /fs/xfs/xfs_bmap_btree.c | |
parent | 9eaead51bed957af0070a277d945744a76df0c8b (diff) |
[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>
Diffstat (limited to 'fs/xfs/xfs_bmap_btree.c')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 138 |
1 files changed, 2 insertions, 136 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 9d18fa8aa1da..809bd6ee177e 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -52,7 +52,6 @@ | |||
52 | STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *); | 52 | STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *); |
53 | STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); | 53 | STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); |
54 | STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); | 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 | STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, | 55 | STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, |
57 | __uint64_t *, xfs_btree_cur_t **, int *); | 56 | __uint64_t *, xfs_btree_cur_t **, int *); |
58 | 57 | ||
@@ -270,7 +269,7 @@ xfs_bmbt_delrec( | |||
270 | bno = be64_to_cpu(right->bb_leftsib); | 269 | bno = be64_to_cpu(right->bb_leftsib); |
271 | if (be16_to_cpu(right->bb_numrecs) - 1 >= | 270 | if (be16_to_cpu(right->bb_numrecs) - 1 >= |
272 | XFS_BMAP_BLOCK_IMINRECS(level, cur)) { | 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 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 273 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
275 | goto error0; | 274 | goto error0; |
276 | } | 275 | } |
@@ -544,7 +543,7 @@ xfs_bmbt_insrec( | |||
544 | if (i) { | 543 | if (i) { |
545 | /* nothing */ | 544 | /* nothing */ |
546 | } else { | 545 | } else { |
547 | if ((error = xfs_bmbt_lshift(cur, level, &i))) { | 546 | if ((error = xfs_btree_lshift(cur, level, &i))) { |
548 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 547 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
549 | return error; | 548 | return error; |
550 | } | 549 | } |
@@ -811,139 +810,6 @@ xfs_bmbt_log_ptrs( | |||
811 | } | 810 | } |
812 | 811 | ||
813 | /* | 812 | /* |
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 | } | ||
945 | |||
946 | /* | ||
947 | * Determine the extent state. | 813 | * Determine the extent state. |
948 | */ | 814 | */ |
949 | /* ARGSUSED */ | 815 | /* ARGSUSED */ |