From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DDA341BDD3 for ; Wed, 6 Mar 2024 05:30:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709703058; cv=none; b=LMwW6Ga5oFRGlDVjFeQ23kGgvgVx34SUwrduwPmLOJq8Gi4qfs3fZJmY23piBIBYV77Vah1AJki1YrLXJO433/1z5Yw0azkYmeUs9cML/9RiUppOmAnZ4X/jpb4C3UdEprV2kLmMK/6yXhp4+DvT6XpqKCQAbB5rQc7R0rEQnv4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709703058; c=relaxed/simple; bh=LZ2GHw34VpfRy7qFSIWq4UfNUcbVBiY63OFvftIFtCw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=adFdepQiO2AL38CgGsdZbK9NuWQeA6nRyh9TdgXcBm+l6iNfmT/6sbxDQoG/lhezqUMePRKIKLvVEF8MwLM0gqNl8auJeTgPy0m2iA8SNTA1HSNqH1F8tWoddp4x3N/+lo1pMVDX3EFJ8Jq+eBnNpAhzj0gHCey5DeM/FbJqGYA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com; spf=pass smtp.mailfrom=fromorbit.com; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b=Uf3Wxaj/; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fromorbit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fromorbit-com.20230601.gappssmtp.com header.i=@fromorbit-com.20230601.gappssmtp.com header.b="Uf3Wxaj/" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-6e5eb3dd2f8so2739302b3a.2 for ; Tue, 05 Mar 2024 21:30:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fromorbit-com.20230601.gappssmtp.com; s=20230601; t=1709703056; x=1710307856; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fnVR35Lc/9BzN1wG8qqWqovotz4yUqWo57lKgFb2Bh0=; b=Uf3Wxaj/GgaPtZ3xWanCVoIG9uaHj9cqlQoFFv6ANafNCC4Pc4v410J0xaBONE0QJR GgaHlerdLpBrujoQLzDQXPwLmtWTxMk3QLAOlIVPka+cOiLTWghjoa9EEocCB2siOYnw HC5FUnr+H61HNVcuMF27O+rRlrmD9qNZWyWs6J5egx0HgasHx4ZL4irCzA0PBGtCdN9m g2JOlrqlj5FNgniQw1OracEbk9Tdh/smYmygVCj/9SiGTs9iZQ8Ww2Bhm0KCQRmm5fJI Goav87x9lo0/1dmYaW9eMF3j4lk4STjEMH/aPuiq0YU7GL7vr6qXz9HK/83JF7FXZinf XN1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709703056; x=1710307856; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fnVR35Lc/9BzN1wG8qqWqovotz4yUqWo57lKgFb2Bh0=; b=bKCZ0xMPELpz+HzKC/WUBVRwI8H0jNwMg/yVmpQq7GwgkwgKzSmcogThlXmLk8KeRk wszmfLj/y+hUNhKips94lH9iG9GTL4QmSygnfxzLHhEkX9rGcvldSPXM4h6O6G9jBzIQ 2A2RfcMCMf2lc53GIT8Kek/GykUEKTNZbMCPv9QdW4TUtfU9c/U29wwrgcwLay6/EBOw 83gK9bhHukI0Q0aZ06nk9m+3folLcpsQJBC3ZcDcp5HcrrvVlzB0nhJPnqWbzhBbEm44 2Ykhsxf8IuanbADTFt0Gfvim4O2LcH9lPFtMGXFntz0DYRlzNmOd4axAJ+L/HnaA6G1Z E9MA== X-Gm-Message-State: AOJu0Yz9ICRMjlUW0kRMXBQiitPz4Yp3fODoJnoG1oCpd4AB3pFhr1Ca GrfYuqy9jpKJ2dDpdSdpO7GDE+plpBwx6/QIqITaPI8gXksbx7iZ2DDfTKpyjyNpZmML9M54eg3 k X-Google-Smtp-Source: AGHT+IETksGNnU4kbJoIQTYAOV37hfsaYvA4t8A1zmietmkIihRsNWjICQsOhJu3YOKWKCdWEiW3vg== X-Received: by 2002:a05:6a00:1248:b0:6e4:fc2b:62d5 with SMTP id u8-20020a056a00124800b006e4fc2b62d5mr14640951pfi.0.1709703055881; Tue, 05 Mar 2024 21:30:55 -0800 (PST) Received: from dread.disaster.area (pa49-181-192-230.pa.nsw.optusnet.com.au. [49.181.192.230]) by smtp.gmail.com with ESMTPSA id j36-20020a63fc24000000b0059b2316be86sm9987883pgi.46.2024.03.05.21.30.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 21:30:55 -0800 (PST) Received: from [192.168.253.23] (helo=devoid.disaster.area) by dread.disaster.area with esmtp (Exim 4.96) (envelope-from ) id 1rhjrg-00FfkF-1e; Wed, 06 Mar 2024 16:30:52 +1100 Received: from dave by devoid.disaster.area with local (Exim 4.97) (envelope-from ) id 1rhjrg-00000006xM6-07hD; Wed, 06 Mar 2024 16:30:52 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Cc: john.g.garry@oracle.com, ojaswin@linux.ibm.com, ritesh.list@gmail.com Subject: [PATCH 2/3] xfs: make EOF allocation simpler Date: Wed, 6 Mar 2024 16:20:12 +1100 Message-ID: <20240306053048.1656747-3-david@fromorbit.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240306053048.1656747-1-david@fromorbit.com> References: <20240306053048.1656747-1-david@fromorbit.com> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Dave Chinner Currently the allocation at EOF is broken into two cases - when the offset is zero and when the offset is non-zero. When the offset is non-zero, we try to do exact block allocation for contiguous extent allocation. When the offset is zero, the allocation is simply an aligned allocation. We want aligned allocation as the fallback when exact block allocation fails, but that complicates the EOF allocation in that it now has to handle two different allocation cases. The caller also has to handle allocation when not at EOF, and for the upcoming forced alignment changes we need that to also be aligned allocation. To simplify all this, pull the aligned allocation cases back into the callers and leave the EOF allocation path for exact block allocation only. This means that the EOF exact block allocation fallback path is the normal aligned allocation path and that ends up making things a lot simpler when forced alignment is introduced. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 131 +++++++++++++++---------------------- fs/xfs/libxfs/xfs_ialloc.c | 8 +-- fs/xfs/xfs_trace.h | 8 +-- 3 files changed, 62 insertions(+), 85 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index d56c82c07505..c2ddf1875e52 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3320,12 +3320,12 @@ xfs_bmap_select_minlen( static int xfs_bmap_btalloc_select_lengths( struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t *blen) + struct xfs_alloc_arg *args) { struct xfs_mount *mp = args->mp; struct xfs_perag *pag; xfs_agnumber_t agno, startag; + xfs_extlen_t blen = 0; int error = 0; if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { @@ -3339,19 +3339,18 @@ xfs_bmap_btalloc_select_lengths( if (startag == NULLAGNUMBER) startag = 0; - *blen = 0; for_each_perag_wrap(mp, startag, agno, pag) { - error = xfs_bmap_longest_free_extent(pag, args->tp, blen); + error = xfs_bmap_longest_free_extent(pag, args->tp, &blen); if (error && error != -EAGAIN) break; error = 0; - if (*blen >= args->maxlen) + if (blen >= args->maxlen) break; } if (pag) xfs_perag_rele(pag); - args->minlen = xfs_bmap_select_minlen(ap, args, *blen); + args->minlen = xfs_bmap_select_minlen(ap, args, blen); return error; } @@ -3561,78 +3560,40 @@ xfs_bmap_exact_minlen_extent_alloc( * If we are not low on available data blocks and we are allocating at * EOF, optimise allocation for contiguous file extension and/or stripe * alignment of the new extent. - * - * NOTE: ap->aeof is only set if the allocation length is >= the - * stripe unit and the allocation offset is at the end of file. */ static int xfs_bmap_btalloc_at_eof( struct xfs_bmalloca *ap, - struct xfs_alloc_arg *args, - xfs_extlen_t blen, - bool ag_only) + struct xfs_alloc_arg *args) { struct xfs_mount *mp = args->mp; struct xfs_perag *caller_pag = args->pag; + xfs_extlen_t alignment = args->alignment; int error; + ASSERT(ap->aeof && ap->offset); + ASSERT(args->alignment >= 1); + /* - * If there are already extents in the file, try an exact EOF block - * allocation to extend the file as a contiguous extent. If that fails, - * or it's the first allocation in a file, just try for a stripe aligned - * allocation. + * Compute the alignment slop for the fallback path so we ensure + * we account for the potential alignemnt space required by the + * fallback paths before we modify the AGF and AGFL here. */ - if (ap->offset) { - xfs_extlen_t alignment = args->alignment; - - /* - * Compute the alignment slop for the fallback path so we ensure - * we account for the potential alignemnt space required by the - * fallback paths before we modify the AGF and AGFL here. - */ - args->alignment = 1; - args->alignslop = alignment - args->alignment; - - if (!caller_pag) - args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); - error = xfs_alloc_vextent_exact_bno(args, ap->blkno); - if (!caller_pag) { - xfs_perag_put(args->pag); - args->pag = NULL; - } - if (error) - return error; - - if (args->fsbno != NULLFSBLOCK) - return 0; - /* - * Exact allocation failed. Reset to try an aligned allocation - * according to the original allocation specification. - */ - args->alignment = alignment; - args->alignslop = 0; - } - - if (ag_only) { - error = xfs_alloc_vextent_near_bno(args, ap->blkno); - } else { + args->alignment = 1; + args->alignslop = alignment - args->alignment; + + if (!caller_pag) + args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); + error = xfs_alloc_vextent_exact_bno(args, ap->blkno); + if (!caller_pag) { + xfs_perag_put(args->pag); args->pag = NULL; - error = xfs_alloc_vextent_start_ag(args, ap->blkno); - ASSERT(args->pag == NULL); - args->pag = caller_pag; } - if (error) - return error; - if (args->fsbno != NULLFSBLOCK) - return 0; - - /* - * Aligned allocation failed, so all fallback paths from here drop the - * start alignment requirement as we know it will not succeed. - */ - args->alignment = 1; - return 0; + /* Reset alignment to original specifications. */ + args->alignment = alignment; + args->alignslop = 0; + return error; } /* @@ -3698,12 +3659,19 @@ xfs_bmap_btalloc_filestreams( } args->minlen = xfs_bmap_select_minlen(ap, args, blen); - if (ap->aeof) - error = xfs_bmap_btalloc_at_eof(ap, args, blen, true); + if (ap->aeof && ap->offset) + error = xfs_bmap_btalloc_at_eof(ap, args); + /* This may be an aligned allocation attempt. */ if (!error && args->fsbno == NULLFSBLOCK) error = xfs_alloc_vextent_near_bno(args, ap->blkno); + /* Attempt non-aligned allocation if we haven't already. */ + if (!error && args->fsbno == NULLFSBLOCK && args->alignment > 1) { + args->alignment = 1; + error = xfs_alloc_vextent_near_bno(args, ap->blkno); + } + out_low_space: /* * We are now done with the perag reference for the filestreams @@ -3725,7 +3693,6 @@ xfs_bmap_btalloc_best_length( struct xfs_bmalloca *ap, struct xfs_alloc_arg *args) { - xfs_extlen_t blen = 0; int error; ap->blkno = XFS_INO_TO_FSB(args->mp, ap->ip->i_ino); @@ -3736,23 +3703,33 @@ xfs_bmap_btalloc_best_length( * the request. If one isn't found, then adjust the minimum allocation * size to the largest space found. */ - error = xfs_bmap_btalloc_select_lengths(ap, args, &blen); + error = xfs_bmap_btalloc_select_lengths(ap, args); if (error) return error; /* - * Don't attempt optimal EOF allocation if previous allocations barely - * succeeded due to being near ENOSPC. It is highly unlikely we'll get - * optimal or even aligned allocations in this case, so don't waste time - * trying. + * If we are in low space mode, then optimal allocation will fail so + * prepare for minimal allocation and run the low space algorithm + * immediately. */ - if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { - error = xfs_bmap_btalloc_at_eof(ap, args, blen, false); - if (error || args->fsbno != NULLFSBLOCK) - return error; + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { + ASSERT(args->fsbno == NULLFSBLOCK); + return xfs_bmap_btalloc_low_space(ap, args); + } + + if (ap->aeof && ap->offset) + error = xfs_bmap_btalloc_at_eof(ap, args); + + /* This may be an aligned allocation attempt. */ + if (!error && args->fsbno == NULLFSBLOCK) + error = xfs_alloc_vextent_start_ag(args, ap->blkno); + + /* Attempt non-aligned allocation if we haven't already. */ + if (!error && args->fsbno == NULLFSBLOCK && args->alignment > 1) { + args->alignment = 1; + error = xfs_alloc_vextent_start_ag(args, ap->blkno); } - error = xfs_alloc_vextent_start_ag(args, ap->blkno); if (error || args->fsbno != NULLFSBLOCK) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index fa27a50f96ac..fc19d93a9d69 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -758,12 +758,12 @@ xfs_ialloc_ag_alloc( * * For an exact allocation, alignment must be 1, * however we need to take cluster alignment into account when - * fixing up the freelist. Use the minalignslop field to + * fixing up the freelist. Use the alignslop field to * indicate that extra blocks might be required for alignment, * but not to use them in the actual exact allocation. */ args.alignment = 1; - args.minalignslop = igeo->cluster_align - 1; + args.alignslop = igeo->cluster_align - 1; /* Allow space for the inode btree to split. */ args.minleft = igeo->inobt_maxlevels; @@ -780,10 +780,10 @@ xfs_ialloc_ag_alloc( * the exact agbno requirement and increase the alignment * instead. It is critical that the total size of the request * (len + alignment + slop) does not increase from this point - * on, so reset minalignslop to ensure it is not included in + * on, so reset alignslop to ensure it is not included in * subsequent requests. */ - args.minalignslop = 0; + args.alignslop = 0; } if (unlikely(args.fsbno == NULLFSBLOCK)) { diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 56b07d8ed431..0b4898b39e30 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1800,7 +1800,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __field(xfs_extlen_t, minleft) __field(xfs_extlen_t, total) __field(xfs_extlen_t, alignment) - __field(xfs_extlen_t, minalignslop) + __field(xfs_extlen_t, alignslop) __field(xfs_extlen_t, len) __field(char, wasdel) __field(char, wasfromfl) @@ -1819,7 +1819,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->minleft = args->minleft; __entry->total = args->total; __entry->alignment = args->alignment; - __entry->minalignslop = args->minalignslop; + __entry->alignslop = args->alignslop; __entry->len = args->len; __entry->wasdel = args->wasdel; __entry->wasfromfl = args->wasfromfl; @@ -1828,7 +1828,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->highest_agno = args->tp->t_highest_agno; ), TP_printk("dev %d:%d agno 0x%x agbno 0x%x minlen %u maxlen %u mod %u " - "prod %u minleft %u total %u alignment %u minalignslop %u " + "prod %u minleft %u total %u alignment %u alignslop %u " "len %u wasdel %d wasfromfl %d resv %d " "datatype 0x%x highest_agno 0x%x", MAJOR(__entry->dev), MINOR(__entry->dev), @@ -1841,7 +1841,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->minleft, __entry->total, __entry->alignment, - __entry->minalignslop, + __entry->alignslop, __entry->len, __entry->wasdel, __entry->wasfromfl, -- 2.43.0