summaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_bmap.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2023-02-12 23:14:55 +0100
committerDave Chinner <dchinner@redhat.com>2023-02-12 23:14:55 +0100
commit8f7747ad8c52cde585b9456f6dbd1984af7b97bc (patch)
treeed3c6af2a35b2148556a1ad7688e77bb46e25b51 /fs/xfs/libxfs/xfs_bmap.c
parentxfs: use xfs_bmap_longest_free_extent() in filestreams (diff)
downloadlinux-8f7747ad8c52cde585b9456f6dbd1984af7b97bc.tar.xz
linux-8f7747ad8c52cde585b9456f6dbd1984af7b97bc.zip
xfs: move xfs_bmap_btalloc_filestreams() to xfs_filestreams.c
xfs_bmap_btalloc_filestreams() calls two filestreams functions to select the AG to allocate from. Both those functions end up in the same selection function that iterates all AGs multiple times. Worst case, xfs_bmap_btalloc_filestreams() can iterate all AGs 4 times just to select the initial AG to allocate in. Move the AG selection to fs/xfs/xfs_filestreams.c as a single interface so that the inefficient AG interation is contained entirely within the filestreams code. This will allow the implementation to be simplified and made more efficient in future patches. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c94
1 files changed, 11 insertions, 83 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 16628fdbcd55..11facb8a6b3a 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3222,68 +3222,6 @@ xfs_bmap_btalloc_select_lengths(
return error;
}
-static int
-xfs_bmap_btalloc_filestreams_select_lengths(
- struct xfs_bmalloca *ap,
- struct xfs_alloc_arg *args,
- xfs_extlen_t *blen)
-{
- struct xfs_mount *mp = ap->ip->i_mount;
- struct xfs_perag *pag;
- xfs_agnumber_t start_agno;
- int error;
-
- args->total = ap->total;
-
- start_agno = XFS_FSB_TO_AGNO(mp, ap->blkno);
- if (start_agno == NULLAGNUMBER)
- start_agno = 0;
-
- pag = xfs_perag_grab(mp, start_agno);
- if (pag) {
- error = xfs_bmap_longest_free_extent(pag, args->tp, blen);
- xfs_perag_rele(pag);
- if (error) {
- if (error != -EAGAIN)
- return error;
- *blen = 0;
- }
- }
-
- if (*blen < args->maxlen) {
- xfs_agnumber_t agno = start_agno;
-
- error = xfs_filestream_new_ag(ap, &agno);
- if (error)
- return error;
- if (agno == NULLAGNUMBER)
- goto out_select;
-
- pag = xfs_perag_grab(mp, agno);
- if (!pag)
- goto out_select;
-
- error = xfs_bmap_longest_free_extent(pag, args->tp, blen);
- xfs_perag_rele(pag);
- if (error) {
- if (error != -EAGAIN)
- return error;
- *blen = 0;
- }
- start_agno = agno;
- }
-
-out_select:
- args->minlen = xfs_bmap_select_minlen(ap, args, *blen);
-
- /*
- * Set the failure fallback case to look in the selected AG as stream
- * may have moved.
- */
- ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, start_agno, 0);
- return 0;
-}
-
/* Update all inode and quota accounting for the allocation we just did. */
static void
xfs_bmap_btalloc_accounting(
@@ -3577,7 +3515,7 @@ xfs_bmap_btalloc_at_eof(
* transaction that we are critically low on space so they don't waste time on
* allocation modes that are unlikely to succeed.
*/
-static int
+int
xfs_bmap_btalloc_low_space(
struct xfs_bmalloca *ap,
struct xfs_alloc_arg *args)
@@ -3606,36 +3544,25 @@ xfs_bmap_btalloc_filestreams(
struct xfs_alloc_arg *args,
int stripe_align)
{
- xfs_agnumber_t agno = xfs_filestream_lookup_ag(ap->ip);
xfs_extlen_t blen = 0;
int error;
- /* Determine the initial block number we will target for allocation. */
- if (agno == NULLAGNUMBER)
- agno = 0;
- ap->blkno = XFS_AGB_TO_FSB(args->mp, agno, 0);
- xfs_bmap_adjacent(ap);
+
+ error = xfs_filestream_select_ag(ap, args, &blen);
+ if (error)
+ return error;
/*
- * If there is very little free space before we start a
- * filestreams allocation, we're almost guaranteed to fail to
- * find an AG with enough contiguous free space to succeed, so
- * just go straight to the low space algorithm.
+ * If we are in low space mode, then optimal allocation will fail so
+ * prepare for minimal allocation and jump to the low space algorithm
+ * immediately.
*/
if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
args->minlen = ap->minlen;
- return xfs_bmap_btalloc_low_space(ap, args);
+ goto out_low_space;
}
- /*
- * Search for an allocation group with a single extent large enough for
- * the request. If one isn't found, then adjust the minimum allocation
- * size to the largest space found.
- */
- error = xfs_bmap_btalloc_filestreams_select_lengths(ap, args, &blen);
- if (error)
- return error;
-
+ args->minlen = xfs_bmap_select_minlen(ap, args, blen);
if (ap->aeof) {
error = xfs_bmap_btalloc_at_eof(ap, args, blen, stripe_align,
true);
@@ -3647,6 +3574,7 @@ xfs_bmap_btalloc_filestreams(
if (error || args->fsbno != NULLFSBLOCK)
return error;
+out_low_space:
return xfs_bmap_btalloc_low_space(ap, args);
}