Skip to content

Commit f48e2df

Browse files
committed
xfs: make xfs_*read_agf return EAGAIN to ALLOC_FLAG_TRYLOCK callers
Refactor xfs_read_agf and xfs_alloc_read_agf to return EAGAIN if the caller passed TRYLOCK and we weren't able to get the lock; and change the callers to recognize this. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Dave Chinner <[email protected]>
1 parent ee647f8 commit f48e2df

File tree

3 files changed

+25
-33
lines changed

3 files changed

+25
-33
lines changed

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2502,12 +2502,11 @@ xfs_alloc_fix_freelist(
25022502

25032503
if (!pag->pagf_init) {
25042504
error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2505-
if (error)
2505+
if (error) {
2506+
/* Couldn't lock the AGF so skip this AG. */
2507+
if (error == -EAGAIN)
2508+
error = 0;
25062509
goto out_no_agbp;
2507-
if (!pag->pagf_init) {
2508-
ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2509-
ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
2510-
goto out_agbp_relse;
25112510
}
25122511
}
25132512

@@ -2533,11 +2532,10 @@ xfs_alloc_fix_freelist(
25332532
*/
25342533
if (!agbp) {
25352534
error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
2536-
if (error)
2537-
goto out_no_agbp;
2538-
if (!agbp) {
2539-
ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
2540-
ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
2535+
if (error) {
2536+
/* Couldn't lock the AGF so skip this AG. */
2537+
if (error == -EAGAIN)
2538+
error = 0;
25412539
goto out_no_agbp;
25422540
}
25432541
}
@@ -2768,11 +2766,10 @@ xfs_alloc_pagf_init(
27682766
xfs_buf_t *bp;
27692767
int error;
27702768

2771-
if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
2772-
return error;
2773-
if (bp)
2769+
error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp);
2770+
if (!error)
27742771
xfs_trans_brelse(tp, bp);
2775-
return 0;
2772+
return error;
27762773
}
27772774

27782775
/*
@@ -2961,12 +2958,6 @@ xfs_read_agf(
29612958
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
29622959
XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
29632960
XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
2964-
/*
2965-
* Callers of xfs_read_agf() currently interpret a NULL bpp as EAGAIN
2966-
* and need to be converted to check for EAGAIN specifically.
2967-
*/
2968-
if (error == -EAGAIN)
2969-
return 0;
29702961
if (error)
29712962
return error;
29722963

@@ -2992,14 +2983,15 @@ xfs_alloc_read_agf(
29922983

29932984
trace_xfs_alloc_read_agf(mp, agno);
29942985

2986+
/* We don't support trylock when freeing. */
2987+
ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
2988+
(XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK));
29952989
ASSERT(agno != NULLAGNUMBER);
29962990
error = xfs_read_agf(mp, tp, agno,
29972991
(flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
29982992
bpp);
29992993
if (error)
30002994
return error;
3001-
if (!*bpp)
3002-
return 0;
30032995
ASSERT(!(*bpp)->b_error);
30042996

30052997
agf = XFS_BUF_TO_AGF(*bpp);

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3311,11 +3311,12 @@ xfs_bmap_longest_free_extent(
33113311
pag = xfs_perag_get(mp, ag);
33123312
if (!pag->pagf_init) {
33133313
error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
3314-
if (error)
3315-
goto out;
3316-
3317-
if (!pag->pagf_init) {
3318-
*notinit = 1;
3314+
if (error) {
3315+
/* Couldn't lock the AGF, so skip this AG. */
3316+
if (error == -EAGAIN) {
3317+
*notinit = 1;
3318+
error = 0;
3319+
}
33193320
goto out;
33203321
}
33213322
}

fs/xfs/xfs_filestream.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,15 @@ xfs_filestream_pick_ag(
159159

160160
if (!pag->pagf_init) {
161161
err = xfs_alloc_pagf_init(mp, NULL, ag, trylock);
162-
if (err && !trylock) {
162+
if (err) {
163163
xfs_perag_put(pag);
164-
return err;
164+
if (err != -EAGAIN)
165+
return err;
166+
/* Couldn't lock the AGF, skip this AG. */
167+
continue;
165168
}
166169
}
167170

168-
/* Might fail sometimes during the 1st pass with trylock set. */
169-
if (!pag->pagf_init)
170-
goto next_ag;
171-
172171
/* Keep track of the AG with the most free blocks. */
173172
if (pag->pagf_freeblks > maxfree) {
174173
maxfree = pag->pagf_freeblks;

0 commit comments

Comments
 (0)