aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc_btree.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 01:57:16 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:57:16 -0400
commit344207ce8474b79be331eb93e6df4cb5bdd48ab2 (patch)
tree7858f63c359e2695a6c368a73b078ff183345922 /fs/xfs/xfs_ialloc_btree.c
parentf5eb8e7ca58bc1e92436614444006120d21668ba (diff)
[XFS] implement semi-generic xfs_btree_new_root
From: Dave Chinner <dgc@sgi.com> Add a xfs_btree_new_root helper for the alloc and ialloc btrees. The bmap btree needs it's own version and is not converted. [hch: split out from bigger patch and minor adaptions] SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32200a 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_ialloc_btree.c')
-rw-r--r--fs/xfs/xfs_ialloc_btree.c164
1 files changed, 16 insertions, 148 deletions
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index c76190a83e4e..7ba3c7bb3984 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -44,7 +44,6 @@ STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);
44STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); 44STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
45STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 45STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
46STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 46STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
47STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
48 47
49/* 48/*
50 * Single level of the xfs_inobt_delete record deletion routine. 49 * Single level of the xfs_inobt_delete record deletion routine.
@@ -556,7 +555,7 @@ xfs_inobt_insrec(
556 * and we're done. 555 * and we're done.
557 */ 556 */
558 if (level >= cur->bc_nlevels) { 557 if (level >= cur->bc_nlevels) {
559 error = xfs_inobt_newroot(cur, &i); 558 error = xfs_btree_new_root(cur, &i);
560 *bnop = NULLAGBLOCK; 559 *bnop = NULLAGBLOCK;
561 *stat = i; 560 *stat = i;
562 return error; 561 return error;
@@ -827,152 +826,6 @@ xfs_inobt_log_recs(
827 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 826 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
828} 827}
829 828
830/*
831 * Allocate a new root block, fill it in.
832 */
833STATIC int /* error */
834xfs_inobt_newroot(
835 xfs_btree_cur_t *cur, /* btree cursor */
836 int *stat) /* success/failure */
837{
838 xfs_agi_t *agi; /* a.g. inode header */
839 xfs_alloc_arg_t args; /* allocation argument structure */
840 xfs_inobt_block_t *block; /* one half of the old root block */
841 xfs_buf_t *bp; /* buffer containing block */
842 int error; /* error return value */
843 xfs_inobt_key_t *kp; /* btree key pointer */
844 xfs_agblock_t lbno; /* left block number */
845 xfs_buf_t *lbp; /* left buffer pointer */
846 xfs_inobt_block_t *left; /* left btree block */
847 xfs_buf_t *nbp; /* new (root) buffer */
848 xfs_inobt_block_t *new; /* new (root) btree block */
849 int nptr; /* new value for key index, 1 or 2 */
850 xfs_inobt_ptr_t *pp; /* btree address pointer */
851 xfs_agblock_t rbno; /* right block number */
852 xfs_buf_t *rbp; /* right buffer pointer */
853 xfs_inobt_block_t *right; /* right btree block */
854 xfs_inobt_rec_t *rp; /* btree record pointer */
855
856 ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp));
857
858 /*
859 * Get a block & a buffer.
860 */
861 agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
862 args.tp = cur->bc_tp;
863 args.mp = cur->bc_mp;
864 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno,
865 be32_to_cpu(agi->agi_root));
866 args.mod = args.minleft = args.alignment = args.total = args.wasdel =
867 args.isfl = args.userdata = args.minalignslop = 0;
868 args.minlen = args.maxlen = args.prod = 1;
869 args.type = XFS_ALLOCTYPE_NEAR_BNO;
870 if ((error = xfs_alloc_vextent(&args)))
871 return error;
872 /*
873 * None available, we fail.
874 */
875 if (args.fsbno == NULLFSBLOCK) {
876 *stat = 0;
877 return 0;
878 }
879 ASSERT(args.len == 1);
880 nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
881 new = XFS_BUF_TO_INOBT_BLOCK(nbp);
882 /*
883 * Set the root data in the a.g. inode structure.
884 */
885 agi->agi_root = cpu_to_be32(args.agbno);
886 be32_add_cpu(&agi->agi_level, 1);
887 xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp,
888 XFS_AGI_ROOT | XFS_AGI_LEVEL);
889 /*
890 * At the previous root level there are now two blocks: the old
891 * root, and the new block generated when it was split.
892 * We don't know which one the cursor is pointing at, so we
893 * set up variables "left" and "right" for each case.
894 */
895 bp = cur->bc_bufs[cur->bc_nlevels - 1];
896 block = XFS_BUF_TO_INOBT_BLOCK(bp);
897#ifdef DEBUG
898 if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
899 return error;
900#endif
901 if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
902 /*
903 * Our block is left, pick up the right block.
904 */
905 lbp = bp;
906 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
907 left = block;
908 rbno = be32_to_cpu(left->bb_rightsib);
909 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
910 rbno, 0, &rbp, XFS_INO_BTREE_REF)))
911 return error;
912 bp = rbp;
913 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
914 if ((error = xfs_btree_check_sblock(cur, right,
915 cur->bc_nlevels - 1, rbp)))
916 return error;
917 nptr = 1;
918 } else {
919 /*
920 * Our block is right, pick up the left block.
921 */
922 rbp = bp;
923 rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
924 right = block;
925 lbno = be32_to_cpu(right->bb_leftsib);
926 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
927 lbno, 0, &lbp, XFS_INO_BTREE_REF)))
928 return error;
929 bp = lbp;
930 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
931 if ((error = xfs_btree_check_sblock(cur, left,
932 cur->bc_nlevels - 1, lbp)))
933 return error;
934 nptr = 2;
935 }
936 /*
937 * Fill in the new block's btree header and log it.
938 */
939 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
940 new->bb_level = cpu_to_be16(cur->bc_nlevels);
941 new->bb_numrecs = cpu_to_be16(2);
942 new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
943 new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
944 xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
945 ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
946 /*
947 * Fill in the key data in the new root.
948 */
949 kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
950 if (be16_to_cpu(left->bb_level) > 0) {
951 kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
952 kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
953 } else {
954 rp = XFS_INOBT_REC_ADDR(left, 1, cur);
955 kp[0].ir_startino = rp->ir_startino;
956 rp = XFS_INOBT_REC_ADDR(right, 1, cur);
957 kp[1].ir_startino = rp->ir_startino;
958 }
959 xfs_inobt_log_keys(cur, nbp, 1, 2);
960 /*
961 * Fill in the pointer data in the new root.
962 */
963 pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
964 pp[0] = cpu_to_be32(lbno);
965 pp[1] = cpu_to_be32(rbno);
966 xfs_inobt_log_ptrs(cur, nbp, 1, 2);
967 /*
968 * Fix up the cursor.
969 */
970 xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
971 cur->bc_ptrs[cur->bc_nlevels] = nptr;
972 cur->bc_nlevels++;
973 *stat = 1;
974 return 0;
975}
976 829
977/* 830/*
978 * Externally visible routines. 831 * Externally visible routines.
@@ -1128,6 +981,20 @@ xfs_inobt_dup_cursor(
1128 cur->bc_private.a.agbp, cur->bc_private.a.agno); 981 cur->bc_private.a.agbp, cur->bc_private.a.agno);
1129} 982}
1130 983
984STATIC void
985xfs_inobt_set_root(
986 struct xfs_btree_cur *cur,
987 union xfs_btree_ptr *nptr,
988 int inc) /* level change */
989{
990 struct xfs_buf *agbp = cur->bc_private.a.agbp;
991 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
992
993 agi->agi_root = nptr->s;
994 be32_add_cpu(&agi->agi_level, inc);
995 xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL);
996}
997
1131STATIC int 998STATIC int
1132xfs_inobt_alloc_block( 999xfs_inobt_alloc_block(
1133 struct xfs_btree_cur *cur, 1000 struct xfs_btree_cur *cur,
@@ -1281,6 +1148,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
1281 .key_len = sizeof(xfs_inobt_key_t), 1148 .key_len = sizeof(xfs_inobt_key_t),
1282 1149
1283 .dup_cursor = xfs_inobt_dup_cursor, 1150 .dup_cursor = xfs_inobt_dup_cursor,
1151 .set_root = xfs_inobt_set_root,
1284 .alloc_block = xfs_inobt_alloc_block, 1152 .alloc_block = xfs_inobt_alloc_block,
1285 .get_maxrecs = xfs_inobt_get_maxrecs, 1153 .get_maxrecs = xfs_inobt_get_maxrecs,
1286 .init_key_from_rec = xfs_inobt_init_key_from_rec, 1154 .init_key_from_rec = xfs_inobt_init_key_from_rec,