1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
6 #include "libxfs_priv.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_btree.h"
14 #include "xfs_btree_staging.h"
15 #include "xfs_alloc_btree.h"
16 #include "xfs_alloc.h"
17 #include "xfs_trace.h"
18 #include "xfs_trans.h"
21 static struct kmem_cache
*xfs_allocbt_cur_cache
;
23 STATIC
struct xfs_btree_cur
*
24 xfs_allocbt_dup_cursor(
25 struct xfs_btree_cur
*cur
)
27 return xfs_allocbt_init_cursor(cur
->bc_mp
, cur
->bc_tp
,
28 cur
->bc_ag
.agbp
, cur
->bc_ag
.pag
, cur
->bc_btnum
);
33 struct xfs_btree_cur
*cur
,
34 const union xfs_btree_ptr
*ptr
,
37 struct xfs_buf
*agbp
= cur
->bc_ag
.agbp
;
38 struct xfs_agf
*agf
= agbp
->b_addr
;
39 int btnum
= cur
->bc_btnum
;
43 agf
->agf_roots
[btnum
] = ptr
->s
;
44 be32_add_cpu(&agf
->agf_levels
[btnum
], inc
);
45 cur
->bc_ag
.pag
->pagf_levels
[btnum
] += inc
;
47 xfs_alloc_log_agf(cur
->bc_tp
, agbp
, XFS_AGF_ROOTS
| XFS_AGF_LEVELS
);
51 xfs_allocbt_alloc_block(
52 struct xfs_btree_cur
*cur
,
53 const union xfs_btree_ptr
*start
,
54 union xfs_btree_ptr
*new,
60 /* Allocate the new block from the freelist. If we can't, give up. */
61 error
= xfs_alloc_get_freelist(cur
->bc_ag
.pag
, cur
->bc_tp
,
62 cur
->bc_ag
.agbp
, &bno
, 1);
66 if (bno
== NULLAGBLOCK
) {
71 atomic64_inc(&cur
->bc_mp
->m_allocbt_blks
);
72 xfs_extent_busy_reuse(cur
->bc_mp
, cur
->bc_ag
.pag
, bno
, 1, false);
74 new->s
= cpu_to_be32(bno
);
81 xfs_allocbt_free_block(
82 struct xfs_btree_cur
*cur
,
85 struct xfs_buf
*agbp
= cur
->bc_ag
.agbp
;
89 bno
= xfs_daddr_to_agbno(cur
->bc_mp
, xfs_buf_daddr(bp
));
90 error
= xfs_alloc_put_freelist(cur
->bc_ag
.pag
, cur
->bc_tp
, agbp
, NULL
,
95 atomic64_dec(&cur
->bc_mp
->m_allocbt_blks
);
96 xfs_extent_busy_insert(cur
->bc_tp
, agbp
->b_pag
, bno
, 1,
97 XFS_EXTENT_BUSY_SKIP_DISCARD
);
102 * Update the longest extent in the AGF
105 xfs_allocbt_update_lastrec(
106 struct xfs_btree_cur
*cur
,
107 const struct xfs_btree_block
*block
,
108 const union xfs_btree_rec
*rec
,
112 struct xfs_agf
*agf
= cur
->bc_ag
.agbp
->b_addr
;
113 struct xfs_perag
*pag
;
117 ASSERT(cur
->bc_btnum
== XFS_BTNUM_CNT
);
122 * If this is the last leaf block and it's the last record,
123 * then update the size of the longest extent in the AG.
125 if (ptr
!= xfs_btree_get_numrecs(block
))
127 len
= rec
->alloc
.ar_blockcount
;
130 if (be32_to_cpu(rec
->alloc
.ar_blockcount
) <=
131 be32_to_cpu(agf
->agf_longest
))
133 len
= rec
->alloc
.ar_blockcount
;
136 numrecs
= xfs_btree_get_numrecs(block
);
139 ASSERT(ptr
== numrecs
+ 1);
142 xfs_alloc_rec_t
*rrp
;
144 rrp
= XFS_ALLOC_REC_ADDR(cur
->bc_mp
, block
, numrecs
);
145 len
= rrp
->ar_blockcount
;
156 agf
->agf_longest
= len
;
157 pag
= cur
->bc_ag
.agbp
->b_pag
;
158 pag
->pagf_longest
= be32_to_cpu(len
);
159 xfs_alloc_log_agf(cur
->bc_tp
, cur
->bc_ag
.agbp
, XFS_AGF_LONGEST
);
163 xfs_allocbt_get_minrecs(
164 struct xfs_btree_cur
*cur
,
167 return cur
->bc_mp
->m_alloc_mnr
[level
!= 0];
171 xfs_allocbt_get_maxrecs(
172 struct xfs_btree_cur
*cur
,
175 return cur
->bc_mp
->m_alloc_mxr
[level
!= 0];
179 xfs_allocbt_init_key_from_rec(
180 union xfs_btree_key
*key
,
181 const union xfs_btree_rec
*rec
)
183 key
->alloc
.ar_startblock
= rec
->alloc
.ar_startblock
;
184 key
->alloc
.ar_blockcount
= rec
->alloc
.ar_blockcount
;
188 xfs_bnobt_init_high_key_from_rec(
189 union xfs_btree_key
*key
,
190 const union xfs_btree_rec
*rec
)
194 x
= be32_to_cpu(rec
->alloc
.ar_startblock
);
195 x
+= be32_to_cpu(rec
->alloc
.ar_blockcount
) - 1;
196 key
->alloc
.ar_startblock
= cpu_to_be32(x
);
197 key
->alloc
.ar_blockcount
= 0;
201 xfs_cntbt_init_high_key_from_rec(
202 union xfs_btree_key
*key
,
203 const union xfs_btree_rec
*rec
)
205 key
->alloc
.ar_blockcount
= rec
->alloc
.ar_blockcount
;
206 key
->alloc
.ar_startblock
= 0;
210 xfs_allocbt_init_rec_from_cur(
211 struct xfs_btree_cur
*cur
,
212 union xfs_btree_rec
*rec
)
214 rec
->alloc
.ar_startblock
= cpu_to_be32(cur
->bc_rec
.a
.ar_startblock
);
215 rec
->alloc
.ar_blockcount
= cpu_to_be32(cur
->bc_rec
.a
.ar_blockcount
);
219 xfs_allocbt_init_ptr_from_cur(
220 struct xfs_btree_cur
*cur
,
221 union xfs_btree_ptr
*ptr
)
223 struct xfs_agf
*agf
= cur
->bc_ag
.agbp
->b_addr
;
225 ASSERT(cur
->bc_ag
.pag
->pag_agno
== be32_to_cpu(agf
->agf_seqno
));
227 ptr
->s
= agf
->agf_roots
[cur
->bc_btnum
];
232 struct xfs_btree_cur
*cur
,
233 const union xfs_btree_key
*key
)
235 struct xfs_alloc_rec_incore
*rec
= &cur
->bc_rec
.a
;
236 const struct xfs_alloc_rec
*kp
= &key
->alloc
;
238 return (int64_t)be32_to_cpu(kp
->ar_startblock
) - rec
->ar_startblock
;
243 struct xfs_btree_cur
*cur
,
244 const union xfs_btree_key
*key
)
246 struct xfs_alloc_rec_incore
*rec
= &cur
->bc_rec
.a
;
247 const struct xfs_alloc_rec
*kp
= &key
->alloc
;
250 diff
= (int64_t)be32_to_cpu(kp
->ar_blockcount
) - rec
->ar_blockcount
;
254 return (int64_t)be32_to_cpu(kp
->ar_startblock
) - rec
->ar_startblock
;
258 xfs_bnobt_diff_two_keys(
259 struct xfs_btree_cur
*cur
,
260 const union xfs_btree_key
*k1
,
261 const union xfs_btree_key
*k2
,
262 const union xfs_btree_key
*mask
)
264 ASSERT(!mask
|| mask
->alloc
.ar_startblock
);
266 return (int64_t)be32_to_cpu(k1
->alloc
.ar_startblock
) -
267 be32_to_cpu(k2
->alloc
.ar_startblock
);
271 xfs_cntbt_diff_two_keys(
272 struct xfs_btree_cur
*cur
,
273 const union xfs_btree_key
*k1
,
274 const union xfs_btree_key
*k2
,
275 const union xfs_btree_key
*mask
)
279 ASSERT(!mask
|| (mask
->alloc
.ar_blockcount
&&
280 mask
->alloc
.ar_startblock
));
282 diff
= be32_to_cpu(k1
->alloc
.ar_blockcount
) -
283 be32_to_cpu(k2
->alloc
.ar_blockcount
);
287 return be32_to_cpu(k1
->alloc
.ar_startblock
) -
288 be32_to_cpu(k2
->alloc
.ar_startblock
);
291 static xfs_failaddr_t
295 struct xfs_mount
*mp
= bp
->b_mount
;
296 struct xfs_btree_block
*block
= XFS_BUF_TO_BLOCK(bp
);
297 struct xfs_perag
*pag
= bp
->b_pag
;
300 xfs_btnum_t btnum
= XFS_BTNUM_BNOi
;
302 if (!xfs_verify_magic(bp
, block
->bb_magic
))
303 return __this_address
;
305 if (xfs_has_crc(mp
)) {
306 fa
= xfs_btree_sblock_v5hdr_verify(bp
);
312 * The perag may not be attached during grow operations or fully
313 * initialized from the AGF during log recovery. Therefore we can only
314 * check against maximum tree depth from those contexts.
316 * Otherwise check against the per-tree limit. Peek at one of the
317 * verifier magic values to determine the type of tree we're verifying
320 level
= be16_to_cpu(block
->bb_level
);
321 if (bp
->b_ops
->magic
[0] == cpu_to_be32(XFS_ABTC_MAGIC
))
322 btnum
= XFS_BTNUM_CNTi
;
323 if (pag
&& xfs_perag_initialised_agf(pag
)) {
324 if (level
>= pag
->pagf_levels
[btnum
])
325 return __this_address
;
326 } else if (level
>= mp
->m_alloc_maxlevels
)
327 return __this_address
;
329 return xfs_btree_sblock_verify(bp
, mp
->m_alloc_mxr
[level
!= 0]);
333 xfs_allocbt_read_verify(
338 if (!xfs_btree_sblock_verify_crc(bp
))
339 xfs_verifier_error(bp
, -EFSBADCRC
, __this_address
);
341 fa
= xfs_allocbt_verify(bp
);
343 xfs_verifier_error(bp
, -EFSCORRUPTED
, fa
);
347 trace_xfs_btree_corrupt(bp
, _RET_IP_
);
351 xfs_allocbt_write_verify(
356 fa
= xfs_allocbt_verify(bp
);
358 trace_xfs_btree_corrupt(bp
, _RET_IP_
);
359 xfs_verifier_error(bp
, -EFSCORRUPTED
, fa
);
362 xfs_btree_sblock_calc_crc(bp
);
366 const struct xfs_buf_ops xfs_bnobt_buf_ops
= {
368 .magic
= { cpu_to_be32(XFS_ABTB_MAGIC
),
369 cpu_to_be32(XFS_ABTB_CRC_MAGIC
) },
370 .verify_read
= xfs_allocbt_read_verify
,
371 .verify_write
= xfs_allocbt_write_verify
,
372 .verify_struct
= xfs_allocbt_verify
,
375 const struct xfs_buf_ops xfs_cntbt_buf_ops
= {
377 .magic
= { cpu_to_be32(XFS_ABTC_MAGIC
),
378 cpu_to_be32(XFS_ABTC_CRC_MAGIC
) },
379 .verify_read
= xfs_allocbt_read_verify
,
380 .verify_write
= xfs_allocbt_write_verify
,
381 .verify_struct
= xfs_allocbt_verify
,
385 xfs_bnobt_keys_inorder(
386 struct xfs_btree_cur
*cur
,
387 const union xfs_btree_key
*k1
,
388 const union xfs_btree_key
*k2
)
390 return be32_to_cpu(k1
->alloc
.ar_startblock
) <
391 be32_to_cpu(k2
->alloc
.ar_startblock
);
395 xfs_bnobt_recs_inorder(
396 struct xfs_btree_cur
*cur
,
397 const union xfs_btree_rec
*r1
,
398 const union xfs_btree_rec
*r2
)
400 return be32_to_cpu(r1
->alloc
.ar_startblock
) +
401 be32_to_cpu(r1
->alloc
.ar_blockcount
) <=
402 be32_to_cpu(r2
->alloc
.ar_startblock
);
406 xfs_cntbt_keys_inorder(
407 struct xfs_btree_cur
*cur
,
408 const union xfs_btree_key
*k1
,
409 const union xfs_btree_key
*k2
)
411 return be32_to_cpu(k1
->alloc
.ar_blockcount
) <
412 be32_to_cpu(k2
->alloc
.ar_blockcount
) ||
413 (k1
->alloc
.ar_blockcount
== k2
->alloc
.ar_blockcount
&&
414 be32_to_cpu(k1
->alloc
.ar_startblock
) <
415 be32_to_cpu(k2
->alloc
.ar_startblock
));
419 xfs_cntbt_recs_inorder(
420 struct xfs_btree_cur
*cur
,
421 const union xfs_btree_rec
*r1
,
422 const union xfs_btree_rec
*r2
)
424 return be32_to_cpu(r1
->alloc
.ar_blockcount
) <
425 be32_to_cpu(r2
->alloc
.ar_blockcount
) ||
426 (r1
->alloc
.ar_blockcount
== r2
->alloc
.ar_blockcount
&&
427 be32_to_cpu(r1
->alloc
.ar_startblock
) <
428 be32_to_cpu(r2
->alloc
.ar_startblock
));
431 STATIC
enum xbtree_key_contig
432 xfs_allocbt_keys_contiguous(
433 struct xfs_btree_cur
*cur
,
434 const union xfs_btree_key
*key1
,
435 const union xfs_btree_key
*key2
,
436 const union xfs_btree_key
*mask
)
438 ASSERT(!mask
|| mask
->alloc
.ar_startblock
);
440 return xbtree_key_contig(be32_to_cpu(key1
->alloc
.ar_startblock
),
441 be32_to_cpu(key2
->alloc
.ar_startblock
));
444 static const struct xfs_btree_ops xfs_bnobt_ops
= {
445 .rec_len
= sizeof(xfs_alloc_rec_t
),
446 .key_len
= sizeof(xfs_alloc_key_t
),
448 .dup_cursor
= xfs_allocbt_dup_cursor
,
449 .set_root
= xfs_allocbt_set_root
,
450 .alloc_block
= xfs_allocbt_alloc_block
,
451 .free_block
= xfs_allocbt_free_block
,
452 .update_lastrec
= xfs_allocbt_update_lastrec
,
453 .get_minrecs
= xfs_allocbt_get_minrecs
,
454 .get_maxrecs
= xfs_allocbt_get_maxrecs
,
455 .init_key_from_rec
= xfs_allocbt_init_key_from_rec
,
456 .init_high_key_from_rec
= xfs_bnobt_init_high_key_from_rec
,
457 .init_rec_from_cur
= xfs_allocbt_init_rec_from_cur
,
458 .init_ptr_from_cur
= xfs_allocbt_init_ptr_from_cur
,
459 .key_diff
= xfs_bnobt_key_diff
,
460 .buf_ops
= &xfs_bnobt_buf_ops
,
461 .diff_two_keys
= xfs_bnobt_diff_two_keys
,
462 .keys_inorder
= xfs_bnobt_keys_inorder
,
463 .recs_inorder
= xfs_bnobt_recs_inorder
,
464 .keys_contiguous
= xfs_allocbt_keys_contiguous
,
467 static const struct xfs_btree_ops xfs_cntbt_ops
= {
468 .rec_len
= sizeof(xfs_alloc_rec_t
),
469 .key_len
= sizeof(xfs_alloc_key_t
),
471 .dup_cursor
= xfs_allocbt_dup_cursor
,
472 .set_root
= xfs_allocbt_set_root
,
473 .alloc_block
= xfs_allocbt_alloc_block
,
474 .free_block
= xfs_allocbt_free_block
,
475 .update_lastrec
= xfs_allocbt_update_lastrec
,
476 .get_minrecs
= xfs_allocbt_get_minrecs
,
477 .get_maxrecs
= xfs_allocbt_get_maxrecs
,
478 .init_key_from_rec
= xfs_allocbt_init_key_from_rec
,
479 .init_high_key_from_rec
= xfs_cntbt_init_high_key_from_rec
,
480 .init_rec_from_cur
= xfs_allocbt_init_rec_from_cur
,
481 .init_ptr_from_cur
= xfs_allocbt_init_ptr_from_cur
,
482 .key_diff
= xfs_cntbt_key_diff
,
483 .buf_ops
= &xfs_cntbt_buf_ops
,
484 .diff_two_keys
= xfs_cntbt_diff_two_keys
,
485 .keys_inorder
= xfs_cntbt_keys_inorder
,
486 .recs_inorder
= xfs_cntbt_recs_inorder
,
487 .keys_contiguous
= NULL
, /* not needed right now */
490 /* Allocate most of a new allocation btree cursor. */
491 STATIC
struct xfs_btree_cur
*
492 xfs_allocbt_init_common(
493 struct xfs_mount
*mp
,
494 struct xfs_trans
*tp
,
495 struct xfs_perag
*pag
,
498 struct xfs_btree_cur
*cur
;
500 ASSERT(btnum
== XFS_BTNUM_BNO
|| btnum
== XFS_BTNUM_CNT
);
502 cur
= xfs_btree_alloc_cursor(mp
, tp
, btnum
, mp
->m_alloc_maxlevels
,
503 xfs_allocbt_cur_cache
);
504 cur
->bc_ag
.abt
.active
= false;
506 if (btnum
== XFS_BTNUM_CNT
) {
507 cur
->bc_ops
= &xfs_cntbt_ops
;
508 cur
->bc_statoff
= XFS_STATS_CALC_INDEX(xs_abtc_2
);
509 cur
->bc_flags
= XFS_BTREE_LASTREC_UPDATE
;
511 cur
->bc_ops
= &xfs_bnobt_ops
;
512 cur
->bc_statoff
= XFS_STATS_CALC_INDEX(xs_abtb_2
);
515 cur
->bc_ag
.pag
= xfs_perag_hold(pag
);
518 cur
->bc_flags
|= XFS_BTREE_CRC_BLOCKS
;
524 * Allocate a new allocation btree cursor.
526 struct xfs_btree_cur
* /* new alloc btree cursor */
527 xfs_allocbt_init_cursor(
528 struct xfs_mount
*mp
, /* file system mount point */
529 struct xfs_trans
*tp
, /* transaction pointer */
530 struct xfs_buf
*agbp
, /* buffer for agf structure */
531 struct xfs_perag
*pag
,
532 xfs_btnum_t btnum
) /* btree identifier */
534 struct xfs_agf
*agf
= agbp
->b_addr
;
535 struct xfs_btree_cur
*cur
;
537 cur
= xfs_allocbt_init_common(mp
, tp
, pag
, btnum
);
538 if (btnum
== XFS_BTNUM_CNT
)
539 cur
->bc_nlevels
= be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_CNT
]);
541 cur
->bc_nlevels
= be32_to_cpu(agf
->agf_levels
[XFS_BTNUM_BNO
]);
543 cur
->bc_ag
.agbp
= agbp
;
548 /* Create a free space btree cursor with a fake root for staging. */
549 struct xfs_btree_cur
*
550 xfs_allocbt_stage_cursor(
551 struct xfs_mount
*mp
,
552 struct xbtree_afakeroot
*afake
,
553 struct xfs_perag
*pag
,
556 struct xfs_btree_cur
*cur
;
558 cur
= xfs_allocbt_init_common(mp
, NULL
, pag
, btnum
);
559 xfs_btree_stage_afakeroot(cur
, afake
);
564 * Install a new free space btree root. Caller is responsible for invalidating
565 * and freeing the old btree blocks.
568 xfs_allocbt_commit_staged_btree(
569 struct xfs_btree_cur
*cur
,
570 struct xfs_trans
*tp
,
571 struct xfs_buf
*agbp
)
573 struct xfs_agf
*agf
= agbp
->b_addr
;
574 struct xbtree_afakeroot
*afake
= cur
->bc_ag
.afake
;
576 ASSERT(cur
->bc_flags
& XFS_BTREE_STAGING
);
578 agf
->agf_roots
[cur
->bc_btnum
] = cpu_to_be32(afake
->af_root
);
579 agf
->agf_levels
[cur
->bc_btnum
] = cpu_to_be32(afake
->af_levels
);
580 xfs_alloc_log_agf(tp
, agbp
, XFS_AGF_ROOTS
| XFS_AGF_LEVELS
);
582 if (cur
->bc_btnum
== XFS_BTNUM_BNO
) {
583 xfs_btree_commit_afakeroot(cur
, tp
, agbp
, &xfs_bnobt_ops
);
585 cur
->bc_flags
|= XFS_BTREE_LASTREC_UPDATE
;
586 xfs_btree_commit_afakeroot(cur
, tp
, agbp
, &xfs_cntbt_ops
);
590 /* Calculate number of records in an alloc btree block. */
591 static inline unsigned int
592 xfs_allocbt_block_maxrecs(
593 unsigned int blocklen
,
597 return blocklen
/ sizeof(xfs_alloc_rec_t
);
598 return blocklen
/ (sizeof(xfs_alloc_key_t
) + sizeof(xfs_alloc_ptr_t
));
602 * Calculate number of records in an alloc btree block.
606 struct xfs_mount
*mp
,
610 blocklen
-= XFS_ALLOC_BLOCK_LEN(mp
);
611 return xfs_allocbt_block_maxrecs(blocklen
, leaf
);
614 /* Free space btrees are at their largest when every other block is free. */
615 #define XFS_MAX_FREESP_RECORDS ((XFS_MAX_AG_BLOCKS + 1) / 2)
617 /* Compute the max possible height for free space btrees. */
619 xfs_allocbt_maxlevels_ondisk(void)
621 unsigned int minrecs
[2];
622 unsigned int blocklen
;
624 blocklen
= min(XFS_MIN_BLOCKSIZE
- XFS_BTREE_SBLOCK_LEN
,
625 XFS_MIN_CRC_BLOCKSIZE
- XFS_BTREE_SBLOCK_CRC_LEN
);
627 minrecs
[0] = xfs_allocbt_block_maxrecs(blocklen
, true) / 2;
628 minrecs
[1] = xfs_allocbt_block_maxrecs(blocklen
, false) / 2;
630 return xfs_btree_compute_maxlevels(minrecs
, XFS_MAX_FREESP_RECORDS
);
633 /* Calculate the freespace btree size for some records. */
635 xfs_allocbt_calc_size(
636 struct xfs_mount
*mp
,
637 unsigned long long len
)
639 return xfs_btree_calc_size(mp
->m_alloc_mnr
, len
);
643 xfs_allocbt_init_cur_cache(void)
645 xfs_allocbt_cur_cache
= kmem_cache_create("xfs_bnobt_cur",
646 xfs_btree_cur_sizeof(xfs_allocbt_maxlevels_ondisk()),
649 if (!xfs_allocbt_cur_cache
)
655 xfs_allocbt_destroy_cur_cache(void)
657 kmem_cache_destroy(xfs_allocbt_cur_cache
);
658 xfs_allocbt_cur_cache
= NULL
;