Skip to content

Commit 826053d

Browse files
dchinnerdgchinner
authored andcommitted
Merge tag 'intents-perag-refs-6.4_2023-04-11' of git://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into guilt/xfs-for-next
xfs: make intent items take a perag reference [v24.5] Now that we've cleaned up some code warts in the deferred work item processing code, let's make intent items take an active perag reference from their creation until they are finally freed by the defer ops machinery. This change facilitates the scrub drain in the next patchset and will make it easier for the future AG removal code to detect a busy AG in need of quiescing. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Dave Chinner <david@fromorbit.com>
2 parents bed25d8 + 00e7b3b commit 826053d

16 files changed

Lines changed: 196 additions & 85 deletions

fs/xfs/libxfs/xfs_ag.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,10 +1043,8 @@ xfs_ag_extend_space(
10431043
if (error)
10441044
return error;
10451045

1046-
error = xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno,
1047-
be32_to_cpu(agf->agf_length) - len),
1048-
len, &XFS_RMAP_OINFO_SKIP_UPDATE,
1049-
XFS_AG_RESV_NONE);
1046+
error = xfs_free_extent(tp, pag, be32_to_cpu(agf->agf_length) - len,
1047+
len, &XFS_RMAP_OINFO_SKIP_UPDATE, XFS_AG_RESV_NONE);
10501048
if (error)
10511049
return error;
10521050

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,7 @@ xfs_defer_agfl_block(
24052405

24062406
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
24072407

2408+
xfs_extent_free_get_group(mp, xefi);
24082409
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &xefi->xefi_list);
24092410
}
24102411

