2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "err_protos.h"
35 * we maintain the current slice (path from root to leaf)
36 * of the btree incore. when we need a new block, we ask
37 * the block allocator for the address of a block on that
38 * level, map the block in, and set up the appropriate
39 * pointers (child, silbing, etc.) and keys that should
40 * point to the new block.
42 typedef struct bt_stat_level
{
44 * set in setup_cursor routine and maintained in the tree-building
47 xfs_buf_t
*buf_p
; /* 2 buffer pointers to ... */
48 xfs_buf_t
*prev_buf_p
;
49 xfs_agblock_t agbno
; /* current block being filled */
50 xfs_agblock_t prev_agbno
; /* previous block */
52 * set in calculate/init cursor routines for each btree level
54 int num_recs_tot
; /* # tree recs in level */
55 int num_blocks
; /* # tree blocks in level */
56 int num_recs_pb
; /* num_recs_tot / num_blocks */
57 int modulo
; /* num_recs_tot % num_blocks */
60 typedef struct bt_status
{
61 int init
; /* cursor set up once? */
62 int num_levels
; /* # of levels in btree */
63 xfs_extlen_t num_tot_blocks
; /* # blocks alloc'ed for tree */
64 xfs_extlen_t num_free_blocks
;/* # blocks currently unused */
66 xfs_agblock_t root
; /* root block */
68 * list of blocks to be used to set up this tree
69 * and pointer to the first unused block on the list
71 xfs_agblock_t
*btree_blocks
; /* block list */
72 xfs_agblock_t
*free_btree_blocks
; /* first unused block */
74 * per-level status info
76 bt_stat_level_t level
[XFS_BTREE_MAXLEVELS
];
77 uint64_t owner
; /* owner */
81 * extra metadata for the agi
84 xfs_agino_t first_agino
;
86 xfs_agino_t freecount
;
89 static uint64_t *sb_icount_ag
; /* allocated inodes per ag */
90 static uint64_t *sb_ifree_ag
; /* free inodes per ag */
91 static uint64_t *sb_fdblocks_ag
; /* free data blocks per ag */
94 mk_incore_fstree(xfs_mount_t
*mp
, xfs_agnumber_t agno
)
98 xfs_agblock_t extent_start
;
99 xfs_extlen_t extent_len
;
101 xfs_agblock_t ag_end
;
107 * scan the bitmap for the ag looking for continuous
108 * extents of free blocks. At this point, we know
109 * that blocks in the bitmap are either set to an
110 * "in use" state or set to unknown (0) since the
111 * bmaps were zero'ed in phase 4 and only blocks
112 * being used by inodes, inode bmaps, ag headers,
113 * and the files themselves were put into the bitmap.
116 ASSERT(agno
< mp
->m_sb
.sb_agcount
);
118 extent_start
= extent_len
= 0;
120 num_extents
= free_blocks
= 0;
122 if (agno
< mp
->m_sb
.sb_agcount
- 1)
123 ag_end
= mp
->m_sb
.sb_agblocks
;
125 ag_end
= mp
->m_sb
.sb_dblocks
-
126 (xfs_rfsblock_t
)mp
->m_sb
.sb_agblocks
*
127 (mp
->m_sb
.sb_agcount
- 1);
130 * ok, now find the number of extents, keep track of the
133 for (agbno
= 0; agbno
< ag_end
; agbno
+= blen
) {
134 bstate
= get_bmap_ext(agno
, agbno
, ag_end
, &blen
);
135 if (bstate
< XR_E_INUSE
) {
137 if (in_extent
== 0) {
139 * found the start of a free extent
143 extent_start
= agbno
;
151 * free extent ends here, add extent to the
152 * 2 incore extent (avl-to-be-B+) trees
155 #if defined(XR_BLD_FREE_TRACE) && defined(XR_BLD_ADD_EXTENT)
156 fprintf(stderr
, "adding extent %u [%u %u]\n",
157 agno
, extent_start
, extent_len
);
159 add_bno_extent(agno
, extent_start
, extent_len
);
160 add_bcnt_extent(agno
, extent_start
, extent_len
);
166 * free extent ends here
168 #if defined(XR_BLD_FREE_TRACE) && defined(XR_BLD_ADD_EXTENT)
169 fprintf(stderr
, "adding extent %u [%u %u]\n",
170 agno
, extent_start
, extent_len
);
172 add_bno_extent(agno
, extent_start
, extent_len
);
173 add_bcnt_extent(agno
, extent_start
, extent_len
);
180 get_next_blockaddr(xfs_agnumber_t agno
, int level
, bt_status_t
*curs
)
182 ASSERT(curs
->free_btree_blocks
< curs
->btree_blocks
+
183 curs
->num_tot_blocks
);
184 ASSERT(curs
->num_free_blocks
> 0);
186 curs
->num_free_blocks
--;
187 return(*curs
->free_btree_blocks
++);
191 * set up the dynamically allocated block allocation data in the btree
192 * cursor that depends on the info in the static portion of the cursor.
193 * allocates space from the incore bno/bcnt extent trees and sets up
194 * the first path up the left side of the tree. Also sets up the
195 * cursor pointer to the btree root. called by init_freespace_cursor()
196 * and init_ino_cursor()
199 setup_cursor(xfs_mount_t
*mp
, xfs_agnumber_t agno
, bt_status_t
*curs
)
203 xfs_extlen_t big_extent_len
;
204 xfs_agblock_t big_extent_start
;
205 extent_tree_node_t
*ext_ptr
;
206 extent_tree_node_t
*bno_ext_ptr
;
207 xfs_extlen_t blocks_allocated
;
208 xfs_agblock_t
*agb_ptr
;
212 * get the number of blocks we need to allocate, then
213 * set up block number array, set the free block pointer
214 * to the first block in the array, and null the array
216 big_extent_len
= curs
->num_tot_blocks
;
217 blocks_allocated
= 0;
219 ASSERT(big_extent_len
> 0);
221 if ((curs
->btree_blocks
= malloc(sizeof(xfs_agblock_t
)
222 * big_extent_len
)) == NULL
)
223 do_error(_("could not set up btree block array\n"));
225 agb_ptr
= curs
->free_btree_blocks
= curs
->btree_blocks
;
227 for (j
= 0; j
< curs
->num_free_blocks
; j
++, agb_ptr
++)
228 *agb_ptr
= NULLAGBLOCK
;
231 * grab the smallest extent and use it up, then get the
232 * next smallest. This mimics the init_*_cursor code.
234 ext_ptr
= findfirst_bcnt_extent(agno
);
236 agb_ptr
= curs
->btree_blocks
;
239 * set up the free block array
241 while (blocks_allocated
< big_extent_len
) {
244 _("error - not enough free space in filesystem\n"));
246 * use up the extent we've got
248 for (u
= 0; u
< ext_ptr
->ex_blockcount
&&
249 blocks_allocated
< big_extent_len
; u
++) {
250 ASSERT(agb_ptr
< curs
->btree_blocks
251 + curs
->num_tot_blocks
);
252 *agb_ptr
++ = ext_ptr
->ex_startblock
+ u
;
256 error
= rmap_add_ag_rec(mp
, agno
, ext_ptr
->ex_startblock
, u
,
259 do_error(_("could not set up btree rmaps: %s\n"),
263 * if we only used part of this last extent, then we
264 * need only to reset the extent in the extent
265 * trees and we're done
267 if (u
< ext_ptr
->ex_blockcount
) {
268 big_extent_start
= ext_ptr
->ex_startblock
+ u
;
269 big_extent_len
= ext_ptr
->ex_blockcount
- u
;
271 ASSERT(big_extent_len
> 0);
273 bno_ext_ptr
= find_bno_extent(agno
,
274 ext_ptr
->ex_startblock
);
275 ASSERT(bno_ext_ptr
!= NULL
);
276 get_bno_extent(agno
, bno_ext_ptr
);
277 release_extent_tree_node(bno_ext_ptr
);
279 ext_ptr
= get_bcnt_extent(agno
, ext_ptr
->ex_startblock
,
280 ext_ptr
->ex_blockcount
);
281 release_extent_tree_node(ext_ptr
);
282 #ifdef XR_BLD_FREE_TRACE
283 fprintf(stderr
, "releasing extent: %u [%u %u]\n",
284 agno
, ext_ptr
->ex_startblock
,
285 ext_ptr
->ex_blockcount
);
286 fprintf(stderr
, "blocks_allocated = %d\n",
290 add_bno_extent(agno
, big_extent_start
, big_extent_len
);
291 add_bcnt_extent(agno
, big_extent_start
, big_extent_len
);
296 * delete the used-up extent from both extent trees and
297 * find next biggest extent
299 #ifdef XR_BLD_FREE_TRACE
300 fprintf(stderr
, "releasing extent: %u [%u %u]\n",
301 agno
, ext_ptr
->ex_startblock
, ext_ptr
->ex_blockcount
);
303 bno_ext_ptr
= find_bno_extent(agno
, ext_ptr
->ex_startblock
);
304 ASSERT(bno_ext_ptr
!= NULL
);
305 get_bno_extent(agno
, bno_ext_ptr
);
306 release_extent_tree_node(bno_ext_ptr
);
308 ext_ptr
= get_bcnt_extent(agno
, ext_ptr
->ex_startblock
,
309 ext_ptr
->ex_blockcount
);
310 ASSERT(ext_ptr
!= NULL
);
311 release_extent_tree_node(ext_ptr
);
313 ext_ptr
= findfirst_bcnt_extent(agno
);
315 #ifdef XR_BLD_FREE_TRACE
316 fprintf(stderr
, "blocks_allocated = %d\n",
322 write_cursor(bt_status_t
*curs
)
326 for (i
= 0; i
< curs
->num_levels
; i
++) {
327 #if defined(XR_BLD_FREE_TRACE) || defined(XR_BLD_INO_TRACE)
328 fprintf(stderr
, "writing bt block %u\n", curs
->level
[i
].agbno
);
330 if (curs
->level
[i
].prev_buf_p
!= NULL
) {
331 ASSERT(curs
->level
[i
].prev_agbno
!= NULLAGBLOCK
);
332 #if defined(XR_BLD_FREE_TRACE) || defined(XR_BLD_INO_TRACE)
333 fprintf(stderr
, "writing bt prev block %u\n",
334 curs
->level
[i
].prev_agbno
);
336 libxfs_writebuf(curs
->level
[i
].prev_buf_p
, 0);
338 libxfs_writebuf(curs
->level
[i
].buf_p
, 0);
343 finish_cursor(bt_status_t
*curs
)
345 ASSERT(curs
->num_free_blocks
== 0);
346 free(curs
->btree_blocks
);
350 * We need to leave some free records in the tree for the corner case of
351 * setting up the AGFL. This may require allocation of blocks, and as
352 * such can require insertion of new records into the tree (e.g. moving
353 * a record in the by-count tree when a long extent is shortened). If we
354 * pack the records into the leaves with no slack space, this requires a
355 * leaf split to occur and a block to be allocated from the free list.
356 * If we don't have any blocks on the free list (because we are setting
357 * it up!), then we fail, and the filesystem will fail with the same
358 * failure at runtime. Hence leave a couple of records slack space in
359 * each block to allow immediate modification of the tree without
360 * requiring splits to be done.
362 * XXX(hch): any reason we don't just look at mp->m_alloc_mxr?
364 #define XR_ALLOC_BLOCK_MAXRECS(mp, level) \
365 (libxfs_allocbt_maxrecs((mp), (mp)->m_sb.sb_blocksize, (level) == 0) - 2)
368 * this calculates a freespace cursor for an ag.
369 * btree_curs is an in/out. returns the number of
370 * blocks that will show up in the AGFL.
373 calculate_freespace_cursor(xfs_mount_t
*mp
, xfs_agnumber_t agno
,
374 xfs_agblock_t
*extents
, bt_status_t
*btree_curs
)
376 xfs_extlen_t blocks_needed
; /* a running count */
377 xfs_extlen_t blocks_allocated_pt
; /* per tree */
378 xfs_extlen_t blocks_allocated_total
; /* for both trees */
379 xfs_agblock_t num_extents
;
383 bt_stat_level_t
*lptr
;
384 bt_stat_level_t
*p_lptr
;
385 extent_tree_node_t
*ext_ptr
;
388 num_extents
= *extents
;
391 ASSERT(num_extents
!= 0);
393 lptr
= &btree_curs
->level
[0];
394 btree_curs
->init
= 1;
397 * figure out how much space we need for the leaf level
398 * of the tree and set up the cursor for the leaf level
399 * (note that the same code is duplicated further down)
401 lptr
->num_blocks
= howmany(num_extents
, XR_ALLOC_BLOCK_MAXRECS(mp
, 0));
402 lptr
->num_recs_pb
= num_extents
/ lptr
->num_blocks
;
403 lptr
->modulo
= num_extents
% lptr
->num_blocks
;
404 lptr
->num_recs_tot
= num_extents
;
407 #ifdef XR_BLD_FREE_TRACE
408 fprintf(stderr
, "%s 0 %d %d %d %d\n", __func__
,
415 * if we need more levels, set them up. # of records
416 * per level is the # of blocks in the level below it
418 if (lptr
->num_blocks
> 1) {
419 for (; btree_curs
->level
[level
- 1].num_blocks
> 1
420 && level
< XFS_BTREE_MAXLEVELS
;
422 lptr
= &btree_curs
->level
[level
];
423 p_lptr
= &btree_curs
->level
[level
- 1];
424 lptr
->num_blocks
= howmany(p_lptr
->num_blocks
,
425 XR_ALLOC_BLOCK_MAXRECS(mp
, level
));
426 lptr
->modulo
= p_lptr
->num_blocks
428 lptr
->num_recs_pb
= p_lptr
->num_blocks
430 lptr
->num_recs_tot
= p_lptr
->num_blocks
;
431 #ifdef XR_BLD_FREE_TRACE
432 fprintf(stderr
, "%s %d %d %d %d %d\n", __func__
,
442 ASSERT(lptr
->num_blocks
== 1);
443 btree_curs
->num_levels
= level
;
446 * ok, now we have a hypothetical cursor that
447 * will work for both the bno and bcnt trees.
448 * now figure out if using up blocks to set up the
449 * trees will perturb the shape of the freespace tree.
450 * if so, we've over-allocated. the freespace trees
451 * as they will be *after* accounting for the free space
452 * we've used up will need fewer blocks to to represent
453 * than we've allocated. We can use the AGFL to hold
454 * xfs_agfl_size (sector/xfs_agfl_t) blocks but that's it.
455 * Thus we limit things to xfs_agfl_size/2 for each of the 2 btrees.
456 * if the number of extra blocks is more than that,
457 * we'll have to be called again.
459 for (blocks_needed
= 0, i
= 0; i
< level
; i
++) {
460 blocks_needed
+= btree_curs
->level
[i
].num_blocks
;
464 * record the # of blocks we've allocated
466 blocks_allocated_pt
= blocks_needed
;
468 blocks_allocated_total
= blocks_needed
;
471 * figure out how many free extents will be used up by
472 * our space allocation
474 if ((ext_ptr
= findfirst_bcnt_extent(agno
)) == NULL
)
475 do_error(_("can't rebuild fs trees -- not enough free space "
476 "on ag %u\n"), agno
);
478 while (ext_ptr
!= NULL
&& blocks_needed
> 0) {
479 if (ext_ptr
->ex_blockcount
<= blocks_needed
) {
480 blocks_needed
-= ext_ptr
->ex_blockcount
;
486 ext_ptr
= findnext_bcnt_extent(agno
, ext_ptr
);
488 #ifdef XR_BLD_FREE_TRACE
489 if (ext_ptr
!= NULL
) {
490 fprintf(stderr
, "got next extent [%u %u]\n",
491 ext_ptr
->ex_startblock
, ext_ptr
->ex_blockcount
);
493 fprintf(stderr
, "out of extents\n");
497 if (blocks_needed
> 0)
498 do_error(_("ag %u - not enough free space to build freespace "
501 ASSERT(num_extents
>= extents_used
);
503 num_extents
-= extents_used
;
506 * see if the number of leaf blocks will change as a result
507 * of the number of extents changing
509 if (howmany(num_extents
, XR_ALLOC_BLOCK_MAXRECS(mp
, 0))
510 != btree_curs
->level
[0].num_blocks
) {
512 * yes -- recalculate the cursor. If the number of
513 * excess (overallocated) blocks is < xfs_agfl_size/2, we're ok.
514 * we can put those into the AGFL. we don't try
515 * and get things to converge exactly (reach a
516 * state with zero excess blocks) because there
517 * exist pathological cases which will never
518 * converge. first, check for the zero-case.
520 if (num_extents
== 0) {
522 * ok, we've used up all the free blocks
523 * trying to lay out the leaf level. go
524 * to a one block (empty) btree and put the
525 * already allocated blocks into the AGFL
527 if (btree_curs
->level
[0].num_blocks
!= 1) {
529 * we really needed more blocks because
530 * the old tree had more than one level.
533 do_warn(_("not enough free blocks left to "
534 "describe all free blocks in AG "
537 #ifdef XR_BLD_FREE_TRACE
539 "ag %u -- no free extents, alloc'ed %d\n",
540 agno
, blocks_allocated_pt
);
542 lptr
->num_blocks
= 1;
544 lptr
->num_recs_pb
= 0;
545 lptr
->num_recs_tot
= 0;
547 btree_curs
->num_levels
= 1;
550 * don't reset the allocation stats, assume
551 * they're all extra blocks
552 * don't forget to return the total block count
553 * not the per-tree block count. these are the
554 * extras that will go into the AGFL. subtract
555 * two for the root blocks.
557 btree_curs
->num_tot_blocks
= blocks_allocated_pt
;
558 btree_curs
->num_free_blocks
= blocks_allocated_pt
;
562 return(blocks_allocated_total
- 2);
565 lptr
= &btree_curs
->level
[0];
566 lptr
->num_blocks
= howmany(num_extents
,
567 XR_ALLOC_BLOCK_MAXRECS(mp
, 0));
568 lptr
->num_recs_pb
= num_extents
/ lptr
->num_blocks
;
569 lptr
->modulo
= num_extents
% lptr
->num_blocks
;
570 lptr
->num_recs_tot
= num_extents
;
574 * if we need more levels, set them up
576 if (lptr
->num_blocks
> 1) {
577 for (level
= 1; btree_curs
->level
[level
-1].num_blocks
578 > 1 && level
< XFS_BTREE_MAXLEVELS
;
580 lptr
= &btree_curs
->level
[level
];
581 p_lptr
= &btree_curs
->level
[level
-1];
582 lptr
->num_blocks
= howmany(p_lptr
->num_blocks
,
583 XR_ALLOC_BLOCK_MAXRECS(mp
, level
));
584 lptr
->modulo
= p_lptr
->num_blocks
586 lptr
->num_recs_pb
= p_lptr
->num_blocks
588 lptr
->num_recs_tot
= p_lptr
->num_blocks
;
591 ASSERT(lptr
->num_blocks
== 1);
592 btree_curs
->num_levels
= level
;
595 * now figure out the number of excess blocks
597 for (blocks_needed
= 0, i
= 0; i
< level
; i
++) {
598 blocks_needed
+= btree_curs
->level
[i
].num_blocks
;
602 ASSERT(blocks_allocated_total
>= blocks_needed
);
603 extra_blocks
= blocks_allocated_total
- blocks_needed
;
605 if (extents_used
> 0) {
607 * reset the leaf level geometry to account
608 * for consumed extents. we can leave the
609 * rest of the cursor alone since the number
610 * of leaf blocks hasn't changed.
612 lptr
= &btree_curs
->level
[0];
614 lptr
->num_recs_pb
= num_extents
/ lptr
->num_blocks
;
615 lptr
->modulo
= num_extents
% lptr
->num_blocks
;
616 lptr
->num_recs_tot
= num_extents
;
622 btree_curs
->num_tot_blocks
= blocks_allocated_pt
;
623 btree_curs
->num_free_blocks
= blocks_allocated_pt
;
625 *extents
= num_extents
;
627 return(extra_blocks
);
631 prop_freespace_cursor(xfs_mount_t
*mp
, xfs_agnumber_t agno
,
632 bt_status_t
*btree_curs
, xfs_agblock_t startblock
,
633 xfs_extlen_t blockcount
, int level
, xfs_btnum_t btnum
)
635 struct xfs_btree_block
*bt_hdr
;
636 xfs_alloc_key_t
*bt_key
;
637 xfs_alloc_ptr_t
*bt_ptr
;
639 bt_stat_level_t
*lptr
;
641 ASSERT(btnum
== XFS_BTNUM_BNO
|| btnum
== XFS_BTNUM_CNT
);
645 if (level
>= btree_curs
->num_levels
)
648 lptr
= &btree_curs
->level
[level
];
649 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
651 if (be16_to_cpu(bt_hdr
->bb_numrecs
) == 0) {
653 * only happens once when initializing the
654 * left-hand side of the tree.
656 prop_freespace_cursor(mp
, agno
, btree_curs
, startblock
,
657 blockcount
, level
, btnum
);
660 if (be16_to_cpu(bt_hdr
->bb_numrecs
) ==
661 lptr
->num_recs_pb
+ (lptr
->modulo
> 0)) {
663 * write out current prev block, grab us a new block,
664 * and set the rightsib pointer of current block
666 #ifdef XR_BLD_FREE_TRACE
667 fprintf(stderr
, " %d ", lptr
->prev_agbno
);
669 if (lptr
->prev_agbno
!= NULLAGBLOCK
) {
670 ASSERT(lptr
->prev_buf_p
!= NULL
);
671 libxfs_writebuf(lptr
->prev_buf_p
, 0);
673 lptr
->prev_agbno
= lptr
->agbno
;;
674 lptr
->prev_buf_p
= lptr
->buf_p
;
675 agbno
= get_next_blockaddr(agno
, level
, btree_curs
);
677 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(agbno
);
679 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
680 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
681 XFS_FSB_TO_BB(mp
, 1));
688 * initialize block header
690 lptr
->buf_p
->b_ops
= &xfs_allocbt_buf_ops
;
691 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
692 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
693 libxfs_btree_init_block(mp
, lptr
->buf_p
, btnum
, level
,
696 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
699 * propagate extent record for first extent in new block up
701 prop_freespace_cursor(mp
, agno
, btree_curs
, startblock
,
702 blockcount
, level
, btnum
);
705 * add extent info to current block
707 be16_add_cpu(&bt_hdr
->bb_numrecs
, 1);
709 bt_key
= XFS_ALLOC_KEY_ADDR(mp
, bt_hdr
,
710 be16_to_cpu(bt_hdr
->bb_numrecs
));
711 bt_ptr
= XFS_ALLOC_PTR_ADDR(mp
, bt_hdr
,
712 be16_to_cpu(bt_hdr
->bb_numrecs
),
715 bt_key
->ar_startblock
= cpu_to_be32(startblock
);
716 bt_key
->ar_blockcount
= cpu_to_be32(blockcount
);
717 *bt_ptr
= cpu_to_be32(btree_curs
->level
[level
-1].agbno
);
721 * rebuilds a freespace tree given a cursor and type
722 * of tree to build (bno or bcnt). returns the number of free blocks
723 * represented by the tree.
726 build_freespace_tree(xfs_mount_t
*mp
, xfs_agnumber_t agno
,
727 bt_status_t
*btree_curs
, xfs_btnum_t btnum
)
731 struct xfs_btree_block
*bt_hdr
;
732 xfs_alloc_rec_t
*bt_rec
;
735 extent_tree_node_t
*ext_ptr
;
736 bt_stat_level_t
*lptr
;
737 xfs_extlen_t freeblks
;
739 ASSERT(btnum
== XFS_BTNUM_BNO
|| btnum
== XFS_BTNUM_CNT
);
741 #ifdef XR_BLD_FREE_TRACE
742 fprintf(stderr
, "in build_freespace_tree, agno = %d\n", agno
);
744 level
= btree_curs
->num_levels
;
750 * initialize the first block on each btree level
752 for (i
= 0; i
< level
; i
++) {
753 lptr
= &btree_curs
->level
[i
];
755 agbno
= get_next_blockaddr(agno
, i
, btree_curs
);
756 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
757 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
758 XFS_FSB_TO_BB(mp
, 1));
760 if (i
== btree_curs
->num_levels
- 1)
761 btree_curs
->root
= agbno
;
764 lptr
->prev_agbno
= NULLAGBLOCK
;
765 lptr
->prev_buf_p
= NULL
;
767 * initialize block header
769 lptr
->buf_p
->b_ops
= &xfs_allocbt_buf_ops
;
770 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
771 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
772 libxfs_btree_init_block(mp
, lptr
->buf_p
, btnum
, i
, 0, agno
, 0);
775 * run along leaf, setting up records. as we have to switch
776 * blocks, call the prop_freespace_cursor routine to set up the new
777 * pointers for the parent. that can recurse up to the root
778 * if required. set the sibling pointers for leaf level here.
780 if (btnum
== XFS_BTNUM_BNO
)
781 ext_ptr
= findfirst_bno_extent(agno
);
783 ext_ptr
= findfirst_bcnt_extent(agno
);
785 #ifdef XR_BLD_FREE_TRACE
786 fprintf(stderr
, "bft, agno = %d, start = %u, count = %u\n",
787 agno
, ext_ptr
->ex_startblock
, ext_ptr
->ex_blockcount
);
790 lptr
= &btree_curs
->level
[0];
792 for (i
= 0; i
< btree_curs
->level
[0].num_blocks
; i
++) {
794 * block initialization, lay in block header
796 lptr
->buf_p
->b_ops
= &xfs_allocbt_buf_ops
;
797 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
798 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
799 libxfs_btree_init_block(mp
, lptr
->buf_p
, btnum
, 0, 0, agno
, 0);
801 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
802 bt_hdr
->bb_numrecs
= cpu_to_be16(lptr
->num_recs_pb
+
804 #ifdef XR_BLD_FREE_TRACE
805 fprintf(stderr
, "bft, bb_numrecs = %d\n",
806 be16_to_cpu(bt_hdr
->bb_numrecs
));
809 if (lptr
->modulo
> 0)
813 * initialize values in the path up to the root if
814 * this is a multi-level btree
816 if (btree_curs
->num_levels
> 1)
817 prop_freespace_cursor(mp
, agno
, btree_curs
,
818 ext_ptr
->ex_startblock
,
819 ext_ptr
->ex_blockcount
,
822 bt_rec
= (xfs_alloc_rec_t
*)
823 ((char *)bt_hdr
+ XFS_ALLOC_BLOCK_LEN(mp
));
824 for (j
= 0; j
< be16_to_cpu(bt_hdr
->bb_numrecs
); j
++) {
825 ASSERT(ext_ptr
!= NULL
);
826 bt_rec
[j
].ar_startblock
= cpu_to_be32(
827 ext_ptr
->ex_startblock
);
828 bt_rec
[j
].ar_blockcount
= cpu_to_be32(
829 ext_ptr
->ex_blockcount
);
830 freeblks
+= ext_ptr
->ex_blockcount
;
831 if (btnum
== XFS_BTNUM_BNO
)
832 ext_ptr
= findnext_bno_extent(ext_ptr
);
834 ext_ptr
= findnext_bcnt_extent(agno
, ext_ptr
);
836 #ifdef XR_BLD_FREE_TRACE
838 fprintf(stderr
, "null extent pointer, j = %d\n",
842 "bft, agno = %d, start = %u, count = %u\n",
843 agno
, ext_ptr
->ex_startblock
,
844 ext_ptr
->ex_blockcount
);
849 if (ext_ptr
!= NULL
) {
851 * get next leaf level block
853 if (lptr
->prev_buf_p
!= NULL
) {
854 #ifdef XR_BLD_FREE_TRACE
855 fprintf(stderr
, " writing fst agbno %u\n",
858 ASSERT(lptr
->prev_agbno
!= NULLAGBLOCK
);
859 libxfs_writebuf(lptr
->prev_buf_p
, 0);
861 lptr
->prev_buf_p
= lptr
->buf_p
;
862 lptr
->prev_agbno
= lptr
->agbno
;
863 lptr
->agbno
= get_next_blockaddr(agno
, 0, btree_curs
);
864 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(lptr
->agbno
);
866 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
867 XFS_AGB_TO_DADDR(mp
, agno
, lptr
->agbno
),
868 XFS_FSB_TO_BB(mp
, 1));
876 * XXX(hch): any reason we don't just look at mp->m_inobt_mxr?
878 #define XR_INOBT_BLOCK_MAXRECS(mp, level) \
879 libxfs_inobt_maxrecs((mp), (mp)->m_sb.sb_blocksize, \
883 * we don't have to worry here about how chewing up free extents
884 * may perturb things because inode tree building happens before
885 * freespace tree building.
888 init_ino_cursor(xfs_mount_t
*mp
, xfs_agnumber_t agno
, bt_status_t
*btree_curs
,
889 uint64_t *num_inos
, uint64_t *num_free_inos
, int finobt
)
895 ino_tree_node_t
*ino_rec
;
898 bt_stat_level_t
*lptr
;
899 bt_stat_level_t
*p_lptr
;
900 xfs_extlen_t blocks_allocated
;
903 *num_inos
= *num_free_inos
= 0;
906 lptr
= &btree_curs
->level
[0];
907 btree_curs
->init
= 1;
908 btree_curs
->owner
= XFS_RMAP_OWN_INOBT
;
911 * build up statistics
913 ino_rec
= findfirst_inode_rec(agno
);
914 for (num_recs
= 0; ino_rec
!= NULL
; ino_rec
= next_ino_rec(ino_rec
)) {
917 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
918 ASSERT(is_inode_confirmed(ino_rec
, i
));
920 * sparse inodes are not factored into superblock (free)
923 if (is_inode_sparse(ino_rec
, i
))
925 if (is_inode_free(ino_rec
, i
))
931 * finobt only considers records with free inodes
933 if (finobt
&& !rec_nfinos
)
936 nfinos
+= rec_nfinos
;
943 * easy corner-case -- no inode records
945 lptr
->num_blocks
= 1;
947 lptr
->num_recs_pb
= 0;
948 lptr
->num_recs_tot
= 0;
950 btree_curs
->num_levels
= 1;
951 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
= 1;
953 setup_cursor(mp
, agno
, btree_curs
);
958 blocks_allocated
= lptr
->num_blocks
= howmany(num_recs
,
959 XR_INOBT_BLOCK_MAXRECS(mp
, 0));
961 lptr
->modulo
= num_recs
% lptr
->num_blocks
;
962 lptr
->num_recs_pb
= num_recs
/ lptr
->num_blocks
;
963 lptr
->num_recs_tot
= num_recs
;
966 if (lptr
->num_blocks
> 1) {
967 for (; btree_curs
->level
[level
-1].num_blocks
> 1
968 && level
< XFS_BTREE_MAXLEVELS
;
970 lptr
= &btree_curs
->level
[level
];
971 p_lptr
= &btree_curs
->level
[level
- 1];
972 lptr
->num_blocks
= howmany(p_lptr
->num_blocks
,
973 XR_INOBT_BLOCK_MAXRECS(mp
, level
));
974 lptr
->modulo
= p_lptr
->num_blocks
% lptr
->num_blocks
;
975 lptr
->num_recs_pb
= p_lptr
->num_blocks
977 lptr
->num_recs_tot
= p_lptr
->num_blocks
;
979 blocks_allocated
+= lptr
->num_blocks
;
982 ASSERT(lptr
->num_blocks
== 1);
983 btree_curs
->num_levels
= level
;
985 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
988 setup_cursor(mp
, agno
, btree_curs
);
991 *num_free_inos
= nfinos
;
997 prop_ino_cursor(xfs_mount_t
*mp
, xfs_agnumber_t agno
, bt_status_t
*btree_curs
,
998 xfs_agino_t startino
, int level
)
1000 struct xfs_btree_block
*bt_hdr
;
1001 xfs_inobt_key_t
*bt_key
;
1002 xfs_inobt_ptr_t
*bt_ptr
;
1003 xfs_agblock_t agbno
;
1004 bt_stat_level_t
*lptr
;
1008 if (level
>= btree_curs
->num_levels
)
1011 lptr
= &btree_curs
->level
[level
];
1012 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1014 if (be16_to_cpu(bt_hdr
->bb_numrecs
) == 0) {
1016 * this only happens once to initialize the
1017 * first path up the left side of the tree
1018 * where the agbno's are already set up
1020 prop_ino_cursor(mp
, agno
, btree_curs
, startino
, level
);
1023 if (be16_to_cpu(bt_hdr
->bb_numrecs
) ==
1024 lptr
->num_recs_pb
+ (lptr
->modulo
> 0)) {
1026 * write out current prev block, grab us a new block,
1027 * and set the rightsib pointer of current block
1029 #ifdef XR_BLD_INO_TRACE
1030 fprintf(stderr
, " ino prop agbno %d ", lptr
->prev_agbno
);
1032 if (lptr
->prev_agbno
!= NULLAGBLOCK
) {
1033 ASSERT(lptr
->prev_buf_p
!= NULL
);
1034 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1036 lptr
->prev_agbno
= lptr
->agbno
;;
1037 lptr
->prev_buf_p
= lptr
->buf_p
;
1038 agbno
= get_next_blockaddr(agno
, level
, btree_curs
);
1040 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(agbno
);
1042 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1043 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1044 XFS_FSB_TO_BB(mp
, 1));
1045 lptr
->agbno
= agbno
;
1051 * initialize block header
1053 lptr
->buf_p
->b_ops
= &xfs_inobt_buf_ops
;
1054 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1055 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1056 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_INO
,
1059 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1062 * propagate extent record for first extent in new block up
1064 prop_ino_cursor(mp
, agno
, btree_curs
, startino
, level
);
1067 * add inode info to current block
1069 be16_add_cpu(&bt_hdr
->bb_numrecs
, 1);
1071 bt_key
= XFS_INOBT_KEY_ADDR(mp
, bt_hdr
,
1072 be16_to_cpu(bt_hdr
->bb_numrecs
));
1073 bt_ptr
= XFS_INOBT_PTR_ADDR(mp
, bt_hdr
,
1074 be16_to_cpu(bt_hdr
->bb_numrecs
),
1075 mp
->m_inobt_mxr
[1]);
1077 bt_key
->ir_startino
= cpu_to_be32(startino
);
1078 *bt_ptr
= cpu_to_be32(btree_curs
->level
[level
-1].agbno
);
1082 * XXX: yet more code that can be shared with mkfs, growfs.
1085 build_agi(xfs_mount_t
*mp
, xfs_agnumber_t agno
, bt_status_t
*btree_curs
,
1086 bt_status_t
*finobt_curs
, struct agi_stat
*agi_stat
)
1092 agi_buf
= libxfs_getbuf(mp
->m_dev
,
1093 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
1094 mp
->m_sb
.sb_sectsize
/BBSIZE
);
1095 agi_buf
->b_ops
= &xfs_agi_buf_ops
;
1096 agi
= XFS_BUF_TO_AGI(agi_buf
);
1097 memset(agi
, 0, mp
->m_sb
.sb_sectsize
);
1099 agi
->agi_magicnum
= cpu_to_be32(XFS_AGI_MAGIC
);
1100 agi
->agi_versionnum
= cpu_to_be32(XFS_AGI_VERSION
);
1101 agi
->agi_seqno
= cpu_to_be32(agno
);
1102 if (agno
< mp
->m_sb
.sb_agcount
- 1)
1103 agi
->agi_length
= cpu_to_be32(mp
->m_sb
.sb_agblocks
);
1105 agi
->agi_length
= cpu_to_be32(mp
->m_sb
.sb_dblocks
-
1106 (xfs_rfsblock_t
) mp
->m_sb
.sb_agblocks
* agno
);
1107 agi
->agi_count
= cpu_to_be32(agi_stat
->count
);
1108 agi
->agi_root
= cpu_to_be32(btree_curs
->root
);
1109 agi
->agi_level
= cpu_to_be32(btree_curs
->num_levels
);
1110 agi
->agi_freecount
= cpu_to_be32(agi_stat
->freecount
);
1111 agi
->agi_newino
= cpu_to_be32(agi_stat
->first_agino
);
1112 agi
->agi_dirino
= cpu_to_be32(NULLAGINO
);
1114 for (i
= 0; i
< XFS_AGI_UNLINKED_BUCKETS
; i
++)
1115 agi
->agi_unlinked
[i
] = cpu_to_be32(NULLAGINO
);
1117 if (xfs_sb_version_hascrc(&mp
->m_sb
))
1118 platform_uuid_copy(&agi
->agi_uuid
, &mp
->m_sb
.sb_meta_uuid
);
1120 if (xfs_sb_version_hasfinobt(&mp
->m_sb
)) {
1121 agi
->agi_free_root
= cpu_to_be32(finobt_curs
->root
);
1122 agi
->agi_free_level
= cpu_to_be32(finobt_curs
->num_levels
);
1125 libxfs_writebuf(agi_buf
, 0);
1129 * rebuilds an inode tree given a cursor. We're lazy here and call
1130 * the routine that builds the agi
1133 build_ino_tree(xfs_mount_t
*mp
, xfs_agnumber_t agno
,
1134 bt_status_t
*btree_curs
, xfs_btnum_t btnum
,
1135 struct agi_stat
*agi_stat
)
1139 xfs_agblock_t agbno
;
1140 xfs_agino_t first_agino
;
1141 struct xfs_btree_block
*bt_hdr
;
1142 xfs_inobt_rec_t
*bt_rec
;
1143 ino_tree_node_t
*ino_rec
;
1144 bt_stat_level_t
*lptr
;
1145 xfs_agino_t count
= 0;
1146 xfs_agino_t freecount
= 0;
1150 int level
= btree_curs
->num_levels
;
1155 ASSERT(btnum
== XFS_BTNUM_INO
|| btnum
== XFS_BTNUM_FINO
);
1157 for (i
= 0; i
< level
; i
++) {
1158 lptr
= &btree_curs
->level
[i
];
1160 agbno
= get_next_blockaddr(agno
, i
, btree_curs
);
1161 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1162 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1163 XFS_FSB_TO_BB(mp
, 1));
1165 if (i
== btree_curs
->num_levels
- 1)
1166 btree_curs
->root
= agbno
;
1168 lptr
->agbno
= agbno
;
1169 lptr
->prev_agbno
= NULLAGBLOCK
;
1170 lptr
->prev_buf_p
= NULL
;
1172 * initialize block header
1175 lptr
->buf_p
->b_ops
= &xfs_inobt_buf_ops
;
1176 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1177 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1178 libxfs_btree_init_block(mp
, lptr
->buf_p
, btnum
, i
, 0, agno
, 0);
1182 * run along leaf, setting up records. as we have to switch
1183 * blocks, call the prop_ino_cursor routine to set up the new
1184 * pointers for the parent. that can recurse up to the root
1185 * if required. set the sibling pointers for leaf level here.
1187 if (btnum
== XFS_BTNUM_FINO
)
1188 ino_rec
= findfirst_free_inode_rec(agno
);
1190 ino_rec
= findfirst_inode_rec(agno
);
1192 if (ino_rec
!= NULL
)
1193 first_agino
= ino_rec
->ino_startnum
;
1195 first_agino
= NULLAGINO
;
1197 lptr
= &btree_curs
->level
[0];
1199 for (i
= 0; i
< lptr
->num_blocks
; i
++) {
1201 * block initialization, lay in block header
1203 lptr
->buf_p
->b_ops
= &xfs_inobt_buf_ops
;
1204 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1205 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1206 libxfs_btree_init_block(mp
, lptr
->buf_p
, btnum
, 0, 0, agno
, 0);
1208 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1209 bt_hdr
->bb_numrecs
= cpu_to_be16(lptr
->num_recs_pb
+
1210 (lptr
->modulo
> 0));
1212 if (lptr
->modulo
> 0)
1215 if (lptr
->num_recs_pb
> 0)
1216 prop_ino_cursor(mp
, agno
, btree_curs
,
1217 ino_rec
->ino_startnum
, 0);
1219 bt_rec
= (xfs_inobt_rec_t
*)
1220 ((char *)bt_hdr
+ XFS_INOBT_BLOCK_LEN(mp
));
1221 for (j
= 0; j
< be16_to_cpu(bt_hdr
->bb_numrecs
); j
++) {
1222 ASSERT(ino_rec
!= NULL
);
1223 bt_rec
[j
].ir_startino
=
1224 cpu_to_be32(ino_rec
->ino_startnum
);
1225 bt_rec
[j
].ir_free
= cpu_to_be64(ino_rec
->ir_free
);
1227 inocnt
= finocnt
= 0;
1228 for (k
= 0; k
< sizeof(xfs_inofree_t
)*NBBY
; k
++) {
1229 ASSERT(is_inode_confirmed(ino_rec
, k
));
1231 if (is_inode_sparse(ino_rec
, k
))
1233 if (is_inode_free(ino_rec
, k
))
1239 * Set the freecount and check whether we need to update
1240 * the sparse format fields. Otherwise, skip to the next
1243 inorec_set_freecount(mp
, &bt_rec
[j
], finocnt
);
1244 if (!xfs_sb_version_hassparseinodes(&mp
->m_sb
))
1248 * Convert the 64-bit in-core sparse inode state to the
1249 * 16-bit on-disk holemask.
1252 spmask
= (1 << XFS_INODES_PER_HOLEMASK_BIT
) - 1;
1253 sparse
= ino_rec
->ir_sparse
;
1254 for (k
= 0; k
< XFS_INOBT_HOLEMASK_BITS
; k
++) {
1255 if (sparse
& spmask
) {
1256 ASSERT((sparse
& spmask
) == spmask
);
1257 holemask
|= (1 << k
);
1259 ASSERT((sparse
& spmask
) == 0);
1260 sparse
>>= XFS_INODES_PER_HOLEMASK_BIT
;
1263 bt_rec
[j
].ir_u
.sp
.ir_count
= inocnt
;
1264 bt_rec
[j
].ir_u
.sp
.ir_holemask
= cpu_to_be16(holemask
);
1267 freecount
+= finocnt
;
1270 if (btnum
== XFS_BTNUM_FINO
)
1271 ino_rec
= next_free_ino_rec(ino_rec
);
1273 ino_rec
= next_ino_rec(ino_rec
);
1276 if (ino_rec
!= NULL
) {
1278 * get next leaf level block
1280 if (lptr
->prev_buf_p
!= NULL
) {
1281 #ifdef XR_BLD_INO_TRACE
1282 fprintf(stderr
, "writing inobt agbno %u\n",
1285 ASSERT(lptr
->prev_agbno
!= NULLAGBLOCK
);
1286 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1288 lptr
->prev_buf_p
= lptr
->buf_p
;
1289 lptr
->prev_agbno
= lptr
->agbno
;
1290 lptr
->agbno
= get_next_blockaddr(agno
, 0, btree_curs
);
1291 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(lptr
->agbno
);
1293 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1294 XFS_AGB_TO_DADDR(mp
, agno
, lptr
->agbno
),
1295 XFS_FSB_TO_BB(mp
, 1));
1300 agi_stat
->first_agino
= first_agino
;
1301 agi_stat
->count
= count
;
1302 agi_stat
->freecount
= freecount
;
1306 /* rebuild the rmap tree */
1309 * we don't have to worry here about how chewing up free extents
1310 * may perturb things because rmap tree building happens before
1311 * freespace tree building.
1315 struct xfs_mount
*mp
,
1316 xfs_agnumber_t agno
,
1317 struct bt_status
*btree_curs
)
1321 struct bt_stat_level
*lptr
;
1322 struct bt_stat_level
*p_lptr
;
1323 xfs_extlen_t blocks_allocated
;
1326 if (!xfs_sb_version_hasrmapbt(&mp
->m_sb
)) {
1327 memset(btree_curs
, 0, sizeof(struct bt_status
));
1331 lptr
= &btree_curs
->level
[0];
1332 btree_curs
->init
= 1;
1333 btree_curs
->owner
= XFS_RMAP_OWN_AG
;
1336 * build up statistics
1338 num_recs
= rmap_record_count(mp
, agno
);
1339 if (num_recs
== 0) {
1341 * easy corner-case -- no rmap records
1343 lptr
->num_blocks
= 1;
1345 lptr
->num_recs_pb
= 0;
1346 lptr
->num_recs_tot
= 0;
1348 btree_curs
->num_levels
= 1;
1349 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
= 1;
1351 setup_cursor(mp
, agno
, btree_curs
);
1357 * Leave enough slack in the rmapbt that we can insert the
1358 * metadata AG entries without too many splits.
1360 maxrecs
= mp
->m_rmap_mxr
[0];
1361 if (num_recs
> maxrecs
)
1363 blocks_allocated
= lptr
->num_blocks
= howmany(num_recs
, maxrecs
);
1365 lptr
->modulo
= num_recs
% lptr
->num_blocks
;
1366 lptr
->num_recs_pb
= num_recs
/ lptr
->num_blocks
;
1367 lptr
->num_recs_tot
= num_recs
;
1370 if (lptr
->num_blocks
> 1) {
1371 for (; btree_curs
->level
[level
-1].num_blocks
> 1
1372 && level
< XFS_BTREE_MAXLEVELS
;
1374 lptr
= &btree_curs
->level
[level
];
1375 p_lptr
= &btree_curs
->level
[level
- 1];
1376 lptr
->num_blocks
= howmany(p_lptr
->num_blocks
,
1378 lptr
->modulo
= p_lptr
->num_blocks
% lptr
->num_blocks
;
1379 lptr
->num_recs_pb
= p_lptr
->num_blocks
1381 lptr
->num_recs_tot
= p_lptr
->num_blocks
;
1383 blocks_allocated
+= lptr
->num_blocks
;
1386 ASSERT(lptr
->num_blocks
== 1);
1387 btree_curs
->num_levels
= level
;
1389 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
1392 setup_cursor(mp
, agno
, btree_curs
);
1397 struct xfs_mount
*mp
,
1398 xfs_agnumber_t agno
,
1399 struct bt_status
*btree_curs
,
1400 struct xfs_rmap_irec
*rm_rec
,
1403 struct xfs_btree_block
*bt_hdr
;
1404 struct xfs_rmap_key
*bt_key
;
1405 xfs_rmap_ptr_t
*bt_ptr
;
1406 xfs_agblock_t agbno
;
1407 struct bt_stat_level
*lptr
;
1411 if (level
>= btree_curs
->num_levels
)
1414 lptr
= &btree_curs
->level
[level
];
1415 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1417 if (be16_to_cpu(bt_hdr
->bb_numrecs
) == 0) {
1419 * this only happens once to initialize the
1420 * first path up the left side of the tree
1421 * where the agbno's are already set up
1423 prop_rmap_cursor(mp
, agno
, btree_curs
, rm_rec
, level
);
1426 if (be16_to_cpu(bt_hdr
->bb_numrecs
) ==
1427 lptr
->num_recs_pb
+ (lptr
->modulo
> 0)) {
1429 * write out current prev block, grab us a new block,
1430 * and set the rightsib pointer of current block
1432 #ifdef XR_BLD_INO_TRACE
1433 fprintf(stderr
, " rmap prop agbno %d ", lptr
->prev_agbno
);
1435 if (lptr
->prev_agbno
!= NULLAGBLOCK
) {
1436 ASSERT(lptr
->prev_buf_p
!= NULL
);
1437 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1439 lptr
->prev_agbno
= lptr
->agbno
;
1440 lptr
->prev_buf_p
= lptr
->buf_p
;
1441 agbno
= get_next_blockaddr(agno
, level
, btree_curs
);
1443 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(agbno
);
1445 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1446 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1447 XFS_FSB_TO_BB(mp
, 1));
1448 lptr
->agbno
= agbno
;
1454 * initialize block header
1456 lptr
->buf_p
->b_ops
= &xfs_rmapbt_buf_ops
;
1457 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1458 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1459 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_RMAP
,
1462 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1465 * propagate extent record for first extent in new block up
1467 prop_rmap_cursor(mp
, agno
, btree_curs
, rm_rec
, level
);
1470 * add rmap info to current block
1472 be16_add_cpu(&bt_hdr
->bb_numrecs
, 1);
1474 bt_key
= XFS_RMAP_KEY_ADDR(bt_hdr
,
1475 be16_to_cpu(bt_hdr
->bb_numrecs
));
1476 bt_ptr
= XFS_RMAP_PTR_ADDR(bt_hdr
,
1477 be16_to_cpu(bt_hdr
->bb_numrecs
),
1480 bt_key
->rm_startblock
= cpu_to_be32(rm_rec
->rm_startblock
);
1481 bt_key
->rm_owner
= cpu_to_be64(rm_rec
->rm_owner
);
1482 bt_key
->rm_offset
= cpu_to_be64(rm_rec
->rm_offset
);
1484 *bt_ptr
= cpu_to_be32(btree_curs
->level
[level
-1].agbno
);
1489 struct xfs_mount
*mp
,
1490 xfs_agnumber_t agno
,
1491 struct bt_status
*btree_curs
,
1492 struct xfs_rmap_irec
*rm_highkey
)
1494 struct xfs_btree_block
*bt_hdr
;
1495 struct xfs_rmap_key
*bt_key
;
1496 struct bt_stat_level
*lptr
;
1497 struct xfs_rmap_irec key
= {0};
1498 struct xfs_rmap_irec high_key
;
1503 high_key
= *rm_highkey
;
1504 for (level
= 1; level
< btree_curs
->num_levels
; level
++) {
1505 lptr
= &btree_curs
->level
[level
];
1506 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1507 numrecs
= be16_to_cpu(bt_hdr
->bb_numrecs
);
1508 bt_key
= XFS_RMAP_HIGH_KEY_ADDR(bt_hdr
, numrecs
);
1510 bt_key
->rm_startblock
= cpu_to_be32(high_key
.rm_startblock
);
1511 bt_key
->rm_owner
= cpu_to_be64(high_key
.rm_owner
);
1512 bt_key
->rm_offset
= cpu_to_be64(
1513 libxfs_rmap_irec_offset_pack(&high_key
));
1515 for (i
= 1; i
< numrecs
- 1; i
++) {
1516 bt_key
= XFS_RMAP_HIGH_KEY_ADDR(bt_hdr
, i
);
1517 key
.rm_startblock
= be32_to_cpu(bt_key
->rm_startblock
);
1518 key
.rm_owner
= be64_to_cpu(bt_key
->rm_owner
);
1519 key
.rm_offset
= be64_to_cpu(bt_key
->rm_offset
);
1520 if (rmap_diffkeys(&key
, &high_key
) > 0)
1527 * rebuilds a rmap btree given a cursor.
1531 struct xfs_mount
*mp
,
1532 xfs_agnumber_t agno
,
1533 struct bt_status
*btree_curs
)
1537 xfs_agblock_t agbno
;
1538 struct xfs_btree_block
*bt_hdr
;
1539 struct xfs_rmap_irec
*rm_rec
;
1540 struct xfs_slab_cursor
*rmap_cur
;
1541 struct xfs_rmap_rec
*bt_rec
;
1542 struct xfs_rmap_irec highest_key
= {0};
1543 struct xfs_rmap_irec hi_key
= {0};
1544 struct bt_stat_level
*lptr
;
1546 int level
= btree_curs
->num_levels
;
1549 highest_key
.rm_flags
= 0;
1550 for (i
= 0; i
< level
; i
++) {
1551 lptr
= &btree_curs
->level
[i
];
1553 agbno
= get_next_blockaddr(agno
, i
, btree_curs
);
1554 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1555 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1556 XFS_FSB_TO_BB(mp
, 1));
1558 if (i
== btree_curs
->num_levels
- 1)
1559 btree_curs
->root
= agbno
;
1561 lptr
->agbno
= agbno
;
1562 lptr
->prev_agbno
= NULLAGBLOCK
;
1563 lptr
->prev_buf_p
= NULL
;
1565 * initialize block header
1568 lptr
->buf_p
->b_ops
= &xfs_rmapbt_buf_ops
;
1569 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1570 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1571 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_RMAP
,
1576 * run along leaf, setting up records. as we have to switch
1577 * blocks, call the prop_rmap_cursor routine to set up the new
1578 * pointers for the parent. that can recurse up to the root
1579 * if required. set the sibling pointers for leaf level here.
1581 error
= rmap_init_cursor(agno
, &rmap_cur
);
1584 _("Insufficient memory to construct reverse-map cursor."));
1585 rm_rec
= pop_slab_cursor(rmap_cur
);
1586 lptr
= &btree_curs
->level
[0];
1588 for (i
= 0; i
< lptr
->num_blocks
; i
++) {
1589 numrecs
= lptr
->num_recs_pb
+ (lptr
->modulo
> 0);
1590 ASSERT(rm_rec
!= NULL
|| numrecs
== 0);
1593 * block initialization, lay in block header
1595 lptr
->buf_p
->b_ops
= &xfs_rmapbt_buf_ops
;
1596 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1597 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1598 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_RMAP
,
1601 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1602 bt_hdr
->bb_numrecs
= cpu_to_be16(numrecs
);
1604 if (lptr
->modulo
> 0)
1607 if (lptr
->num_recs_pb
> 0) {
1608 ASSERT(rm_rec
!= NULL
);
1609 prop_rmap_cursor(mp
, agno
, btree_curs
, rm_rec
, 0);
1612 bt_rec
= (struct xfs_rmap_rec
*)
1613 ((char *)bt_hdr
+ XFS_RMAP_BLOCK_LEN
);
1614 highest_key
.rm_startblock
= 0;
1615 highest_key
.rm_owner
= 0;
1616 highest_key
.rm_offset
= 0;
1617 for (j
= 0; j
< be16_to_cpu(bt_hdr
->bb_numrecs
); j
++) {
1618 ASSERT(rm_rec
!= NULL
);
1619 bt_rec
[j
].rm_startblock
=
1620 cpu_to_be32(rm_rec
->rm_startblock
);
1621 bt_rec
[j
].rm_blockcount
=
1622 cpu_to_be32(rm_rec
->rm_blockcount
);
1623 bt_rec
[j
].rm_owner
= cpu_to_be64(rm_rec
->rm_owner
);
1624 bt_rec
[j
].rm_offset
= cpu_to_be64(
1625 libxfs_rmap_irec_offset_pack(rm_rec
));
1626 rmap_high_key_from_rec(rm_rec
, &hi_key
);
1627 if (rmap_diffkeys(&hi_key
, &highest_key
) > 0)
1628 highest_key
= hi_key
;
1630 rm_rec
= pop_slab_cursor(rmap_cur
);
1633 /* Now go set the parent key */
1634 prop_rmap_highkey(mp
, agno
, btree_curs
, &highest_key
);
1636 if (rm_rec
!= NULL
) {
1638 * get next leaf level block
1640 if (lptr
->prev_buf_p
!= NULL
) {
1641 #ifdef XR_BLD_RL_TRACE
1642 fprintf(stderr
, "writing rmapbt agbno %u\n",
1645 ASSERT(lptr
->prev_agbno
!= NULLAGBLOCK
);
1646 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1648 lptr
->prev_buf_p
= lptr
->buf_p
;
1649 lptr
->prev_agbno
= lptr
->agbno
;
1650 lptr
->agbno
= get_next_blockaddr(agno
, 0, btree_curs
);
1651 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(lptr
->agbno
);
1653 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1654 XFS_AGB_TO_DADDR(mp
, agno
, lptr
->agbno
),
1655 XFS_FSB_TO_BB(mp
, 1));
1658 free_slab_cursor(&rmap_cur
);
1661 /* rebuild the refcount tree */
1664 * we don't have to worry here about how chewing up free extents
1665 * may perturb things because reflink tree building happens before
1666 * freespace tree building.
1670 struct xfs_mount
*mp
,
1671 xfs_agnumber_t agno
,
1672 struct bt_status
*btree_curs
)
1676 struct bt_stat_level
*lptr
;
1677 struct bt_stat_level
*p_lptr
;
1678 xfs_extlen_t blocks_allocated
;
1680 if (!xfs_sb_version_hasreflink(&mp
->m_sb
)) {
1681 memset(btree_curs
, 0, sizeof(struct bt_status
));
1685 lptr
= &btree_curs
->level
[0];
1686 btree_curs
->init
= 1;
1687 btree_curs
->owner
= XFS_RMAP_OWN_REFC
;
1690 * build up statistics
1692 num_recs
= refcount_record_count(mp
, agno
);
1693 if (num_recs
== 0) {
1695 * easy corner-case -- no refcount records
1697 lptr
->num_blocks
= 1;
1699 lptr
->num_recs_pb
= 0;
1700 lptr
->num_recs_tot
= 0;
1702 btree_curs
->num_levels
= 1;
1703 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
= 1;
1705 setup_cursor(mp
, agno
, btree_curs
);
1710 blocks_allocated
= lptr
->num_blocks
= howmany(num_recs
,
1713 lptr
->modulo
= num_recs
% lptr
->num_blocks
;
1714 lptr
->num_recs_pb
= num_recs
/ lptr
->num_blocks
;
1715 lptr
->num_recs_tot
= num_recs
;
1718 if (lptr
->num_blocks
> 1) {
1719 for (; btree_curs
->level
[level
-1].num_blocks
> 1
1720 && level
< XFS_BTREE_MAXLEVELS
;
1722 lptr
= &btree_curs
->level
[level
];
1723 p_lptr
= &btree_curs
->level
[level
- 1];
1724 lptr
->num_blocks
= howmany(p_lptr
->num_blocks
,
1726 lptr
->modulo
= p_lptr
->num_blocks
% lptr
->num_blocks
;
1727 lptr
->num_recs_pb
= p_lptr
->num_blocks
1729 lptr
->num_recs_tot
= p_lptr
->num_blocks
;
1731 blocks_allocated
+= lptr
->num_blocks
;
1734 ASSERT(lptr
->num_blocks
== 1);
1735 btree_curs
->num_levels
= level
;
1737 btree_curs
->num_tot_blocks
= btree_curs
->num_free_blocks
1740 setup_cursor(mp
, agno
, btree_curs
);
1745 struct xfs_mount
*mp
,
1746 xfs_agnumber_t agno
,
1747 struct bt_status
*btree_curs
,
1748 xfs_agblock_t startbno
,
1751 struct xfs_btree_block
*bt_hdr
;
1752 struct xfs_refcount_key
*bt_key
;
1753 xfs_refcount_ptr_t
*bt_ptr
;
1754 xfs_agblock_t agbno
;
1755 struct bt_stat_level
*lptr
;
1759 if (level
>= btree_curs
->num_levels
)
1762 lptr
= &btree_curs
->level
[level
];
1763 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1765 if (be16_to_cpu(bt_hdr
->bb_numrecs
) == 0) {
1767 * this only happens once to initialize the
1768 * first path up the left side of the tree
1769 * where the agbno's are already set up
1771 prop_refc_cursor(mp
, agno
, btree_curs
, startbno
, level
);
1774 if (be16_to_cpu(bt_hdr
->bb_numrecs
) ==
1775 lptr
->num_recs_pb
+ (lptr
->modulo
> 0)) {
1777 * write out current prev block, grab us a new block,
1778 * and set the rightsib pointer of current block
1780 #ifdef XR_BLD_INO_TRACE
1781 fprintf(stderr
, " ino prop agbno %d ", lptr
->prev_agbno
);
1783 if (lptr
->prev_agbno
!= NULLAGBLOCK
) {
1784 ASSERT(lptr
->prev_buf_p
!= NULL
);
1785 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1787 lptr
->prev_agbno
= lptr
->agbno
;
1788 lptr
->prev_buf_p
= lptr
->buf_p
;
1789 agbno
= get_next_blockaddr(agno
, level
, btree_curs
);
1791 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(agbno
);
1793 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1794 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1795 XFS_FSB_TO_BB(mp
, 1));
1796 lptr
->agbno
= agbno
;
1802 * initialize block header
1804 lptr
->buf_p
->b_ops
= &xfs_refcountbt_buf_ops
;
1805 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1806 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1807 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_REFC
,
1810 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1813 * propagate extent record for first extent in new block up
1815 prop_refc_cursor(mp
, agno
, btree_curs
, startbno
, level
);
1818 * add inode info to current block
1820 be16_add_cpu(&bt_hdr
->bb_numrecs
, 1);
1822 bt_key
= XFS_REFCOUNT_KEY_ADDR(bt_hdr
,
1823 be16_to_cpu(bt_hdr
->bb_numrecs
));
1824 bt_ptr
= XFS_REFCOUNT_PTR_ADDR(bt_hdr
,
1825 be16_to_cpu(bt_hdr
->bb_numrecs
),
1828 bt_key
->rc_startblock
= cpu_to_be32(startbno
);
1829 *bt_ptr
= cpu_to_be32(btree_curs
->level
[level
-1].agbno
);
1833 * rebuilds a refcount btree given a cursor.
1836 build_refcount_tree(
1837 struct xfs_mount
*mp
,
1838 xfs_agnumber_t agno
,
1839 struct bt_status
*btree_curs
)
1843 xfs_agblock_t agbno
;
1844 struct xfs_btree_block
*bt_hdr
;
1845 struct xfs_refcount_irec
*refc_rec
;
1846 struct xfs_slab_cursor
*refc_cur
;
1847 struct xfs_refcount_rec
*bt_rec
;
1848 struct bt_stat_level
*lptr
;
1850 int level
= btree_curs
->num_levels
;
1853 for (i
= 0; i
< level
; i
++) {
1854 lptr
= &btree_curs
->level
[i
];
1856 agbno
= get_next_blockaddr(agno
, i
, btree_curs
);
1857 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1858 XFS_AGB_TO_DADDR(mp
, agno
, agbno
),
1859 XFS_FSB_TO_BB(mp
, 1));
1861 if (i
== btree_curs
->num_levels
- 1)
1862 btree_curs
->root
= agbno
;
1864 lptr
->agbno
= agbno
;
1865 lptr
->prev_agbno
= NULLAGBLOCK
;
1866 lptr
->prev_buf_p
= NULL
;
1868 * initialize block header
1871 lptr
->buf_p
->b_ops
= &xfs_refcountbt_buf_ops
;
1872 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1873 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1874 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_REFC
,
1879 * run along leaf, setting up records. as we have to switch
1880 * blocks, call the prop_refc_cursor routine to set up the new
1881 * pointers for the parent. that can recurse up to the root
1882 * if required. set the sibling pointers for leaf level here.
1884 error
= init_refcount_cursor(agno
, &refc_cur
);
1887 _("Insufficient memory to construct refcount cursor."));
1888 refc_rec
= pop_slab_cursor(refc_cur
);
1889 lptr
= &btree_curs
->level
[0];
1891 for (i
= 0; i
< lptr
->num_blocks
; i
++) {
1892 numrecs
= lptr
->num_recs_pb
+ (lptr
->modulo
> 0);
1893 ASSERT(refc_rec
!= NULL
|| numrecs
== 0);
1896 * block initialization, lay in block header
1898 lptr
->buf_p
->b_ops
= &xfs_refcountbt_buf_ops
;
1899 bt_hdr
= XFS_BUF_TO_BLOCK(lptr
->buf_p
);
1900 memset(bt_hdr
, 0, mp
->m_sb
.sb_blocksize
);
1901 libxfs_btree_init_block(mp
, lptr
->buf_p
, XFS_BTNUM_REFC
,
1904 bt_hdr
->bb_u
.s
.bb_leftsib
= cpu_to_be32(lptr
->prev_agbno
);
1905 bt_hdr
->bb_numrecs
= cpu_to_be16(numrecs
);
1907 if (lptr
->modulo
> 0)
1910 if (lptr
->num_recs_pb
> 0)
1911 prop_refc_cursor(mp
, agno
, btree_curs
,
1912 refc_rec
->rc_startblock
, 0);
1914 bt_rec
= (struct xfs_refcount_rec
*)
1915 ((char *)bt_hdr
+ XFS_REFCOUNT_BLOCK_LEN
);
1916 for (j
= 0; j
< be16_to_cpu(bt_hdr
->bb_numrecs
); j
++) {
1917 ASSERT(refc_rec
!= NULL
);
1918 bt_rec
[j
].rc_startblock
=
1919 cpu_to_be32(refc_rec
->rc_startblock
);
1920 bt_rec
[j
].rc_blockcount
=
1921 cpu_to_be32(refc_rec
->rc_blockcount
);
1922 bt_rec
[j
].rc_refcount
= cpu_to_be32(refc_rec
->rc_refcount
);
1924 refc_rec
= pop_slab_cursor(refc_cur
);
1927 if (refc_rec
!= NULL
) {
1929 * get next leaf level block
1931 if (lptr
->prev_buf_p
!= NULL
) {
1932 #ifdef XR_BLD_RL_TRACE
1933 fprintf(stderr
, "writing refcntbt agbno %u\n",
1936 ASSERT(lptr
->prev_agbno
!= NULLAGBLOCK
);
1937 libxfs_writebuf(lptr
->prev_buf_p
, 0);
1939 lptr
->prev_buf_p
= lptr
->buf_p
;
1940 lptr
->prev_agbno
= lptr
->agbno
;
1941 lptr
->agbno
= get_next_blockaddr(agno
, 0, btree_curs
);
1942 bt_hdr
->bb_u
.s
.bb_rightsib
= cpu_to_be32(lptr
->agbno
);
1944 lptr
->buf_p
= libxfs_getbuf(mp
->m_dev
,
1945 XFS_AGB_TO_DADDR(mp
, agno
, lptr
->agbno
),
1946 XFS_FSB_TO_BB(mp
, 1));
1949 free_slab_cursor(&refc_cur
);
1953 * build both the agf and the agfl for an agno given both
1956 * XXX: yet more common code that can be shared with mkfs/growfs.
1960 struct xfs_mount
*mp
,
1961 xfs_agnumber_t agno
,
1962 struct bt_status
*bno_bt
,
1963 struct bt_status
*bcnt_bt
,
1964 xfs_extlen_t freeblks
, /* # free blocks in tree */
1965 int lostblocks
, /* # blocks that will be lost */
1966 struct bt_status
*rmap_bt
,
1967 struct bt_status
*refcnt_bt
,
1968 struct xfs_slab
*lost_fsb
)
1970 struct extent_tree_node
*ext_ptr
;
1971 struct xfs_buf
*agf_buf
, *agfl_buf
;
1973 struct xfs_agfl
*agfl
;
1974 struct xfs_agf
*agf
;
1979 agf_buf
= libxfs_getbuf(mp
->m_dev
,
1980 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
1981 mp
->m_sb
.sb_sectsize
/BBSIZE
);
1982 agf_buf
->b_ops
= &xfs_agf_buf_ops
;
1983 agf
= XFS_BUF_TO_AGF(agf_buf
);
1984 memset(agf
, 0, mp
->m_sb
.sb_sectsize
);
1986 #ifdef XR_BLD_FREE_TRACE
1987 fprintf(stderr
, "agf = %p, agf_buf->b_addr = %p\n",
1988 agf
, agf_buf
->b_addr
);
1992 * set up fixed part of agf
1994 agf
->agf_magicnum
= cpu_to_be32(XFS_AGF_MAGIC
);
1995 agf
->agf_versionnum
= cpu_to_be32(XFS_AGF_VERSION
);
1996 agf
->agf_seqno
= cpu_to_be32(agno
);
1998 if (agno
< mp
->m_sb
.sb_agcount
- 1)
1999 agf
->agf_length
= cpu_to_be32(mp
->m_sb
.sb_agblocks
);
2001 agf
->agf_length
= cpu_to_be32(mp
->m_sb
.sb_dblocks
-
2002 (xfs_rfsblock_t
) mp
->m_sb
.sb_agblocks
* agno
);
2004 agf
->agf_roots
[XFS_BTNUM_BNO
] = cpu_to_be32(bno_bt
->root
);
2005 agf
->agf_levels
[XFS_BTNUM_BNO
] = cpu_to_be32(bno_bt
->num_levels
);
2006 agf
->agf_roots
[XFS_BTNUM_CNT
] = cpu_to_be32(bcnt_bt
->root
);
2007 agf
->agf_levels
[XFS_BTNUM_CNT
] = cpu_to_be32(bcnt_bt
->num_levels
);
2008 agf
->agf_roots
[XFS_BTNUM_RMAP
] = cpu_to_be32(rmap_bt
->root
);
2009 agf
->agf_levels
[XFS_BTNUM_RMAP
] = cpu_to_be32(rmap_bt
->num_levels
);
2010 agf
->agf_freeblks
= cpu_to_be32(freeblks
);
2011 agf
->agf_rmap_blocks
= cpu_to_be32(rmap_bt
->num_tot_blocks
-
2012 rmap_bt
->num_free_blocks
);
2013 agf
->agf_refcount_root
= cpu_to_be32(refcnt_bt
->root
);
2014 agf
->agf_refcount_level
= cpu_to_be32(refcnt_bt
->num_levels
);
2015 agf
->agf_refcount_blocks
= cpu_to_be32(refcnt_bt
->num_tot_blocks
-
2016 refcnt_bt
->num_free_blocks
);
2019 * Count and record the number of btree blocks consumed if required.
2021 if (xfs_sb_version_haslazysbcount(&mp
->m_sb
)) {
2024 * Don't count the root blocks as they are already
2027 blks
= (bno_bt
->num_tot_blocks
- bno_bt
->num_free_blocks
) +
2028 (bcnt_bt
->num_tot_blocks
- bcnt_bt
->num_free_blocks
) -
2030 if (xfs_sb_version_hasrmapbt(&mp
->m_sb
))
2031 blks
+= rmap_bt
->num_tot_blocks
- rmap_bt
->num_free_blocks
- 1;
2032 agf
->agf_btreeblks
= cpu_to_be32(blks
);
2033 #ifdef XR_BLD_FREE_TRACE
2034 fprintf(stderr
, "agf->agf_btreeblks = %u\n",
2035 be32_to_cpu(agf
->agf_btreeblks
));
2039 #ifdef XR_BLD_FREE_TRACE
2040 fprintf(stderr
, "bno root = %u, bcnt root = %u, indices = %u %u\n",
2041 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNO
]),
2042 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNT
]),
2047 if (xfs_sb_version_hascrc(&mp
->m_sb
))
2048 platform_uuid_copy(&agf
->agf_uuid
, &mp
->m_sb
.sb_meta_uuid
);
2050 /* initialise the AGFL, then fill it if there are blocks left over. */
2051 agfl_buf
= libxfs_getbuf(mp
->m_dev
,
2052 XFS_AG_DADDR(mp
, agno
, XFS_AGFL_DADDR(mp
)),
2053 mp
->m_sb
.sb_sectsize
/BBSIZE
);
2054 agfl_buf
->b_ops
= &xfs_agfl_buf_ops
;
2055 agfl
= XFS_BUF_TO_AGFL(agfl_buf
);
2057 /* setting to 0xff results in initialisation to NULLAGBLOCK */
2058 memset(agfl
, 0xff, mp
->m_sb
.sb_sectsize
);
2059 if (xfs_sb_version_hascrc(&mp
->m_sb
)) {
2060 agfl
->agfl_magicnum
= cpu_to_be32(XFS_AGFL_MAGIC
);
2061 agfl
->agfl_seqno
= cpu_to_be32(agno
);
2062 platform_uuid_copy(&agfl
->agfl_uuid
, &mp
->m_sb
.sb_meta_uuid
);
2063 for (i
= 0; i
< libxfs_agfl_size(mp
); i
++)
2064 agfl
->agfl_bno
[i
] = cpu_to_be32(NULLAGBLOCK
);
2066 freelist
= XFS_BUF_TO_AGFL_BNO(mp
, agfl_buf
);
2069 * do we have left-over blocks in the btree cursors that should
2070 * be used to fill the AGFL?
2072 if (bno_bt
->num_free_blocks
> 0 || bcnt_bt
->num_free_blocks
> 0) {
2074 * yes, now grab as many blocks as we can
2077 while (bno_bt
->num_free_blocks
> 0 && i
< libxfs_agfl_size(mp
))
2079 freelist
[i
] = cpu_to_be32(
2080 get_next_blockaddr(agno
, 0, bno_bt
));
2084 while (bcnt_bt
->num_free_blocks
> 0 && i
< libxfs_agfl_size(mp
))
2086 freelist
[i
] = cpu_to_be32(
2087 get_next_blockaddr(agno
, 0, bcnt_bt
));
2091 * now throw the rest of the blocks away and complain
2093 while (bno_bt
->num_free_blocks
> 0) {
2094 fsb
= XFS_AGB_TO_FSB(mp
, agno
,
2095 get_next_blockaddr(agno
, 0, bno_bt
));
2096 error
= slab_add(lost_fsb
, &fsb
);
2099 _("Insufficient memory saving lost blocks.\n"));
2101 while (bcnt_bt
->num_free_blocks
> 0) {
2102 fsb
= XFS_AGB_TO_FSB(mp
, agno
,
2103 get_next_blockaddr(agno
, 0, bcnt_bt
));
2104 error
= slab_add(lost_fsb
, &fsb
);
2107 _("Insufficient memory saving lost blocks.\n"));
2110 agf
->agf_flfirst
= 0;
2111 agf
->agf_fllast
= cpu_to_be32(i
- 1);
2112 agf
->agf_flcount
= cpu_to_be32(i
);
2113 rmap_store_agflcount(mp
, agno
, i
);
2115 #ifdef XR_BLD_FREE_TRACE
2116 fprintf(stderr
, "writing agfl for ag %u\n", agno
);
2120 agf
->agf_flfirst
= 0;
2121 agf
->agf_fllast
= cpu_to_be32(libxfs_agfl_size(mp
) - 1);
2122 agf
->agf_flcount
= 0;
2125 libxfs_writebuf(agfl_buf
, 0);
2127 ext_ptr
= findbiggest_bcnt_extent(agno
);
2128 agf
->agf_longest
= cpu_to_be32((ext_ptr
!= NULL
) ?
2129 ext_ptr
->ex_blockcount
: 0);
2131 ASSERT(be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNOi
]) !=
2132 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNTi
]));
2133 ASSERT(be32_to_cpu(agf
->agf_refcount_root
) !=
2134 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_BNOi
]));
2135 ASSERT(be32_to_cpu(agf
->agf_refcount_root
) !=
2136 be32_to_cpu(agf
->agf_roots
[XFS_BTNUM_CNTi
]));
2138 libxfs_writebuf(agf_buf
, 0);
2141 * now fix up the free list appropriately
2143 fix_freelist(mp
, agno
, true);
2145 #ifdef XR_BLD_FREE_TRACE
2146 fprintf(stderr
, "wrote agf for ag %u\n", agno
);
2151 * update the superblock counters, sync the sb version numbers and
2152 * feature bits to the filesystem, and sync up the on-disk superblock
2153 * to match the incore superblock.
2156 sync_sb(xfs_mount_t
*mp
)
2160 bp
= libxfs_getsb(mp
, 0);
2162 do_error(_("couldn't get superblock\n"));
2164 mp
->m_sb
.sb_icount
= sb_icount
;
2165 mp
->m_sb
.sb_ifree
= sb_ifree
;
2166 mp
->m_sb
.sb_fdblocks
= sb_fdblocks
;
2167 mp
->m_sb
.sb_frextents
= sb_frextents
;
2169 update_sb_version(mp
);
2171 libxfs_sb_to_disk(XFS_BUF_TO_SBP(bp
), &mp
->m_sb
);
2172 libxfs_writebuf(bp
, 0);
2176 * make sure the root and realtime inodes show up allocated
2177 * even if they've been freed. they get reinitialized in phase6.
2180 keep_fsinos(xfs_mount_t
*mp
)
2182 ino_tree_node_t
*irec
;
2185 irec
= find_inode_rec(mp
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
),
2186 XFS_INO_TO_AGINO(mp
, mp
->m_sb
.sb_rootino
));
2188 for (i
= 0; i
< 3; i
++)
2189 set_inode_used(irec
, i
);
2195 xfs_agnumber_t agno
,
2196 struct xfs_slab
*lost_fsb
)
2199 uint64_t num_free_inos
;
2200 uint64_t finobt_num_inos
;
2201 uint64_t finobt_num_free_inos
;
2202 bt_status_t bno_btree_curs
;
2203 bt_status_t bcnt_btree_curs
;
2204 bt_status_t ino_btree_curs
;
2205 bt_status_t fino_btree_curs
;
2206 bt_status_t rmap_btree_curs
;
2207 bt_status_t refcnt_btree_curs
;
2208 int extra_blocks
= 0;
2209 uint num_freeblocks
;
2210 xfs_extlen_t freeblks1
;
2212 xfs_extlen_t freeblks2
;
2214 xfs_agblock_t num_extents
;
2215 struct agi_stat agi_stat
= {0,};
2219 do_log(_(" - agno = %d\n"), agno
);
2223 * build up incore bno and bcnt extent btrees
2225 num_extents
= mk_incore_fstree(mp
, agno
);
2227 #ifdef XR_BLD_FREE_TRACE
2228 fprintf(stderr
, "# of bno extents is %d\n",
2229 count_bno_extents(agno
));
2232 if (num_extents
== 0) {
2234 * XXX - what we probably should do here is pick an
2235 * inode for a regular file in the allocation group
2236 * that has space allocated and shoot it by traversing
2237 * the bmap list and putting all its extents on the
2238 * incore freespace trees, clearing the inode,
2239 * and clearing the in-use bit in the incore inode
2240 * tree. Then try mk_incore_fstree() again.
2242 do_error(_("unable to rebuild AG %u. "
2243 "Not enough free space in on-disk AG.\n"),
2248 * ok, now set up the btree cursors for the
2249 * on-disk btrees (includs pre-allocating all
2250 * required blocks for the trees themselves)
2252 init_ino_cursor(mp
, agno
, &ino_btree_curs
, &num_inos
,
2255 if (xfs_sb_version_hasfinobt(&mp
->m_sb
))
2256 init_ino_cursor(mp
, agno
, &fino_btree_curs
,
2257 &finobt_num_inos
, &finobt_num_free_inos
,
2260 sb_icount_ag
[agno
] += num_inos
;
2261 sb_ifree_ag
[agno
] += num_free_inos
;
2264 * Set up the btree cursors for the on-disk rmap btrees,
2265 * which includes pre-allocating all required blocks.
2267 init_rmapbt_cursor(mp
, agno
, &rmap_btree_curs
);
2270 * Set up the btree cursors for the on-disk refcount btrees,
2271 * which includes pre-allocating all required blocks.
2273 init_refc_cursor(mp
, agno
, &refcnt_btree_curs
);
2275 num_extents
= count_bno_extents_blocks(agno
, &num_freeblocks
);
2277 * lose two blocks per AG -- the space tree roots
2278 * are counted as allocated since the space trees
2281 sb_fdblocks_ag
[agno
] += num_freeblocks
- 2;
2283 if (num_extents
== 0) {
2285 * XXX - what we probably should do here is pick an
2286 * inode for a regular file in the allocation group
2287 * that has space allocated and shoot it by traversing
2288 * the bmap list and putting all its extents on the
2289 * incore freespace trees, clearing the inode,
2290 * and clearing the in-use bit in the incore inode
2291 * tree. Then try mk_incore_fstree() again.
2294 _("unable to rebuild AG %u. No free space.\n"), agno
);
2297 #ifdef XR_BLD_FREE_TRACE
2298 fprintf(stderr
, "# of bno extents is %d\n", num_extents
);
2302 * track blocks that we might really lose
2304 extra_blocks
= calculate_freespace_cursor(mp
, agno
,
2305 &num_extents
, &bno_btree_curs
);
2308 * freespace btrees live in the "free space" but
2309 * the filesystem treats AGFL blocks as allocated
2310 * since they aren't described by the freespace trees
2314 * see if we can fit all the extra blocks into the AGFL
2316 extra_blocks
= (extra_blocks
- libxfs_agfl_size(mp
) > 0)
2317 ? extra_blocks
- libxfs_agfl_size(mp
)
2320 if (extra_blocks
> 0)
2321 sb_fdblocks_ag
[agno
] -= extra_blocks
;
2323 bcnt_btree_curs
= bno_btree_curs
;
2325 bno_btree_curs
.owner
= XFS_RMAP_OWN_AG
;
2326 bcnt_btree_curs
.owner
= XFS_RMAP_OWN_AG
;
2327 setup_cursor(mp
, agno
, &bno_btree_curs
);
2328 setup_cursor(mp
, agno
, &bcnt_btree_curs
);
2330 #ifdef XR_BLD_FREE_TRACE
2331 fprintf(stderr
, "# of bno extents is %d\n",
2332 count_bno_extents(agno
));
2333 fprintf(stderr
, "# of bcnt extents is %d\n",
2334 count_bcnt_extents(agno
));
2338 * now rebuild the freespace trees
2340 freeblks1
= build_freespace_tree(mp
, agno
,
2341 &bno_btree_curs
, XFS_BTNUM_BNO
);
2342 #ifdef XR_BLD_FREE_TRACE
2343 fprintf(stderr
, "# of free blocks == %d\n", freeblks1
);
2345 write_cursor(&bno_btree_curs
);
2348 freeblks2
= build_freespace_tree(mp
, agno
,
2349 &bcnt_btree_curs
, XFS_BTNUM_CNT
);
2351 (void) build_freespace_tree(mp
, agno
,
2352 &bcnt_btree_curs
, XFS_BTNUM_CNT
);
2354 write_cursor(&bcnt_btree_curs
);
2356 ASSERT(freeblks1
== freeblks2
);
2358 if (xfs_sb_version_hasrmapbt(&mp
->m_sb
)) {
2359 build_rmap_tree(mp
, agno
, &rmap_btree_curs
);
2360 write_cursor(&rmap_btree_curs
);
2361 sb_fdblocks_ag
[agno
] += (rmap_btree_curs
.num_tot_blocks
-
2362 rmap_btree_curs
.num_free_blocks
) - 1;
2365 if (xfs_sb_version_hasreflink(&mp
->m_sb
)) {
2366 build_refcount_tree(mp
, agno
, &refcnt_btree_curs
);
2367 write_cursor(&refcnt_btree_curs
);
2371 * set up agf and agfl
2373 build_agf_agfl(mp
, agno
, &bno_btree_curs
,
2374 &bcnt_btree_curs
, freeblks1
, extra_blocks
,
2375 &rmap_btree_curs
, &refcnt_btree_curs
, lost_fsb
);
2377 * build inode allocation tree.
2379 build_ino_tree(mp
, agno
, &ino_btree_curs
, XFS_BTNUM_INO
,
2381 write_cursor(&ino_btree_curs
);
2384 * build free inode tree
2386 if (xfs_sb_version_hasfinobt(&mp
->m_sb
)) {
2387 build_ino_tree(mp
, agno
, &fino_btree_curs
,
2388 XFS_BTNUM_FINO
, NULL
);
2389 write_cursor(&fino_btree_curs
);
2393 build_agi(mp
, agno
, &ino_btree_curs
, &fino_btree_curs
,
2399 finish_cursor(&bno_btree_curs
);
2400 finish_cursor(&ino_btree_curs
);
2401 if (xfs_sb_version_hasrmapbt(&mp
->m_sb
))
2402 finish_cursor(&rmap_btree_curs
);
2403 if (xfs_sb_version_hasreflink(&mp
->m_sb
))
2404 finish_cursor(&refcnt_btree_curs
);
2405 if (xfs_sb_version_hasfinobt(&mp
->m_sb
))
2406 finish_cursor(&fino_btree_curs
);
2407 finish_cursor(&bcnt_btree_curs
);
2410 * Put the per-AG btree rmap data into the rmapbt
2412 error
= rmap_store_ag_btree_rec(mp
, agno
);
2415 _("unable to add AG %u reverse-mapping data to btree.\n"), agno
);
2418 * release the incore per-AG bno/bcnt trees so
2419 * the extent nodes can be recycled
2421 release_agbno_extent_tree(agno
);
2422 release_agbcnt_extent_tree(agno
);
2424 PROG_RPT_INC(prog_rpt_done
[agno
], 1);
2427 /* Inject lost blocks back into the filesystem. */
2430 struct xfs_mount
*mp
,
2431 struct xfs_slab
*lost_fsbs
)
2433 struct xfs_trans
*tp
= NULL
;
2434 struct xfs_slab_cursor
*cur
= NULL
;
2436 struct xfs_trans_res tres
= {0};
2437 struct xfs_owner_info oinfo
;
2440 libxfs_rmap_ag_owner(&oinfo
, XFS_RMAP_OWN_AG
);
2441 error
= init_slab_cursor(lost_fsbs
, NULL
, &cur
);
2445 while ((fsb
= pop_slab_cursor(cur
)) != NULL
) {
2446 error
= -libxfs_trans_alloc(mp
, &tres
, 16, 0, 0, &tp
);
2450 error
= -libxfs_free_extent(tp
, *fsb
, 1, &oinfo
,
2455 error
= -libxfs_trans_commit(tp
);
2463 libxfs_trans_cancel(tp
);
2464 free_slab_cursor(&cur
);
2469 phase5(xfs_mount_t
*mp
)
2471 struct xfs_slab
*lost_fsb
;
2472 xfs_agnumber_t agno
;
2475 do_log(_("Phase 5 - rebuild AG headers and trees...\n"));
2476 set_progress_msg(PROG_FMT_REBUILD_AG
, (uint64_t)glob_agcount
);
2478 #ifdef XR_BLD_FREE_TRACE
2479 fprintf(stderr
, "inobt level 1, maxrec = %d, minrec = %d\n",
2480 libxfs_inobt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0),
2481 libxfs_inobt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0) / 2);
2482 fprintf(stderr
, "inobt level 0 (leaf), maxrec = %d, minrec = %d\n",
2483 libxfs_inobt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 1),
2484 libxfs_inobt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 1) / 2);
2485 fprintf(stderr
, "xr inobt level 0 (leaf), maxrec = %d\n",
2486 XR_INOBT_BLOCK_MAXRECS(mp
, 0));
2487 fprintf(stderr
, "xr inobt level 1 (int), maxrec = %d\n",
2488 XR_INOBT_BLOCK_MAXRECS(mp
, 1));
2489 fprintf(stderr
, "bnobt level 1, maxrec = %d, minrec = %d\n",
2490 libxfs_allocbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0),
2491 libxfs_allocbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 0) / 2);
2492 fprintf(stderr
, "bnobt level 0 (leaf), maxrec = %d, minrec = %d\n",
2493 libxfs_allocbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 1),
2494 libxfs_allocbt_maxrecs(mp
, mp
->m_sb
.sb_blocksize
, 1) / 2);
2497 * make sure the root and realtime inodes show up allocated
2501 /* allocate per ag counters */
2502 sb_icount_ag
= calloc(mp
->m_sb
.sb_agcount
, sizeof(uint64_t));
2503 if (sb_icount_ag
== NULL
)
2504 do_error(_("cannot alloc sb_icount_ag buffers\n"));
2506 sb_ifree_ag
= calloc(mp
->m_sb
.sb_agcount
, sizeof(uint64_t));
2507 if (sb_ifree_ag
== NULL
)
2508 do_error(_("cannot alloc sb_ifree_ag buffers\n"));
2510 sb_fdblocks_ag
= calloc(mp
->m_sb
.sb_agcount
, sizeof(uint64_t));
2511 if (sb_fdblocks_ag
== NULL
)
2512 do_error(_("cannot alloc sb_fdblocks_ag buffers\n"));
2514 error
= init_slab(&lost_fsb
, sizeof(xfs_fsblock_t
));
2516 do_error(_("cannot alloc lost block slab\n"));
2518 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
2519 phase5_func(mp
, agno
, lost_fsb
);
2523 /* aggregate per ag counters */
2524 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
2525 sb_icount
+= sb_icount_ag
[agno
];
2526 sb_ifree
+= sb_ifree_ag
[agno
];
2527 sb_fdblocks
+= sb_fdblocks_ag
[agno
];
2531 free(sb_fdblocks_ag
);
2533 if (mp
->m_sb
.sb_rblocks
) {
2535 _(" - generate realtime summary info and bitmap...\n"));
2537 generate_rtinfo(mp
, btmcompute
, sumcompute
);
2540 do_log(_(" - reset superblock...\n"));
2543 * sync superblock counter and set version bits correctly
2547 error
= inject_lost_blocks(mp
, lost_fsb
);
2549 do_error(_("Unable to reinsert lost blocks into filesystem.\n"));
2550 free_slab(&lost_fsb
);