0001
0002
0003
0004
0005
0006
0007
0008 #include "xfs.h"
0009 #include "xfs_fs.h"
0010 #include "xfs_shared.h"
0011 #include "xfs_format.h"
0012 #include "xfs_trans_resv.h"
0013 #include "xfs_bit.h"
0014 #include "xfs_sb.h"
0015 #include "xfs_mount.h"
0016 #include "xfs_btree.h"
0017 #include "xfs_alloc_btree.h"
0018 #include "xfs_rmap_btree.h"
0019 #include "xfs_alloc.h"
0020 #include "xfs_ialloc.h"
0021 #include "xfs_rmap.h"
0022 #include "xfs_ag.h"
0023 #include "xfs_ag_resv.h"
0024 #include "xfs_health.h"
0025 #include "xfs_error.h"
0026 #include "xfs_bmap.h"
0027 #include "xfs_defer.h"
0028 #include "xfs_log_format.h"
0029 #include "xfs_trans.h"
0030 #include "xfs_trace.h"
0031 #include "xfs_inode.h"
0032 #include "xfs_icache.h"
0033
0034
0035
0036
0037
0038
0039
0040
0041 struct xfs_perag *
0042 xfs_perag_get(
0043 struct xfs_mount *mp,
0044 xfs_agnumber_t agno)
0045 {
0046 struct xfs_perag *pag;
0047 int ref = 0;
0048
0049 rcu_read_lock();
0050 pag = radix_tree_lookup(&mp->m_perag_tree, agno);
0051 if (pag) {
0052 ASSERT(atomic_read(&pag->pag_ref) >= 0);
0053 ref = atomic_inc_return(&pag->pag_ref);
0054 }
0055 rcu_read_unlock();
0056 trace_xfs_perag_get(mp, agno, ref, _RET_IP_);
0057 return pag;
0058 }
0059
0060
0061
0062
0063 struct xfs_perag *
0064 xfs_perag_get_tag(
0065 struct xfs_mount *mp,
0066 xfs_agnumber_t first,
0067 unsigned int tag)
0068 {
0069 struct xfs_perag *pag;
0070 int found;
0071 int ref;
0072
0073 rcu_read_lock();
0074 found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
0075 (void **)&pag, first, 1, tag);
0076 if (found <= 0) {
0077 rcu_read_unlock();
0078 return NULL;
0079 }
0080 ref = atomic_inc_return(&pag->pag_ref);
0081 rcu_read_unlock();
0082 trace_xfs_perag_get_tag(mp, pag->pag_agno, ref, _RET_IP_);
0083 return pag;
0084 }
0085
0086 void
0087 xfs_perag_put(
0088 struct xfs_perag *pag)
0089 {
0090 int ref;
0091
0092 ASSERT(atomic_read(&pag->pag_ref) > 0);
0093 ref = atomic_dec_return(&pag->pag_ref);
0094 trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_);
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 int
0106 xfs_initialize_perag_data(
0107 struct xfs_mount *mp,
0108 xfs_agnumber_t agcount)
0109 {
0110 xfs_agnumber_t index;
0111 struct xfs_perag *pag;
0112 struct xfs_sb *sbp = &mp->m_sb;
0113 uint64_t ifree = 0;
0114 uint64_t ialloc = 0;
0115 uint64_t bfree = 0;
0116 uint64_t bfreelst = 0;
0117 uint64_t btree = 0;
0118 uint64_t fdblocks;
0119 int error = 0;
0120
0121 for (index = 0; index < agcount; index++) {
0122
0123
0124
0125
0126 pag = xfs_perag_get(mp, index);
0127 error = xfs_alloc_read_agf(pag, NULL, 0, NULL);
0128 if (!error)
0129 error = xfs_ialloc_read_agi(pag, NULL, NULL);
0130 if (error) {
0131 xfs_perag_put(pag);
0132 return error;
0133 }
0134
0135 ifree += pag->pagi_freecount;
0136 ialloc += pag->pagi_count;
0137 bfree += pag->pagf_freeblks;
0138 bfreelst += pag->pagf_flcount;
0139 btree += pag->pagf_btreeblks;
0140 xfs_perag_put(pag);
0141 }
0142 fdblocks = bfree + bfreelst + btree;
0143
0144
0145
0146
0147
0148
0149
0150 if (fdblocks > sbp->sb_dblocks || ifree > ialloc) {
0151 xfs_alert(mp, "AGF corruption. Please run xfs_repair.");
0152 error = -EFSCORRUPTED;
0153 goto out;
0154 }
0155
0156
0157 spin_lock(&mp->m_sb_lock);
0158 sbp->sb_ifree = ifree;
0159 sbp->sb_icount = ialloc;
0160 sbp->sb_fdblocks = fdblocks;
0161 spin_unlock(&mp->m_sb_lock);
0162
0163 xfs_reinit_percpu_counters(mp);
0164 out:
0165 xfs_fs_mark_healthy(mp, XFS_SICK_FS_COUNTERS);
0166 return error;
0167 }
0168
0169 STATIC void
0170 __xfs_free_perag(
0171 struct rcu_head *head)
0172 {
0173 struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head);
0174
0175 ASSERT(!delayed_work_pending(&pag->pag_blockgc_work));
0176 kmem_free(pag);
0177 }
0178
0179
0180
0181
0182 void
0183 xfs_free_perag(
0184 struct xfs_mount *mp)
0185 {
0186 struct xfs_perag *pag;
0187 xfs_agnumber_t agno;
0188
0189 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
0190 spin_lock(&mp->m_perag_lock);
0191 pag = radix_tree_delete(&mp->m_perag_tree, agno);
0192 spin_unlock(&mp->m_perag_lock);
0193 ASSERT(pag);
0194 XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0);
0195
0196 cancel_delayed_work_sync(&pag->pag_blockgc_work);
0197 xfs_buf_hash_destroy(pag);
0198
0199 call_rcu(&pag->rcu_head, __xfs_free_perag);
0200 }
0201 }
0202
0203
0204 static xfs_agblock_t
0205 __xfs_ag_block_count(
0206 struct xfs_mount *mp,
0207 xfs_agnumber_t agno,
0208 xfs_agnumber_t agcount,
0209 xfs_rfsblock_t dblocks)
0210 {
0211 ASSERT(agno < agcount);
0212
0213 if (agno < agcount - 1)
0214 return mp->m_sb.sb_agblocks;
0215 return dblocks - (agno * mp->m_sb.sb_agblocks);
0216 }
0217
0218 xfs_agblock_t
0219 xfs_ag_block_count(
0220 struct xfs_mount *mp,
0221 xfs_agnumber_t agno)
0222 {
0223 return __xfs_ag_block_count(mp, agno, mp->m_sb.sb_agcount,
0224 mp->m_sb.sb_dblocks);
0225 }
0226
0227
0228 static void
0229 __xfs_agino_range(
0230 struct xfs_mount *mp,
0231 xfs_agblock_t eoag,
0232 xfs_agino_t *first,
0233 xfs_agino_t *last)
0234 {
0235 xfs_agblock_t bno;
0236
0237
0238
0239
0240
0241 bno = round_up(XFS_AGFL_BLOCK(mp) + 1, M_IGEO(mp)->cluster_align);
0242 *first = XFS_AGB_TO_AGINO(mp, bno);
0243
0244
0245
0246
0247
0248 bno = round_down(eoag, M_IGEO(mp)->cluster_align);
0249 *last = XFS_AGB_TO_AGINO(mp, bno) - 1;
0250 }
0251
0252 void
0253 xfs_agino_range(
0254 struct xfs_mount *mp,
0255 xfs_agnumber_t agno,
0256 xfs_agino_t *first,
0257 xfs_agino_t *last)
0258 {
0259 return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
0260 }
0261
0262 int
0263 xfs_initialize_perag(
0264 struct xfs_mount *mp,
0265 xfs_agnumber_t agcount,
0266 xfs_rfsblock_t dblocks,
0267 xfs_agnumber_t *maxagi)
0268 {
0269 struct xfs_perag *pag;
0270 xfs_agnumber_t index;
0271 xfs_agnumber_t first_initialised = NULLAGNUMBER;
0272 int error;
0273
0274
0275
0276
0277
0278
0279 for (index = 0; index < agcount; index++) {
0280 pag = xfs_perag_get(mp, index);
0281 if (pag) {
0282 xfs_perag_put(pag);
0283 continue;
0284 }
0285
0286 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);
0287 if (!pag) {
0288 error = -ENOMEM;
0289 goto out_unwind_new_pags;
0290 }
0291 pag->pag_agno = index;
0292 pag->pag_mount = mp;
0293
0294 error = radix_tree_preload(GFP_NOFS);
0295 if (error)
0296 goto out_free_pag;
0297
0298 spin_lock(&mp->m_perag_lock);
0299 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
0300 WARN_ON_ONCE(1);
0301 spin_unlock(&mp->m_perag_lock);
0302 radix_tree_preload_end();
0303 error = -EEXIST;
0304 goto out_free_pag;
0305 }
0306 spin_unlock(&mp->m_perag_lock);
0307 radix_tree_preload_end();
0308
0309 #ifdef __KERNEL__
0310
0311 spin_lock_init(&pag->pag_ici_lock);
0312 spin_lock_init(&pag->pagb_lock);
0313 spin_lock_init(&pag->pag_state_lock);
0314 INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
0315 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
0316 init_waitqueue_head(&pag->pagb_wait);
0317 pag->pagb_count = 0;
0318 pag->pagb_tree = RB_ROOT;
0319 #endif
0320
0321 error = xfs_buf_hash_init(pag);
0322 if (error)
0323 goto out_remove_pag;
0324
0325
0326 if (first_initialised == NULLAGNUMBER)
0327 first_initialised = index;
0328
0329
0330
0331
0332 pag->block_count = __xfs_ag_block_count(mp, index, agcount,
0333 dblocks);
0334 pag->min_block = XFS_AGFL_BLOCK(mp);
0335 __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
0336 &pag->agino_max);
0337 }
0338
0339 index = xfs_set_inode_alloc(mp, agcount);
0340
0341 if (maxagi)
0342 *maxagi = index;
0343
0344 mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
0345 return 0;
0346
0347 out_remove_pag:
0348 radix_tree_delete(&mp->m_perag_tree, index);
0349 out_free_pag:
0350 kmem_free(pag);
0351 out_unwind_new_pags:
0352
0353 for (index = first_initialised; index < agcount; index++) {
0354 pag = radix_tree_delete(&mp->m_perag_tree, index);
0355 if (!pag)
0356 break;
0357 xfs_buf_hash_destroy(pag);
0358 kmem_free(pag);
0359 }
0360 return error;
0361 }
0362
0363 static int
0364 xfs_get_aghdr_buf(
0365 struct xfs_mount *mp,
0366 xfs_daddr_t blkno,
0367 size_t numblks,
0368 struct xfs_buf **bpp,
0369 const struct xfs_buf_ops *ops)
0370 {
0371 struct xfs_buf *bp;
0372 int error;
0373
0374 error = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0, &bp);
0375 if (error)
0376 return error;
0377
0378 bp->b_maps[0].bm_bn = blkno;
0379 bp->b_ops = ops;
0380
0381 *bpp = bp;
0382 return 0;
0383 }
0384
0385
0386
0387
0388 static void
0389 xfs_btroot_init(
0390 struct xfs_mount *mp,
0391 struct xfs_buf *bp,
0392 struct aghdr_init_data *id)
0393 {
0394 xfs_btree_init_block(mp, bp, id->type, 0, 0, id->agno);
0395 }
0396
0397
0398 static void
0399 xfs_freesp_init_recs(
0400 struct xfs_mount *mp,
0401 struct xfs_buf *bp,
0402 struct aghdr_init_data *id)
0403 {
0404 struct xfs_alloc_rec *arec;
0405 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
0406
0407 arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
0408 arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks);
0409
0410 if (xfs_ag_contains_log(mp, id->agno)) {
0411 struct xfs_alloc_rec *nrec;
0412 xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp,
0413 mp->m_sb.sb_logstart);
0414
0415 ASSERT(start >= mp->m_ag_prealloc_blocks);
0416 if (start != mp->m_ag_prealloc_blocks) {
0417
0418
0419
0420 arec->ar_blockcount = cpu_to_be32(start -
0421 mp->m_ag_prealloc_blocks);
0422 nrec = arec + 1;
0423
0424
0425
0426
0427
0428 nrec->ar_startblock = cpu_to_be32(
0429 be32_to_cpu(arec->ar_startblock) +
0430 be32_to_cpu(arec->ar_blockcount));
0431 arec = nrec;
0432 be16_add_cpu(&block->bb_numrecs, 1);
0433 }
0434
0435
0436
0437 be32_add_cpu(&arec->ar_startblock, mp->m_sb.sb_logblocks);
0438 }
0439
0440
0441
0442
0443
0444
0445
0446 arec->ar_blockcount = cpu_to_be32(id->agsize -
0447 be32_to_cpu(arec->ar_startblock));
0448 if (!arec->ar_blockcount)
0449 block->bb_numrecs = 0;
0450 }
0451
0452
0453
0454
0455 static void
0456 xfs_bnoroot_init(
0457 struct xfs_mount *mp,
0458 struct xfs_buf *bp,
0459 struct aghdr_init_data *id)
0460 {
0461 xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno);
0462 xfs_freesp_init_recs(mp, bp, id);
0463 }
0464
0465 static void
0466 xfs_cntroot_init(
0467 struct xfs_mount *mp,
0468 struct xfs_buf *bp,
0469 struct aghdr_init_data *id)
0470 {
0471 xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno);
0472 xfs_freesp_init_recs(mp, bp, id);
0473 }
0474
0475
0476
0477
0478 static void
0479 xfs_rmaproot_init(
0480 struct xfs_mount *mp,
0481 struct xfs_buf *bp,
0482 struct aghdr_init_data *id)
0483 {
0484 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
0485 struct xfs_rmap_rec *rrec;
0486
0487 xfs_btree_init_block(mp, bp, XFS_BTNUM_RMAP, 0, 4, id->agno);
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 rrec = XFS_RMAP_REC_ADDR(block, 1);
0499 rrec->rm_startblock = 0;
0500 rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
0501 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
0502 rrec->rm_offset = 0;
0503
0504
0505 rrec = XFS_RMAP_REC_ADDR(block, 2);
0506 rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
0507 rrec->rm_blockcount = cpu_to_be32(2);
0508 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
0509 rrec->rm_offset = 0;
0510
0511
0512 rrec = XFS_RMAP_REC_ADDR(block, 3);
0513 rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
0514 rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
0515 XFS_IBT_BLOCK(mp));
0516 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
0517 rrec->rm_offset = 0;
0518
0519
0520 rrec = XFS_RMAP_REC_ADDR(block, 4);
0521 rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
0522 rrec->rm_blockcount = cpu_to_be32(1);
0523 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
0524 rrec->rm_offset = 0;
0525
0526
0527 if (xfs_has_reflink(mp)) {
0528 rrec = XFS_RMAP_REC_ADDR(block, 5);
0529 rrec->rm_startblock = cpu_to_be32(xfs_refc_block(mp));
0530 rrec->rm_blockcount = cpu_to_be32(1);
0531 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
0532 rrec->rm_offset = 0;
0533 be16_add_cpu(&block->bb_numrecs, 1);
0534 }
0535
0536
0537 if (xfs_ag_contains_log(mp, id->agno)) {
0538 rrec = XFS_RMAP_REC_ADDR(block,
0539 be16_to_cpu(block->bb_numrecs) + 1);
0540 rrec->rm_startblock = cpu_to_be32(
0541 XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart));
0542 rrec->rm_blockcount = cpu_to_be32(mp->m_sb.sb_logblocks);
0543 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
0544 rrec->rm_offset = 0;
0545 be16_add_cpu(&block->bb_numrecs, 1);
0546 }
0547 }
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 static void
0558 xfs_sbblock_init(
0559 struct xfs_mount *mp,
0560 struct xfs_buf *bp,
0561 struct aghdr_init_data *id)
0562 {
0563 struct xfs_dsb *dsb = bp->b_addr;
0564
0565 xfs_sb_to_disk(dsb, &mp->m_sb);
0566 dsb->sb_inprogress = 1;
0567 }
0568
0569 static void
0570 xfs_agfblock_init(
0571 struct xfs_mount *mp,
0572 struct xfs_buf *bp,
0573 struct aghdr_init_data *id)
0574 {
0575 struct xfs_agf *agf = bp->b_addr;
0576 xfs_extlen_t tmpsize;
0577
0578 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
0579 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
0580 agf->agf_seqno = cpu_to_be32(id->agno);
0581 agf->agf_length = cpu_to_be32(id->agsize);
0582 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
0583 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
0584 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
0585 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
0586 if (xfs_has_rmapbt(mp)) {
0587 agf->agf_roots[XFS_BTNUM_RMAPi] =
0588 cpu_to_be32(XFS_RMAP_BLOCK(mp));
0589 agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
0590 agf->agf_rmap_blocks = cpu_to_be32(1);
0591 }
0592
0593 agf->agf_flfirst = cpu_to_be32(1);
0594 agf->agf_fllast = 0;
0595 agf->agf_flcount = 0;
0596 tmpsize = id->agsize - mp->m_ag_prealloc_blocks;
0597 agf->agf_freeblks = cpu_to_be32(tmpsize);
0598 agf->agf_longest = cpu_to_be32(tmpsize);
0599 if (xfs_has_crc(mp))
0600 uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
0601 if (xfs_has_reflink(mp)) {
0602 agf->agf_refcount_root = cpu_to_be32(
0603 xfs_refc_block(mp));
0604 agf->agf_refcount_level = cpu_to_be32(1);
0605 agf->agf_refcount_blocks = cpu_to_be32(1);
0606 }
0607
0608 if (xfs_ag_contains_log(mp, id->agno)) {
0609 int64_t logblocks = mp->m_sb.sb_logblocks;
0610
0611 be32_add_cpu(&agf->agf_freeblks, -logblocks);
0612 agf->agf_longest = cpu_to_be32(id->agsize -
0613 XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart) - logblocks);
0614 }
0615 }
0616
0617 static void
0618 xfs_agflblock_init(
0619 struct xfs_mount *mp,
0620 struct xfs_buf *bp,
0621 struct aghdr_init_data *id)
0622 {
0623 struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
0624 __be32 *agfl_bno;
0625 int bucket;
0626
0627 if (xfs_has_crc(mp)) {
0628 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
0629 agfl->agfl_seqno = cpu_to_be32(id->agno);
0630 uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
0631 }
0632
0633 agfl_bno = xfs_buf_to_agfl_bno(bp);
0634 for (bucket = 0; bucket < xfs_agfl_size(mp); bucket++)
0635 agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
0636 }
0637
0638 static void
0639 xfs_agiblock_init(
0640 struct xfs_mount *mp,
0641 struct xfs_buf *bp,
0642 struct aghdr_init_data *id)
0643 {
0644 struct xfs_agi *agi = bp->b_addr;
0645 int bucket;
0646
0647 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
0648 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
0649 agi->agi_seqno = cpu_to_be32(id->agno);
0650 agi->agi_length = cpu_to_be32(id->agsize);
0651 agi->agi_count = 0;
0652 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
0653 agi->agi_level = cpu_to_be32(1);
0654 agi->agi_freecount = 0;
0655 agi->agi_newino = cpu_to_be32(NULLAGINO);
0656 agi->agi_dirino = cpu_to_be32(NULLAGINO);
0657 if (xfs_has_crc(mp))
0658 uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
0659 if (xfs_has_finobt(mp)) {
0660 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
0661 agi->agi_free_level = cpu_to_be32(1);
0662 }
0663 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
0664 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
0665 if (xfs_has_inobtcounts(mp)) {
0666 agi->agi_iblocks = cpu_to_be32(1);
0667 if (xfs_has_finobt(mp))
0668 agi->agi_fblocks = cpu_to_be32(1);
0669 }
0670 }
0671
0672 typedef void (*aghdr_init_work_f)(struct xfs_mount *mp, struct xfs_buf *bp,
0673 struct aghdr_init_data *id);
0674 static int
0675 xfs_ag_init_hdr(
0676 struct xfs_mount *mp,
0677 struct aghdr_init_data *id,
0678 aghdr_init_work_f work,
0679 const struct xfs_buf_ops *ops)
0680 {
0681 struct xfs_buf *bp;
0682 int error;
0683
0684 error = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, &bp, ops);
0685 if (error)
0686 return error;
0687
0688 (*work)(mp, bp, id);
0689
0690 xfs_buf_delwri_queue(bp, &id->buffer_list);
0691 xfs_buf_relse(bp);
0692 return 0;
0693 }
0694
0695 struct xfs_aghdr_grow_data {
0696 xfs_daddr_t daddr;
0697 size_t numblks;
0698 const struct xfs_buf_ops *ops;
0699 aghdr_init_work_f work;
0700 xfs_btnum_t type;
0701 bool need_init;
0702 };
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 int
0715 xfs_ag_init_headers(
0716 struct xfs_mount *mp,
0717 struct aghdr_init_data *id)
0718
0719 {
0720 struct xfs_aghdr_grow_data aghdr_data[] = {
0721 {
0722 .daddr = XFS_AG_DADDR(mp, id->agno, XFS_SB_DADDR),
0723 .numblks = XFS_FSS_TO_BB(mp, 1),
0724 .ops = &xfs_sb_buf_ops,
0725 .work = &xfs_sbblock_init,
0726 .need_init = true
0727 },
0728 {
0729 .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGF_DADDR(mp)),
0730 .numblks = XFS_FSS_TO_BB(mp, 1),
0731 .ops = &xfs_agf_buf_ops,
0732 .work = &xfs_agfblock_init,
0733 .need_init = true
0734 },
0735 {
0736 .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGFL_DADDR(mp)),
0737 .numblks = XFS_FSS_TO_BB(mp, 1),
0738 .ops = &xfs_agfl_buf_ops,
0739 .work = &xfs_agflblock_init,
0740 .need_init = true
0741 },
0742 {
0743 .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGI_DADDR(mp)),
0744 .numblks = XFS_FSS_TO_BB(mp, 1),
0745 .ops = &xfs_agi_buf_ops,
0746 .work = &xfs_agiblock_init,
0747 .need_init = true
0748 },
0749 {
0750 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_BNO_BLOCK(mp)),
0751 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0752 .ops = &xfs_bnobt_buf_ops,
0753 .work = &xfs_bnoroot_init,
0754 .need_init = true
0755 },
0756 {
0757 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_CNT_BLOCK(mp)),
0758 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0759 .ops = &xfs_cntbt_buf_ops,
0760 .work = &xfs_cntroot_init,
0761 .need_init = true
0762 },
0763 {
0764 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_IBT_BLOCK(mp)),
0765 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0766 .ops = &xfs_inobt_buf_ops,
0767 .work = &xfs_btroot_init,
0768 .type = XFS_BTNUM_INO,
0769 .need_init = true
0770 },
0771 {
0772 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_FIBT_BLOCK(mp)),
0773 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0774 .ops = &xfs_finobt_buf_ops,
0775 .work = &xfs_btroot_init,
0776 .type = XFS_BTNUM_FINO,
0777 .need_init = xfs_has_finobt(mp)
0778 },
0779 {
0780 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_RMAP_BLOCK(mp)),
0781 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0782 .ops = &xfs_rmapbt_buf_ops,
0783 .work = &xfs_rmaproot_init,
0784 .need_init = xfs_has_rmapbt(mp)
0785 },
0786 {
0787 .daddr = XFS_AGB_TO_DADDR(mp, id->agno, xfs_refc_block(mp)),
0788 .numblks = BTOBB(mp->m_sb.sb_blocksize),
0789 .ops = &xfs_refcountbt_buf_ops,
0790 .work = &xfs_btroot_init,
0791 .type = XFS_BTNUM_REFC,
0792 .need_init = xfs_has_reflink(mp)
0793 },
0794 {
0795 .daddr = XFS_BUF_DADDR_NULL,
0796 }
0797 };
0798 struct xfs_aghdr_grow_data *dp;
0799 int error = 0;
0800
0801
0802 id->nfree += id->agsize - mp->m_ag_prealloc_blocks;
0803 for (dp = &aghdr_data[0]; dp->daddr != XFS_BUF_DADDR_NULL; dp++) {
0804 if (!dp->need_init)
0805 continue;
0806
0807 id->daddr = dp->daddr;
0808 id->numblks = dp->numblks;
0809 id->type = dp->type;
0810 error = xfs_ag_init_hdr(mp, id, dp->work, dp->ops);
0811 if (error)
0812 break;
0813 }
0814 return error;
0815 }
0816
0817 int
0818 xfs_ag_shrink_space(
0819 struct xfs_perag *pag,
0820 struct xfs_trans **tpp,
0821 xfs_extlen_t delta)
0822 {
0823 struct xfs_mount *mp = pag->pag_mount;
0824 struct xfs_alloc_arg args = {
0825 .tp = *tpp,
0826 .mp = mp,
0827 .type = XFS_ALLOCTYPE_THIS_BNO,
0828 .minlen = delta,
0829 .maxlen = delta,
0830 .oinfo = XFS_RMAP_OINFO_SKIP_UPDATE,
0831 .resv = XFS_AG_RESV_NONE,
0832 .prod = 1
0833 };
0834 struct xfs_buf *agibp, *agfbp;
0835 struct xfs_agi *agi;
0836 struct xfs_agf *agf;
0837 xfs_agblock_t aglen;
0838 int error, err2;
0839
0840 ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1);
0841 error = xfs_ialloc_read_agi(pag, *tpp, &agibp);
0842 if (error)
0843 return error;
0844
0845 agi = agibp->b_addr;
0846
0847 error = xfs_alloc_read_agf(pag, *tpp, 0, &agfbp);
0848 if (error)
0849 return error;
0850
0851 agf = agfbp->b_addr;
0852 aglen = be32_to_cpu(agi->agi_length);
0853
0854 if (XFS_IS_CORRUPT(mp, agf->agf_length != agi->agi_length))
0855 return -EFSCORRUPTED;
0856 if (delta >= aglen)
0857 return -EINVAL;
0858
0859 args.fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, aglen - delta);
0860
0861
0862
0863
0864
0865 error = xfs_ialloc_check_shrink(*tpp, pag->pag_agno, agibp,
0866 aglen - delta);
0867 if (error)
0868 return error;
0869
0870
0871
0872
0873
0874 error = xfs_ag_resv_free(pag);
0875 if (error)
0876 return error;
0877
0878
0879 error = xfs_alloc_vextent(&args);
0880 if (!error && args.agbno == NULLAGBLOCK)
0881 error = -ENOSPC;
0882
0883 if (error) {
0884
0885
0886
0887
0888 xfs_trans_bhold(*tpp, agfbp);
0889 err2 = xfs_trans_roll(tpp);
0890 if (err2)
0891 return err2;
0892 xfs_trans_bjoin(*tpp, agfbp);
0893 goto resv_init_out;
0894 }
0895
0896
0897
0898
0899
0900 be32_add_cpu(&agi->agi_length, -delta);
0901 be32_add_cpu(&agf->agf_length, -delta);
0902
0903 err2 = xfs_ag_resv_init(pag, *tpp);
0904 if (err2) {
0905 be32_add_cpu(&agi->agi_length, delta);
0906 be32_add_cpu(&agf->agf_length, delta);
0907 if (err2 != -ENOSPC)
0908 goto resv_err;
0909
0910 __xfs_free_extent_later(*tpp, args.fsbno, delta, NULL, true);
0911
0912
0913
0914
0915
0916
0917 error = xfs_defer_finish(tpp);
0918 if (error)
0919 return error;
0920
0921 error = -ENOSPC;
0922 goto resv_init_out;
0923 }
0924 xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH);
0925 xfs_alloc_log_agf(*tpp, agfbp, XFS_AGF_LENGTH);
0926 return 0;
0927
0928 resv_init_out:
0929 err2 = xfs_ag_resv_init(pag, *tpp);
0930 if (!err2)
0931 return error;
0932 resv_err:
0933 xfs_warn(mp, "Error %d reserving per-AG metadata reserve pool.", err2);
0934 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
0935 return err2;
0936 }
0937
0938
0939
0940
0941 int
0942 xfs_ag_extend_space(
0943 struct xfs_perag *pag,
0944 struct xfs_trans *tp,
0945 xfs_extlen_t len)
0946 {
0947 struct xfs_buf *bp;
0948 struct xfs_agi *agi;
0949 struct xfs_agf *agf;
0950 int error;
0951
0952 ASSERT(pag->pag_agno == pag->pag_mount->m_sb.sb_agcount - 1);
0953
0954 error = xfs_ialloc_read_agi(pag, tp, &bp);
0955 if (error)
0956 return error;
0957
0958 agi = bp->b_addr;
0959 be32_add_cpu(&agi->agi_length, len);
0960 xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
0961
0962
0963
0964
0965 error = xfs_alloc_read_agf(pag, tp, 0, &bp);
0966 if (error)
0967 return error;
0968
0969 agf = bp->b_addr;
0970 be32_add_cpu(&agf->agf_length, len);
0971 ASSERT(agf->agf_length == agi->agi_length);
0972 xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
0973
0974
0975
0976
0977
0978
0979
0980 error = xfs_rmap_free(tp, bp, pag, be32_to_cpu(agf->agf_length) - len,
0981 len, &XFS_RMAP_OINFO_SKIP_UPDATE);
0982 if (error)
0983 return error;
0984
0985 error = xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno,
0986 be32_to_cpu(agf->agf_length) - len),
0987 len, &XFS_RMAP_OINFO_SKIP_UPDATE,
0988 XFS_AG_RESV_NONE);
0989 if (error)
0990 return error;
0991
0992
0993 pag->block_count = be32_to_cpu(agf->agf_length);
0994 __xfs_agino_range(pag->pag_mount, pag->block_count, &pag->agino_min,
0995 &pag->agino_max);
0996 return 0;
0997 }
0998
0999
1000 int
1001 xfs_ag_get_geometry(
1002 struct xfs_perag *pag,
1003 struct xfs_ag_geometry *ageo)
1004 {
1005 struct xfs_buf *agi_bp;
1006 struct xfs_buf *agf_bp;
1007 struct xfs_agi *agi;
1008 struct xfs_agf *agf;
1009 unsigned int freeblks;
1010 int error;
1011
1012
1013 error = xfs_ialloc_read_agi(pag, NULL, &agi_bp);
1014 if (error)
1015 return error;
1016 error = xfs_alloc_read_agf(pag, NULL, 0, &agf_bp);
1017 if (error)
1018 goto out_agi;
1019
1020
1021 memset(ageo, 0, sizeof(*ageo));
1022 ageo->ag_number = pag->pag_agno;
1023
1024 agi = agi_bp->b_addr;
1025 ageo->ag_icount = be32_to_cpu(agi->agi_count);
1026 ageo->ag_ifree = be32_to_cpu(agi->agi_freecount);
1027
1028 agf = agf_bp->b_addr;
1029 ageo->ag_length = be32_to_cpu(agf->agf_length);
1030 freeblks = pag->pagf_freeblks +
1031 pag->pagf_flcount +
1032 pag->pagf_btreeblks -
1033 xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE);
1034 ageo->ag_freeblks = freeblks;
1035 xfs_ag_geom_health(pag, ageo);
1036
1037
1038 xfs_buf_relse(agf_bp);
1039 out_agi:
1040 xfs_buf_relse(agi_bp);
1041 return error;
1042 }