diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-07-30 01:37:08 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-07-30 01:37:08 -0400 |
commit | ebcbef3a61a6081ffe20b0b684f18ebbf23f1dfb (patch) | |
tree | d9b30678acfa6dc5e99944a4e7dc5fca6f09f2a9 | |
parent | 1c02d502c20809a2a5f71ec16a930a61ed779b81 (diff) |
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>
-rw-r--r-- | fs/xfs/libxfs/xfs_ag_resv.c | 13 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ag_resv.h | 2 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 10 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.h | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_refcount_btree.c | 5 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_refcount_btree.h | 3 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap_btree.c | 5 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap_btree.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_fsops.c | 2 |
9 files changed, 26 insertions, 20 deletions
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index fecd187fcf2c..e701ebc36c06 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c | |||
@@ -248,7 +248,8 @@ __xfs_ag_resv_init( | |||
248 | /* Create a per-AG block reservation. */ | 248 | /* Create a per-AG block reservation. */ |
249 | int | 249 | int |
250 | xfs_ag_resv_init( | 250 | xfs_ag_resv_init( |
251 | struct xfs_perag *pag) | 251 | struct xfs_perag *pag, |
252 | struct xfs_trans *tp) | ||
252 | { | 253 | { |
253 | struct xfs_mount *mp = pag->pag_mount; | 254 | struct xfs_mount *mp = pag->pag_mount; |
254 | xfs_agnumber_t agno = pag->pag_agno; | 255 | xfs_agnumber_t agno = pag->pag_agno; |
@@ -260,11 +261,11 @@ xfs_ag_resv_init( | |||
260 | if (pag->pag_meta_resv.ar_asked == 0) { | 261 | if (pag->pag_meta_resv.ar_asked == 0) { |
261 | ask = used = 0; | 262 | ask = used = 0; |
262 | 263 | ||
263 | error = xfs_refcountbt_calc_reserves(mp, agno, &ask, &used); | 264 | error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, &used); |
264 | if (error) | 265 | if (error) |
265 | goto out; | 266 | goto out; |
266 | 267 | ||
267 | error = xfs_finobt_calc_reserves(mp, agno, &ask, &used); | 268 | error = xfs_finobt_calc_reserves(mp, tp, agno, &ask, &used); |
268 | if (error) | 269 | if (error) |
269 | goto out; | 270 | goto out; |
270 | 271 | ||
@@ -282,7 +283,7 @@ xfs_ag_resv_init( | |||
282 | 283 | ||
283 | mp->m_inotbt_nores = true; | 284 | mp->m_inotbt_nores = true; |
284 | 285 | ||
285 | error = xfs_refcountbt_calc_reserves(mp, agno, &ask, | 286 | error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, |
286 | &used); | 287 | &used); |
287 | if (error) | 288 | if (error) |
288 | goto out; | 289 | goto out; |
@@ -298,7 +299,7 @@ xfs_ag_resv_init( | |||
298 | if (pag->pag_rmapbt_resv.ar_asked == 0) { | 299 | if (pag->pag_rmapbt_resv.ar_asked == 0) { |
299 | ask = used = 0; | 300 | ask = used = 0; |
300 | 301 | ||
301 | error = xfs_rmapbt_calc_reserves(mp, agno, &ask, &used); | 302 | error = xfs_rmapbt_calc_reserves(mp, tp, agno, &ask, &used); |
302 | if (error) | 303 | if (error) |
303 | goto out; | 304 | goto out; |
304 | 305 | ||
@@ -309,7 +310,7 @@ xfs_ag_resv_init( | |||
309 | 310 | ||
310 | #ifdef DEBUG | 311 | #ifdef DEBUG |
311 | /* need to read in the AGF for the ASSERT below to work */ | 312 | /* need to read in the AGF for the ASSERT below to work */ |
312 | error = xfs_alloc_pagf_init(pag->pag_mount, NULL, pag->pag_agno, 0); | 313 | error = xfs_alloc_pagf_init(pag->pag_mount, tp, pag->pag_agno, 0); |
313 | if (error) | 314 | if (error) |
314 | return error; | 315 | return error; |
315 | 316 | ||
diff --git a/fs/xfs/libxfs/xfs_ag_resv.h b/fs/xfs/libxfs/xfs_ag_resv.h index dc953fc84b2f..c0352edc8e41 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.h +++ b/fs/xfs/libxfs/xfs_ag_resv.h | |||
@@ -7,7 +7,7 @@ | |||
7 | #define __XFS_AG_RESV_H__ | 7 | #define __XFS_AG_RESV_H__ |
8 | 8 | ||
9 | int xfs_ag_resv_free(struct xfs_perag *pag); | 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 | bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type); | 12 | bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type); |
13 | xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag, | 13 | xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag, |
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 735a33252eb2..86c50208a143 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -552,6 +552,7 @@ xfs_inobt_max_size( | |||
552 | static int | 552 | static int |
553 | xfs_inobt_count_blocks( | 553 | xfs_inobt_count_blocks( |
554 | struct xfs_mount *mp, | 554 | struct xfs_mount *mp, |
555 | struct xfs_trans *tp, | ||
555 | xfs_agnumber_t agno, | 556 | xfs_agnumber_t agno, |
556 | xfs_btnum_t btnum, | 557 | xfs_btnum_t btnum, |
557 | xfs_extlen_t *tree_blocks) | 558 | xfs_extlen_t *tree_blocks) |
@@ -560,14 +561,14 @@ xfs_inobt_count_blocks( | |||
560 | struct xfs_btree_cur *cur; | 561 | struct xfs_btree_cur *cur; |
561 | int error; | 562 | int error; |
562 | 563 | ||
563 | error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); | 564 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
564 | if (error) | 565 | if (error) |
565 | return error; | 566 | return error; |
566 | 567 | ||
567 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); | 568 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); |
568 | error = xfs_btree_count_blocks(cur, tree_blocks); | 569 | error = xfs_btree_count_blocks(cur, tree_blocks); |
569 | xfs_btree_del_cursor(cur, error); | 570 | xfs_btree_del_cursor(cur, error); |
570 | xfs_buf_relse(agbp); | 571 | xfs_trans_brelse(tp, agbp); |
571 | 572 | ||
572 | return error; | 573 | return error; |
573 | } | 574 | } |
@@ -578,6 +579,7 @@ xfs_inobt_count_blocks( | |||
578 | int | 579 | int |
579 | xfs_finobt_calc_reserves( | 580 | xfs_finobt_calc_reserves( |
580 | struct xfs_mount *mp, | 581 | struct xfs_mount *mp, |
582 | struct xfs_trans *tp, | ||
581 | xfs_agnumber_t agno, | 583 | xfs_agnumber_t agno, |
582 | xfs_extlen_t *ask, | 584 | xfs_extlen_t *ask, |
583 | xfs_extlen_t *used) | 585 | xfs_extlen_t *used) |
@@ -588,7 +590,7 @@ xfs_finobt_calc_reserves( | |||
588 | if (!xfs_sb_version_hasfinobt(&mp->m_sb)) | 590 | if (!xfs_sb_version_hasfinobt(&mp->m_sb)) |
589 | return 0; | 591 | return 0; |
590 | 592 | ||
591 | error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len); | 593 | error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len); |
592 | if (error) | 594 | if (error) |
593 | return error; | 595 | return error; |
594 | 596 | ||
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index bf8f0c405e7d..ebdd0c6b8766 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h | |||
@@ -60,8 +60,8 @@ int xfs_inobt_rec_check_count(struct xfs_mount *, | |||
60 | #define xfs_inobt_rec_check_count(mp, rec) 0 | 60 | #define xfs_inobt_rec_check_count(mp, rec) 0 |
61 | #endif /* DEBUG */ | 61 | #endif /* DEBUG */ |
62 | 62 | ||
63 | int xfs_finobt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, | 63 | int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, |
64 | xfs_extlen_t *ask, xfs_extlen_t *used); | 64 | xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); |
65 | extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, | 65 | extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, |
66 | unsigned long long len); | 66 | unsigned long long len); |
67 | 67 | ||
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 26d2300ed865..1aaa01c97517 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c | |||
@@ -404,6 +404,7 @@ xfs_refcountbt_max_size( | |||
404 | int | 404 | int |
405 | xfs_refcountbt_calc_reserves( | 405 | xfs_refcountbt_calc_reserves( |
406 | struct xfs_mount *mp, | 406 | struct xfs_mount *mp, |
407 | struct xfs_trans *tp, | ||
407 | xfs_agnumber_t agno, | 408 | xfs_agnumber_t agno, |
408 | xfs_extlen_t *ask, | 409 | xfs_extlen_t *ask, |
409 | xfs_extlen_t *used) | 410 | xfs_extlen_t *used) |
@@ -418,14 +419,14 @@ xfs_refcountbt_calc_reserves( | |||
418 | return 0; | 419 | return 0; |
419 | 420 | ||
420 | 421 | ||
421 | error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); | 422 | error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); |
422 | if (error) | 423 | if (error) |
423 | return error; | 424 | return error; |
424 | 425 | ||
425 | agf = XFS_BUF_TO_AGF(agbp); | 426 | agf = XFS_BUF_TO_AGF(agbp); |
426 | agblocks = be32_to_cpu(agf->agf_length); | 427 | agblocks = be32_to_cpu(agf->agf_length); |
427 | tree_len = be32_to_cpu(agf->agf_refcount_blocks); | 428 | tree_len = be32_to_cpu(agf->agf_refcount_blocks); |
428 | xfs_buf_relse(agbp); | 429 | xfs_trans_brelse(tp, agbp); |
429 | 430 | ||
430 | *ask += xfs_refcountbt_max_size(mp, agblocks); | 431 | *ask += xfs_refcountbt_max_size(mp, agblocks); |
431 | *used += tree_len; | 432 | *used += tree_len; |
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index 801c2c7732fd..ba416f71c824 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h | |||
@@ -55,6 +55,7 @@ extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp, | |||
55 | xfs_agblock_t agblocks); | 55 | xfs_agblock_t agblocks); |
56 | 56 | ||
57 | extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, | 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 | #endif /* __XFS_REFCOUNT_BTREE_H__ */ | 61 | #endif /* __XFS_REFCOUNT_BTREE_H__ */ |
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 221a88ea60bb..f79cf040d745 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c | |||
@@ -554,6 +554,7 @@ xfs_rmapbt_max_size( | |||
554 | int | 554 | int |
555 | xfs_rmapbt_calc_reserves( | 555 | xfs_rmapbt_calc_reserves( |
556 | struct xfs_mount *mp, | 556 | struct xfs_mount *mp, |
557 | struct xfs_trans *tp, | ||
557 | xfs_agnumber_t agno, | 558 | xfs_agnumber_t agno, |
558 | xfs_extlen_t *ask, | 559 | xfs_extlen_t *ask, |
559 | xfs_extlen_t *used) | 560 | xfs_extlen_t *used) |
@@ -567,14 +568,14 @@ xfs_rmapbt_calc_reserves( | |||
567 | if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) | 568 | if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) |
568 | return 0; | 569 | return 0; |
569 | 570 | ||
570 | error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); | 571 | error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); |
571 | if (error) | 572 | if (error) |
572 | return error; | 573 | return error; |
573 | 574 | ||
574 | agf = XFS_BUF_TO_AGF(agbp); | 575 | agf = XFS_BUF_TO_AGF(agbp); |
575 | agblocks = be32_to_cpu(agf->agf_length); | 576 | agblocks = be32_to_cpu(agf->agf_length); |
576 | tree_len = be32_to_cpu(agf->agf_rmap_blocks); | 577 | tree_len = be32_to_cpu(agf->agf_rmap_blocks); |
577 | xfs_buf_relse(agbp); | 578 | xfs_trans_brelse(tp, agbp); |
578 | 579 | ||
579 | /* Reserve 1% of the AG or enough for 1 block per record. */ | 580 | /* Reserve 1% of the AG or enough for 1 block per record. */ |
580 | *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); | 581 | *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); |
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 50198b6c3bb2..820d668b063d 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h | |||
@@ -51,7 +51,7 @@ extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp, | |||
51 | extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, | 51 | extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, |
52 | xfs_agblock_t agblocks); | 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 | xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); | 55 | xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); |
56 | 56 | ||
57 | #endif /* __XFS_RMAP_BTREE_H__ */ | 57 | #endif /* __XFS_RMAP_BTREE_H__ */ |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 3f2bd6032cf8..7c00b8bedfe3 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -536,7 +536,7 @@ xfs_fs_reserve_ag_blocks( | |||
536 | 536 | ||
537 | for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { | 537 | for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { |
538 | pag = xfs_perag_get(mp, agno); | 538 | pag = xfs_perag_get(mp, agno); |
539 | err2 = xfs_ag_resv_init(pag); | 539 | err2 = xfs_ag_resv_init(pag, NULL); |
540 | xfs_perag_put(pag); | 540 | xfs_perag_put(pag); |
541 | if (err2 && !error) | 541 | if (err2 && !error) |
542 | error = err2; | 542 | error = err2; |