@@ -2421,8 +2422,8 @@ __xfs_free_extent_later(
24212422
bool skip_discard)
24222423
{
24232424
struct xfs_extent_free_item *xefi;
2424-
#ifdef DEBUG
24252425
struct xfs_mount *mp = tp->t_mountp;
2426+
#ifdef DEBUG
24262427
xfs_agnumber_t agno;
24272428
xfs_agblock_t agbno;
24282429

@@ -2456,9 +2457,11 @@ __xfs_free_extent_later(
24562457
} else {
24572458
xefi->xefi_owner = XFS_RMAP_OWN_NULL;
24582459
}
2459-
trace_xfs_bmap_free_defer(tp->t_mountp,
2460+
trace_xfs_bmap_free_defer(mp,
24602461
XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
24612462
XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
2463+
2464+
xfs_extent_free_get_group(mp, xefi);
24622465
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &xefi->xefi_list);
24632466
}
24642467

@@ -3596,20 +3599,18 @@ xfs_free_extent_fix_freelist(
35963599
int
35973600
__xfs_free_extent(
35983601
struct xfs_trans *tp,
3599-
xfs_fsblock_t bno,
3602+
struct xfs_perag *pag,
3603+
xfs_agblock_t agbno,
36003604
xfs_extlen_t len,
36013605
const struct xfs_owner_info *oinfo,
36023606
enum xfs_ag_resv_type type,
36033607
bool skip_discard)
36043608
{
36053609
struct xfs_mount *mp = tp->t_mountp;
36063610
struct xfs_buf *agbp;
3607-
xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
3608-
xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
36093611
struct xfs_agf *agf;
36103612
int error;
36113613
unsigned int busy_flags = 0;
3612-
struct xfs_perag *pag;
36133614

36143615
ASSERT(len != 0);
36153616
ASSERT(type != XFS_AG_RESV_AGFL);
@@ -3618,10 +3619,9 @@ __xfs_free_extent(
36183619
XFS_ERRTAG_FREE_EXTENT))
36193620
return -EIO;
36203621

3621-
pag = xfs_perag_get(mp, agno);
36223622
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
36233623
if (error)
3624-
goto err;
3624+
return error;
36253625
agf = agbp->b_addr;
36263626

36273627
if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
@@ -3635,20 +3635,18 @@ __xfs_free_extent(
36353635
goto err_release;
36363636
}
36373637

3638-
error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
3638+
error = xfs_free_ag_extent(tp, agbp, pag->pag_agno, agbno, len, oinfo,
3639+
type);
36393640
if (error)
36403641
goto err_release;
36413642

36423643
if (skip_discard)
36433644
busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
36443645
xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
3645-
xfs_perag_put(pag);
36463646
return 0;
36473647

36483648
err_release:
36493649
xfs_trans_brelse(tp, agbp);
3650-
err:
3651-
xfs_perag_put(pag);
36523650
return error;
36533651
}
36543652

fs/xfs/libxfs/xfs_alloc.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ int xfs_alloc_vextent_first_ag(struct xfs_alloc_arg *args,
141141
int /* error */
142142
__xfs_free_extent(
143143
struct xfs_trans *tp, /* transaction pointer */
144-
xfs_fsblock_t bno, /* starting block number of extent */
144+
struct xfs_perag *pag,
145+
xfs_agblock_t agbno,
145146
xfs_extlen_t len, /* length of extent */
146147
const struct xfs_owner_info *oinfo, /* extent owner */
147148
enum xfs_ag_resv_type type, /* block reservation type */
@@ -150,12 +151,13 @@ __xfs_free_extent(
150151
static inline int
151152
xfs_free_extent(
152153
struct xfs_trans *tp,
153-
xfs_fsblock_t bno,
154+
struct xfs_perag *pag,
155+
xfs_agblock_t agbno,
154156
xfs_extlen_t len,
155157
const struct xfs_owner_info *oinfo,
156158
enum xfs_ag_resv_type type)
157159
{
158-
return __xfs_free_extent(tp, bno, len, oinfo, type, false);
160+
return __xfs_free_extent(tp, pag, agbno, len, oinfo, type, false);
159161
}
160162

161163
int /* error */
@@ -235,9 +237,13 @@ struct xfs_extent_free_item {
235237
uint64_t xefi_owner;
236238
xfs_fsblock_t xefi_startblock;/* starting fs block number */
237239
xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
240+
struct xfs_perag *xefi_pag;
238241
unsigned int xefi_flags;
239242
};
240243

244+
void xfs_extent_free_get_group(struct xfs_mount *mp,
245+
struct xfs_extent_free_item *xefi);
246+
241247
#define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */
242248
#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
243249
#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6081,6 +6081,7 @@ __xfs_bmap_add(
60816081
bi->bi_whichfork = whichfork;
60826082
bi->bi_bmap = *bmap;
60836083

6084+
xfs_bmap_update_get_group(tp->t_mountp, bi);
60846085
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list);
60856086
return 0;
60866087
}

fs/xfs/libxfs/xfs_bmap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,13 @@ struct xfs_bmap_intent {
238238
enum xfs_bmap_intent_type bi_type;
239239
int bi_whichfork;
240240
struct xfs_inode *bi_owner;
241+
struct xfs_perag *bi_pag;
241242
struct xfs_bmbt_irec bi_bmap;
242243
};
243244

245+
void xfs_bmap_update_get_group(struct xfs_mount *mp,
246+
struct xfs_bmap_intent *bi);
247+
244248
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
245249
void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
246250
struct xfs_bmbt_irec *imap);

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,12 @@ __xfs_inobt_free_block(
156156
struct xfs_buf *bp,
157157
enum xfs_ag_resv_type resv)
158158
{
159+
xfs_fsblock_t fsbno;
160+
159161
xfs_inobt_mod_blockcount(cur, -1);
160-
return xfs_free_extent(cur->bc_tp,
161-
XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp)), 1,
162+
fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp));
163+
return xfs_free_extent(cur->bc_tp, cur->bc_ag.pag,
164+
XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1,
162165
&XFS_RMAP_OINFO_INOBT, resv);
163166
}
164167

fs/xfs/libxfs/xfs_refcount.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,39 +1332,35 @@ xfs_refcount_finish_one(
13321332
xfs_agblock_t bno;
13331333
unsigned long nr_ops = 0;
13341334
int shape_changes = 0;
1335-
struct xfs_perag *pag;
13361335

1337-
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock));
13381336
bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);
13391337

