diff options
-rw-r--r-- | fs/xfs/xfs_alloc.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 45 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc_btree.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 59 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_btree.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.c | 107 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.h | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_ialloc_btree.c | 41 | ||||
-rw-r--r-- | fs/xfs/xfs_ialloc_btree.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_itable.c | 6 |
12 files changed, 196 insertions, 158 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 1956f83489f1..69833eb1de4f 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -640,8 +640,8 @@ xfs_alloc_ag_vextent_exact( | |||
640 | /* | 640 | /* |
641 | * Allocate/initialize a cursor for the by-number freespace btree. | 641 | * Allocate/initialize a cursor for the by-number freespace btree. |
642 | */ | 642 | */ |
643 | bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 643 | bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
644 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 644 | args->agno, XFS_BTNUM_BNO); |
645 | /* | 645 | /* |
646 | * Lookup bno and minlen in the btree (minlen is irrelevant, really). | 646 | * Lookup bno and minlen in the btree (minlen is irrelevant, really). |
647 | * Look for the closest free block <= bno, it must contain bno | 647 | * Look for the closest free block <= bno, it must contain bno |
@@ -696,8 +696,8 @@ xfs_alloc_ag_vextent_exact( | |||
696 | * We are allocating agbno for rlen [agbno .. end] | 696 | * We are allocating agbno for rlen [agbno .. end] |
697 | * Allocate/initialize a cursor for the by-size btree. | 697 | * Allocate/initialize a cursor for the by-size btree. |
698 | */ | 698 | */ |
699 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 699 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
700 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 700 | args->agno, XFS_BTNUM_CNT); |
701 | ASSERT(args->agbno + args->len <= | 701 | ASSERT(args->agbno + args->len <= |
702 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); | 702 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); |
703 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, | 703 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, |
@@ -759,8 +759,8 @@ xfs_alloc_ag_vextent_near( | |||
759 | /* | 759 | /* |
760 | * Get a cursor for the by-size btree. | 760 | * Get a cursor for the by-size btree. |
761 | */ | 761 | */ |
762 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 762 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
763 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 763 | args->agno, XFS_BTNUM_CNT); |
764 | ltlen = 0; | 764 | ltlen = 0; |
765 | bno_cur_lt = bno_cur_gt = NULL; | 765 | bno_cur_lt = bno_cur_gt = NULL; |
766 | /* | 766 | /* |
@@ -886,8 +886,8 @@ xfs_alloc_ag_vextent_near( | |||
886 | /* | 886 | /* |
887 | * Set up a cursor for the by-bno tree. | 887 | * Set up a cursor for the by-bno tree. |
888 | */ | 888 | */ |
889 | bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, | 889 | bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, |
890 | args->agbp, args->agno, XFS_BTNUM_BNO, NULL, 0); | 890 | args->agbp, args->agno, XFS_BTNUM_BNO); |
891 | /* | 891 | /* |
892 | * Fix up the btree entries. | 892 | * Fix up the btree entries. |
893 | */ | 893 | */ |
@@ -914,8 +914,8 @@ xfs_alloc_ag_vextent_near( | |||
914 | /* | 914 | /* |
915 | * Allocate and initialize the cursor for the leftward search. | 915 | * Allocate and initialize the cursor for the leftward search. |
916 | */ | 916 | */ |
917 | bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 917 | bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
918 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 918 | args->agno, XFS_BTNUM_BNO); |
919 | /* | 919 | /* |
920 | * Lookup <= bno to find the leftward search's starting point. | 920 | * Lookup <= bno to find the leftward search's starting point. |
921 | */ | 921 | */ |
@@ -1267,8 +1267,8 @@ xfs_alloc_ag_vextent_size( | |||
1267 | /* | 1267 | /* |
1268 | * Allocate and initialize a cursor for the by-size btree. | 1268 | * Allocate and initialize a cursor for the by-size btree. |
1269 | */ | 1269 | */ |
1270 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 1270 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
1271 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 1271 | args->agno, XFS_BTNUM_CNT); |
1272 | bno_cur = NULL; | 1272 | bno_cur = NULL; |
1273 | /* | 1273 | /* |
1274 | * Look for an entry >= maxlen+alignment-1 blocks. | 1274 | * Look for an entry >= maxlen+alignment-1 blocks. |
@@ -1372,8 +1372,8 @@ xfs_alloc_ag_vextent_size( | |||
1372 | /* | 1372 | /* |
1373 | * Allocate and initialize a cursor for the by-block tree. | 1373 | * Allocate and initialize a cursor for the by-block tree. |
1374 | */ | 1374 | */ |
1375 | bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 1375 | bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
1376 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 1376 | args->agno, XFS_BTNUM_BNO); |
1377 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, | 1377 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, |
1378 | rbno, rlen, XFSA_FIXUP_CNT_OK))) | 1378 | rbno, rlen, XFSA_FIXUP_CNT_OK))) |
1379 | goto error0; | 1379 | goto error0; |
@@ -1515,8 +1515,7 @@ xfs_free_ag_extent( | |||
1515 | /* | 1515 | /* |
1516 | * Allocate and initialize a cursor for the by-block btree. | 1516 | * Allocate and initialize a cursor for the by-block btree. |
1517 | */ | 1517 | */ |
1518 | bno_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO, NULL, | 1518 | bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); |
1519 | 0); | ||
1520 | cnt_cur = NULL; | 1519 | cnt_cur = NULL; |
1521 | /* | 1520 | /* |
1522 | * Look for a neighboring block on the left (lower block numbers) | 1521 | * Look for a neighboring block on the left (lower block numbers) |
@@ -1575,8 +1574,7 @@ xfs_free_ag_extent( | |||
1575 | /* | 1574 | /* |
1576 | * Now allocate and initialize a cursor for the by-size tree. | 1575 | * Now allocate and initialize a cursor for the by-size tree. |
1577 | */ | 1576 | */ |
1578 | cnt_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT, NULL, | 1577 | cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT); |
1579 | 0); | ||
1580 | /* | 1578 | /* |
1581 | * Have both left and right contiguous neighbors. | 1579 | * Have both left and right contiguous neighbors. |
1582 | * Merge all three into a single free block. | 1580 | * Merge all three into a single free block. |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 3ce2645508ae..60c121f1e81b 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -2209,3 +2209,48 @@ xfs_alloc_update( | |||
2209 | } | 2209 | } |
2210 | return 0; | 2210 | return 0; |
2211 | } | 2211 | } |
2212 | |||
2213 | STATIC struct xfs_btree_cur * | ||
2214 | xfs_allocbt_dup_cursor( | ||
2215 | struct xfs_btree_cur *cur) | ||
2216 | { | ||
2217 | return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp, | ||
2218 | cur->bc_private.a.agbp, cur->bc_private.a.agno, | ||
2219 | cur->bc_btnum); | ||
2220 | } | ||
2221 | |||
2222 | static const struct xfs_btree_ops xfs_allocbt_ops = { | ||
2223 | .dup_cursor = xfs_allocbt_dup_cursor, | ||
2224 | }; | ||
2225 | |||
2226 | /* | ||
2227 | * Allocate a new allocation btree cursor. | ||
2228 | */ | ||
2229 | struct xfs_btree_cur * /* new alloc btree cursor */ | ||
2230 | xfs_allocbt_init_cursor( | ||
2231 | struct xfs_mount *mp, /* file system mount point */ | ||
2232 | struct xfs_trans *tp, /* transaction pointer */ | ||
2233 | struct xfs_buf *agbp, /* buffer for agf structure */ | ||
2234 | xfs_agnumber_t agno, /* allocation group number */ | ||
2235 | xfs_btnum_t btnum) /* btree identifier */ | ||
2236 | { | ||
2237 | struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); | ||
2238 | struct xfs_btree_cur *cur; | ||
2239 | |||
2240 | ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); | ||
2241 | |||
2242 | cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); | ||
2243 | |||
2244 | cur->bc_tp = tp; | ||
2245 | cur->bc_mp = mp; | ||
2246 | cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]); | ||
2247 | cur->bc_btnum = btnum; | ||
2248 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | ||
2249 | |||
2250 | cur->bc_ops = &xfs_allocbt_ops; | ||
2251 | |||
2252 | cur->bc_private.a.agbp = agbp; | ||
2253 | cur->bc_private.a.agno = agno; | ||
2254 | |||
2255 | return cur; | ||
2256 | } | ||
diff --git a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h index 5bd1a2c8bd07..60735384a4ce 100644 --- a/fs/xfs/xfs_alloc_btree.h +++ b/fs/xfs/xfs_alloc_btree.h | |||
@@ -152,4 +152,9 @@ extern int xfs_alloc_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, | |||
152 | extern int xfs_alloc_update(struct xfs_btree_cur *cur, xfs_agblock_t bno, | 152 | extern int xfs_alloc_update(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
153 | xfs_extlen_t len); | 153 | xfs_extlen_t len); |
154 | 154 | ||
155 | |||
156 | extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *, | ||
157 | struct xfs_trans *, struct xfs_buf *, | ||
158 | xfs_agnumber_t, xfs_btnum_t); | ||
159 | |||
155 | #endif /* __XFS_ALLOC_BTREE_H__ */ | 160 | #endif /* __XFS_ALLOC_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index a1aab9275d5a..a84d0c30b485 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -422,8 +422,7 @@ xfs_bmap_add_attrfork_btree( | |||
422 | if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) | 422 | if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) |
423 | *flags |= XFS_ILOG_DBROOT; | 423 | *flags |= XFS_ILOG_DBROOT; |
424 | else { | 424 | else { |
425 | cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, | 425 | cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); |
426 | XFS_DATA_FORK); | ||
427 | cur->bc_private.b.flist = flist; | 426 | cur->bc_private.b.flist = flist; |
428 | cur->bc_private.b.firstblock = *firstblock; | 427 | cur->bc_private.b.firstblock = *firstblock; |
429 | if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) | 428 | if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) |
@@ -3441,8 +3440,7 @@ xfs_bmap_extents_to_btree( | |||
3441 | * Need a cursor. Can't allocate until bb_level is filled in. | 3440 | * Need a cursor. Can't allocate until bb_level is filled in. |
3442 | */ | 3441 | */ |
3443 | mp = ip->i_mount; | 3442 | mp = ip->i_mount; |
3444 | cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, | 3443 | cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); |
3445 | whichfork); | ||
3446 | cur->bc_private.b.firstblock = *firstblock; | 3444 | cur->bc_private.b.firstblock = *firstblock; |
3447 | cur->bc_private.b.flist = flist; | 3445 | cur->bc_private.b.flist = flist; |
3448 | cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; | 3446 | cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; |
@@ -5029,8 +5027,7 @@ xfs_bmapi( | |||
5029 | if (abno == NULLFSBLOCK) | 5027 | if (abno == NULLFSBLOCK) |
5030 | break; | 5028 | break; |
5031 | if ((ifp->if_flags & XFS_IFBROOT) && !cur) { | 5029 | if ((ifp->if_flags & XFS_IFBROOT) && !cur) { |
5032 | cur = xfs_btree_init_cursor(mp, | 5030 | cur = xfs_bmbt_init_cursor(mp, tp, |
5033 | tp, NULL, 0, XFS_BTNUM_BMAP, | ||
5034 | ip, whichfork); | 5031 | ip, whichfork); |
5035 | cur->bc_private.b.firstblock = | 5032 | cur->bc_private.b.firstblock = |
5036 | *firstblock; | 5033 | *firstblock; |
@@ -5147,9 +5144,8 @@ xfs_bmapi( | |||
5147 | */ | 5144 | */ |
5148 | ASSERT(mval->br_blockcount <= len); | 5145 | ASSERT(mval->br_blockcount <= len); |
5149 | if ((ifp->if_flags & XFS_IFBROOT) && !cur) { | 5146 | if ((ifp->if_flags & XFS_IFBROOT) && !cur) { |
5150 | cur = xfs_btree_init_cursor(mp, | 5147 | cur = xfs_bmbt_init_cursor(mp, |
5151 | tp, NULL, 0, XFS_BTNUM_BMAP, | 5148 | tp, ip, whichfork); |
5152 | ip, whichfork); | ||
5153 | cur->bc_private.b.firstblock = | 5149 | cur->bc_private.b.firstblock = |
5154 | *firstblock; | 5150 | *firstblock; |
5155 | cur->bc_private.b.flist = flist; | 5151 | cur->bc_private.b.flist = flist; |
@@ -5440,8 +5436,7 @@ xfs_bunmapi( | |||
5440 | logflags = 0; | 5436 | logflags = 0; |
5441 | if (ifp->if_flags & XFS_IFBROOT) { | 5437 | if (ifp->if_flags & XFS_IFBROOT) { |
5442 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); | 5438 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); |
5443 | cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, | 5439 | cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); |
5444 | whichfork); | ||
5445 | cur->bc_private.b.firstblock = *firstblock; | 5440 | cur->bc_private.b.firstblock = *firstblock; |
5446 | cur->bc_private.b.flist = flist; | 5441 | cur->bc_private.b.flist = flist; |
5447 | cur->bc_private.b.flags = 0; | 5442 | cur->bc_private.b.flags = 0; |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 23efad29a5cd..cfbdd00045cf 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -2608,3 +2608,62 @@ xfs_check_nostate_extents( | |||
2608 | } | 2608 | } |
2609 | return 0; | 2609 | return 0; |
2610 | } | 2610 | } |
2611 | |||
2612 | |||
2613 | STATIC struct xfs_btree_cur * | ||
2614 | xfs_bmbt_dup_cursor( | ||
2615 | struct xfs_btree_cur *cur) | ||
2616 | { | ||
2617 | struct xfs_btree_cur *new; | ||
2618 | |||
2619 | new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp, | ||
2620 | cur->bc_private.b.ip, cur->bc_private.b.whichfork); | ||
2621 | |||
2622 | /* | ||
2623 | * Copy the firstblock, flist, and flags values, | ||
2624 | * since init cursor doesn't get them. | ||
2625 | */ | ||
2626 | new->bc_private.b.firstblock = cur->bc_private.b.firstblock; | ||
2627 | new->bc_private.b.flist = cur->bc_private.b.flist; | ||
2628 | new->bc_private.b.flags = cur->bc_private.b.flags; | ||
2629 | |||
2630 | return new; | ||
2631 | } | ||
2632 | |||
2633 | static const struct xfs_btree_ops xfs_bmbt_ops = { | ||
2634 | .dup_cursor = xfs_bmbt_dup_cursor, | ||
2635 | }; | ||
2636 | |||
2637 | /* | ||
2638 | * Allocate a new bmap btree cursor. | ||
2639 | */ | ||
2640 | struct xfs_btree_cur * /* new bmap btree cursor */ | ||
2641 | xfs_bmbt_init_cursor( | ||
2642 | struct xfs_mount *mp, /* file system mount point */ | ||
2643 | struct xfs_trans *tp, /* transaction pointer */ | ||
2644 | struct xfs_inode *ip, /* inode owning the btree */ | ||
2645 | int whichfork) /* data or attr fork */ | ||
2646 | { | ||
2647 | struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); | ||
2648 | struct xfs_btree_cur *cur; | ||
2649 | |||
2650 | cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); | ||
2651 | |||
2652 | cur->bc_tp = tp; | ||
2653 | cur->bc_mp = mp; | ||
2654 | cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; | ||
2655 | cur->bc_btnum = XFS_BTNUM_BMAP; | ||
2656 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | ||
2657 | |||
2658 | cur->bc_ops = &xfs_bmbt_ops; | ||
2659 | |||
2660 | cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); | ||
2661 | cur->bc_private.b.ip = ip; | ||
2662 | cur->bc_private.b.firstblock = NULLFSBLOCK; | ||
2663 | cur->bc_private.b.flist = NULL; | ||
2664 | cur->bc_private.b.allocated = 0; | ||
2665 | cur->bc_private.b.flags = 0; | ||
2666 | cur->bc_private.b.whichfork = whichfork; | ||
2667 | |||
2668 | return cur; | ||
2669 | } | ||
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index cd0d4b4bb816..4f12fff54975 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h | |||
@@ -24,6 +24,7 @@ struct xfs_btree_cur; | |||
24 | struct xfs_btree_lblock; | 24 | struct xfs_btree_lblock; |
25 | struct xfs_mount; | 25 | struct xfs_mount; |
26 | struct xfs_inode; | 26 | struct xfs_inode; |
27 | struct xfs_trans; | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * Bmap root header, on-disk form only. | 30 | * Bmap root header, on-disk form only. |
@@ -300,6 +301,9 @@ extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); | |||
300 | extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, | 301 | extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, |
301 | xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t); | 302 | xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t); |
302 | 303 | ||
304 | extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, | ||
305 | struct xfs_trans *, struct xfs_inode *, int); | ||
306 | |||
303 | #endif /* __KERNEL__ */ | 307 | #endif /* __KERNEL__ */ |
304 | 308 | ||
305 | #endif /* __XFS_BMAP_BTREE_H__ */ | 309 | #endif /* __XFS_BMAP_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 31002093bfb7..074f7f6aa27c 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -387,16 +387,17 @@ xfs_btree_dup_cursor( | |||
387 | 387 | ||
388 | tp = cur->bc_tp; | 388 | tp = cur->bc_tp; |
389 | mp = cur->bc_mp; | 389 | mp = cur->bc_mp; |
390 | |||
390 | /* | 391 | /* |
391 | * Allocate a new cursor like the old one. | 392 | * Allocate a new cursor like the old one. |
392 | */ | 393 | */ |
393 | new = xfs_btree_init_cursor(mp, tp, cur->bc_private.a.agbp, | 394 | new = cur->bc_ops->dup_cursor(cur); |
394 | cur->bc_private.a.agno, cur->bc_btnum, cur->bc_private.b.ip, | 395 | |
395 | cur->bc_private.b.whichfork); | ||
396 | /* | 396 | /* |
397 | * Copy the record currently in the cursor. | 397 | * Copy the record currently in the cursor. |
398 | */ | 398 | */ |
399 | new->bc_rec = cur->bc_rec; | 399 | new->bc_rec = cur->bc_rec; |
400 | |||
400 | /* | 401 | /* |
401 | * For each level current, re-get the buffer and copy the ptr value. | 402 | * For each level current, re-get the buffer and copy the ptr value. |
402 | */ | 403 | */ |
@@ -416,15 +417,6 @@ xfs_btree_dup_cursor( | |||
416 | } else | 417 | } else |
417 | new->bc_bufs[i] = NULL; | 418 | new->bc_bufs[i] = NULL; |
418 | } | 419 | } |
419 | /* | ||
420 | * For bmap btrees, copy the firstblock, flist, and flags values, | ||
421 | * since init cursor doesn't get them. | ||
422 | */ | ||
423 | if (new->bc_btnum == XFS_BTNUM_BMAP) { | ||
424 | new->bc_private.b.firstblock = cur->bc_private.b.firstblock; | ||
425 | new->bc_private.b.flist = cur->bc_private.b.flist; | ||
426 | new->bc_private.b.flags = cur->bc_private.b.flags; | ||
427 | } | ||
428 | *ncur = new; | 420 | *ncur = new; |
429 | return 0; | 421 | return 0; |
430 | } | 422 | } |
@@ -505,97 +497,6 @@ xfs_btree_get_bufs( | |||
505 | } | 497 | } |
506 | 498 | ||
507 | /* | 499 | /* |
508 | * Allocate a new btree cursor. | ||
509 | * The cursor is either for allocation (A) or bmap (B) or inodes (I). | ||
510 | */ | ||
511 | xfs_btree_cur_t * /* new btree cursor */ | ||
512 | xfs_btree_init_cursor( | ||
513 | xfs_mount_t *mp, /* file system mount point */ | ||
514 | xfs_trans_t *tp, /* transaction pointer */ | ||
515 | xfs_buf_t *agbp, /* (A only) buffer for agf structure */ | ||
516 | /* (I only) buffer for agi structure */ | ||
517 | xfs_agnumber_t agno, /* (AI only) allocation group number */ | ||
518 | xfs_btnum_t btnum, /* btree identifier */ | ||
519 | xfs_inode_t *ip, /* (B only) inode owning the btree */ | ||
520 | int whichfork) /* (B only) data or attr fork */ | ||
521 | { | ||
522 | xfs_agf_t *agf; /* (A) allocation group freespace */ | ||
523 | xfs_agi_t *agi; /* (I) allocation group inodespace */ | ||
524 | xfs_btree_cur_t *cur; /* return value */ | ||
525 | xfs_ifork_t *ifp; /* (I) inode fork pointer */ | ||
526 | int nlevels=0; /* number of levels in the btree */ | ||
527 | |||
528 | ASSERT(xfs_btree_cur_zone != NULL); | ||
529 | /* | ||
530 | * Allocate a new cursor. | ||
531 | */ | ||
532 | cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); | ||
533 | /* | ||
534 | * Deduce the number of btree levels from the arguments. | ||
535 | */ | ||
536 | switch (btnum) { | ||
537 | case XFS_BTNUM_BNO: | ||
538 | case XFS_BTNUM_CNT: | ||
539 | agf = XFS_BUF_TO_AGF(agbp); | ||
540 | nlevels = be32_to_cpu(agf->agf_levels[btnum]); | ||
541 | break; | ||
542 | case XFS_BTNUM_BMAP: | ||
543 | ifp = XFS_IFORK_PTR(ip, whichfork); | ||
544 | nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; | ||
545 | break; | ||
546 | case XFS_BTNUM_INO: | ||
547 | agi = XFS_BUF_TO_AGI(agbp); | ||
548 | nlevels = be32_to_cpu(agi->agi_level); | ||
549 | break; | ||
550 | default: | ||
551 | ASSERT(0); | ||
552 | } | ||
553 | /* | ||
554 | * Fill in the common fields. | ||
555 | */ | ||
556 | cur->bc_tp = tp; | ||
557 | cur->bc_mp = mp; | ||
558 | cur->bc_nlevels = nlevels; | ||
559 | cur->bc_btnum = btnum; | ||
560 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | ||
561 | /* | ||
562 | * Fill in private fields. | ||
563 | */ | ||
564 | switch (btnum) { | ||
565 | case XFS_BTNUM_BNO: | ||
566 | case XFS_BTNUM_CNT: | ||
567 | /* | ||
568 | * Allocation btree fields. | ||
569 | */ | ||
570 | cur->bc_private.a.agbp = agbp; | ||
571 | cur->bc_private.a.agno = agno; | ||
572 | break; | ||
573 | case XFS_BTNUM_INO: | ||
574 | /* | ||
575 | * Inode allocation btree fields. | ||
576 | */ | ||
577 | cur->bc_private.a.agbp = agbp; | ||
578 | cur->bc_private.a.agno = agno; | ||
579 | break; | ||
580 | case XFS_BTNUM_BMAP: | ||
581 | /* | ||
582 | * Bmap btree fields. | ||
583 | */ | ||
584 | cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); | ||
585 | cur->bc_private.b.ip = ip; | ||
586 | cur->bc_private.b.firstblock = NULLFSBLOCK; | ||
587 | cur->bc_private.b.flist = NULL; | ||
588 | cur->bc_private.b.allocated = 0; | ||
589 | cur->bc_private.b.flags = 0; | ||
590 | cur->bc_private.b.whichfork = whichfork; | ||
591 | break; | ||
592 | default: | ||
593 | ASSERT(0); | ||
594 | } | ||
595 | return cur; | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * Check for the cursor referring to the last block at the given level. | 500 | * Check for the cursor referring to the last block at the given level. |
600 | */ | 501 | */ |
601 | int /* 1=is last block, 0=not last block */ | 502 | int /* 1=is last block, 0=not last block */ |
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 332b9f1da203..d30ee7498606 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h | |||
@@ -131,6 +131,11 @@ extern const __uint32_t xfs_magics[]; | |||
131 | 131 | ||
132 | #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ | 132 | #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ |
133 | 133 | ||
134 | struct xfs_btree_ops { | ||
135 | /* cursor operations */ | ||
136 | struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); | ||
137 | }; | ||
138 | |||
134 | /* | 139 | /* |
135 | * Btree cursor structure. | 140 | * Btree cursor structure. |
136 | * This collects all information needed by the btree code in one place. | 141 | * This collects all information needed by the btree code in one place. |
@@ -139,6 +144,7 @@ typedef struct xfs_btree_cur | |||
139 | { | 144 | { |
140 | struct xfs_trans *bc_tp; /* transaction we're in, if any */ | 145 | struct xfs_trans *bc_tp; /* transaction we're in, if any */ |
141 | struct xfs_mount *bc_mp; /* file system mount struct */ | 146 | struct xfs_mount *bc_mp; /* file system mount struct */ |
147 | const struct xfs_btree_ops *bc_ops; | ||
142 | union { | 148 | union { |
143 | xfs_alloc_rec_incore_t a; | 149 | xfs_alloc_rec_incore_t a; |
144 | xfs_bmbt_irec_t b; | 150 | xfs_bmbt_irec_t b; |
@@ -308,20 +314,6 @@ xfs_btree_get_bufs( | |||
308 | uint lock); /* lock flags for get_buf */ | 314 | uint lock); /* lock flags for get_buf */ |
309 | 315 | ||
310 | /* | 316 | /* |
311 | * Allocate a new btree cursor. | ||
312 | * The cursor is either for allocation (A) or bmap (B). | ||
313 | */ | ||
314 | xfs_btree_cur_t * /* new btree cursor */ | ||
315 | xfs_btree_init_cursor( | ||
316 | struct xfs_mount *mp, /* file system mount point */ | ||
317 | struct xfs_trans *tp, /* transaction pointer */ | ||
318 | struct xfs_buf *agbp, /* (A only) buffer for agf structure */ | ||
319 | xfs_agnumber_t agno, /* (A only) allocation group number */ | ||
320 | xfs_btnum_t btnum, /* btree identifier */ | ||
321 | struct xfs_inode *ip, /* (B only) inode owning the btree */ | ||
322 | int whichfork); /* (B only) data/attr fork */ | ||
323 | |||
324 | /* | ||
325 | * Check for the cursor referring to the last block at the given level. | 317 | * Check for the cursor referring to the last block at the given level. |
326 | */ | 318 | */ |
327 | int /* 1=is last block, 0=not last block */ | 319 | int /* 1=is last block, 0=not last block */ |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index aad8c5da38af..11bb169561ce 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -335,8 +335,7 @@ xfs_ialloc_ag_alloc( | |||
335 | /* | 335 | /* |
336 | * Insert records describing the new inode chunk into the btree. | 336 | * Insert records describing the new inode chunk into the btree. |
337 | */ | 337 | */ |
338 | cur = xfs_btree_init_cursor(args.mp, tp, agbp, agno, | 338 | cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno); |
339 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); | ||
340 | for (thisino = newino; | 339 | for (thisino = newino; |
341 | thisino < newino + newlen; | 340 | thisino < newino + newlen; |
342 | thisino += XFS_INODES_PER_CHUNK) { | 341 | thisino += XFS_INODES_PER_CHUNK) { |
@@ -676,8 +675,7 @@ nextag: | |||
676 | */ | 675 | */ |
677 | agno = tagno; | 676 | agno = tagno; |
678 | *IO_agbp = NULL; | 677 | *IO_agbp = NULL; |
679 | cur = xfs_btree_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno), | 678 | cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); |
680 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); | ||
681 | /* | 679 | /* |
682 | * If pagino is 0 (this is the root inode allocation) use newino. | 680 | * If pagino is 0 (this is the root inode allocation) use newino. |
683 | * This must work because we've just allocated some. | 681 | * This must work because we've just allocated some. |
@@ -1022,8 +1020,7 @@ xfs_difree( | |||
1022 | /* | 1020 | /* |
1023 | * Initialize the cursor. | 1021 | * Initialize the cursor. |
1024 | */ | 1022 | */ |
1025 | cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO, | 1023 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
1026 | (xfs_inode_t *)0, 0); | ||
1027 | #ifdef DEBUG | 1024 | #ifdef DEBUG |
1028 | if (cur->bc_nlevels == 1) { | 1025 | if (cur->bc_nlevels == 1) { |
1029 | int freecount = 0; | 1026 | int freecount = 0; |
@@ -1259,8 +1256,7 @@ xfs_dilocate( | |||
1259 | #endif /* DEBUG */ | 1256 | #endif /* DEBUG */ |
1260 | return error; | 1257 | return error; |
1261 | } | 1258 | } |
1262 | cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO, | 1259 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
1263 | (xfs_inode_t *)0, 0); | ||
1264 | if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) { | 1260 | if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) { |
1265 | #ifdef DEBUG | 1261 | #ifdef DEBUG |
1266 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " | 1262 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " |
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 83502f3edef0..8c0c4748a8df 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -2076,3 +2076,44 @@ xfs_inobt_update( | |||
2076 | } | 2076 | } |
2077 | return 0; | 2077 | return 0; |
2078 | } | 2078 | } |
2079 | |||
2080 | STATIC struct xfs_btree_cur * | ||
2081 | xfs_inobt_dup_cursor( | ||
2082 | struct xfs_btree_cur *cur) | ||
2083 | { | ||
2084 | return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, | ||
2085 | cur->bc_private.a.agbp, cur->bc_private.a.agno); | ||
2086 | } | ||
2087 | |||
2088 | static const struct xfs_btree_ops xfs_inobt_ops = { | ||
2089 | .dup_cursor = xfs_inobt_dup_cursor, | ||
2090 | }; | ||
2091 | |||
2092 | /* | ||
2093 | * Allocate a new inode btree cursor. | ||
2094 | */ | ||
2095 | struct xfs_btree_cur * /* new inode btree cursor */ | ||
2096 | xfs_inobt_init_cursor( | ||
2097 | struct xfs_mount *mp, /* file system mount point */ | ||
2098 | struct xfs_trans *tp, /* transaction pointer */ | ||
2099 | struct xfs_buf *agbp, /* buffer for agi structure */ | ||
2100 | xfs_agnumber_t agno) /* allocation group number */ | ||
2101 | { | ||
2102 | struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); | ||
2103 | struct xfs_btree_cur *cur; | ||
2104 | |||
2105 | cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); | ||
2106 | |||
2107 | cur->bc_tp = tp; | ||
2108 | cur->bc_mp = mp; | ||
2109 | cur->bc_nlevels = be32_to_cpu(agi->agi_level); | ||
2110 | cur->bc_btnum = XFS_BTNUM_INO; | ||
2111 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | ||
2112 | |||
2113 | cur->bc_ops = &xfs_inobt_ops; | ||
2114 | |||
2115 | cur->bc_private.a.agbp = agbp; | ||
2116 | cur->bc_private.a.agno = agno; | ||
2117 | |||
2118 | return cur; | ||
2119 | } | ||
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index 8efc4a5b8b92..eea409349eba 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h | |||
@@ -175,4 +175,8 @@ extern int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino, | |||
175 | extern int xfs_inobt_update(struct xfs_btree_cur *cur, xfs_agino_t ino, | 175 | extern int xfs_inobt_update(struct xfs_btree_cur *cur, xfs_agino_t ino, |
176 | __int32_t fcnt, xfs_inofree_t free); | 176 | __int32_t fcnt, xfs_inofree_t free); |
177 | 177 | ||
178 | |||
179 | extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, | ||
180 | struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t); | ||
181 | |||
178 | #endif /* __XFS_IALLOC_BTREE_H__ */ | 182 | #endif /* __XFS_IALLOC_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 4f4c93941067..a5f02f0e4c2a 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -416,8 +416,7 @@ xfs_bulkstat( | |||
416 | /* | 416 | /* |
417 | * Allocate and initialize a btree cursor for ialloc btree. | 417 | * Allocate and initialize a btree cursor for ialloc btree. |
418 | */ | 418 | */ |
419 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, | 419 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
420 | (xfs_inode_t *)0, 0); | ||
421 | irbp = irbuf; | 420 | irbp = irbuf; |
422 | irbufend = irbuf + nirbuf; | 421 | irbufend = irbuf + nirbuf; |
423 | end_of_ag = 0; | 422 | end_of_ag = 0; |
@@ -842,8 +841,7 @@ xfs_inumbers( | |||
842 | agino = 0; | 841 | agino = 0; |
843 | continue; | 842 | continue; |
844 | } | 843 | } |
845 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, | 844 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
846 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); | ||
847 | error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); | 845 | error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); |
848 | if (error) { | 846 | if (error) { |
849 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 847 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |