From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Chandan Babu R <chandanrlinux@gmail.com>
Cc: linux-xfs@vger.kernel.org, david@fromorbit.com
Subject: Re: [PATCH V5 12/12] xfs: Introduce error injection to allocate only minlen size extents for files
Date: Mon, 5 Oct 2020 21:27:32 -0700 [thread overview]
Message-ID: <20201006042732.GR49547@magnolia> (raw)
In-Reply-To: <2322881.G0kAUReszQ@garuda>
On Tue, Oct 06, 2020 at 09:55:03AM +0530, Chandan Babu R wrote:
> On Saturday 3 October 2020 11:26:33 AM IST Chandan Babu R wrote:
> > This commit adds XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT error tag which
> > helps userspace test programs to get xfs_bmap_btalloc() to always
> > allocate minlen sized extents.
> >
> > This is required for test programs which need a guarantee that minlen
> > extents allocated for a file do not get merged with their existing
> > neighbours in the inode's BMBT. "Inode fork extent overflow check" for
> > Directories, Xattrs and extension of realtime inodes need this since the
> > file offset at which the extents are being allocated cannot be
> > explicitly controlled from userspace.
> >
> > One way to use this error tag is to,
> > 1. Consume all of the free space by sequentially writing to a file.
> > 2. Punch alternate blocks of the file. This causes CNTBT to contain
> > sufficient number of one block sized extent records.
> > 3. Inject XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT error tag.
> > After step 3, xfs_bmap_btalloc() will issue space allocation
> > requests for minlen sized extents only.
> >
> > ENOSPC error code is returned to userspace when there aren't any "one
> > block sized" extents left in any of the AGs.
> >
> > Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
> > ---
> > fs/xfs/libxfs/xfs_alloc.c | 46 ++++++++++++++++++++++++++++++++++++
> > fs/xfs/libxfs/xfs_alloc.h | 1 +
> > fs/xfs/libxfs/xfs_bmap.c | 26 ++++++++++++++------
> > fs/xfs/libxfs/xfs_errortag.h | 4 +++-
> > fs/xfs/xfs_error.c | 3 +++
> > 5 files changed, 72 insertions(+), 8 deletions(-)
> >
> > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> > index 852b536551b5..d8d8ab1478db 100644
> > --- a/fs/xfs/libxfs/xfs_alloc.c
> > +++ b/fs/xfs/libxfs/xfs_alloc.c
> > @@ -2473,6 +2473,45 @@ xfs_defer_agfl_block(
> > xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
> > }
> >
> > +STATIC int
> > +minlen_freespace_available(
> > + struct xfs_alloc_arg *args,
> > + struct xfs_buf *agbp,
> > + int *stat)
> > +{
> > + xfs_btree_cur_t *cnt_cur;
> > + xfs_agblock_t fbno;
> > + xfs_extlen_t flen;
> > + int btree_error = XFS_BTREE_NOERROR;
> > + int error = 0;
> > +
> > + cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, agbp,
> > + args->agno, XFS_BTNUM_CNT);
> > + error = xfs_alloc_lookup_ge(cnt_cur, 0, args->minlen, stat);
> > + if (error) {
> > + btree_error = XFS_BTREE_ERROR;
> > + goto out;
> > + }
> > +
> > + ASSERT(*stat == 1);
> > +
> > + error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, stat);
> > + if (error) {
> > + btree_error = XFS_BTREE_ERROR;
> > + goto out;
> > + }
> > +
> > + if (flen == args->minlen)
> > + *stat = 1;
> > + else
> > + *stat = 0;
> > +
> > +out:
> > + xfs_btree_del_cursor(cnt_cur, btree_error);
> > +
> > + return error;
> > +}
> > +
> > /*
> > * Decide whether to use this allocation group for this allocation.
> > * If so, fix up the btree freelist's size.
> > @@ -2490,6 +2529,7 @@ xfs_alloc_fix_freelist(
> > struct xfs_alloc_arg targs; /* local allocation arguments */
> > xfs_agblock_t bno; /* freelist block */
> > xfs_extlen_t need; /* total blocks needed in freelist */
> > + int i;
> > int error = 0;
> >
> > /* deferred ops (AGFL block frees) require permanent transactions */
> > @@ -2544,6 +2584,12 @@ xfs_alloc_fix_freelist(
> > if (!xfs_alloc_space_available(args, need, flags))
> > goto out_agbp_relse;
> >
> > + if (args->alloc_minlen_only) {
> > + error = minlen_freespace_available(args, agbp, &i);
> > + if (error || !i)
> > + goto out_agbp_relse;
> > + }
> > +
> > /*
> > * Make the freelist shorter if it's too long.
> > *
> > diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
> > index 6c22b12176b8..1d04089b7fb4 100644
> > --- a/fs/xfs/libxfs/xfs_alloc.h
> > +++ b/fs/xfs/libxfs/xfs_alloc.h
> > @@ -75,6 +75,7 @@ typedef struct xfs_alloc_arg {
> > char wasfromfl; /* set if allocation is from freelist */
> > struct xfs_owner_info oinfo; /* owner of blocks being allocated */
> > enum xfs_ag_resv_type resv; /* block reservation to use */
> > + bool alloc_minlen_only;
> > } xfs_alloc_arg_t;
> >
> > /*
> > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> > index 5156cbd476f2..fab4097e7492 100644
> > --- a/fs/xfs/libxfs/xfs_bmap.c
> > +++ b/fs/xfs/libxfs/xfs_bmap.c
> > @@ -3510,12 +3510,19 @@ xfs_bmap_btalloc(
> > ASSERT(ap->length);
> > }
> >
> > + memset(&args, 0, sizeof(args));
> > +
> > + args.alloc_minlen_only = XFS_TEST_ERROR(false, mp,
> > + XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT);
> >
> > nullfb = ap->tp->t_firstblock == NULLFSBLOCK;
> > fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp,
> > ap->tp->t_firstblock);
> > if (nullfb) {
> > - if ((ap->datatype & XFS_ALLOC_USERDATA) &&
> > + if (args.alloc_minlen_only) {
> > + ag = 0;
> > + ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0);
> > + } else if ((ap->datatype & XFS_ALLOC_USERDATA) &&
> > xfs_inode_is_filestream(ap->ip)) {
> > ag = xfs_filestream_lookup_ag(ap->ip);
> > ag = (ag != NULLAGNUMBER) ? ag : 0;
> > @@ -3523,10 +3530,12 @@ xfs_bmap_btalloc(
> > } else {
> > ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
> > }
> > - } else
> > + } else {
> > ap->blkno = ap->tp->t_firstblock;
> > + }
> >
> > - xfs_bmap_adjacent(ap);
> > + if (!args.alloc_minlen_only)
> > + xfs_bmap_adjacent(ap);
> >
> > /*
> > * If allowed, use ap->blkno; otherwise must use firstblock since
> > @@ -3540,7 +3549,6 @@ xfs_bmap_btalloc(
> > * Normal allocation, done through xfs_alloc_vextent.
> > */
> > tryagain = isaligned = 0;
> > - memset(&args, 0, sizeof(args));
> > args.tp = ap->tp;
> > args.mp = mp;
> > args.fsbno = ap->blkno;
> > @@ -3549,7 +3557,10 @@ xfs_bmap_btalloc(
> > /* Trim the allocation back to the maximum an AG can fit. */
> > args.maxlen = min(ap->length, mp->m_ag_max_usable);
> > blen = 0;
> > - if (nullfb) {
> > + if (args.alloc_minlen_only) {
> > + args.type = XFS_ALLOCTYPE_START_AG;
>
> The above should have been,
>
> args.type = XFS_ALLOCTYPE_FIRST_AG;
>
> In my experiments, I had introduced a new args.type value and had later
> realized that XFS_ALLOCTYPE_FIRST_AG would suffice for my requirements. I had
> tested the changed version (which was in my git stash) and forgot to apply
> that to this commit after testing was completed. Hence I ended up sending a
> slightly stale patch. I am sorry about this. I will resend the series.
Ok, but wait till I've gotten all the way through the replies (nearly
done now).
--D
> --
> chandan
>
>
>
next prev parent reply other threads:[~2020-10-06 4:29 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-03 5:56 [PATCH V5 00/12] Bail out if transaction can cause extent count to overflow Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 01/12] xfs: Add helper for checking per-inode extent count overflow Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 02/12] xfs: Check for extent overflow when trivally adding a new extent Chandan Babu R
2020-10-06 4:18 ` Darrick J. Wong
2020-10-03 5:56 ` [PATCH V5 03/12] xfs: Check for extent overflow when punching a hole Chandan Babu R
2020-10-06 4:18 ` Darrick J. Wong
2020-10-03 5:56 ` [PATCH V5 04/12] xfs: Check for extent overflow when adding/removing xattrs Chandan Babu R
2020-10-06 4:23 ` Darrick J. Wong
2020-10-06 9:21 ` Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 05/12] xfs: Check for extent overflow when adding/removing dir entries Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 06/12] xfs: Check for extent overflow when writing to unwritten extent Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 07/12] xfs: Check for extent overflow when moving extent from cow to data fork Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 08/12] xfs: Check for extent overflow when remapping an extent Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 09/12] xfs: Check for extent overflow when swapping extents Chandan Babu R
2020-10-06 4:23 ` Darrick J. Wong
2020-10-03 5:56 ` [PATCH V5 10/12] xfs: Introduce error injection to reduce maximum inode fork extent count Chandan Babu R
2020-10-06 4:24 ` Darrick J. Wong
2020-10-03 5:56 ` [PATCH V5 11/12] xfs: Set tp->t_firstblock only once during a transaction's lifetime Chandan Babu R
2020-10-06 4:26 ` Darrick J. Wong
2020-10-06 5:17 ` Chandan Babu R
2020-10-03 5:56 ` [PATCH V5 12/12] xfs: Introduce error injection to allocate only minlen size extents for files Chandan Babu R
2020-10-06 4:25 ` Chandan Babu R
2020-10-06 4:27 ` Darrick J. Wong [this message]
2020-10-06 4:34 ` Darrick J. Wong
2020-10-06 9:17 ` Chandan Babu R
2020-10-07 5:09 ` Chandan Babu R
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201006042732.GR49547@magnolia \
--to=darrick.wong@oracle.com \
--cc=chandanrlinux@gmail.com \
--cc=david@fromorbit.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).