Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: pass transaction lock while setting up agresv on cyclic metadata

Pass a tranaction pointer through to all helpers that calculate the
per-AG block reservation. Online repair will use this to reinitialize
per-ag reservations while it still holds all the AG headers locked to
the repair transaction.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>

+26 -20
+7 -6
fs/xfs/libxfs/xfs_ag_resv.c
··· 248 248 /* Create a per-AG block reservation. */ 249 249 int 250 250 xfs_ag_resv_init( 251 - struct xfs_perag *pag) 251 + struct xfs_perag *pag, 252 + struct xfs_trans *tp) 252 253 { 253 254 struct xfs_mount *mp = pag->pag_mount; 254 255 xfs_agnumber_t agno = pag->pag_agno; ··· 261 260 if (pag->pag_meta_resv.ar_asked == 0) { 262 261 ask = used = 0; 263 262 264 - error = xfs_refcountbt_calc_reserves(mp, agno, &ask, &used); 263 + error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, &used); 265 264 if (error) 266 265 goto out; 267 266 268 - error = xfs_finobt_calc_reserves(mp, agno, &ask, &used); 267 + error = xfs_finobt_calc_reserves(mp, tp, agno, &ask, &used); 269 268 if (error) 270 269 goto out; 271 270 ··· 283 282 284 283 mp->m_inotbt_nores = true; 285 284 286 - error = xfs_refcountbt_calc_reserves(mp, agno, &ask, 285 + error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, 287 286 &used); 288 287 if (error) 289 288 goto out; ··· 299 298 if (pag->pag_rmapbt_resv.ar_asked == 0) { 300 299 ask = used = 0; 301 300 302 - error = xfs_rmapbt_calc_reserves(mp, agno, &ask, &used); 301 + error = xfs_rmapbt_calc_reserves(mp, tp, agno, &ask, &used); 303 302 if (error) 304 303 goto out; 305 304 ··· 310 309 311 310 #ifdef DEBUG 312 311 /* need to read in the AGF for the ASSERT below to work */ 313 - error = xfs_alloc_pagf_init(pag->pag_mount, NULL, pag->pag_agno, 0); 312 + error = xfs_alloc_pagf_init(pag->pag_mount, tp, pag->pag_agno, 0); 314 313 if (error) 315 314 return error; 316 315
+1 -1
fs/xfs/libxfs/xfs_ag_resv.h
··· 7 7 #define __XFS_AG_RESV_H__ 8 8 9 9 int xfs_ag_resv_free(struct xfs_perag *pag); 10 - int xfs_ag_resv_init(struct xfs_perag *pag); 10 + int xfs_ag_resv_init(struct xfs_perag *pag, struct xfs_trans *tp); 11 11 12 12 bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type); 13 13 xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag,
+6 -4
fs/xfs/libxfs/xfs_ialloc_btree.c
··· 552 552 static int 553 553 xfs_inobt_count_blocks( 554 554 struct xfs_mount *mp, 555 + struct xfs_trans *tp, 555 556 xfs_agnumber_t agno, 556 557 xfs_btnum_t btnum, 557 558 xfs_extlen_t *tree_blocks) ··· 561 560 struct xfs_btree_cur *cur; 562 561 int error; 563 562 564 - error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); 563 + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); 565 564 if (error) 566 565 return error; 567 566 568 - cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); 567 + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); 569 568 error = xfs_btree_count_blocks(cur, tree_blocks); 570 569 xfs_btree_del_cursor(cur, error); 571 - xfs_buf_relse(agbp); 570 + xfs_trans_brelse(tp, agbp); 572 571 573 572 return error; 574 573 } ··· 579 578 int 580 579 xfs_finobt_calc_reserves( 581 580 struct xfs_mount *mp, 581 + struct xfs_trans *tp, 582 582 xfs_agnumber_t agno, 583 583 xfs_extlen_t *ask, 584 584 xfs_extlen_t *used) ··· 590 588 if (!xfs_sb_version_hasfinobt(&mp->m_sb)) 591 589 return 0; 592 590 593 - error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len); 591 + error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len); 594 592 if (error) 595 593 return error; 596 594
+2 -2
fs/xfs/libxfs/xfs_ialloc_btree.h
··· 60 60 #define xfs_inobt_rec_check_count(mp, rec) 0 61 61 #endif /* DEBUG */ 62 62 63 - int xfs_finobt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, 64 - xfs_extlen_t *ask, xfs_extlen_t *used); 63 + int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, 64 + xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); 65 65 extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, 66 66 unsigned long long len); 67 67
+3 -2
fs/xfs/libxfs/xfs_refcount_btree.c
··· 404 404 int 405 405 xfs_refcountbt_calc_reserves( 406 406 struct xfs_mount *mp, 407 + struct xfs_trans *tp, 407 408 xfs_agnumber_t agno, 408 409 xfs_extlen_t *ask, 409 410 xfs_extlen_t *used) ··· 419 418 return 0; 420 419 421 420 422 - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); 421 + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); 423 422 if (error) 424 423 return error; 425 424 426 425 agf = XFS_BUF_TO_AGF(agbp); 427 426 agblocks = be32_to_cpu(agf->agf_length); 428 427 tree_len = be32_to_cpu(agf->agf_refcount_blocks); 429 - xfs_buf_relse(agbp); 428 + xfs_trans_brelse(tp, agbp); 430 429 431 430 *ask += xfs_refcountbt_max_size(mp, agblocks); 432 431 *used += tree_len;
+2 -1
fs/xfs/libxfs/xfs_refcount_btree.h
··· 55 55 xfs_agblock_t agblocks); 56 56 57 57 extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, 58 - xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); 58 + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, 59 + xfs_extlen_t *used); 59 60 60 61 #endif /* __XFS_REFCOUNT_BTREE_H__ */
+3 -2
fs/xfs/libxfs/xfs_rmap_btree.c
··· 554 554 int 555 555 xfs_rmapbt_calc_reserves( 556 556 struct xfs_mount *mp, 557 + struct xfs_trans *tp, 557 558 xfs_agnumber_t agno, 558 559 xfs_extlen_t *ask, 559 560 xfs_extlen_t *used) ··· 568 567 if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) 569 568 return 0; 570 569 571 - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); 570 + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); 572 571 if (error) 573 572 return error; 574 573 575 574 agf = XFS_BUF_TO_AGF(agbp); 576 575 agblocks = be32_to_cpu(agf->agf_length); 577 576 tree_len = be32_to_cpu(agf->agf_rmap_blocks); 578 - xfs_buf_relse(agbp); 577 + xfs_trans_brelse(tp, agbp); 579 578 580 579 /* Reserve 1% of the AG or enough for 1 block per record. */ 581 580 *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks));
+1 -1
fs/xfs/libxfs/xfs_rmap_btree.h
··· 51 51 extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, 52 52 xfs_agblock_t agblocks); 53 53 54 - extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, 54 + extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, 55 55 xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); 56 56 57 57 #endif /* __XFS_RMAP_BTREE_H__ */
+1 -1
fs/xfs/xfs_fsops.c
··· 536 536 537 537 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 538 538 pag = xfs_perag_get(mp, agno); 539 - err2 = xfs_ag_resv_init(pag); 539 + err2 = xfs_ag_resv_init(pag, NULL); 540 540 xfs_perag_put(pag); 541 541 if (err2 && !error) 542 542 error = err2;