All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 00/16] xfs: Extend per-inode extent counters
@ 2021-12-14  8:45 Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h Chandan Babu R
                   ` (15 more replies)
  0 siblings, 16 replies; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

The commit xfs: fix inode fork extent count overflow
(3f8a4f1d876d3e3e49e50b0396eaffcc4ba71b08) mentions that 10 billion
data fork extents should be possible to create. However the
corresponding on-disk field has a signed 32-bit type. Hence this
patchset extends the per-inode data fork extent counter to 64 bits out
of which 48 bits are used to store the extent count.

Also, XFS has an attribute fork extent counter which is 16 bits
wide. A workload that,
1. Creates 1 million 255-byte sized xattrs,
2. Deletes 50% of these xattrs in an alternating manner,
3. Tries to insert 400,000 new 255-byte sized xattrs
   causes the xattr extent counter to overflow.

Dave tells me that there are instances where a single file has more
than 100 million hardlinks. With parent pointers being stored in
xattrs, we will overflow the signed 16-bits wide xattr extent counter
when large number of hardlinks are created. Hence this patchset
extends the on-disk field to 32-bits.

The following changes are made to accomplish this,
1. A 64-bit inode field is carved out of existing di_pad and
   di_flushiter fields to hold the 64-bit data fork extent counter.
2. The existing 32-bit inode data fork extent counter will be used to
   hold the attr fork extent counter.
3. A new incompat superblock flag to prevent older kernels from mounting
   the filesystem.

The patchset has been tested by executing xfstests with the following
mkfs.xfs options,
1. -m crc=0 -b size=1k
2. -m crc=0 -b size=4k
3. -m crc=0 -b size=512
4. -m rmapbt=1,reflink=1 -b size=1k
5. -m rmapbt=1,reflink=1 -b size=4k

Each of the above test scenarios were executed on the following
combinations (For V4 FS test scenario, the last combination
i.e. "Patched (enable extcnt64bit)", was omitted).
|-------------------------------+-----------|
| Xfsprogs                      | Kernel    |
|-------------------------------+-----------|
| Unpatched                     | Patched   |
| Patched (disable extcnt64bit) | Unpatched |
| Patched (disable extcnt64bit) | Patched   |
| Patched (enable extcnt64bit)  | Patched   |
|-------------------------------+-----------|

I have also written a test (yet to be converted into xfstests format)
to check if the correct extent counter fields are updated with/without
the new incompat flag. I have also fixed an existing test to work with
the new extent counter fields.

These patches can also be obtained from
https://github.com/chandanr/linux.git at branch
xfs-incompat-extend-extcnt-v4.

I will be posting the changes associated with xfsprogs separately.

Changelog:
V3 -> V4:
1. Rebase patchset on xfs-linux/for-next branch.
2. Carve out a 64-bit inode field out of the existing di_pad and
   di_flushiter fields to hold the 64-bit data fork extent counter.
3. Use the existing 32-bit inode data fork extent counter to hold the
   attr fork extent counter.
4. Verify the contents of newly introduced inode fields immediately
   after the inode has been read from the disk.
5. Upgrade inodes to be able to hold large extent counters when
   reading them from disk.
6. Use XFS_BULK_IREQ_NREXT64 as the flag that userspace can use to
   indicate that it can read 64-bit data fork extent counter.
7. Bulkstat ioctl returns -EOVERFLOW when userspace is not capable of
   working with large extent counters and inode's data fork extent
   count is larger than INT32_MAX.

V2 -> V3:
1. Define maximum extent length as a function of
   BMBT_BLOCKCOUNT_BITLEN.
2. Introduce xfs_iext_max_nextents() function in the patch series
   before renaming MAXEXTNUM/MAXAEXTNUM. This is done to reduce
   proliferation of macros indicating maximum extent count for data
   and attribute forks.
3. Define xfs_dfork_nextents() as an inline function.
4. Use xfs_rfsblock_t as the data type for variables that hold block
   count.
5. xfs_dfork_nextents() now returns -EFSCORRUPTED when an invalid fork
   is passed as an argument.
6. The following changes are done to enable bulkstat ioctl to report
   64-bit extent counters,
   - Carve out a new 64-bit field xfs_bulkstat->bs_extents64 from
     xfs_bulkstat->bs_pad[].
   - Carve out a new 64-bit field xfs_bulk_ireq->bulkstat_flags from
     xfs_bulk_ireq->reserved[] to hold bulkstat specific operational
     flags. Introduce XFS_IBULK_NREXT64 flag to indicate that
     userspace has the necessary infrastructure to receive 64-bit
     extent counters.
   - Define the new flag XFS_BULK_IREQ_BULKSTAT for userspace to
     indicate that xfs_bulk_ireq->bulkstat_flags has valid flags set.
7. Rename the incompat flag from XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT
   to XFS_SB_FEAT_INCOMPAT_NREXT64.
8. Add a new helper function xfs_inode_to_disk_iext_counters() to
   convert from incore inode extent counters to ondisk inode extent
   counters.
9. Reuse XFS_ERRTAG_REDUCE_MAX_IEXTENTS error tag to skip reporting
   inodes with more than 10 extents when bulkstat ioctl is invoked by
   userspace.
10. Introduce the new per-inode XFS_DIFLAG2_NREXT64 flag to indicate
    that the inode uses 64-bit extent counter. This is used to allow
    administrators to upgrade existing filesystems.
11. Export presence of XFS_SB_FEAT_INCOMPAT_NREXT64 feature to
    userspace via XFS_IOC_FSGEOMETRY ioctl.

V1 -> V2:
1. Rebase patches on top of Darrick's btree-dynamic-depth branch.
2. Add new bulkstat ioctl version to support 64-bit data fork extent
   counter field.
3. Introduce new error tag to verify if the old bulkstat ioctls skip
   reporting inodes with large data fork extent counters.

Chandan Babu R (16):
  xfs: Move extent count limits to xfs_format.h
  xfs: Introduce xfs_iext_max_nextents() helper
  xfs: Use xfs_extnum_t instead of basic data types
  xfs: Introduce xfs_dfork_nextents() helper
  xfs: Use basic types to define xfs_log_dinode's di_nextents and
    di_anextents
  xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits
    respectively
  xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs
    feature bit
  xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
  xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers
  xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by
    BMBT
  xfs: Introduce macros to represent new maximum extent counts for
    data/attr forks
  xfs: Introduce per-inode 64-bit extent counters
  xfs: Conditionally upgrade existing inodes to use 64-bit extent
    counters
  xfs: Enable bulkstat ioctl to support 64-bit per-inode extent counters
  xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags
  xfs: Define max extent length based on on-disk format definition

 fs/xfs/libxfs/xfs_alloc.c       |  2 +-
 fs/xfs/libxfs/xfs_bmap.c        | 78 +++++++++++++++---------------
 fs/xfs/libxfs/xfs_bmap_btree.c  |  2 +-
 fs/xfs/libxfs/xfs_format.h      | 52 +++++++++++++++-----
 fs/xfs/libxfs/xfs_fs.h          | 13 +++--
 fs/xfs/libxfs/xfs_ialloc.c      |  2 +
 fs/xfs/libxfs/xfs_inode_buf.c   | 84 +++++++++++++++++++++++++-------
 fs/xfs/libxfs/xfs_inode_fork.c  | 14 +++---
 fs/xfs/libxfs/xfs_inode_fork.h  | 59 ++++++++++++++++++++++-
 fs/xfs/libxfs/xfs_log_format.h  | 22 +++++++--
 fs/xfs/libxfs/xfs_sb.c          |  5 ++
 fs/xfs/libxfs/xfs_trans_resv.c  | 11 +++--
 fs/xfs/libxfs/xfs_types.h       | 11 +----
 fs/xfs/scrub/bmap.c             |  2 +-
 fs/xfs/scrub/inode.c            | 20 ++++----
 fs/xfs/xfs_bmap_util.c          | 14 +++---
 fs/xfs/xfs_inode.c              |  4 +-
 fs/xfs/xfs_inode.h              |  5 ++
 fs/xfs/xfs_inode_item.c         | 23 +++++++--
 fs/xfs/xfs_inode_item_recover.c | 85 ++++++++++++++++++++++++++++-----
 fs/xfs/xfs_ioctl.c              |  3 ++
 fs/xfs/xfs_iomap.c              | 28 +++++------
 fs/xfs/xfs_itable.c             | 24 +++++++++-
 fs/xfs/xfs_itable.h             |  2 +
 fs/xfs/xfs_iwalk.h              |  7 ++-
 fs/xfs/xfs_mount.h              |  2 +
 fs/xfs/xfs_trace.h              |  4 +-
 27 files changed, 428 insertions(+), 150 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-04 23:28   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

Maximum values associated with extent counters i.e. Maximum extent length,
Maximum data extents and Maximum xattr extents are dictated by the on-disk
format. Hence move these definitions over to xfs_format.h.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_format.h | 7 +++++++
 fs/xfs/libxfs/xfs_types.h  | 7 -------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index d665c04e69dd..d75e5b16da7e 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -869,6 +869,13 @@ enum xfs_dinode_fmt {
 	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
 	{ XFS_DINODE_FMT_UUID,		"uuid" }
 
+/*
+ * Max values for extlen, extnum, aextnum.
+ */
+#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
+#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
+#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
+
 /*
  * Inode minimum and maximum sizes.
  */
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index b6da06b40989..794a54cbd0de 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -56,13 +56,6 @@ typedef void *		xfs_failaddr_t;
 #define	NULLFSINO	((xfs_ino_t)-1)
 #define	NULLAGINO	((xfs_agino_t)-1)
 
-/*
- * Max values for extlen, extnum, aextnum.
- */
-#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
-#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
-#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
-
 /*
  * Minimum and maximum blocksize and sectorsize.
  * The blocksize upper limit is pretty much arbitrary.
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-04 23:30   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 03/16] xfs: Use xfs_extnum_t instead of basic data types Chandan Babu R
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

xfs_iext_max_nextents() returns the maximum number of extents possible for one
of data, cow or attribute fork. This helper will be extended further in a
future commit when maximum extent counts associated with data/attribute forks
are increased.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_bmap.c       | 9 ++++-----
 fs/xfs/libxfs/xfs_inode_buf.c  | 8 +++-----
 fs/xfs/libxfs/xfs_inode_fork.c | 2 +-
 fs/xfs/libxfs/xfs_inode_fork.h | 8 ++++++++
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 4dccd4d90622..75e8e8a97568 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -74,13 +74,12 @@ xfs_bmap_compute_maxlevels(
 	 * ATTR2 we have to assume the worst case scenario of a minimum size
 	 * available.
 	 */
-	if (whichfork == XFS_DATA_FORK) {
-		maxleafents = MAXEXTNUM;
+	maxleafents = xfs_iext_max_nextents(whichfork);
+	if (whichfork == XFS_DATA_FORK)
 		sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
-	} else {
-		maxleafents = MAXAEXTNUM;
+	else
 		sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
-	}
+
 	maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
 	minleafrecs = mp->m_bmap_dmnr[0];
 	minnoderecs = mp->m_bmap_dmnr[1];
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index cae9708c8587..e6f9bdc4558f 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -337,6 +337,7 @@ xfs_dinode_verify_fork(
 	int			whichfork)
 {
 	uint32_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+	xfs_extnum_t		max_extents;
 
 	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
 	case XFS_DINODE_FMT_LOCAL:
@@ -358,12 +359,9 @@ xfs_dinode_verify_fork(
 			return __this_address;
 		break;
 	case XFS_DINODE_FMT_BTREE:
-		if (whichfork == XFS_ATTR_FORK) {
-			if (di_nextents > MAXAEXTNUM)
-				return __this_address;
-		} else if (di_nextents > MAXEXTNUM) {
+		max_extents = xfs_iext_max_nextents(whichfork);
+		if (di_nextents > max_extents)
 			return __this_address;
-		}
 		break;
 	default:
 		return __this_address;
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 9149f4f796fc..e136c29a0ec1 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -744,7 +744,7 @@ xfs_iext_count_may_overflow(
 	if (whichfork == XFS_COW_FORK)
 		return 0;
 
-	max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM;
+	max_exts = xfs_iext_max_nextents(whichfork);
 
 	if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
 		max_exts = 10;
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 3d64a3acb0ed..2605f7ff8fc1 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -133,6 +133,14 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
 	return ifp->if_format;
 }
 
+static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
+{
+	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
+		return MAXEXTNUM;
+
+	return MAXAEXTNUM;
+}
+
 struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
 				xfs_extnum_t nextents);
 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 03/16] xfs: Use xfs_extnum_t instead of basic data types
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper Chandan Babu R
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

xfs_extnum_t is the type to use to declare variables which have values
obtained from xfs_dinode->di_[a]nextents. This commit replaces basic
types (e.g. uint32_t) with xfs_extnum_t for such variables.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_bmap.c       | 2 +-
 fs/xfs/libxfs/xfs_inode_buf.c  | 2 +-
 fs/xfs/libxfs/xfs_inode_fork.c | 2 +-
 fs/xfs/scrub/inode.c           | 2 +-
 fs/xfs/xfs_trace.h             | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 75e8e8a97568..6a0da0a2b3fd 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -54,7 +54,7 @@ xfs_bmap_compute_maxlevels(
 {
 	int		level;		/* btree level */
 	uint		maxblocks;	/* max blocks at this level */
-	uint		maxleafents;	/* max leaf entries possible */
+	xfs_extnum_t	maxleafents;	/* max leaf entries possible */
 	int		maxrootrecs;	/* max records in root block */
 	int		minleafrecs;	/* min records in leaf block */
 	int		minnoderecs;	/* min records in node block */
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index e6f9bdc4558f..5c95a5428fc7 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -336,7 +336,7 @@ xfs_dinode_verify_fork(
 	struct xfs_mount	*mp,
 	int			whichfork)
 {
-	uint32_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+	xfs_extnum_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
 	xfs_extnum_t		max_extents;
 
 	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index e136c29a0ec1..a17c4d87520a 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -105,7 +105,7 @@ xfs_iformat_extents(
 	struct xfs_mount	*mp = ip->i_mount;
 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
 	int			state = xfs_bmap_fork_to_state(whichfork);
-	int			nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+	xfs_extnum_t		nex = XFS_DFORK_NEXTENTS(dip, whichfork);
 	int			size = nex * sizeof(xfs_bmbt_rec_t);
 	struct xfs_iext_cursor	icur;
 	struct xfs_bmbt_rec	*dp;
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index 2405b09d03d0..aefdf8fe1372 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -232,7 +232,7 @@ xchk_dinode(
 	size_t			fork_recs;
 	unsigned long long	isize;
 	uint64_t		flags2;
-	uint32_t		nextents;
+	xfs_extnum_t		nextents;
 	uint16_t		flags;
 	uint16_t		mode;
 
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 4a8076ef8cb4..3153db29de40 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -2169,7 +2169,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class,
 		__field(int, which)
 		__field(xfs_ino_t, ino)
 		__field(int, format)
-		__field(int, nex)
+		__field(xfs_extnum_t, nex)
 		__field(int, broot_size)
 		__field(int, fork_off)
 	),
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (2 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 03/16] xfs: Use xfs_extnum_t instead of basic data types Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-04 23:48   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

This commit replaces the macro XFS_DFORK_NEXTENTS() with the helper function
xfs_dfork_nextents(). As of this commit, xfs_dfork_nextents() returns the same
value as XFS_DFORK_NEXTENTS(). A future commit which extends inode's extent
counter fields will add more logic to this helper.

This commit also replaces direct accesses to xfs_dinode->di_[a]nextents
with calls to xfs_dfork_nextents().

No functional changes have been made.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_format.h     |  4 ----
 fs/xfs/libxfs/xfs_inode_buf.c  | 16 +++++++++++-----
 fs/xfs/libxfs/xfs_inode_fork.c | 10 ++++++----
 fs/xfs/libxfs/xfs_inode_fork.h | 32 ++++++++++++++++++++++++++++++++
 fs/xfs/scrub/inode.c           | 18 ++++++++++--------
 5 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index d75e5b16da7e..e5654b578ec0 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -925,10 +925,6 @@ enum xfs_dinode_fmt {
 	((w) == XFS_DATA_FORK ? \
 		(dip)->di_format : \
 		(dip)->di_aformat)
-#define XFS_DFORK_NEXTENTS(dip,w) \
-	((w) == XFS_DATA_FORK ? \
-		be32_to_cpu((dip)->di_nextents) : \
-		be16_to_cpu((dip)->di_anextents))
 
 /*
  * For block and character special files the 32bit dev_t is stored at the
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 5c95a5428fc7..860d32816909 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -336,9 +336,11 @@ xfs_dinode_verify_fork(
 	struct xfs_mount	*mp,
 	int			whichfork)
 {
-	xfs_extnum_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+	xfs_extnum_t		di_nextents;
 	xfs_extnum_t		max_extents;
 
+	di_nextents = xfs_dfork_nextents(dip, whichfork);
+
 	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
 	case XFS_DINODE_FMT_LOCAL:
 		/*
@@ -405,6 +407,8 @@ xfs_dinode_verify(
 	uint16_t		flags;
 	uint64_t		flags2;
 	uint64_t		di_size;
+	xfs_extnum_t            nextents;
+	xfs_filblks_t		nblocks;
 
 	if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
 		return __this_address;
@@ -435,10 +439,12 @@ xfs_dinode_verify(
 	if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
 		return __this_address;
 
+	nextents = xfs_dfork_data_extents(dip);
+	nextents += xfs_dfork_attr_extents(dip);
+	nblocks = be64_to_cpu(dip->di_nblocks);
+
 	/* Fork checks carried over from xfs_iformat_fork */
-	if (mode &&
-	    be32_to_cpu(dip->di_nextents) + be16_to_cpu(dip->di_anextents) >
-			be64_to_cpu(dip->di_nblocks))
+	if (mode && nextents > nblocks)
 		return __this_address;
 
 	if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
@@ -495,7 +501,7 @@ xfs_dinode_verify(
 		default:
 			return __this_address;
 		}
-		if (dip->di_anextents)
+		if (xfs_dfork_attr_extents(dip))
 			return __this_address;
 	}
 
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index a17c4d87520a..829739e249b6 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -105,7 +105,7 @@ xfs_iformat_extents(
 	struct xfs_mount	*mp = ip->i_mount;
 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
 	int			state = xfs_bmap_fork_to_state(whichfork);
-	xfs_extnum_t		nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+	xfs_extnum_t		nex = xfs_dfork_nextents(dip, whichfork);
 	int			size = nex * sizeof(xfs_bmbt_rec_t);
 	struct xfs_iext_cursor	icur;
 	struct xfs_bmbt_rec	*dp;
@@ -230,7 +230,7 @@ xfs_iformat_data_fork(
 	 * depend on it.
 	 */
 	ip->i_df.if_format = dip->di_format;
-	ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents);
+	ip->i_df.if_nextents = xfs_dfork_data_extents(dip);
 
 	switch (inode->i_mode & S_IFMT) {
 	case S_IFIFO:
@@ -295,14 +295,16 @@ xfs_iformat_attr_fork(
 	struct xfs_inode	*ip,
 	struct xfs_dinode	*dip)
 {
+	xfs_extnum_t		naextents;
 	int			error = 0;
 
+	naextents = xfs_dfork_attr_extents(dip);
+
 	/*
 	 * Initialize the extent count early, as the per-format routines may
 	 * depend on it.
 	 */
-	ip->i_afp = xfs_ifork_alloc(dip->di_aformat,
-				be16_to_cpu(dip->di_anextents));
+	ip->i_afp = xfs_ifork_alloc(dip->di_aformat, naextents);
 
 	switch (ip->i_afp->if_format) {
 	case XFS_DINODE_FMT_LOCAL:
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 2605f7ff8fc1..7ed2ecb51bca 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -141,6 +141,38 @@ static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
 	return MAXAEXTNUM;
 }
 
+static inline xfs_extnum_t
+xfs_dfork_data_extents(
+	struct xfs_dinode	*dip)
+{
+	return be32_to_cpu(dip->di_nextents);
+}
+
+static inline xfs_extnum_t
+xfs_dfork_attr_extents(
+	struct xfs_dinode	*dip)
+{
+	return be16_to_cpu(dip->di_anextents);
+}
+
+static inline xfs_extnum_t
+xfs_dfork_nextents(
+	struct xfs_dinode	*dip,
+	int			whichfork)
+{
+	switch (whichfork) {
+	case XFS_DATA_FORK:
+		return xfs_dfork_data_extents(dip);
+	case XFS_ATTR_FORK:
+		return xfs_dfork_attr_extents(dip);
+	default:
+		ASSERT(0);
+		break;
+	}
+
+	return 0;
+}
+
 struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
 				xfs_extnum_t nextents);
 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index aefdf8fe1372..a601b04fe408 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -233,6 +233,7 @@ xchk_dinode(
 	unsigned long long	isize;
 	uint64_t		flags2;
 	xfs_extnum_t		nextents;
+	xfs_extnum_t		naextents;
 	uint16_t		flags;
 	uint16_t		mode;
 
@@ -377,7 +378,7 @@ xchk_dinode(
 	xchk_inode_extsize(sc, dip, ino, mode, flags);
 
 	/* di_nextents */
-	nextents = be32_to_cpu(dip->di_nextents);
+	nextents = xfs_dfork_data_extents(dip);
 	fork_recs =  XFS_DFORK_DSIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
 	switch (dip->di_format) {
 	case XFS_DINODE_FMT_EXTENTS:
@@ -394,10 +395,12 @@ xchk_dinode(
 		break;
 	}
 
+	naextents = xfs_dfork_attr_extents(dip);
+
 	/* di_forkoff */
 	if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize)
 		xchk_ino_set_corrupt(sc, ino);
-	if (dip->di_anextents != 0 && dip->di_forkoff == 0)
+	if (naextents != 0 && dip->di_forkoff == 0)
 		xchk_ino_set_corrupt(sc, ino);
 	if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS)
 		xchk_ino_set_corrupt(sc, ino);
@@ -409,19 +412,18 @@ xchk_dinode(
 		xchk_ino_set_corrupt(sc, ino);
 
 	/* di_anextents */
-	nextents = be16_to_cpu(dip->di_anextents);
 	fork_recs =  XFS_DFORK_ASIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
 	switch (dip->di_aformat) {
 	case XFS_DINODE_FMT_EXTENTS:
-		if (nextents > fork_recs)
+		if (naextents > fork_recs)
 			xchk_ino_set_corrupt(sc, ino);
 		break;
 	case XFS_DINODE_FMT_BTREE:
-		if (nextents <= fork_recs)
+		if (naextents <= fork_recs)
 			xchk_ino_set_corrupt(sc, ino);
 		break;
 	default:
-		if (nextents != 0)
+		if (naextents != 0)
 			xchk_ino_set_corrupt(sc, ino);
 	}
 
@@ -499,14 +501,14 @@ xchk_inode_xref_bmap(
 			&nextents, &count);
 	if (!xchk_should_check_xref(sc, &error, NULL))
 		return;
-	if (nextents < be32_to_cpu(dip->di_nextents))
+	if (nextents < xfs_dfork_data_extents(dip))
 		xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
 
 	error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK,
 			&nextents, &acount);
 	if (!xchk_should_check_xref(sc, &error, NULL))
 		return;
-	if (nextents != be16_to_cpu(dip->di_anextents))
+	if (nextents != xfs_dfork_attr_extents(dip))
 		xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
 
 	/* Check nblocks against the inode. */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (3 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-04 23:50   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

A future commit will increase the width of xfs_extnum_t in order to facilitate
larger per-inode extent counters. Hence this patch now uses basic types to
define xfs_log_dinode->[di_nextents|dianextents].

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_log_format.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index b322db523d65..fd66e70248f7 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -396,8 +396,8 @@ struct xfs_log_dinode {
 	xfs_fsize_t	di_size;	/* number of bytes in file */
 	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
 	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
-	xfs_extnum_t	di_nextents;	/* number of extents in data fork */
-	xfs_aextnum_t	di_anextents;	/* number of extents in attribute fork*/
+	uint32_t	di_nextents;	/* number of extents in data fork */
+	uint16_t	di_anextents;	/* number of extents in attribute fork*/
 	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
 	int8_t		di_aformat;	/* format of attr fork's data */
 	uint32_t	di_dmevmask;	/* DMIG event mask */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (4 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2021-12-14 14:54     ` kernel test robot
                     ` (2 more replies)
  2021-12-14  8:45 ` [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
                   ` (9 subsequent siblings)
  15 siblings, 3 replies; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

A future commit will introduce a 64-bit on-disk data extent counter and a
32-bit on-disk attr extent counter. This commit promotes xfs_extnum_t and
xfs_aextnum_t to 64 and 32-bits in order to correctly handle in-core versions
of these quantities.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_bmap.c       | 4 ++--
 fs/xfs/libxfs/xfs_inode_fork.c | 2 +-
 fs/xfs/libxfs/xfs_inode_fork.h | 2 +-
 fs/xfs/libxfs/xfs_types.h      | 4 ++--
 fs/xfs/xfs_inode.c             | 4 ++--
 fs/xfs/xfs_trace.h             | 2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 6a0da0a2b3fd..4071dee181b1 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -52,9 +52,9 @@ xfs_bmap_compute_maxlevels(
 	xfs_mount_t	*mp,		/* file system mount structure */
 	int		whichfork)	/* data or attr fork */
 {
+	xfs_extnum_t	maxleafents;	/* max leaf entries possible */
 	int		level;		/* btree level */
 	uint		maxblocks;	/* max blocks at this level */
-	xfs_extnum_t	maxleafents;	/* max leaf entries possible */
 	int		maxrootrecs;	/* max records in root block */
 	int		minleafrecs;	/* min records in leaf block */
 	int		minnoderecs;	/* min records in node block */
@@ -467,7 +467,7 @@ xfs_bmap_check_leaf_extents(
 	if (bp_release)
 		xfs_trans_brelse(NULL, bp);
 error_norelse:
-	xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
+	xfs_warn(mp, "%s: BAD after btree leaves for %llu extents",
 		__func__, i);
 	xfs_err(mp, "%s: CORRUPTED BTREE OR SOMETHING", __func__);
 	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 829739e249b6..ce690abe5dce 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -117,7 +117,7 @@ xfs_iformat_extents(
 	 * we just bail out rather than crash in kmem_alloc() or memcpy() below.
 	 */
 	if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
-		xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
+		xfs_warn(ip->i_mount, "corrupt inode %llu ((a)extents = %llu).",
 			(unsigned long long) ip->i_ino, nex);
 		xfs_inode_verifier_error(ip, -EFSCORRUPTED,
 				"xfs_iformat_extents(1)", dip, sizeof(*dip),
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 7ed2ecb51bca..4a8b77d425df 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -21,9 +21,9 @@ struct xfs_ifork {
 		void		*if_root;	/* extent tree root */
 		char		*if_data;	/* inline file data */
 	} if_u1;
+	xfs_extnum_t		if_nextents;	/* # of extents in this fork */
 	short			if_broot_bytes;	/* bytes allocated for root */
 	int8_t			if_format;	/* format of this fork */
-	xfs_extnum_t		if_nextents;	/* # of extents in this fork */
 };
 
 /*
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 794a54cbd0de..373f64a492a4 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -12,8 +12,8 @@ typedef uint32_t	xfs_agblock_t;	/* blockno in alloc. group */
 typedef uint32_t	xfs_agino_t;	/* inode # within allocation grp */
 typedef uint32_t	xfs_extlen_t;	/* extent length in blocks */
 typedef uint32_t	xfs_agnumber_t;	/* allocation group number */
-typedef int32_t		xfs_extnum_t;	/* # of extents in a file */
-typedef int16_t		xfs_aextnum_t;	/* # extents in an attribute fork */
+typedef uint64_t	xfs_extnum_t;	/* # of extents in a file */
+typedef uint32_t	xfs_aextnum_t;	/* # extents in an attribute fork */
 typedef int64_t		xfs_fsize_t;	/* bytes in a file */
 typedef uint64_t	xfs_ufsize_t;	/* unsigned bytes in a file */
 
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 64b9bf334806..b8095634eeb3 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3496,8 +3496,8 @@ xfs_iflush(
 	if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) >
 				ip->i_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) {
 		xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
-			"%s: detected corrupt incore inode %Lu, "
-			"total extents = %d, nblocks = %Ld, ptr "PTR_FMT,
+			"%s: detected corrupt incore inode %llu, "
+			"total extents = %llu nblocks = %lld, ptr "PTR_FMT,
 			__func__, ip->i_ino,
 			ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp),
 			ip->i_nblocks, ip);
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 3153db29de40..6b4a7f197308 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -2182,7 +2182,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class,
 		__entry->broot_size = ip->i_df.if_broot_bytes;
 		__entry->fork_off = XFS_IFORK_BOFF(ip);
 	),
-	TP_printk("dev %d:%d ino 0x%llx (%s), %s format, num_extents %d, "
+	TP_printk("dev %d:%d ino 0x%llx (%s), %s format, num_extents %llu, "
 		  "broot size %d, forkoff 0x%x",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->ino,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (5 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:03   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

XFS_SB_FEAT_INCOMPAT_NREXT64 incompat feature bit will be set on filesystems
which support large per-inode extent counters. This commit defines the new
incompat feature bit and the corresponding per-fs feature bit (along with
inline functions to work on it).

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_format.h | 1 +
 fs/xfs/libxfs/xfs_sb.c     | 3 +++
 fs/xfs/xfs_mount.h         | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index e5654b578ec0..7972cbc22608 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -372,6 +372,7 @@ xfs_sb_has_ro_compat_feature(
 #define XFS_SB_FEAT_INCOMPAT_META_UUID	(1 << 2)	/* metadata UUID */
 #define XFS_SB_FEAT_INCOMPAT_BIGTIME	(1 << 3)	/* large timestamps */
 #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4)	/* needs xfs_repair */
+#define XFS_SB_FEAT_INCOMPAT_NREXT64	(1 << 5)	/* 64-bit data fork extent counter */
 #define XFS_SB_FEAT_INCOMPAT_ALL \
 		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\
 		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index f4e84aa1d50a..bd632389ae92 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -124,6 +124,9 @@ xfs_sb_version_to_features(
 		features |= XFS_FEAT_BIGTIME;
 	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
 		features |= XFS_FEAT_NEEDSREPAIR;
+	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NREXT64)
+		features |= XFS_FEAT_NREXT64;
+
 	return features;
 }
 
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 00720a02e761..10941481f7e6 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -276,6 +276,7 @@ typedef struct xfs_mount {
 #define XFS_FEAT_INOBTCNT	(1ULL << 23)	/* inobt block counts */
 #define XFS_FEAT_BIGTIME	(1ULL << 24)	/* large timestamps */
 #define XFS_FEAT_NEEDSREPAIR	(1ULL << 25)	/* needs xfs_repair */
+#define XFS_FEAT_NREXT64	(1ULL << 26)	/* 64-bit inode extent counters */
 
 /* Mount features */
 #define XFS_FEAT_NOATTR2	(1ULL << 48)	/* disable attr2 creation */
@@ -338,6 +339,7 @@ __XFS_HAS_FEAT(realtime, REALTIME)
 __XFS_HAS_FEAT(inobtcounts, INOBTCNT)
 __XFS_HAS_FEAT(bigtime, BIGTIME)
 __XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
+__XFS_HAS_FEAT(nrext64, NREXT64)
 
 /*
  * Mount features
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (6 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:05   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

XFS_FSOP_GEOM_FLAGS_NREXT64 indicates that the current filesystem instance
supports 64-bit per-inode extent counters.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_fs.h | 1 +
 fs/xfs/libxfs/xfs_sb.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index c43877c8a279..42bc39501d81 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
 #define XFS_FSOP_GEOM_FLAGS_REFLINK	(1 << 20) /* files can share blocks */
 #define XFS_FSOP_GEOM_FLAGS_BIGTIME	(1 << 21) /* 64-bit nsec timestamps */
 #define XFS_FSOP_GEOM_FLAGS_INOBTCNT	(1 << 22) /* inobt btree counter */
+#define XFS_FSOP_GEOM_FLAGS_NREXT64	(1 << 23) /* 64-bit extent counter */
 
 /*
  * Minimum and maximum sizes need for growth checks.
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index bd632389ae92..0c1add39177f 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -1138,6 +1138,8 @@ xfs_fs_geometry(
 	} else {
 		geo->logsectsize = BBSIZE;
 	}
+	if (xfs_has_nrext64(mp))
+		geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64;
 	geo->rtsectsize = sbp->sb_blocksize;
 	geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (7 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:43   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

This commit adds the new per-inode flag XFS_DIFLAG2_NREXT64 to indicate that
an inode supports 64-bit extent counters. This flag is also enabled by default
on newly created inodes when the corresponding filesystem has large extent
counter feature bit (i.e. XFS_FEAT_NREXT64) set.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_format.h      | 10 +++++++++-
 fs/xfs/libxfs/xfs_ialloc.c      |  2 ++
 fs/xfs/xfs_inode.h              |  5 +++++
 fs/xfs/xfs_inode_item_recover.c |  6 ++++++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 7972cbc22608..9934c320bf01 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -992,15 +992,17 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
 #define XFS_DIFLAG2_REFLINK_BIT	1	/* file's blocks may be shared */
 #define XFS_DIFLAG2_COWEXTSIZE_BIT   2  /* copy on write extent size hint */
 #define XFS_DIFLAG2_BIGTIME_BIT	3	/* big timestamps */
+#define XFS_DIFLAG2_NREXT64_BIT 4	/* 64-bit extent counter enabled */
 
 #define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)
 #define XFS_DIFLAG2_REFLINK     (1 << XFS_DIFLAG2_REFLINK_BIT)
 #define XFS_DIFLAG2_COWEXTSIZE  (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
 #define XFS_DIFLAG2_BIGTIME	(1 << XFS_DIFLAG2_BIGTIME_BIT)
+#define XFS_DIFLAG2_NREXT64	(1 << XFS_DIFLAG2_NREXT64_BIT)
 
 #define XFS_DIFLAG2_ANY \
 	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
-	 XFS_DIFLAG2_BIGTIME)
+	 XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64)
 
 static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
 {
@@ -1008,6 +1010,12 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
 	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
 }
 
+static inline bool xfs_dinode_has_nrext64(const struct xfs_dinode *dip)
+{
+	return dip->di_version >= 3 &&
+	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64));
+}
+
 /*
  * Inode number format:
  * low inopblog bits - offset in block
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index b418fe0c0679..1d2ba51483ec 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -2772,6 +2772,8 @@ xfs_ialloc_setup_geometry(
 	igeo->new_diflags2 = 0;
 	if (xfs_has_bigtime(mp))
 		igeo->new_diflags2 |= XFS_DIFLAG2_BIGTIME;
+	if (xfs_has_nrext64(mp))
+		igeo->new_diflags2 |= XFS_DIFLAG2_NREXT64;
 
 	/* Compute inode btree geometry. */
 	igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index c447bf04205a..97946156359d 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -218,6 +218,11 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
 	return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
 }
 
+static inline bool xfs_inode_has_nrext64(struct xfs_inode *ip)
+{
+	return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
+}
+
 /*
  * Return the buftarg used for data allocations on a given inode.
  */
diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
index 239dd2e3384e..767a551816a0 100644
--- a/fs/xfs/xfs_inode_item_recover.c
+++ b/fs/xfs/xfs_inode_item_recover.c
@@ -142,6 +142,12 @@ xfs_log_dinode_to_disk_ts(
 	return ts;
 }
 
+static inline bool xfs_log_dinode_has_nrext64(const struct xfs_log_dinode *ld)
+{
+	return ld->di_version >= 3 &&
+	       (ld->di_flags2 & XFS_DIFLAG2_NREXT64);
+}
+
 STATIC void
 xfs_log_dinode_to_disk(
 	struct xfs_log_dinode	*from,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (8 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2021-12-14 18:15     ` kernel test robot
  2021-12-14  8:45 ` [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_bmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 4071dee181b1..4113622e9733 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -53,8 +53,8 @@ xfs_bmap_compute_maxlevels(
 	int		whichfork)	/* data or attr fork */
 {
 	xfs_extnum_t	maxleafents;	/* max leaf entries possible */
+	xfs_rfsblock_t	maxblocks;	/* max blocks at this level */
 	int		level;		/* btree level */
-	uint		maxblocks;	/* max blocks at this level */
 	int		maxrootrecs;	/* max records in root block */
 	int		minleafrecs;	/* min records in leaf block */
 	int		minnoderecs;	/* min records in node block */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (9 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:42   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters Chandan Babu R
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

This commit defines new macros to represent maximum extent counts allowed by
filesystems which have support for large per-inode extent counters.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_bmap.c       |  8 +++-----
 fs/xfs/libxfs/xfs_bmap_btree.c |  2 +-
 fs/xfs/libxfs/xfs_format.h     |  8 +++++---
 fs/xfs/libxfs/xfs_inode_buf.c  |  3 ++-
 fs/xfs/libxfs/xfs_inode_fork.c |  2 +-
 fs/xfs/libxfs/xfs_inode_fork.h | 19 +++++++++++++++----
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 4113622e9733..0ce58e4a9c44 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -61,10 +61,8 @@ xfs_bmap_compute_maxlevels(
 	int		sz;		/* root block size */
 
 	/*
-	 * The maximum number of extents in a file, hence the maximum number of
-	 * leaf entries, is controlled by the size of the on-disk extent count,
-	 * either a signed 32-bit number for the data fork, or a signed 16-bit
-	 * number for the attr fork.
+	 * The maximum number of extents in a fork, hence the maximum number of
+	 * leaf entries, is controlled by the size of the on-disk extent count.
 	 *
 	 * Note that we can no longer assume that if we are in ATTR1 that the
 	 * fork offset of all the inodes will be
@@ -74,7 +72,7 @@ xfs_bmap_compute_maxlevels(
 	 * ATTR2 we have to assume the worst case scenario of a minimum size
 	 * available.
 	 */
-	maxleafents = xfs_iext_max_nextents(whichfork);
+	maxleafents = xfs_iext_max_nextents(xfs_has_nrext64(mp), whichfork);
 	if (whichfork == XFS_DATA_FORK)
 		sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
 	else
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index 453309fc85f2..e8d21d69b9ff 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -611,7 +611,7 @@ xfs_bmbt_maxlevels_ondisk(void)
 	minrecs[1] = xfs_bmbt_block_maxrecs(blocklen, false) / 2;
 
 	/* One extra level for the inode root. */
-	return xfs_btree_compute_maxlevels(minrecs, MAXEXTNUM) + 1;
+	return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_EXTCNT_DATA_FORK) + 1;
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 9934c320bf01..eff86f6c4c99 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -873,9 +873,11 @@ enum xfs_dinode_fmt {
 /*
  * Max values for extlen, extnum, aextnum.
  */
-#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
-#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
-#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
+#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
+#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
+#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
 
 /*
  * Inode minimum and maximum sizes.
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 860d32816909..34f360a38603 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -361,7 +361,8 @@ xfs_dinode_verify_fork(
 			return __this_address;
 		break;
 	case XFS_DINODE_FMT_BTREE:
-		max_extents = xfs_iext_max_nextents(whichfork);
+		max_extents = xfs_iext_max_nextents(xfs_dinode_has_nrext64(dip),
+					whichfork);
 		if (di_nextents > max_extents)
 			return __this_address;
 		break;
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index ce690abe5dce..a3a3b54f9c55 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -746,7 +746,7 @@ xfs_iext_count_may_overflow(
 	if (whichfork == XFS_COW_FORK)
 		return 0;
 
-	max_exts = xfs_iext_max_nextents(whichfork);
+	max_exts = xfs_iext_max_nextents(xfs_inode_has_nrext64(ip), whichfork);
 
 	if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
 		max_exts = 10;
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 4a8b77d425df..0cfc351648f9 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -133,12 +133,23 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
 	return ifp->if_format;
 }
 
-static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
+static inline xfs_extnum_t xfs_iext_max_nextents(bool has_big_extcnt,
+				int whichfork)
 {
-	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
-		return MAXEXTNUM;
+	switch (whichfork) {
+	case XFS_DATA_FORK:
+	case XFS_COW_FORK:
+		return has_big_extcnt ? XFS_MAX_EXTCNT_DATA_FORK
+			: XFS_MAX_EXTCNT_DATA_FORK_OLD;
+
+	case XFS_ATTR_FORK:
+		return has_big_extcnt ? XFS_MAX_EXTCNT_ATTR_FORK
+			: XFS_MAX_EXTCNT_ATTR_FORK_OLD;
 
-	return MAXAEXTNUM;
+	default:
+		ASSERT(0);
+		return 0;
+	}
 }
 
 static inline xfs_extnum_t
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (10 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  1:04   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use " Chandan Babu R
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david, Dave Chinner

This commit introduces new fields in the on-disk inode format to support
64-bit data fork extent counters and 32-bit attribute fork extent
counters. The new fields will be used only when an inode has
XFS_DIFLAG2_NREXT64 flag set. Otherwise we continue to use the regular 32-bit
data fork extent counters and 16-bit attribute fork extent counters.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Suggested-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/libxfs/xfs_format.h      | 22 +++++++--
 fs/xfs/libxfs/xfs_inode_buf.c   | 49 ++++++++++++++++++--
 fs/xfs/libxfs/xfs_inode_fork.h  | 10 ++++-
 fs/xfs/libxfs/xfs_log_format.h  | 22 +++++++--
 fs/xfs/xfs_inode_item.c         | 23 ++++++++--
 fs/xfs/xfs_inode_item_recover.c | 79 ++++++++++++++++++++++++++++-----
 6 files changed, 176 insertions(+), 29 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index eff86f6c4c99..2868cec1154d 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -792,16 +792,30 @@ struct xfs_dinode {
 	__be32		di_nlink;	/* number of links to file */
 	__be16		di_projid_lo;	/* lower part of owner's project id */
 	__be16		di_projid_hi;	/* higher part owner's project id */
-	__u8		di_pad[6];	/* unused, zeroed space */
-	__be16		di_flushiter;	/* incremented on flush */
+	union {
+		__be64	di_big_dextcnt;	/* NREXT64 data extents */
+		__u8	di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
+		struct {
+			__u8	di_v2_pad[6];	/* V2 inode zeroed space */
+			__be16	di_flushiter;	/* V2 inode incremented on flush */
+		};
+	};
 	xfs_timestamp_t	di_atime;	/* time last accessed */
 	xfs_timestamp_t	di_mtime;	/* time last modified */
 	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
 	__be64		di_size;	/* number of bytes in file */
 	__be64		di_nblocks;	/* # of direct & btree blocks used */
 	__be32		di_extsize;	/* basic/minimum extent size for file */
-	__be32		di_nextents;	/* number of extents in data fork */
-	__be16		di_anextents;	/* number of extents in attribute fork*/
+	union {
+		struct {
+			__be32	di_big_aextcnt; /* NREXT64 attr extents */
+			__be16	di_nrext64_pad; /* NREXT64 unused, zero */
+		} __packed;
+		struct {
+			__be32	di_nextents;	/* !NREXT64 data extents */
+			__be16	di_anextents;	/* !NREXT64 attr extents */
+		} __packed;
+	};
 	__u8		di_forkoff;	/* attr fork offs, <<3 for 64b align */
 	__s8		di_aformat;	/* format of attr fork's data */
 	__be32		di_dmevmask;	/* DMIG event mask */
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 34f360a38603..fe21e9808f80 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -279,6 +279,25 @@ xfs_inode_to_disk_ts(
 	return ts;
 }
 
+static inline void
+xfs_inode_to_disk_iext_counters(
+	struct xfs_inode	*ip,
+	struct xfs_dinode	*to)
+{
+	if (xfs_inode_has_nrext64(ip)) {
+		to->di_big_dextcnt = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
+		to->di_big_aextcnt = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
+		/*
+		 * We might be upgrading the inode to use larger extent counters
+		 * than was previously used. Hence zero the unused field.
+		 */
+		to->di_nrext64_pad = cpu_to_be16(0);
+	} else {
+		to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
+		to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
+	}
+}
+
 void
 xfs_inode_to_disk(
 	struct xfs_inode	*ip,
@@ -296,7 +315,6 @@ xfs_inode_to_disk(
 	to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
 	to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
 
-	memset(to->di_pad, 0, sizeof(to->di_pad));
 	to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
 	to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
 	to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
@@ -307,8 +325,6 @@ xfs_inode_to_disk(
 	to->di_size = cpu_to_be64(ip->i_disk_size);
 	to->di_nblocks = cpu_to_be64(ip->i_nblocks);
 	to->di_extsize = cpu_to_be32(ip->i_extsize);
-	to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
-	to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
 	to->di_forkoff = ip->i_forkoff;
 	to->di_aformat = xfs_ifork_format(ip->i_afp);
 	to->di_flags = cpu_to_be16(ip->i_diflags);
@@ -323,11 +339,14 @@ xfs_inode_to_disk(
 		to->di_lsn = cpu_to_be64(lsn);
 		memset(to->di_pad2, 0, sizeof(to->di_pad2));
 		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
-		to->di_flushiter = 0;
+		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
 	} else {
 		to->di_version = 2;
 		to->di_flushiter = cpu_to_be16(ip->i_flushiter);
+		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
 	}
+
+	xfs_inode_to_disk_iext_counters(ip, to);
 }
 
 static xfs_failaddr_t
@@ -397,6 +416,24 @@ xfs_dinode_verify_forkoff(
 	return NULL;
 }
 
+static xfs_failaddr_t
+xfs_dinode_verify_nextents(
+	struct xfs_mount	*mp,
+	struct xfs_dinode	*dip)
+{
+	if (xfs_dinode_has_nrext64(dip)) {
+		if (!xfs_has_nrext64(mp))
+			return __this_address;
+		if (dip->di_nrext64_pad != 0)
+			return __this_address;
+	} else {
+		if (dip->di_version == 3 && dip->di_big_dextcnt != 0)
+			return __this_address;
+	}
+
+	return NULL;
+}
+
 xfs_failaddr_t
 xfs_dinode_verify(
 	struct xfs_mount	*mp,
@@ -440,6 +477,10 @@ xfs_dinode_verify(
 	if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
 		return __this_address;
 
+	fa = xfs_dinode_verify_nextents(mp, dip);
+	if (fa)
+		return fa;
+
 	nextents = xfs_dfork_data_extents(dip);
 	nextents += xfs_dfork_attr_extents(dip);
 	nblocks = be64_to_cpu(dip->di_nblocks);
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index 0cfc351648f9..fa5143fb889b 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -156,14 +156,20 @@ static inline xfs_extnum_t
 xfs_dfork_data_extents(
 	struct xfs_dinode	*dip)
 {
-	return be32_to_cpu(dip->di_nextents);
+	if (xfs_dinode_has_nrext64(dip))
+		return be64_to_cpu(dip->di_big_dextcnt);
+	else
+		return be32_to_cpu(dip->di_nextents);
 }
 
 static inline xfs_extnum_t
 xfs_dfork_attr_extents(
 	struct xfs_dinode	*dip)
 {
-	return be16_to_cpu(dip->di_anextents);
+	if (xfs_dinode_has_nrext64(dip))
+		return be32_to_cpu(dip->di_big_aextcnt);
+	else
+		return be16_to_cpu(dip->di_anextents);
 }
 
 static inline xfs_extnum_t
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index fd66e70248f7..46aed637c98b 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -388,16 +388,30 @@ struct xfs_log_dinode {
 	uint32_t	di_nlink;	/* number of links to file */
 	uint16_t	di_projid_lo;	/* lower part of owner's project id */
 	uint16_t	di_projid_hi;	/* higher part of owner's project id */
-	uint8_t		di_pad[6];	/* unused, zeroed space */
-	uint16_t	di_flushiter;	/* incremented on flush */
+	union {
+		uint64_t	di_big_dextcnt;	/* NREXT64 data extents */
+		uint8_t		di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
+		struct {
+			uint8_t	di_v2_pad[6];	/* V2 inode zeroed space */
+			uint16_t di_flushiter;	/* V2 inode incremented on flush */
+		};
+	};
 	xfs_log_timestamp_t di_atime;	/* time last accessed */
 	xfs_log_timestamp_t di_mtime;	/* time last modified */
 	xfs_log_timestamp_t di_ctime;	/* time created/inode modified */
 	xfs_fsize_t	di_size;	/* number of bytes in file */
 	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
 	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
-	uint32_t	di_nextents;	/* number of extents in data fork */
-	uint16_t	di_anextents;	/* number of extents in attribute fork*/
+	union {
+		struct {
+			uint32_t  di_big_aextcnt; /* NREXT64 attr extents */
+			uint16_t  di_nrext64_pad; /* NREXT64 unused, zero */
+		} __packed;
+		struct {
+			uint32_t  di_nextents;	  /* !NREXT64 data extents */
+			uint16_t  di_anextents;	  /* !NREXT64 attr extents */
+		} __packed;
+	};
 	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
 	int8_t		di_aformat;	/* format of attr fork's data */
 	uint32_t	di_dmevmask;	/* DMIG event mask */
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 90d8e591baf8..82f4b9bb871b 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -358,6 +358,21 @@ xfs_copy_dm_fields_to_log_dinode(
 	}
 }
 
+static inline void
+xfs_inode_to_log_dinode_iext_counters(
+	struct xfs_inode	*ip,
+	struct xfs_log_dinode	*to)
+{
+	if (xfs_inode_has_nrext64(ip)) {
+		to->di_big_dextcnt = xfs_ifork_nextents(&ip->i_df);
+		to->di_big_aextcnt = xfs_ifork_nextents(ip->i_afp);
+		to->di_nrext64_pad = 0;
+	} else {
+		to->di_nextents = xfs_ifork_nextents(&ip->i_df);
+		to->di_anextents = xfs_ifork_nextents(ip->i_afp);
+	}
+}
+
 static void
 xfs_inode_to_log_dinode(
 	struct xfs_inode	*ip,
@@ -373,7 +388,6 @@ xfs_inode_to_log_dinode(
 	to->di_projid_lo = ip->i_projid & 0xffff;
 	to->di_projid_hi = ip->i_projid >> 16;
 
-	memset(to->di_pad, 0, sizeof(to->di_pad));
 	memset(to->di_pad3, 0, sizeof(to->di_pad3));
 	to->di_atime = xfs_inode_to_log_dinode_ts(ip, inode->i_atime);
 	to->di_mtime = xfs_inode_to_log_dinode_ts(ip, inode->i_mtime);
@@ -385,8 +399,6 @@ xfs_inode_to_log_dinode(
 	to->di_size = ip->i_disk_size;
 	to->di_nblocks = ip->i_nblocks;
 	to->di_extsize = ip->i_extsize;
-	to->di_nextents = xfs_ifork_nextents(&ip->i_df);
-	to->di_anextents = xfs_ifork_nextents(ip->i_afp);
 	to->di_forkoff = ip->i_forkoff;
 	to->di_aformat = xfs_ifork_format(ip->i_afp);
 	to->di_flags = ip->i_diflags;
@@ -406,11 +418,14 @@ xfs_inode_to_log_dinode(
 		to->di_lsn = lsn;
 		memset(to->di_pad2, 0, sizeof(to->di_pad2));
 		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
-		to->di_flushiter = 0;
+		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
 	} else {
 		to->di_version = 2;
 		to->di_flushiter = ip->i_flushiter;
+		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
 	}
+
+	xfs_inode_to_log_dinode_iext_counters(ip, to);
 }
 
 /*
diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
index 767a551816a0..7434ad4772dc 100644
--- a/fs/xfs/xfs_inode_item_recover.c
+++ b/fs/xfs/xfs_inode_item_recover.c
@@ -148,6 +148,22 @@ static inline bool xfs_log_dinode_has_nrext64(const struct xfs_log_dinode *ld)
 	       (ld->di_flags2 & XFS_DIFLAG2_NREXT64);
 }
 
+static inline void
+xfs_log_dinode_to_disk_iext_counters(
+	struct xfs_log_dinode	*from,
+	struct xfs_dinode	*to)
+{
+	if (xfs_log_dinode_has_nrext64(from)) {
+		to->di_big_dextcnt = cpu_to_be64(from->di_big_dextcnt);
+		to->di_big_aextcnt = cpu_to_be32(from->di_big_aextcnt);
+		to->di_nrext64_pad = cpu_to_be16(from->di_nrext64_pad);
+	} else {
+		to->di_nextents = cpu_to_be32(from->di_nextents);
+		to->di_anextents = cpu_to_be16(from->di_anextents);
+	}
+
+}
+
 STATIC void
 xfs_log_dinode_to_disk(
 	struct xfs_log_dinode	*from,
@@ -164,7 +180,6 @@ xfs_log_dinode_to_disk(
 	to->di_nlink = cpu_to_be32(from->di_nlink);
 	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
 	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
-	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
 
 	to->di_atime = xfs_log_dinode_to_disk_ts(from, from->di_atime);
 	to->di_mtime = xfs_log_dinode_to_disk_ts(from, from->di_mtime);
@@ -173,8 +188,6 @@ xfs_log_dinode_to_disk(
 	to->di_size = cpu_to_be64(from->di_size);
 	to->di_nblocks = cpu_to_be64(from->di_nblocks);
 	to->di_extsize = cpu_to_be32(from->di_extsize);
-	to->di_nextents = cpu_to_be32(from->di_nextents);
-	to->di_anextents = cpu_to_be16(from->di_anextents);
 	to->di_forkoff = from->di_forkoff;
 	to->di_aformat = from->di_aformat;
 	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
@@ -192,10 +205,13 @@ xfs_log_dinode_to_disk(
 		to->di_lsn = cpu_to_be64(lsn);
 		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
 		uuid_copy(&to->di_uuid, &from->di_uuid);
-		to->di_flushiter = 0;
+		memcpy(to->di_v3_pad, from->di_v3_pad, sizeof(to->di_v3_pad));
 	} else {
 		to->di_flushiter = cpu_to_be16(from->di_flushiter);
+		memcpy(to->di_v2_pad, from->di_v2_pad, sizeof(to->di_v2_pad));
 	}
+
+	xfs_log_dinode_to_disk_iext_counters(from, to);
 }
 
 STATIC int
@@ -209,6 +225,8 @@ xlog_recover_inode_commit_pass2(
 	struct xfs_mount		*mp = log->l_mp;
 	struct xfs_buf			*bp;
 	struct xfs_dinode		*dip;
+	xfs_extnum_t                    nextents;
+	xfs_aextnum_t                   anextents;
 	int				len;
 	char				*src;
 	char				*dest;
@@ -348,21 +366,60 @@ xlog_recover_inode_commit_pass2(
 			goto out_release;
 		}
 	}
-	if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
-		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
+
+	if (xfs_log_dinode_has_nrext64(ldip)) {
+		if (!xfs_has_nrext64(mp) || (ldip->di_nrext64_pad != 0)) {
+			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
+				     XFS_ERRLEVEL_LOW, mp, ldip,
+				     sizeof(*ldip));
+			xfs_alert(mp,
+				"%s: Bad inode log record, rec ptr "PTR_FMT", "
+				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
+				"ino %Ld, xfs_has_nrext64(mp) = %d, "
+				"ldip->di_nrext64_pad = %u",
+				__func__, item, dip, bp, in_f->ilf_ino,
+				xfs_has_nrext64(mp), ldip->di_nrext64_pad);
+			error = -EFSCORRUPTED;
+			goto out_release;
+		}
+	} else {
+		if (ldip->di_version == 3 && ldip->di_big_dextcnt != 0) {
+			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
+				     XFS_ERRLEVEL_LOW, mp, ldip,
+				     sizeof(*ldip));
+			xfs_alert(mp,
+				"%s: Bad inode log record, rec ptr "PTR_FMT", "
+				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
+				"ino %Ld, ldip->di_big_dextcnt = %llu",
+				__func__, item, dip, bp, in_f->ilf_ino,
+				ldip->di_big_dextcnt);
+			error = -EFSCORRUPTED;
+			goto out_release;
+		}
+	}
+
+	if (xfs_log_dinode_has_nrext64(ldip)) {
+		nextents = ldip->di_big_dextcnt;
+		anextents = ldip->di_big_aextcnt;
+	} else {
+		nextents = ldip->di_nextents;
+		anextents = ldip->di_anextents;
+	}
+
+	if (unlikely(nextents + anextents > ldip->di_nblocks)) {
+		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
 				     XFS_ERRLEVEL_LOW, mp, ldip,
 				     sizeof(*ldip));
 		xfs_alert(mp,
 	"%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
-	"dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld",
+	"dino bp "PTR_FMT", ino %Ld, total extents = %llu, nblocks = %Ld",
 			__func__, item, dip, bp, in_f->ilf_ino,
-			ldip->di_nextents + ldip->di_anextents,
-			ldip->di_nblocks);
+			nextents + anextents, ldip->di_nblocks);
 		error = -EFSCORRUPTED;
 		goto out_release;
 	}
 	if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
-		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
+		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(8)",
 				     XFS_ERRLEVEL_LOW, mp, ldip,
 				     sizeof(*ldip));
 		xfs_alert(mp,
@@ -374,7 +431,7 @@ xlog_recover_inode_commit_pass2(
 	}
 	isize = xfs_log_dinode_size(mp);
 	if (unlikely(item->ri_buf[1].i_len > isize)) {
-		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
+		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(9)",
 				     XFS_ERRLEVEL_LOW, mp, ldip,
 				     sizeof(*ldip));
 		xfs_alert(mp,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use 64-bit extent counters
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (11 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:18   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode " Chandan Babu R
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

This commit upgrades inodes to use 64-bit extent counters when they are read
from disk. Inodes are upgraded only when the filesystem instance has
XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag set.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_inode_buf.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index fe21e9808f80..b8e4e1f69989 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -253,6 +253,12 @@ xfs_inode_from_disk(
 	}
 	if (xfs_is_reflink_inode(ip))
 		xfs_ifork_init_cow(ip);
+
+	if ((from->di_version == 3) &&
+		xfs_has_nrext64(ip->i_mount) &&
+		!xfs_dinode_has_nrext64(from))
+		ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
+
 	return 0;
 
 out_destroy_data_fork:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode extent counters
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (12 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use " Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:28   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
  2021-12-14  8:45 ` [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition Chandan Babu R
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

The following changes are made to enable userspace to obtain 64-bit extent
counters,
1. Carve out a new 64-bit field xfs_bulkstat->bs_extents64 from
   xfs_bulkstat->bs_pad[] to hold 64-bit extent counter.
2. Define the new flag XFS_BULK_IREQ_BULKSTAT for userspace to indicate that
   it is capable of receiving 64-bit extent counters.

Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_fs.h | 12 ++++++++----
 fs/xfs/xfs_ioctl.c     |  3 +++
 fs/xfs/xfs_itable.c    | 24 +++++++++++++++++++++++-
 fs/xfs/xfs_itable.h    |  2 ++
 fs/xfs/xfs_iwalk.h     |  7 +++++--
 5 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 42bc39501d81..4e12530eb518 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -393,7 +393,7 @@ struct xfs_bulkstat {
 	uint32_t	bs_extsize_blks; /* extent size hint, blocks	*/
 
 	uint32_t	bs_nlink;	/* number of links		*/
-	uint32_t	bs_extents;	/* number of extents		*/
+	uint32_t	bs_extents;	/* 32-bit data fork extent counter */
 	uint32_t	bs_aextents;	/* attribute number of extents	*/
 	uint16_t	bs_version;	/* structure version		*/
 	uint16_t	bs_forkoff;	/* inode fork offset in bytes	*/
@@ -402,8 +402,9 @@ struct xfs_bulkstat {
 	uint16_t	bs_checked;	/* checked inode metadata	*/
 	uint16_t	bs_mode;	/* type and mode		*/
 	uint16_t	bs_pad2;	/* zeroed			*/
+	uint64_t	bs_extents64;	/* 64-bit data fork extent counter */
 
-	uint64_t	bs_pad[7];	/* zeroed			*/
+	uint64_t	bs_pad[6];	/* zeroed			*/
 };
 
 #define XFS_BULKSTAT_VERSION_V1	(1)
@@ -484,8 +485,11 @@ struct xfs_bulk_ireq {
  */
 #define XFS_BULK_IREQ_SPECIAL	(1 << 1)
 
-#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO | \
-				 XFS_BULK_IREQ_SPECIAL)
+#define XFS_BULK_IREQ_NREXT64	(1 << 2)
+
+#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO |	 \
+				 XFS_BULK_IREQ_SPECIAL | \
+				 XFS_BULK_IREQ_NREXT64)
 
 /* Operate on the root directory inode. */
 #define XFS_BULK_IREQ_SPECIAL_ROOT	(1)
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 174cd8950cb6..d9e9a805b67b 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -893,6 +893,9 @@ xfs_bulk_ireq_setup(
 	if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
 		return -ECANCELED;
 
+	if (hdr->flags & XFS_BULK_IREQ_NREXT64)
+		breq->flags |= XFS_IBULK_NREXT64;
+
 	return 0;
 }
 
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index c08c79d9e311..53ec0afebdc9 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -20,6 +20,7 @@
 #include "xfs_icache.h"
 #include "xfs_health.h"
 #include "xfs_trans.h"
+#include "xfs_errortag.h"
 
 /*
  * Bulk Stat
@@ -64,6 +65,7 @@ xfs_bulkstat_one_int(
 	struct xfs_inode	*ip;		/* incore inode pointer */
 	struct inode		*inode;
 	struct xfs_bulkstat	*buf = bc->buf;
+	xfs_extnum_t		nextents;
 	int			error = -EINVAL;
 
 	if (xfs_internal_inum(mp, ino))
@@ -102,7 +104,27 @@ xfs_bulkstat_one_int(
 
 	buf->bs_xflags = xfs_ip2xflags(ip);
 	buf->bs_extsize_blks = ip->i_extsize;
-	buf->bs_extents = xfs_ifork_nextents(&ip->i_df);
+
+	nextents = xfs_ifork_nextents(&ip->i_df);
+	if (!(bc->breq->flags & XFS_IBULK_NREXT64)) {
+		xfs_extnum_t max_nextents = XFS_MAX_EXTCNT_DATA_FORK_OLD;
+
+		if (unlikely(XFS_TEST_ERROR(false, mp,
+				XFS_ERRTAG_REDUCE_MAX_IEXTENTS)))
+			max_nextents = 10;
+
+		if (nextents > max_nextents) {
+			xfs_iunlock(ip, XFS_ILOCK_SHARED);
+			xfs_irele(ip);
+			error = -EOVERFLOW;
+			goto out;
+		}
+
+		buf->bs_extents = nextents;
+	} else {
+		buf->bs_extents64 = nextents;
+	}
+
 	xfs_bulkstat_health(ip, buf);
 	buf->bs_aextents = xfs_ifork_nextents(ip->i_afp);
 	buf->bs_forkoff = XFS_IFORK_BOFF(ip);
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 7078d10c9b12..a561acd95383 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -19,6 +19,8 @@ struct xfs_ibulk {
 /* Only iterate within the same AG as startino */
 #define XFS_IBULK_SAME_AG	(XFS_IWALK_SAME_AG)
 
+#define XFS_IBULK_NREXT64	(XFS_IWALK_NREXT64)
+
 /*
  * Advance the user buffer pointer by one record of the given size.  If the
  * buffer is now full, return the appropriate error code.
diff --git a/fs/xfs/xfs_iwalk.h b/fs/xfs/xfs_iwalk.h
index 37a795f03267..11be9dbb45c7 100644
--- a/fs/xfs/xfs_iwalk.h
+++ b/fs/xfs/xfs_iwalk.h
@@ -26,9 +26,12 @@ int xfs_iwalk_threaded(struct xfs_mount *mp, xfs_ino_t startino,
 		unsigned int inode_records, bool poll, void *data);
 
 /* Only iterate inodes within the same AG as @startino. */
-#define XFS_IWALK_SAME_AG	(0x1)
+#define XFS_IWALK_SAME_AG	(1 << 0)
 
-#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG)
+#define XFS_IWALK_NREXT64	(1 << 1)
+
+#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG |	\
+				 XFS_IWALK_NREXT64)
 
 /* Walk all inode btree records in the filesystem starting from @startino. */
 typedef int (*xfs_inobt_walk_fn)(struct xfs_mount *mp, struct xfs_trans *tp,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (13 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode " Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:47   ` Darrick J. Wong
  2021-12-14  8:45 ` [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition Chandan Babu R
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

This commit enables XFS module to work with fs instances having 64-bit
per-inode extent counters by adding XFS_SB_FEAT_INCOMPAT_NREXT64 flag to the
list of supported incompat feature flags.

Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_format.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 2868cec1154d..3183f78fe7a3 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -378,7 +378,8 @@ xfs_sb_has_ro_compat_feature(
 		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
 		 XFS_SB_FEAT_INCOMPAT_META_UUID| \
 		 XFS_SB_FEAT_INCOMPAT_BIGTIME| \
-		 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
+		 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \
+		 XFS_SB_FEAT_INCOMPAT_NREXT64)
 
 #define XFS_SB_FEAT_INCOMPAT_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_ALL
 static inline bool
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition
  2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
                   ` (14 preceding siblings ...)
  2021-12-14  8:45 ` [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
@ 2021-12-14  8:45 ` Chandan Babu R
  2022-01-05  0:47   ` Darrick J. Wong
  15 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2021-12-14  8:45 UTC (permalink / raw)
  To: linux-xfs; +Cc: Chandan Babu R, djwong, david

The maximum extent length depends on maximum block count that can be stored in
a BMBT record. Hence this commit defines MAXEXTLEN based on
BMBT_BLOCKCOUNT_BITLEN.

While at it, the commit also renames MAXEXTLEN to XFS_MAX_BMBT_EXTLEN.

Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
 fs/xfs/libxfs/xfs_alloc.c      |  2 +-
 fs/xfs/libxfs/xfs_bmap.c       | 57 +++++++++++++++++-----------------
 fs/xfs/libxfs/xfs_format.h     | 21 +++++++------
 fs/xfs/libxfs/xfs_inode_buf.c  |  4 +--
 fs/xfs/libxfs/xfs_trans_resv.c | 11 ++++---
 fs/xfs/scrub/bmap.c            |  2 +-
 fs/xfs/xfs_bmap_util.c         | 14 +++++----
 fs/xfs/xfs_iomap.c             | 28 ++++++++---------
 8 files changed, 72 insertions(+), 67 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 353e53b892e6..3f9b9cbfef43 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2493,7 +2493,7 @@ __xfs_free_extent_later(
 
 	ASSERT(bno != NULLFSBLOCK);
 	ASSERT(len > 0);
-	ASSERT(len <= MAXEXTLEN);
+	ASSERT(len <= XFS_MAX_BMBT_EXTLEN);
 	ASSERT(!isnullstartblock(bno));
 	agno = XFS_FSB_TO_AGNO(mp, bno);
 	agbno = XFS_FSB_TO_AGBNO(mp, bno);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 0ce58e4a9c44..9c3da7a916df 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1449,7 +1449,7 @@ xfs_bmap_add_extent_delay_real(
 	    LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
 	    LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
 	    LEFT.br_state == new->br_state &&
-	    LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+	    LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
 		state |= BMAP_LEFT_CONTIG;
 
 	/*
@@ -1467,13 +1467,13 @@ xfs_bmap_add_extent_delay_real(
 	    new_endoff == RIGHT.br_startoff &&
 	    new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
 	    new->br_state == RIGHT.br_state &&
-	    new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+	    new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
 	    ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
 		       BMAP_RIGHT_FILLING)) !=
 		      (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
 		       BMAP_RIGHT_FILLING) ||
 	     LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
-			<= MAXEXTLEN))
+			<= XFS_MAX_BMBT_EXTLEN))
 		state |= BMAP_RIGHT_CONTIG;
 
 	error = 0;
@@ -1997,7 +1997,7 @@ xfs_bmap_add_extent_unwritten_real(
 	    LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
 	    LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
 	    LEFT.br_state == new->br_state &&
-	    LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+	    LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
 		state |= BMAP_LEFT_CONTIG;
 
 	/*
@@ -2015,13 +2015,13 @@ xfs_bmap_add_extent_unwritten_real(
 	    new_endoff == RIGHT.br_startoff &&
 	    new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
 	    new->br_state == RIGHT.br_state &&
-	    new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
+	    new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
 	    ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
 		       BMAP_RIGHT_FILLING)) !=
 		      (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
 		       BMAP_RIGHT_FILLING) ||
 	     LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
-			<= MAXEXTLEN))
+			<= XFS_MAX_BMBT_EXTLEN))
 		state |= BMAP_RIGHT_CONTIG;
 
 	/*
@@ -2507,15 +2507,15 @@ xfs_bmap_add_extent_hole_delay(
 	 */
 	if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
 	    left.br_startoff + left.br_blockcount == new->br_startoff &&
-	    left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+	    left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
 		state |= BMAP_LEFT_CONTIG;
 
 	if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
 	    new->br_startoff + new->br_blockcount == right.br_startoff &&
-	    new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+	    new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
 	    (!(state & BMAP_LEFT_CONTIG) ||
 	     (left.br_blockcount + new->br_blockcount +
-	      right.br_blockcount <= MAXEXTLEN)))
+	      right.br_blockcount <= XFS_MAX_BMBT_EXTLEN)))
 		state |= BMAP_RIGHT_CONTIG;
 
 	/*
@@ -2658,17 +2658,17 @@ xfs_bmap_add_extent_hole_real(
 	    left.br_startoff + left.br_blockcount == new->br_startoff &&
 	    left.br_startblock + left.br_blockcount == new->br_startblock &&
 	    left.br_state == new->br_state &&
-	    left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
+	    left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN)
 		state |= BMAP_LEFT_CONTIG;
 
 	if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
 	    new->br_startoff + new->br_blockcount == right.br_startoff &&
 	    new->br_startblock + new->br_blockcount == right.br_startblock &&
 	    new->br_state == right.br_state &&
-	    new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
+	    new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
 	    (!(state & BMAP_LEFT_CONTIG) ||
 	     left.br_blockcount + new->br_blockcount +
-	     right.br_blockcount <= MAXEXTLEN))
+	     right.br_blockcount <= XFS_MAX_BMBT_EXTLEN))
 		state |= BMAP_RIGHT_CONTIG;
 
 	error = 0;
@@ -2903,15 +2903,15 @@ xfs_bmap_extsize_align(
 
 	/*
 	 * For large extent hint sizes, the aligned extent might be larger than
-	 * MAXEXTLEN. In that case, reduce the size by an extsz so that it pulls
-	 * the length back under MAXEXTLEN. The outer allocation loops handle
-	 * short allocation just fine, so it is safe to do this. We only want to
-	 * do it when we are forced to, though, because it means more allocation
-	 * operations are required.
+	 * XFS_BMBT_MAX_EXTLEN. In that case, reduce the size by an extsz so
+	 * that it pulls the length back under XFS_BMBT_MAX_EXTLEN. The outer
+	 * allocation loops handle short allocation just fine, so it is safe to
+	 * do this. We only want to do it when we are forced to, though, because
+	 * it means more allocation operations are required.
 	 */
-	while (align_alen > MAXEXTLEN)
+	while (align_alen > XFS_MAX_BMBT_EXTLEN)
 		align_alen -= extsz;
-	ASSERT(align_alen <= MAXEXTLEN);
+	ASSERT(align_alen <= XFS_MAX_BMBT_EXTLEN);
 
 	/*
 	 * If the previous block overlaps with this proposed allocation
@@ -3001,9 +3001,9 @@ xfs_bmap_extsize_align(
 			return -EINVAL;
 	} else {
 		ASSERT(orig_off >= align_off);
-		/* see MAXEXTLEN handling above */
+		/* see XFS_BMBT_MAX_EXTLEN handling above */
 		ASSERT(orig_end <= align_off + align_alen ||
-		       align_alen + extsz > MAXEXTLEN);
+		       align_alen + extsz > XFS_MAX_BMBT_EXTLEN);
 	}
 
 #ifdef DEBUG
@@ -3968,7 +3968,7 @@ xfs_bmapi_reserve_delalloc(
 	 * Cap the alloc length. Keep track of prealloc so we know whether to
 	 * tag the inode before we return.
 	 */
-	alen = XFS_FILBLKS_MIN(len + prealloc, MAXEXTLEN);
+	alen = XFS_FILBLKS_MIN(len + prealloc, XFS_MAX_BMBT_EXTLEN);
 	if (!eof)
 		alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
 	if (prealloc && alen >= len)
@@ -4101,7 +4101,7 @@ xfs_bmapi_allocate(
 		if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev))
 			bma->prev.br_startoff = NULLFILEOFF;
 	} else {
-		bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
+		bma->length = XFS_FILBLKS_MIN(bma->length, XFS_MAX_BMBT_EXTLEN);
 		if (!bma->eof)
 			bma->length = XFS_FILBLKS_MIN(bma->length,
 					bma->got.br_startoff - bma->offset);
@@ -4421,8 +4421,8 @@ xfs_bmapi_write(
 			 * xfs_extlen_t and therefore 32 bits. Hence we have to
 			 * check for 32-bit overflows and handle them here.
 			 */
-			if (len > (xfs_filblks_t)MAXEXTLEN)
-				bma.length = MAXEXTLEN;
+			if (len > (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN)
+				bma.length = XFS_MAX_BMBT_EXTLEN;
 			else
 				bma.length = len;
 
@@ -4557,7 +4557,8 @@ xfs_bmapi_convert_delalloc(
 	bma.ip = ip;
 	bma.wasdel = true;
 	bma.offset = bma.got.br_startoff;
-	bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN);
+	bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount,
+			XFS_MAX_BMBT_EXTLEN);
 	bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
 
 	/*
@@ -4638,7 +4639,7 @@ xfs_bmapi_remap(
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	ASSERT(len > 0);
-	ASSERT(len <= (xfs_filblks_t)MAXEXTLEN);
+	ASSERT(len <= (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN);
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 	ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC |
 			   XFS_BMAPI_NORMAP)));
@@ -5638,7 +5639,7 @@ xfs_bmse_can_merge(
 	if ((left->br_startoff + left->br_blockcount != startoff) ||
 	    (left->br_startblock + left->br_blockcount != got->br_startblock) ||
 	    (left->br_state != got->br_state) ||
-	    (left->br_blockcount + got->br_blockcount > MAXEXTLEN))
+	    (left->br_blockcount + got->br_blockcount > XFS_MAX_BMBT_EXTLEN))
 		return false;
 
 	return true;
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 3183f78fe7a3..dd5cffe63be3 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -885,15 +885,6 @@ enum xfs_dinode_fmt {
 	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
 	{ XFS_DINODE_FMT_UUID,		"uuid" }
 
-/*
- * Max values for extlen, extnum, aextnum.
- */
-#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
-#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
-#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
-#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
-#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
-
 /*
  * Inode minimum and maximum sizes.
  */
@@ -1623,7 +1614,17 @@ typedef struct xfs_bmdr_block {
 #define BMBT_BLOCKCOUNT_BITLEN	21
 
 #define BMBT_STARTOFF_MASK	((1ULL << BMBT_STARTOFF_BITLEN) - 1)
-#define BMBT_BLOCKCOUNT_MASK	((1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
+
+/*
+ * Max values for extlen and disk inode's extent counters.
+ */
+#define XFS_MAX_BMBT_EXTLEN		((xfs_extlen_t)(1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
+#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
+#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
+#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
+
+#define BMBT_BLOCKCOUNT_MASK	XFS_MAX_BMBT_EXTLEN
 
 /*
  * bmbt records have a file offset (block) field that is 54 bits wide, so this
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index b8e4e1f69989..780bad03d953 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -691,7 +691,7 @@ xfs_inode_validate_extsize(
 	if (extsize_bytes % blocksize_bytes)
 		return __this_address;
 
-	if (extsize > MAXEXTLEN)
+	if (extsize > XFS_MAX_BMBT_EXTLEN)
 		return __this_address;
 
 	if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2)
@@ -748,7 +748,7 @@ xfs_inode_validate_cowextsize(
 	if (cowextsize_bytes % mp->m_sb.sb_blocksize)
 		return __this_address;
 
-	if (cowextsize > MAXEXTLEN)
+	if (cowextsize > XFS_MAX_BMBT_EXTLEN)
 		return __this_address;
 
 	if (cowextsize > mp->m_sb.sb_agblocks / 2)
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index 6f83d9b306ee..19313021fb99 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -199,8 +199,8 @@ xfs_calc_inode_chunk_res(
 /*
  * Per-extent log reservation for the btree changes involved in freeing or
  * allocating a realtime extent.  We have to be able to log as many rtbitmap
- * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents,
- * as well as the realtime summary block.
+ * blocks as needed to mark inuse XFS_BMBT_MAX_EXTLEN blocks' worth of realtime
+ * extents, as well as the realtime summary block.
  */
 static unsigned int
 xfs_rtalloc_log_count(
@@ -210,7 +210,7 @@ xfs_rtalloc_log_count(
 	unsigned int		blksz = XFS_FSB_TO_B(mp, 1);
 	unsigned int		rtbmp_bytes;
 
-	rtbmp_bytes = (MAXEXTLEN / mp->m_sb.sb_rextsize) / NBBY;
+	rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY;
 	return (howmany(rtbmp_bytes, blksz) + 1) * num_ops;
 }
 
@@ -247,7 +247,7 @@ xfs_rtalloc_log_count(
  *    the inode's bmap btree: max depth * block size
  *    the agfs of the ags from which the extents are allocated: 2 * sector
  *    the superblock free block counter: sector size
- *    the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes
+ *    the realtime bitmap: ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY) bytes
  *    the realtime summary: 1 block
  *    the allocation btrees: 2 trees * (2 * max depth - 1) * block size
  * And the bmap_finish transaction can free bmap blocks in a join (t3):
@@ -299,7 +299,8 @@ xfs_calc_write_reservation(
  *    the agf for each of the ags: 2 * sector size
  *    the agfl for each of the ags: 2 * sector size
  *    the super block to reflect the freed blocks: sector size
- *    the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes
+ *    the realtime bitmap: 2 exts * ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY)
+ *    bytes
  *    the realtime summary: 2 exts * 1 block
  *    worst case split in allocation btrees per extent assuming 2 extents:
  *		2 exts * 2 trees * (2 * max depth - 1) * block size
diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
index a4cbbc346f60..c357593e0a02 100644
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -350,7 +350,7 @@ xchk_bmap_iextent(
 				irec->br_startoff);
 
 	/* Make sure the extent points to a valid place. */
-	if (irec->br_blockcount > MAXEXTLEN)
+	if (irec->br_blockcount > XFS_MAX_BMBT_EXTLEN)
 		xchk_fblock_set_corrupt(info->sc, info->whichfork,
 				irec->br_startoff);
 	if (info->is_rt &&
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 73a36b7be3bd..36cde254dedd 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -119,14 +119,14 @@ xfs_bmap_rtalloc(
 	 */
 	ralen = ap->length / mp->m_sb.sb_rextsize;
 	/*
-	 * If the old value was close enough to MAXEXTLEN that
+	 * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that
 	 * we rounded up to it, cut it back so it's valid again.
 	 * Note that if it's a really large request (bigger than
-	 * MAXEXTLEN), we don't hear about that number, and can't
+	 * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't
 	 * adjust the starting point to match it.
 	 */
-	if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
-		ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
+	if (ralen * mp->m_sb.sb_rextsize >= XFS_MAX_BMBT_EXTLEN)
+		ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize;
 
 	/*
 	 * Lock out modifications to both the RT bitmap and summary inodes
@@ -840,9 +840,11 @@ xfs_alloc_file_space(
 		 * count, hence we need to limit the number of blocks we are
 		 * trying to reserve to avoid an overflow. We can't allocate
 		 * more than @nimaps extents, and an extent is limited on disk
-		 * to MAXEXTLEN (21 bits), so use that to enforce the limit.
+		 * to XFS_BMBT_MAX_EXTLEN (21 bits), so use that to enforce the
+		 * limit.
 		 */
-		resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps));
+		resblks = min_t(xfs_fileoff_t, (e - s),
+				(XFS_MAX_BMBT_EXTLEN * nimaps));
 		if (unlikely(rt)) {
 			dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
 			rblocks = resblks;
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 093758440ad5..6835adc8d62f 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -395,7 +395,7 @@ xfs_iomap_prealloc_size(
 	 */
 	plen = prev.br_blockcount;
 	while (xfs_iext_prev_extent(ifp, &ncur, &got)) {
-		if (plen > MAXEXTLEN / 2 ||
+		if (plen > XFS_MAX_BMBT_EXTLEN / 2 ||
 		    isnullstartblock(got.br_startblock) ||
 		    got.br_startoff + got.br_blockcount != prev.br_startoff ||
 		    got.br_startblock + got.br_blockcount != prev.br_startblock)
@@ -407,23 +407,23 @@ xfs_iomap_prealloc_size(
 	/*
 	 * If the size of the extents is greater than half the maximum extent
 	 * length, then use the current offset as the basis.  This ensures that
-	 * for large files the preallocation size always extends to MAXEXTLEN
-	 * rather than falling short due to things like stripe unit/width
-	 * alignment of real extents.
+	 * for large files the preallocation size always extends to
+	 * XFS_BMBT_MAX_EXTLEN rather than falling short due to things like stripe
+	 * unit/width alignment of real extents.
 	 */
 	alloc_blocks = plen * 2;
-	if (alloc_blocks > MAXEXTLEN)
+	if (alloc_blocks > XFS_MAX_BMBT_EXTLEN)
 		alloc_blocks = XFS_B_TO_FSB(mp, offset);
 	qblocks = alloc_blocks;
 
 	/*
-	 * MAXEXTLEN is not a power of two value but we round the prealloc down
-	 * to the nearest power of two value after throttling. To prevent the
-	 * round down from unconditionally reducing the maximum supported
-	 * prealloc size, we round up first, apply appropriate throttling,
-	 * round down and cap the value to MAXEXTLEN.
+	 * XFS_BMBT_MAX_EXTLEN is not a power of two value but we round the prealloc
+	 * down to the nearest power of two value after throttling. To prevent
+	 * the round down from unconditionally reducing the maximum supported
+	 * prealloc size, we round up first, apply appropriate throttling, round
+	 * down and cap the value to XFS_BMBT_MAX_EXTLEN.
 	 */
-	alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(MAXEXTLEN),
+	alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(XFS_MAX_BMBT_EXTLEN),
 				       alloc_blocks);
 
 	freesp = percpu_counter_read_positive(&mp->m_fdblocks);
@@ -471,14 +471,14 @@ xfs_iomap_prealloc_size(
 	 */
 	if (alloc_blocks)
 		alloc_blocks = rounddown_pow_of_two(alloc_blocks);
-	if (alloc_blocks > MAXEXTLEN)
-		alloc_blocks = MAXEXTLEN;
+	if (alloc_blocks > XFS_MAX_BMBT_EXTLEN)
+		alloc_blocks = XFS_MAX_BMBT_EXTLEN;
 
 	/*
 	 * If we are still trying to allocate more space than is
 	 * available, squash the prealloc hard. This can happen if we
 	 * have a large file on a small filesystem and the above
-	 * lowspace thresholds are smaller than MAXEXTLEN.
+	 * lowspace thresholds are smaller than XFS_BMBT_MAX_EXTLEN.
 	 */
 	while (alloc_blocks && alloc_blocks >= freesp)
 		alloc_blocks >>= 4;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-12-14 14:54     ` kernel test robot
  2021-12-14 15:05     ` kernel test robot
  2021-12-14 15:15     ` kernel test robot
  2 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 14:54 UTC (permalink / raw)
  To: Chandan Babu R, linux-xfs; +Cc: llvm, kbuild-all, Chandan Babu R, djwong, david

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: riscv-randconfig-r042-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142236.nxhglKkO-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project b6a2ddb6c8ac29412b1361810972e15221fa021c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: __udivdi3
   >>> referenced by xfs_bmap.c
   >>>               xfs/libxfs/xfs_bmap.o:(xfs_bmap_compute_maxlevels) in archive fs/built-in.a

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2021-12-14 14:54     ` kernel test robot
  0 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 14:54 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2048 bytes --]

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: riscv-randconfig-r042-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142236.nxhglKkO-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project b6a2ddb6c8ac29412b1361810972e15221fa021c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: __udivdi3
   >>> referenced by xfs_bmap.c
   >>>               xfs/libxfs/xfs_bmap.o:(xfs_bmap_compute_maxlevels) in archive fs/built-in.a

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-12-14 15:05     ` kernel test robot
  2021-12-14 15:05     ` kernel test robot
  2021-12-14 15:15     ` kernel test robot
  2 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 15:05 UTC (permalink / raw)
  To: Chandan Babu R, linux-xfs; +Cc: kbuild-all, Chandan Babu R, djwong, david

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: m68k-randconfig-r022-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142242.zS3qrBYM-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   m68k-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> xfs_bmap.c:(.text+0x5680): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2021-12-14 15:05     ` kernel test robot
  0 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 15:05 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: m68k-randconfig-r022-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142242.zS3qrBYM-lkp(a)intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   m68k-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> xfs_bmap.c:(.text+0x5680): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-12-14 15:15     ` kernel test robot
  2021-12-14 15:05     ` kernel test robot
  2021-12-14 15:15     ` kernel test robot
  2 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 15:15 UTC (permalink / raw)
  To: Chandan Babu R, linux-xfs; +Cc: kbuild-all, Chandan Babu R, djwong, david

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> (.text+0x10cc0): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2021-12-14 15:15     ` kernel test robot
  0 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 15:15 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1847 bytes --]

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
compiler: microblaze-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout db28da144803c4262c0d8622d736a7d20952ef6b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> (.text+0x10cc0): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT
  2021-12-14  8:45 ` [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
@ 2021-12-14 18:15     ` kernel test robot
  0 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 18:15 UTC (permalink / raw)
  To: Chandan Babu R, linux-xfs; +Cc: kbuild-all, Chandan Babu R, djwong, david

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5 next-20211213]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211215/202112150258.palxcNEy-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f682028d9c9681363db692733e244a8e2e5b767f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout f682028d9c9681363db692733e244a8e2e5b767f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
   (.text+0x10cbc): undefined reference to `__udivdi3'
>> microblaze-linux-ld: (.text+0x10dc0): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT
@ 2021-12-14 18:15     ` kernel test robot
  0 siblings, 0 replies; 58+ messages in thread
From: kernel test robot @ 2021-12-14 18:15 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1938 bytes --]

Hi Chandan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xfs-linux/for-next]
[also build test ERROR on v5.16-rc5 next-20211213]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211215/202112150258.palxcNEy-lkp(a)intel.com/config)
compiler: microblaze-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f682028d9c9681363db692733e244a8e2e5b767f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
        git checkout f682028d9c9681363db692733e244a8e2e5b767f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
   (.text+0x10cbc): undefined reference to `__udivdi3'
>> microblaze-linux-ld: (.text+0x10dc0): undefined reference to `__udivdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-14 15:15     ` kernel test robot
@ 2021-12-15  9:19       ` Chandan Babu R
  -1 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2021-12-15  9:19 UTC (permalink / raw)
  To: kernel test robot; +Cc: linux-xfs, kbuild-all, djwong, david

On 14 Dec 2021 at 20:45, kernel test robot wrote:
> Hi Chandan,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on xfs-linux/for-next]
> [also build test ERROR on v5.16-rc5]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
> compiler: microblaze-linux-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>>> (.text+0x10cc0): undefined reference to `__udivdi3'
>

The fix for the compilation error on 32-bit systems involved invoking do_div()
instead of using the regular division operator. I will include the fix in the
next version of the patchset.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2021-12-15  9:19       ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2021-12-15  9:19 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2046 bytes --]

On 14 Dec 2021 at 20:45, kernel test robot wrote:
> Hi Chandan,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on xfs-linux/for-next]
> [also build test ERROR on v5.16-rc5]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
> compiler: microblaze-linux-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>>> (.text+0x10cc0): undefined reference to `__udivdi3'
>

The fix for the compilation error on 32-bit systems involved invoking do_div()
instead of using the regular division operator. I will include the fix in the
next version of the patchset.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h
  2021-12-14  8:45 ` [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h Chandan Babu R
@ 2022-01-04 23:28   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:28 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:04PM +0530, Chandan Babu R wrote:
> Maximum values associated with extent counters i.e. Maximum extent length,
> Maximum data extents and Maximum xattr extents are dictated by the on-disk
> format. Hence move these definitions over to xfs_format.h.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_format.h | 7 +++++++
>  fs/xfs/libxfs/xfs_types.h  | 7 -------
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index d665c04e69dd..d75e5b16da7e 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -869,6 +869,13 @@ enum xfs_dinode_fmt {
>  	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
>  	{ XFS_DINODE_FMT_UUID,		"uuid" }
>  
> +/*
> + * Max values for extlen, extnum, aextnum.
> + */
> +#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
> +#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
> +#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
> +
>  /*
>   * Inode minimum and maximum sizes.
>   */
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index b6da06b40989..794a54cbd0de 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -56,13 +56,6 @@ typedef void *		xfs_failaddr_t;
>  #define	NULLFSINO	((xfs_ino_t)-1)
>  #define	NULLAGINO	((xfs_agino_t)-1)
>  
> -/*
> - * Max values for extlen, extnum, aextnum.
> - */
> -#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
> -#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
> -#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
> -
>  /*
>   * Minimum and maximum blocksize and sectorsize.
>   * The blocksize upper limit is pretty much arbitrary.
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper
  2021-12-14  8:45 ` [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
@ 2022-01-04 23:30   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:30 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:05PM +0530, Chandan Babu R wrote:
> xfs_iext_max_nextents() returns the maximum number of extents possible for one
> of data, cow or attribute fork. This helper will be extended further in a
> future commit when maximum extent counts associated with data/attribute forks
> are increased.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>

Pretty straightforward...
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_bmap.c       | 9 ++++-----
>  fs/xfs/libxfs/xfs_inode_buf.c  | 8 +++-----
>  fs/xfs/libxfs/xfs_inode_fork.c | 2 +-
>  fs/xfs/libxfs/xfs_inode_fork.h | 8 ++++++++
>  4 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 4dccd4d90622..75e8e8a97568 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -74,13 +74,12 @@ xfs_bmap_compute_maxlevels(
>  	 * ATTR2 we have to assume the worst case scenario of a minimum size
>  	 * available.
>  	 */
> -	if (whichfork == XFS_DATA_FORK) {
> -		maxleafents = MAXEXTNUM;
> +	maxleafents = xfs_iext_max_nextents(whichfork);
> +	if (whichfork == XFS_DATA_FORK)
>  		sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
> -	} else {
> -		maxleafents = MAXAEXTNUM;
> +	else
>  		sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
> -	}
> +
>  	maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
>  	minleafrecs = mp->m_bmap_dmnr[0];
>  	minnoderecs = mp->m_bmap_dmnr[1];
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index cae9708c8587..e6f9bdc4558f 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -337,6 +337,7 @@ xfs_dinode_verify_fork(
>  	int			whichfork)
>  {
>  	uint32_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
> +	xfs_extnum_t		max_extents;
>  
>  	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
>  	case XFS_DINODE_FMT_LOCAL:
> @@ -358,12 +359,9 @@ xfs_dinode_verify_fork(
>  			return __this_address;
>  		break;
>  	case XFS_DINODE_FMT_BTREE:
> -		if (whichfork == XFS_ATTR_FORK) {
> -			if (di_nextents > MAXAEXTNUM)
> -				return __this_address;
> -		} else if (di_nextents > MAXEXTNUM) {
> +		max_extents = xfs_iext_max_nextents(whichfork);
> +		if (di_nextents > max_extents)
>  			return __this_address;
> -		}
>  		break;
>  	default:
>  		return __this_address;
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
> index 9149f4f796fc..e136c29a0ec1 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.c
> +++ b/fs/xfs/libxfs/xfs_inode_fork.c
> @@ -744,7 +744,7 @@ xfs_iext_count_may_overflow(
>  	if (whichfork == XFS_COW_FORK)
>  		return 0;
>  
> -	max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM;
> +	max_exts = xfs_iext_max_nextents(whichfork);
>  
>  	if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
>  		max_exts = 10;
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
> index 3d64a3acb0ed..2605f7ff8fc1 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.h
> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
> @@ -133,6 +133,14 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
>  	return ifp->if_format;
>  }
>  
> +static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
> +{
> +	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
> +		return MAXEXTNUM;
> +
> +	return MAXAEXTNUM;
> +}
> +
>  struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
>  				xfs_extnum_t nextents);
>  struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper
  2021-12-14  8:45 ` [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper Chandan Babu R
@ 2022-01-04 23:48   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:48 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:07PM +0530, Chandan Babu R wrote:
> This commit replaces the macro XFS_DFORK_NEXTENTS() with the helper function
> xfs_dfork_nextents(). As of this commit, xfs_dfork_nextents() returns the same
> value as XFS_DFORK_NEXTENTS(). A future commit which extends inode's extent
> counter fields will add more logic to this helper.
> 
> This commit also replaces direct accesses to xfs_dinode->di_[a]nextents
> with calls to xfs_dfork_nextents().
> 
> No functional changes have been made.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_format.h     |  4 ----
>  fs/xfs/libxfs/xfs_inode_buf.c  | 16 +++++++++++-----
>  fs/xfs/libxfs/xfs_inode_fork.c | 10 ++++++----
>  fs/xfs/libxfs/xfs_inode_fork.h | 32 ++++++++++++++++++++++++++++++++
>  fs/xfs/scrub/inode.c           | 18 ++++++++++--------
>  5 files changed, 59 insertions(+), 21 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index d75e5b16da7e..e5654b578ec0 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -925,10 +925,6 @@ enum xfs_dinode_fmt {
>  	((w) == XFS_DATA_FORK ? \
>  		(dip)->di_format : \
>  		(dip)->di_aformat)
> -#define XFS_DFORK_NEXTENTS(dip,w) \
> -	((w) == XFS_DATA_FORK ? \
> -		be32_to_cpu((dip)->di_nextents) : \
> -		be16_to_cpu((dip)->di_anextents))

Yay, I love watching macros die.  Especially when the replacement
validates its arguments completely!

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

>  
>  /*
>   * For block and character special files the 32bit dev_t is stored at the
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 5c95a5428fc7..860d32816909 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -336,9 +336,11 @@ xfs_dinode_verify_fork(
>  	struct xfs_mount	*mp,
>  	int			whichfork)
>  {
> -	xfs_extnum_t		di_nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
> +	xfs_extnum_t		di_nextents;
>  	xfs_extnum_t		max_extents;
>  
> +	di_nextents = xfs_dfork_nextents(dip, whichfork);
> +
>  	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
>  	case XFS_DINODE_FMT_LOCAL:
>  		/*
> @@ -405,6 +407,8 @@ xfs_dinode_verify(
>  	uint16_t		flags;
>  	uint64_t		flags2;
>  	uint64_t		di_size;
> +	xfs_extnum_t            nextents;
> +	xfs_filblks_t		nblocks;
>  
>  	if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
>  		return __this_address;
> @@ -435,10 +439,12 @@ xfs_dinode_verify(
>  	if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
>  		return __this_address;
>  
> +	nextents = xfs_dfork_data_extents(dip);
> +	nextents += xfs_dfork_attr_extents(dip);
> +	nblocks = be64_to_cpu(dip->di_nblocks);
> +
>  	/* Fork checks carried over from xfs_iformat_fork */
> -	if (mode &&
> -	    be32_to_cpu(dip->di_nextents) + be16_to_cpu(dip->di_anextents) >
> -			be64_to_cpu(dip->di_nblocks))
> +	if (mode && nextents > nblocks)
>  		return __this_address;
>  
>  	if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
> @@ -495,7 +501,7 @@ xfs_dinode_verify(
>  		default:
>  			return __this_address;
>  		}
> -		if (dip->di_anextents)
> +		if (xfs_dfork_attr_extents(dip))
>  			return __this_address;
>  	}
>  
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
> index a17c4d87520a..829739e249b6 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.c
> +++ b/fs/xfs/libxfs/xfs_inode_fork.c
> @@ -105,7 +105,7 @@ xfs_iformat_extents(
>  	struct xfs_mount	*mp = ip->i_mount;
>  	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
>  	int			state = xfs_bmap_fork_to_state(whichfork);
> -	xfs_extnum_t		nex = XFS_DFORK_NEXTENTS(dip, whichfork);
> +	xfs_extnum_t		nex = xfs_dfork_nextents(dip, whichfork);
>  	int			size = nex * sizeof(xfs_bmbt_rec_t);
>  	struct xfs_iext_cursor	icur;
>  	struct xfs_bmbt_rec	*dp;
> @@ -230,7 +230,7 @@ xfs_iformat_data_fork(
>  	 * depend on it.
>  	 */
>  	ip->i_df.if_format = dip->di_format;
> -	ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents);
> +	ip->i_df.if_nextents = xfs_dfork_data_extents(dip);
>  
>  	switch (inode->i_mode & S_IFMT) {
>  	case S_IFIFO:
> @@ -295,14 +295,16 @@ xfs_iformat_attr_fork(
>  	struct xfs_inode	*ip,
>  	struct xfs_dinode	*dip)
>  {
> +	xfs_extnum_t		naextents;
>  	int			error = 0;
>  
> +	naextents = xfs_dfork_attr_extents(dip);
> +
>  	/*
>  	 * Initialize the extent count early, as the per-format routines may
>  	 * depend on it.
>  	 */
> -	ip->i_afp = xfs_ifork_alloc(dip->di_aformat,
> -				be16_to_cpu(dip->di_anextents));
> +	ip->i_afp = xfs_ifork_alloc(dip->di_aformat, naextents);
>  
>  	switch (ip->i_afp->if_format) {
>  	case XFS_DINODE_FMT_LOCAL:
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
> index 2605f7ff8fc1..7ed2ecb51bca 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.h
> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
> @@ -141,6 +141,38 @@ static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
>  	return MAXAEXTNUM;
>  }
>  
> +static inline xfs_extnum_t
> +xfs_dfork_data_extents(
> +	struct xfs_dinode	*dip)
> +{
> +	return be32_to_cpu(dip->di_nextents);
> +}
> +
> +static inline xfs_extnum_t
> +xfs_dfork_attr_extents(
> +	struct xfs_dinode	*dip)
> +{
> +	return be16_to_cpu(dip->di_anextents);
> +}
> +
> +static inline xfs_extnum_t
> +xfs_dfork_nextents(
> +	struct xfs_dinode	*dip,
> +	int			whichfork)
> +{
> +	switch (whichfork) {
> +	case XFS_DATA_FORK:
> +		return xfs_dfork_data_extents(dip);
> +	case XFS_ATTR_FORK:
> +		return xfs_dfork_attr_extents(dip);
> +	default:
> +		ASSERT(0);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
>  				xfs_extnum_t nextents);
>  struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
> diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
> index aefdf8fe1372..a601b04fe408 100644
> --- a/fs/xfs/scrub/inode.c
> +++ b/fs/xfs/scrub/inode.c
> @@ -233,6 +233,7 @@ xchk_dinode(
>  	unsigned long long	isize;
>  	uint64_t		flags2;
>  	xfs_extnum_t		nextents;
> +	xfs_extnum_t		naextents;
>  	uint16_t		flags;
>  	uint16_t		mode;
>  
> @@ -377,7 +378,7 @@ xchk_dinode(
>  	xchk_inode_extsize(sc, dip, ino, mode, flags);
>  
>  	/* di_nextents */
> -	nextents = be32_to_cpu(dip->di_nextents);
> +	nextents = xfs_dfork_data_extents(dip);
>  	fork_recs =  XFS_DFORK_DSIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
>  	switch (dip->di_format) {
>  	case XFS_DINODE_FMT_EXTENTS:
> @@ -394,10 +395,12 @@ xchk_dinode(
>  		break;
>  	}
>  
> +	naextents = xfs_dfork_attr_extents(dip);
> +
>  	/* di_forkoff */
>  	if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize)
>  		xchk_ino_set_corrupt(sc, ino);
> -	if (dip->di_anextents != 0 && dip->di_forkoff == 0)
> +	if (naextents != 0 && dip->di_forkoff == 0)
>  		xchk_ino_set_corrupt(sc, ino);
>  	if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS)
>  		xchk_ino_set_corrupt(sc, ino);
> @@ -409,19 +412,18 @@ xchk_dinode(
>  		xchk_ino_set_corrupt(sc, ino);
>  
>  	/* di_anextents */
> -	nextents = be16_to_cpu(dip->di_anextents);
>  	fork_recs =  XFS_DFORK_ASIZE(dip, mp) / sizeof(struct xfs_bmbt_rec);
>  	switch (dip->di_aformat) {
>  	case XFS_DINODE_FMT_EXTENTS:
> -		if (nextents > fork_recs)
> +		if (naextents > fork_recs)
>  			xchk_ino_set_corrupt(sc, ino);
>  		break;
>  	case XFS_DINODE_FMT_BTREE:
> -		if (nextents <= fork_recs)
> +		if (naextents <= fork_recs)
>  			xchk_ino_set_corrupt(sc, ino);
>  		break;
>  	default:
> -		if (nextents != 0)
> +		if (naextents != 0)
>  			xchk_ino_set_corrupt(sc, ino);
>  	}
>  
> @@ -499,14 +501,14 @@ xchk_inode_xref_bmap(
>  			&nextents, &count);
>  	if (!xchk_should_check_xref(sc, &error, NULL))
>  		return;
> -	if (nextents < be32_to_cpu(dip->di_nextents))
> +	if (nextents < xfs_dfork_data_extents(dip))
>  		xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
>  
>  	error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK,
>  			&nextents, &acount);
>  	if (!xchk_should_check_xref(sc, &error, NULL))
>  		return;
> -	if (nextents != be16_to_cpu(dip->di_anextents))
> +	if (nextents != xfs_dfork_attr_extents(dip))
>  		xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
>  
>  	/* Check nblocks against the inode. */
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents
  2021-12-14  8:45 ` [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
@ 2022-01-04 23:50   ` Darrick J. Wong
  2022-01-05 13:43     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:50 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:08PM +0530, Chandan Babu R wrote:
> A future commit will increase the width of xfs_extnum_t in order to facilitate
> larger per-inode extent counters. Hence this patch now uses basic types to
> define xfs_log_dinode->[di_nextents|dianextents].
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>

I wonder how this didn't trip the xfs_ondisk.h checks in the last
revision of the patches, but ... who cares, let's see what I think of
how /this/ version handles the field enlargements.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_log_format.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
> index b322db523d65..fd66e70248f7 100644
> --- a/fs/xfs/libxfs/xfs_log_format.h
> +++ b/fs/xfs/libxfs/xfs_log_format.h
> @@ -396,8 +396,8 @@ struct xfs_log_dinode {
>  	xfs_fsize_t	di_size;	/* number of bytes in file */
>  	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
>  	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
> -	xfs_extnum_t	di_nextents;	/* number of extents in data fork */
> -	xfs_aextnum_t	di_anextents;	/* number of extents in attribute fork*/
> +	uint32_t	di_nextents;	/* number of extents in data fork */
> +	uint16_t	di_anextents;	/* number of extents in attribute fork*/
>  	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>  	int8_t		di_aformat;	/* format of attr fork's data */
>  	uint32_t	di_dmevmask;	/* DMIG event mask */
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2021-12-15  9:19       ` Chandan Babu R
@ 2022-01-04 23:54         ` Darrick J. Wong
  -1 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:54 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: kernel test robot, linux-xfs, kbuild-all, david

On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> > Hi Chandan,
> >
> > Thank you for the patch! Yet something to improve:
> >
> > [auto build test ERROR on xfs-linux/for-next]
> > [also build test ERROR on v5.16-rc5]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch]
> >
> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> > reproduce (this is a W=1 build):
> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >         chmod +x ~/bin/make.cross
> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >         git remote add linux-review https://github.com/0day-ci/linux
> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >         # save the config file to linux build tree
> >         mkdir build_dir
> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <lkp@intel.com>
> >
> > All errors (new ones prefixed by >>):
> >
> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >
> 
> The fix for the compilation error on 32-bit systems involved invoking do_div()
> instead of using the regular division operator. I will include the fix in the
> next version of the patchset.

So, uh, how did you resolve this in the end?

	maxblocks = roundup_64(maxleafents, minleafrecs);

and

	maxblocks = roundup_64(maxblocks, minnodrecs);

?

--D

> 
> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2022-01-04 23:54         ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-04 23:54 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2367 bytes --]

On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> > Hi Chandan,
> >
> > Thank you for the patch! Yet something to improve:
> >
> > [auto build test ERROR on xfs-linux/for-next]
> > [also build test ERROR on v5.16-rc5]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch]
> >
> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> > reproduce (this is a W=1 build):
> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >         chmod +x ~/bin/make.cross
> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >         git remote add linux-review https://github.com/0day-ci/linux
> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >         # save the config file to linux build tree
> >         mkdir build_dir
> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <lkp@intel.com>
> >
> > All errors (new ones prefixed by >>):
> >
> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >
> 
> The fix for the compilation error on 32-bit systems involved invoking do_div()
> instead of using the regular division operator. I will include the fix in the
> next version of the patchset.

So, uh, how did you resolve this in the end?

	maxblocks = roundup_64(maxleafents, minleafrecs);

and

	maxblocks = roundup_64(maxblocks, minnodrecs);

?

--D

> 
> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit
  2021-12-14  8:45 ` [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
@ 2022-01-05  0:03   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:03 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:10PM +0530, Chandan Babu R wrote:
> XFS_SB_FEAT_INCOMPAT_NREXT64 incompat feature bit will be set on filesystems
> which support large per-inode extent counters. This commit defines the new
> incompat feature bit and the corresponding per-fs feature bit (along with
> inline functions to work on it).
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_format.h | 1 +
>  fs/xfs/libxfs/xfs_sb.c     | 3 +++
>  fs/xfs/xfs_mount.h         | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index e5654b578ec0..7972cbc22608 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -372,6 +372,7 @@ xfs_sb_has_ro_compat_feature(
>  #define XFS_SB_FEAT_INCOMPAT_META_UUID	(1 << 2)	/* metadata UUID */
>  #define XFS_SB_FEAT_INCOMPAT_BIGTIME	(1 << 3)	/* large timestamps */
>  #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4)	/* needs xfs_repair */
> +#define XFS_SB_FEAT_INCOMPAT_NREXT64	(1 << 5)	/* 64-bit data fork extent counter */

EXT6, I like it. :P

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

>  #define XFS_SB_FEAT_INCOMPAT_ALL \
>  		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\
>  		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index f4e84aa1d50a..bd632389ae92 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
> @@ -124,6 +124,9 @@ xfs_sb_version_to_features(
>  		features |= XFS_FEAT_BIGTIME;
>  	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
>  		features |= XFS_FEAT_NEEDSREPAIR;
> +	if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NREXT64)
> +		features |= XFS_FEAT_NREXT64;
> +
>  	return features;
>  }
>  
> diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
> index 00720a02e761..10941481f7e6 100644
> --- a/fs/xfs/xfs_mount.h
> +++ b/fs/xfs/xfs_mount.h
> @@ -276,6 +276,7 @@ typedef struct xfs_mount {
>  #define XFS_FEAT_INOBTCNT	(1ULL << 23)	/* inobt block counts */
>  #define XFS_FEAT_BIGTIME	(1ULL << 24)	/* large timestamps */
>  #define XFS_FEAT_NEEDSREPAIR	(1ULL << 25)	/* needs xfs_repair */
> +#define XFS_FEAT_NREXT64	(1ULL << 26)	/* 64-bit inode extent counters */
>  
>  /* Mount features */
>  #define XFS_FEAT_NOATTR2	(1ULL << 48)	/* disable attr2 creation */
> @@ -338,6 +339,7 @@ __XFS_HAS_FEAT(realtime, REALTIME)
>  __XFS_HAS_FEAT(inobtcounts, INOBTCNT)
>  __XFS_HAS_FEAT(bigtime, BIGTIME)
>  __XFS_HAS_FEAT(needsrepair, NEEDSREPAIR)
> +__XFS_HAS_FEAT(nrext64, NREXT64)
>  
>  /*
>   * Mount features
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
  2021-12-14  8:45 ` [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
@ 2022-01-05  0:05   ` Darrick J. Wong
  2022-01-05 13:44     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:05 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:11PM +0530, Chandan Babu R wrote:
> XFS_FSOP_GEOM_FLAGS_NREXT64 indicates that the current filesystem instance
> supports 64-bit per-inode extent counters.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_fs.h | 1 +
>  fs/xfs/libxfs/xfs_sb.c | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index c43877c8a279..42bc39501d81 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
>  #define XFS_FSOP_GEOM_FLAGS_REFLINK	(1 << 20) /* files can share blocks */
>  #define XFS_FSOP_GEOM_FLAGS_BIGTIME	(1 << 21) /* 64-bit nsec timestamps */
>  #define XFS_FSOP_GEOM_FLAGS_INOBTCNT	(1 << 22) /* inobt btree counter */
> +#define XFS_FSOP_GEOM_FLAGS_NREXT64	(1 << 23) /* 64-bit extent counter */
>  
>  /*
>   * Minimum and maximum sizes need for growth checks.
> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> index bd632389ae92..0c1add39177f 100644
> --- a/fs/xfs/libxfs/xfs_sb.c
> +++ b/fs/xfs/libxfs/xfs_sb.c
> @@ -1138,6 +1138,8 @@ xfs_fs_geometry(
>  	} else {
>  		geo->logsectsize = BBSIZE;
>  	}
> +	if (xfs_has_nrext64(mp))
> +		geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64;
>  	geo->rtsectsize = sbp->sb_blocksize;
>  	geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
>  
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use 64-bit extent counters
  2021-12-14  8:45 ` [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use " Chandan Babu R
@ 2022-01-05  0:18   ` Darrick J. Wong
  2022-01-05 13:49     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:18 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:16PM +0530, Chandan Babu R wrote:
> This commit upgrades inodes to use 64-bit extent counters when they are read
> from disk. Inodes are upgraded only when the filesystem instance has
> XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag set.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_inode_buf.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index fe21e9808f80..b8e4e1f69989 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -253,6 +253,12 @@ xfs_inode_from_disk(
>  	}
>  	if (xfs_is_reflink_inode(ip))
>  		xfs_ifork_init_cow(ip);
> +
> +	if ((from->di_version == 3) &&
> +		xfs_has_nrext64(ip->i_mount) &&
> +		!xfs_dinode_has_nrext64(from))
> +		ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;

The indentation levels of the if test should not be aligned with the if
body, and this should be in xfs_trans_log_inode so that the metadata
update is staged properly with a transaction.  V3 did it this way, so
I'm a little surprised to see V4 regressing that...?

--D

> +
>  	return 0;
>  
>  out_destroy_data_fork:
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode extent counters
  2021-12-14  8:45 ` [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode " Chandan Babu R
@ 2022-01-05  0:28   ` Darrick J. Wong
  2022-01-05 13:50     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:28 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:17PM +0530, Chandan Babu R wrote:
> The following changes are made to enable userspace to obtain 64-bit extent
> counters,
> 1. Carve out a new 64-bit field xfs_bulkstat->bs_extents64 from
>    xfs_bulkstat->bs_pad[] to hold 64-bit extent counter.
> 2. Define the new flag XFS_BULK_IREQ_BULKSTAT for userspace to indicate that
>    it is capable of receiving 64-bit extent counters.
> 
> Suggested-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_fs.h | 12 ++++++++----
>  fs/xfs/xfs_ioctl.c     |  3 +++
>  fs/xfs/xfs_itable.c    | 24 +++++++++++++++++++++++-
>  fs/xfs/xfs_itable.h    |  2 ++
>  fs/xfs/xfs_iwalk.h     |  7 +++++--
>  5 files changed, 41 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index 42bc39501d81..4e12530eb518 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -393,7 +393,7 @@ struct xfs_bulkstat {
>  	uint32_t	bs_extsize_blks; /* extent size hint, blocks	*/
>  
>  	uint32_t	bs_nlink;	/* number of links		*/
> -	uint32_t	bs_extents;	/* number of extents		*/
> +	uint32_t	bs_extents;	/* 32-bit data fork extent counter */
>  	uint32_t	bs_aextents;	/* attribute number of extents	*/
>  	uint16_t	bs_version;	/* structure version		*/
>  	uint16_t	bs_forkoff;	/* inode fork offset in bytes	*/
> @@ -402,8 +402,9 @@ struct xfs_bulkstat {
>  	uint16_t	bs_checked;	/* checked inode metadata	*/
>  	uint16_t	bs_mode;	/* type and mode		*/
>  	uint16_t	bs_pad2;	/* zeroed			*/
> +	uint64_t	bs_extents64;	/* 64-bit data fork extent counter */
>  
> -	uint64_t	bs_pad[7];	/* zeroed			*/
> +	uint64_t	bs_pad[6];	/* zeroed			*/
>  };
>  
>  #define XFS_BULKSTAT_VERSION_V1	(1)
> @@ -484,8 +485,11 @@ struct xfs_bulk_ireq {
>   */
>  #define XFS_BULK_IREQ_SPECIAL	(1 << 1)
>  
> -#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO | \
> -				 XFS_BULK_IREQ_SPECIAL)
> +#define XFS_BULK_IREQ_NREXT64	(1 << 2)
> +
> +#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO |	 \
> +				 XFS_BULK_IREQ_SPECIAL | \
> +				 XFS_BULK_IREQ_NREXT64)
>  
>  /* Operate on the root directory inode. */
>  #define XFS_BULK_IREQ_SPECIAL_ROOT	(1)
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 174cd8950cb6..d9e9a805b67b 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -893,6 +893,9 @@ xfs_bulk_ireq_setup(
>  	if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
>  		return -ECANCELED;
>  
> +	if (hdr->flags & XFS_BULK_IREQ_NREXT64)
> +		breq->flags |= XFS_IBULK_NREXT64;
> +
>  	return 0;
>  }
>  
> diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
> index c08c79d9e311..53ec0afebdc9 100644
> --- a/fs/xfs/xfs_itable.c
> +++ b/fs/xfs/xfs_itable.c
> @@ -20,6 +20,7 @@
>  #include "xfs_icache.h"
>  #include "xfs_health.h"
>  #include "xfs_trans.h"
> +#include "xfs_errortag.h"
>  
>  /*
>   * Bulk Stat
> @@ -64,6 +65,7 @@ xfs_bulkstat_one_int(
>  	struct xfs_inode	*ip;		/* incore inode pointer */
>  	struct inode		*inode;
>  	struct xfs_bulkstat	*buf = bc->buf;
> +	xfs_extnum_t		nextents;
>  	int			error = -EINVAL;
>  
>  	if (xfs_internal_inum(mp, ino))
> @@ -102,7 +104,27 @@ xfs_bulkstat_one_int(
>  
>  	buf->bs_xflags = xfs_ip2xflags(ip);
>  	buf->bs_extsize_blks = ip->i_extsize;
> -	buf->bs_extents = xfs_ifork_nextents(&ip->i_df);
> +
> +	nextents = xfs_ifork_nextents(&ip->i_df);
> +	if (!(bc->breq->flags & XFS_IBULK_NREXT64)) {
> +		xfs_extnum_t max_nextents = XFS_MAX_EXTCNT_DATA_FORK_OLD;
> +
> +		if (unlikely(XFS_TEST_ERROR(false, mp,
> +				XFS_ERRTAG_REDUCE_MAX_IEXTENTS)))
> +			max_nextents = 10;
> +
> +		if (nextents > max_nextents) {
> +			xfs_iunlock(ip, XFS_ILOCK_SHARED);
> +			xfs_irele(ip);
> +			error = -EOVERFLOW;
> +			goto out;
> +		}
> +
> +		buf->bs_extents = nextents;
> +	} else {
> +		buf->bs_extents64 = nextents;
> +	}
> +
>  	xfs_bulkstat_health(ip, buf);
>  	buf->bs_aextents = xfs_ifork_nextents(ip->i_afp);
>  	buf->bs_forkoff = XFS_IFORK_BOFF(ip);
> diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
> index 7078d10c9b12..a561acd95383 100644
> --- a/fs/xfs/xfs_itable.h
> +++ b/fs/xfs/xfs_itable.h
> @@ -19,6 +19,8 @@ struct xfs_ibulk {
>  /* Only iterate within the same AG as startino */
>  #define XFS_IBULK_SAME_AG	(XFS_IWALK_SAME_AG)
>  
> +#define XFS_IBULK_NREXT64	(XFS_IWALK_NREXT64)
> +
>  /*
>   * Advance the user buffer pointer by one record of the given size.  If the
>   * buffer is now full, return the appropriate error code.
> diff --git a/fs/xfs/xfs_iwalk.h b/fs/xfs/xfs_iwalk.h
> index 37a795f03267..11be9dbb45c7 100644
> --- a/fs/xfs/xfs_iwalk.h
> +++ b/fs/xfs/xfs_iwalk.h
> @@ -26,9 +26,12 @@ int xfs_iwalk_threaded(struct xfs_mount *mp, xfs_ino_t startino,
>  		unsigned int inode_records, bool poll, void *data);
>  
>  /* Only iterate inodes within the same AG as @startino. */
> -#define XFS_IWALK_SAME_AG	(0x1)
> +#define XFS_IWALK_SAME_AG	(1 << 0)
>  
> -#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG)
> +#define XFS_IWALK_NREXT64	(1 << 1)

The ability of the caller to handle 64-bit extent counters is not
relevant to the internal inode walking code, so I don't think this
belongs in the iwalk flags namespace.

IOWs, XFS_IBULK_NREXT64 should be defined like this:

#define XFS_IBULK_NREXT64	(1U << 31)

and xfs_bulkstat should be changed to translate only the relevant
breq->flags into the appropriate IWALK bits.  Sorry for the code
smell...

--D

> +
> +#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG |	\
> +				 XFS_IWALK_NREXT64)
>  
>  /* Walk all inode btree records in the filesystem starting from @startino. */
>  typedef int (*xfs_inobt_walk_fn)(struct xfs_mount *mp, struct xfs_trans *tp,
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks
  2021-12-14  8:45 ` [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
@ 2022-01-05  0:42   ` Darrick J. Wong
  2022-01-05 13:46     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:42 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:14PM +0530, Chandan Babu R wrote:
> This commit defines new macros to represent maximum extent counts allowed by
> filesystems which have support for large per-inode extent counters.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_bmap.c       |  8 +++-----
>  fs/xfs/libxfs/xfs_bmap_btree.c |  2 +-
>  fs/xfs/libxfs/xfs_format.h     |  8 +++++---
>  fs/xfs/libxfs/xfs_inode_buf.c  |  3 ++-
>  fs/xfs/libxfs/xfs_inode_fork.c |  2 +-
>  fs/xfs/libxfs/xfs_inode_fork.h | 19 +++++++++++++++----
>  6 files changed, 27 insertions(+), 15 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 4113622e9733..0ce58e4a9c44 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -61,10 +61,8 @@ xfs_bmap_compute_maxlevels(
>  	int		sz;		/* root block size */
>  
>  	/*
> -	 * The maximum number of extents in a file, hence the maximum number of
> -	 * leaf entries, is controlled by the size of the on-disk extent count,
> -	 * either a signed 32-bit number for the data fork, or a signed 16-bit
> -	 * number for the attr fork.
> +	 * The maximum number of extents in a fork, hence the maximum number of
> +	 * leaf entries, is controlled by the size of the on-disk extent count.
>  	 *
>  	 * Note that we can no longer assume that if we are in ATTR1 that the
>  	 * fork offset of all the inodes will be
> @@ -74,7 +72,7 @@ xfs_bmap_compute_maxlevels(
>  	 * ATTR2 we have to assume the worst case scenario of a minimum size
>  	 * available.
>  	 */
> -	maxleafents = xfs_iext_max_nextents(whichfork);
> +	maxleafents = xfs_iext_max_nextents(xfs_has_nrext64(mp), whichfork);
>  	if (whichfork == XFS_DATA_FORK)
>  		sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
>  	else
> diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
> index 453309fc85f2..e8d21d69b9ff 100644
> --- a/fs/xfs/libxfs/xfs_bmap_btree.c
> +++ b/fs/xfs/libxfs/xfs_bmap_btree.c
> @@ -611,7 +611,7 @@ xfs_bmbt_maxlevels_ondisk(void)
>  	minrecs[1] = xfs_bmbt_block_maxrecs(blocklen, false) / 2;
>  
>  	/* One extra level for the inode root. */
> -	return xfs_btree_compute_maxlevels(minrecs, MAXEXTNUM) + 1;
> +	return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_EXTCNT_DATA_FORK) + 1;
>  }
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 9934c320bf01..eff86f6c4c99 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -873,9 +873,11 @@ enum xfs_dinode_fmt {
>  /*
>   * Max values for extlen, extnum, aextnum.
>   */
> -#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
> -#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
> -#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
> +#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
> +#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
> +#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
> +#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
> +#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */

Could you change the #define value to a shift and subtract like you do
for MAXEXTLEN^WXFS_MAX_BMBT_EXTLEN in patch 16?

e.g.

#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)((1ULL << 48) - 1))

Also, you might want to document briefly in this header file why it is
that the bmbt is limited to 2^48 extents even though the dinode fields
are 64 bits wide and there can be up to 2^54 blocks mapped by a fork.
ISTR the reason is to avoid having the bmbt cursor cache have to handle
a 12-level btree or something, right?

(Sorry, it's been a while...)

>  
>  /*
>   * Inode minimum and maximum sizes.
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 860d32816909..34f360a38603 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -361,7 +361,8 @@ xfs_dinode_verify_fork(
>  			return __this_address;
>  		break;
>  	case XFS_DINODE_FMT_BTREE:
> -		max_extents = xfs_iext_max_nextents(whichfork);
> +		max_extents = xfs_iext_max_nextents(xfs_dinode_has_nrext64(dip),
> +					whichfork);
>  		if (di_nextents > max_extents)
>  			return __this_address;
>  		break;
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
> index ce690abe5dce..a3a3b54f9c55 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.c
> +++ b/fs/xfs/libxfs/xfs_inode_fork.c
> @@ -746,7 +746,7 @@ xfs_iext_count_may_overflow(
>  	if (whichfork == XFS_COW_FORK)
>  		return 0;
>  
> -	max_exts = xfs_iext_max_nextents(whichfork);
> +	max_exts = xfs_iext_max_nextents(xfs_inode_has_nrext64(ip), whichfork);
>  
>  	if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
>  		max_exts = 10;
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
> index 4a8b77d425df..0cfc351648f9 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.h
> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
> @@ -133,12 +133,23 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
>  	return ifp->if_format;
>  }
>  
> -static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
> +static inline xfs_extnum_t xfs_iext_max_nextents(bool has_big_extcnt,

has_nrext64, to be consistent with most everywhere else?

--D

> +				int whichfork)
>  {
> -	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
> -		return MAXEXTNUM;
> +	switch (whichfork) {
> +	case XFS_DATA_FORK:
> +	case XFS_COW_FORK:
> +		return has_big_extcnt ? XFS_MAX_EXTCNT_DATA_FORK
> +			: XFS_MAX_EXTCNT_DATA_FORK_OLD;
> +
> +	case XFS_ATTR_FORK:
> +		return has_big_extcnt ? XFS_MAX_EXTCNT_ATTR_FORK
> +			: XFS_MAX_EXTCNT_ATTR_FORK_OLD;
>  
> -	return MAXAEXTNUM;
> +	default:
> +		ASSERT(0);
> +		return 0;
> +	}
>  }
>  
>  static inline xfs_extnum_t
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers
  2021-12-14  8:45 ` [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
@ 2022-01-05  0:43   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:43 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:12PM +0530, Chandan Babu R wrote:
> This commit adds the new per-inode flag XFS_DIFLAG2_NREXT64 to indicate that
> an inode supports 64-bit extent counters. This flag is also enabled by default
> on newly created inodes when the corresponding filesystem has large extent
> counter feature bit (i.e. XFS_FEAT_NREXT64) set.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>

Seems pretty straightforward so far; let's see what I think as I keep
going...

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_format.h      | 10 +++++++++-
>  fs/xfs/libxfs/xfs_ialloc.c      |  2 ++
>  fs/xfs/xfs_inode.h              |  5 +++++
>  fs/xfs/xfs_inode_item_recover.c |  6 ++++++
>  4 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 7972cbc22608..9934c320bf01 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -992,15 +992,17 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
>  #define XFS_DIFLAG2_REFLINK_BIT	1	/* file's blocks may be shared */
>  #define XFS_DIFLAG2_COWEXTSIZE_BIT   2  /* copy on write extent size hint */
>  #define XFS_DIFLAG2_BIGTIME_BIT	3	/* big timestamps */
> +#define XFS_DIFLAG2_NREXT64_BIT 4	/* 64-bit extent counter enabled */
>  
>  #define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)
>  #define XFS_DIFLAG2_REFLINK     (1 << XFS_DIFLAG2_REFLINK_BIT)
>  #define XFS_DIFLAG2_COWEXTSIZE  (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
>  #define XFS_DIFLAG2_BIGTIME	(1 << XFS_DIFLAG2_BIGTIME_BIT)
> +#define XFS_DIFLAG2_NREXT64	(1 << XFS_DIFLAG2_NREXT64_BIT)
>  
>  #define XFS_DIFLAG2_ANY \
>  	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
> -	 XFS_DIFLAG2_BIGTIME)
> +	 XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_NREXT64)
>  
>  static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
>  {
> @@ -1008,6 +1010,12 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
>  	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
>  }
>  
> +static inline bool xfs_dinode_has_nrext64(const struct xfs_dinode *dip)
> +{
> +	return dip->di_version >= 3 &&
> +	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64));
> +}
> +
>  /*
>   * Inode number format:
>   * low inopblog bits - offset in block
> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
> index b418fe0c0679..1d2ba51483ec 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.c
> +++ b/fs/xfs/libxfs/xfs_ialloc.c
> @@ -2772,6 +2772,8 @@ xfs_ialloc_setup_geometry(
>  	igeo->new_diflags2 = 0;
>  	if (xfs_has_bigtime(mp))
>  		igeo->new_diflags2 |= XFS_DIFLAG2_BIGTIME;
> +	if (xfs_has_nrext64(mp))
> +		igeo->new_diflags2 |= XFS_DIFLAG2_NREXT64;
>  
>  	/* Compute inode btree geometry. */
>  	igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index c447bf04205a..97946156359d 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -218,6 +218,11 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
>  	return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
>  }
>  
> +static inline bool xfs_inode_has_nrext64(struct xfs_inode *ip)
> +{
> +	return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
> +}
> +
>  /*
>   * Return the buftarg used for data allocations on a given inode.
>   */
> diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
> index 239dd2e3384e..767a551816a0 100644
> --- a/fs/xfs/xfs_inode_item_recover.c
> +++ b/fs/xfs/xfs_inode_item_recover.c
> @@ -142,6 +142,12 @@ xfs_log_dinode_to_disk_ts(
>  	return ts;
>  }
>  
> +static inline bool xfs_log_dinode_has_nrext64(const struct xfs_log_dinode *ld)
> +{
> +	return ld->di_version >= 3 &&
> +	       (ld->di_flags2 & XFS_DIFLAG2_NREXT64);
> +}
> +
>  STATIC void
>  xfs_log_dinode_to_disk(
>  	struct xfs_log_dinode	*from,
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition
  2021-12-14  8:45 ` [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition Chandan Babu R
@ 2022-01-05  0:47   ` Darrick J. Wong
  2022-01-05 13:51     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:47 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:19PM +0530, Chandan Babu R wrote:
> The maximum extent length depends on maximum block count that can be stored in
> a BMBT record. Hence this commit defines MAXEXTLEN based on
> BMBT_BLOCKCOUNT_BITLEN.
> 
> While at it, the commit also renames MAXEXTLEN to XFS_MAX_BMBT_EXTLEN.
> 
> Suggested-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_alloc.c      |  2 +-
>  fs/xfs/libxfs/xfs_bmap.c       | 57 +++++++++++++++++-----------------
>  fs/xfs/libxfs/xfs_format.h     | 21 +++++++------
>  fs/xfs/libxfs/xfs_inode_buf.c  |  4 +--
>  fs/xfs/libxfs/xfs_trans_resv.c | 11 ++++---
>  fs/xfs/scrub/bmap.c            |  2 +-
>  fs/xfs/xfs_bmap_util.c         | 14 +++++----
>  fs/xfs/xfs_iomap.c             | 28 ++++++++---------
>  8 files changed, 72 insertions(+), 67 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 353e53b892e6..3f9b9cbfef43 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2493,7 +2493,7 @@ __xfs_free_extent_later(
>  
>  	ASSERT(bno != NULLFSBLOCK);
>  	ASSERT(len > 0);
> -	ASSERT(len <= MAXEXTLEN);
> +	ASSERT(len <= XFS_MAX_BMBT_EXTLEN);
>  	ASSERT(!isnullstartblock(bno));
>  	agno = XFS_FSB_TO_AGNO(mp, bno);
>  	agbno = XFS_FSB_TO_AGBNO(mp, bno);

Yessss another  unprefixed constant goes away.

<snip>

> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 3183f78fe7a3..dd5cffe63be3 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -885,15 +885,6 @@ enum xfs_dinode_fmt {
>  	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
>  	{ XFS_DINODE_FMT_UUID,		"uuid" }
>  
> -/*
> - * Max values for extlen, extnum, aextnum.
> - */
> -#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
> -#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
> -#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
> -#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
> -#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
> -
>  /*
>   * Inode minimum and maximum sizes.
>   */
> @@ -1623,7 +1614,17 @@ typedef struct xfs_bmdr_block {
>  #define BMBT_BLOCKCOUNT_BITLEN	21
>  
>  #define BMBT_STARTOFF_MASK	((1ULL << BMBT_STARTOFF_BITLEN) - 1)
> -#define BMBT_BLOCKCOUNT_MASK	((1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
> +
> +/*
> + * Max values for extlen and disk inode's extent counters.

Nit: 'ondisk inode'


> + */
> +#define XFS_MAX_BMBT_EXTLEN		((xfs_extlen_t)(1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
> +#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
> +#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
> +#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
> +#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
> +
> +#define BMBT_BLOCKCOUNT_MASK	XFS_MAX_BMBT_EXTLEN

Would this be simpler if XFS_MAX_EXTCNT* stay where they are, and only
XFS_MAX_BMBT_EXTLEN moves down to be defined as an alias of
BMBT_BLOCKCOUNT_MASK?

--D

>  
>  /*
>   * bmbt records have a file offset (block) field that is 54 bits wide, so this
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index b8e4e1f69989..780bad03d953 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -691,7 +691,7 @@ xfs_inode_validate_extsize(
>  	if (extsize_bytes % blocksize_bytes)
>  		return __this_address;
>  
> -	if (extsize > MAXEXTLEN)
> +	if (extsize > XFS_MAX_BMBT_EXTLEN)
>  		return __this_address;
>  
>  	if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2)
> @@ -748,7 +748,7 @@ xfs_inode_validate_cowextsize(
>  	if (cowextsize_bytes % mp->m_sb.sb_blocksize)
>  		return __this_address;
>  
> -	if (cowextsize > MAXEXTLEN)
> +	if (cowextsize > XFS_MAX_BMBT_EXTLEN)
>  		return __this_address;
>  
>  	if (cowextsize > mp->m_sb.sb_agblocks / 2)
> diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
> index 6f83d9b306ee..19313021fb99 100644
> --- a/fs/xfs/libxfs/xfs_trans_resv.c
> +++ b/fs/xfs/libxfs/xfs_trans_resv.c
> @@ -199,8 +199,8 @@ xfs_calc_inode_chunk_res(
>  /*
>   * Per-extent log reservation for the btree changes involved in freeing or
>   * allocating a realtime extent.  We have to be able to log as many rtbitmap
> - * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents,
> - * as well as the realtime summary block.
> + * blocks as needed to mark inuse XFS_BMBT_MAX_EXTLEN blocks' worth of realtime
> + * extents, as well as the realtime summary block.
>   */
>  static unsigned int
>  xfs_rtalloc_log_count(
> @@ -210,7 +210,7 @@ xfs_rtalloc_log_count(
>  	unsigned int		blksz = XFS_FSB_TO_B(mp, 1);
>  	unsigned int		rtbmp_bytes;
>  
> -	rtbmp_bytes = (MAXEXTLEN / mp->m_sb.sb_rextsize) / NBBY;
> +	rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY;
>  	return (howmany(rtbmp_bytes, blksz) + 1) * num_ops;
>  }
>  
> @@ -247,7 +247,7 @@ xfs_rtalloc_log_count(
>   *    the inode's bmap btree: max depth * block size
>   *    the agfs of the ags from which the extents are allocated: 2 * sector
>   *    the superblock free block counter: sector size
> - *    the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes
> + *    the realtime bitmap: ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY) bytes
>   *    the realtime summary: 1 block
>   *    the allocation btrees: 2 trees * (2 * max depth - 1) * block size
>   * And the bmap_finish transaction can free bmap blocks in a join (t3):
> @@ -299,7 +299,8 @@ xfs_calc_write_reservation(
>   *    the agf for each of the ags: 2 * sector size
>   *    the agfl for each of the ags: 2 * sector size
>   *    the super block to reflect the freed blocks: sector size
> - *    the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes
> + *    the realtime bitmap: 2 exts * ((XFS_BMBT_MAX_EXTLEN / rtextsize) / NBBY)
> + *    bytes
>   *    the realtime summary: 2 exts * 1 block
>   *    worst case split in allocation btrees per extent assuming 2 extents:
>   *		2 exts * 2 trees * (2 * max depth - 1) * block size
> diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
> index a4cbbc346f60..c357593e0a02 100644
> --- a/fs/xfs/scrub/bmap.c
> +++ b/fs/xfs/scrub/bmap.c
> @@ -350,7 +350,7 @@ xchk_bmap_iextent(
>  				irec->br_startoff);
>  
>  	/* Make sure the extent points to a valid place. */
> -	if (irec->br_blockcount > MAXEXTLEN)
> +	if (irec->br_blockcount > XFS_MAX_BMBT_EXTLEN)
>  		xchk_fblock_set_corrupt(info->sc, info->whichfork,
>  				irec->br_startoff);
>  	if (info->is_rt &&
> diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
> index 73a36b7be3bd..36cde254dedd 100644
> --- a/fs/xfs/xfs_bmap_util.c
> +++ b/fs/xfs/xfs_bmap_util.c
> @@ -119,14 +119,14 @@ xfs_bmap_rtalloc(
>  	 */
>  	ralen = ap->length / mp->m_sb.sb_rextsize;
>  	/*
> -	 * If the old value was close enough to MAXEXTLEN that
> +	 * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that
>  	 * we rounded up to it, cut it back so it's valid again.
>  	 * Note that if it's a really large request (bigger than
> -	 * MAXEXTLEN), we don't hear about that number, and can't
> +	 * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't
>  	 * adjust the starting point to match it.
>  	 */
> -	if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN)
> -		ralen = MAXEXTLEN / mp->m_sb.sb_rextsize;
> +	if (ralen * mp->m_sb.sb_rextsize >= XFS_MAX_BMBT_EXTLEN)
> +		ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize;
>  
>  	/*
>  	 * Lock out modifications to both the RT bitmap and summary inodes
> @@ -840,9 +840,11 @@ xfs_alloc_file_space(
>  		 * count, hence we need to limit the number of blocks we are
>  		 * trying to reserve to avoid an overflow. We can't allocate
>  		 * more than @nimaps extents, and an extent is limited on disk
> -		 * to MAXEXTLEN (21 bits), so use that to enforce the limit.
> +		 * to XFS_BMBT_MAX_EXTLEN (21 bits), so use that to enforce the
> +		 * limit.
>  		 */
> -		resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps));
> +		resblks = min_t(xfs_fileoff_t, (e - s),
> +				(XFS_MAX_BMBT_EXTLEN * nimaps));
>  		if (unlikely(rt)) {
>  			dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
>  			rblocks = resblks;
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 093758440ad5..6835adc8d62f 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -395,7 +395,7 @@ xfs_iomap_prealloc_size(
>  	 */
>  	plen = prev.br_blockcount;
>  	while (xfs_iext_prev_extent(ifp, &ncur, &got)) {
> -		if (plen > MAXEXTLEN / 2 ||
> +		if (plen > XFS_MAX_BMBT_EXTLEN / 2 ||
>  		    isnullstartblock(got.br_startblock) ||
>  		    got.br_startoff + got.br_blockcount != prev.br_startoff ||
>  		    got.br_startblock + got.br_blockcount != prev.br_startblock)
> @@ -407,23 +407,23 @@ xfs_iomap_prealloc_size(
>  	/*
>  	 * If the size of the extents is greater than half the maximum extent
>  	 * length, then use the current offset as the basis.  This ensures that
> -	 * for large files the preallocation size always extends to MAXEXTLEN
> -	 * rather than falling short due to things like stripe unit/width
> -	 * alignment of real extents.
> +	 * for large files the preallocation size always extends to
> +	 * XFS_BMBT_MAX_EXTLEN rather than falling short due to things like stripe
> +	 * unit/width alignment of real extents.
>  	 */
>  	alloc_blocks = plen * 2;
> -	if (alloc_blocks > MAXEXTLEN)
> +	if (alloc_blocks > XFS_MAX_BMBT_EXTLEN)
>  		alloc_blocks = XFS_B_TO_FSB(mp, offset);
>  	qblocks = alloc_blocks;
>  
>  	/*
> -	 * MAXEXTLEN is not a power of two value but we round the prealloc down
> -	 * to the nearest power of two value after throttling. To prevent the
> -	 * round down from unconditionally reducing the maximum supported
> -	 * prealloc size, we round up first, apply appropriate throttling,
> -	 * round down and cap the value to MAXEXTLEN.
> +	 * XFS_BMBT_MAX_EXTLEN is not a power of two value but we round the prealloc
> +	 * down to the nearest power of two value after throttling. To prevent
> +	 * the round down from unconditionally reducing the maximum supported
> +	 * prealloc size, we round up first, apply appropriate throttling, round
> +	 * down and cap the value to XFS_BMBT_MAX_EXTLEN.
>  	 */
> -	alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(MAXEXTLEN),
> +	alloc_blocks = XFS_FILEOFF_MIN(roundup_pow_of_two(XFS_MAX_BMBT_EXTLEN),
>  				       alloc_blocks);
>  
>  	freesp = percpu_counter_read_positive(&mp->m_fdblocks);
> @@ -471,14 +471,14 @@ xfs_iomap_prealloc_size(
>  	 */
>  	if (alloc_blocks)
>  		alloc_blocks = rounddown_pow_of_two(alloc_blocks);
> -	if (alloc_blocks > MAXEXTLEN)
> -		alloc_blocks = MAXEXTLEN;
> +	if (alloc_blocks > XFS_MAX_BMBT_EXTLEN)
> +		alloc_blocks = XFS_MAX_BMBT_EXTLEN;
>  
>  	/*
>  	 * If we are still trying to allocate more space than is
>  	 * available, squash the prealloc hard. This can happen if we
>  	 * have a large file on a small filesystem and the above
> -	 * lowspace thresholds are smaller than MAXEXTLEN.
> +	 * lowspace thresholds are smaller than XFS_BMBT_MAX_EXTLEN.
>  	 */
>  	while (alloc_blocks && alloc_blocks >= freesp)
>  		alloc_blocks >>= 4;
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags
  2021-12-14  8:45 ` [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
@ 2022-01-05  0:47   ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  0:47 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Tue, Dec 14, 2021 at 02:15:18PM +0530, Chandan Babu R wrote:
> This commit enables XFS module to work with fs instances having 64-bit
> per-inode extent counters by adding XFS_SB_FEAT_INCOMPAT_NREXT64 flag to the
> list of supported incompat feature flags.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>

Looks good,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_format.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 2868cec1154d..3183f78fe7a3 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -378,7 +378,8 @@ xfs_sb_has_ro_compat_feature(
>  		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
>  		 XFS_SB_FEAT_INCOMPAT_META_UUID| \
>  		 XFS_SB_FEAT_INCOMPAT_BIGTIME| \
> -		 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
> +		 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \
> +		 XFS_SB_FEAT_INCOMPAT_NREXT64)
>  
>  #define XFS_SB_FEAT_INCOMPAT_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_ALL
>  static inline bool
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters
  2021-12-14  8:45 ` [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters Chandan Babu R
@ 2022-01-05  1:04   ` Darrick J. Wong
  2022-01-05 13:47     ` Chandan Babu R
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05  1:04 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david, Dave Chinner

On Tue, Dec 14, 2021 at 02:15:15PM +0530, Chandan Babu R wrote:
> This commit introduces new fields in the on-disk inode format to support
> 64-bit data fork extent counters and 32-bit attribute fork extent
> counters. The new fields will be used only when an inode has
> XFS_DIFLAG2_NREXT64 flag set. Otherwise we continue to use the regular 32-bit
> data fork extent counters and 16-bit attribute fork extent counters.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> Suggested-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/libxfs/xfs_format.h      | 22 +++++++--
>  fs/xfs/libxfs/xfs_inode_buf.c   | 49 ++++++++++++++++++--
>  fs/xfs/libxfs/xfs_inode_fork.h  | 10 ++++-
>  fs/xfs/libxfs/xfs_log_format.h  | 22 +++++++--
>  fs/xfs/xfs_inode_item.c         | 23 ++++++++--
>  fs/xfs/xfs_inode_item_recover.c | 79 ++++++++++++++++++++++++++++-----
>  6 files changed, 176 insertions(+), 29 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index eff86f6c4c99..2868cec1154d 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -792,16 +792,30 @@ struct xfs_dinode {
>  	__be32		di_nlink;	/* number of links to file */
>  	__be16		di_projid_lo;	/* lower part of owner's project id */
>  	__be16		di_projid_hi;	/* higher part owner's project id */
> -	__u8		di_pad[6];	/* unused, zeroed space */
> -	__be16		di_flushiter;	/* incremented on flush */
> +	union {
> +		__be64	di_big_dextcnt;	/* NREXT64 data extents */

Hm.  I was expecting "__be64 di_big_nextents" and "__be32
di_big_naextents" but I'm not sure if you're just following what Dave
suggested back in September or if there's a reason to deviate?

> +		__u8	di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
> +		struct {
> +			__u8	di_v2_pad[6];	/* V2 inode zeroed space */
> +			__be16	di_flushiter;	/* V2 inode incremented on flush */
> +		};
> +	};
>  	xfs_timestamp_t	di_atime;	/* time last accessed */
>  	xfs_timestamp_t	di_mtime;	/* time last modified */
>  	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
>  	__be64		di_size;	/* number of bytes in file */
>  	__be64		di_nblocks;	/* # of direct & btree blocks used */
>  	__be32		di_extsize;	/* basic/minimum extent size for file */
> -	__be32		di_nextents;	/* number of extents in data fork */
> -	__be16		di_anextents;	/* number of extents in attribute fork*/
> +	union {
> +		struct {
> +			__be32	di_big_aextcnt; /* NREXT64 attr extents */
> +			__be16	di_nrext64_pad; /* NREXT64 unused, zero */
> +		} __packed;
> +		struct {
> +			__be32	di_nextents;	/* !NREXT64 data extents */
> +			__be16	di_anextents;	/* !NREXT64 attr extents */
> +		} __packed;
> +	};
>  	__u8		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>  	__s8		di_aformat;	/* format of attr fork's data */
>  	__be32		di_dmevmask;	/* DMIG event mask */
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 34f360a38603..fe21e9808f80 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -279,6 +279,25 @@ xfs_inode_to_disk_ts(
>  	return ts;
>  }
>  
> +static inline void
> +xfs_inode_to_disk_iext_counters(
> +	struct xfs_inode	*ip,
> +	struct xfs_dinode	*to)
> +{
> +	if (xfs_inode_has_nrext64(ip)) {
> +		to->di_big_dextcnt = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
> +		to->di_big_aextcnt = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
> +		/*
> +		 * We might be upgrading the inode to use larger extent counters
> +		 * than was previously used. Hence zero the unused field.
> +		 */
> +		to->di_nrext64_pad = cpu_to_be16(0);

If you upgrade the inode to DIFLAG_NREXT64 in xfs_trans_log_inode, won't
zeroing xfs_log_dinode.di_nrext64_pad also clean out the xfs_dinode
field?

For that matter, what /was/ the resolution of the discussion about how
log recovery should work w.r.t. changing the nrext64 inode flag?  I
thought that the inode/transaction LSN checks during recovery suffice to
prevent recovery of pre-change values into a post-change ondisk inode?

> +	} else {
> +		to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> +		to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
> +	}
> +}
> +
>  void
>  xfs_inode_to_disk(
>  	struct xfs_inode	*ip,
> @@ -296,7 +315,6 @@ xfs_inode_to_disk(
>  	to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
>  	to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
>  
> -	memset(to->di_pad, 0, sizeof(to->di_pad));
>  	to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
>  	to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
>  	to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
> @@ -307,8 +325,6 @@ xfs_inode_to_disk(
>  	to->di_size = cpu_to_be64(ip->i_disk_size);
>  	to->di_nblocks = cpu_to_be64(ip->i_nblocks);
>  	to->di_extsize = cpu_to_be32(ip->i_extsize);
> -	to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> -	to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
>  	to->di_forkoff = ip->i_forkoff;
>  	to->di_aformat = xfs_ifork_format(ip->i_afp);
>  	to->di_flags = cpu_to_be16(ip->i_diflags);
> @@ -323,11 +339,14 @@ xfs_inode_to_disk(
>  		to->di_lsn = cpu_to_be64(lsn);
>  		memset(to->di_pad2, 0, sizeof(to->di_pad2));
>  		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
> -		to->di_flushiter = 0;
> +		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
>  	} else {
>  		to->di_version = 2;
>  		to->di_flushiter = cpu_to_be16(ip->i_flushiter);
> +		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
>  	}
> +
> +	xfs_inode_to_disk_iext_counters(ip, to);
>  }
>  
>  static xfs_failaddr_t
> @@ -397,6 +416,24 @@ xfs_dinode_verify_forkoff(
>  	return NULL;
>  }
>  
> +static xfs_failaddr_t
> +xfs_dinode_verify_nextents(
> +	struct xfs_mount	*mp,
> +	struct xfs_dinode	*dip)
> +{
> +	if (xfs_dinode_has_nrext64(dip)) {
> +		if (!xfs_has_nrext64(mp))
> +			return __this_address;
> +		if (dip->di_nrext64_pad != 0)
> +			return __this_address;
> +	} else {
> +		if (dip->di_version == 3 && dip->di_big_dextcnt != 0)
> +			return __this_address;
> +	}
> +
> +	return NULL;
> +}
> +
>  xfs_failaddr_t
>  xfs_dinode_verify(
>  	struct xfs_mount	*mp,
> @@ -440,6 +477,10 @@ xfs_dinode_verify(
>  	if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
>  		return __this_address;
>  
> +	fa = xfs_dinode_verify_nextents(mp, dip);
> +	if (fa)
> +		return fa;
> +
>  	nextents = xfs_dfork_data_extents(dip);
>  	nextents += xfs_dfork_attr_extents(dip);
>  	nblocks = be64_to_cpu(dip->di_nblocks);
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
> index 0cfc351648f9..fa5143fb889b 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.h
> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
> @@ -156,14 +156,20 @@ static inline xfs_extnum_t
>  xfs_dfork_data_extents(
>  	struct xfs_dinode	*dip)
>  {
> -	return be32_to_cpu(dip->di_nextents);
> +	if (xfs_dinode_has_nrext64(dip))
> +		return be64_to_cpu(dip->di_big_dextcnt);
> +	else
> +		return be32_to_cpu(dip->di_nextents);

No need for the else in these helpers.

>  }
>  
>  static inline xfs_extnum_t
>  xfs_dfork_attr_extents(
>  	struct xfs_dinode	*dip)
>  {
> -	return be16_to_cpu(dip->di_anextents);
> +	if (xfs_dinode_has_nrext64(dip))
> +		return be32_to_cpu(dip->di_big_aextcnt);
> +	else
> +		return be16_to_cpu(dip->di_anextents);
>  }
>  
>  static inline xfs_extnum_t
> diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
> index fd66e70248f7..46aed637c98b 100644
> --- a/fs/xfs/libxfs/xfs_log_format.h
> +++ b/fs/xfs/libxfs/xfs_log_format.h
> @@ -388,16 +388,30 @@ struct xfs_log_dinode {
>  	uint32_t	di_nlink;	/* number of links to file */
>  	uint16_t	di_projid_lo;	/* lower part of owner's project id */
>  	uint16_t	di_projid_hi;	/* higher part of owner's project id */
> -	uint8_t		di_pad[6];	/* unused, zeroed space */
> -	uint16_t	di_flushiter;	/* incremented on flush */
> +	union {
> +		uint64_t	di_big_dextcnt;	/* NREXT64 data extents */
> +		uint8_t		di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
> +		struct {
> +			uint8_t	di_v2_pad[6];	/* V2 inode zeroed space */
> +			uint16_t di_flushiter;	/* V2 inode incremented on flush */
> +		};
> +	};
>  	xfs_log_timestamp_t di_atime;	/* time last accessed */
>  	xfs_log_timestamp_t di_mtime;	/* time last modified */
>  	xfs_log_timestamp_t di_ctime;	/* time created/inode modified */
>  	xfs_fsize_t	di_size;	/* number of bytes in file */
>  	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
>  	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
> -	uint32_t	di_nextents;	/* number of extents in data fork */
> -	uint16_t	di_anextents;	/* number of extents in attribute fork*/
> +	union {
> +		struct {
> +			uint32_t  di_big_aextcnt; /* NREXT64 attr extents */
> +			uint16_t  di_nrext64_pad; /* NREXT64 unused, zero */
> +		} __packed;
> +		struct {
> +			uint32_t  di_nextents;	  /* !NREXT64 data extents */
> +			uint16_t  di_anextents;	  /* !NREXT64 attr extents */
> +		} __packed;
> +	};
>  	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>  	int8_t		di_aformat;	/* format of attr fork's data */
>  	uint32_t	di_dmevmask;	/* DMIG event mask */
> diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> index 90d8e591baf8..82f4b9bb871b 100644
> --- a/fs/xfs/xfs_inode_item.c
> +++ b/fs/xfs/xfs_inode_item.c
> @@ -358,6 +358,21 @@ xfs_copy_dm_fields_to_log_dinode(
>  	}
>  }
>  
> +static inline void
> +xfs_inode_to_log_dinode_iext_counters(
> +	struct xfs_inode	*ip,
> +	struct xfs_log_dinode	*to)
> +{
> +	if (xfs_inode_has_nrext64(ip)) {
> +		to->di_big_dextcnt = xfs_ifork_nextents(&ip->i_df);
> +		to->di_big_aextcnt = xfs_ifork_nextents(ip->i_afp);
> +		to->di_nrext64_pad = 0;
> +	} else {
> +		to->di_nextents = xfs_ifork_nextents(&ip->i_df);
> +		to->di_anextents = xfs_ifork_nextents(ip->i_afp);
> +	}
> +}
> +
>  static void
>  xfs_inode_to_log_dinode(
>  	struct xfs_inode	*ip,
> @@ -373,7 +388,6 @@ xfs_inode_to_log_dinode(
>  	to->di_projid_lo = ip->i_projid & 0xffff;
>  	to->di_projid_hi = ip->i_projid >> 16;
>  
> -	memset(to->di_pad, 0, sizeof(to->di_pad));
>  	memset(to->di_pad3, 0, sizeof(to->di_pad3));
>  	to->di_atime = xfs_inode_to_log_dinode_ts(ip, inode->i_atime);
>  	to->di_mtime = xfs_inode_to_log_dinode_ts(ip, inode->i_mtime);
> @@ -385,8 +399,6 @@ xfs_inode_to_log_dinode(
>  	to->di_size = ip->i_disk_size;
>  	to->di_nblocks = ip->i_nblocks;
>  	to->di_extsize = ip->i_extsize;
> -	to->di_nextents = xfs_ifork_nextents(&ip->i_df);
> -	to->di_anextents = xfs_ifork_nextents(ip->i_afp);
>  	to->di_forkoff = ip->i_forkoff;
>  	to->di_aformat = xfs_ifork_format(ip->i_afp);
>  	to->di_flags = ip->i_diflags;
> @@ -406,11 +418,14 @@ xfs_inode_to_log_dinode(
>  		to->di_lsn = lsn;
>  		memset(to->di_pad2, 0, sizeof(to->di_pad2));
>  		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
> -		to->di_flushiter = 0;
> +		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
>  	} else {
>  		to->di_version = 2;
>  		to->di_flushiter = ip->i_flushiter;
> +		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
>  	}
> +
> +	xfs_inode_to_log_dinode_iext_counters(ip, to);
>  }
>  
>  /*
> diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
> index 767a551816a0..7434ad4772dc 100644
> --- a/fs/xfs/xfs_inode_item_recover.c
> +++ b/fs/xfs/xfs_inode_item_recover.c
> @@ -148,6 +148,22 @@ static inline bool xfs_log_dinode_has_nrext64(const struct xfs_log_dinode *ld)
>  	       (ld->di_flags2 & XFS_DIFLAG2_NREXT64);
>  }
>  
> +static inline void
> +xfs_log_dinode_to_disk_iext_counters(
> +	struct xfs_log_dinode	*from,
> +	struct xfs_dinode	*to)
> +{
> +	if (xfs_log_dinode_has_nrext64(from)) {
> +		to->di_big_dextcnt = cpu_to_be64(from->di_big_dextcnt);
> +		to->di_big_aextcnt = cpu_to_be32(from->di_big_aextcnt);
> +		to->di_nrext64_pad = cpu_to_be16(from->di_nrext64_pad);
> +	} else {
> +		to->di_nextents = cpu_to_be32(from->di_nextents);
> +		to->di_anextents = cpu_to_be16(from->di_anextents);
> +	}
> +
> +}
> +
>  STATIC void
>  xfs_log_dinode_to_disk(
>  	struct xfs_log_dinode	*from,
> @@ -164,7 +180,6 @@ xfs_log_dinode_to_disk(
>  	to->di_nlink = cpu_to_be32(from->di_nlink);
>  	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
>  	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
> -	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
>  
>  	to->di_atime = xfs_log_dinode_to_disk_ts(from, from->di_atime);
>  	to->di_mtime = xfs_log_dinode_to_disk_ts(from, from->di_mtime);
> @@ -173,8 +188,6 @@ xfs_log_dinode_to_disk(
>  	to->di_size = cpu_to_be64(from->di_size);
>  	to->di_nblocks = cpu_to_be64(from->di_nblocks);
>  	to->di_extsize = cpu_to_be32(from->di_extsize);
> -	to->di_nextents = cpu_to_be32(from->di_nextents);
> -	to->di_anextents = cpu_to_be16(from->di_anextents);
>  	to->di_forkoff = from->di_forkoff;
>  	to->di_aformat = from->di_aformat;
>  	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
> @@ -192,10 +205,13 @@ xfs_log_dinode_to_disk(
>  		to->di_lsn = cpu_to_be64(lsn);
>  		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
>  		uuid_copy(&to->di_uuid, &from->di_uuid);
> -		to->di_flushiter = 0;
> +		memcpy(to->di_v3_pad, from->di_v3_pad, sizeof(to->di_v3_pad));
>  	} else {
>  		to->di_flushiter = cpu_to_be16(from->di_flushiter);
> +		memcpy(to->di_v2_pad, from->di_v2_pad, sizeof(to->di_v2_pad));
>  	}
> +
> +	xfs_log_dinode_to_disk_iext_counters(from, to);
>  }
>  
>  STATIC int
> @@ -209,6 +225,8 @@ xlog_recover_inode_commit_pass2(
>  	struct xfs_mount		*mp = log->l_mp;
>  	struct xfs_buf			*bp;
>  	struct xfs_dinode		*dip;
> +	xfs_extnum_t                    nextents;
> +	xfs_aextnum_t                   anextents;
>  	int				len;
>  	char				*src;
>  	char				*dest;
> @@ -348,21 +366,60 @@ xlog_recover_inode_commit_pass2(
>  			goto out_release;
>  		}
>  	}
> -	if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
> +
> +	if (xfs_log_dinode_has_nrext64(ldip)) {
> +		if (!xfs_has_nrext64(mp) || (ldip->di_nrext64_pad != 0)) {
> +			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
> +				     XFS_ERRLEVEL_LOW, mp, ldip,
> +				     sizeof(*ldip));
> +			xfs_alert(mp,
> +				"%s: Bad inode log record, rec ptr "PTR_FMT", "
> +				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
> +				"ino %Ld, xfs_has_nrext64(mp) = %d, "
> +				"ldip->di_nrext64_pad = %u",
> +				__func__, item, dip, bp, in_f->ilf_ino,
> +				xfs_has_nrext64(mp), ldip->di_nrext64_pad);
> +			error = -EFSCORRUPTED;
> +			goto out_release;
> +		}
> +	} else {
> +		if (ldip->di_version == 3 && ldip->di_big_dextcnt != 0) {
> +			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
> +				     XFS_ERRLEVEL_LOW, mp, ldip,
> +				     sizeof(*ldip));
> +			xfs_alert(mp,
> +				"%s: Bad inode log record, rec ptr "PTR_FMT", "
> +				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
> +				"ino %Ld, ldip->di_big_dextcnt = %llu",
> +				__func__, item, dip, bp, in_f->ilf_ino,
> +				ldip->di_big_dextcnt);
> +			error = -EFSCORRUPTED;
> +			goto out_release;
> +		}
> +	}
> +
> +	if (xfs_log_dinode_has_nrext64(ldip)) {
> +		nextents = ldip->di_big_dextcnt;
> +		anextents = ldip->di_big_aextcnt;
> +	} else {
> +		nextents = ldip->di_nextents;
> +		anextents = ldip->di_anextents;
> +	}
> +
> +	if (unlikely(nextents + anextents > ldip->di_nblocks)) {
> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>  				     sizeof(*ldip));
>  		xfs_alert(mp,
>  	"%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
> -	"dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld",
> +	"dino bp "PTR_FMT", ino %Ld, total extents = %llu, nblocks = %Ld",
>  			__func__, item, dip, bp, in_f->ilf_ino,
> -			ldip->di_nextents + ldip->di_anextents,
> -			ldip->di_nblocks);
> +			nextents + anextents, ldip->di_nblocks);
>  		error = -EFSCORRUPTED;
>  		goto out_release;
>  	}
>  	if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(8)",
>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>  				     sizeof(*ldip));
>  		xfs_alert(mp,
> @@ -374,7 +431,7 @@ xlog_recover_inode_commit_pass2(
>  	}
>  	isize = xfs_log_dinode_size(mp);
>  	if (unlikely(item->ri_buf[1].i_len > isize)) {
> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(9)",
>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>  				     sizeof(*ldip));
>  		xfs_alert(mp,
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents
  2022-01-04 23:50   ` Darrick J. Wong
@ 2022-01-05 13:43     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 05:20, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:08PM +0530, Chandan Babu R wrote:
>> A future commit will increase the width of xfs_extnum_t in order to facilitate
>> larger per-inode extent counters. Hence this patch now uses basic types to
>> define xfs_log_dinode->[di_nextents|dianextents].
>> 
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>
> I wonder how this didn't trip the xfs_ondisk.h checks in the last
> revision of the patches, but ... who cares, let's see what I think of
> how /this/ version handles the field enlargements.
>

This change was part of "xfs: Rename inode's extent counter fields based on
their width" patch in v3 patchset. As Dave had correctly complained, this
change had to be done in a separate patch.

> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
>
> --D
>
>> ---
>>  fs/xfs/libxfs/xfs_log_format.h | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
>> index b322db523d65..fd66e70248f7 100644
>> --- a/fs/xfs/libxfs/xfs_log_format.h
>> +++ b/fs/xfs/libxfs/xfs_log_format.h
>> @@ -396,8 +396,8 @@ struct xfs_log_dinode {
>>  	xfs_fsize_t	di_size;	/* number of bytes in file */
>>  	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
>>  	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
>> -	xfs_extnum_t	di_nextents;	/* number of extents in data fork */
>> -	xfs_aextnum_t	di_anextents;	/* number of extents in attribute fork*/
>> +	uint32_t	di_nextents;	/* number of extents in data fork */
>> +	uint16_t	di_anextents;	/* number of extents in attribute fork*/
>>  	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>>  	int8_t		di_aformat;	/* format of attr fork's data */
>>  	uint32_t	di_dmevmask;	/* DMIG event mask */
>> -- 
>> 2.30.2
>> 


-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
  2022-01-05  0:05   ` Darrick J. Wong
@ 2022-01-05 13:44     ` Chandan Babu R
  2022-01-05 17:22       ` Darrick J. Wong
  0 siblings, 1 reply; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 05:35, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:11PM +0530, Chandan Babu R wrote:
>> XFS_FSOP_GEOM_FLAGS_NREXT64 indicates that the current filesystem instance
>> supports 64-bit per-inode extent counters.
>> 
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>>  fs/xfs/libxfs/xfs_fs.h | 1 +
>>  fs/xfs/libxfs/xfs_sb.c | 2 ++
>>  2 files changed, 3 insertions(+)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
>> index c43877c8a279..42bc39501d81 100644
>> --- a/fs/xfs/libxfs/xfs_fs.h
>> +++ b/fs/xfs/libxfs/xfs_fs.h
>> @@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
>>  #define XFS_FSOP_GEOM_FLAGS_REFLINK	(1 << 20) /* files can share blocks */
>>  #define XFS_FSOP_GEOM_FLAGS_BIGTIME	(1 << 21) /* 64-bit nsec timestamps */
>>  #define XFS_FSOP_GEOM_FLAGS_INOBTCNT	(1 << 22) /* inobt btree counter */
>> +#define XFS_FSOP_GEOM_FLAGS_NREXT64	(1 << 23) /* 64-bit extent counter */
>>  
>>  /*
>>   * Minimum and maximum sizes need for growth checks.
>> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
>> index bd632389ae92..0c1add39177f 100644
>> --- a/fs/xfs/libxfs/xfs_sb.c
>> +++ b/fs/xfs/libxfs/xfs_sb.c
>> @@ -1138,6 +1138,8 @@ xfs_fs_geometry(
>>  	} else {
>>  		geo->logsectsize = BBSIZE;
>>  	}
>> +	if (xfs_has_nrext64(mp))
>> +		geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64;
>>  	geo->rtsectsize = sbp->sb_blocksize;
>>  	geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
>>  
>> -- 
>> 2.30.2
>> 

I think you accidently missed typing your response to this patch?

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks
  2022-01-05  0:42   ` Darrick J. Wong
@ 2022-01-05 13:46     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:46 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 06:12, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:14PM +0530, Chandan Babu R wrote:
>> This commit defines new macros to represent maximum extent counts allowed by
>> filesystems which have support for large per-inode extent counters.
>> 
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>>  fs/xfs/libxfs/xfs_bmap.c       |  8 +++-----
>>  fs/xfs/libxfs/xfs_bmap_btree.c |  2 +-
>>  fs/xfs/libxfs/xfs_format.h     |  8 +++++---
>>  fs/xfs/libxfs/xfs_inode_buf.c  |  3 ++-
>>  fs/xfs/libxfs/xfs_inode_fork.c |  2 +-
>>  fs/xfs/libxfs/xfs_inode_fork.h | 19 +++++++++++++++----
>>  6 files changed, 27 insertions(+), 15 deletions(-)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
>> index 4113622e9733..0ce58e4a9c44 100644
>> --- a/fs/xfs/libxfs/xfs_bmap.c
>> +++ b/fs/xfs/libxfs/xfs_bmap.c
>> @@ -61,10 +61,8 @@ xfs_bmap_compute_maxlevels(
>>  	int		sz;		/* root block size */
>>  
>>  	/*
>> -	 * The maximum number of extents in a file, hence the maximum number of
>> -	 * leaf entries, is controlled by the size of the on-disk extent count,
>> -	 * either a signed 32-bit number for the data fork, or a signed 16-bit
>> -	 * number for the attr fork.
>> +	 * The maximum number of extents in a fork, hence the maximum number of
>> +	 * leaf entries, is controlled by the size of the on-disk extent count.
>>  	 *
>>  	 * Note that we can no longer assume that if we are in ATTR1 that the
>>  	 * fork offset of all the inodes will be
>> @@ -74,7 +72,7 @@ xfs_bmap_compute_maxlevels(
>>  	 * ATTR2 we have to assume the worst case scenario of a minimum size
>>  	 * available.
>>  	 */
>> -	maxleafents = xfs_iext_max_nextents(whichfork);
>> +	maxleafents = xfs_iext_max_nextents(xfs_has_nrext64(mp), whichfork);
>>  	if (whichfork == XFS_DATA_FORK)
>>  		sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
>>  	else
>> diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
>> index 453309fc85f2..e8d21d69b9ff 100644
>> --- a/fs/xfs/libxfs/xfs_bmap_btree.c
>> +++ b/fs/xfs/libxfs/xfs_bmap_btree.c
>> @@ -611,7 +611,7 @@ xfs_bmbt_maxlevels_ondisk(void)
>>  	minrecs[1] = xfs_bmbt_block_maxrecs(blocklen, false) / 2;
>>  
>>  	/* One extra level for the inode root. */
>> -	return xfs_btree_compute_maxlevels(minrecs, MAXEXTNUM) + 1;
>> +	return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_EXTCNT_DATA_FORK) + 1;
>>  }
>>  
>>  /*
>> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
>> index 9934c320bf01..eff86f6c4c99 100644
>> --- a/fs/xfs/libxfs/xfs_format.h
>> +++ b/fs/xfs/libxfs/xfs_format.h
>> @@ -873,9 +873,11 @@ enum xfs_dinode_fmt {
>>  /*
>>   * Max values for extlen, extnum, aextnum.
>>   */
>> -#define	MAXEXTLEN	((xfs_extlen_t)0x001fffff)	/* 21 bits */
>> -#define	MAXEXTNUM	((xfs_extnum_t)0x7fffffff)	/* signed int */
>> -#define	MAXAEXTNUM	((xfs_aextnum_t)0x7fff)		/* signed short */
>> +#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
>> +#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
>> +#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
>> +#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
>> +#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
>
> Could you change the #define value to a shift and subtract like you do
> for MAXEXTLEN^WXFS_MAX_BMBT_EXTLEN in patch 16?
>
> e.g.
>
> #define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)((1ULL << 48) - 1))

Sure. I will incorporate the above change.

>
> Also, you might want to document briefly in this header file why it is
> that the bmbt is limited to 2^48 extents even though the dinode fields
> are 64 bits wide and there can be up to 2^54 blocks mapped by a fork.
> ISTR the reason is to avoid having the bmbt cursor cache have to handle
> a 12-level btree or something, right?
>
> (Sorry, it's been a while...)
>

The discussion initially started with the observation that anything more than
2^43 extents on a 1k block sized filesystem can cause a BMBT tree's height to
become larger than XFS_BTREE_MAXLEVELS (i.e. 9). Increasing the value of
XFS_BTREE_MAXLEVELS was not an option since that would cause the following
sequence of events,

1. An increase in the rmapbt's maximum height (on filesystems which have both
   reflink and rmap features enabled).
2. An increase in transaction reservation values.

However this is no longer an issue since the btree cursor now contains a
variable length array and XFS_BTREE_MAXLEVELS is now removed.

2^48 as the maximum extent count was arrived at based on the following logic,

2^63 (max file size) / 64k (max block size) = 2^47

i.e. 2^47 can be a valid upper bound for all block sizes.

Rounding up 47 to the nearest multiple of bits-per-byte results in 48. Hence
2^48 was chosen as the maximum data fork extent count.

I will include the above description in the next version of the patchset.

>>  
>>  /*
>>   * Inode minimum and maximum sizes.
>> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
>> index 860d32816909..34f360a38603 100644
>> --- a/fs/xfs/libxfs/xfs_inode_buf.c
>> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
>> @@ -361,7 +361,8 @@ xfs_dinode_verify_fork(
>>  			return __this_address;
>>  		break;
>>  	case XFS_DINODE_FMT_BTREE:
>> -		max_extents = xfs_iext_max_nextents(whichfork);
>> +		max_extents = xfs_iext_max_nextents(xfs_dinode_has_nrext64(dip),
>> +					whichfork);
>>  		if (di_nextents > max_extents)
>>  			return __this_address;
>>  		break;
>> diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
>> index ce690abe5dce..a3a3b54f9c55 100644
>> --- a/fs/xfs/libxfs/xfs_inode_fork.c
>> +++ b/fs/xfs/libxfs/xfs_inode_fork.c
>> @@ -746,7 +746,7 @@ xfs_iext_count_may_overflow(
>>  	if (whichfork == XFS_COW_FORK)
>>  		return 0;
>>  
>> -	max_exts = xfs_iext_max_nextents(whichfork);
>> +	max_exts = xfs_iext_max_nextents(xfs_inode_has_nrext64(ip), whichfork);
>>  
>>  	if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
>>  		max_exts = 10;
>> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
>> index 4a8b77d425df..0cfc351648f9 100644
>> --- a/fs/xfs/libxfs/xfs_inode_fork.h
>> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
>> @@ -133,12 +133,23 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
>>  	return ifp->if_format;
>>  }
>>  
>> -static inline xfs_extnum_t xfs_iext_max_nextents(int whichfork)
>> +static inline xfs_extnum_t xfs_iext_max_nextents(bool has_big_extcnt,
>
> has_nrext64, to be consistent with most everywhere else?
>

You are right. I will fix this.

> --D
>
>> +				int whichfork)
>>  {
>> -	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
>> -		return MAXEXTNUM;
>> +	switch (whichfork) {
>> +	case XFS_DATA_FORK:
>> +	case XFS_COW_FORK:
>> +		return has_big_extcnt ? XFS_MAX_EXTCNT_DATA_FORK
>> +			: XFS_MAX_EXTCNT_DATA_FORK_OLD;
>> +
>> +	case XFS_ATTR_FORK:
>> +		return has_big_extcnt ? XFS_MAX_EXTCNT_ATTR_FORK
>> +			: XFS_MAX_EXTCNT_ATTR_FORK_OLD;
>>  
>> -	return MAXAEXTNUM;
>> +	default:
>> +		ASSERT(0);
>> +		return 0;
>> +	}
>>  }
>>  
>>  static inline xfs_extnum_t
>> -- 
>> 2.30.2
>> 


-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters
  2022-01-05  1:04   ` Darrick J. Wong
@ 2022-01-05 13:47     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:47 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david, Dave Chinner

On 05 Jan 2022 at 06:34, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:15PM +0530, Chandan Babu R wrote:
>> This commit introduces new fields in the on-disk inode format to support
>> 64-bit data fork extent counters and 32-bit attribute fork extent
>> counters. The new fields will be used only when an inode has
>> XFS_DIFLAG2_NREXT64 flag set. Otherwise we continue to use the regular 32-bit
>> data fork extent counters and 16-bit attribute fork extent counters.
>> 
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> Suggested-by: Dave Chinner <dchinner@redhat.com>
>> ---
>>  fs/xfs/libxfs/xfs_format.h      | 22 +++++++--
>>  fs/xfs/libxfs/xfs_inode_buf.c   | 49 ++++++++++++++++++--
>>  fs/xfs/libxfs/xfs_inode_fork.h  | 10 ++++-
>>  fs/xfs/libxfs/xfs_log_format.h  | 22 +++++++--
>>  fs/xfs/xfs_inode_item.c         | 23 ++++++++--
>>  fs/xfs/xfs_inode_item_recover.c | 79 ++++++++++++++++++++++++++++-----
>>  6 files changed, 176 insertions(+), 29 deletions(-)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
>> index eff86f6c4c99..2868cec1154d 100644
>> --- a/fs/xfs/libxfs/xfs_format.h
>> +++ b/fs/xfs/libxfs/xfs_format.h
>> @@ -792,16 +792,30 @@ struct xfs_dinode {
>>  	__be32		di_nlink;	/* number of links to file */
>>  	__be16		di_projid_lo;	/* lower part of owner's project id */
>>  	__be16		di_projid_hi;	/* higher part owner's project id */
>> -	__u8		di_pad[6];	/* unused, zeroed space */
>> -	__be16		di_flushiter;	/* incremented on flush */
>> +	union {
>> +		__be64	di_big_dextcnt;	/* NREXT64 data extents */
>
> Hm.  I was expecting "__be64 di_big_nextents" and "__be32
> di_big_naextents" but I'm not sure if you're just following what Dave
> suggested back in September or if there's a reason to deviate?
>

Yes, I have followed what Dave had suggested. But I think di_big_n[a]extents
field names are consistent with the existing extent counter field names. I
will fix this up too.

>> +		__u8	di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
>> +		struct {
>> +			__u8	di_v2_pad[6];	/* V2 inode zeroed space */
>> +			__be16	di_flushiter;	/* V2 inode incremented on flush */
>> +		};
>> +	};
>>  	xfs_timestamp_t	di_atime;	/* time last accessed */
>>  	xfs_timestamp_t	di_mtime;	/* time last modified */
>>  	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
>>  	__be64		di_size;	/* number of bytes in file */
>>  	__be64		di_nblocks;	/* # of direct & btree blocks used */
>>  	__be32		di_extsize;	/* basic/minimum extent size for file */
>> -	__be32		di_nextents;	/* number of extents in data fork */
>> -	__be16		di_anextents;	/* number of extents in attribute fork*/
>> +	union {
>> +		struct {
>> +			__be32	di_big_aextcnt; /* NREXT64 attr extents */
>> +			__be16	di_nrext64_pad; /* NREXT64 unused, zero */
>> +		} __packed;
>> +		struct {
>> +			__be32	di_nextents;	/* !NREXT64 data extents */
>> +			__be16	di_anextents;	/* !NREXT64 attr extents */
>> +		} __packed;
>> +	};
>>  	__u8		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>>  	__s8		di_aformat;	/* format of attr fork's data */
>>  	__be32		di_dmevmask;	/* DMIG event mask */
>> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
>> index 34f360a38603..fe21e9808f80 100644
>> --- a/fs/xfs/libxfs/xfs_inode_buf.c
>> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
>> @@ -279,6 +279,25 @@ xfs_inode_to_disk_ts(
>>  	return ts;
>>  }
>>  
>> +static inline void
>> +xfs_inode_to_disk_iext_counters(
>> +	struct xfs_inode	*ip,
>> +	struct xfs_dinode	*to)
>> +{
>> +	if (xfs_inode_has_nrext64(ip)) {
>> +		to->di_big_dextcnt = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
>> +		to->di_big_aextcnt = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
>> +		/*
>> +		 * We might be upgrading the inode to use larger extent counters
>> +		 * than was previously used. Hence zero the unused field.
>> +		 */
>> +		to->di_nrext64_pad = cpu_to_be16(0);
>
> If you upgrade the inode to DIFLAG_NREXT64 in xfs_trans_log_inode, won't
> zeroing xfs_log_dinode.di_nrext64_pad also clean out the xfs_dinode
> field?
>

In the event where the log tail gets unpinned the corresponding inode item
gets pushed (via xfs_inode_item_push()), the incore inode's contents are then
written to the disk by xfs_inode_to_disk(). At this instance, the ondisk inode
can have a non-zero value at xfs_dinode->di_nrext64_pad since this field maps
to the older 16-bit attr fork extent counter. Hence this field has to be
zeroed out.

> For that matter, what /was/ the resolution of the discussion about how
> log recovery should work w.r.t. changing the nrext64 inode flag?  I
> thought that the inode/transaction LSN checks during recovery suffice to
> prevent recovery of pre-change values into a post-change ondisk inode?
>

Yes, The current inode recovery mechanism does prevent overwriting areas of an
upgraded ondisk inode with values from fields belonging to a non-upgraded log
dinode.

The following code snippet from xlog_recover_inode_commit_pass2() skips replay
of xfs_log_dinode entries when ondisk inode's LSN is greater than checkpoint
transaction's LSN,

        if (dip->di_version >= 3) {
                xfs_lsn_t       lsn = be64_to_cpu(dip->di_lsn);

                if (lsn && lsn != -1 && XFS_LSN_CMP(lsn, current_lsn) > 0) {
                        trace_xfs_log_recover_inode_skip(log, in_f);
                        error = 0;
                        goto out_owner_change;
                }
        }


And as Dave had clarified earlier
(https://lore.kernel.org/all/20210916100647.176018-7-chandan.babu@oracle.com/T/#m7b43e474e8473b03cc03e884f23aa173e539a60c),
in the event that we have three checkpoint transactions having the same LSN
with the 3rd one setting DIFLAG_NREXT64 flag, The inode can have inconsistent
data after the 1st and the 2nd transactions are replayed. But we are assured
of the inode returning to its consistent state since the 3rd transaction is
guaranteed to be replayed. However, This scenario should not occur since we
now set DIFLAG_NREXT64 during xfs_inode_from_disk().

>> +	} else {
>> +		to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
>> +		to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
>> +	}
>> +}
>> +
>>  void
>>  xfs_inode_to_disk(
>>  	struct xfs_inode	*ip,
>> @@ -296,7 +315,6 @@ xfs_inode_to_disk(
>>  	to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
>>  	to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
>>  
>> -	memset(to->di_pad, 0, sizeof(to->di_pad));
>>  	to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
>>  	to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
>>  	to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
>> @@ -307,8 +325,6 @@ xfs_inode_to_disk(
>>  	to->di_size = cpu_to_be64(ip->i_disk_size);
>>  	to->di_nblocks = cpu_to_be64(ip->i_nblocks);
>>  	to->di_extsize = cpu_to_be32(ip->i_extsize);
>> -	to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
>> -	to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
>>  	to->di_forkoff = ip->i_forkoff;
>>  	to->di_aformat = xfs_ifork_format(ip->i_afp);
>>  	to->di_flags = cpu_to_be16(ip->i_diflags);
>> @@ -323,11 +339,14 @@ xfs_inode_to_disk(
>>  		to->di_lsn = cpu_to_be64(lsn);
>>  		memset(to->di_pad2, 0, sizeof(to->di_pad2));
>>  		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
>> -		to->di_flushiter = 0;
>> +		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
>>  	} else {
>>  		to->di_version = 2;
>>  		to->di_flushiter = cpu_to_be16(ip->i_flushiter);
>> +		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
>>  	}
>> +
>> +	xfs_inode_to_disk_iext_counters(ip, to);
>>  }
>>  
>>  static xfs_failaddr_t
>> @@ -397,6 +416,24 @@ xfs_dinode_verify_forkoff(
>>  	return NULL;
>>  }
>>  
>> +static xfs_failaddr_t
>> +xfs_dinode_verify_nextents(
>> +	struct xfs_mount	*mp,
>> +	struct xfs_dinode	*dip)
>> +{
>> +	if (xfs_dinode_has_nrext64(dip)) {
>> +		if (!xfs_has_nrext64(mp))
>> +			return __this_address;
>> +		if (dip->di_nrext64_pad != 0)
>> +			return __this_address;
>> +	} else {
>> +		if (dip->di_version == 3 && dip->di_big_dextcnt != 0)
>> +			return __this_address;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>>  xfs_failaddr_t
>>  xfs_dinode_verify(
>>  	struct xfs_mount	*mp,
>> @@ -440,6 +477,10 @@ xfs_dinode_verify(
>>  	if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
>>  		return __this_address;
>>  
>> +	fa = xfs_dinode_verify_nextents(mp, dip);
>> +	if (fa)
>> +		return fa;
>> +
>>  	nextents = xfs_dfork_data_extents(dip);
>>  	nextents += xfs_dfork_attr_extents(dip);
>>  	nblocks = be64_to_cpu(dip->di_nblocks);
>> diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
>> index 0cfc351648f9..fa5143fb889b 100644
>> --- a/fs/xfs/libxfs/xfs_inode_fork.h
>> +++ b/fs/xfs/libxfs/xfs_inode_fork.h
>> @@ -156,14 +156,20 @@ static inline xfs_extnum_t
>>  xfs_dfork_data_extents(
>>  	struct xfs_dinode	*dip)
>>  {
>> -	return be32_to_cpu(dip->di_nextents);
>> +	if (xfs_dinode_has_nrext64(dip))
>> +		return be64_to_cpu(dip->di_big_dextcnt);
>> +	else
>> +		return be32_to_cpu(dip->di_nextents);
>
> No need for the else in these helpers.
>

Ok. I will fix this.

>>  }
>>  
>>  static inline xfs_extnum_t
>>  xfs_dfork_attr_extents(
>>  	struct xfs_dinode	*dip)
>>  {
>> -	return be16_to_cpu(dip->di_anextents);
>> +	if (xfs_dinode_has_nrext64(dip))
>> +		return be32_to_cpu(dip->di_big_aextcnt);
>> +	else
>> +		return be16_to_cpu(dip->di_anextents);
>>  }
>>  
>>  static inline xfs_extnum_t
>> diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
>> index fd66e70248f7..46aed637c98b 100644
>> --- a/fs/xfs/libxfs/xfs_log_format.h
>> +++ b/fs/xfs/libxfs/xfs_log_format.h
>> @@ -388,16 +388,30 @@ struct xfs_log_dinode {
>>  	uint32_t	di_nlink;	/* number of links to file */
>>  	uint16_t	di_projid_lo;	/* lower part of owner's project id */
>>  	uint16_t	di_projid_hi;	/* higher part of owner's project id */
>> -	uint8_t		di_pad[6];	/* unused, zeroed space */
>> -	uint16_t	di_flushiter;	/* incremented on flush */
>> +	union {
>> +		uint64_t	di_big_dextcnt;	/* NREXT64 data extents */
>> +		uint8_t		di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
>> +		struct {
>> +			uint8_t	di_v2_pad[6];	/* V2 inode zeroed space */
>> +			uint16_t di_flushiter;	/* V2 inode incremented on flush */
>> +		};
>> +	};
>>  	xfs_log_timestamp_t di_atime;	/* time last accessed */
>>  	xfs_log_timestamp_t di_mtime;	/* time last modified */
>>  	xfs_log_timestamp_t di_ctime;	/* time created/inode modified */
>>  	xfs_fsize_t	di_size;	/* number of bytes in file */
>>  	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
>>  	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
>> -	uint32_t	di_nextents;	/* number of extents in data fork */
>> -	uint16_t	di_anextents;	/* number of extents in attribute fork*/
>> +	union {
>> +		struct {
>> +			uint32_t  di_big_aextcnt; /* NREXT64 attr extents */
>> +			uint16_t  di_nrext64_pad; /* NREXT64 unused, zero */
>> +		} __packed;
>> +		struct {
>> +			uint32_t  di_nextents;	  /* !NREXT64 data extents */
>> +			uint16_t  di_anextents;	  /* !NREXT64 attr extents */
>> +		} __packed;
>> +	};
>>  	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>>  	int8_t		di_aformat;	/* format of attr fork's data */
>>  	uint32_t	di_dmevmask;	/* DMIG event mask */
>> diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
>> index 90d8e591baf8..82f4b9bb871b 100644
>> --- a/fs/xfs/xfs_inode_item.c
>> +++ b/fs/xfs/xfs_inode_item.c
>> @@ -358,6 +358,21 @@ xfs_copy_dm_fields_to_log_dinode(
>>  	}
>>  }
>>  
>> +static inline void
>> +xfs_inode_to_log_dinode_iext_counters(
>> +	struct xfs_inode	*ip,
>> +	struct xfs_log_dinode	*to)
>> +{
>> +	if (xfs_inode_has_nrext64(ip)) {
>> +		to->di_big_dextcnt = xfs_ifork_nextents(&ip->i_df);
>> +		to->di_big_aextcnt = xfs_ifork_nextents(ip->i_afp);
>> +		to->di_nrext64_pad = 0;
>> +	} else {
>> +		to->di_nextents = xfs_ifork_nextents(&ip->i_df);
>> +		to->di_anextents = xfs_ifork_nextents(ip->i_afp);
>> +	}
>> +}
>> +
>>  static void
>>  xfs_inode_to_log_dinode(
>>  	struct xfs_inode	*ip,
>> @@ -373,7 +388,6 @@ xfs_inode_to_log_dinode(
>>  	to->di_projid_lo = ip->i_projid & 0xffff;
>>  	to->di_projid_hi = ip->i_projid >> 16;
>>  
>> -	memset(to->di_pad, 0, sizeof(to->di_pad));
>>  	memset(to->di_pad3, 0, sizeof(to->di_pad3));
>>  	to->di_atime = xfs_inode_to_log_dinode_ts(ip, inode->i_atime);
>>  	to->di_mtime = xfs_inode_to_log_dinode_ts(ip, inode->i_mtime);
>> @@ -385,8 +399,6 @@ xfs_inode_to_log_dinode(
>>  	to->di_size = ip->i_disk_size;
>>  	to->di_nblocks = ip->i_nblocks;
>>  	to->di_extsize = ip->i_extsize;
>> -	to->di_nextents = xfs_ifork_nextents(&ip->i_df);
>> -	to->di_anextents = xfs_ifork_nextents(ip->i_afp);
>>  	to->di_forkoff = ip->i_forkoff;
>>  	to->di_aformat = xfs_ifork_format(ip->i_afp);
>>  	to->di_flags = ip->i_diflags;
>> @@ -406,11 +418,14 @@ xfs_inode_to_log_dinode(
>>  		to->di_lsn = lsn;
>>  		memset(to->di_pad2, 0, sizeof(to->di_pad2));
>>  		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
>> -		to->di_flushiter = 0;
>> +		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
>>  	} else {
>>  		to->di_version = 2;
>>  		to->di_flushiter = ip->i_flushiter;
>> +		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
>>  	}
>> +
>> +	xfs_inode_to_log_dinode_iext_counters(ip, to);
>>  }
>>  
>>  /*
>> diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c
>> index 767a551816a0..7434ad4772dc 100644
>> --- a/fs/xfs/xfs_inode_item_recover.c
>> +++ b/fs/xfs/xfs_inode_item_recover.c
>> @@ -148,6 +148,22 @@ static inline bool xfs_log_dinode_has_nrext64(const struct xfs_log_dinode *ld)
>>  	       (ld->di_flags2 & XFS_DIFLAG2_NREXT64);
>>  }
>>  
>> +static inline void
>> +xfs_log_dinode_to_disk_iext_counters(
>> +	struct xfs_log_dinode	*from,
>> +	struct xfs_dinode	*to)
>> +{
>> +	if (xfs_log_dinode_has_nrext64(from)) {
>> +		to->di_big_dextcnt = cpu_to_be64(from->di_big_dextcnt);
>> +		to->di_big_aextcnt = cpu_to_be32(from->di_big_aextcnt);
>> +		to->di_nrext64_pad = cpu_to_be16(from->di_nrext64_pad);
>> +	} else {
>> +		to->di_nextents = cpu_to_be32(from->di_nextents);
>> +		to->di_anextents = cpu_to_be16(from->di_anextents);
>> +	}
>> +
>> +}
>> +
>>  STATIC void
>>  xfs_log_dinode_to_disk(
>>  	struct xfs_log_dinode	*from,
>> @@ -164,7 +180,6 @@ xfs_log_dinode_to_disk(
>>  	to->di_nlink = cpu_to_be32(from->di_nlink);
>>  	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
>>  	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
>> -	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
>>  
>>  	to->di_atime = xfs_log_dinode_to_disk_ts(from, from->di_atime);
>>  	to->di_mtime = xfs_log_dinode_to_disk_ts(from, from->di_mtime);
>> @@ -173,8 +188,6 @@ xfs_log_dinode_to_disk(
>>  	to->di_size = cpu_to_be64(from->di_size);
>>  	to->di_nblocks = cpu_to_be64(from->di_nblocks);
>>  	to->di_extsize = cpu_to_be32(from->di_extsize);
>> -	to->di_nextents = cpu_to_be32(from->di_nextents);
>> -	to->di_anextents = cpu_to_be16(from->di_anextents);
>>  	to->di_forkoff = from->di_forkoff;
>>  	to->di_aformat = from->di_aformat;
>>  	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
>> @@ -192,10 +205,13 @@ xfs_log_dinode_to_disk(
>>  		to->di_lsn = cpu_to_be64(lsn);
>>  		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
>>  		uuid_copy(&to->di_uuid, &from->di_uuid);
>> -		to->di_flushiter = 0;
>> +		memcpy(to->di_v3_pad, from->di_v3_pad, sizeof(to->di_v3_pad));
>>  	} else {
>>  		to->di_flushiter = cpu_to_be16(from->di_flushiter);
>> +		memcpy(to->di_v2_pad, from->di_v2_pad, sizeof(to->di_v2_pad));
>>  	}
>> +
>> +	xfs_log_dinode_to_disk_iext_counters(from, to);
>>  }
>>  
>>  STATIC int
>> @@ -209,6 +225,8 @@ xlog_recover_inode_commit_pass2(
>>  	struct xfs_mount		*mp = log->l_mp;
>>  	struct xfs_buf			*bp;
>>  	struct xfs_dinode		*dip;
>> +	xfs_extnum_t                    nextents;
>> +	xfs_aextnum_t                   anextents;
>>  	int				len;
>>  	char				*src;
>>  	char				*dest;
>> @@ -348,21 +366,60 @@ xlog_recover_inode_commit_pass2(
>>  			goto out_release;
>>  		}
>>  	}
>> -	if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
>> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
>> +
>> +	if (xfs_log_dinode_has_nrext64(ldip)) {
>> +		if (!xfs_has_nrext64(mp) || (ldip->di_nrext64_pad != 0)) {
>> +			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
>> +				     XFS_ERRLEVEL_LOW, mp, ldip,
>> +				     sizeof(*ldip));
>> +			xfs_alert(mp,
>> +				"%s: Bad inode log record, rec ptr "PTR_FMT", "
>> +				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
>> +				"ino %Ld, xfs_has_nrext64(mp) = %d, "
>> +				"ldip->di_nrext64_pad = %u",
>> +				__func__, item, dip, bp, in_f->ilf_ino,
>> +				xfs_has_nrext64(mp), ldip->di_nrext64_pad);
>> +			error = -EFSCORRUPTED;
>> +			goto out_release;
>> +		}
>> +	} else {
>> +		if (ldip->di_version == 3 && ldip->di_big_dextcnt != 0) {
>> +			XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
>> +				     XFS_ERRLEVEL_LOW, mp, ldip,
>> +				     sizeof(*ldip));
>> +			xfs_alert(mp,
>> +				"%s: Bad inode log record, rec ptr "PTR_FMT", "
>> +				"dino ptr "PTR_FMT", dino bp "PTR_FMT", "
>> +				"ino %Ld, ldip->di_big_dextcnt = %llu",
>> +				__func__, item, dip, bp, in_f->ilf_ino,
>> +				ldip->di_big_dextcnt);
>> +			error = -EFSCORRUPTED;
>> +			goto out_release;
>> +		}
>> +	}
>> +
>> +	if (xfs_log_dinode_has_nrext64(ldip)) {
>> +		nextents = ldip->di_big_dextcnt;
>> +		anextents = ldip->di_big_aextcnt;
>> +	} else {
>> +		nextents = ldip->di_nextents;
>> +		anextents = ldip->di_anextents;
>> +	}
>> +
>> +	if (unlikely(nextents + anextents > ldip->di_nblocks)) {
>> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
>>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>>  				     sizeof(*ldip));
>>  		xfs_alert(mp,
>>  	"%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", "
>> -	"dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld",
>> +	"dino bp "PTR_FMT", ino %Ld, total extents = %llu, nblocks = %Ld",
>>  			__func__, item, dip, bp, in_f->ilf_ino,
>> -			ldip->di_nextents + ldip->di_anextents,
>> -			ldip->di_nblocks);
>> +			nextents + anextents, ldip->di_nblocks);
>>  		error = -EFSCORRUPTED;
>>  		goto out_release;
>>  	}
>>  	if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
>> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
>> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(8)",
>>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>>  				     sizeof(*ldip));
>>  		xfs_alert(mp,
>> @@ -374,7 +431,7 @@ xlog_recover_inode_commit_pass2(
>>  	}
>>  	isize = xfs_log_dinode_size(mp);
>>  	if (unlikely(item->ri_buf[1].i_len > isize)) {
>> -		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
>> +		XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(9)",
>>  				     XFS_ERRLEVEL_LOW, mp, ldip,
>>  				     sizeof(*ldip));
>>  		xfs_alert(mp,
>> -- 
>> 2.30.2
>> 


-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use 64-bit extent counters
  2022-01-05  0:18   ` Darrick J. Wong
@ 2022-01-05 13:49     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:49 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 05:48, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:16PM +0530, Chandan Babu R wrote:
>> This commit upgrades inodes to use 64-bit extent counters when they are read
>> from disk. Inodes are upgraded only when the filesystem instance has
>> XFS_SB_FEAT_INCOMPAT_NREXT64 incompat flag set.
>> 
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>>  fs/xfs/libxfs/xfs_inode_buf.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
>> index fe21e9808f80..b8e4e1f69989 100644
>> --- a/fs/xfs/libxfs/xfs_inode_buf.c
>> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
>> @@ -253,6 +253,12 @@ xfs_inode_from_disk(
>>  	}
>>  	if (xfs_is_reflink_inode(ip))
>>  		xfs_ifork_init_cow(ip);
>> +
>> +	if ((from->di_version == 3) &&
>> +		xfs_has_nrext64(ip->i_mount) &&
>> +		!xfs_dinode_has_nrext64(from))
>> +		ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
>
> The indentation levels of the if test should not be aligned with the if
> body, and this should be in xfs_trans_log_inode so that the metadata
> update is staged properly with a transaction.  V3 did it this way, so
> I'm a little surprised to see V4 regressing that...?

The following is the thought process behind upgrading an inode to
XFS_DIFLAG2_NREXT64 when it is read from the disk,

1. With support for dynamic upgrade, The extent count limits of an inode needs
   to be determined by checking flags present within the inode i.e. we need to
   satisfy self-describing metadata property. This helps tools like xfs_repair
   and scrub to verify inode's extent count limits without having to refer to
   other metadata objects (e.g. superblock feature flags).
   
2. Upgrade when performed inside xfs_trans_log_inode() may cause
   xfs_iext_count_may_overflow() to return -EFBIG when the inode's data/attr
   extent count is already close to 2^31/2^15 respectively. Hence none of the
   file operations will be able to add new extents to a file.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode extent counters
  2022-01-05  0:28   ` Darrick J. Wong
@ 2022-01-05 13:50     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 05:58, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:17PM +0530, Chandan Babu R wrote:
>> The following changes are made to enable userspace to obtain 64-bit extent
>> counters,
>> 1. Carve out a new 64-bit field xfs_bulkstat->bs_extents64 from
>>    xfs_bulkstat->bs_pad[] to hold 64-bit extent counter.
>> 2. Define the new flag XFS_BULK_IREQ_BULKSTAT for userspace to indicate that
>>    it is capable of receiving 64-bit extent counters.
>> 
>> Suggested-by: Darrick J. Wong <djwong@kernel.org>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>>  fs/xfs/libxfs/xfs_fs.h | 12 ++++++++----
>>  fs/xfs/xfs_ioctl.c     |  3 +++
>>  fs/xfs/xfs_itable.c    | 24 +++++++++++++++++++++++-
>>  fs/xfs/xfs_itable.h    |  2 ++
>>  fs/xfs/xfs_iwalk.h     |  7 +++++--
>>  5 files changed, 41 insertions(+), 7 deletions(-)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
>> index 42bc39501d81..4e12530eb518 100644
>> --- a/fs/xfs/libxfs/xfs_fs.h
>> +++ b/fs/xfs/libxfs/xfs_fs.h
>> @@ -393,7 +393,7 @@ struct xfs_bulkstat {
>>  	uint32_t	bs_extsize_blks; /* extent size hint, blocks	*/
>>  
>>  	uint32_t	bs_nlink;	/* number of links		*/
>> -	uint32_t	bs_extents;	/* number of extents		*/
>> +	uint32_t	bs_extents;	/* 32-bit data fork extent counter */
>>  	uint32_t	bs_aextents;	/* attribute number of extents	*/
>>  	uint16_t	bs_version;	/* structure version		*/
>>  	uint16_t	bs_forkoff;	/* inode fork offset in bytes	*/
>> @@ -402,8 +402,9 @@ struct xfs_bulkstat {
>>  	uint16_t	bs_checked;	/* checked inode metadata	*/
>>  	uint16_t	bs_mode;	/* type and mode		*/
>>  	uint16_t	bs_pad2;	/* zeroed			*/
>> +	uint64_t	bs_extents64;	/* 64-bit data fork extent counter */
>>  
>> -	uint64_t	bs_pad[7];	/* zeroed			*/
>> +	uint64_t	bs_pad[6];	/* zeroed			*/
>>  };
>>  
>>  #define XFS_BULKSTAT_VERSION_V1	(1)
>> @@ -484,8 +485,11 @@ struct xfs_bulk_ireq {
>>   */
>>  #define XFS_BULK_IREQ_SPECIAL	(1 << 1)
>>  
>> -#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO | \
>> -				 XFS_BULK_IREQ_SPECIAL)
>> +#define XFS_BULK_IREQ_NREXT64	(1 << 2)
>> +
>> +#define XFS_BULK_IREQ_FLAGS_ALL	(XFS_BULK_IREQ_AGNO |	 \
>> +				 XFS_BULK_IREQ_SPECIAL | \
>> +				 XFS_BULK_IREQ_NREXT64)
>>  
>>  /* Operate on the root directory inode. */
>>  #define XFS_BULK_IREQ_SPECIAL_ROOT	(1)
>> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
>> index 174cd8950cb6..d9e9a805b67b 100644
>> --- a/fs/xfs/xfs_ioctl.c
>> +++ b/fs/xfs/xfs_ioctl.c
>> @@ -893,6 +893,9 @@ xfs_bulk_ireq_setup(
>>  	if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
>>  		return -ECANCELED;
>>  
>> +	if (hdr->flags & XFS_BULK_IREQ_NREXT64)
>> +		breq->flags |= XFS_IBULK_NREXT64;
>> +
>>  	return 0;
>>  }
>>  
>> diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
>> index c08c79d9e311..53ec0afebdc9 100644
>> --- a/fs/xfs/xfs_itable.c
>> +++ b/fs/xfs/xfs_itable.c
>> @@ -20,6 +20,7 @@
>>  #include "xfs_icache.h"
>>  #include "xfs_health.h"
>>  #include "xfs_trans.h"
>> +#include "xfs_errortag.h"
>>  
>>  /*
>>   * Bulk Stat
>> @@ -64,6 +65,7 @@ xfs_bulkstat_one_int(
>>  	struct xfs_inode	*ip;		/* incore inode pointer */
>>  	struct inode		*inode;
>>  	struct xfs_bulkstat	*buf = bc->buf;
>> +	xfs_extnum_t		nextents;
>>  	int			error = -EINVAL;
>>  
>>  	if (xfs_internal_inum(mp, ino))
>> @@ -102,7 +104,27 @@ xfs_bulkstat_one_int(
>>  
>>  	buf->bs_xflags = xfs_ip2xflags(ip);
>>  	buf->bs_extsize_blks = ip->i_extsize;
>> -	buf->bs_extents = xfs_ifork_nextents(&ip->i_df);
>> +
>> +	nextents = xfs_ifork_nextents(&ip->i_df);
>> +	if (!(bc->breq->flags & XFS_IBULK_NREXT64)) {
>> +		xfs_extnum_t max_nextents = XFS_MAX_EXTCNT_DATA_FORK_OLD;
>> +
>> +		if (unlikely(XFS_TEST_ERROR(false, mp,
>> +				XFS_ERRTAG_REDUCE_MAX_IEXTENTS)))
>> +			max_nextents = 10;
>> +
>> +		if (nextents > max_nextents) {
>> +			xfs_iunlock(ip, XFS_ILOCK_SHARED);
>> +			xfs_irele(ip);
>> +			error = -EOVERFLOW;
>> +			goto out;
>> +		}
>> +
>> +		buf->bs_extents = nextents;
>> +	} else {
>> +		buf->bs_extents64 = nextents;
>> +	}
>> +
>>  	xfs_bulkstat_health(ip, buf);
>>  	buf->bs_aextents = xfs_ifork_nextents(ip->i_afp);
>>  	buf->bs_forkoff = XFS_IFORK_BOFF(ip);
>> diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
>> index 7078d10c9b12..a561acd95383 100644
>> --- a/fs/xfs/xfs_itable.h
>> +++ b/fs/xfs/xfs_itable.h
>> @@ -19,6 +19,8 @@ struct xfs_ibulk {
>>  /* Only iterate within the same AG as startino */
>>  #define XFS_IBULK_SAME_AG	(XFS_IWALK_SAME_AG)
>>  
>> +#define XFS_IBULK_NREXT64	(XFS_IWALK_NREXT64)
>> +
>>  /*
>>   * Advance the user buffer pointer by one record of the given size.  If the
>>   * buffer is now full, return the appropriate error code.
>> diff --git a/fs/xfs/xfs_iwalk.h b/fs/xfs/xfs_iwalk.h
>> index 37a795f03267..11be9dbb45c7 100644
>> --- a/fs/xfs/xfs_iwalk.h
>> +++ b/fs/xfs/xfs_iwalk.h
>> @@ -26,9 +26,12 @@ int xfs_iwalk_threaded(struct xfs_mount *mp, xfs_ino_t startino,
>>  		unsigned int inode_records, bool poll, void *data);
>>  
>>  /* Only iterate inodes within the same AG as @startino. */
>> -#define XFS_IWALK_SAME_AG	(0x1)
>> +#define XFS_IWALK_SAME_AG	(1 << 0)
>>  
>> -#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG)
>> +#define XFS_IWALK_NREXT64	(1 << 1)
>
> The ability of the caller to handle 64-bit extent counters is not
> relevant to the internal inode walking code, so I don't think this
> belongs in the iwalk flags namespace.
>
> IOWs, XFS_IBULK_NREXT64 should be defined like this:
>
> #define XFS_IBULK_NREXT64	(1U << 31)
>
> and xfs_bulkstat should be changed to translate only the relevant
> breq->flags into the appropriate IWALK bits.  Sorry for the code
> smell...

Ok. I will incorporate this review comment in the next revision of the
patchset..

>
> --D
>
>> +
>> +#define XFS_IWALK_FLAGS_ALL	(XFS_IWALK_SAME_AG |	\
>> +				 XFS_IWALK_NREXT64)
>>  
>>  /* Walk all inode btree records in the filesystem starting from @startino. */
>>  typedef int (*xfs_inobt_walk_fn)(struct xfs_mount *mp, struct xfs_trans *tp,
>> -- 
>> 2.30.2
>> 


-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition
  2022-01-05  0:47   ` Darrick J. Wong
@ 2022-01-05 13:51     ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 13:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs, david

On 05 Jan 2022 at 06:17, Darrick J. Wong wrote:
> On Tue, Dec 14, 2021 at 02:15:19PM +0530, Chandan Babu R wrote:
>> The maximum extent length depends on maximum block count that can be stored in
>> a BMBT record. Hence this commit defines MAXEXTLEN based on
>> BMBT_BLOCKCOUNT_BITLEN.
>> 
>> While at it, the commit also renames MAXEXTLEN to XFS_MAX_BMBT_EXTLEN.
>> 
>> Suggested-by: Darrick J. Wong <djwong@kernel.org>
>> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
>> ---
>>  fs/xfs/libxfs/xfs_alloc.c      |  2 +-
>>  fs/xfs/libxfs/xfs_bmap.c       | 57 +++++++++++++++++-----------------
>>  fs/xfs/libxfs/xfs_format.h     | 21 +++++++------
>>  fs/xfs/libxfs/xfs_inode_buf.c  |  4 +--
>>  fs/xfs/libxfs/xfs_trans_resv.c | 11 ++++---
>>  fs/xfs/scrub/bmap.c            |  2 +-
>>  fs/xfs/xfs_bmap_util.c         | 14 +++++----
>>  fs/xfs/xfs_iomap.c             | 28 ++++++++---------
>>  8 files changed, 72 insertions(+), 67 deletions(-)
>> 
>> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
>> index 353e53b892e6..3f9b9cbfef43 100644
>> --- a/fs/xfs/libxfs/xfs_alloc.c
>> +++ b/fs/xfs/libxfs/xfs_alloc.c
>> @@ -2493,7 +2493,7 @@ __xfs_free_extent_later(
>>  
>>  	ASSERT(bno != NULLFSBLOCK);
>>  	ASSERT(len > 0);
>> -	ASSERT(len <= MAXEXTLEN);
>> +	ASSERT(len <= XFS_MAX_BMBT_EXTLEN);
>>  	ASSERT(!isnullstartblock(bno));
>>  	agno = XFS_FSB_TO_AGNO(mp, bno);
>>  	agbno = XFS_FSB_TO_AGBNO(mp, bno);
>
> Yessss another  unprefixed constant goes away.
>
> <snip>
>
>> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
>> index 3183f78fe7a3..dd5cffe63be3 100644
>> --- a/fs/xfs/libxfs/xfs_format.h
>> +++ b/fs/xfs/libxfs/xfs_format.h
>> @@ -885,15 +885,6 @@ enum xfs_dinode_fmt {
>>  	{ XFS_DINODE_FMT_BTREE,		"btree" }, \
>>  	{ XFS_DINODE_FMT_UUID,		"uuid" }
>>  
>> -/*
>> - * Max values for extlen, extnum, aextnum.
>> - */
>> -#define	MAXEXTLEN			((xfs_extlen_t)0x1fffff)	/* 21 bits */
>> -#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
>> -#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
>> -#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
>> -#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
>> -
>>  /*
>>   * Inode minimum and maximum sizes.
>>   */
>> @@ -1623,7 +1614,17 @@ typedef struct xfs_bmdr_block {
>>  #define BMBT_BLOCKCOUNT_BITLEN	21
>>  
>>  #define BMBT_STARTOFF_MASK	((1ULL << BMBT_STARTOFF_BITLEN) - 1)
>> -#define BMBT_BLOCKCOUNT_MASK	((1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
>> +
>> +/*
>> + * Max values for extlen and disk inode's extent counters.
>
> Nit: 'ondisk inode'
>
>
>> + */
>> +#define XFS_MAX_BMBT_EXTLEN		((xfs_extlen_t)(1ULL << BMBT_BLOCKCOUNT_BITLEN) - 1)
>> +#define XFS_MAX_EXTCNT_DATA_FORK	((xfs_extnum_t)0xffffffffffff)	/* Unsigned 48-bits */
>> +#define XFS_MAX_EXTCNT_ATTR_FORK	((xfs_aextnum_t)0xffffffff)	/* Unsigned 32-bits */
>> +#define XFS_MAX_EXTCNT_DATA_FORK_OLD	((xfs_extnum_t)0x7fffffff)	/* Signed 32-bits */
>> +#define XFS_MAX_EXTCNT_ATTR_FORK_OLD	((xfs_aextnum_t)0x7fff)		/* Signed 16-bits */
>> +
>> +#define BMBT_BLOCKCOUNT_MASK	XFS_MAX_BMBT_EXTLEN
>
> Would this be simpler if XFS_MAX_EXTCNT* stay where they are, and only
> XFS_MAX_BMBT_EXTLEN moves down to be defined as an alias of
> BMBT_BLOCKCOUNT_MASK?
>

Yes, I think so. Also, all the *BMBT* macros defined around the same place
will probably help make the organization better.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2022-01-04 23:54         ` Darrick J. Wong
@ 2022-01-05 14:14           ` Chandan Babu R
  -1 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 14:14 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: kernel test robot, linux-xfs, kbuild-all, david

On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
>> On 14 Dec 2021 at 20:45, kernel test robot wrote:
>> > Hi Chandan,
>> >
>> > Thank you for the patch! Yet something to improve:
>> >
>> > [auto build test ERROR on xfs-linux/for-next]
>> > [also build test ERROR on v5.16-rc5]
>> > [If your patch is applied to the wrong git tree, kindly drop us a note.
>> > And when submitting patch, we suggest to use '--base' as documented in
>> > https://git-scm.com/docs/git-format-patch]
>> >
>> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
>> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
>> > compiler: microblaze-linux-gcc (GCC) 11.2.0
>> > reproduce (this is a W=1 build):
>> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> >         chmod +x ~/bin/make.cross
>> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>> >         git remote add linux-review https://github.com/0day-ci/linux
>> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>> >         # save the config file to linux build tree
>> >         mkdir build_dir
>> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>> >
>> > If you fix the issue, kindly add following tag as appropriate
>> > Reported-by: kernel test robot <lkp@intel.com>
>> >
>> > All errors (new ones prefixed by >>):
>> >
>> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
>> >
>> 
>> The fix for the compilation error on 32-bit systems involved invoking do_div()
>> instead of using the regular division operator. I will include the fix in the
>> next version of the patchset.
>
> So, uh, how did you resolve this in the end?
>
> 	maxblocks = roundup_64(maxleafents, minleafrecs);
>
> and
>
> 	maxblocks = roundup_64(maxblocks, minnodrecs);
>
> ?

I had made the following changes,

	maxblocks = maxleafents + minleafrecs - 1;
	do_div(maxblocks, minleafrecs);

and
	maxblocks += minnoderecs - 1;
	do_div(maxblocks, minnoderecs);

roundup_64() would cause maxleafents to have a value >= its previous value
right?

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2022-01-05 14:14           ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-05 14:14 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2733 bytes --]

On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
>> On 14 Dec 2021 at 20:45, kernel test robot wrote:
>> > Hi Chandan,
>> >
>> > Thank you for the patch! Yet something to improve:
>> >
>> > [auto build test ERROR on xfs-linux/for-next]
>> > [also build test ERROR on v5.16-rc5]
>> > [If your patch is applied to the wrong git tree, kindly drop us a note.
>> > And when submitting patch, we suggest to use '--base' as documented in
>> > https://git-scm.com/docs/git-format-patch]
>> >
>> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
>> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
>> > compiler: microblaze-linux-gcc (GCC) 11.2.0
>> > reproduce (this is a W=1 build):
>> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> >         chmod +x ~/bin/make.cross
>> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>> >         git remote add linux-review https://github.com/0day-ci/linux
>> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>> >         # save the config file to linux build tree
>> >         mkdir build_dir
>> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>> >
>> > If you fix the issue, kindly add following tag as appropriate
>> > Reported-by: kernel test robot <lkp@intel.com>
>> >
>> > All errors (new ones prefixed by >>):
>> >
>> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
>> >
>> 
>> The fix for the compilation error on 32-bit systems involved invoking do_div()
>> instead of using the regular division operator. I will include the fix in the
>> next version of the patchset.
>
> So, uh, how did you resolve this in the end?
>
> 	maxblocks = roundup_64(maxleafents, minleafrecs);
>
> and
>
> 	maxblocks = roundup_64(maxblocks, minnodrecs);
>
> ?

I had made the following changes,

	maxblocks = maxleafents + minleafrecs - 1;
	do_div(maxblocks, minleafrecs);

and
	maxblocks += minnoderecs - 1;
	do_div(maxblocks, minnoderecs);

roundup_64() would cause maxleafents to have a value >= its previous value
right?

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2022-01-05 14:14           ` Chandan Babu R
@ 2022-01-05 17:21             ` Darrick J. Wong
  -1 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05 17:21 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: kernel test robot, linux-xfs, kbuild-all, david

On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> >> > Hi Chandan,
> >> >
> >> > Thank you for the patch! Yet something to improve:
> >> >
> >> > [auto build test ERROR on xfs-linux/for-next]
> >> > [also build test ERROR on v5.16-rc5]
> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> >> > And when submitting patch, we suggest to use '--base' as documented in
> >> > https://git-scm.com/docs/git-format-patch]
> >> >
> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> >> > reproduce (this is a W=1 build):
> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >> >         chmod +x ~/bin/make.cross
> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >> >         git remote add linux-review https://github.com/0day-ci/linux
> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >> >         # save the config file to linux build tree
> >> >         mkdir build_dir
> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >> >
> >> > If you fix the issue, kindly add following tag as appropriate
> >> > Reported-by: kernel test robot <lkp@intel.com>
> >> >
> >> > All errors (new ones prefixed by >>):
> >> >
> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >> >
> >> 
> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
> >> instead of using the regular division operator. I will include the fix in the
> >> next version of the patchset.
> >
> > So, uh, how did you resolve this in the end?
> >
> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
> >
> > and
> >
> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
> >
> > ?
> 
> I had made the following changes,
> 
> 	maxblocks = maxleafents + minleafrecs - 1;
> 	do_div(maxblocks, minleafrecs);
> 
> and
> 	maxblocks += minnoderecs - 1;
> 	do_div(maxblocks, minnoderecs);
> 
> roundup_64() would cause maxleafents to have a value >= its previous value
> right?

roundup_64 doesn't alter its parameters, if I'm not mistaken:

static inline uint64_t roundup_64(uint64_t x, uint32_t y)
{
	x += y - 1;
	do_div(x, y);
	return x * y;
}

--D

> 
> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2022-01-05 17:21             ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05 17:21 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3115 bytes --]

On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> >> > Hi Chandan,
> >> >
> >> > Thank you for the patch! Yet something to improve:
> >> >
> >> > [auto build test ERROR on xfs-linux/for-next]
> >> > [also build test ERROR on v5.16-rc5]
> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> >> > And when submitting patch, we suggest to use '--base' as documented in
> >> > https://git-scm.com/docs/git-format-patch]
> >> >
> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> >> > reproduce (this is a W=1 build):
> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >> >         chmod +x ~/bin/make.cross
> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >> >         git remote add linux-review https://github.com/0day-ci/linux
> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >> >         # save the config file to linux build tree
> >> >         mkdir build_dir
> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >> >
> >> > If you fix the issue, kindly add following tag as appropriate
> >> > Reported-by: kernel test robot <lkp@intel.com>
> >> >
> >> > All errors (new ones prefixed by >>):
> >> >
> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >> >
> >> 
> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
> >> instead of using the regular division operator. I will include the fix in the
> >> next version of the patchset.
> >
> > So, uh, how did you resolve this in the end?
> >
> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
> >
> > and
> >
> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
> >
> > ?
> 
> I had made the following changes,
> 
> 	maxblocks = maxleafents + minleafrecs - 1;
> 	do_div(maxblocks, minleafrecs);
> 
> and
> 	maxblocks += minnoderecs - 1;
> 	do_div(maxblocks, minnoderecs);
> 
> roundup_64() would cause maxleafents to have a value >= its previous value
> right?

roundup_64 doesn't alter its parameters, if I'm not mistaken:

static inline uint64_t roundup_64(uint64_t x, uint32_t y)
{
	x += y - 1;
	do_div(x, y);
	return x * y;
}

--D

> 
> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64
  2022-01-05 13:44     ` Chandan Babu R
@ 2022-01-05 17:22       ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-05 17:22 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: linux-xfs, david

On Wed, Jan 05, 2022 at 07:14:55PM +0530, Chandan Babu R wrote:
> On 05 Jan 2022 at 05:35, Darrick J. Wong wrote:
> > On Tue, Dec 14, 2021 at 02:15:11PM +0530, Chandan Babu R wrote:
> >> XFS_FSOP_GEOM_FLAGS_NREXT64 indicates that the current filesystem instance
> >> supports 64-bit per-inode extent counters.
> >> 
> >> Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
> >> ---
> >>  fs/xfs/libxfs/xfs_fs.h | 1 +
> >>  fs/xfs/libxfs/xfs_sb.c | 2 ++
> >>  2 files changed, 3 insertions(+)
> >> 
> >> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> >> index c43877c8a279..42bc39501d81 100644
> >> --- a/fs/xfs/libxfs/xfs_fs.h
> >> +++ b/fs/xfs/libxfs/xfs_fs.h
> >> @@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
> >>  #define XFS_FSOP_GEOM_FLAGS_REFLINK	(1 << 20) /* files can share blocks */
> >>  #define XFS_FSOP_GEOM_FLAGS_BIGTIME	(1 << 21) /* 64-bit nsec timestamps */
> >>  #define XFS_FSOP_GEOM_FLAGS_INOBTCNT	(1 << 22) /* inobt btree counter */
> >> +#define XFS_FSOP_GEOM_FLAGS_NREXT64	(1 << 23) /* 64-bit extent counter */
> >>  
> >>  /*
> >>   * Minimum and maximum sizes need for growth checks.
> >> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
> >> index bd632389ae92..0c1add39177f 100644
> >> --- a/fs/xfs/libxfs/xfs_sb.c
> >> +++ b/fs/xfs/libxfs/xfs_sb.c
> >> @@ -1138,6 +1138,8 @@ xfs_fs_geometry(
> >>  	} else {
> >>  		geo->logsectsize = BBSIZE;
> >>  	}
> >> +	if (xfs_has_nrext64(mp))
> >> +		geo->flags |= XFS_FSOP_GEOM_FLAGS_NREXT64;
> >>  	geo->rtsectsize = sbp->sb_blocksize;
> >>  	geo->dirblocksize = xfs_dir2_dirblock_bytes(sbp);
> >>  
> >> -- 
> >> 2.30.2
> >> 
> 
> I think you accidently missed typing your response to this patch?

Yep.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> 
> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2022-01-05 17:21             ` Darrick J. Wong
@ 2022-01-06  7:03               ` Chandan Babu R
  -1 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-06  7:03 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: kernel test robot, linux-xfs, kbuild-all, david

On 05 Jan 2022 at 22:51, Darrick J. Wong wrote:
> On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
>> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
>> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
>> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
>> >> > Hi Chandan,
>> >> >
>> >> > Thank you for the patch! Yet something to improve:
>> >> >
>> >> > [auto build test ERROR on xfs-linux/for-next]
>> >> > [also build test ERROR on v5.16-rc5]
>> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
>> >> > And when submitting patch, we suggest to use '--base' as documented in
>> >> > https://git-scm.com/docs/git-format-patch]
>> >> >
>> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
>> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
>> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
>> >> > reproduce (this is a W=1 build):
>> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> >> >         chmod +x ~/bin/make.cross
>> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>> >> >         git remote add linux-review https://github.com/0day-ci/linux
>> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>> >> >         # save the config file to linux build tree
>> >> >         mkdir build_dir
>> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>> >> >
>> >> > If you fix the issue, kindly add following tag as appropriate
>> >> > Reported-by: kernel test robot <lkp@intel.com>
>> >> >
>> >> > All errors (new ones prefixed by >>):
>> >> >
>> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
>> >> >
>> >> 
>> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
>> >> instead of using the regular division operator. I will include the fix in the
>> >> next version of the patchset.
>> >
>> > So, uh, how did you resolve this in the end?
>> >
>> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
>> >
>> > and
>> >
>> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
>> >
>> > ?
>> 
>> I had made the following changes,
>> 
>> 	maxblocks = maxleafents + minleafrecs - 1;
>> 	do_div(maxblocks, minleafrecs);
>> 
>> and
>> 	maxblocks += minnoderecs - 1;
>> 	do_div(maxblocks, minnoderecs);
>> 
>> roundup_64() would cause maxleafents to have a value >= its previous value
>> right?

Sorry, I meant to say "The result of roundup_64(maxleafents, minleafrecs) will
be >= than maxleafents".

The original statement was,
maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
i.e. maxblocks would contain the number of leaf blocks required to hold
maxleafents number of records.

With maxleafents = 2^48, minleafrecs = minnoderecs = 125,
"maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs" would result in,
maxblocks = (2^48 + 125 - 1) / 125
          = ~2^41

>
> roundup_64 doesn't alter its parameters, if I'm not mistaken:
>
> static inline uint64_t roundup_64(uint64_t x, uint32_t y)
> {
> 	x += y - 1;
> 	do_div(x, y);
> 	return x * y;
> }
>
          
A call to roundup_64(maxleafents, minleafrecs) would result in,
x = 2^48 + 125 - 1
x = do_div((2^48 + 125 - 1), 125) = ~2^41
x = 2^41 * 125 = ~2^48

i.e. maxblocks will not have the number of required leaf blocks.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2022-01-06  7:03               ` Chandan Babu R
  0 siblings, 0 replies; 58+ messages in thread
From: Chandan Babu R @ 2022-01-06  7:03 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3964 bytes --]

On 05 Jan 2022 at 22:51, Darrick J. Wong wrote:
> On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
>> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
>> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
>> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
>> >> > Hi Chandan,
>> >> >
>> >> > Thank you for the patch! Yet something to improve:
>> >> >
>> >> > [auto build test ERROR on xfs-linux/for-next]
>> >> > [also build test ERROR on v5.16-rc5]
>> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
>> >> > And when submitting patch, we suggest to use '--base' as documented in
>> >> > https://git-scm.com/docs/git-format-patch]
>> >> >
>> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
>> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
>> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
>> >> > reproduce (this is a W=1 build):
>> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> >> >         chmod +x ~/bin/make.cross
>> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
>> >> >         git remote add linux-review https://github.com/0day-ci/linux
>> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
>> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
>> >> >         # save the config file to linux build tree
>> >> >         mkdir build_dir
>> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
>> >> >
>> >> > If you fix the issue, kindly add following tag as appropriate
>> >> > Reported-by: kernel test robot <lkp@intel.com>
>> >> >
>> >> > All errors (new ones prefixed by >>):
>> >> >
>> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
>> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
>> >> >
>> >> 
>> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
>> >> instead of using the regular division operator. I will include the fix in the
>> >> next version of the patchset.
>> >
>> > So, uh, how did you resolve this in the end?
>> >
>> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
>> >
>> > and
>> >
>> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
>> >
>> > ?
>> 
>> I had made the following changes,
>> 
>> 	maxblocks = maxleafents + minleafrecs - 1;
>> 	do_div(maxblocks, minleafrecs);
>> 
>> and
>> 	maxblocks += minnoderecs - 1;
>> 	do_div(maxblocks, minnoderecs);
>> 
>> roundup_64() would cause maxleafents to have a value >= its previous value
>> right?

Sorry, I meant to say "The result of roundup_64(maxleafents, minleafrecs) will
be >= than maxleafents".

The original statement was,
maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
i.e. maxblocks would contain the number of leaf blocks required to hold
maxleafents number of records.

With maxleafents = 2^48, minleafrecs = minnoderecs = 125,
"maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs" would result in,
maxblocks = (2^48 + 125 - 1) / 125
          = ~2^41

>
> roundup_64 doesn't alter its parameters, if I'm not mistaken:
>
> static inline uint64_t roundup_64(uint64_t x, uint32_t y)
> {
> 	x += y - 1;
> 	do_div(x, y);
> 	return x * y;
> }
>
          
A call to roundup_64(maxleafents, minleafrecs) would result in,
x = 2^48 + 125 - 1
x = do_div((2^48 + 125 - 1), 125) = ~2^41
x = 2^41 * 125 = ~2^48

i.e. maxblocks will not have the number of required leaf blocks.

-- 
chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
  2022-01-06  7:03               ` Chandan Babu R
@ 2022-01-06 20:31                 ` Darrick J. Wong
  -1 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-06 20:31 UTC (permalink / raw)
  To: Chandan Babu R; +Cc: kernel test robot, linux-xfs, kbuild-all, david

On Thu, Jan 06, 2022 at 12:33:25PM +0530, Chandan Babu R wrote:
> On 05 Jan 2022 at 22:51, Darrick J. Wong wrote:
> > On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
> >> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> >> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> >> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> >> >> > Hi Chandan,
> >> >> >
> >> >> > Thank you for the patch! Yet something to improve:
> >> >> >
> >> >> > [auto build test ERROR on xfs-linux/for-next]
> >> >> > [also build test ERROR on v5.16-rc5]
> >> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> >> >> > And when submitting patch, we suggest to use '--base' as documented in
> >> >> > https://git-scm.com/docs/git-format-patch]
> >> >> >
> >> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> >> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp@intel.com/config)
> >> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> >> >> > reproduce (this is a W=1 build):
> >> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >> >> >         chmod +x ~/bin/make.cross
> >> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >> >> >         git remote add linux-review https://github.com/0day-ci/linux
> >> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >> >> >         # save the config file to linux build tree
> >> >> >         mkdir build_dir
> >> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >> >> >
> >> >> > If you fix the issue, kindly add following tag as appropriate
> >> >> > Reported-by: kernel test robot <lkp@intel.com>
> >> >> >
> >> >> > All errors (new ones prefixed by >>):
> >> >> >
> >> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >> >> >
> >> >> 
> >> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
> >> >> instead of using the regular division operator. I will include the fix in the
> >> >> next version of the patchset.
> >> >
> >> > So, uh, how did you resolve this in the end?
> >> >
> >> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
> >> >
> >> > and
> >> >
> >> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
> >> >
> >> > ?
> >> 
> >> I had made the following changes,
> >> 
> >> 	maxblocks = maxleafents + minleafrecs - 1;
> >> 	do_div(maxblocks, minleafrecs);
> >> 
> >> and
> >> 	maxblocks += minnoderecs - 1;
> >> 	do_div(maxblocks, minnoderecs);
> >> 
> >> roundup_64() would cause maxleafents to have a value >= its previous value
> >> right?
> 
> Sorry, I meant to say "The result of roundup_64(maxleafents, minleafrecs) will
> be >= than maxleafents".
> 
> The original statement was,
> maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
> i.e. maxblocks would contain the number of leaf blocks required to hold
> maxleafents number of records.
> 
> With maxleafents = 2^48, minleafrecs = minnoderecs = 125,
> "maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs" would result in,
> maxblocks = (2^48 + 125 - 1) / 125
>           = ~2^41
> 
> >
> > roundup_64 doesn't alter its parameters, if I'm not mistaken:
> >
> > static inline uint64_t roundup_64(uint64_t x, uint32_t y)
> > {
> > 	x += y - 1;
> > 	do_div(x, y);
> > 	return x * y;
> > }
> >
>           
> A call to roundup_64(maxleafents, minleafrecs) would result in,
> x = 2^48 + 125 - 1
> x = do_div((2^48 + 125 - 1), 125) = ~2^41
> x = 2^41 * 125 = ~2^48
> 
> i.e. maxblocks will not have the number of required leaf blocks.

Arrrgh.  I meant to say "howmany_64", not "roundup_64".  Sorry for
wasting everybody's time. :(

static inline uint64_t howmany_64(uint64_t x, uint32_t y)
{
	x += y - 1;
	do_div(x, y);
	return x;	// <-- we don't multiply by (y)
}

--D

> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
@ 2022-01-06 20:31                 ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2022-01-06 20:31 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4471 bytes --]

On Thu, Jan 06, 2022 at 12:33:25PM +0530, Chandan Babu R wrote:
> On 05 Jan 2022 at 22:51, Darrick J. Wong wrote:
> > On Wed, Jan 05, 2022 at 07:44:23PM +0530, Chandan Babu R wrote:
> >> On 05 Jan 2022 at 05:24, Darrick J. Wong wrote:
> >> > On Wed, Dec 15, 2021 at 02:49:48PM +0530, Chandan Babu R wrote:
> >> >> On 14 Dec 2021 at 20:45, kernel test robot wrote:
> >> >> > Hi Chandan,
> >> >> >
> >> >> > Thank you for the patch! Yet something to improve:
> >> >> >
> >> >> > [auto build test ERROR on xfs-linux/for-next]
> >> >> > [also build test ERROR on v5.16-rc5]
> >> >> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> >> >> > And when submitting patch, we suggest to use '--base' as documented in
> >> >> > https://git-scm.com/docs/git-format-patch]
> >> >> >
> >> >> > url:    https://github.com/0day-ci/linux/commits/Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >> > base:   https://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git for-next
> >> >> > config: microblaze-randconfig-r016-20211214 (https://download.01.org/0day-ci/archive/20211214/202112142335.O3Nu0vQI-lkp(a)intel.com/config)
> >> >> > compiler: microblaze-linux-gcc (GCC) 11.2.0
> >> >> > reproduce (this is a W=1 build):
> >> >> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >> >> >         chmod +x ~/bin/make.cross
> >> >> >         # https://github.com/0day-ci/linux/commit/db28da144803c4262c0d8622d736a7d20952ef6b
> >> >> >         git remote add linux-review https://github.com/0day-ci/linux
> >> >> >         git fetch --no-tags linux-review Chandan-Babu-R/xfs-Extend-per-inode-extent-counters/20211214-164920
> >> >> >         git checkout db28da144803c4262c0d8622d736a7d20952ef6b
> >> >> >         # save the config file to linux build tree
> >> >> >         mkdir build_dir
> >> >> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=microblaze SHELL=/bin/bash
> >> >> >
> >> >> > If you fix the issue, kindly add following tag as appropriate
> >> >> > Reported-by: kernel test robot <lkp@intel.com>
> >> >> >
> >> >> > All errors (new ones prefixed by >>):
> >> >> >
> >> >> >    microblaze-linux-ld: fs/xfs/libxfs/xfs_bmap.o: in function `xfs_bmap_compute_maxlevels':
> >> >> >>> (.text+0x10cc0): undefined reference to `__udivdi3'
> >> >> >
> >> >> 
> >> >> The fix for the compilation error on 32-bit systems involved invoking do_div()
> >> >> instead of using the regular division operator. I will include the fix in the
> >> >> next version of the patchset.
> >> >
> >> > So, uh, how did you resolve this in the end?
> >> >
> >> > 	maxblocks = roundup_64(maxleafents, minleafrecs);
> >> >
> >> > and
> >> >
> >> > 	maxblocks = roundup_64(maxblocks, minnodrecs);
> >> >
> >> > ?
> >> 
> >> I had made the following changes,
> >> 
> >> 	maxblocks = maxleafents + minleafrecs - 1;
> >> 	do_div(maxblocks, minleafrecs);
> >> 
> >> and
> >> 	maxblocks += minnoderecs - 1;
> >> 	do_div(maxblocks, minnoderecs);
> >> 
> >> roundup_64() would cause maxleafents to have a value >= its previous value
> >> right?
> 
> Sorry, I meant to say "The result of roundup_64(maxleafents, minleafrecs) will
> be >= than maxleafents".
> 
> The original statement was,
> maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
> i.e. maxblocks would contain the number of leaf blocks required to hold
> maxleafents number of records.
> 
> With maxleafents = 2^48, minleafrecs = minnoderecs = 125,
> "maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs" would result in,
> maxblocks = (2^48 + 125 - 1) / 125
>           = ~2^41
> 
> >
> > roundup_64 doesn't alter its parameters, if I'm not mistaken:
> >
> > static inline uint64_t roundup_64(uint64_t x, uint32_t y)
> > {
> > 	x += y - 1;
> > 	do_div(x, y);
> > 	return x * y;
> > }
> >
>           
> A call to roundup_64(maxleafents, minleafrecs) would result in,
> x = 2^48 + 125 - 1
> x = do_div((2^48 + 125 - 1), 125) = ~2^41
> x = 2^41 * 125 = ~2^48
> 
> i.e. maxblocks will not have the number of required leaf blocks.

Arrrgh.  I meant to say "howmany_64", not "roundup_64".  Sorry for
wasting everybody's time. :(

static inline uint64_t howmany_64(uint64_t x, uint32_t y)
{
	x += y - 1;
	do_div(x, y);
	return x;	// <-- we don't multiply by (y)
}

--D

> -- 
> chandan

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2022-01-06 20:31 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-14  8:45 [PATCH V4 00/16] xfs: Extend per-inode extent counters Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 01/16] xfs: Move extent count limits to xfs_format.h Chandan Babu R
2022-01-04 23:28   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 02/16] xfs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
2022-01-04 23:30   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 03/16] xfs: Use xfs_extnum_t instead of basic data types Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 04/16] xfs: Introduce xfs_dfork_nextents() helper Chandan Babu R
2022-01-04 23:48   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 05/16] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
2022-01-04 23:50   ` Darrick J. Wong
2022-01-05 13:43     ` Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 06/16] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
2021-12-14 14:54   ` kernel test robot
2021-12-14 14:54     ` kernel test robot
2021-12-14 15:05   ` kernel test robot
2021-12-14 15:05     ` kernel test robot
2021-12-14 15:15   ` kernel test robot
2021-12-14 15:15     ` kernel test robot
2021-12-15  9:19     ` Chandan Babu R
2021-12-15  9:19       ` Chandan Babu R
2022-01-04 23:54       ` Darrick J. Wong
2022-01-04 23:54         ` Darrick J. Wong
2022-01-05 14:14         ` Chandan Babu R
2022-01-05 14:14           ` Chandan Babu R
2022-01-05 17:21           ` Darrick J. Wong
2022-01-05 17:21             ` Darrick J. Wong
2022-01-06  7:03             ` Chandan Babu R
2022-01-06  7:03               ` Chandan Babu R
2022-01-06 20:31               ` Darrick J. Wong
2022-01-06 20:31                 ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 07/16] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
2022-01-05  0:03   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 08/16] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
2022-01-05  0:05   ` Darrick J. Wong
2022-01-05 13:44     ` Chandan Babu R
2022-01-05 17:22       ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 09/16] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
2022-01-05  0:43   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 10/16] xfs: Use xfs_rfsblock_t to count maximum blocks that can be used by BMBT Chandan Babu R
2021-12-14 18:15   ` kernel test robot
2021-12-14 18:15     ` kernel test robot
2021-12-14  8:45 ` [PATCH V4 11/16] xfs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
2022-01-05  0:42   ` Darrick J. Wong
2022-01-05 13:46     ` Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 12/16] xfs: Introduce per-inode 64-bit extent counters Chandan Babu R
2022-01-05  1:04   ` Darrick J. Wong
2022-01-05 13:47     ` Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 13/16] xfs: Conditionally upgrade existing inodes to use " Chandan Babu R
2022-01-05  0:18   ` Darrick J. Wong
2022-01-05 13:49     ` Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 14/16] xfs: Enable bulkstat ioctl to support 64-bit per-inode " Chandan Babu R
2022-01-05  0:28   ` Darrick J. Wong
2022-01-05 13:50     ` Chandan Babu R
2021-12-14  8:45 ` [PATCH V4 15/16] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
2022-01-05  0:47   ` Darrick J. Wong
2021-12-14  8:45 ` [PATCH V4 16/16] xfs: Define max extent length based on on-disk format definition Chandan Babu R
2022-01-05  0:47   ` Darrick J. Wong
2022-01-05 13:51     ` Chandan Babu R

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.