hc
2024-09-20 a36159eec6ca17402b0e146b86efaf76568dc353
kernel/fs/xfs/libxfs/xfs_refcount_btree.c
....@@ -12,12 +12,11 @@
1212 #include "xfs_sb.h"
1313 #include "xfs_mount.h"
1414 #include "xfs_btree.h"
15
-#include "xfs_bmap.h"
15
+#include "xfs_btree_staging.h"
1616 #include "xfs_refcount_btree.h"
1717 #include "xfs_alloc.h"
1818 #include "xfs_error.h"
1919 #include "xfs_trace.h"
20
-#include "xfs_cksum.h"
2120 #include "xfs_trans.h"
2221 #include "xfs_bit.h"
2322 #include "xfs_rmap.h"
....@@ -27,7 +26,7 @@
2726 struct xfs_btree_cur *cur)
2827 {
2928 return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp,
30
- cur->bc_private.a.agbp, cur->bc_private.a.agno);
29
+ cur->bc_ag.agbp, cur->bc_ag.agno);
3130 }
3231
3332 STATIC void
....@@ -36,17 +35,15 @@
3635 union xfs_btree_ptr *ptr,
3736 int inc)
3837 {
39
- struct xfs_buf *agbp = cur->bc_private.a.agbp;
40
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
41
- xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
42
- struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno);
38
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
39
+ struct xfs_agf *agf = agbp->b_addr;
40
+ struct xfs_perag *pag = agbp->b_pag;
4341
4442 ASSERT(ptr->s != 0);
4543
4644 agf->agf_refcount_root = ptr->s;
4745 be32_add_cpu(&agf->agf_refcount_level, inc);
4846 pag->pagf_refcount_level += inc;
49
- xfs_perag_put(pag);
5047
5148 xfs_alloc_log_agf(cur->bc_tp, agbp,
5249 XFS_AGF_REFCOUNT_ROOT | XFS_AGF_REFCOUNT_LEVEL);
....@@ -59,8 +56,8 @@
5956 union xfs_btree_ptr *new,
6057 int *stat)
6158 {
62
- struct xfs_buf *agbp = cur->bc_private.a.agbp;
63
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
59
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
60
+ struct xfs_agf *agf = agbp->b_addr;
6461 struct xfs_alloc_arg args; /* block allocation args */
6562 int error; /* error return value */
6663
....@@ -68,22 +65,22 @@
6865 args.tp = cur->bc_tp;
6966 args.mp = cur->bc_mp;
7067 args.type = XFS_ALLOCTYPE_NEAR_BNO;
71
- args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno,
68
+ args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.agno,
7269 xfs_refc_block(args.mp));
73
- xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_REFC);
70
+ args.oinfo = XFS_RMAP_OINFO_REFC;
7471 args.minlen = args.maxlen = args.prod = 1;
7572 args.resv = XFS_AG_RESV_METADATA;
7673
7774 error = xfs_alloc_vextent(&args);
7875 if (error)
7976 goto out_error;
80
- trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_private.a.agno,
77
+ trace_xfs_refcountbt_alloc_block(cur->bc_mp, cur->bc_ag.agno,
8178 args.agbno, 1);
8279 if (args.fsbno == NULLFSBLOCK) {
8380 *stat = 0;
8481 return 0;
8582 }
86
- ASSERT(args.agno == cur->bc_private.a.agno);
83
+ ASSERT(args.agno == cur->bc_ag.agno);
8784 ASSERT(args.len == 1);
8885
8986 new->s = cpu_to_be32(args.agbno);
....@@ -103,18 +100,16 @@
103100 struct xfs_buf *bp)
104101 {
105102 struct xfs_mount *mp = cur->bc_mp;
106
- struct xfs_buf *agbp = cur->bc_private.a.agbp;
107
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
103
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
104
+ struct xfs_agf *agf = agbp->b_addr;
108105 xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp));
109
- struct xfs_owner_info oinfo;
110106 int error;
111107
112
- trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_private.a.agno,
108
+ trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_ag.agno,
113109 XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1);
114
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_REFC);
115110 be32_add_cpu(&agf->agf_refcount_blocks, -1);
116111 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
117
- error = xfs_free_extent(cur->bc_tp, fsbno, 1, &oinfo,
112
+ error = xfs_free_extent(cur->bc_tp, fsbno, 1, &XFS_RMAP_OINFO_REFC,
118113 XFS_AG_RESV_METADATA);
119114 if (error)
120115 return error;
....@@ -173,9 +168,9 @@
173168 struct xfs_btree_cur *cur,
174169 union xfs_btree_ptr *ptr)
175170 {
176
- struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
171
+ struct xfs_agf *agf = cur->bc_ag.agbp->b_addr;
177172
178
- ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno));
173
+ ASSERT(cur->bc_ag.agno == be32_to_cpu(agf->agf_seqno));
179174
180175 ptr->s = agf->agf_refcount_root;
181176 }
....@@ -205,13 +200,13 @@
205200 xfs_refcountbt_verify(
206201 struct xfs_buf *bp)
207202 {
208
- struct xfs_mount *mp = bp->b_target->bt_mount;
203
+ struct xfs_mount *mp = bp->b_mount;
209204 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
210205 struct xfs_perag *pag = bp->b_pag;
211206 xfs_failaddr_t fa;
212207 unsigned int level;
213208
214
- if (block->bb_magic != cpu_to_be32(XFS_REFC_CRC_MAGIC))
209
+ if (!xfs_verify_magic(bp, block->bb_magic))
215210 return __this_address;
216211
217212 if (!xfs_sb_version_hasreflink(&mp->m_sb))
....@@ -266,6 +261,7 @@
266261
267262 const struct xfs_buf_ops xfs_refcountbt_buf_ops = {
268263 .name = "xfs_refcountbt",
264
+ .magic = { 0, cpu_to_be32(XFS_REFC_CRC_MAGIC) },
269265 .verify_read = xfs_refcountbt_read_verify,
270266 .verify_write = xfs_refcountbt_write_verify,
271267 .verify_struct = xfs_refcountbt_verify,
....@@ -314,8 +310,36 @@
314310 };
315311
316312 /*
317
- * Allocate a new refcount btree cursor.
313
+ * Initialize a new refcount btree cursor.
318314 */
315
+static struct xfs_btree_cur *
316
+xfs_refcountbt_init_common(
317
+ struct xfs_mount *mp,
318
+ struct xfs_trans *tp,
319
+ xfs_agnumber_t agno)
320
+{
321
+ struct xfs_btree_cur *cur;
322
+
323
+ ASSERT(agno != NULLAGNUMBER);
324
+ ASSERT(agno < mp->m_sb.sb_agcount);
325
+
326
+ cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL);
327
+ cur->bc_tp = tp;
328
+ cur->bc_mp = mp;
329
+ cur->bc_btnum = XFS_BTNUM_REFC;
330
+ cur->bc_blocklog = mp->m_sb.sb_blocklog;
331
+ cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
332
+
333
+ cur->bc_ag.agno = agno;
334
+ cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
335
+
336
+ cur->bc_ag.refc.nr_ops = 0;
337
+ cur->bc_ag.refc.shape_changes = 0;
338
+ cur->bc_ops = &xfs_refcountbt_ops;
339
+ return cur;
340
+}
341
+
342
+/* Create a btree cursor. */
319343 struct xfs_btree_cur *
320344 xfs_refcountbt_init_cursor(
321345 struct xfs_mount *mp,
....@@ -323,30 +347,51 @@
323347 struct xfs_buf *agbp,
324348 xfs_agnumber_t agno)
325349 {
326
- struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
350
+ struct xfs_agf *agf = agbp->b_addr;
327351 struct xfs_btree_cur *cur;
328352
329
- ASSERT(agno != NULLAGNUMBER);
330
- ASSERT(agno < mp->m_sb.sb_agcount);
331
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
332
-
333
- cur->bc_tp = tp;
334
- cur->bc_mp = mp;
335
- cur->bc_btnum = XFS_BTNUM_REFC;
336
- cur->bc_blocklog = mp->m_sb.sb_blocklog;
337
- cur->bc_ops = &xfs_refcountbt_ops;
338
- cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
339
-
353
+ cur = xfs_refcountbt_init_common(mp, tp, agno);
340354 cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
341
-
342
- cur->bc_private.a.agbp = agbp;
343
- cur->bc_private.a.agno = agno;
344
- cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
345
-
346
- cur->bc_private.a.priv.refc.nr_ops = 0;
347
- cur->bc_private.a.priv.refc.shape_changes = 0;
348
-
355
+ cur->bc_ag.agbp = agbp;
349356 return cur;
357
+}
358
+
359
+/* Create a btree cursor with a fake root for staging. */
360
+struct xfs_btree_cur *
361
+xfs_refcountbt_stage_cursor(
362
+ struct xfs_mount *mp,
363
+ struct xbtree_afakeroot *afake,
364
+ xfs_agnumber_t agno)
365
+{
366
+ struct xfs_btree_cur *cur;
367
+
368
+ cur = xfs_refcountbt_init_common(mp, NULL, agno);
369
+ xfs_btree_stage_afakeroot(cur, afake);
370
+ return cur;
371
+}
372
+
373
+/*
374
+ * Swap in the new btree root. Once we pass this point the newly rebuilt btree
375
+ * is in place and we have to kill off all the old btree blocks.
376
+ */
377
+void
378
+xfs_refcountbt_commit_staged_btree(
379
+ struct xfs_btree_cur *cur,
380
+ struct xfs_trans *tp,
381
+ struct xfs_buf *agbp)
382
+{
383
+ struct xfs_agf *agf = agbp->b_addr;
384
+ struct xbtree_afakeroot *afake = cur->bc_ag.afake;
385
+
386
+ ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
387
+
388
+ agf->agf_refcount_root = cpu_to_be32(afake->af_root);
389
+ agf->agf_refcount_level = cpu_to_be32(afake->af_levels);
390
+ agf->agf_refcount_blocks = cpu_to_be32(afake->af_blocks);
391
+ xfs_alloc_log_agf(tp, agbp, XFS_AGF_REFCOUNT_BLOCKS |
392
+ XFS_AGF_REFCOUNT_ROOT |
393
+ XFS_AGF_REFCOUNT_LEVEL);
394
+ xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_refcountbt_ops);
350395 }
351396
352397 /*
....@@ -423,11 +468,20 @@
423468 if (error)
424469 return error;
425470
426
- agf = XFS_BUF_TO_AGF(agbp);
471
+ agf = agbp->b_addr;
427472 agblocks = be32_to_cpu(agf->agf_length);
428473 tree_len = be32_to_cpu(agf->agf_refcount_blocks);
429474 xfs_trans_brelse(tp, agbp);
430475
476
+ /*
477
+ * The log is permanently allocated, so the space it occupies will
478
+ * never be available for the kinds of things that would require btree
479
+ * expansion. We therefore can pretend the space isn't there.
480
+ */
481
+ if (mp->m_sb.sb_logstart &&
482
+ XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno)
483
+ agblocks -= mp->m_sb.sb_logblocks;
484
+
431485 *ask += xfs_refcountbt_max_size(mp, agblocks);
432486 *used += tree_len;
433487