public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Chandan Babu R <chandanrlinux@gmail.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: linux-xfs@vger.kernel.org, david@fromorbit.com, hch@infradead.org
Subject: Re: [PATCH V3 04/10] xfs: Check for extent overflow when adding/removing xattrs
Date: Tue, 01 Sep 2020 15:14:43 +0530	[thread overview]
Message-ID: <6128468.3vHh2LMAbu@garuda> (raw)
In-Reply-To: <20200831163759.GM6096@magnolia>

On Monday 31 August 2020 10:07:59 PM IST Darrick J. Wong wrote:
> On Thu, Aug 20, 2020 at 11:13:43AM +0530, Chandan Babu R wrote:
> > Adding/removing an xattr can cause XFS_DA_NODE_MAXDEPTH extents to be
> > added. One extra extent for dabtree in case a local attr is large enough
> > to cause a double split.  It can also cause extent count to increase
> > proportional to the size of a remote xattr's value.
> > 
> > Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
> > ---
> >  fs/xfs/libxfs/xfs_attr.c       | 13 +++++++++++++
> >  fs/xfs/libxfs/xfs_inode_fork.h |  9 +++++++++
> >  2 files changed, 22 insertions(+)
> > 
> > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> > index d4583a0d1b3f..c481389da40f 100644
> > --- a/fs/xfs/libxfs/xfs_attr.c
> > +++ b/fs/xfs/libxfs/xfs_attr.c
> > @@ -396,6 +396,7 @@ xfs_attr_set(
> >  	struct xfs_trans_res	tres;
> >  	bool			rsvd = (args->attr_filter & XFS_ATTR_ROOT);
> >  	int			error, local;
> > +	int			rmt_blks = 0;
> >  	unsigned int		total;
> >  
> >  	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
> > @@ -442,11 +443,15 @@ xfs_attr_set(
> >  		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
> >  		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
> >  		total = args->total;
> > +
> > +		if (!local)
> > +			rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
> >  	} else {
> >  		XFS_STATS_INC(mp, xs_attr_remove);
> >  
> >  		tres = M_RES(mp)->tr_attrrm;
> >  		total = XFS_ATTRRM_SPACE_RES(mp);
> > +		rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
> >  	}
> >  
> >  	/*
> > @@ -460,6 +465,14 @@ xfs_attr_set(
> >  
> >  	xfs_ilock(dp, XFS_ILOCK_EXCL);
> >  	xfs_trans_ijoin(args->trans, dp, 0);
> > +
> > +	if (args->value || xfs_inode_hasattr(dp)) {
> > +		error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
> > +				XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
> 
> What happens if the free space is fragmented and each of these rmt
> blocks results in a separate allocation?

In such a case, We would have "rmt_blks" number of new extents. These are
accounted for by "max(1, rmt_blks)" in XFS_IEXT_ATTR_MANIP_CNT(rmt_blks)
macro. The two arguments to max() i.e. "1" and "rmt_blks" are mutually
exclusive.
"1" occurs when a local value is large enough to cause a double split of a
dabtree leaf.
"rmt_blks" occurs when an xattr value is large enough to be stored
non-locally.

> 
> I'm also not sure why we'd need to account for the remote blocks if
> we're removing an attr?  Those mappings simply go away, right?
>

Lets say the following extent mappings are present in the attr fork of an
inode,
 | Dabtree block | Hole | Dabtree block |

Lets say, to store an xattr's remote value we allocate blocks which cause the
following,
 | Dabtree block | Remote value | Dabtree block |

i.e the region labelled above as "Remote value" is contiguous with both its
neighbours in terms of both "file offset" (belonging to attr fork) and "disk
offset" space. In such a case, xfs_bmap_add_extent_hole_real() would mark the
entire region shown above as just one extent.

A future xattr remove opertion, will fragment this extent into two causing
extent count to increase by 1. Considering the worst case scenario where each
of blocks holding the remote value ends up belonging to such an extent, the
macro XFS_IEXT_ATTR_MANIP_CNT() adds "rmt_blks" number to possible increase in
extent count.

> --D
> 
> > +		if (error)
> > +			goto out_trans_cancel;
> > +	}
> > +
> >  	if (args->value) {
> >  		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
> >  
> > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
> > index 2642e4847ee0..aae8e6e80b71 100644
> > --- a/fs/xfs/libxfs/xfs_inode_fork.h
> > +++ b/fs/xfs/libxfs/xfs_inode_fork.h
> > @@ -45,6 +45,15 @@ struct xfs_ifork {
> >   * i.e. | Old extent | Hole | Old extent |
> >   */
> >  #define XFS_IEXT_REMOVE_CNT		(1)
> > +/*
> > + * Adding/removing an xattr can cause XFS_DA_NODE_MAXDEPTH extents to
> > + * be added. One extra extent for dabtree in case a local attr is
> > + * large enough to cause a double split.  It can also cause extent
> > + * count to increase proportional to the size of a remote xattr's
> > + * value.
> > + */
> > +#define XFS_IEXT_ATTR_MANIP_CNT(rmt_blks) \
> > +	(XFS_DA_NODE_MAXDEPTH + max(1, rmt_blks))
> >  
> >  /*
> >   * Fork handling.
> 

-- 
chandan




  reply	other threads:[~2020-09-01  9:46 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-20  5:43 [PATCH V3 00/10] Bail out if transaction can cause extent count to overflow Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 01/10] xfs: Add helper for checking per-inode extent count overflow Chandan Babu R
2020-08-31 16:08   ` Darrick J. Wong
2020-08-31 16:44     ` Darrick J. Wong
2020-09-01  9:44       ` Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 02/10] xfs: Check for extent overflow when trivally adding a new extent Chandan Babu R
2020-08-31 16:12   ` Darrick J. Wong
2020-08-20  5:43 ` [PATCH V3 03/10] xfs: Check for extent overflow when deleting an extent Chandan Babu R
2020-08-31 16:34   ` Darrick J. Wong
2020-09-01  9:44     ` Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 04/10] xfs: Check for extent overflow when adding/removing xattrs Chandan Babu R
2020-08-31 16:37   ` Darrick J. Wong
2020-09-01  9:44     ` Chandan Babu R [this message]
2020-08-20  5:43 ` [PATCH V3 05/10] xfs: Check for extent overflow when adding/removing dir entries Chandan Babu R
2020-08-31 16:41   ` Darrick J. Wong
2020-08-20  5:43 ` [PATCH V3 06/10] xfs: Check for extent overflow when writing to unwritten extent Chandan Babu R
2020-08-31 16:45   ` Darrick J. Wong
2020-08-20  5:43 ` [PATCH V3 07/10] xfs: Check for extent overflow when inserting a hole Chandan Babu R
2020-08-31 16:46   ` Darrick J. Wong
2020-09-01  9:44     ` Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 08/10] xfs: Check for extent overflow when moving extent from cow to data fork Chandan Babu R
2020-08-31 16:29   ` Darrick J. Wong
2020-09-01  9:45     ` Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 09/10] xfs: Check for extent overflow when remapping an extent Chandan Babu R
2020-08-31 16:23   ` Darrick J. Wong
2020-09-01  9:45     ` Chandan Babu R
2020-08-20  5:43 ` [PATCH V3 10/10] xfs: Check for extent overflow when swapping extents Chandan Babu R
2020-08-31 16:20   ` Darrick J. Wong
2020-09-01  9:45     ` 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=6128468.3vHh2LMAbu@garuda \
    --to=chandanrlinux@gmail.com \
    --cc=darrick.wong@oracle.com \
    --cc=david@fromorbit.com \
    --cc=hch@infradead.org \
    --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