diff options
author | Christoph Hellwig <hch@lst.de> | 2024-08-30 15:37:10 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2024-09-01 08:58:19 -0700 |
commit | fd048a1bb391d0ad50144160c3a490b6b34e0755 (patch) | |
tree | ab457529402f67bdbcc4458d18a555344cba1c59 /fs/xfs/xfs_rtalloc.c | |
parent | a9f646af4307aca3e9006668264761949d5eb35c (diff) |
xfs: rework the rtalloc fallback handling
xfs_rtallocate currently has two fallbacks, when an allocation fails:
1) drop the requested extent size alignment, if any, and retry
2) ignore the locality hint
Oddly enough it does those in order, as trying a different location
is more in line with what the user asked for, and does it in a very
unstructured way.
Lift the fallback to try to allocate without the locality hint into
xfs_rtallocate to both perform them in a more sensible order and to
clean up the code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 12cf7cb3c02c..a6b9ba572cdc 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1271,6 +1271,8 @@ xfs_rtallocate( xfs_rtxlen_t maxlen, xfs_rtxlen_t prod, bool wasdel, + bool initial_user_data, + bool *rtlocked, xfs_rtblock_t *bno, xfs_extlen_t *blen) { @@ -1280,12 +1282,38 @@ xfs_rtallocate( }; xfs_rtxnum_t rtx; xfs_rtxlen_t len = 0; - int error; + int error = 0; + + /* + * Lock out modifications to both the RT bitmap and summary inodes. + */ + if (!*rtlocked) { + xfs_rtbitmap_lock(args.mp); + xfs_rtbitmap_trans_join(tp); + *rtlocked = true; + } + + /* + * For an allocation to an empty file at offset 0, pick an extent that + * will space things out in the rt area. + */ + if (!start && initial_user_data) + start = xfs_rtpick_extent(args.mp, tp, maxlen); if (start) { error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen, &len, prod, &rtx); - } else { + /* + * If we can't allocate near a specific rt extent, try again + * without locality criteria. + */ + if (error == -ENOSPC) { + xfs_rtbuf_cache_relse(&args); + error = 0; + } + } + + if (!error) { error = xfs_rtallocate_extent_size(&args, minlen, maxlen, &len, prod, &rtx); } @@ -1314,7 +1342,7 @@ xfs_bmap_rtalloc( { struct xfs_mount *mp = ap->ip->i_mount; xfs_fileoff_t orig_offset = ap->offset; - xfs_rtxnum_t start; /* allocation hint rtextent no */ + xfs_rtxnum_t start = 0; /* allocation hint rtextent no */ xfs_rtxlen_t prod = 0; /* product factor for allocators */ xfs_extlen_t mod = 0; /* product factor for allocators */ xfs_rtxlen_t ralen = 0; /* realtime allocation length */ @@ -1323,7 +1351,6 @@ xfs_bmap_rtalloc( xfs_extlen_t minlen = mp->m_sb.sb_rextsize; xfs_rtxlen_t raminlen; bool rtlocked = false; - bool ignore_locality = false; int error; align = xfs_get_extsz_hint(ap->ip); @@ -1361,28 +1388,8 @@ retry: ASSERT(raminlen > 0); ASSERT(raminlen <= ralen); - /* - * Lock out modifications to both the RT bitmap and summary inodes - */ - if (!rtlocked) { - xfs_rtbitmap_lock(mp); - xfs_rtbitmap_trans_join(ap->tp); - rtlocked = true; - } - - if (ignore_locality) { - start = 0; - } else if (xfs_bmap_adjacent(ap)) { + if (xfs_bmap_adjacent(ap)) start = xfs_rtb_to_rtx(mp, ap->blkno); - } else if (ap->datatype & XFS_ALLOC_INITIAL_USER_DATA) { - /* - * If it's an allocation to an empty file at offset 0, pick an - * extent that will space things out in the rt area. - */ - start = xfs_rtpick_extent(mp, ap->tp, ralen); - } else { - start = 0; - } /* * Only bother calculating a real prod factor if offset & length are @@ -1398,7 +1405,8 @@ retry: } error = xfs_rtallocate(ap->tp, start, raminlen, ralen, prod, ap->wasdel, - &ap->blkno, &ap->length); + ap->datatype & XFS_ALLOC_INITIAL_USER_DATA, &rtlocked, + &ap->blkno, &ap->length); if (error == -ENOSPC) { if (align > mp->m_sb.sb_rextsize) { /* @@ -1414,15 +1422,6 @@ retry: goto retry; } - if (!ignore_locality && start != 0) { - /* - * If we can't allocate near a specific rt extent, try - * again without locality criteria. - */ - ignore_locality = true; - goto retry; - } - ap->blkno = NULLFSBLOCK; ap->length = 0; return 0; |