hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/xfs/libxfs/xfs_ialloc_btree.c
....@@ -11,24 +11,22 @@
1111 #include "xfs_trans_resv.h"
1212 #include "xfs_bit.h"
1313 #include "xfs_mount.h"
14
-#include "xfs_inode.h"
1514 #include "xfs_btree.h"
15
+#include "xfs_btree_staging.h"
1616 #include "xfs_ialloc.h"
1717 #include "xfs_ialloc_btree.h"
1818 #include "xfs_alloc.h"
1919 #include "xfs_error.h"
2020 #include "xfs_trace.h"
21
-#include "xfs_cksum.h"
2221 #include "xfs_trans.h"
2322 #include "xfs_rmap.h"
24
-
2523
2624 STATIC int
2725 xfs_inobt_get_minrecs(
2826 struct xfs_btree_cur *cur,
2927 int level)
3028 {
31
- return cur->bc_mp->m_inobt_mnr[level != 0];
29
+ return M_IGEO(cur->bc_mp)->inobt_mnr[level != 0];
3230 }
3331
3432 STATIC struct xfs_btree_cur *
....@@ -36,7 +34,7 @@
3634 struct xfs_btree_cur *cur)
3735 {
3836 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
39
- cur->bc_private.a.agbp, cur->bc_private.a.agno,
37
+ cur->bc_ag.agbp, cur->bc_ag.agno,
4038 cur->bc_btnum);
4139 }
4240
....@@ -46,8 +44,8 @@
4644 union xfs_btree_ptr *nptr,
4745 int inc) /* level change */
4846 {
49
- struct xfs_buf *agbp = cur->bc_private.a.agbp;
50
- struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
47
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
48
+ struct xfs_agi *agi = agbp->b_addr;
5149
5250 agi->agi_root = nptr->s;
5351 be32_add_cpu(&agi->agi_level, inc);
....@@ -60,13 +58,32 @@
6058 union xfs_btree_ptr *nptr,
6159 int inc) /* level change */
6260 {
63
- struct xfs_buf *agbp = cur->bc_private.a.agbp;
64
- struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
61
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
62
+ struct xfs_agi *agi = agbp->b_addr;
6563
6664 agi->agi_free_root = nptr->s;
6765 be32_add_cpu(&agi->agi_free_level, inc);
6866 xfs_ialloc_log_agi(cur->bc_tp, agbp,
6967 XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL);
68
+}
69
+
70
+/* Update the inode btree block counter for this btree. */
71
+static inline void
72
+xfs_inobt_mod_blockcount(
73
+ struct xfs_btree_cur *cur,
74
+ int howmuch)
75
+{
76
+ struct xfs_buf *agbp = cur->bc_ag.agbp;
77
+ struct xfs_agi *agi = agbp->b_addr;
78
+
79
+ if (!xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb))
80
+ return;
81
+
82
+ if (cur->bc_btnum == XFS_BTNUM_FINO)
83
+ be32_add_cpu(&agi->agi_fblocks, howmuch);
84
+ else if (cur->bc_btnum == XFS_BTNUM_INO)
85
+ be32_add_cpu(&agi->agi_iblocks, howmuch);
86
+ xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS);
7087 }
7188
7289 STATIC int
....@@ -84,8 +101,8 @@
84101 memset(&args, 0, sizeof(args));
85102 args.tp = cur->bc_tp;
86103 args.mp = cur->bc_mp;
87
- xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INOBT);
88
- args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno);
104
+ args.oinfo = XFS_RMAP_OINFO_INOBT;
105
+ args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.agno, sbno);
89106 args.minlen = 1;
90107 args.maxlen = 1;
91108 args.prod = 1;
....@@ -104,6 +121,7 @@
104121
105122 new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno));
106123 *stat = 1;
124
+ xfs_inobt_mod_blockcount(cur, 1);
107125 return 0;
108126 }
109127
....@@ -136,12 +154,10 @@
136154 struct xfs_buf *bp,
137155 enum xfs_ag_resv_type resv)
138156 {
139
- struct xfs_owner_info oinfo;
140
-
141
- xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT);
157
+ xfs_inobt_mod_blockcount(cur, -1);
142158 return xfs_free_extent(cur->bc_tp,
143159 XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1,
144
- &oinfo, resv);
160
+ &XFS_RMAP_OINFO_INOBT, resv);
145161 }
146162
147163 STATIC int
....@@ -167,7 +183,7 @@
167183 struct xfs_btree_cur *cur,
168184 int level)
169185 {
170
- return cur->bc_mp->m_inobt_mxr[level != 0];
186
+ return M_IGEO(cur->bc_mp)->inobt_mxr[level != 0];
171187 }
172188
173189 STATIC void
....@@ -217,9 +233,9 @@
217233 struct xfs_btree_cur *cur,
218234 union xfs_btree_ptr *ptr)
219235 {
220
- struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
236
+ struct xfs_agi *agi = cur->bc_ag.agbp->b_addr;
221237
222
- ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
238
+ ASSERT(cur->bc_ag.agno == be32_to_cpu(agi->agi_seqno));
223239
224240 ptr->s = agi->agi_root;
225241 }
....@@ -229,9 +245,9 @@
229245 struct xfs_btree_cur *cur,
230246 union xfs_btree_ptr *ptr)
231247 {
232
- struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
248
+ struct xfs_agi *agi = cur->bc_ag.agbp->b_addr;
233249
234
- ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
250
+ ASSERT(cur->bc_ag.agno == be32_to_cpu(agi->agi_seqno));
235251 ptr->s = agi->agi_free_root;
236252 }
237253
....@@ -258,10 +274,13 @@
258274 xfs_inobt_verify(
259275 struct xfs_buf *bp)
260276 {
261
- struct xfs_mount *mp = bp->b_target->bt_mount;
277
+ struct xfs_mount *mp = bp->b_mount;
262278 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
263279 xfs_failaddr_t fa;
264280 unsigned int level;
281
+
282
+ if (!xfs_verify_magic(bp, block->bb_magic))
283
+ return __this_address;
265284
266285 /*
267286 * During growfs operations, we can't verify the exact owner as the
....@@ -273,26 +292,19 @@
273292 * but beware of the landmine (i.e. need to check pag->pagi_init) if we
274293 * ever do.
275294 */
276
- switch (block->bb_magic) {
277
- case cpu_to_be32(XFS_IBT_CRC_MAGIC):
278
- case cpu_to_be32(XFS_FIBT_CRC_MAGIC):
295
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
279296 fa = xfs_btree_sblock_v5hdr_verify(bp);
280297 if (fa)
281298 return fa;
282
- /* fall through */
283
- case cpu_to_be32(XFS_IBT_MAGIC):
284
- case cpu_to_be32(XFS_FIBT_MAGIC):
285
- break;
286
- default:
287
- return __this_address;
288299 }
289300
290301 /* level verification */
291302 level = be16_to_cpu(block->bb_level);
292
- if (level >= mp->m_in_maxlevels)
303
+ if (level >= M_IGEO(mp)->inobt_maxlevels)
293304 return __this_address;
294305
295
- return xfs_btree_sblock_verify(bp, mp->m_inobt_mxr[level != 0]);
306
+ return xfs_btree_sblock_verify(bp,
307
+ M_IGEO(mp)->inobt_mxr[level != 0]);
296308 }
297309
298310 static void
....@@ -331,6 +343,16 @@
331343
332344 const struct xfs_buf_ops xfs_inobt_buf_ops = {
333345 .name = "xfs_inobt",
346
+ .magic = { cpu_to_be32(XFS_IBT_MAGIC), cpu_to_be32(XFS_IBT_CRC_MAGIC) },
347
+ .verify_read = xfs_inobt_read_verify,
348
+ .verify_write = xfs_inobt_write_verify,
349
+ .verify_struct = xfs_inobt_verify,
350
+};
351
+
352
+const struct xfs_buf_ops xfs_finobt_buf_ops = {
353
+ .name = "xfs_finobt",
354
+ .magic = { cpu_to_be32(XFS_FIBT_MAGIC),
355
+ cpu_to_be32(XFS_FIBT_CRC_MAGIC) },
334356 .verify_read = xfs_inobt_read_verify,
335357 .verify_write = xfs_inobt_write_verify,
336358 .verify_struct = xfs_inobt_verify,
....@@ -392,39 +414,34 @@
392414 .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
393415 .init_ptr_from_cur = xfs_finobt_init_ptr_from_cur,
394416 .key_diff = xfs_inobt_key_diff,
395
- .buf_ops = &xfs_inobt_buf_ops,
417
+ .buf_ops = &xfs_finobt_buf_ops,
396418 .diff_two_keys = xfs_inobt_diff_two_keys,
397419 .keys_inorder = xfs_inobt_keys_inorder,
398420 .recs_inorder = xfs_inobt_recs_inorder,
399421 };
400422
401423 /*
402
- * Allocate a new inode btree cursor.
424
+ * Initialize a new inode btree cursor.
403425 */
404
-struct xfs_btree_cur * /* new inode btree cursor */
405
-xfs_inobt_init_cursor(
426
+static struct xfs_btree_cur *
427
+xfs_inobt_init_common(
406428 struct xfs_mount *mp, /* file system mount point */
407429 struct xfs_trans *tp, /* transaction pointer */
408
- struct xfs_buf *agbp, /* buffer for agi structure */
409430 xfs_agnumber_t agno, /* allocation group number */
410431 xfs_btnum_t btnum) /* ialloc or free ino btree */
411432 {
412
- struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
413433 struct xfs_btree_cur *cur;
414434
415
- cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
416
-
435
+ cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL);
417436 cur->bc_tp = tp;
418437 cur->bc_mp = mp;
419438 cur->bc_btnum = btnum;
420439 if (btnum == XFS_BTNUM_INO) {
421
- cur->bc_nlevels = be32_to_cpu(agi->agi_level);
422
- cur->bc_ops = &xfs_inobt_ops;
423440 cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
441
+ cur->bc_ops = &xfs_inobt_ops;
424442 } else {
425
- cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
426
- cur->bc_ops = &xfs_finobt_ops;
427443 cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
444
+ cur->bc_ops = &xfs_finobt_ops;
428445 }
429446
430447 cur->bc_blocklog = mp->m_sb.sb_blocklog;
....@@ -432,10 +449,83 @@
432449 if (xfs_sb_version_hascrc(&mp->m_sb))
433450 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
434451
435
- cur->bc_private.a.agbp = agbp;
436
- cur->bc_private.a.agno = agno;
437
-
452
+ cur->bc_ag.agno = agno;
438453 return cur;
454
+}
455
+
456
+/* Create an inode btree cursor. */
457
+struct xfs_btree_cur *
458
+xfs_inobt_init_cursor(
459
+ struct xfs_mount *mp,
460
+ struct xfs_trans *tp,
461
+ struct xfs_buf *agbp,
462
+ xfs_agnumber_t agno,
463
+ xfs_btnum_t btnum)
464
+{
465
+ struct xfs_btree_cur *cur;
466
+ struct xfs_agi *agi = agbp->b_addr;
467
+
468
+ cur = xfs_inobt_init_common(mp, tp, agno, btnum);
469
+ if (btnum == XFS_BTNUM_INO)
470
+ cur->bc_nlevels = be32_to_cpu(agi->agi_level);
471
+ else
472
+ cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
473
+ cur->bc_ag.agbp = agbp;
474
+ return cur;
475
+}
476
+
477
+/* Create an inode btree cursor with a fake root for staging. */
478
+struct xfs_btree_cur *
479
+xfs_inobt_stage_cursor(
480
+ struct xfs_mount *mp,
481
+ struct xbtree_afakeroot *afake,
482
+ xfs_agnumber_t agno,
483
+ xfs_btnum_t btnum)
484
+{
485
+ struct xfs_btree_cur *cur;
486
+
487
+ cur = xfs_inobt_init_common(mp, NULL, agno, btnum);
488
+ xfs_btree_stage_afakeroot(cur, afake);
489
+ return cur;
490
+}
491
+
492
+/*
493
+ * Install a new inobt btree root. Caller is responsible for invalidating
494
+ * and freeing the old btree blocks.
495
+ */
496
+void
497
+xfs_inobt_commit_staged_btree(
498
+ struct xfs_btree_cur *cur,
499
+ struct xfs_trans *tp,
500
+ struct xfs_buf *agbp)
501
+{
502
+ struct xfs_agi *agi = agbp->b_addr;
503
+ struct xbtree_afakeroot *afake = cur->bc_ag.afake;
504
+ int fields;
505
+
506
+ ASSERT(cur->bc_flags & XFS_BTREE_STAGING);
507
+
508
+ if (cur->bc_btnum == XFS_BTNUM_INO) {
509
+ fields = XFS_AGI_ROOT | XFS_AGI_LEVEL;
510
+ agi->agi_root = cpu_to_be32(afake->af_root);
511
+ agi->agi_level = cpu_to_be32(afake->af_levels);
512
+ if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) {
513
+ agi->agi_iblocks = cpu_to_be32(afake->af_blocks);
514
+ fields |= XFS_AGI_IBLOCKS;
515
+ }
516
+ xfs_ialloc_log_agi(tp, agbp, fields);
517
+ xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_inobt_ops);
518
+ } else {
519
+ fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL;
520
+ agi->agi_free_root = cpu_to_be32(afake->af_root);
521
+ agi->agi_free_level = cpu_to_be32(afake->af_levels);
522
+ if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) {
523
+ agi->agi_fblocks = cpu_to_be32(afake->af_blocks);
524
+ fields |= XFS_AGI_IBLOCKS;
525
+ }
526
+ xfs_ialloc_log_agi(tp, agbp, fields);
527
+ xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_finobt_ops);
528
+ }
439529 }
440530
441531 /*
....@@ -538,15 +628,57 @@
538628
539629 static xfs_extlen_t
540630 xfs_inobt_max_size(
541
- struct xfs_mount *mp)
631
+ struct xfs_mount *mp,
632
+ xfs_agnumber_t agno)
542633 {
634
+ xfs_agblock_t agblocks = xfs_ag_block_count(mp, agno);
635
+
543636 /* Bail out if we're uninitialized, which can happen in mkfs. */
544
- if (mp->m_inobt_mxr[0] == 0)
637
+ if (M_IGEO(mp)->inobt_mxr[0] == 0)
545638 return 0;
546639
547
- return xfs_btree_calc_size(mp->m_inobt_mnr,
548
- (uint64_t)mp->m_sb.sb_agblocks * mp->m_sb.sb_inopblock /
549
- XFS_INODES_PER_CHUNK);
640
+ /*
641
+ * The log is permanently allocated, so the space it occupies will
642
+ * never be available for the kinds of things that would require btree
643
+ * expansion. We therefore can pretend the space isn't there.
644
+ */
645
+ if (mp->m_sb.sb_logstart &&
646
+ XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno)
647
+ agblocks -= mp->m_sb.sb_logblocks;
648
+
649
+ return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr,
650
+ (uint64_t)agblocks * mp->m_sb.sb_inopblock /
651
+ XFS_INODES_PER_CHUNK);
652
+}
653
+
654
+/* Read AGI and create inobt cursor. */
655
+int
656
+xfs_inobt_cur(
657
+ struct xfs_mount *mp,
658
+ struct xfs_trans *tp,
659
+ xfs_agnumber_t agno,
660
+ xfs_btnum_t which,
661
+ struct xfs_btree_cur **curpp,
662
+ struct xfs_buf **agi_bpp)
663
+{
664
+ struct xfs_btree_cur *cur;
665
+ int error;
666
+
667
+ ASSERT(*agi_bpp == NULL);
668
+ ASSERT(*curpp == NULL);
669
+
670
+ error = xfs_ialloc_read_agi(mp, tp, agno, agi_bpp);
671
+ if (error)
672
+ return error;
673
+
674
+ cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, agno, which);
675
+ if (!cur) {
676
+ xfs_trans_brelse(tp, *agi_bpp);
677
+ *agi_bpp = NULL;
678
+ return -ENOMEM;
679
+ }
680
+ *curpp = cur;
681
+ return 0;
550682 }
551683
552684 static int
....@@ -557,20 +689,41 @@
557689 xfs_btnum_t btnum,
558690 xfs_extlen_t *tree_blocks)
559691 {
692
+ struct xfs_buf *agbp = NULL;
693
+ struct xfs_btree_cur *cur = NULL;
694
+ int error;
695
+
696
+ error = xfs_inobt_cur(mp, tp, agno, btnum, &cur, &agbp);
697
+ if (error)
698
+ return error;
699
+
700
+ error = xfs_btree_count_blocks(cur, tree_blocks);
701
+ xfs_btree_del_cursor(cur, error);
702
+ xfs_trans_brelse(tp, agbp);
703
+
704
+ return error;
705
+}
706
+
707
+/* Read finobt block count from AGI header. */
708
+static int
709
+xfs_finobt_read_blocks(
710
+ struct xfs_mount *mp,
711
+ struct xfs_trans *tp,
712
+ xfs_agnumber_t agno,
713
+ xfs_extlen_t *tree_blocks)
714
+{
560715 struct xfs_buf *agbp;
561
- struct xfs_btree_cur *cur;
716
+ struct xfs_agi *agi;
562717 int error;
563718
564719 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
565720 if (error)
566721 return error;
567722
568
- cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
569
- error = xfs_btree_count_blocks(cur, tree_blocks);
570
- xfs_btree_del_cursor(cur, error);
723
+ agi = agbp->b_addr;
724
+ *tree_blocks = be32_to_cpu(agi->agi_fblocks);
571725 xfs_trans_brelse(tp, agbp);
572
-
573
- return error;
726
+ return 0;
574727 }
575728
576729 /*
....@@ -590,11 +743,15 @@
590743 if (!xfs_sb_version_hasfinobt(&mp->m_sb))
591744 return 0;
592745
593
- error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len);
746
+ if (xfs_sb_version_hasinobtcounts(&mp->m_sb))
747
+ error = xfs_finobt_read_blocks(mp, tp, agno, &tree_len);
748
+ else
749
+ error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO,
750
+ &tree_len);
594751 if (error)
595752 return error;
596753
597
- *ask += xfs_inobt_max_size(mp);
754
+ *ask += xfs_inobt_max_size(mp, agno);
598755 *used += tree_len;
599756 return 0;
600757 }
....@@ -605,5 +762,5 @@
605762 struct xfs_mount *mp,
606763 unsigned long long len)
607764 {
608
- return xfs_btree_calc_size(mp->m_inobt_mnr, len);
765
+ return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, len);
609766 }