13401338
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock),
13411339
ri->ri_type, XFS_FSB_TO_AGBNO(mp, ri->ri_startblock),
13421340
ri->ri_blockcount);
13431341

1344-
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
1345-
error = -EIO;
1346-
goto out_drop;
1347-
}
1342+
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE))
1343+
return -EIO;
13481344

13491345
/*
13501346
* If we haven't gotten a cursor or the cursor AG doesn't match
13511347
* the startblock, get one now.
13521348
*/
13531349
rcur = *pcur;
1354-
if (rcur != NULL && rcur->bc_ag.pag != pag) {
1350+
if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
13551351
nr_ops = rcur->bc_ag.refc.nr_ops;
13561352
shape_changes = rcur->bc_ag.refc.shape_changes;
13571353
xfs_refcount_finish_one_cleanup(tp, rcur, 0);
13581354
rcur = NULL;
13591355
*pcur = NULL;
13601356
}
13611357
if (rcur == NULL) {
1362-
error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_FREEING,
1363-
&agbp);
1358+
error = xfs_alloc_read_agf(ri->ri_pag, tp,
1359+
XFS_ALLOC_FLAG_FREEING, &agbp);
13641360
if (error)
1365-
goto out_drop;
1361+
return error;
13661362

1367-
rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
1363+
rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, ri->ri_pag);
13681364
rcur->bc_ag.refc.nr_ops = nr_ops;
13691365
rcur->bc_ag.refc.shape_changes = shape_changes;
13701366
}
@@ -1375,39 +1371,37 @@ xfs_refcount_finish_one(
13751371
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
13761372
XFS_REFCOUNT_ADJUST_INCREASE);
13771373
if (error)
1378-
goto out_drop;
1374+
return error;
13791375
if (ri->ri_blockcount > 0)
13801376
error = xfs_refcount_continue_op(rcur, ri, bno);
13811377
break;
13821378
case XFS_REFCOUNT_DECREASE:
13831379
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
13841380
XFS_REFCOUNT_ADJUST_DECREASE);
13851381
if (error)
1386-
goto out_drop;
1382+
return error;
13871383
if (ri->ri_blockcount > 0)
13881384
error = xfs_refcount_continue_op(rcur, ri, bno);
13891385
break;
13901386
case XFS_REFCOUNT_ALLOC_COW:
13911387
error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount);
13921388
if (error)
1393-
goto out_drop;
1389+
return error;
13941390
ri->ri_blockcount = 0;
13951391
break;
13961392
case XFS_REFCOUNT_FREE_COW:
13971393
error = __xfs_refcount_cow_free(rcur, bno, ri->ri_blockcount);
13981394
if (error)
1399-
goto out_drop;
1395+
return error;
14001396
ri->ri_blockcount = 0;
14011397
break;
14021398
default:
14031399
ASSERT(0);
1404-
error = -EFSCORRUPTED;
1400+
return -EFSCORRUPTED;
14051401
}
14061402
if (!error && ri->ri_blockcount > 0)
1407-
trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno,
1403+
trace_xfs_refcount_finish_one_leftover(mp, ri->ri_pag->pag_agno,
14081404
ri->ri_type, bno, ri->ri_blockcount);
1409-
out_drop:
1410-
xfs_perag_put(pag);
14111405
return error;
14121406
}
14131407

@@ -1435,6 +1429,7 @@ __xfs_refcount_add(
14351429
ri->ri_startblock = startblock;
14361430
ri->ri_blockcount = blockcount;
14371431

1432+
xfs_refcount_update_get_group(tp->t_mountp, ri);
14381433
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_REFCOUNT, &ri->ri_list);
14391434
}
14401435

