Message ID | 20201117134416.207945-11-chandanrlinux@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Bail out if transaction can cause extent count to overflow | expand |
On Tue, Nov 17, 2020 at 07:14:12PM +0530, Chandan Babu R wrote: > This commit adds XFS_ERRTAG_REDUCE_MAX_IEXTENTS error tag which enables > userspace programs to test "Inode fork extent count overflow detection" > by reducing maximum possible inode fork extent count to 35. > > With block size of 4k, xattr (with local value) insert operation would > require in the worst case "XFS_DA_NODE_MAXDEPTH + 1" plus > "XFS_DA_NODE_MAXDEPTH + (64k / 4k)" (required for guaranteeing removal > of a maximum sized xattr) number of extents. This evaluates to ~28 > extents. To allow for additions of two or more xattrs during extent > overflow testing, the pseudo max extent count is set to 35. > > Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> > --- > fs/xfs/libxfs/xfs_errortag.h | 4 +++- > fs/xfs/libxfs/xfs_inode_fork.c | 4 ++++ > fs/xfs/xfs_error.c | 3 +++ > 3 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h > index 53b305dea381..1c56fcceeea6 100644 > --- a/fs/xfs/libxfs/xfs_errortag.h > +++ b/fs/xfs/libxfs/xfs_errortag.h > @@ -56,7 +56,8 @@ > #define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33 > #define XFS_ERRTAG_IUNLINK_FALLBACK 34 > #define XFS_ERRTAG_BUF_IOERROR 35 > -#define XFS_ERRTAG_MAX 36 > +#define XFS_ERRTAG_REDUCE_MAX_IEXTENTS 36 > +#define XFS_ERRTAG_MAX 37 > > /* > * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. > @@ -97,5 +98,6 @@ > #define XFS_RANDOM_FORCE_SUMMARY_RECALC 1 > #define XFS_RANDOM_IUNLINK_FALLBACK (XFS_RANDOM_DEFAULT/10) > #define XFS_RANDOM_BUF_IOERROR XFS_RANDOM_DEFAULT > +#define XFS_RANDOM_REDUCE_MAX_IEXTENTS 1 > > #endif /* __XFS_ERRORTAG_H_ */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 8d48716547e5..989b20977654 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -24,6 +24,7 @@ > #include "xfs_dir2_priv.h" > #include "xfs_attr_leaf.h" > #include "xfs_types.h" > +#include "xfs_errortag.h" > > kmem_zone_t *xfs_ifork_zone; > > @@ -745,6 +746,9 @@ xfs_iext_count_may_overflow( > > max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM; > > + if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS)) > + max_exts = 35; Please add a comment here explaining why 35. Sorry about the longish review delay, last week was a US holiday and this week I have eye problems again. :( --D > + > nr_exts = ifp->if_nextents + nr_to_add; > if (nr_exts < ifp->if_nextents || nr_exts > max_exts) > return -EFBIG; > diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c > index 7f6e20899473..3780b118cc47 100644 > --- a/fs/xfs/xfs_error.c > +++ b/fs/xfs/xfs_error.c > @@ -54,6 +54,7 @@ static unsigned int xfs_errortag_random_default[] = { > XFS_RANDOM_FORCE_SUMMARY_RECALC, > XFS_RANDOM_IUNLINK_FALLBACK, > XFS_RANDOM_BUF_IOERROR, > + XFS_RANDOM_REDUCE_MAX_IEXTENTS, > }; > > struct xfs_errortag_attr { > @@ -164,6 +165,7 @@ XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); > XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC); > XFS_ERRORTAG_ATTR_RW(iunlink_fallback, XFS_ERRTAG_IUNLINK_FALLBACK); > XFS_ERRORTAG_ATTR_RW(buf_ioerror, XFS_ERRTAG_BUF_IOERROR); > +XFS_ERRORTAG_ATTR_RW(reduce_max_iextents, XFS_ERRTAG_REDUCE_MAX_IEXTENTS); > > static struct attribute *xfs_errortag_attrs[] = { > XFS_ERRORTAG_ATTR_LIST(noerror), > @@ -202,6 +204,7 @@ static struct attribute *xfs_errortag_attrs[] = { > XFS_ERRORTAG_ATTR_LIST(bad_summary), > XFS_ERRORTAG_ATTR_LIST(iunlink_fallback), > XFS_ERRORTAG_ATTR_LIST(buf_ioerror), > + XFS_ERRORTAG_ATTR_LIST(reduce_max_iextents), > NULL, > }; > > -- > 2.28.0 >
On Thu, 03 Dec 2020 11:06:16 -0800, Darrick J. Wong wrote: > On Tue, Nov 17, 2020 at 07:14:12PM +0530, Chandan Babu R wrote: > > This commit adds XFS_ERRTAG_REDUCE_MAX_IEXTENTS error tag which enables > > userspace programs to test "Inode fork extent count overflow detection" > > by reducing maximum possible inode fork extent count to 35. > > > > With block size of 4k, xattr (with local value) insert operation would > > require in the worst case "XFS_DA_NODE_MAXDEPTH + 1" plus > > "XFS_DA_NODE_MAXDEPTH + (64k / 4k)" (required for guaranteeing removal > > of a maximum sized xattr) number of extents. This evaluates to ~28 > > extents. To allow for additions of two or more xattrs during extent > > overflow testing, the pseudo max extent count is set to 35. > > > > Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> > > --- > > fs/xfs/libxfs/xfs_errortag.h | 4 +++- > > fs/xfs/libxfs/xfs_inode_fork.c | 4 ++++ > > fs/xfs/xfs_error.c | 3 +++ > > 3 files changed, 10 insertions(+), 1 deletion(-) > > > > diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h > > index 53b305dea381..1c56fcceeea6 100644 > > --- a/fs/xfs/libxfs/xfs_errortag.h > > +++ b/fs/xfs/libxfs/xfs_errortag.h > > @@ -56,7 +56,8 @@ > > #define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33 > > #define XFS_ERRTAG_IUNLINK_FALLBACK 34 > > #define XFS_ERRTAG_BUF_IOERROR 35 > > -#define XFS_ERRTAG_MAX 36 > > +#define XFS_ERRTAG_REDUCE_MAX_IEXTENTS 36 > > +#define XFS_ERRTAG_MAX 37 > > > > /* > > * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. > > @@ -97,5 +98,6 @@ > > #define XFS_RANDOM_FORCE_SUMMARY_RECALC 1 > > #define XFS_RANDOM_IUNLINK_FALLBACK (XFS_RANDOM_DEFAULT/10) > > #define XFS_RANDOM_BUF_IOERROR XFS_RANDOM_DEFAULT > > +#define XFS_RANDOM_REDUCE_MAX_IEXTENTS 1 > > > > #endif /* __XFS_ERRORTAG_H_ */ > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > > index 8d48716547e5..989b20977654 100644 > > --- a/fs/xfs/libxfs/xfs_inode_fork.c > > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > > @@ -24,6 +24,7 @@ > > #include "xfs_dir2_priv.h" > > #include "xfs_attr_leaf.h" > > #include "xfs_types.h" > > +#include "xfs_errortag.h" > > > > kmem_zone_t *xfs_ifork_zone; > > > > @@ -745,6 +746,9 @@ xfs_iext_count_may_overflow( > > > > max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM; > > > > + if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS)) > > + max_exts = 35; > > Please add a comment here explaining why 35. Sure. I will do that. > > Sorry about the longish review delay, last week was a US holiday and > this week I have eye problems again. :( Np. Please take care. > > --D > > > + > > nr_exts = ifp->if_nextents + nr_to_add; > > if (nr_exts < ifp->if_nextents || nr_exts > max_exts) > > return -EFBIG; > > diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c > > index 7f6e20899473..3780b118cc47 100644 > > --- a/fs/xfs/xfs_error.c > > +++ b/fs/xfs/xfs_error.c > > @@ -54,6 +54,7 @@ static unsigned int xfs_errortag_random_default[] = { > > XFS_RANDOM_FORCE_SUMMARY_RECALC, > > XFS_RANDOM_IUNLINK_FALLBACK, > > XFS_RANDOM_BUF_IOERROR, > > + XFS_RANDOM_REDUCE_MAX_IEXTENTS, > > }; > > > > struct xfs_errortag_attr { > > @@ -164,6 +165,7 @@ XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); > > XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC); > > XFS_ERRORTAG_ATTR_RW(iunlink_fallback, XFS_ERRTAG_IUNLINK_FALLBACK); > > XFS_ERRORTAG_ATTR_RW(buf_ioerror, XFS_ERRTAG_BUF_IOERROR); > > +XFS_ERRORTAG_ATTR_RW(reduce_max_iextents, XFS_ERRTAG_REDUCE_MAX_IEXTENTS); > > > > static struct attribute *xfs_errortag_attrs[] = { > > XFS_ERRORTAG_ATTR_LIST(noerror), > > @@ -202,6 +204,7 @@ static struct attribute *xfs_errortag_attrs[] = { > > XFS_ERRORTAG_ATTR_LIST(bad_summary), > > XFS_ERRORTAG_ATTR_LIST(iunlink_fallback), > > XFS_ERRORTAG_ATTR_LIST(buf_ioerror), > > + XFS_ERRORTAG_ATTR_LIST(reduce_max_iextents), > > NULL, > > }; > > >
diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h index 53b305dea381..1c56fcceeea6 100644 --- a/fs/xfs/libxfs/xfs_errortag.h +++ b/fs/xfs/libxfs/xfs_errortag.h @@ -56,7 +56,8 @@ #define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33 #define XFS_ERRTAG_IUNLINK_FALLBACK 34 #define XFS_ERRTAG_BUF_IOERROR 35 -#define XFS_ERRTAG_MAX 36 +#define XFS_ERRTAG_REDUCE_MAX_IEXTENTS 36 +#define XFS_ERRTAG_MAX 37 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -97,5 +98,6 @@ #define XFS_RANDOM_FORCE_SUMMARY_RECALC 1 #define XFS_RANDOM_IUNLINK_FALLBACK (XFS_RANDOM_DEFAULT/10) #define XFS_RANDOM_BUF_IOERROR XFS_RANDOM_DEFAULT +#define XFS_RANDOM_REDUCE_MAX_IEXTENTS 1 #endif /* __XFS_ERRORTAG_H_ */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 8d48716547e5..989b20977654 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -24,6 +24,7 @@ #include "xfs_dir2_priv.h" #include "xfs_attr_leaf.h" #include "xfs_types.h" +#include "xfs_errortag.h" kmem_zone_t *xfs_ifork_zone; @@ -745,6 +746,9 @@ xfs_iext_count_may_overflow( max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM; + if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS)) + max_exts = 35; + nr_exts = ifp->if_nextents + nr_to_add; if (nr_exts < ifp->if_nextents || nr_exts > max_exts) return -EFBIG; diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 7f6e20899473..3780b118cc47 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -54,6 +54,7 @@ static unsigned int xfs_errortag_random_default[] = { XFS_RANDOM_FORCE_SUMMARY_RECALC, XFS_RANDOM_IUNLINK_FALLBACK, XFS_RANDOM_BUF_IOERROR, + XFS_RANDOM_REDUCE_MAX_IEXTENTS, }; struct xfs_errortag_attr { @@ -164,6 +165,7 @@ XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC); XFS_ERRORTAG_ATTR_RW(iunlink_fallback, XFS_ERRTAG_IUNLINK_FALLBACK); XFS_ERRORTAG_ATTR_RW(buf_ioerror, XFS_ERRTAG_BUF_IOERROR); +XFS_ERRORTAG_ATTR_RW(reduce_max_iextents, XFS_ERRTAG_REDUCE_MAX_IEXTENTS); static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(noerror), @@ -202,6 +204,7 @@ static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(bad_summary), XFS_ERRORTAG_ATTR_LIST(iunlink_fallback), XFS_ERRORTAG_ATTR_LIST(buf_ioerror), + XFS_ERRORTAG_ATTR_LIST(reduce_max_iextents), NULL, };
This commit adds XFS_ERRTAG_REDUCE_MAX_IEXTENTS error tag which enables userspace programs to test "Inode fork extent count overflow detection" by reducing maximum possible inode fork extent count to 35. With block size of 4k, xattr (with local value) insert operation would require in the worst case "XFS_DA_NODE_MAXDEPTH + 1" plus "XFS_DA_NODE_MAXDEPTH + (64k / 4k)" (required for guaranteeing removal of a maximum sized xattr) number of extents. This evaluates to ~28 extents. To allow for additions of two or more xattrs during extent overflow testing, the pseudo max extent count is set to 35. Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com> --- fs/xfs/libxfs/xfs_errortag.h | 4 +++- fs/xfs/libxfs/xfs_inode_fork.c | 4 ++++ fs/xfs/xfs_error.c | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-)