fs/xfs/libxfs/xfs_refcount.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ enum xfs_refcount_intent_type {
5050

5151
struct xfs_refcount_intent {
5252
struct list_head ri_list;
53+
struct xfs_perag *ri_pag;
5354
enum xfs_refcount_intent_type ri_type;
5455
xfs_extlen_t ri_blockcount;
5556
xfs_fsblock_t ri_startblock;
@@ -67,6 +68,9 @@ xfs_refcount_check_domain(
6768
return true;
6869
}
6970

71+
void xfs_refcount_update_get_group(struct xfs_mount *mp,
72+
struct xfs_refcount_intent *ri);
73+
7074
void xfs_refcount_increase_extent(struct xfs_trans *tp,
7175
struct xfs_bmbt_irec *irec);
7276
void xfs_refcount_decrease_extent(struct xfs_trans *tp,

fs/xfs/libxfs/xfs_refcount_btree.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ xfs_refcountbt_free_block(
112112
XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1);
113113
be32_add_cpu(&agf->agf_refcount_blocks, -1);
114114
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
115-
error = xfs_free_extent(cur->bc_tp, fsbno, 1, &XFS_RMAP_OINFO_REFC,
116-
XFS_AG_RESV_METADATA);
115+
error = xfs_free_extent(cur->bc_tp, cur->bc_ag.pag,
116+
XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1,
117+
&XFS_RMAP_OINFO_REFC, XFS_AG_RESV_METADATA);
117118
if (error)
118119
return error;
119120

fs/xfs/libxfs/xfs_rmap.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,34 +2394,29 @@ xfs_rmap_finish_one(
23942394
struct xfs_btree_cur **pcur)
23952395
{
23962396
struct xfs_mount *mp = tp->t_mountp;
2397-
struct xfs_perag *pag;
23982397
struct xfs_btree_cur *rcur;
23992398
struct xfs_buf *agbp = NULL;
24002399
int error = 0;
24012400
struct xfs_owner_info oinfo;
24022401
xfs_agblock_t bno;
24032402
bool unwritten;
24042403

2405-
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ri->ri_bmap.br_startblock));
24062404
bno = XFS_FSB_TO_AGBNO(mp, ri->ri_bmap.br_startblock);
24072405

2408-
trace_xfs_rmap_deferred(mp, pag->pag_agno, ri->ri_type, bno,
2406+
trace_xfs_rmap_deferred(mp, ri->ri_pag->pag_agno, ri->ri_type, bno,
24092407
ri->ri_owner, ri->ri_whichfork,
24102408
ri->ri_bmap.br_startoff, ri->ri_bmap.br_blockcount,
24112409
ri->ri_bmap.br_state);
24122410

2413-
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE)) {
2414-
error = -EIO;
2415-
goto out_drop;
2416-
}
2417-
2411+
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE))
2412+
return -EIO;
24182413

24192414
/*
24202415
* If we haven't gotten a cursor or the cursor AG doesn't match
24212416
* the startblock, get one now.
24222417
*/
24232418
rcur = *pcur;
2424-
if (rcur != NULL && rcur->bc_ag.pag != pag) {
2419+
if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
24252420
xfs_rmap_finish_one_cleanup(tp, rcur, 0);
24262421
rcur = NULL;
24272422
*pcur = NULL;
@@ -2432,15 +2427,13 @@ xfs_rmap_finish_one(
24322427
* rmapbt, because a shape change could cause us to
24332428
* allocate blocks.
24342429
*/
2435-
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
2430+
error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
24362431
if (error)
2437-
goto out_drop;
2438-
if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
2439-
error = -EFSCORRUPTED;
2440-
goto out_drop;
2441-
}
2432+
return error;
2433+
if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
2434+
return -EFSCORRUPTED;
24422435

2443-
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
2436+
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
24442437
}
24452438
*pcur = rcur;
24462439

@@ -2480,8 +2473,7 @@ xfs_rmap_finish_one(
24802473
ASSERT(0);
24812474
error = -EFSCORRUPTED;
24822475
}
2483-
out_drop:
2484-
xfs_perag_put(pag);
2476+
24852477
return error;
24862478
}
24872479

@@ -2526,6 +2518,7 @@ __xfs_rmap_add(
25262518
ri->ri_whichfork = whichfork;
25272519
ri->ri_bmap = *bmap;
25282520

2521+
xfs_rmap_update_get_group(tp->t_mountp, ri);
25292522
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
25302523
}
25312524

0 commit comments

Comments
 (0)