* [PATCH V2 01/12] xfsprogs: Move extent count limits to xfs_format.h
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 02/12] xfsprogs: Rename MAXEXTNUM, MAXAEXTNUM to XFS_IFORK_EXTCNT_MAXS32, XFS_IFORK_EXTCNT_MAXS16 Chandan Babu R
` (10 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
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 <chandanrlinux@gmail.com>
---
libxfs/xfs_format.h | 7 +++++++
libxfs/xfs_types.h | 7 -------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index b7704620c..24277f45a 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1109,6 +1109,13 @@ enum xfs_dinode_fmt {
{ XFS_DINODE_FMT_BTREE, "btree" }, \
{ XFS_DINODE_FMT_UUID, "uuid" }
+/*
+ * Max values for extlen, extnum, aextnum.
+ */
+#define MAXEXTLEN ((uint32_t)0x001fffff) /* 21 bits */
+#define MAXEXTNUM ((int32_t)0x7fffffff) /* signed int */
+#define MAXAEXTNUM ((int16_t)0x7fff) /* signed short */
+
/*
* Inode minimum and maximum sizes.
*/
diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h
index 5c0cc8060..8908346b1 100644
--- a/libxfs/xfs_types.h
+++ b/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] 19+ messages in thread
* [PATCH V2 02/12] xfsprogs: Rename MAXEXTNUM, MAXAEXTNUM to XFS_IFORK_EXTCNT_MAXS32, XFS_IFORK_EXTCNT_MAXS16
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 01/12] xfsprogs: Move extent count limits to xfs_format.h Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 03/12] xfsprogs: Introduce xfs_iext_max() helper Chandan Babu R
` (9 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
In preparation for introducing larger extent count limits, this commit renames
existing extent count limits based on their signedness and width.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
libxfs/xfs_bmap.c | 4 ++--
libxfs/xfs_format.h | 8 ++++----
libxfs/xfs_inode_buf.c | 4 ++--
libxfs/xfs_inode_fork.c | 3 ++-
repair/dinode.c | 4 ++--
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 277727a1a..7927e2712 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -69,10 +69,10 @@ xfs_bmap_compute_maxlevels(
* available.
*/
if (whichfork == XFS_DATA_FORK) {
- maxleafents = MAXEXTNUM;
+ maxleafents = XFS_IFORK_EXTCNT_MAXS32;
sz = xfs_bmdr_space_calc(MINDBTPTRS);
} else {
- maxleafents = MAXAEXTNUM;
+ maxleafents = XFS_IFORK_EXTCNT_MAXS16;
sz = xfs_bmdr_space_calc(MINABTPTRS);
}
maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 24277f45a..84b3aefe2 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1110,11 +1110,11 @@ enum xfs_dinode_fmt {
{ XFS_DINODE_FMT_UUID, "uuid" }
/*
- * Max values for extlen, extnum, aextnum.
+ * Max values for extlen, disk inode's extent counters.
*/
-#define MAXEXTLEN ((uint32_t)0x001fffff) /* 21 bits */
-#define MAXEXTNUM ((int32_t)0x7fffffff) /* signed int */
-#define MAXAEXTNUM ((int16_t)0x7fff) /* signed short */
+#define MAXEXTLEN ((uint32_t)0x1fffff) /* 21 bits */
+#define XFS_IFORK_EXTCNT_MAXS32 ((int32_t)0x7fffffff) /* Signed 32-bits */
+#define XFS_IFORK_EXTCNT_MAXS16 ((int16_t)0x7fff) /* Signed 16-bits */
/*
* Inode minimum and maximum sizes.
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 3d1805e4c..855cb0b85 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -362,9 +362,9 @@ xfs_dinode_verify_fork(
break;
case XFS_DINODE_FMT_BTREE:
if (whichfork == XFS_ATTR_FORK) {
- if (di_nextents > MAXAEXTNUM)
+ if (di_nextents > XFS_IFORK_EXTCNT_MAXS16)
return __this_address;
- } else if (di_nextents > MAXEXTNUM) {
+ } else if (di_nextents > XFS_IFORK_EXTCNT_MAXS32) {
return __this_address;
}
break;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index e3979ceef..36e8bf702 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -734,7 +734,8 @@ xfs_iext_count_may_overflow(
if (whichfork == XFS_COW_FORK)
return 0;
- max_exts = (whichfork == XFS_ATTR_FORK) ? MAXAEXTNUM : MAXEXTNUM;
+ max_exts = (whichfork == XFS_ATTR_FORK) ?
+ XFS_IFORK_EXTCNT_MAXS16 : XFS_IFORK_EXTCNT_MAXS32;
if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
max_exts = 10;
diff --git a/repair/dinode.c b/repair/dinode.c
index ffd409646..45c8174cf 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1831,7 +1831,7 @@ _("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (nextents > MAXEXTNUM) {
+ if (nextents > XFS_IFORK_EXTCNT_MAXS32) {
do_warn(
_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
@@ -1854,7 +1854,7 @@ _("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (anextents > MAXAEXTNUM) {
+ if (anextents > XFS_IFORK_EXTCNT_MAXS16) {
do_warn(
_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 03/12] xfsprogs: Introduce xfs_iext_max() helper
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 01/12] xfsprogs: Move extent count limits to xfs_format.h Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 02/12] xfsprogs: Rename MAXEXTNUM, MAXAEXTNUM to XFS_IFORK_EXTCNT_MAXS32, XFS_IFORK_EXTCNT_MAXS16 Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 04/12] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
` (8 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
xfs_iext_max() 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 <chandanrlinux@gmail.com>
---
libxfs/xfs_bmap.c | 9 ++++-----
libxfs/xfs_inode_buf.c | 8 +++-----
libxfs/xfs_inode_fork.c | 6 +++---
libxfs/xfs_inode_fork.h | 8 ++++++++
repair/dinode.c | 7 ++++---
5 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 7927e2712..608ae5b83 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -68,13 +68,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 = XFS_IFORK_EXTCNT_MAXS32;
+ maxleafents = xfs_iext_max(mp, whichfork);
+ if (whichfork == XFS_DATA_FORK)
sz = xfs_bmdr_space_calc(MINDBTPTRS);
- } else {
- maxleafents = XFS_IFORK_EXTCNT_MAXS16;
+ 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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 855cb0b85..056fe252b 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -340,6 +340,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:
@@ -361,12 +362,9 @@ xfs_dinode_verify_fork(
return __this_address;
break;
case XFS_DINODE_FMT_BTREE:
- if (whichfork == XFS_ATTR_FORK) {
- if (di_nextents > XFS_IFORK_EXTCNT_MAXS16)
- return __this_address;
- } else if (di_nextents > XFS_IFORK_EXTCNT_MAXS32) {
+ max_extents = xfs_iext_max(mp, whichfork);
+ if (di_nextents > max_extents)
return __this_address;
- }
break;
default:
return __this_address;
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 36e8bf702..4cd117382 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -727,6 +727,7 @@ xfs_iext_count_may_overflow(
int whichfork,
int nr_to_add)
{
+ struct xfs_mount *mp = ip->i_mount;
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
uint64_t max_exts;
uint64_t nr_exts;
@@ -734,10 +735,9 @@ xfs_iext_count_may_overflow(
if (whichfork == XFS_COW_FORK)
return 0;
- max_exts = (whichfork == XFS_ATTR_FORK) ?
- XFS_IFORK_EXTCNT_MAXS16 : XFS_IFORK_EXTCNT_MAXS32;
+ max_exts = xfs_iext_max(mp, whichfork);
- if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
+ if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
max_exts = 10;
nr_exts = ifp->if_nextents + nr_to_add;
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index cf82be263..1eda21636 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/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(struct xfs_mount *mp, int whichfork)
+{
+ if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
+ return XFS_IFORK_EXTCNT_MAXS32;
+ else
+ return XFS_IFORK_EXTCNT_MAXS16;
+}
+
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/repair/dinode.c b/repair/dinode.c
index 45c8174cf..a0c5be7c3 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1808,6 +1808,7 @@ _("bad attr fork offset %d in inode %" PRIu64 ", max=%zu\n"),
*/
static int
process_inode_blocks_and_extents(
+ struct xfs_mount *mp,
xfs_dinode_t *dino,
xfs_rfsblock_t nblocks,
uint64_t nextents,
@@ -1831,7 +1832,7 @@ _("bad nblocks %llu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (nextents > XFS_IFORK_EXTCNT_MAXS32) {
+ if (nextents > xfs_iext_max(mp, XFS_DATA_FORK)) {
do_warn(
_("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
@@ -1854,7 +1855,7 @@ _("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
}
}
- if (anextents > XFS_IFORK_EXTCNT_MAXS16) {
+ if (anextents > xfs_iext_max(mp, XFS_ATTR_FORK)) {
do_warn(
_("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
@@ -2961,7 +2962,7 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "),
/*
* correct space counters if required
*/
- if (process_inode_blocks_and_extents(dino, totblocks + atotblocks,
+ if (process_inode_blocks_and_extents(mp, dino, totblocks + atotblocks,
nextents, anextents, lino, dirty) != 0)
goto clear_bad_out;
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 04/12] xfsprogs: Use xfs_extnum_t instead of basic data types
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (2 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 03/12] xfsprogs: Introduce xfs_iext_max() helper Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-27 23:11 ` Darrick J. Wong
2021-07-26 11:47 ` [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
` (7 subsequent siblings)
11 siblings, 1 reply; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
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.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
db/bmap.c | 2 +-
db/frag.c | 2 +-
libxfs/xfs_bmap.c | 2 +-
libxfs/xfs_inode_buf.c | 2 +-
libxfs/xfs_inode_fork.c | 2 +-
repair/dinode.c | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/db/bmap.c b/db/bmap.c
index 5f81d2b52..50f0474bc 100644
--- a/db/bmap.c
+++ b/db/bmap.c
@@ -47,7 +47,7 @@ bmap(
int n;
int nex;
xfs_fsblock_t nextbno;
- int nextents;
+ xfs_extnum_t nextents;
xfs_bmbt_ptr_t *pp;
xfs_bmdr_block_t *rblock;
typnm_t typ;
diff --git a/db/frag.c b/db/frag.c
index 570ad3b74..90fa2131c 100644
--- a/db/frag.c
+++ b/db/frag.c
@@ -273,7 +273,7 @@ process_fork(
int whichfork)
{
extmap_t *extmap;
- int nex;
+ xfs_extnum_t nex;
nex = XFS_DFORK_NEXTENTS(dip, whichfork);
if (!nex)
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index 608ae5b83..dd60d8105 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -46,9 +46,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 */
- uint 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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 056fe252b..b2e8e431a 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -339,7 +339,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/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 4cd117382..48afaaeec 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/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/repair/dinode.c b/repair/dinode.c
index a0c5be7c3..a034b5e86 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -967,7 +967,7 @@ process_exinode(
xfs_bmbt_rec_t *rp;
xfs_fileoff_t first_key;
xfs_fileoff_t last_key;
- int32_t numrecs;
+ xfs_extnum_t numrecs;
int ret;
lino = XFS_AGINO_TO_INO(mp, agno, ino);
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH V2 04/12] xfsprogs: Use xfs_extnum_t instead of basic data types
2021-07-26 11:47 ` [PATCH V2 04/12] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
@ 2021-07-27 23:11 ` Darrick J. Wong
0 siblings, 0 replies; 19+ messages in thread
From: Darrick J. Wong @ 2021-07-27 23:11 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs
On Mon, Jul 26, 2021 at 05:17:16PM +0530, Chandan Babu R wrote:
> 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.
>
> Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
> ---
> db/bmap.c | 2 +-
> db/frag.c | 2 +-
For the db and repair parts,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> libxfs/xfs_bmap.c | 2 +-
> libxfs/xfs_inode_buf.c | 2 +-
> libxfs/xfs_inode_fork.c | 2 +-
> repair/dinode.c | 2 +-
> 6 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/db/bmap.c b/db/bmap.c
> index 5f81d2b52..50f0474bc 100644
> --- a/db/bmap.c
> +++ b/db/bmap.c
> @@ -47,7 +47,7 @@ bmap(
> int n;
> int nex;
> xfs_fsblock_t nextbno;
> - int nextents;
> + xfs_extnum_t nextents;
> xfs_bmbt_ptr_t *pp;
> xfs_bmdr_block_t *rblock;
> typnm_t typ;
> diff --git a/db/frag.c b/db/frag.c
> index 570ad3b74..90fa2131c 100644
> --- a/db/frag.c
> +++ b/db/frag.c
> @@ -273,7 +273,7 @@ process_fork(
> int whichfork)
> {
> extmap_t *extmap;
> - int nex;
> + xfs_extnum_t nex;
>
> nex = XFS_DFORK_NEXTENTS(dip, whichfork);
> if (!nex)
> diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
> index 608ae5b83..dd60d8105 100644
> --- a/libxfs/xfs_bmap.c
> +++ b/libxfs/xfs_bmap.c
> @@ -46,9 +46,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 */
> - uint 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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
> index 056fe252b..b2e8e431a 100644
> --- a/libxfs/xfs_inode_buf.c
> +++ b/libxfs/xfs_inode_buf.c
> @@ -339,7 +339,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/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
> index 4cd117382..48afaaeec 100644
> --- a/libxfs/xfs_inode_fork.c
> +++ b/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/repair/dinode.c b/repair/dinode.c
> index a0c5be7c3..a034b5e86 100644
> --- a/repair/dinode.c
> +++ b/repair/dinode.c
> @@ -967,7 +967,7 @@ process_exinode(
> xfs_bmbt_rec_t *rp;
> xfs_fileoff_t first_key;
> xfs_fileoff_t last_key;
> - int32_t numrecs;
> + xfs_extnum_t numrecs;
> int ret;
>
> lino = XFS_AGINO_TO_INO(mp, agno, ino);
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (3 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 04/12] xfsprogs: Use xfs_extnum_t instead of basic data types Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-27 23:14 ` Darrick J. Wong
2021-07-26 11:47 ` [PATCH V2 06/12] xfsprogs: xfs_dfork_nextents: Return extent count via an out argument Chandan Babu R
` (6 subsequent siblings)
11 siblings, 1 reply; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
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 <chandanrlinux@gmail.com>
---
db/bmap.c | 6 ++--
db/btdump.c | 4 +--
db/check.c | 27 ++++++++++-------
db/frag.c | 6 ++--
db/inode.c | 14 +++++----
db/metadump.c | 4 +--
libxfs/xfs_format.h | 4 ---
libxfs/xfs_inode_buf.c | 43 +++++++++++++++++++++++----
libxfs/xfs_inode_buf.h | 2 ++
libxfs/xfs_inode_fork.c | 11 ++++---
repair/attr_repair.c | 2 +-
repair/bmap_repair.c | 4 +--
repair/dinode.c | 66 ++++++++++++++++++++++++-----------------
repair/prefetch.c | 2 +-
14 files changed, 123 insertions(+), 72 deletions(-)
diff --git a/db/bmap.c b/db/bmap.c
index 50f0474bc..5e1ab9258 100644
--- a/db/bmap.c
+++ b/db/bmap.c
@@ -68,7 +68,7 @@ bmap(
ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS ||
fmt == XFS_DINODE_FMT_BTREE);
if (fmt == XFS_DINODE_FMT_EXTENTS) {
- nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nextents = xfs_dfork_nextents(mp, dip, whichfork);
xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep))
@@ -158,9 +158,9 @@ bmap_f(
push_cur();
set_cur_inode(iocur_top->ino);
dip = iocur_top->data;
- if (be32_to_cpu(dip->di_nextents))
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK))
dfork = 1;
- if (be16_to_cpu(dip->di_anextents))
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
afork = 1;
pop_cur();
}
diff --git a/db/btdump.c b/db/btdump.c
index 920f595b4..59609fd2d 100644
--- a/db/btdump.c
+++ b/db/btdump.c
@@ -166,13 +166,13 @@ dump_inode(
dip = iocur_top->data;
if (attrfork) {
- if (!dip->di_anextents ||
+ if (!xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) ||
dip->di_aformat != XFS_DINODE_FMT_BTREE) {
dbprintf(_("attr fork not in btree format\n"));
return 0;
}
} else {
- if (!dip->di_nextents ||
+ if (!xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) ||
dip->di_format != XFS_DINODE_FMT_BTREE) {
dbprintf(_("data fork not in btree format\n"));
return 0;
diff --git a/db/check.c b/db/check.c
index 0d923e3ae..fe422e0ca 100644
--- a/db/check.c
+++ b/db/check.c
@@ -2720,7 +2720,7 @@ process_exinode(
xfs_bmbt_rec_t *rp;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- *nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ *nex = xfs_dfork_nextents(mp, dip, whichfork);
if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
sizeof(xfs_bmbt_rec_t)) {
if (!sflag || id->ilist)
@@ -2744,12 +2744,14 @@ process_inode(
inodata_t *id = NULL;
xfs_ino_t ino;
xfs_extnum_t nextents = 0;
+ xfs_extnum_t dnextents;
int security;
xfs_rfsblock_t totblocks;
xfs_rfsblock_t totdblocks = 0;
xfs_rfsblock_t totiblocks = 0;
dbm_t type;
xfs_extnum_t anextents = 0;
+ xfs_extnum_t danextents;
xfs_rfsblock_t atotdblocks = 0;
xfs_rfsblock_t atotiblocks = 0;
xfs_qcnt_t bc = 0;
@@ -2878,14 +2880,17 @@ process_inode(
error++;
return;
}
+
+ dnextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
+ danextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+
if (verbose || (id && id->ilist) || CHECK_BLIST(bno))
dbprintf(_("inode %lld mode %#o fmt %s "
"afmt %s "
"nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
id->ino, mode, fmtnames[(int)dip->di_format],
fmtnames[(int)dip->di_aformat],
- be32_to_cpu(dip->di_nextents),
- be16_to_cpu(dip->di_anextents),
+ dnextents, danextents,
be64_to_cpu(dip->di_nblocks), be64_to_cpu(dip->di_size),
diflags & XFS_DIFLAG_REALTIME ? " rt" : "",
diflags & XFS_DIFLAG_PREALLOC ? " pre" : "",
@@ -2903,19 +2908,19 @@ process_inode(
if (xfs_sb_version_hasmetadir(&mp->m_sb) &&
id->ino == mp->m_sb.sb_metadirino)
addlink_inode(id);
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
break;
case S_IFREG:
if (diflags & XFS_DIFLAG_REALTIME)
type = DBM_RTDATA;
else if (id->ino == mp->m_sb.sb_rbmino) {
type = DBM_RTBITMAP;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
if (!xfs_sb_version_hasmetadir(&mp->m_sb))
addlink_inode(id);
} else if (id->ino == mp->m_sb.sb_rsumino) {
type = DBM_RTSUM;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
if (!xfs_sb_version_hasmetadir(&mp->m_sb))
addlink_inode(id);
}
@@ -2923,7 +2928,7 @@ process_inode(
id->ino == mp->m_sb.sb_gquotino ||
id->ino == mp->m_sb.sb_pquotino) {
type = DBM_QUOTA;
- blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
+ blkmap = blkmap_alloc(dnextents);
if (!xfs_sb_version_hasmetadir(&mp->m_sb))
addlink_inode(id);
}
@@ -3006,17 +3011,17 @@ process_inode(
be64_to_cpu(dip->di_nblocks), id->ino, totblocks);
error++;
}
- if (nextents != be32_to_cpu(dip->di_nextents)) {
+ if (nextents != dnextents) {
if (v)
dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
- be32_to_cpu(dip->di_nextents), id->ino, nextents);
+ dnextents, id->ino, nextents);
error++;
}
- if (anextents != be16_to_cpu(dip->di_anextents)) {
+ if (anextents != danextents) {
if (v)
dbprintf(_("bad anextents %d for inode %lld, counted "
"%d\n"),
- be16_to_cpu(dip->di_anextents), id->ino, anextents);
+ danextents, id->ino, anextents);
error++;
}
if (type == DBM_DIR)
diff --git a/db/frag.c b/db/frag.c
index 90fa2131c..3e43a9a21 100644
--- a/db/frag.c
+++ b/db/frag.c
@@ -262,9 +262,11 @@ process_exinode(
int whichfork)
{
xfs_bmbt_rec_t *rp;
+ xfs_extnum_t nextents;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp);
+ nextents = xfs_dfork_nextents(mp, dip, whichfork);
+ process_bmbt_reclist(rp, nextents, extmapp);
}
static void
@@ -275,7 +277,7 @@ process_fork(
extmap_t *extmap;
xfs_extnum_t nex;
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nex = xfs_dfork_nextents(mp, dip, whichfork);
if (!nex)
return;
extmap = extmap_alloc(nex);
diff --git a/db/inode.c b/db/inode.c
index e59cff451..681f4f98a 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -278,7 +278,7 @@ inode_a_bmx_count(
return 0;
ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
- be16_to_cpu(dip->di_anextents) : 0;
+ xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) : 0;
}
static int
@@ -332,6 +332,7 @@ inode_a_size(
{
struct xfs_attr_shortform *asf;
xfs_dinode_t *dip;
+ xfs_extnum_t nextents;
ASSERT(startoff == 0);
ASSERT(idx == 0);
@@ -341,8 +342,8 @@ inode_a_size(
asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
return bitize(be16_to_cpu(asf->hdr.totsize));
case XFS_DINODE_FMT_EXTENTS:
- return (int)be16_to_cpu(dip->di_anextents) *
- bitsz(xfs_bmbt_rec_t);
+ nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ return (int)nextents * bitsz(xfs_bmbt_rec_t);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_ASIZE(dip, mp));
default:
@@ -503,7 +504,7 @@ inode_u_bmx_count(
dip = obj;
ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
- be32_to_cpu(dip->di_nextents) : 0;
+ xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) : 0;
}
static int
@@ -589,6 +590,7 @@ inode_u_size(
int idx)
{
xfs_dinode_t *dip;
+ xfs_extnum_t nextents;
ASSERT(startoff == 0);
ASSERT(idx == 0);
@@ -599,8 +601,8 @@ inode_u_size(
case XFS_DINODE_FMT_LOCAL:
return bitize((int)be64_to_cpu(dip->di_size));
case XFS_DINODE_FMT_EXTENTS:
- return (int)be32_to_cpu(dip->di_nextents) *
- bitsz(xfs_bmbt_rec_t);
+ nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
+ return (int)nextents * bitsz(xfs_bmbt_rec_t);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_DSIZE(dip, mp));
case XFS_DINODE_FMT_UUID:
diff --git a/db/metadump.c b/db/metadump.c
index 332e43a8e..c194501d0 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2314,7 +2314,7 @@ process_exinode(
whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
+ nex = xfs_dfork_nextents(mp, dip, whichfork);
used = nex * sizeof(xfs_bmbt_rec_t);
if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
if (show_warnings)
@@ -2369,7 +2369,7 @@ static int
process_dev_inode(
xfs_dinode_t *dip)
{
- if (XFS_DFORK_NEXTENTS(dip, XFS_DATA_FORK)) {
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK)) {
if (show_warnings)
print_warning("inode %llu has unexpected extents",
(unsigned long long)cur_ino);
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 84b3aefe2..2a5e7e3a3 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1166,10 +1166,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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index b2e8e431a..8d52ce186 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -339,9 +339,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(mp, dip, whichfork);
+
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
case XFS_DINODE_FMT_LOCAL:
/*
@@ -372,6 +374,31 @@ xfs_dinode_verify_fork(
return NULL;
}
+xfs_extnum_t
+xfs_dfork_nextents(
+ struct xfs_mount *mp,
+ struct xfs_dinode *dip,
+ int whichfork)
+{
+ xfs_extnum_t nextents = 0;
+
+ switch (whichfork) {
+ case XFS_DATA_FORK:
+ nextents = be32_to_cpu(dip->di_nextents);
+ break;
+
+ case XFS_ATTR_FORK:
+ nextents = be16_to_cpu(dip->di_anextents);
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ return nextents;
+}
+
static xfs_failaddr_t
xfs_dinode_verify_forkoff(
struct xfs_dinode *dip,
@@ -471,6 +498,8 @@ xfs_dinode_verify(
uint16_t flags;
uint64_t flags2;
uint64_t di_size;
+ uint64_t nblocks;
+ xfs_extnum_t nextents;
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
return __this_address;
@@ -501,10 +530,12 @@ xfs_dinode_verify(
if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
return __this_address;
- /* 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))
+ nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
+ nextents += xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ nblocks = be64_to_cpu(dip->di_nblocks);
+
+ /* Fork checks carried over from xfs_iformat_fork */
+ if (mode && nextents > nblocks)
return __this_address;
if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
@@ -561,7 +592,7 @@ xfs_dinode_verify(
default:
return __this_address;
}
- if (dip->di_anextents)
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
return __this_address;
}
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index a30b76760..ea2c35091 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -36,6 +36,8 @@ xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp,
xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
uint32_t cowextsize, uint16_t mode, uint16_t flags,
uint64_t flags2);
+xfs_extnum_t xfs_dfork_nextents(struct xfs_mount *mp, struct xfs_dinode *dip,
+ int whichfork);
static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
{
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 48afaaeec..831313e3a 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/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(mp, dip, whichfork);
int size = nex * sizeof(xfs_bmbt_rec_t);
struct xfs_iext_cursor icur;
struct xfs_bmbt_rec *dp;
@@ -224,6 +224,7 @@ xfs_iformat_data_fork(
struct xfs_inode *ip,
struct xfs_dinode *dip)
{
+ struct xfs_mount *mp = ip->i_mount;
struct inode *inode = VFS_I(ip);
int error;
@@ -232,7 +233,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_nextents(mp, dip, XFS_DATA_FORK);
switch (inode->i_mode & S_IFMT) {
case S_IFIFO:
@@ -299,14 +300,16 @@ xfs_iformat_attr_fork(
struct xfs_inode *ip,
struct xfs_dinode *dip)
{
+ struct xfs_mount *mp = ip->i_mount;
+ xfs_extnum_t nextents;
int error = 0;
/*
* 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));
+ nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ ip->i_afp = xfs_ifork_alloc(dip->di_aformat, nextents);
switch (ip->i_afp->if_format) {
case XFS_DINODE_FMT_LOCAL:
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index bc3c2bef7..0a461b675 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -1083,7 +1083,7 @@ process_longform_attr(
bno = blkmap_get(blkmap, 0);
if (bno == NULLFSBLOCK) {
if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS &&
- be16_to_cpu(dip->di_anextents) == 0)
+ xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) == 0)
return(0); /* the kernel can handle this state */
do_warn(
_("block 0 of inode %" PRIu64 " attribute fork is missing\n"),
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index 699089791..2e0475db1 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -528,7 +528,7 @@ rebuild_bmap(
*/
switch (whichfork) {
case XFS_DATA_FORK:
- if ((*dinop)->di_nextents == 0)
+ if (!xfs_dfork_nextents(mp, *dinop, XFS_DATA_FORK))
return 0;
(*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
(*dinop)->di_nextents = 0;
@@ -536,7 +536,7 @@ rebuild_bmap(
*dirty = 1;
break;
case XFS_ATTR_FORK:
- if ((*dinop)->di_anextents == 0)
+ if (!xfs_dfork_nextents(mp, *dinop, XFS_ATTR_FORK))
return 0;
(*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
(*dinop)->di_anextents = 0;
diff --git a/repair/dinode.c b/repair/dinode.c
index a034b5e86..6cc5bce5c 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -69,7 +69,7 @@ _("clearing inode %" PRIu64 " attributes\n"), ino_num);
fprintf(stderr,
_("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
- if (be16_to_cpu(dino->di_anextents) != 0) {
+ if (xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK) != 0) {
if (no_modify)
return(1);
dino->di_anextents = cpu_to_be16(0);
@@ -973,7 +973,7 @@ process_exinode(
lino = XFS_AGINO_TO_INO(mp, agno, ino);
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
*tot = 0;
- numrecs = XFS_DFORK_NEXTENTS(dip, whichfork);
+ numrecs = xfs_dfork_nextents(mp, dip, whichfork);
/*
* We've already decided on the maximum number of extents on the inode,
@@ -1050,7 +1050,7 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino)
xfs_fileoff_t expected_offset;
xfs_bmbt_rec_t *rp;
xfs_bmbt_irec_t irec;
- int numrecs;
+ xfs_extnum_t numrecs;
int i;
int max_blocks;
@@ -1072,7 +1072,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
}
rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
- numrecs = be32_to_cpu(dino->di_nextents);
+ numrecs = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
/*
* the max # of extents in a symlink inode is equal to the
@@ -1578,6 +1578,8 @@ process_check_sb_inodes(
int *type,
int *dirty)
{
+ xfs_extnum_t nextents;
+
if (lino == mp->m_sb.sb_rootino) {
if (*type != XR_INO_DIR) {
do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"),
@@ -1632,10 +1634,12 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
do_warn(_("would reset to regular file\n"));
}
}
- if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
+
+ nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
+ if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%u) for realtime summary inode %" PRIu64 "\n"),
- be32_to_cpu(dinoc->di_nextents), lino);
+_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
+ nextents, lino);
return 1;
}
return 0;
@@ -1653,10 +1657,12 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
do_warn(_("would reset to regular file\n"));
}
}
- if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
+
+ nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
+ if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"),
- be32_to_cpu(dinoc->di_nextents), lino);
+_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
+ nextents, lino);
return 1;
}
return 0;
@@ -1816,6 +1822,8 @@ process_inode_blocks_and_extents(
xfs_ino_t lino,
int *dirty)
{
+ xfs_extnum_t dnextents;
+
if (nblocks != be64_to_cpu(dino->di_nblocks)) {
if (!no_modify) {
do_warn(
@@ -1838,20 +1846,19 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
- if (nextents != be32_to_cpu(dino->di_nextents)) {
+
+ dnextents = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
+ if (nextents != dnextents) {
if (!no_modify) {
do_warn(
_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
- lino,
- be32_to_cpu(dino->di_nextents),
- nextents);
+ lino, dnextents, nextents);
dino->di_nextents = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
- be32_to_cpu(dino->di_nextents),
- lino, nextents);
+ dnextents, lino, nextents);
}
}
@@ -1861,19 +1868,19 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
anextents, lino);
return 1;
}
- if (anextents != be16_to_cpu(dino->di_anextents)) {
+
+ dnextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
+ if (anextents != dnextents) {
if (!no_modify) {
do_warn(
_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
- lino,
- be16_to_cpu(dino->di_anextents), anextents);
+ lino, dnextents, anextents);
dino->di_anextents = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
- be16_to_cpu(dino->di_anextents),
- lino, anextents);
+ dnextents, lino, anextents);
}
}
@@ -1910,8 +1917,8 @@ process_inode_data_fork(
{
struct xfs_dinode *dino = *dinop;
xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
+ xfs_extnum_t nex;
int err = 0;
- int nex;
int try_rebuild = -1; /* don't know yet */
retry:
@@ -1920,7 +1927,7 @@ retry:
* uses negative values in memory. hence if we see negative numbers
* here, trash it!
*/
- nex = be32_to_cpu(dino->di_nextents);
+ nex = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
if (nex < 0)
*nextents = 1;
else
@@ -1970,8 +1977,7 @@ _("rebuilding inode %"PRIu64" data fork\n"),
lino);
try_rebuild = 0;
err = rebuild_bmap(mp, lino, XFS_DATA_FORK,
- be32_to_cpu(dino->di_nextents),
- ino_bpp, dinop, dirty);
+ nex, ino_bpp, dinop, dirty);
dino = *dinop;
if (!err)
goto retry;
@@ -2070,7 +2076,7 @@ retry:
return 0;
}
- *anextents = be16_to_cpu(dino->di_anextents);
+ *anextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
if (*anextents > be64_to_cpu(dino->di_nblocks))
*anextents = 1;
@@ -2118,13 +2124,17 @@ retry:
if (!no_modify) {
if (try_rebuild == 1) {
+ xfs_extnum_t danextents;
+
+ danextents = xfs_dfork_nextents(mp, dino,
+ XFS_ATTR_FORK);
do_warn(
_("rebuilding inode %"PRIu64" attr fork\n"),
lino);
try_rebuild = 0;
err = rebuild_bmap(mp, lino, XFS_ATTR_FORK,
- be16_to_cpu(dino->di_anextents),
- ino_bpp, dinop, dirty);
+ danextents, ino_bpp, dinop,
+ dirty);
dino = *dinop;
if (!err)
goto retry;
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 9e5ced94a..b8d11ead0 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -393,7 +393,7 @@ pf_read_exinode(
xfs_dinode_t *dino)
{
pf_read_bmbt_reclist(args, (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino),
- be32_to_cpu(dino->di_nextents));
+ xfs_dfork_nextents(mp, dino, XFS_DATA_FORK));
}
static void
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper
2021-07-26 11:47 ` [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
@ 2021-07-27 23:14 ` Darrick J. Wong
2021-07-28 7:34 ` Chandan Babu R
0 siblings, 1 reply; 19+ messages in thread
From: Darrick J. Wong @ 2021-07-27 23:14 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs
On Mon, Jul 26, 2021 at 05:17:17PM +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 <chandanrlinux@gmail.com>
> ---
> db/bmap.c | 6 ++--
> db/btdump.c | 4 +--
> db/check.c | 27 ++++++++++-------
> db/frag.c | 6 ++--
> db/inode.c | 14 +++++----
> db/metadump.c | 4 +--
> libxfs/xfs_format.h | 4 ---
> libxfs/xfs_inode_buf.c | 43 +++++++++++++++++++++++----
> libxfs/xfs_inode_buf.h | 2 ++
> libxfs/xfs_inode_fork.c | 11 ++++---
> repair/attr_repair.c | 2 +-
> repair/bmap_repair.c | 4 +--
> repair/dinode.c | 66 ++++++++++++++++++++++++-----------------
> repair/prefetch.c | 2 +-
> 14 files changed, 123 insertions(+), 72 deletions(-)
>
> diff --git a/db/bmap.c b/db/bmap.c
> index 50f0474bc..5e1ab9258 100644
> --- a/db/bmap.c
> +++ b/db/bmap.c
> @@ -68,7 +68,7 @@ bmap(
> ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS ||
> fmt == XFS_DINODE_FMT_BTREE);
> if (fmt == XFS_DINODE_FMT_EXTENTS) {
> - nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
> + nextents = xfs_dfork_nextents(mp, dip, whichfork);
> xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
> for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
> if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep))
> @@ -158,9 +158,9 @@ bmap_f(
> push_cur();
> set_cur_inode(iocur_top->ino);
> dip = iocur_top->data;
> - if (be32_to_cpu(dip->di_nextents))
> + if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK))
> dfork = 1;
> - if (be16_to_cpu(dip->di_anextents))
> + if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
> afork = 1;
> pop_cur();
> }
> diff --git a/db/btdump.c b/db/btdump.c
> index 920f595b4..59609fd2d 100644
> --- a/db/btdump.c
> +++ b/db/btdump.c
> @@ -166,13 +166,13 @@ dump_inode(
>
> dip = iocur_top->data;
> if (attrfork) {
> - if (!dip->di_anextents ||
> + if (!xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) ||
> dip->di_aformat != XFS_DINODE_FMT_BTREE) {
> dbprintf(_("attr fork not in btree format\n"));
> return 0;
> }
> } else {
> - if (!dip->di_nextents ||
> + if (!xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) ||
> dip->di_format != XFS_DINODE_FMT_BTREE) {
> dbprintf(_("data fork not in btree format\n"));
> return 0;
> diff --git a/db/check.c b/db/check.c
> index 0d923e3ae..fe422e0ca 100644
> --- a/db/check.c
> +++ b/db/check.c
> @@ -2720,7 +2720,7 @@ process_exinode(
> xfs_bmbt_rec_t *rp;
>
> rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
> - *nex = XFS_DFORK_NEXTENTS(dip, whichfork);
> + *nex = xfs_dfork_nextents(mp, dip, whichfork);
> if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
> sizeof(xfs_bmbt_rec_t)) {
> if (!sflag || id->ilist)
> @@ -2744,12 +2744,14 @@ process_inode(
> inodata_t *id = NULL;
> xfs_ino_t ino;
> xfs_extnum_t nextents = 0;
> + xfs_extnum_t dnextents;
> int security;
> xfs_rfsblock_t totblocks;
> xfs_rfsblock_t totdblocks = 0;
> xfs_rfsblock_t totiblocks = 0;
> dbm_t type;
> xfs_extnum_t anextents = 0;
> + xfs_extnum_t danextents;
> xfs_rfsblock_t atotdblocks = 0;
> xfs_rfsblock_t atotiblocks = 0;
> xfs_qcnt_t bc = 0;
> @@ -2878,14 +2880,17 @@ process_inode(
> error++;
> return;
> }
> +
> + dnextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
> + danextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
> +
> if (verbose || (id && id->ilist) || CHECK_BLIST(bno))
> dbprintf(_("inode %lld mode %#o fmt %s "
> "afmt %s "
> "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
> id->ino, mode, fmtnames[(int)dip->di_format],
> fmtnames[(int)dip->di_aformat],
> - be32_to_cpu(dip->di_nextents),
> - be16_to_cpu(dip->di_anextents),
> + dnextents, danextents,
> be64_to_cpu(dip->di_nblocks), be64_to_cpu(dip->di_size),
> diflags & XFS_DIFLAG_REALTIME ? " rt" : "",
> diflags & XFS_DIFLAG_PREALLOC ? " pre" : "",
> @@ -2903,19 +2908,19 @@ process_inode(
> if (xfs_sb_version_hasmetadir(&mp->m_sb) &&
> id->ino == mp->m_sb.sb_metadirino)
> addlink_inode(id);
> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
> + blkmap = blkmap_alloc(dnextents);
> break;
> case S_IFREG:
> if (diflags & XFS_DIFLAG_REALTIME)
> type = DBM_RTDATA;
> else if (id->ino == mp->m_sb.sb_rbmino) {
> type = DBM_RTBITMAP;
> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
> + blkmap = blkmap_alloc(dnextents);
> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
> addlink_inode(id);
> } else if (id->ino == mp->m_sb.sb_rsumino) {
> type = DBM_RTSUM;
> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
> + blkmap = blkmap_alloc(dnextents);
> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
> addlink_inode(id);
> }
> @@ -2923,7 +2928,7 @@ process_inode(
> id->ino == mp->m_sb.sb_gquotino ||
> id->ino == mp->m_sb.sb_pquotino) {
> type = DBM_QUOTA;
> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
> + blkmap = blkmap_alloc(dnextents);
> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
> addlink_inode(id);
> }
> @@ -3006,17 +3011,17 @@ process_inode(
> be64_to_cpu(dip->di_nblocks), id->ino, totblocks);
> error++;
> }
> - if (nextents != be32_to_cpu(dip->di_nextents)) {
> + if (nextents != dnextents) {
> if (v)
> dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
> - be32_to_cpu(dip->di_nextents), id->ino, nextents);
> + dnextents, id->ino, nextents);
> error++;
> }
> - if (anextents != be16_to_cpu(dip->di_anextents)) {
> + if (anextents != danextents) {
> if (v)
> dbprintf(_("bad anextents %d for inode %lld, counted "
> "%d\n"),
> - be16_to_cpu(dip->di_anextents), id->ino, anextents);
> + danextents, id->ino, anextents);
> error++;
> }
> if (type == DBM_DIR)
> diff --git a/db/frag.c b/db/frag.c
> index 90fa2131c..3e43a9a21 100644
> --- a/db/frag.c
> +++ b/db/frag.c
> @@ -262,9 +262,11 @@ process_exinode(
> int whichfork)
> {
> xfs_bmbt_rec_t *rp;
> + xfs_extnum_t nextents;
>
> rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
> - process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp);
> + nextents = xfs_dfork_nextents(mp, dip, whichfork);
> + process_bmbt_reclist(rp, nextents, extmapp);
> }
>
> static void
> @@ -275,7 +277,7 @@ process_fork(
> extmap_t *extmap;
> xfs_extnum_t nex;
>
> - nex = XFS_DFORK_NEXTENTS(dip, whichfork);
> + nex = xfs_dfork_nextents(mp, dip, whichfork);
> if (!nex)
> return;
> extmap = extmap_alloc(nex);
> diff --git a/db/inode.c b/db/inode.c
> index e59cff451..681f4f98a 100644
> --- a/db/inode.c
> +++ b/db/inode.c
> @@ -278,7 +278,7 @@ inode_a_bmx_count(
> return 0;
> ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
> return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
> - be16_to_cpu(dip->di_anextents) : 0;
> + xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) : 0;
> }
>
> static int
> @@ -332,6 +332,7 @@ inode_a_size(
> {
> struct xfs_attr_shortform *asf;
> xfs_dinode_t *dip;
> + xfs_extnum_t nextents;
>
> ASSERT(startoff == 0);
> ASSERT(idx == 0);
> @@ -341,8 +342,8 @@ inode_a_size(
> asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
> return bitize(be16_to_cpu(asf->hdr.totsize));
> case XFS_DINODE_FMT_EXTENTS:
> - return (int)be16_to_cpu(dip->di_anextents) *
> - bitsz(xfs_bmbt_rec_t);
> + nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
> + return (int)nextents * bitsz(xfs_bmbt_rec_t);
I think you can drop the cast (and convert the typedef) her.
> case XFS_DINODE_FMT_BTREE:
> return bitize((int)XFS_DFORK_ASIZE(dip, mp));
> default:
> @@ -503,7 +504,7 @@ inode_u_bmx_count(
> dip = obj;
> ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
> return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
> - be32_to_cpu(dip->di_nextents) : 0;
> + xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) : 0;
> }
>
> static int
> @@ -589,6 +590,7 @@ inode_u_size(
> int idx)
> {
> xfs_dinode_t *dip;
> + xfs_extnum_t nextents;
>
> ASSERT(startoff == 0);
> ASSERT(idx == 0);
> @@ -599,8 +601,8 @@ inode_u_size(
> case XFS_DINODE_FMT_LOCAL:
> return bitize((int)be64_to_cpu(dip->di_size));
> case XFS_DINODE_FMT_EXTENTS:
> - return (int)be32_to_cpu(dip->di_nextents) *
> - bitsz(xfs_bmbt_rec_t);
> + nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
> + return (int)nextents * bitsz(xfs_bmbt_rec_t);
...and here.
The rest of the db/repair changes look good.
--D
> case XFS_DINODE_FMT_BTREE:
> return bitize((int)XFS_DFORK_DSIZE(dip, mp));
> case XFS_DINODE_FMT_UUID:
> diff --git a/db/metadump.c b/db/metadump.c
> index 332e43a8e..c194501d0 100644
> --- a/db/metadump.c
> +++ b/db/metadump.c
> @@ -2314,7 +2314,7 @@ process_exinode(
>
> whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
>
> - nex = XFS_DFORK_NEXTENTS(dip, whichfork);
> + nex = xfs_dfork_nextents(mp, dip, whichfork);
> used = nex * sizeof(xfs_bmbt_rec_t);
> if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
> if (show_warnings)
> @@ -2369,7 +2369,7 @@ static int
> process_dev_inode(
> xfs_dinode_t *dip)
> {
> - if (XFS_DFORK_NEXTENTS(dip, XFS_DATA_FORK)) {
> + if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK)) {
> if (show_warnings)
> print_warning("inode %llu has unexpected extents",
> (unsigned long long)cur_ino);
> diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
> index 84b3aefe2..2a5e7e3a3 100644
> --- a/libxfs/xfs_format.h
> +++ b/libxfs/xfs_format.h
> @@ -1166,10 +1166,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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
> index b2e8e431a..8d52ce186 100644
> --- a/libxfs/xfs_inode_buf.c
> +++ b/libxfs/xfs_inode_buf.c
> @@ -339,9 +339,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(mp, dip, whichfork);
> +
> switch (XFS_DFORK_FORMAT(dip, whichfork)) {
> case XFS_DINODE_FMT_LOCAL:
> /*
> @@ -372,6 +374,31 @@ xfs_dinode_verify_fork(
> return NULL;
> }
>
> +xfs_extnum_t
> +xfs_dfork_nextents(
> + struct xfs_mount *mp,
> + struct xfs_dinode *dip,
> + int whichfork)
> +{
> + xfs_extnum_t nextents = 0;
> +
> + switch (whichfork) {
> + case XFS_DATA_FORK:
> + nextents = be32_to_cpu(dip->di_nextents);
> + break;
> +
> + case XFS_ATTR_FORK:
> + nextents = be16_to_cpu(dip->di_anextents);
> + break;
> +
> + default:
> + ASSERT(0);
> + break;
> + }
> +
> + return nextents;
> +}
> +
> static xfs_failaddr_t
> xfs_dinode_verify_forkoff(
> struct xfs_dinode *dip,
> @@ -471,6 +498,8 @@ xfs_dinode_verify(
> uint16_t flags;
> uint64_t flags2;
> uint64_t di_size;
> + uint64_t nblocks;
> + xfs_extnum_t nextents;
>
> if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
> return __this_address;
> @@ -501,10 +530,12 @@ xfs_dinode_verify(
> if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
> return __this_address;
>
> - /* 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))
> + nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
> + nextents += xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
> + nblocks = be64_to_cpu(dip->di_nblocks);
> +
> + /* Fork checks carried over from xfs_iformat_fork */
> + if (mode && nextents > nblocks)
> return __this_address;
>
> if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
> @@ -561,7 +592,7 @@ xfs_dinode_verify(
> default:
> return __this_address;
> }
> - if (dip->di_anextents)
> + if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
> return __this_address;
> }
>
> diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
> index a30b76760..ea2c35091 100644
> --- a/libxfs/xfs_inode_buf.h
> +++ b/libxfs/xfs_inode_buf.h
> @@ -36,6 +36,8 @@ xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp,
> xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
> uint32_t cowextsize, uint16_t mode, uint16_t flags,
> uint64_t flags2);
> +xfs_extnum_t xfs_dfork_nextents(struct xfs_mount *mp, struct xfs_dinode *dip,
> + int whichfork);
>
> static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
> {
> diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
> index 48afaaeec..831313e3a 100644
> --- a/libxfs/xfs_inode_fork.c
> +++ b/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(mp, dip, whichfork);
> int size = nex * sizeof(xfs_bmbt_rec_t);
> struct xfs_iext_cursor icur;
> struct xfs_bmbt_rec *dp;
> @@ -224,6 +224,7 @@ xfs_iformat_data_fork(
> struct xfs_inode *ip,
> struct xfs_dinode *dip)
> {
> + struct xfs_mount *mp = ip->i_mount;
> struct inode *inode = VFS_I(ip);
> int error;
>
> @@ -232,7 +233,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_nextents(mp, dip, XFS_DATA_FORK);
>
> switch (inode->i_mode & S_IFMT) {
> case S_IFIFO:
> @@ -299,14 +300,16 @@ xfs_iformat_attr_fork(
> struct xfs_inode *ip,
> struct xfs_dinode *dip)
> {
> + struct xfs_mount *mp = ip->i_mount;
> + xfs_extnum_t nextents;
> int error = 0;
>
> /*
> * 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));
> + nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
> + ip->i_afp = xfs_ifork_alloc(dip->di_aformat, nextents);
>
> switch (ip->i_afp->if_format) {
> case XFS_DINODE_FMT_LOCAL:
> diff --git a/repair/attr_repair.c b/repair/attr_repair.c
> index bc3c2bef7..0a461b675 100644
> --- a/repair/attr_repair.c
> +++ b/repair/attr_repair.c
> @@ -1083,7 +1083,7 @@ process_longform_attr(
> bno = blkmap_get(blkmap, 0);
> if (bno == NULLFSBLOCK) {
> if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS &&
> - be16_to_cpu(dip->di_anextents) == 0)
> + xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) == 0)
> return(0); /* the kernel can handle this state */
> do_warn(
> _("block 0 of inode %" PRIu64 " attribute fork is missing\n"),
> diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
> index 699089791..2e0475db1 100644
> --- a/repair/bmap_repair.c
> +++ b/repair/bmap_repair.c
> @@ -528,7 +528,7 @@ rebuild_bmap(
> */
> switch (whichfork) {
> case XFS_DATA_FORK:
> - if ((*dinop)->di_nextents == 0)
> + if (!xfs_dfork_nextents(mp, *dinop, XFS_DATA_FORK))
> return 0;
> (*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
> (*dinop)->di_nextents = 0;
> @@ -536,7 +536,7 @@ rebuild_bmap(
> *dirty = 1;
> break;
> case XFS_ATTR_FORK:
> - if ((*dinop)->di_anextents == 0)
> + if (!xfs_dfork_nextents(mp, *dinop, XFS_ATTR_FORK))
> return 0;
> (*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
> (*dinop)->di_anextents = 0;
> diff --git a/repair/dinode.c b/repair/dinode.c
> index a034b5e86..6cc5bce5c 100644
> --- a/repair/dinode.c
> +++ b/repair/dinode.c
> @@ -69,7 +69,7 @@ _("clearing inode %" PRIu64 " attributes\n"), ino_num);
> fprintf(stderr,
> _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
>
> - if (be16_to_cpu(dino->di_anextents) != 0) {
> + if (xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK) != 0) {
> if (no_modify)
> return(1);
> dino->di_anextents = cpu_to_be16(0);
> @@ -973,7 +973,7 @@ process_exinode(
> lino = XFS_AGINO_TO_INO(mp, agno, ino);
> rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
> *tot = 0;
> - numrecs = XFS_DFORK_NEXTENTS(dip, whichfork);
> + numrecs = xfs_dfork_nextents(mp, dip, whichfork);
>
> /*
> * We've already decided on the maximum number of extents on the inode,
> @@ -1050,7 +1050,7 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino)
> xfs_fileoff_t expected_offset;
> xfs_bmbt_rec_t *rp;
> xfs_bmbt_irec_t irec;
> - int numrecs;
> + xfs_extnum_t numrecs;
> int i;
> int max_blocks;
>
> @@ -1072,7 +1072,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
> }
>
> rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
> - numrecs = be32_to_cpu(dino->di_nextents);
> + numrecs = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
>
> /*
> * the max # of extents in a symlink inode is equal to the
> @@ -1578,6 +1578,8 @@ process_check_sb_inodes(
> int *type,
> int *dirty)
> {
> + xfs_extnum_t nextents;
> +
> if (lino == mp->m_sb.sb_rootino) {
> if (*type != XR_INO_DIR) {
> do_warn(_("root inode %" PRIu64 " has bad type 0x%x\n"),
> @@ -1632,10 +1634,12 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
> do_warn(_("would reset to regular file\n"));
> }
> }
> - if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
> +
> + nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
> + if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
> do_warn(
> -_("bad # of extents (%u) for realtime summary inode %" PRIu64 "\n"),
> - be32_to_cpu(dinoc->di_nextents), lino);
> +_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
> + nextents, lino);
> return 1;
> }
> return 0;
> @@ -1653,10 +1657,12 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
> do_warn(_("would reset to regular file\n"));
> }
> }
> - if (mp->m_sb.sb_rblocks == 0 && dinoc->di_nextents != 0) {
> +
> + nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
> + if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
> do_warn(
> -_("bad # of extents (%u) for realtime bitmap inode %" PRIu64 "\n"),
> - be32_to_cpu(dinoc->di_nextents), lino);
> +_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
> + nextents, lino);
> return 1;
> }
> return 0;
> @@ -1816,6 +1822,8 @@ process_inode_blocks_and_extents(
> xfs_ino_t lino,
> int *dirty)
> {
> + xfs_extnum_t dnextents;
> +
> if (nblocks != be64_to_cpu(dino->di_nblocks)) {
> if (!no_modify) {
> do_warn(
> @@ -1838,20 +1846,19 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> nextents, lino);
> return 1;
> }
> - if (nextents != be32_to_cpu(dino->di_nextents)) {
> +
> + dnextents = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
> + if (nextents != dnextents) {
> if (!no_modify) {
> do_warn(
> _("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
> - lino,
> - be32_to_cpu(dino->di_nextents),
> - nextents);
> + lino, dnextents, nextents);
> dino->di_nextents = cpu_to_be32(nextents);
> *dirty = 1;
> } else {
> do_warn(
> _("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> - be32_to_cpu(dino->di_nextents),
> - lino, nextents);
> + dnextents, lino, nextents);
> }
> }
>
> @@ -1861,19 +1868,19 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> anextents, lino);
> return 1;
> }
> - if (anextents != be16_to_cpu(dino->di_anextents)) {
> +
> + dnextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
> + if (anextents != dnextents) {
> if (!no_modify) {
> do_warn(
> _("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
> - lino,
> - be16_to_cpu(dino->di_anextents), anextents);
> + lino, dnextents, anextents);
> dino->di_anextents = cpu_to_be16(anextents);
> *dirty = 1;
> } else {
> do_warn(
> _("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> - be16_to_cpu(dino->di_anextents),
> - lino, anextents);
> + dnextents, lino, anextents);
> }
> }
>
> @@ -1910,8 +1917,8 @@ process_inode_data_fork(
> {
> struct xfs_dinode *dino = *dinop;
> xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
> + xfs_extnum_t nex;
> int err = 0;
> - int nex;
> int try_rebuild = -1; /* don't know yet */
>
> retry:
> @@ -1920,7 +1927,7 @@ retry:
> * uses negative values in memory. hence if we see negative numbers
> * here, trash it!
> */
> - nex = be32_to_cpu(dino->di_nextents);
> + nex = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
> if (nex < 0)
> *nextents = 1;
> else
> @@ -1970,8 +1977,7 @@ _("rebuilding inode %"PRIu64" data fork\n"),
> lino);
> try_rebuild = 0;
> err = rebuild_bmap(mp, lino, XFS_DATA_FORK,
> - be32_to_cpu(dino->di_nextents),
> - ino_bpp, dinop, dirty);
> + nex, ino_bpp, dinop, dirty);
> dino = *dinop;
> if (!err)
> goto retry;
> @@ -2070,7 +2076,7 @@ retry:
> return 0;
> }
>
> - *anextents = be16_to_cpu(dino->di_anextents);
> + *anextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
> if (*anextents > be64_to_cpu(dino->di_nblocks))
> *anextents = 1;
>
> @@ -2118,13 +2124,17 @@ retry:
>
> if (!no_modify) {
> if (try_rebuild == 1) {
> + xfs_extnum_t danextents;
> +
> + danextents = xfs_dfork_nextents(mp, dino,
> + XFS_ATTR_FORK);
> do_warn(
> _("rebuilding inode %"PRIu64" attr fork\n"),
> lino);
> try_rebuild = 0;
> err = rebuild_bmap(mp, lino, XFS_ATTR_FORK,
> - be16_to_cpu(dino->di_anextents),
> - ino_bpp, dinop, dirty);
> + danextents, ino_bpp, dinop,
> + dirty);
> dino = *dinop;
> if (!err)
> goto retry;
> diff --git a/repair/prefetch.c b/repair/prefetch.c
> index 9e5ced94a..b8d11ead0 100644
> --- a/repair/prefetch.c
> +++ b/repair/prefetch.c
> @@ -393,7 +393,7 @@ pf_read_exinode(
> xfs_dinode_t *dino)
> {
> pf_read_bmbt_reclist(args, (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino),
> - be32_to_cpu(dino->di_nextents));
> + xfs_dfork_nextents(mp, dino, XFS_DATA_FORK));
> }
>
> static void
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper
2021-07-27 23:14 ` Darrick J. Wong
@ 2021-07-28 7:34 ` Chandan Babu R
0 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-28 7:34 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 28 Jul 2021 at 04:44, Darrick J. Wong wrote:
> On Mon, Jul 26, 2021 at 05:17:17PM +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 <chandanrlinux@gmail.com>
>> ---
>> db/bmap.c | 6 ++--
>> db/btdump.c | 4 +--
>> db/check.c | 27 ++++++++++-------
>> db/frag.c | 6 ++--
>> db/inode.c | 14 +++++----
>> db/metadump.c | 4 +--
>> libxfs/xfs_format.h | 4 ---
>> libxfs/xfs_inode_buf.c | 43 +++++++++++++++++++++++----
>> libxfs/xfs_inode_buf.h | 2 ++
>> libxfs/xfs_inode_fork.c | 11 ++++---
>> repair/attr_repair.c | 2 +-
>> repair/bmap_repair.c | 4 +--
>> repair/dinode.c | 66 ++++++++++++++++++++++++-----------------
>> repair/prefetch.c | 2 +-
>> 14 files changed, 123 insertions(+), 72 deletions(-)
>>
>> diff --git a/db/bmap.c b/db/bmap.c
>> index 50f0474bc..5e1ab9258 100644
>> --- a/db/bmap.c
>> +++ b/db/bmap.c
>> @@ -68,7 +68,7 @@ bmap(
>> ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS ||
>> fmt == XFS_DINODE_FMT_BTREE);
>> if (fmt == XFS_DINODE_FMT_EXTENTS) {
>> - nextents = XFS_DFORK_NEXTENTS(dip, whichfork);
>> + nextents = xfs_dfork_nextents(mp, dip, whichfork);
>> xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
>> for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
>> if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep))
>> @@ -158,9 +158,9 @@ bmap_f(
>> push_cur();
>> set_cur_inode(iocur_top->ino);
>> dip = iocur_top->data;
>> - if (be32_to_cpu(dip->di_nextents))
>> + if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK))
>> dfork = 1;
>> - if (be16_to_cpu(dip->di_anextents))
>> + if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
>> afork = 1;
>> pop_cur();
>> }
>> diff --git a/db/btdump.c b/db/btdump.c
>> index 920f595b4..59609fd2d 100644
>> --- a/db/btdump.c
>> +++ b/db/btdump.c
>> @@ -166,13 +166,13 @@ dump_inode(
>>
>> dip = iocur_top->data;
>> if (attrfork) {
>> - if (!dip->di_anextents ||
>> + if (!xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) ||
>> dip->di_aformat != XFS_DINODE_FMT_BTREE) {
>> dbprintf(_("attr fork not in btree format\n"));
>> return 0;
>> }
>> } else {
>> - if (!dip->di_nextents ||
>> + if (!xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) ||
>> dip->di_format != XFS_DINODE_FMT_BTREE) {
>> dbprintf(_("data fork not in btree format\n"));
>> return 0;
>> diff --git a/db/check.c b/db/check.c
>> index 0d923e3ae..fe422e0ca 100644
>> --- a/db/check.c
>> +++ b/db/check.c
>> @@ -2720,7 +2720,7 @@ process_exinode(
>> xfs_bmbt_rec_t *rp;
>>
>> rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
>> - *nex = XFS_DFORK_NEXTENTS(dip, whichfork);
>> + *nex = xfs_dfork_nextents(mp, dip, whichfork);
>> if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
>> sizeof(xfs_bmbt_rec_t)) {
>> if (!sflag || id->ilist)
>> @@ -2744,12 +2744,14 @@ process_inode(
>> inodata_t *id = NULL;
>> xfs_ino_t ino;
>> xfs_extnum_t nextents = 0;
>> + xfs_extnum_t dnextents;
>> int security;
>> xfs_rfsblock_t totblocks;
>> xfs_rfsblock_t totdblocks = 0;
>> xfs_rfsblock_t totiblocks = 0;
>> dbm_t type;
>> xfs_extnum_t anextents = 0;
>> + xfs_extnum_t danextents;
>> xfs_rfsblock_t atotdblocks = 0;
>> xfs_rfsblock_t atotiblocks = 0;
>> xfs_qcnt_t bc = 0;
>> @@ -2878,14 +2880,17 @@ process_inode(
>> error++;
>> return;
>> }
>> +
>> + dnextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
>> + danextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
>> +
>> if (verbose || (id && id->ilist) || CHECK_BLIST(bno))
>> dbprintf(_("inode %lld mode %#o fmt %s "
>> "afmt %s "
>> "nex %d anex %d nblk %lld sz %lld%s%s%s%s%s%s%s\n"),
>> id->ino, mode, fmtnames[(int)dip->di_format],
>> fmtnames[(int)dip->di_aformat],
>> - be32_to_cpu(dip->di_nextents),
>> - be16_to_cpu(dip->di_anextents),
>> + dnextents, danextents,
>> be64_to_cpu(dip->di_nblocks), be64_to_cpu(dip->di_size),
>> diflags & XFS_DIFLAG_REALTIME ? " rt" : "",
>> diflags & XFS_DIFLAG_PREALLOC ? " pre" : "",
>> @@ -2903,19 +2908,19 @@ process_inode(
>> if (xfs_sb_version_hasmetadir(&mp->m_sb) &&
>> id->ino == mp->m_sb.sb_metadirino)
>> addlink_inode(id);
>> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
>> + blkmap = blkmap_alloc(dnextents);
>> break;
>> case S_IFREG:
>> if (diflags & XFS_DIFLAG_REALTIME)
>> type = DBM_RTDATA;
>> else if (id->ino == mp->m_sb.sb_rbmino) {
>> type = DBM_RTBITMAP;
>> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
>> + blkmap = blkmap_alloc(dnextents);
>> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
>> addlink_inode(id);
>> } else if (id->ino == mp->m_sb.sb_rsumino) {
>> type = DBM_RTSUM;
>> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
>> + blkmap = blkmap_alloc(dnextents);
>> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
>> addlink_inode(id);
>> }
>> @@ -2923,7 +2928,7 @@ process_inode(
>> id->ino == mp->m_sb.sb_gquotino ||
>> id->ino == mp->m_sb.sb_pquotino) {
>> type = DBM_QUOTA;
>> - blkmap = blkmap_alloc(be32_to_cpu(dip->di_nextents));
>> + blkmap = blkmap_alloc(dnextents);
>> if (!xfs_sb_version_hasmetadir(&mp->m_sb))
>> addlink_inode(id);
>> }
>> @@ -3006,17 +3011,17 @@ process_inode(
>> be64_to_cpu(dip->di_nblocks), id->ino, totblocks);
>> error++;
>> }
>> - if (nextents != be32_to_cpu(dip->di_nextents)) {
>> + if (nextents != dnextents) {
>> if (v)
>> dbprintf(_("bad nextents %d for inode %lld, counted %d\n"),
>> - be32_to_cpu(dip->di_nextents), id->ino, nextents);
>> + dnextents, id->ino, nextents);
>> error++;
>> }
>> - if (anextents != be16_to_cpu(dip->di_anextents)) {
>> + if (anextents != danextents) {
>> if (v)
>> dbprintf(_("bad anextents %d for inode %lld, counted "
>> "%d\n"),
>> - be16_to_cpu(dip->di_anextents), id->ino, anextents);
>> + danextents, id->ino, anextents);
>> error++;
>> }
>> if (type == DBM_DIR)
>> diff --git a/db/frag.c b/db/frag.c
>> index 90fa2131c..3e43a9a21 100644
>> --- a/db/frag.c
>> +++ b/db/frag.c
>> @@ -262,9 +262,11 @@ process_exinode(
>> int whichfork)
>> {
>> xfs_bmbt_rec_t *rp;
>> + xfs_extnum_t nextents;
>>
>> rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
>> - process_bmbt_reclist(rp, XFS_DFORK_NEXTENTS(dip, whichfork), extmapp);
>> + nextents = xfs_dfork_nextents(mp, dip, whichfork);
>> + process_bmbt_reclist(rp, nextents, extmapp);
>> }
>>
>> static void
>> @@ -275,7 +277,7 @@ process_fork(
>> extmap_t *extmap;
>> xfs_extnum_t nex;
>>
>> - nex = XFS_DFORK_NEXTENTS(dip, whichfork);
>> + nex = xfs_dfork_nextents(mp, dip, whichfork);
>> if (!nex)
>> return;
>> extmap = extmap_alloc(nex);
>> diff --git a/db/inode.c b/db/inode.c
>> index e59cff451..681f4f98a 100644
>> --- a/db/inode.c
>> +++ b/db/inode.c
>> @@ -278,7 +278,7 @@ inode_a_bmx_count(
>> return 0;
>> ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
>> return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
>> - be16_to_cpu(dip->di_anextents) : 0;
>> + xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) : 0;
>> }
>>
>> static int
>> @@ -332,6 +332,7 @@ inode_a_size(
>> {
>> struct xfs_attr_shortform *asf;
>> xfs_dinode_t *dip;
>> + xfs_extnum_t nextents;
>>
>> ASSERT(startoff == 0);
>> ASSERT(idx == 0);
>> @@ -341,8 +342,8 @@ inode_a_size(
>> asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
>> return bitize(be16_to_cpu(asf->hdr.totsize));
>> case XFS_DINODE_FMT_EXTENTS:
>> - return (int)be16_to_cpu(dip->di_anextents) *
>> - bitsz(xfs_bmbt_rec_t);
>> + nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
>> + return (int)nextents * bitsz(xfs_bmbt_rec_t);
>
> I think you can drop the cast (and convert the typedef) her.
>
>> case XFS_DINODE_FMT_BTREE:
>> return bitize((int)XFS_DFORK_ASIZE(dip, mp));
>> default:
>> @@ -503,7 +504,7 @@ inode_u_bmx_count(
>> dip = obj;
>> ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
>> return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
>> - be32_to_cpu(dip->di_nextents) : 0;
>> + xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) : 0;
>> }
>>
>> static int
>> @@ -589,6 +590,7 @@ inode_u_size(
>> int idx)
>> {
>> xfs_dinode_t *dip;
>> + xfs_extnum_t nextents;
>>
>> ASSERT(startoff == 0);
>> ASSERT(idx == 0);
>> @@ -599,8 +601,8 @@ inode_u_size(
>> case XFS_DINODE_FMT_LOCAL:
>> return bitize((int)be64_to_cpu(dip->di_size));
>> case XFS_DINODE_FMT_EXTENTS:
>> - return (int)be32_to_cpu(dip->di_nextents) *
>> - bitsz(xfs_bmbt_rec_t);
>> + nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
>> + return (int)nextents * bitsz(xfs_bmbt_rec_t);
>
> ...and here.
>
Ok. I will apply the two review comments before posting the next version.
> The rest of the db/repair changes look good.
>
> --D
--
chandan
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 06/12] xfsprogs: xfs_dfork_nextents: Return extent count via an out argument
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (4 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 05/12] xfsprogs: Introduce xfs_dfork_nextents() helper Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 07/12] xfsprogs: Rename inode's extent counter fields based on their width Chandan Babu R
` (5 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
This commit changes xfs_dfork_nextents() to return an error code. The extent
count itself is now returned through an out argument. This facility will be
used by a future commit to indicate an inconsistent ondisk extent count.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
db/bmap.c | 19 +++++++++-----
db/btdump.c | 11 +++++---
db/check.c | 23 ++++++++++++++---
db/frag.c | 7 ++---
db/inode.c | 28 +++++++++++++++-----
db/metadump.c | 12 +++++++--
libxfs/xfs_inode_buf.c | 29 +++++++++++++--------
libxfs/xfs_inode_buf.h | 4 +--
libxfs/xfs_inode_fork.c | 26 ++++++++++++++-----
repair/attr_repair.c | 11 +++++---
repair/bmap_repair.c | 12 +++++++--
repair/dinode.c | 57 +++++++++++++++++++++++++++++++----------
repair/prefetch.c | 7 +++--
13 files changed, 181 insertions(+), 65 deletions(-)
diff --git a/db/bmap.c b/db/bmap.c
index 5e1ab9258..5846e2c83 100644
--- a/db/bmap.c
+++ b/db/bmap.c
@@ -68,11 +68,13 @@ bmap(
ASSERT(fmt == XFS_DINODE_FMT_LOCAL || fmt == XFS_DINODE_FMT_EXTENTS ||
fmt == XFS_DINODE_FMT_BTREE);
if (fmt == XFS_DINODE_FMT_EXTENTS) {
- nextents = xfs_dfork_nextents(mp, dip, whichfork);
- xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
- if (!bmap_one_extent(ep, &curoffset, eoffset, &n, bep))
- break;
+ if (!xfs_dfork_nextents(mp, dip, whichfork, &nextents)) {
+ xp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
+ for (ep = xp; ep < &xp[nextents] && n < nex; ep++) {
+ if (!bmap_one_extent(ep, &curoffset, eoffset,
+ &n, bep))
+ break;
+ }
}
} else if (fmt == XFS_DINODE_FMT_BTREE) {
push_cur();
@@ -155,12 +157,15 @@ bmap_f(
}
}
if (afork + dfork == 0) {
+ xfs_extnum_t nextents;
push_cur();
set_cur_inode(iocur_top->ino);
dip = iocur_top->data;
- if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK))
+ if (!xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents) &&
+ nextents)
dfork = 1;
- if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
+ if (!xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &nextents) &&
+ nextents)
afork = 1;
pop_cur();
}
diff --git a/db/btdump.c b/db/btdump.c
index 59609fd2d..b1d16d919 100644
--- a/db/btdump.c
+++ b/db/btdump.c
@@ -153,6 +153,7 @@ dump_inode(
bool dump_node_blocks,
bool attrfork)
{
+ xfs_extnum_t nextents;
char *prefix;
struct xfs_dinode *dip;
int ret = 0;
@@ -166,14 +167,16 @@ dump_inode(
dip = iocur_top->data;
if (attrfork) {
- if (!xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) ||
- dip->di_aformat != XFS_DINODE_FMT_BTREE) {
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &nextents))
+ return -1;
+ if (!nextents || dip->di_aformat != XFS_DINODE_FMT_BTREE) {
dbprintf(_("attr fork not in btree format\n"));
return 0;
}
} else {
- if (!xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) ||
- dip->di_format != XFS_DINODE_FMT_BTREE) {
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents))
+ return -1;
+ if (!nextents || dip->di_format != XFS_DINODE_FMT_BTREE) {
dbprintf(_("data fork not in btree format\n"));
return 0;
}
diff --git a/db/check.c b/db/check.c
index fe422e0ca..45aaa8445 100644
--- a/db/check.c
+++ b/db/check.c
@@ -2718,10 +2718,17 @@ process_exinode(
int whichfork)
{
xfs_bmbt_rec_t *rp;
+ int ret;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- *nex = xfs_dfork_nextents(mp, dip, whichfork);
- if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
+ ret = xfs_dfork_nextents(mp, dip, whichfork, nex);
+ if (ret) {
+ if (!sflag || id->ilist)
+ dbprintf(_("Corrupt extent count for inode %lld\n"),
+ id->ino);
+ error++;
+ return;
+ } else if (*nex < 0 || *nex > XFS_DFORK_SIZE(dip, mp, whichfork) /
sizeof(xfs_bmbt_rec_t)) {
if (!sflag || id->ilist)
dbprintf(_("bad number of extents %d for inode %lld\n"),
@@ -2881,8 +2888,16 @@ process_inode(
return;
}
- dnextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
- danextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &dnextents)) {
+ if (v)
+ dbprintf(_("Corrupt extent count for inode %lld\n"),
+ id->ino);
+ error++;
+ return;
+ }
+
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &danextents))
+ ASSERT(0);
if (verbose || (id && id->ilist) || CHECK_BLIST(bno))
dbprintf(_("inode %lld mode %#o fmt %s "
diff --git a/db/frag.c b/db/frag.c
index 3e43a9a21..f1816b32f 100644
--- a/db/frag.c
+++ b/db/frag.c
@@ -263,9 +263,11 @@ process_exinode(
{
xfs_bmbt_rec_t *rp;
xfs_extnum_t nextents;
+ int error;
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
- nextents = xfs_dfork_nextents(mp, dip, whichfork);
+ error = xfs_dfork_nextents(mp, dip, whichfork, &nextents);
+ ASSERT(error == 0);
process_bmbt_reclist(rp, nextents, extmapp);
}
@@ -277,8 +279,7 @@ process_fork(
extmap_t *extmap;
xfs_extnum_t nex;
- nex = xfs_dfork_nextents(mp, dip, whichfork);
- if (!nex)
+ if (xfs_dfork_nextents(mp, dip, whichfork, &nex) || !nex)
return;
extmap = extmap_alloc(nex);
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
diff --git a/db/inode.c b/db/inode.c
index 681f4f98a..e3b7d04c0 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -269,6 +269,7 @@ inode_a_bmx_count(
void *obj,
int startoff)
{
+ xfs_extnum_t nextents;
xfs_dinode_t *dip;
ASSERT(bitoffs(startoff) == 0);
@@ -277,8 +278,13 @@ inode_a_bmx_count(
if (!dip->di_forkoff)
return 0;
ASSERT((char *)XFS_DFORK_APTR(dip) - (char *)dip == byteize(startoff));
- return dip->di_aformat == XFS_DINODE_FMT_EXTENTS ?
- xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) : 0;
+
+ if (dip->di_aformat != XFS_DINODE_FMT_EXTENTS ||
+ xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &nextents)) {
+ nextents = 0;
+ }
+
+ return nextents;
}
static int
@@ -342,7 +348,8 @@ inode_a_size(
asf = (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
return bitize(be16_to_cpu(asf->hdr.totsize));
case XFS_DINODE_FMT_EXTENTS:
- nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &nextents))
+ nextents = 0;
return (int)nextents * bitsz(xfs_bmbt_rec_t);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_ASIZE(dip, mp));
@@ -497,14 +504,20 @@ inode_u_bmx_count(
void *obj,
int startoff)
{
+ xfs_extnum_t nextents;
xfs_dinode_t *dip;
ASSERT(bitoffs(startoff) == 0);
ASSERT(obj == iocur_top->data);
dip = obj;
ASSERT((char *)XFS_DFORK_DPTR(dip) - (char *)dip == byteize(startoff));
- return dip->di_format == XFS_DINODE_FMT_EXTENTS ?
- xfs_dfork_nextents(mp, dip, XFS_DATA_FORK) : 0;
+
+ if (dip->di_format != XFS_DINODE_FMT_EXTENTS ||
+ xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents)) {
+ nextents = 0;
+ }
+
+ return nextents;
}
static int
@@ -590,7 +603,7 @@ inode_u_size(
int idx)
{
xfs_dinode_t *dip;
- xfs_extnum_t nextents;
+ xfs_extnum_t nextents = 0;
ASSERT(startoff == 0);
ASSERT(idx == 0);
@@ -601,7 +614,8 @@ inode_u_size(
case XFS_DINODE_FMT_LOCAL:
return bitize((int)be64_to_cpu(dip->di_size));
case XFS_DINODE_FMT_EXTENTS:
- nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents))
+ nextents = 0;
return (int)nextents * bitsz(xfs_bmbt_rec_t);
case XFS_DINODE_FMT_BTREE:
return bitize((int)XFS_DFORK_DSIZE(dip, mp));
diff --git a/db/metadump.c b/db/metadump.c
index c194501d0..1b63b3179 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -2314,7 +2314,13 @@ process_exinode(
whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK;
- nex = xfs_dfork_nextents(mp, dip, whichfork);
+ if (xfs_dfork_nextents(mp, dip, whichfork, &nex)) {
+ if (show_warnings)
+ print_warning("Corrupt extent count for inode %lld\n",
+ (long long)cur_ino);
+ return 1;
+ }
+
used = nex * sizeof(xfs_bmbt_rec_t);
if (nex < 0 || used > XFS_DFORK_SIZE(dip, mp, whichfork)) {
if (show_warnings)
@@ -2369,7 +2375,9 @@ static int
process_dev_inode(
xfs_dinode_t *dip)
{
- if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK)) {
+ xfs_extnum_t nextents;
+
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents) || nextents) {
if (show_warnings)
print_warning("inode %llu has unexpected extents",
(unsigned long long)cur_ino);
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 8d52ce186..353050365 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -342,7 +342,8 @@ xfs_dinode_verify_fork(
xfs_extnum_t di_nextents;
xfs_extnum_t max_extents;
- di_nextents = xfs_dfork_nextents(mp, dip, whichfork);
+ if (xfs_dfork_nextents(mp, dip, whichfork, &di_nextents))
+ return __this_address;
switch (XFS_DFORK_FORMAT(dip, whichfork)) {
case XFS_DINODE_FMT_LOCAL:
@@ -374,29 +375,31 @@ xfs_dinode_verify_fork(
return NULL;
}
-xfs_extnum_t
+int
xfs_dfork_nextents(
struct xfs_mount *mp,
struct xfs_dinode *dip,
- int whichfork)
+ int whichfork,
+ xfs_extnum_t *nextents)
{
- xfs_extnum_t nextents = 0;
+ int error = 0;
switch (whichfork) {
case XFS_DATA_FORK:
- nextents = be32_to_cpu(dip->di_nextents);
+ *nextents = be32_to_cpu(dip->di_nextents);
break;
case XFS_ATTR_FORK:
- nextents = be16_to_cpu(dip->di_anextents);
+ *nextents = be16_to_cpu(dip->di_anextents);
break;
default:
ASSERT(0);
+ error = -EINVAL;
break;
}
- return nextents;
+ return error;
}
static xfs_failaddr_t
@@ -500,6 +503,7 @@ xfs_dinode_verify(
uint64_t di_size;
uint64_t nblocks;
xfs_extnum_t nextents;
+ xfs_extnum_t naextents;
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
return __this_address;
@@ -530,8 +534,13 @@ xfs_dinode_verify(
if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
return __this_address;
- nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
- nextents += xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
+ if (xfs_dfork_nextents(mp, dip, XFS_DATA_FORK, &nextents))
+ return __this_address;
+
+ if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &naextents))
+ return __this_address;
+
+ nextents += naextents;
nblocks = be64_to_cpu(dip->di_nblocks);
/* Fork checks carried over from xfs_iformat_fork */
@@ -592,7 +601,7 @@ xfs_dinode_verify(
default:
return __this_address;
}
- if (xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK))
+ if (naextents)
return __this_address;
}
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index ea2c35091..20f796610 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -36,8 +36,8 @@ xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp,
xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
uint32_t cowextsize, uint16_t mode, uint16_t flags,
uint64_t flags2);
-xfs_extnum_t xfs_dfork_nextents(struct xfs_mount *mp, struct xfs_dinode *dip,
- int whichfork);
+int xfs_dfork_nextents(struct xfs_mount *mp, struct xfs_dinode *dip,
+ int whichfork, xfs_extnum_t *nextents);
static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
{
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 831313e3a..699bac823 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -105,12 +105,19 @@ 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(mp, dip, whichfork);
- int size = nex * sizeof(xfs_bmbt_rec_t);
+ xfs_extnum_t nex;
+ int size;
struct xfs_iext_cursor icur;
struct xfs_bmbt_rec *dp;
struct xfs_bmbt_irec new;
- int i;
+ int error;
+ xfs_extnum_t i;
+
+ error = xfs_dfork_nextents(mp, dip, whichfork, &nex);
+ if (error)
+ return error;
+
+ size = nex * sizeof(xfs_bmbt_rec_t);
/*
* If the number of extents is unreasonable, then something is wrong and
@@ -233,7 +240,11 @@ xfs_iformat_data_fork(
* depend on it.
*/
ip->i_df.if_format = dip->di_format;
- ip->i_df.if_nextents = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK);
+
+ error = xfs_dfork_nextents(mp, dip, XFS_DATA_FORK,
+ &ip->i_df.if_nextents);
+ if (error)
+ return error;
switch (inode->i_mode & S_IFMT) {
case S_IFIFO:
@@ -304,11 +315,14 @@ xfs_iformat_attr_fork(
xfs_extnum_t nextents;
int error = 0;
- /*
+ error = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK, &nextents);
+ if (error)
+ return error;
+
+ /*
* Initialize the extent count early, as the per-format routines may
* depend on it.
*/
- nextents = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK);
ip->i_afp = xfs_ifork_alloc(dip->di_aformat, nextents);
switch (ip->i_afp->if_format) {
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index 0a461b675..c6c30210f 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -1073,6 +1073,7 @@ process_longform_attr(
struct blkmap *blkmap,
int *repair) /* out - 1 if something was fixed */
{
+ xfs_extnum_t anextents;
xfs_fsblock_t bno;
struct xfs_buf *bp;
struct xfs_da_blkinfo *info;
@@ -1082,9 +1083,13 @@ process_longform_attr(
bno = blkmap_get(blkmap, 0);
if (bno == NULLFSBLOCK) {
- if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS &&
- xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK) == 0)
- return(0); /* the kernel can handle this state */
+ if (dip->di_aformat == XFS_DINODE_FMT_EXTENTS) {
+ error = xfs_dfork_nextents(mp, dip, XFS_ATTR_FORK,
+ &anextents);
+ ASSERT(error == 0);
+ if (anextents == 0)
+ return(0); /* the kernel can handle this state */
+ }
do_warn(
_("block 0 of inode %" PRIu64 " attribute fork is missing\n"),
ino);
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index 2e0475db1..84f3a7048 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -14,6 +14,7 @@
#include "rmap.h"
#include "bulkload.h"
#include "bmap_repair.h"
+#include "xfs_inode_buf.h"
#define min_t(type, x, y) ( ((type)(x)) > ((type)(y)) ? ((type)(y)) : ((type)(x)) )
@@ -516,6 +517,7 @@ rebuild_bmap(
struct xfs_buf *bp;
unsigned long long resblks;
xfs_daddr_t bp_bn;
+ xfs_extnum_t nextents;
int bp_length;
int error;
@@ -528,7 +530,10 @@ rebuild_bmap(
*/
switch (whichfork) {
case XFS_DATA_FORK:
- if (!xfs_dfork_nextents(mp, *dinop, XFS_DATA_FORK))
+ error = xfs_dfork_nextents(mp, *dinop, whichfork, &nextents);
+ if (error)
+ return error;
+ if (nextents == 0)
return 0;
(*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
(*dinop)->di_nextents = 0;
@@ -536,7 +541,10 @@ rebuild_bmap(
*dirty = 1;
break;
case XFS_ATTR_FORK:
- if (!xfs_dfork_nextents(mp, *dinop, XFS_ATTR_FORK))
+ error = xfs_dfork_nextents(mp, *dinop, whichfork, &nextents);
+ if (error)
+ return error;
+ if (nextents == 0)
return 0;
(*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
(*dinop)->di_anextents = 0;
diff --git a/repair/dinode.c b/repair/dinode.c
index 6cc5bce5c..096335191 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -60,6 +60,9 @@ get_forkname(int whichfork)
static int
clear_dinode_attr(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
{
+ xfs_extnum_t anextents;
+ int err;
+
ASSERT(dino->di_forkoff != 0);
if (!no_modify)
@@ -69,7 +72,10 @@ _("clearing inode %" PRIu64 " attributes\n"), ino_num);
fprintf(stderr,
_("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
- if (xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK) != 0) {
+ err = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK, &anextents);
+ ASSERT(err == 0);
+
+ if (anextents != 0) {
if (no_modify)
return(1);
dino->di_anextents = cpu_to_be16(0);
@@ -973,7 +979,8 @@ process_exinode(
lino = XFS_AGINO_TO_INO(mp, agno, ino);
rp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, whichfork);
*tot = 0;
- numrecs = xfs_dfork_nextents(mp, dip, whichfork);
+ ret = xfs_dfork_nextents(mp, dip, whichfork, &numrecs);
+ ASSERT(ret == 0);
/*
* We've already decided on the maximum number of extents on the inode,
@@ -1053,6 +1060,7 @@ process_symlink_extlist(xfs_mount_t *mp, xfs_ino_t lino, xfs_dinode_t *dino)
xfs_extnum_t numrecs;
int i;
int max_blocks;
+ int ret;
if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
if (dino->di_format == XFS_DINODE_FMT_LOCAL)
@@ -1072,7 +1080,8 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
}
rp = (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino);
- numrecs = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
+ ret = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK, &numrecs);
+ ASSERT(ret == 0);
/*
* the max # of extents in a symlink inode is equal to the
@@ -1579,6 +1588,7 @@ process_check_sb_inodes(
int *dirty)
{
xfs_extnum_t nextents;
+ int ret;
if (lino == mp->m_sb.sb_rootino) {
if (*type != XR_INO_DIR) {
@@ -1635,7 +1645,9 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
}
}
- nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
+ ret = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK, &nextents);
+ ASSERT(ret == 0);
+
if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
@@ -1658,8 +1670,10 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
}
}
- nextents = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK);
- if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
+ ret = xfs_dfork_nextents(mp, dinoc, XFS_DATA_FORK, &nextents);
+ ASSERT(ret == 0);
+
+ if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
nextents, lino);
@@ -1823,6 +1837,7 @@ process_inode_blocks_and_extents(
int *dirty)
{
xfs_extnum_t dnextents;
+ int ret;
if (nblocks != be64_to_cpu(dino->di_nblocks)) {
if (!no_modify) {
@@ -1847,7 +1862,9 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
return 1;
}
- dnextents = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
+ ret = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK, &dnextents);
+ ASSERT(ret == 0);
+
if (nextents != dnextents) {
if (!no_modify) {
do_warn(
@@ -1869,7 +1886,9 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
return 1;
}
- dnextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
+ ret = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK, &dnextents);
+ ASSERT(ret == 0);
+
if (anextents != dnextents) {
if (!no_modify) {
do_warn(
@@ -1920,6 +1939,7 @@ process_inode_data_fork(
xfs_extnum_t nex;
int err = 0;
int try_rebuild = -1; /* don't know yet */
+ int ret;
retry:
/*
@@ -1927,7 +1947,9 @@ retry:
* uses negative values in memory. hence if we see negative numbers
* here, trash it!
*/
- nex = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK);
+ ret = xfs_dfork_nextents(mp, dino, XFS_DATA_FORK, &nex);
+ ASSERT(ret == 0);
+
if (nex < 0)
*nextents = 1;
else
@@ -2076,8 +2098,11 @@ retry:
return 0;
}
- *anextents = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK);
- if (*anextents > be64_to_cpu(dino->di_nblocks))
+ err = xfs_dfork_nextents(mp, dino, XFS_ATTR_FORK,
+ (xfs_extnum_t *)anextents);
+ ASSERT(err == 0);
+
+ if (*anextents > be64_to_cpu(dino->di_nblocks))
*anextents = 1;
switch (dino->di_aformat) {
@@ -2126,8 +2151,10 @@ retry:
if (try_rebuild == 1) {
xfs_extnum_t danextents;
- danextents = xfs_dfork_nextents(mp, dino,
- XFS_ATTR_FORK);
+ err = xfs_dfork_nextents(mp, dino,
+ XFS_ATTR_FORK, &danextents);
+ ASSERT(err == 0);
+
do_warn(
_("rebuilding inode %"PRIu64" attr fork\n"),
lino);
@@ -2831,6 +2858,10 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
goto clear_bad_out;
}
+ if (xfs_dfork_nextents(mp, dino, XFS_DATA_FORK,
+ (xfs_extnum_t *)&nextents))
+ goto clear_bad_out;
+
/*
* type checks for superblock inodes
*/
diff --git a/repair/prefetch.c b/repair/prefetch.c
index b8d11ead0..5ba0ecaa9 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -392,8 +392,11 @@ pf_read_exinode(
prefetch_args_t *args,
xfs_dinode_t *dino)
{
- pf_read_bmbt_reclist(args, (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino),
- xfs_dfork_nextents(mp, dino, XFS_DATA_FORK));
+ xfs_extnum_t nextents;
+
+ if (!xfs_dfork_nextents(mp, dino, XFS_DATA_FORK, &nextents))
+ pf_read_bmbt_reclist(args,
+ (xfs_bmbt_rec_t *)XFS_DFORK_DPTR(dino), nextents);
}
static void
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 07/12] xfsprogs: Rename inode's extent counter fields based on their width
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (5 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 06/12] xfsprogs: xfs_dfork_nextents: Return extent count via an out argument Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 08/12] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
` (4 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
This commit renames extent counter fields in "struct xfs_dinode" and "struct
xfs_log_dinode" based on the width of the fields. As of this commit, the
32-bit field will be used to count data fork extents and the 16-bit field will
be used to count attr fork extents.
This change is done to enable a future commit to introduce a new 64-bit extent
counter field.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
db/inode.c | 4 ++--
libxfs/xfs_format.h | 4 ++--
libxfs/xfs_inode_buf.c | 8 ++++----
libxfs/xfs_log_format.h | 4 ++--
logprint/log_misc.c | 4 ++--
logprint/log_print_all.c | 2 +-
repair/bmap_repair.c | 4 ++--
repair/dinode.c | 6 +++---
8 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/db/inode.c b/db/inode.c
index e3b7d04c0..27251f02f 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -100,8 +100,8 @@ const field_t inode_core_flds[] = {
{ "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
{ "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
{ "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
- { "nextents", FLDT_EXTNUM, OI(COFF(nextents)), C1, 0, TYP_NONE },
- { "naextents", FLDT_AEXTNUM, OI(COFF(anextents)), C1, 0, TYP_NONE },
+ { "nextents32", FLDT_EXTNUM, OI(COFF(nextents32)), C1, 0, TYP_NONE },
+ { "nextents16", FLDT_AEXTNUM, OI(COFF(nextents16)), C1, 0, TYP_NONE },
{ "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
{ "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
{ "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 2a5e7e3a3..6564bc135 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1039,8 +1039,8 @@ typedef struct xfs_dinode {
__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*/
+ __be32 di_nextents32; /* 32-bit extent counter */
+ __be16 di_nextents16; /* 16-bit extent counter */
__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/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 353050365..95fd95cc0 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -310,8 +310,8 @@ 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_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
+ to->di_nextents16 = 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);
@@ -386,11 +386,11 @@ xfs_dfork_nextents(
switch (whichfork) {
case XFS_DATA_FORK:
- *nextents = be32_to_cpu(dip->di_nextents);
+ *nextents = be32_to_cpu(dip->di_nextents32);
break;
case XFS_ATTR_FORK:
- *nextents = be16_to_cpu(dip->di_anextents);
+ *nextents = be16_to_cpu(dip->di_nextents16);
break;
default:
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index 0c888f921..ca8e4ad83 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -402,8 +402,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_nextents32; /* number of extents in data fork */
+ uint16_t di_nextents16; /* 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 */
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index c06fd233b..4e8760c43 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -452,9 +452,9 @@ xlog_print_trans_inode_core(
xlog_extract_dinode_ts(ip->di_ctime));
printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
(unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
- ip->di_extsize, ip->di_nextents);
+ ip->di_extsize, ip->di_nextents32);
printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
- ip->di_anextents, (int)ip->di_forkoff, ip->di_dmevmask,
+ ip->di_nextents16, (int)ip->di_forkoff, ip->di_dmevmask,
ip->di_dmstate);
printf(_("flags 0x%x gen 0x%x\n"),
ip->di_flags, ip->di_gen);
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 37669372e..403c56372 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -257,7 +257,7 @@ xlog_recover_print_inode_core(
printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
"nextents:%d anextents:%d\n"), (unsigned long long)
di->di_size, (unsigned long long)di->di_nblocks,
- di->di_extsize, di->di_nextents, (int)di->di_anextents);
+ di->di_extsize, di->di_nextents32, (int)di->di_nextents16);
printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
"gen:%u\n"),
(int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index 84f3a7048..f41a18f00 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -536,7 +536,7 @@ rebuild_bmap(
if (nextents == 0)
return 0;
(*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
- (*dinop)->di_nextents = 0;
+ (*dinop)->di_nextents32 = 0;
libxfs_dinode_calc_crc(mp, *dinop);
*dirty = 1;
break;
@@ -547,7 +547,7 @@ rebuild_bmap(
if (nextents == 0)
return 0;
(*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
- (*dinop)->di_anextents = 0;
+ (*dinop)->di_nextents16 = 0;
libxfs_dinode_calc_crc(mp, *dinop);
*dirty = 1;
break;
diff --git a/repair/dinode.c b/repair/dinode.c
index 096335191..efff83ef9 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -78,7 +78,7 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
if (anextents != 0) {
if (no_modify)
return(1);
- dino->di_anextents = cpu_to_be16(0);
+ dino->di_nextents16 = cpu_to_be16(0);
}
if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
@@ -1870,7 +1870,7 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
lino, dnextents, nextents);
- dino->di_nextents = cpu_to_be32(nextents);
+ dino->di_nextents32 = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
@@ -1894,7 +1894,7 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
lino, dnextents, anextents);
- dino->di_anextents = cpu_to_be16(anextents);
+ dino->di_nextents16 = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 08/12] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (6 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 07/12] xfsprogs: Rename inode's extent counter fields based on their width Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-27 23:15 ` Darrick J. Wong
2021-07-26 11:47 ` [PATCH V2 09/12] xfsprogs: Rename XFS_IOC_BULKSTAT to XFS_IOC_BULKSTAT_V5 Chandan Babu R
` (3 subsequent siblings)
11 siblings, 1 reply; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
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 <chandanrlinux@gmail.com>
---
libxfs/xfs_inode_fork.c | 2 +-
libxfs/xfs_types.h | 4 ++--
repair/dinode.c | 20 ++++++++++----------
repair/dinode.h | 4 ++--
repair/scan.c | 6 +++---
5 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 699bac823..8e2da89c7 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -124,7 +124,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 %Lu ((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/libxfs/xfs_types.h b/libxfs/xfs_types.h
index 8908346b1..584fa61e3 100644
--- a/libxfs/xfs_types.h
+++ b/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/repair/dinode.c b/repair/dinode.c
index efff83ef9..beeb9ed07 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -357,7 +357,7 @@ static int
process_bmbt_reclist_int(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -680,7 +680,7 @@ int
process_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -703,7 +703,7 @@ int
scan_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -1089,7 +1089,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
*/
if (numrecs > max_symlink_blocks) {
do_warn(
-_("bad number of extents (%d) in symlink %" PRIu64 " data fork\n"),
+_("bad number of extents (%lu) in symlink %" PRIu64 " data fork\n"),
numrecs, lino);
return(1);
}
@@ -1650,7 +1650,7 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
+_("bad # of extents (%lu) for realtime summary inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
@@ -1675,7 +1675,7 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
do_warn(
-_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
+_("bad # of extents (%lu) for realtime bitmap inode %" PRIu64 "\n"),
nextents, lino);
return 1;
}
@@ -1868,13 +1868,13 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
if (nextents != dnextents) {
if (!no_modify) {
do_warn(
-_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
+_("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, nextents);
dino->di_nextents32 = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
-_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
+_("bad nextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
dnextents, lino, nextents);
}
}
@@ -1892,13 +1892,13 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
if (anextents != dnextents) {
if (!no_modify) {
do_warn(
-_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
+_("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, anextents);
dino->di_nextents16 = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
-_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
+_("bad anextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
dnextents, lino, anextents);
}
}
diff --git a/repair/dinode.h b/repair/dinode.h
index e190b7435..09129e7b5 100644
--- a/repair/dinode.h
+++ b/repair/dinode.h
@@ -20,7 +20,7 @@ convert_extent(
int
process_bmbt_reclist(xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
@@ -34,7 +34,7 @@ int
scan_bmbt_reclist(
xfs_mount_t *mp,
xfs_bmbt_rec_t *rp,
- int *numrecs,
+ xfs_extnum_t *numrecs,
int type,
xfs_ino_t ino,
xfs_rfsblock_t *tot,
diff --git a/repair/scan.c b/repair/scan.c
index 86fa8b4dd..76021cff0 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -223,7 +223,7 @@ scan_bmapbt(
xfs_fileoff_t first_key;
xfs_fileoff_t last_key;
char *forkname = get_forkname(whichfork);
- int numrecs;
+ xfs_extnum_t numrecs;
xfs_agnumber_t agno;
xfs_agblock_t agbno;
int state;
@@ -443,7 +443,7 @@ _("couldn't add inode %"PRIu64" bmbt block %"PRIu64" reverse-mapping data."),
if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs <
mp->m_bmap_dmnr[0])) {
do_warn(
-_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
+_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
ino, numrecs, mp->m_bmap_dmnr[0],
mp->m_bmap_dmxr[0]);
return(1);
@@ -495,7 +495,7 @@ _("out-of-order bmap key (file offset) in inode %" PRIu64 ", %s fork, fsbno %" P
if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs <
mp->m_bmap_dmnr[1])) {
do_warn(
-_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
+_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
ino, numrecs, mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]);
return(1);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH V2 08/12] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively
2021-07-26 11:47 ` [PATCH V2 08/12] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-07-27 23:15 ` Darrick J. Wong
0 siblings, 0 replies; 19+ messages in thread
From: Darrick J. Wong @ 2021-07-27 23:15 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs
On Mon, Jul 26, 2021 at 05:17:20PM +0530, Chandan Babu R wrote:
> 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 <chandanrlinux@gmail.com>
xfs_repair changes look good,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
--D
> ---
> libxfs/xfs_inode_fork.c | 2 +-
> libxfs/xfs_types.h | 4 ++--
> repair/dinode.c | 20 ++++++++++----------
> repair/dinode.h | 4 ++--
> repair/scan.c | 6 +++---
> 5 files changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
> index 699bac823..8e2da89c7 100644
> --- a/libxfs/xfs_inode_fork.c
> +++ b/libxfs/xfs_inode_fork.c
> @@ -124,7 +124,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 %Lu ((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/libxfs/xfs_types.h b/libxfs/xfs_types.h
> index 8908346b1..584fa61e3 100644
> --- a/libxfs/xfs_types.h
> +++ b/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/repair/dinode.c b/repair/dinode.c
> index efff83ef9..beeb9ed07 100644
> --- a/repair/dinode.c
> +++ b/repair/dinode.c
> @@ -357,7 +357,7 @@ static int
> process_bmbt_reclist_int(
> xfs_mount_t *mp,
> xfs_bmbt_rec_t *rp,
> - int *numrecs,
> + xfs_extnum_t *numrecs,
> int type,
> xfs_ino_t ino,
> xfs_rfsblock_t *tot,
> @@ -680,7 +680,7 @@ int
> process_bmbt_reclist(
> xfs_mount_t *mp,
> xfs_bmbt_rec_t *rp,
> - int *numrecs,
> + xfs_extnum_t *numrecs,
> int type,
> xfs_ino_t ino,
> xfs_rfsblock_t *tot,
> @@ -703,7 +703,7 @@ int
> scan_bmbt_reclist(
> xfs_mount_t *mp,
> xfs_bmbt_rec_t *rp,
> - int *numrecs,
> + xfs_extnum_t *numrecs,
> int type,
> xfs_ino_t ino,
> xfs_rfsblock_t *tot,
> @@ -1089,7 +1089,7 @@ _("mismatch between format (%d) and size (%" PRId64 ") in symlink inode %" PRIu6
> */
> if (numrecs > max_symlink_blocks) {
> do_warn(
> -_("bad number of extents (%d) in symlink %" PRIu64 " data fork\n"),
> +_("bad number of extents (%lu) in symlink %" PRIu64 " data fork\n"),
> numrecs, lino);
> return(1);
> }
> @@ -1650,7 +1650,7 @@ _("realtime summary inode %" PRIu64 " has bad type 0x%x, "),
>
> if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
> do_warn(
> -_("bad # of extents (%d) for realtime summary inode %" PRIu64 "\n"),
> +_("bad # of extents (%lu) for realtime summary inode %" PRIu64 "\n"),
> nextents, lino);
> return 1;
> }
> @@ -1675,7 +1675,7 @@ _("realtime bitmap inode %" PRIu64 " has bad type 0x%x, "),
>
> if (mp->m_sb.sb_rblocks == 0 && nextents != 0) {
> do_warn(
> -_("bad # of extents (%d) for realtime bitmap inode %" PRIu64 "\n"),
> +_("bad # of extents (%lu) for realtime bitmap inode %" PRIu64 "\n"),
> nextents, lino);
> return 1;
> }
> @@ -1868,13 +1868,13 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> if (nextents != dnextents) {
> if (!no_modify) {
> do_warn(
> -_("correcting nextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
> +_("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
> lino, dnextents, nextents);
> dino->di_nextents32 = cpu_to_be32(nextents);
> *dirty = 1;
> } else {
> do_warn(
> -_("bad nextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> +_("bad nextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> dnextents, lino, nextents);
> }
> }
> @@ -1892,13 +1892,13 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> if (anextents != dnextents) {
> if (!no_modify) {
> do_warn(
> -_("correcting anextents for inode %" PRIu64 ", was %d - counted %" PRIu64 "\n"),
> +_("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
> lino, dnextents, anextents);
> dino->di_nextents16 = cpu_to_be16(anextents);
> *dirty = 1;
> } else {
> do_warn(
> -_("bad anextents %d for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> +_("bad anextents %lu for inode %" PRIu64 ", would reset to %" PRIu64 "\n"),
> dnextents, lino, anextents);
> }
> }
> diff --git a/repair/dinode.h b/repair/dinode.h
> index e190b7435..09129e7b5 100644
> --- a/repair/dinode.h
> +++ b/repair/dinode.h
> @@ -20,7 +20,7 @@ convert_extent(
> int
> process_bmbt_reclist(xfs_mount_t *mp,
> xfs_bmbt_rec_t *rp,
> - int *numrecs,
> + xfs_extnum_t *numrecs,
> int type,
> xfs_ino_t ino,
> xfs_rfsblock_t *tot,
> @@ -34,7 +34,7 @@ int
> scan_bmbt_reclist(
> xfs_mount_t *mp,
> xfs_bmbt_rec_t *rp,
> - int *numrecs,
> + xfs_extnum_t *numrecs,
> int type,
> xfs_ino_t ino,
> xfs_rfsblock_t *tot,
> diff --git a/repair/scan.c b/repair/scan.c
> index 86fa8b4dd..76021cff0 100644
> --- a/repair/scan.c
> +++ b/repair/scan.c
> @@ -223,7 +223,7 @@ scan_bmapbt(
> xfs_fileoff_t first_key;
> xfs_fileoff_t last_key;
> char *forkname = get_forkname(whichfork);
> - int numrecs;
> + xfs_extnum_t numrecs;
> xfs_agnumber_t agno;
> xfs_agblock_t agbno;
> int state;
> @@ -443,7 +443,7 @@ _("couldn't add inode %"PRIu64" bmbt block %"PRIu64" reverse-mapping data."),
> if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs <
> mp->m_bmap_dmnr[0])) {
> do_warn(
> -_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
> +_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
> ino, numrecs, mp->m_bmap_dmnr[0],
> mp->m_bmap_dmxr[0]);
> return(1);
> @@ -495,7 +495,7 @@ _("out-of-order bmap key (file offset) in inode %" PRIu64 ", %s fork, fsbno %" P
> if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs <
> mp->m_bmap_dmnr[1])) {
> do_warn(
> -_("inode %" PRIu64 " bad # of bmap records (%u, min - %u, max - %u)\n"),
> +_("inode %" PRIu64 " bad # of bmap records (%lu, min - %u, max - %u)\n"),
> ino, numrecs, mp->m_bmap_dmnr[1], mp->m_bmap_dmxr[1]);
> return(1);
> }
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 09/12] xfsprogs: Rename XFS_IOC_BULKSTAT to XFS_IOC_BULKSTAT_V5
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (7 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 08/12] xfsprogs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 10/12] xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters Chandan Babu R
` (2 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
This commit renames XFS_IOC_BULKSTAT to XFS_IOC_BULKSTAT_V5 to allow a future
commit to extend bulkstat facility to support 64-bit extent counters. To this
end, this commit also renames xfs_bulkstat->bs_extents field to
xfs_bulkstat->bs_extents32.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
fsr/xfs_fsr.c | 4 ++--
io/bulkstat.c | 2 +-
libfrog/bulkstat.c | 8 ++++----
libxfs/xfs_fs.h | 4 ++--
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index bb5d4a2c0..3446944cb 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -606,7 +606,7 @@ cmp(const void *s1, const void *s2)
(bs1->bs_version == XFS_BULKSTAT_VERSION_V5 &&
bs2->bs_version == XFS_BULKSTAT_VERSION_V5));
- return (bs2->bs_extents - bs1->bs_extents);
+ return (bs2->bs_extents32 - bs1->bs_extents32);
}
/*
@@ -670,7 +670,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
for (p = buf, endp = (buf + buflenout); p < endp ; p++) {
/* Do some obvious checks now */
if (((p->bs_mode & S_IFMT) != S_IFREG) ||
- (p->bs_extents < 2))
+ (p->bs_extents32 < 2))
continue;
ret = open_handle(&file_fd, fshandlep, p,
diff --git a/io/bulkstat.c b/io/bulkstat.c
index 4ae275864..378048379 100644
--- a/io/bulkstat.c
+++ b/io/bulkstat.c
@@ -49,7 +49,7 @@ dump_bulkstat(
printf("\tbs_extsize_blks = %"PRIu32"\n", bstat->bs_extsize_blks);
printf("\tbs_nlink = %"PRIu32"\n", bstat->bs_nlink);
- printf("\tbs_extents = %"PRIu32"\n", bstat->bs_extents);
+ printf("\tbs_extents = %"PRIu32"\n", bstat->bs_extents32);
printf("\tbs_aextents = %"PRIu32"\n", bstat->bs_aextents);
printf("\tbs_version = %"PRIu16"\n", bstat->bs_version);
printf("\tbs_forkoff = %"PRIu16"\n", bstat->bs_forkoff);
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
index 195f6ea05..5a967d4b1 100644
--- a/libfrog/bulkstat.c
+++ b/libfrog/bulkstat.c
@@ -61,7 +61,7 @@ xfrog_bulkstat_single5(
return ret;
req->hdr.flags = flags;
- ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT, req);
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V5, req);
if (ret) {
ret = -errno;
goto free;
@@ -260,7 +260,7 @@ xfrog_bulkstat5(
{
int ret;
- ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT, req);
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V5, req);
if (ret)
return -errno;
return 0;
@@ -366,7 +366,7 @@ xfrog_bulkstat_v5_to_v1(
bs1->bs_blocks = bs5->bs_blocks;
bs1->bs_xflags = bs5->bs_xflags;
bs1->bs_extsize = cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks);
- bs1->bs_extents = bs5->bs_extents;
+ bs1->bs_extents = bs5->bs_extents32;
bs1->bs_gen = bs5->bs_gen;
bs1->bs_projid_lo = bs5->bs_projectid & 0xFFFF;
bs1->bs_forkoff = bs5->bs_forkoff;
@@ -407,7 +407,7 @@ xfrog_bulkstat_v1_to_v5(
bs5->bs_blocks = bs1->bs_blocks;
bs5->bs_xflags = bs1->bs_xflags;
bs5->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
- bs5->bs_extents = bs1->bs_extents;
+ bs5->bs_extents32 = bs1->bs_extents;
bs5->bs_gen = bs1->bs_gen;
bs5->bs_projectid = bstat_get_projid(bs1);
bs5->bs_forkoff = bs1->bs_forkoff;
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 2594fb647..d760a9695 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -394,7 +394,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_extents32; /* number of extents */
uint32_t bs_aextents; /* attribute number of extents */
uint16_t bs_version; /* structure version */
uint16_t bs_forkoff; /* inode fork offset in bytes */
@@ -853,7 +853,7 @@ struct xfs_scrub_metadata {
#define XFS_IOC_FSGEOMETRY_V4 _IOR ('X', 124, struct xfs_fsop_geom_v4)
#define XFS_IOC_GOINGDOWN _IOR ('X', 125, uint32_t)
#define XFS_IOC_FSGEOMETRY _IOR ('X', 126, struct xfs_fsop_geom)
-#define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req)
+#define XFS_IOC_BULKSTAT_V5 _IOR ('X', 127, struct xfs_bulkstat_req)
#define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req)
/* FIEXCHANGE_RANGE ----------- hoisted 129 */
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 10/12] xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (8 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 09/12] xfsprogs: Rename XFS_IOC_BULKSTAT to XFS_IOC_BULKSTAT_V5 Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths Chandan Babu R
2021-07-26 11:47 ` [PATCH V2 12/12] xfsprogs: Add extcnt64bit mkfs option Chandan Babu R
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
This commit adds XFS_IOC_BULKSTAT_V6 to support 64-bit inode extent
counters. The new field xfs_bulkstat->bs_extents64 is added to hold data
extent count for filesystems supporting 64-bit data extent counters.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
fsr/xfs_fsr.c | 9 +-
io/bulkstat.c | 10 +-
libfrog/bulkstat.c | 260 ++++++++++++++++++++++++++-------------------
libfrog/bulkstat.h | 7 +-
libfrog/fsgeom.h | 5 +-
libxfs/xfs_fs.h | 7 +-
6 files changed, 175 insertions(+), 123 deletions(-)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 3446944cb..db917d015 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -6,6 +6,7 @@
#include "libxfs.h"
#include "xfs.h"
+#include "xfs/xfs_fs.h"
#include "xfs_types.h"
#include "jdm.h"
#include "xfs_bmap_btree.h"
@@ -604,9 +605,11 @@ cmp(const void *s1, const void *s2)
ASSERT((bs1->bs_version == XFS_BULKSTAT_VERSION_V1 &&
bs2->bs_version == XFS_BULKSTAT_VERSION_V1) ||
(bs1->bs_version == XFS_BULKSTAT_VERSION_V5 &&
- bs2->bs_version == XFS_BULKSTAT_VERSION_V5));
+ bs2->bs_version == XFS_BULKSTAT_VERSION_V5) ||
+ (bs1->bs_version == XFS_BULKSTAT_VERSION_V6 &&
+ bs2->bs_version == XFS_BULKSTAT_VERSION_V6));
- return (bs2->bs_extents32 - bs1->bs_extents32);
+ return (bs2->bs_extents64 - bs1->bs_extents64);
}
/*
@@ -670,7 +673,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
for (p = buf, endp = (buf + buflenout); p < endp ; p++) {
/* Do some obvious checks now */
if (((p->bs_mode & S_IFMT) != S_IFREG) ||
- (p->bs_extents32 < 2))
+ (p->bs_extents64 < 2))
continue;
ret = open_handle(&file_fd, fshandlep, p,
diff --git a/io/bulkstat.c b/io/bulkstat.c
index 378048379..92fbbaadb 100644
--- a/io/bulkstat.c
+++ b/io/bulkstat.c
@@ -49,7 +49,7 @@ dump_bulkstat(
printf("\tbs_extsize_blks = %"PRIu32"\n", bstat->bs_extsize_blks);
printf("\tbs_nlink = %"PRIu32"\n", bstat->bs_nlink);
- printf("\tbs_extents = %"PRIu32"\n", bstat->bs_extents32);
+ printf("\tbs_extents = %"PRIu64"\n", bstat->bs_extents64);
printf("\tbs_aextents = %"PRIu32"\n", bstat->bs_aextents);
printf("\tbs_version = %"PRIu16"\n", bstat->bs_version);
printf("\tbs_forkoff = %"PRIu16"\n", bstat->bs_forkoff);
@@ -86,6 +86,9 @@ set_xfd_flags(
case 5:
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V5;
break;
+ case 6:
+ xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V6;
+ break;
default:
break;
}
@@ -153,8 +156,9 @@ bulkstat_f(
perror(optarg);
return 1;
}
- if (ver != 1 && ver != 5) {
- fprintf(stderr, "version must be 1 or 5.\n");
+ if (ver != 1 && ver != 5 && ver != 6) {
+ fprintf(stderr,
+ "version must be 1 or 5 or 6.\n");
return 1;
}
break;
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
index 5a967d4b1..b169a1334 100644
--- a/libfrog/bulkstat.c
+++ b/libfrog/bulkstat.c
@@ -5,6 +5,7 @@
*/
#include <string.h>
#include <strings.h>
+#include <assert.h>
#include "xfs.h"
#include "fsgeom.h"
#include "bulkstat.h"
@@ -42,6 +43,42 @@ xfrog_bulkstat_prep_v1_emulation(
return xfd_prepare_geometry(xfd);
}
+/* Bulkstat a single inode using v6 ioctl. */
+static int
+xfrog_bulkstat_single6(
+ struct xfs_fd *xfd,
+ uint64_t ino,
+ unsigned int flags,
+ struct xfs_bulkstat *bulkstat)
+{
+ struct xfs_bulkstat_req *req;
+ int ret;
+
+ if (flags & ~(XFS_BULK_IREQ_SPECIAL))
+ return -EINVAL;
+
+ ret = xfrog_bulkstat_alloc_req(1, ino, &req);
+ if (ret)
+ return ret;
+
+ req->hdr.flags = flags;
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V6, req);
+ if (ret) {
+ ret = -errno;
+ goto free;
+ }
+
+ if (req->hdr.ocount == 0) {
+ ret = -ENOENT;
+ goto free;
+ }
+
+ memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
+free:
+ free(req);
+ return ret;
+}
+
/* Bulkstat a single inode using v5 ioctl. */
static int
xfrog_bulkstat_single5(
@@ -73,6 +110,9 @@ xfrog_bulkstat_single5(
}
memcpy(bulkstat, req->bulkstat, sizeof(struct xfs_bulkstat));
+
+ xfrog_bulkstat_v5_to_v6(bulkstat);
+
free:
free(req);
return ret;
@@ -104,34 +144,46 @@ xfrog_bulkstat_single1(
if (error)
return -errno;
- xfrog_bulkstat_v1_to_v5(xfd, bulkstat, &bstat);
+ xfrog_bulkstat_v1_to_v6(xfd, bulkstat, &bstat);
return 0;
}
/* Bulkstat a single inode. Returns zero or a negative error code. */
int
xfrog_bulkstat_single(
- struct xfs_fd *xfd,
- uint64_t ino,
- unsigned int flags,
- struct xfs_bulkstat *bulkstat)
+ struct xfs_fd *xfd,
+ uint64_t ino,
+ unsigned int flags,
+ struct xfs_bulkstat *bulkstat)
{
- int error;
+ unsigned int xfd_flags = 0;
+ int error;
if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
goto try_v1;
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ goto try_v5;
+
+ error = xfrog_bulkstat_single6(xfd, ino, flags, bulkstat);
+ if (error == 0 || xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V6)
+ return error;
+
+ if (error == -EOPNOTSUPP && error == -ENOTTY)
+ xfd_flags = XFROG_FLAG_BULKSTAT_FORCE_V5;
+
+try_v5:
error = xfrog_bulkstat_single5(xfd, ino, flags, bulkstat);
- if (error == 0 || (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5))
+ if (error == 0) {
+ xfd->flags |= xfd_flags;
+ return 0;
+ }
+
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
return error;
- /* If the v5 ioctl wasn't found, we punt to v1. */
- switch (error) {
- case -EOPNOTSUPP:
- case -ENOTTY:
+ if (error == -EOPNOTSUPP && error == -ENOTTY)
xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
- break;
- }
try_v1:
return xfrog_bulkstat_single1(xfd, ino, flags, bulkstat);
@@ -200,14 +252,14 @@ xfrog_bulk_req_v1_cleanup(
struct xfs_fsop_bulkreq *bulkreq,
size_t v1_rec_size,
uint64_t (*v1_ino)(void *v1_rec),
- void *v5_records,
- size_t v5_rec_size,
+ void *v6_records,
+ size_t v6_rec_size,
void (*cvt)(struct xfs_fd *xfd, void *v5, void *v1),
unsigned int startino_adj,
int error)
{
void *v1_rec = bulkreq->ubuffer;
- void *v5_rec = v5_records;
+ void *v6_rec = v6_records;
unsigned int i;
if (error == -ECANCELED) {
@@ -224,7 +276,7 @@ xfrog_bulk_req_v1_cleanup(
*/
for (i = 0;
i < hdr->ocount;
- i++, v1_rec += v1_rec_size, v5_rec += v5_rec_size) {
+ i++, v1_rec += v1_rec_size, v6_rec += v6_rec_size) {
uint64_t ino = v1_ino(v1_rec);
/* Stop if we hit a different AG. */
@@ -233,7 +285,7 @@ xfrog_bulk_req_v1_cleanup(
hdr->ocount = i;
break;
}
- cvt(xfd, v5_rec, v1_rec);
+ cvt(xfd, v6_rec, v1_rec);
hdr->ino = ino + startino_adj;
}
@@ -247,9 +299,23 @@ static uint64_t xfrog_bstat_ino(void *v1_rec)
return ((struct xfs_bstat *)v1_rec)->bs_ino;
}
-static void xfrog_bstat_cvt(struct xfs_fd *xfd, void *v5, void *v1)
+static void xfrog_bstat_cvt(struct xfs_fd *xfd, void *v6, void *v1)
{
- xfrog_bulkstat_v1_to_v5(xfd, v5, v1);
+ xfrog_bulkstat_v1_to_v6(xfd, v6, v1);
+}
+
+/* Bulkstat a bunch of inodes using the v6 interface. */
+static int
+xfrog_bulkstat6(
+ struct xfs_fd *xfd,
+ struct xfs_bulkstat_req *req)
+{
+ int ret;
+
+ ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V6, req);
+ if (ret)
+ return -errno;
+ return 0;
}
/* Bulkstat a bunch of inodes using the v5 interface. */
@@ -258,11 +324,17 @@ xfrog_bulkstat5(
struct xfs_fd *xfd,
struct xfs_bulkstat_req *req)
{
+ struct xfs_bulk_ireq *hdr = &req->hdr;
int ret;
+ int i;
ret = ioctl(xfd->fd, XFS_IOC_BULKSTAT_V5, req);
if (ret)
return -errno;
+
+ for (i = 0; i < hdr->ocount; i++)
+ xfrog_bulkstat_v5_to_v6(&req->bulkstat[i]);
+
return 0;
}
@@ -303,118 +375,86 @@ xfrog_bulkstat(
struct xfs_fd *xfd,
struct xfs_bulkstat_req *req)
{
+ unsigned int xfd_flags = 0;
int error;
if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
goto try_v1;
- error = xfrog_bulkstat5(xfd, req);
- if (error == 0 || (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5))
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ goto try_v5;
+
+ error = xfrog_bulkstat6(xfd, req);
+ if (error == 0 || xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V6)
return error;
- /* If the v5 ioctl wasn't found, we punt to v1. */
- switch (error) {
- case -EOPNOTSUPP:
- case -ENOTTY:
- xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
- break;
+ if (error == -EOPNOTSUPP || error == -ENOTTY)
+ xfd_flags = XFROG_FLAG_BULKSTAT_FORCE_V5;
+
+try_v5:
+ error = xfrog_bulkstat5(xfd, req);
+ if (error == 0) {
+ xfd->flags |= xfd_flags;
+ return 0;
}
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5)
+ return error;
+
+ if (error == -EOPNOTSUPP || error == -ENOTTY)
+ xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
+
try_v1:
return xfrog_bulkstat1(xfd, req);
}
-static bool
-time_too_big(
- uint64_t time)
+/* Convert bulkstat data from v5 format to v6 format. */
+void
+xfrog_bulkstat_v5_to_v6(
+ struct xfs_bulkstat *bs)
{
- time_t TIME_MAX;
+ bs->bs_version = XFS_BULKSTAT_VERSION_V5;
- memset(&TIME_MAX, 0xFF, sizeof(TIME_MAX));
- return time > TIME_MAX;
-}
-
-/* Convert bulkstat data from v5 format to v1 format. */
-int
-xfrog_bulkstat_v5_to_v1(
- struct xfs_fd *xfd,
- struct xfs_bstat *bs1,
- const struct xfs_bulkstat *bs5)
-{
- if (bs5->bs_aextents > UINT16_MAX ||
- cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks) > UINT32_MAX ||
- cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks) > UINT32_MAX ||
- time_too_big(bs5->bs_atime) ||
- time_too_big(bs5->bs_ctime) ||
- time_too_big(bs5->bs_mtime))
- return -ERANGE;
-
- bs1->bs_ino = bs5->bs_ino;
- bs1->bs_mode = bs5->bs_mode;
- bs1->bs_nlink = bs5->bs_nlink;
- bs1->bs_uid = bs5->bs_uid;
- bs1->bs_gid = bs5->bs_gid;
- bs1->bs_rdev = bs5->bs_rdev;
- bs1->bs_blksize = bs5->bs_blksize;
- bs1->bs_size = bs5->bs_size;
- bs1->bs_atime.tv_sec = bs5->bs_atime;
- bs1->bs_mtime.tv_sec = bs5->bs_mtime;
- bs1->bs_ctime.tv_sec = bs5->bs_ctime;
- bs1->bs_atime.tv_nsec = bs5->bs_atime_nsec;
- bs1->bs_mtime.tv_nsec = bs5->bs_mtime_nsec;
- bs1->bs_ctime.tv_nsec = bs5->bs_ctime_nsec;
- bs1->bs_blocks = bs5->bs_blocks;
- bs1->bs_xflags = bs5->bs_xflags;
- bs1->bs_extsize = cvt_off_fsb_to_b(xfd, bs5->bs_extsize_blks);
- bs1->bs_extents = bs5->bs_extents32;
- bs1->bs_gen = bs5->bs_gen;
- bs1->bs_projid_lo = bs5->bs_projectid & 0xFFFF;
- bs1->bs_forkoff = bs5->bs_forkoff;
- bs1->bs_projid_hi = bs5->bs_projectid >> 16;
- bs1->bs_sick = bs5->bs_sick;
- bs1->bs_checked = bs5->bs_checked;
- bs1->bs_cowextsize = cvt_off_fsb_to_b(xfd, bs5->bs_cowextsize_blks);
- bs1->bs_dmevmask = 0;
- bs1->bs_dmstate = 0;
- bs1->bs_aextents = bs5->bs_aextents;
- return 0;
+ assert(bs->bs_extents64 == 0);
+ bs->bs_extents64 = bs->bs_extents32;
+ bs->bs_extents32 = 0;
}
/* Convert bulkstat data from v1 format to v5 format. */
void
-xfrog_bulkstat_v1_to_v5(
+xfrog_bulkstat_v1_to_v6(
struct xfs_fd *xfd,
- struct xfs_bulkstat *bs5,
+ struct xfs_bulkstat *bs6,
const struct xfs_bstat *bs1)
{
- memset(bs5, 0, sizeof(*bs5));
- bs5->bs_version = XFS_BULKSTAT_VERSION_V1;
-
- bs5->bs_ino = bs1->bs_ino;
- bs5->bs_mode = bs1->bs_mode;
- bs5->bs_nlink = bs1->bs_nlink;
- bs5->bs_uid = bs1->bs_uid;
- bs5->bs_gid = bs1->bs_gid;
- bs5->bs_rdev = bs1->bs_rdev;
- bs5->bs_blksize = bs1->bs_blksize;
- bs5->bs_size = bs1->bs_size;
- bs5->bs_atime = bs1->bs_atime.tv_sec;
- bs5->bs_mtime = bs1->bs_mtime.tv_sec;
- bs5->bs_ctime = bs1->bs_ctime.tv_sec;
- bs5->bs_atime_nsec = bs1->bs_atime.tv_nsec;
- bs5->bs_mtime_nsec = bs1->bs_mtime.tv_nsec;
- bs5->bs_ctime_nsec = bs1->bs_ctime.tv_nsec;
- bs5->bs_blocks = bs1->bs_blocks;
- bs5->bs_xflags = bs1->bs_xflags;
- bs5->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
- bs5->bs_extents32 = bs1->bs_extents;
- bs5->bs_gen = bs1->bs_gen;
- bs5->bs_projectid = bstat_get_projid(bs1);
- bs5->bs_forkoff = bs1->bs_forkoff;
- bs5->bs_sick = bs1->bs_sick;
- bs5->bs_checked = bs1->bs_checked;
- bs5->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
- bs5->bs_aextents = bs1->bs_aextents;
+ memset(bs6, 0, sizeof(*bs6));
+ bs6->bs_version = XFS_BULKSTAT_VERSION_V1;
+
+ bs6->bs_ino = bs1->bs_ino;
+ bs6->bs_mode = bs1->bs_mode;
+ bs6->bs_nlink = bs1->bs_nlink;
+ bs6->bs_uid = bs1->bs_uid;
+ bs6->bs_gid = bs1->bs_gid;
+ bs6->bs_rdev = bs1->bs_rdev;
+ bs6->bs_blksize = bs1->bs_blksize;
+ bs6->bs_size = bs1->bs_size;
+ bs6->bs_atime = bs1->bs_atime.tv_sec;
+ bs6->bs_mtime = bs1->bs_mtime.tv_sec;
+ bs6->bs_ctime = bs1->bs_ctime.tv_sec;
+ bs6->bs_atime_nsec = bs1->bs_atime.tv_nsec;
+ bs6->bs_mtime_nsec = bs1->bs_mtime.tv_nsec;
+ bs6->bs_ctime_nsec = bs1->bs_ctime.tv_nsec;
+ bs6->bs_blocks = bs1->bs_blocks;
+ bs6->bs_xflags = bs1->bs_xflags;
+ bs6->bs_extsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_extsize);
+ bs6->bs_extents64 = bs1->bs_extents;
+ bs6->bs_gen = bs1->bs_gen;
+ bs6->bs_projectid = bstat_get_projid(bs1);
+ bs6->bs_forkoff = bs1->bs_forkoff;
+ bs6->bs_sick = bs1->bs_sick;
+ bs6->bs_checked = bs1->bs_checked;
+ bs6->bs_cowextsize_blks = cvt_b_to_off_fsbt(xfd, bs1->bs_cowextsize);
+ bs6->bs_aextents = bs1->bs_aextents;
}
/* Allocate a bulkstat request. Returns zero or a negative error code. */
diff --git a/libfrog/bulkstat.h b/libfrog/bulkstat.h
index 2f440b14f..504ceda9c 100644
--- a/libfrog/bulkstat.h
+++ b/libfrog/bulkstat.h
@@ -18,10 +18,9 @@ int xfrog_bulkstat(struct xfs_fd *xfd, struct xfs_bulkstat_req *req);
int xfrog_bulkstat_alloc_req(uint32_t nr, uint64_t startino,
struct xfs_bulkstat_req **preq);
-int xfrog_bulkstat_v5_to_v1(struct xfs_fd *xfd, struct xfs_bstat *bs1,
- const struct xfs_bulkstat *bstat);
-void xfrog_bulkstat_v1_to_v5(struct xfs_fd *xfd, struct xfs_bulkstat *bstat,
- const struct xfs_bstat *bs1);
+void xfrog_bulkstat_v1_to_v6(struct xfs_fd *xfd, struct xfs_bulkstat *bstat,
+ const struct xfs_bstat *bs1);
+void xfrog_bulkstat_v5_to_v6(struct xfs_bulkstat *bs);
void xfrog_bulkstat_set_ag(struct xfs_bulkstat_req *req, uint32_t agno);
diff --git a/libfrog/fsgeom.h b/libfrog/fsgeom.h
index bef864fce..423b14ea9 100644
--- a/libfrog/fsgeom.h
+++ b/libfrog/fsgeom.h
@@ -48,7 +48,10 @@ struct xfs_fd {
#define XFROG_FLAG_BULKSTAT_FORCE_V1 (1 << 0)
/* Only use v5 bulkstat/inumbers ioctls. */
-#define XFROG_FLAG_BULKSTAT_FORCE_V5 (1 << 1)
+#define XFROG_FLAG_BULKSTAT_FORCE_V5 (1 << 1)
+
+/* Only use v6 bulkstat ioctls. */
+#define XFROG_FLAG_BULKSTAT_FORCE_V6 (1 << 2)
/* Only use the old XFS swapext ioctl for file data exchanges. */
#define XFROG_FLAG_FORCE_SWAPEXT (1 << 2)
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index d760a9695..bfa81af82 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -394,7 +394,7 @@ struct xfs_bulkstat {
uint32_t bs_extsize_blks; /* extent size hint, blocks */
uint32_t bs_nlink; /* number of links */
- uint32_t bs_extents32; /* number of extents */
+ uint32_t bs_extents32; /* number of extents; v5 only */
uint32_t bs_aextents; /* attribute number of extents */
uint16_t bs_version; /* structure version */
uint16_t bs_forkoff; /* inode fork offset in bytes */
@@ -403,12 +403,14 @@ 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; /* number of extents; v6 only */
- uint64_t bs_pad[7]; /* zeroed */
+ uint64_t bs_pad[6]; /* zeroed */
};
#define XFS_BULKSTAT_VERSION_V1 (1)
#define XFS_BULKSTAT_VERSION_V5 (5)
+#define XFS_BULKSTAT_VERSION_V6 (6)
/* bs_sick flags */
#define XFS_BS_SICK_INODE (1 << 0) /* inode core */
@@ -856,6 +858,7 @@ struct xfs_scrub_metadata {
#define XFS_IOC_BULKSTAT_V5 _IOR ('X', 127, struct xfs_bulkstat_req)
#define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req)
/* FIEXCHANGE_RANGE ----------- hoisted 129 */
+#define XFS_IOC_BULKSTAT_V6 _IOR ('X', 130, struct xfs_bulkstat_req)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (9 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 10/12] xfsprogs: Enable bulkstat ioctl to support 64-bit extent counters Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
2021-07-28 19:11 ` Darrick J. Wong
2021-07-26 11:47 ` [PATCH V2 12/12] xfsprogs: Add extcnt64bit mkfs option Chandan Babu R
11 siblings, 1 reply; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
This commit adds a new 64-bit per-inode data extent counter. However the
maximum number of extents that a data fork can hold is limited to 2^48
extents. This feature is available only when
XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT feature bit is enabled on the
filesystem. Also, enabling this feature bit causes attr fork extent counter to
use the 32-bit extent counter that was previously used to hold the data fork
extent counter. This implies that the attr fork can now occupy a maximum of
2^32 extents.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
db/field.c | 4 ----
db/field.h | 2 --
db/inode.c | 30 +++++++++++++++++++++++++++---
include/libxlog.h | 6 ++++--
libxfs/xfs_bmap.c | 8 +++-----
libxfs/xfs_format.h | 15 +++++++++++++--
libxfs/xfs_inode_buf.c | 30 +++++++++++++++++++++++++-----
libxfs/xfs_inode_fork.h | 18 ++++++++++++++----
libxfs/xfs_log_format.h | 3 ++-
logprint/log_misc.c | 23 ++++++++++++++++++-----
logprint/log_print_all.c | 34 +++++++++++++++++++++++++++-------
logprint/log_print_trans.c | 2 +-
repair/bmap_repair.c | 10 ++++++++--
repair/dinode.c | 15 ++++++++++++---
14 files changed, 154 insertions(+), 46 deletions(-)
diff --git a/db/field.c b/db/field.c
index 51268938a..1e274ffc4 100644
--- a/db/field.c
+++ b/db/field.c
@@ -25,8 +25,6 @@
#include "symlink.h"
const ftattr_t ftattrtab[] = {
- { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)),
- FTARG_SIGNED, NULL, NULL },
{ FLDT_AGBLOCK, "agblock", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
FTARG_DONULL, fa_agblock, NULL },
{ FLDT_AGBLOCKNZ, "agblocknz", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
@@ -300,8 +298,6 @@ const ftattr_t ftattrtab[] = {
FTARG_DONULL, fa_drtbno, NULL },
{ FLDT_EXTLEN, "extlen", fp_num, "%u", SI(bitsz(xfs_extlen_t)), 0, NULL,
NULL },
- { FLDT_EXTNUM, "extnum", fp_num, "%d", SI(bitsz(xfs_extnum_t)),
- FTARG_SIGNED, NULL, NULL },
{ FLDT_FSIZE, "fsize", fp_num, "%lld", SI(bitsz(xfs_fsize_t)),
FTARG_SIGNED, NULL, NULL },
{ FLDT_INO, "ino", fp_num, "%llu", SI(bitsz(xfs_ino_t)), FTARG_DONULL,
diff --git a/db/field.h b/db/field.h
index 387c189ec..614fd0ab4 100644
--- a/db/field.h
+++ b/db/field.h
@@ -5,7 +5,6 @@
*/
typedef enum fldt {
- FLDT_AEXTNUM,
FLDT_AGBLOCK,
FLDT_AGBLOCKNZ,
FLDT_AGF,
@@ -143,7 +142,6 @@ typedef enum fldt {
FLDT_DRFSBNO,
FLDT_DRTBNO,
FLDT_EXTLEN,
- FLDT_EXTNUM,
FLDT_FSIZE,
FLDT_INO,
FLDT_INOBT,
diff --git a/db/inode.c b/db/inode.c
index 27251f02f..6f941184c 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -37,6 +37,8 @@ static int inode_u_muuid_count(void *obj, int startoff);
static int inode_u_sfdir2_count(void *obj, int startoff);
static int inode_u_sfdir3_count(void *obj, int startoff);
static int inode_u_symlink_count(void *obj, int startoff);
+static int inode_v3_64bitext_count(void *obj, int startoff);
+static int inode_v3_pad2_count(void *obj, int startoff);
static const cmdinfo_t inode_cmd =
{ "inode", NULL, inode_f, 0, 1, 1, "[inode#]",
@@ -100,8 +102,8 @@ const field_t inode_core_flds[] = {
{ "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
{ "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
{ "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
- { "nextents32", FLDT_EXTNUM, OI(COFF(nextents32)), C1, 0, TYP_NONE },
- { "nextents16", FLDT_AEXTNUM, OI(COFF(nextents16)), C1, 0, TYP_NONE },
+ { "nextents32", FLDT_UINT32D, OI(COFF(nextents32)), C1, 0, TYP_NONE },
+ { "nextents16", FLDT_UINT16D, OI(COFF(nextents16)), C1, 0, TYP_NONE },
{ "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
{ "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
{ "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
@@ -162,7 +164,10 @@ const field_t inode_v3_flds[] = {
{ "lsn", FLDT_UINT64X, OI(COFF(lsn)), C1, 0, TYP_NONE },
{ "flags2", FLDT_UINT64X, OI(COFF(flags2)), C1, 0, TYP_NONE },
{ "cowextsize", FLDT_EXTLEN, OI(COFF(cowextsize)), C1, 0, TYP_NONE },
- { "pad2", FLDT_UINT8X, OI(OFF(pad2)), CI(12), FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
+ { "nextents64", FLDT_UINT64D, OI(COFF(nextents64)),
+ inode_v3_64bitext_count, FLD_COUNT, TYP_NONE },
+ { "pad2", FLDT_UINT8X, OI(OFF(pad2)), inode_v3_pad2_count,
+ FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
{ "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE },
{ "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE },
{ "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE },
@@ -410,6 +415,25 @@ inode_core_projid_count(
return dic->di_version >= 2;
}
+static int
+inode_v3_64bitext_count(
+ void *obj,
+ int startoff)
+{
+ return xfs_sb_version_hasextcount_64bit(&mp->m_sb);
+}
+
+static int
+inode_v3_pad2_count(
+ void *obj,
+ int startoff)
+{
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ return 4;
+ else
+ return 12;
+}
+
static int
inode_f(
int argc,
diff --git a/include/libxlog.h b/include/libxlog.h
index adaa9963c..fe30481cf 100644
--- a/include/libxlog.h
+++ b/include/libxlog.h
@@ -89,13 +89,15 @@ extern int xlog_find_tail(struct xlog *log, xfs_daddr_t *head_blk,
extern int xlog_recover(struct xlog *log, int readonly);
extern void xlog_recover_print_data(char *p, int len);
-extern void xlog_recover_print_logitem(struct xlog_recover_item *item);
+extern void xlog_recover_print_logitem(struct xlog *log,
+ struct xlog_recover_item *item);
extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
extern int xlog_print_find_oldest(struct xlog *log, xfs_daddr_t *last_blk);
/* for transactional view */
extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
-extern void xlog_recover_print_trans(struct xlog_recover *trans,
+extern void xlog_recover_print_trans(struct xlog *log,
+ struct xlog_recover *trans,
struct list_head *itemq, int print);
extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk,
xfs_daddr_t tail_blk, int pass);
diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
index dd60d8105..155d1e935 100644
--- a/libxfs/xfs_bmap.c
+++ b/libxfs/xfs_bmap.c
@@ -47,18 +47,16 @@ xfs_bmap_compute_maxlevels(
int whichfork) /* data or attr fork */
{
xfs_extnum_t maxleafents; /* max leaf entries possible */
+ uint64_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 */
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
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 6564bc135..db3085974 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -485,13 +485,15 @@ xfs_sb_has_ro_compat_feature(
#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_METADIR (1 << 5) /* metadata dir tree */
+#define XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT (1 << 6) /* 64-bit inode fork extent counters */
#define XFS_SB_FEAT_INCOMPAT_ALL \
(XFS_SB_FEAT_INCOMPAT_FTYPE| \
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_METADIR)
+ XFS_SB_FEAT_INCOMPAT_METADIR| \
+ XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT)
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool
@@ -591,6 +593,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp)
(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID);
}
+static inline bool xfs_sb_version_hasextcount_64bit(struct xfs_sb *sbp)
+{
+ return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
+ (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT);
+}
+
static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp)
{
return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
@@ -1057,7 +1065,8 @@ typedef struct xfs_dinode {
__be64 di_lsn; /* flush sequence */
__be64 di_flags2; /* more random flags */
__be32 di_cowextsize; /* basic cow extent size for file */
- __u8 di_pad2[12]; /* more padding for future expansion */
+ __u8 di_pad2[4]; /* more padding for future expansion */
+ __be64 di_nextents64; /* 64-bit extent counter */
/* fields only written to during inode creation */
xfs_timestamp_t di_crtime; /* time created */
@@ -1113,6 +1122,8 @@ enum xfs_dinode_fmt {
* Max values for extlen, disk inode's extent counters.
*/
#define MAXEXTLEN ((uint32_t)0x1fffff) /* 21 bits */
+#define XFS_IFORK_EXTCNT_MAXU48 ((uint64_t)0xffffffffffff) /* Unsigned 48-bits */
+#define XFS_IFORK_EXTCNT_MAXU32 ((uint32_t)0xffffffff) /* Unsigned 32-bits */
#define XFS_IFORK_EXTCNT_MAXS32 ((int32_t)0x7fffffff) /* Signed 32-bits */
#define XFS_IFORK_EXTCNT_MAXS16 ((int16_t)0x7fff) /* Signed 16-bits */
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 95fd95cc0..25877251f 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -288,6 +288,7 @@ xfs_inode_to_disk(
struct xfs_dinode *to,
xfs_lsn_t lsn)
{
+ struct xfs_sb *sbp = &ip->i_mount->m_sb;
struct inode *inode = VFS_I(ip);
to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
@@ -307,11 +308,9 @@ xfs_inode_to_disk(
to->di_gen = cpu_to_be32(inode->i_generation);
to->di_mode = cpu_to_be16(inode->i_mode);
- to->di_size = cpu_to_be64(ip->i_disk_size);
+ 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_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
- to->di_nextents16 = 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);
@@ -331,6 +330,19 @@ xfs_inode_to_disk(
to->di_version = 2;
to->di_flushiter = cpu_to_be16(ip->i_flushiter);
}
+
+ if (xfs_sb_version_hasextcount_64bit(sbp)) {
+ to->di_nextents64 = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
+ to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
+ /*
+ * xchk_dinode() passes an uninitialized disk inode. Hence,
+ * clear di_nextents16 field explicitly.
+ */
+ to->di_nextents16 = cpu_to_be16(0);
+ } else {
+ to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
+ to->di_nextents16 = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
+ }
}
static xfs_failaddr_t
@@ -383,14 +395,22 @@ xfs_dfork_nextents(
xfs_extnum_t *nextents)
{
int error = 0;
+ bool has_64bit_extcnt;
+
+ has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
+
+ if (has_64bit_extcnt && dip->di_nextents16 != 0)
+ return -EFSCORRUPTED;
switch (whichfork) {
case XFS_DATA_FORK:
- *nextents = be32_to_cpu(dip->di_nextents32);
+ *nextents = has_64bit_extcnt ? be64_to_cpu(dip->di_nextents64)
+ : be32_to_cpu(dip->di_nextents32);
break;
case XFS_ATTR_FORK:
- *nextents = be16_to_cpu(dip->di_nextents16);
+ *nextents = has_64bit_extcnt ? be32_to_cpu(dip->di_nextents32)
+ : be16_to_cpu(dip->di_nextents16);
break;
default:
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index 1eda21636..cc8145941 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -135,10 +135,20 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
static inline xfs_extnum_t xfs_iext_max(struct xfs_mount *mp, int whichfork)
{
- if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
- return XFS_IFORK_EXTCNT_MAXS32;
- else
- return XFS_IFORK_EXTCNT_MAXS16;
+ bool has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
+
+ switch (whichfork) {
+ case XFS_DATA_FORK:
+ case XFS_COW_FORK:
+ return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU48 : XFS_IFORK_EXTCNT_MAXS32;
+
+ case XFS_ATTR_FORK:
+ return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU32 : XFS_IFORK_EXTCNT_MAXS16;
+
+ default:
+ ASSERT(0);
+ return 0;
+ }
}
struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index ca8e4ad83..9b5d64708 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -420,7 +420,8 @@ struct xfs_log_dinode {
xfs_lsn_t di_lsn; /* flush sequence */
uint64_t di_flags2; /* more random flags */
uint32_t di_cowextsize; /* basic cow extent size for file */
- uint8_t di_pad2[12]; /* more padding for future expansion */
+ uint8_t di_pad2[4]; /* more padding for future expansion */
+ uint64_t di_nextents64; /* higher part of data fork extent count */
/* fields only written to during inode creation */
xfs_log_timestamp_t di_crtime; /* time created */
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index 4e8760c43..1fb580c58 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -438,8 +438,11 @@ xlog_print_trans_qoff(char **ptr, uint len)
static void
xlog_print_trans_inode_core(
+ struct xfs_mount *mp,
struct xfs_log_dinode *ip)
{
+ xfs_extnum_t nextents;
+
printf(_("INODE CORE\n"));
printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
ip->di_magic, ip->di_mode, (int)ip->di_version,
@@ -450,11 +453,21 @@ xlog_print_trans_inode_core(
xlog_extract_dinode_ts(ip->di_atime),
xlog_extract_dinode_ts(ip->di_mtime),
xlog_extract_dinode_ts(ip->di_ctime));
- printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
+
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ nextents = ip->di_nextents64;
+ else
+ nextents = ip->di_nextents32;
+ printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%lx\n"),
(unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
- ip->di_extsize, ip->di_nextents32);
- printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
- ip->di_nextents16, (int)ip->di_forkoff, ip->di_dmevmask,
+ ip->di_extsize, nextents);
+
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ nextents = ip->di_nextents32;
+ else
+ nextents = ip->di_nextents16;
+ printf(_("naextents 0x%lx forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
+ nextents, (int)ip->di_forkoff, ip->di_dmevmask,
ip->di_dmstate);
printf(_("flags 0x%x gen 0x%x\n"),
ip->di_flags, ip->di_gen);
@@ -564,7 +577,7 @@ xlog_print_trans_inode(
memmove(&dino, *ptr, sizeof(dino));
mode = dino.di_mode & S_IFMT;
size = (int)dino.di_size;
- xlog_print_trans_inode_core(&dino);
+ xlog_print_trans_inode_core(log->l_mp, &dino);
*ptr += xfs_log_dinode_size(log->l_mp);
skip_count--;
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 403c56372..b528e1c57 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -238,9 +238,14 @@ xlog_recover_print_dquot(
STATIC void
xlog_recover_print_inode_core(
+ struct xlog *log,
struct xfs_log_dinode *di)
{
- printf(_(" CORE inode:\n"));
+ struct xfs_sb *sbp = &log->l_mp->m_sb;
+ xfs_extnum_t nextents;
+ xfs_aextnum_t anextents;
+
+ printf(_(" CORE inode:\n"));
if (!print_inode)
return;
printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"),
@@ -254,10 +259,21 @@ xlog_recover_print_inode_core(
xlog_extract_dinode_ts(di->di_mtime),
xlog_extract_dinode_ts(di->di_ctime));
printf(_(" flushiter:%d\n"), di->di_flushiter);
+
+ if (xfs_sb_version_hasextcount_64bit(sbp))
+ nextents = di->di_nextents64;
+ else
+ nextents = di->di_nextents32;
+
+ if (xfs_sb_version_hasextcount_64bit(sbp))
+ anextents = di->di_nextents32;
+ else
+ anextents = di->di_nextents16;
+
printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
- "nextents:%d anextents:%d\n"), (unsigned long long)
+ "nextents:%lu anextents:%u\n"), (unsigned long long)
di->di_size, (unsigned long long)di->di_nblocks,
- di->di_extsize, di->di_nextents32, (int)di->di_nextents16);
+ di->di_extsize, nextents, anextents);
printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
"gen:%u\n"),
(int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
@@ -270,6 +286,7 @@ xlog_recover_print_inode_core(
STATIC void
xlog_recover_print_inode(
+ struct xlog *log,
struct xlog_recover_item *item)
{
struct xfs_inode_log_format f_buf;
@@ -291,7 +308,7 @@ xlog_recover_print_inode(
ASSERT(item->ri_buf[1].i_len ==
offsetof(struct xfs_log_dinode, di_next_unlinked) ||
item->ri_buf[1].i_len == sizeof(struct xfs_log_dinode));
- xlog_recover_print_inode_core((struct xfs_log_dinode *)
+ xlog_recover_print_inode_core(log, (struct xfs_log_dinode *)
item->ri_buf[1].i_addr);
hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0;
@@ -386,6 +403,7 @@ xlog_recover_print_icreate(
void
xlog_recover_print_logitem(
+ struct xlog *log,
struct xlog_recover_item *item)
{
switch (ITEM_TYPE(item)) {
@@ -396,7 +414,7 @@ xlog_recover_print_logitem(
xlog_recover_print_icreate(item);
break;
case XFS_LI_INODE:
- xlog_recover_print_inode(item);
+ xlog_recover_print_inode(log, item);
break;
case XFS_LI_EFD:
xlog_recover_print_efd(item);
@@ -442,6 +460,7 @@ xlog_recover_print_logitem(
static void
xlog_recover_print_item(
+ struct xlog *log,
struct xlog_recover_item *item)
{
int i;
@@ -507,11 +526,12 @@ xlog_recover_print_item(
(long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len);
}
printf("\n");
- xlog_recover_print_logitem(item);
+ xlog_recover_print_logitem(log, item);
}
void
xlog_recover_print_trans(
+ struct xlog *log,
struct xlog_recover *trans,
struct list_head *itemq,
int print)
@@ -524,5 +544,5 @@ xlog_recover_print_trans(
print_xlog_record_line();
xlog_recover_print_trans_head(trans);
list_for_each_entry(item, itemq, ri_list)
- xlog_recover_print_item(item);
+ xlog_recover_print_item(log, item);
}
diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c
index 2004b5a0e..c6386fb0c 100644
--- a/logprint/log_print_trans.c
+++ b/logprint/log_print_trans.c
@@ -24,7 +24,7 @@ xlog_recover_do_trans(
struct xlog_recover *trans,
int pass)
{
- xlog_recover_print_trans(trans, &trans->r_itemq, 3);
+ xlog_recover_print_trans(log, trans, &trans->r_itemq, 3);
return 0;
}
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index f41a18f00..a9fca82f1 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -536,7 +536,10 @@ rebuild_bmap(
if (nextents == 0)
return 0;
(*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
- (*dinop)->di_nextents32 = 0;
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ (*dinop)->di_nextents64 = cpu_to_be64(0);
+ else
+ (*dinop)->di_nextents32 = cpu_to_be32(0);
libxfs_dinode_calc_crc(mp, *dinop);
*dirty = 1;
break;
@@ -547,7 +550,10 @@ rebuild_bmap(
if (nextents == 0)
return 0;
(*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
- (*dinop)->di_nextents16 = 0;
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ (*dinop)->di_nextents32 = cpu_to_be32(0);
+ else
+ (*dinop)->di_nextents16 = cpu_to_be16(0);
libxfs_dinode_calc_crc(mp, *dinop);
*dirty = 1;
break;
diff --git a/repair/dinode.c b/repair/dinode.c
index beeb9ed07..5d2dff70a 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -78,7 +78,10 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
if (anextents != 0) {
if (no_modify)
return(1);
- dino->di_nextents16 = cpu_to_be16(0);
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ dino->di_nextents32 = cpu_to_be32(0);
+ else
+ dino->di_nextents16 = cpu_to_be16(0);
}
if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
@@ -1870,7 +1873,10 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, nextents);
- dino->di_nextents32 = cpu_to_be32(nextents);
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ dino->di_nextents64 = cpu_to_be64(nextents);
+ else
+ dino->di_nextents32 = cpu_to_be32(nextents);
*dirty = 1;
} else {
do_warn(
@@ -1894,7 +1900,10 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
do_warn(
_("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
lino, dnextents, anextents);
- dino->di_nextents16 = cpu_to_be16(anextents);
+ if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
+ dino->di_nextents32 = cpu_to_be32(anextents);
+ else
+ dino->di_nextents16 = cpu_to_be16(anextents);
*dirty = 1;
} else {
do_warn(
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths
2021-07-26 11:47 ` [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths Chandan Babu R
@ 2021-07-28 19:11 ` Darrick J. Wong
2021-07-29 7:26 ` Chandan Babu R
0 siblings, 1 reply; 19+ messages in thread
From: Darrick J. Wong @ 2021-07-28 19:11 UTC (permalink / raw)
To: Chandan Babu R; +Cc: linux-xfs
On Mon, Jul 26, 2021 at 05:17:23PM +0530, Chandan Babu R wrote:
> This commit adds a new 64-bit per-inode data extent counter. However the
> maximum number of extents that a data fork can hold is limited to 2^48
> extents. This feature is available only when
> XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT feature bit is enabled on the
> filesystem. Also, enabling this feature bit causes attr fork extent counter to
> use the 32-bit extent counter that was previously used to hold the data fork
> extent counter. This implies that the attr fork can now occupy a maximum of
> 2^32 extents.
>
> Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
> ---
> db/field.c | 4 ----
> db/field.h | 2 --
> db/inode.c | 30 +++++++++++++++++++++++++++---
> include/libxlog.h | 6 ++++--
> libxfs/xfs_bmap.c | 8 +++-----
> libxfs/xfs_format.h | 15 +++++++++++++--
> libxfs/xfs_inode_buf.c | 30 +++++++++++++++++++++++++-----
> libxfs/xfs_inode_fork.h | 18 ++++++++++++++----
> libxfs/xfs_log_format.h | 3 ++-
> logprint/log_misc.c | 23 ++++++++++++++++++-----
> logprint/log_print_all.c | 34 +++++++++++++++++++++++++++-------
> logprint/log_print_trans.c | 2 +-
> repair/bmap_repair.c | 10 ++++++++--
> repair/dinode.c | 15 ++++++++++++---
> 14 files changed, 154 insertions(+), 46 deletions(-)
>
> diff --git a/db/field.c b/db/field.c
> index 51268938a..1e274ffc4 100644
> --- a/db/field.c
> +++ b/db/field.c
> @@ -25,8 +25,6 @@
> #include "symlink.h"
>
> const ftattr_t ftattrtab[] = {
> - { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)),
> - FTARG_SIGNED, NULL, NULL },
> { FLDT_AGBLOCK, "agblock", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
> FTARG_DONULL, fa_agblock, NULL },
> { FLDT_AGBLOCKNZ, "agblocknz", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
> @@ -300,8 +298,6 @@ const ftattr_t ftattrtab[] = {
> FTARG_DONULL, fa_drtbno, NULL },
> { FLDT_EXTLEN, "extlen", fp_num, "%u", SI(bitsz(xfs_extlen_t)), 0, NULL,
> NULL },
> - { FLDT_EXTNUM, "extnum", fp_num, "%d", SI(bitsz(xfs_extnum_t)),
> - FTARG_SIGNED, NULL, NULL },
> { FLDT_FSIZE, "fsize", fp_num, "%lld", SI(bitsz(xfs_fsize_t)),
> FTARG_SIGNED, NULL, NULL },
> { FLDT_INO, "ino", fp_num, "%llu", SI(bitsz(xfs_ino_t)), FTARG_DONULL,
> diff --git a/db/field.h b/db/field.h
> index 387c189ec..614fd0ab4 100644
> --- a/db/field.h
> +++ b/db/field.h
> @@ -5,7 +5,6 @@
> */
>
> typedef enum fldt {
> - FLDT_AEXTNUM,
> FLDT_AGBLOCK,
> FLDT_AGBLOCKNZ,
> FLDT_AGF,
> @@ -143,7 +142,6 @@ typedef enum fldt {
> FLDT_DRFSBNO,
> FLDT_DRTBNO,
> FLDT_EXTLEN,
> - FLDT_EXTNUM,
> FLDT_FSIZE,
> FLDT_INO,
> FLDT_INOBT,
> diff --git a/db/inode.c b/db/inode.c
> index 27251f02f..6f941184c 100644
> --- a/db/inode.c
> +++ b/db/inode.c
> @@ -37,6 +37,8 @@ static int inode_u_muuid_count(void *obj, int startoff);
> static int inode_u_sfdir2_count(void *obj, int startoff);
> static int inode_u_sfdir3_count(void *obj, int startoff);
> static int inode_u_symlink_count(void *obj, int startoff);
> +static int inode_v3_64bitext_count(void *obj, int startoff);
> +static int inode_v3_pad2_count(void *obj, int startoff);
>
> static const cmdinfo_t inode_cmd =
> { "inode", NULL, inode_f, 0, 1, 1, "[inode#]",
> @@ -100,8 +102,8 @@ const field_t inode_core_flds[] = {
> { "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
> { "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
> { "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
> - { "nextents32", FLDT_EXTNUM, OI(COFF(nextents32)), C1, 0, TYP_NONE },
> - { "nextents16", FLDT_AEXTNUM, OI(COFF(nextents16)), C1, 0, TYP_NONE },
> + { "nextents32", FLDT_UINT32D, OI(COFF(nextents32)), C1, 0, TYP_NONE },
> + { "nextents16", FLDT_UINT16D, OI(COFF(nextents16)), C1, 0, TYP_NONE },
> { "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
> { "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
> { "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
> @@ -162,7 +164,10 @@ const field_t inode_v3_flds[] = {
> { "lsn", FLDT_UINT64X, OI(COFF(lsn)), C1, 0, TYP_NONE },
> { "flags2", FLDT_UINT64X, OI(COFF(flags2)), C1, 0, TYP_NONE },
> { "cowextsize", FLDT_EXTLEN, OI(COFF(cowextsize)), C1, 0, TYP_NONE },
> - { "pad2", FLDT_UINT8X, OI(OFF(pad2)), CI(12), FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
> + { "nextents64", FLDT_UINT64D, OI(COFF(nextents64)),
> + inode_v3_64bitext_count, FLD_COUNT, TYP_NONE },
> + { "pad2", FLDT_UINT8X, OI(OFF(pad2)), inode_v3_pad2_count,
> + FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
> { "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE },
> { "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE },
> { "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE },
> @@ -410,6 +415,25 @@ inode_core_projid_count(
> return dic->di_version >= 2;
> }
>
> +static int
> +inode_v3_64bitext_count(
> + void *obj,
> + int startoff)
> +{
> + return xfs_sb_version_hasextcount_64bit(&mp->m_sb);
> +}
> +
> +static int
> +inode_v3_pad2_count(
> + void *obj,
> + int startoff)
> +{
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + return 4;
> + else
> + return 12;
> +}
> +
> static int
> inode_f(
> int argc,
> diff --git a/include/libxlog.h b/include/libxlog.h
> index adaa9963c..fe30481cf 100644
> --- a/include/libxlog.h
> +++ b/include/libxlog.h
> @@ -89,13 +89,15 @@ extern int xlog_find_tail(struct xlog *log, xfs_daddr_t *head_blk,
>
> extern int xlog_recover(struct xlog *log, int readonly);
> extern void xlog_recover_print_data(char *p, int len);
> -extern void xlog_recover_print_logitem(struct xlog_recover_item *item);
> +extern void xlog_recover_print_logitem(struct xlog *log,
> + struct xlog_recover_item *item);
> extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
> extern int xlog_print_find_oldest(struct xlog *log, xfs_daddr_t *last_blk);
>
> /* for transactional view */
> extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
> -extern void xlog_recover_print_trans(struct xlog_recover *trans,
> +extern void xlog_recover_print_trans(struct xlog *log,
> + struct xlog_recover *trans,
> struct list_head *itemq, int print);
> extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk,
> xfs_daddr_t tail_blk, int pass);
> diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
> index dd60d8105..155d1e935 100644
> --- a/libxfs/xfs_bmap.c
> +++ b/libxfs/xfs_bmap.c
> @@ -47,18 +47,16 @@ xfs_bmap_compute_maxlevels(
> int whichfork) /* data or attr fork */
> {
> xfs_extnum_t maxleafents; /* max leaf entries possible */
> + uint64_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 */
> 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
> diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
> index 6564bc135..db3085974 100644
> --- a/libxfs/xfs_format.h
> +++ b/libxfs/xfs_format.h
> @@ -485,13 +485,15 @@ xfs_sb_has_ro_compat_feature(
> #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_METADIR (1 << 5) /* metadata dir tree */
> +#define XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT (1 << 6) /* 64-bit inode fork extent counters */
Extra space here ^^^
> #define XFS_SB_FEAT_INCOMPAT_ALL \
> (XFS_SB_FEAT_INCOMPAT_FTYPE| \
> 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_METADIR)
> + XFS_SB_FEAT_INCOMPAT_METADIR| \
> + XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT)
Adding NREXT64 to XFS_SB_FEAT_INCOMPAT_ALL should be a separate patch
just prior to the mkfs patch so that anyone trying to bisect the kernel
or xfsprogs on a system with nrext64 enabled will not land in the middle
of your patchset. We really do not want bisect runners to end up with
half-brained tools that think they can touch the filesystem.
> #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
> static inline bool
> @@ -591,6 +593,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp)
> (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID);
> }
>
> +static inline bool xfs_sb_version_hasextcount_64bit(struct xfs_sb *sbp)
> +{
> + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
> + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT);
> +}
> +
> static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp)
> {
> return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
> @@ -1057,7 +1065,8 @@ typedef struct xfs_dinode {
> __be64 di_lsn; /* flush sequence */
> __be64 di_flags2; /* more random flags */
> __be32 di_cowextsize; /* basic cow extent size for file */
> - __u8 di_pad2[12]; /* more padding for future expansion */
> + __u8 di_pad2[4]; /* more padding for future expansion */
> + __be64 di_nextents64; /* 64-bit extent counter */
>
> /* fields only written to during inode creation */
> xfs_timestamp_t di_crtime; /* time created */
> @@ -1113,6 +1122,8 @@ enum xfs_dinode_fmt {
> * Max values for extlen, disk inode's extent counters.
> */
> #define MAXEXTLEN ((uint32_t)0x1fffff) /* 21 bits */
> +#define XFS_IFORK_EXTCNT_MAXU48 ((uint64_t)0xffffffffffff) /* Unsigned 48-bits */
> +#define XFS_IFORK_EXTCNT_MAXU32 ((uint32_t)0xffffffff) /* Unsigned 32-bits */
Nit: extra space here ^^^
--D
> #define XFS_IFORK_EXTCNT_MAXS32 ((int32_t)0x7fffffff) /* Signed 32-bits */
> #define XFS_IFORK_EXTCNT_MAXS16 ((int16_t)0x7fff) /* Signed 16-bits */
>
> diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
> index 95fd95cc0..25877251f 100644
> --- a/libxfs/xfs_inode_buf.c
> +++ b/libxfs/xfs_inode_buf.c
> @@ -288,6 +288,7 @@ xfs_inode_to_disk(
> struct xfs_dinode *to,
> xfs_lsn_t lsn)
> {
> + struct xfs_sb *sbp = &ip->i_mount->m_sb;
> struct inode *inode = VFS_I(ip);
>
> to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
> @@ -307,11 +308,9 @@ xfs_inode_to_disk(
> to->di_gen = cpu_to_be32(inode->i_generation);
> to->di_mode = cpu_to_be16(inode->i_mode);
>
> - to->di_size = cpu_to_be64(ip->i_disk_size);
> + 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_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> - to->di_nextents16 = 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);
> @@ -331,6 +330,19 @@ xfs_inode_to_disk(
> to->di_version = 2;
> to->di_flushiter = cpu_to_be16(ip->i_flushiter);
> }
> +
> + if (xfs_sb_version_hasextcount_64bit(sbp)) {
> + to->di_nextents64 = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
> + to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
> + /*
> + * xchk_dinode() passes an uninitialized disk inode. Hence,
> + * clear di_nextents16 field explicitly.
> + */
> + to->di_nextents16 = cpu_to_be16(0);
> + } else {
> + to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> + to->di_nextents16 = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
> + }
> }
>
> static xfs_failaddr_t
> @@ -383,14 +395,22 @@ xfs_dfork_nextents(
> xfs_extnum_t *nextents)
> {
> int error = 0;
> + bool has_64bit_extcnt;
> +
> + has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
> +
> + if (has_64bit_extcnt && dip->di_nextents16 != 0)
> + return -EFSCORRUPTED;
>
> switch (whichfork) {
> case XFS_DATA_FORK:
> - *nextents = be32_to_cpu(dip->di_nextents32);
> + *nextents = has_64bit_extcnt ? be64_to_cpu(dip->di_nextents64)
> + : be32_to_cpu(dip->di_nextents32);
> break;
>
> case XFS_ATTR_FORK:
> - *nextents = be16_to_cpu(dip->di_nextents16);
> + *nextents = has_64bit_extcnt ? be32_to_cpu(dip->di_nextents32)
> + : be16_to_cpu(dip->di_nextents16);
> break;
>
> default:
> diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
> index 1eda21636..cc8145941 100644
> --- a/libxfs/xfs_inode_fork.h
> +++ b/libxfs/xfs_inode_fork.h
> @@ -135,10 +135,20 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
>
> static inline xfs_extnum_t xfs_iext_max(struct xfs_mount *mp, int whichfork)
> {
> - if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
> - return XFS_IFORK_EXTCNT_MAXS32;
> - else
> - return XFS_IFORK_EXTCNT_MAXS16;
> + bool has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
> +
> + switch (whichfork) {
> + case XFS_DATA_FORK:
> + case XFS_COW_FORK:
> + return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU48 : XFS_IFORK_EXTCNT_MAXS32;
> +
> + case XFS_ATTR_FORK:
> + return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU32 : XFS_IFORK_EXTCNT_MAXS16;
> +
> + default:
> + ASSERT(0);
> + return 0;
> + }
> }
>
> struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
> diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
> index ca8e4ad83..9b5d64708 100644
> --- a/libxfs/xfs_log_format.h
> +++ b/libxfs/xfs_log_format.h
> @@ -420,7 +420,8 @@ struct xfs_log_dinode {
> xfs_lsn_t di_lsn; /* flush sequence */
> uint64_t di_flags2; /* more random flags */
> uint32_t di_cowextsize; /* basic cow extent size for file */
> - uint8_t di_pad2[12]; /* more padding for future expansion */
> + uint8_t di_pad2[4]; /* more padding for future expansion */
> + uint64_t di_nextents64; /* higher part of data fork extent count */
>
> /* fields only written to during inode creation */
> xfs_log_timestamp_t di_crtime; /* time created */
> diff --git a/logprint/log_misc.c b/logprint/log_misc.c
> index 4e8760c43..1fb580c58 100644
> --- a/logprint/log_misc.c
> +++ b/logprint/log_misc.c
> @@ -438,8 +438,11 @@ xlog_print_trans_qoff(char **ptr, uint len)
>
> static void
> xlog_print_trans_inode_core(
> + struct xfs_mount *mp,
> struct xfs_log_dinode *ip)
> {
> + xfs_extnum_t nextents;
> +
> printf(_("INODE CORE\n"));
> printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
> ip->di_magic, ip->di_mode, (int)ip->di_version,
> @@ -450,11 +453,21 @@ xlog_print_trans_inode_core(
> xlog_extract_dinode_ts(ip->di_atime),
> xlog_extract_dinode_ts(ip->di_mtime),
> xlog_extract_dinode_ts(ip->di_ctime));
> - printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
> +
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + nextents = ip->di_nextents64;
> + else
> + nextents = ip->di_nextents32;
> + printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%lx\n"),
> (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
> - ip->di_extsize, ip->di_nextents32);
> - printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
> - ip->di_nextents16, (int)ip->di_forkoff, ip->di_dmevmask,
> + ip->di_extsize, nextents);
> +
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + nextents = ip->di_nextents32;
> + else
> + nextents = ip->di_nextents16;
> + printf(_("naextents 0x%lx forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
> + nextents, (int)ip->di_forkoff, ip->di_dmevmask,
> ip->di_dmstate);
> printf(_("flags 0x%x gen 0x%x\n"),
> ip->di_flags, ip->di_gen);
> @@ -564,7 +577,7 @@ xlog_print_trans_inode(
> memmove(&dino, *ptr, sizeof(dino));
> mode = dino.di_mode & S_IFMT;
> size = (int)dino.di_size;
> - xlog_print_trans_inode_core(&dino);
> + xlog_print_trans_inode_core(log->l_mp, &dino);
> *ptr += xfs_log_dinode_size(log->l_mp);
> skip_count--;
>
> diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
> index 403c56372..b528e1c57 100644
> --- a/logprint/log_print_all.c
> +++ b/logprint/log_print_all.c
> @@ -238,9 +238,14 @@ xlog_recover_print_dquot(
>
> STATIC void
> xlog_recover_print_inode_core(
> + struct xlog *log,
> struct xfs_log_dinode *di)
> {
> - printf(_(" CORE inode:\n"));
> + struct xfs_sb *sbp = &log->l_mp->m_sb;
> + xfs_extnum_t nextents;
> + xfs_aextnum_t anextents;
> +
> + printf(_(" CORE inode:\n"));
> if (!print_inode)
> return;
> printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"),
> @@ -254,10 +259,21 @@ xlog_recover_print_inode_core(
> xlog_extract_dinode_ts(di->di_mtime),
> xlog_extract_dinode_ts(di->di_ctime));
> printf(_(" flushiter:%d\n"), di->di_flushiter);
> +
> + if (xfs_sb_version_hasextcount_64bit(sbp))
> + nextents = di->di_nextents64;
> + else
> + nextents = di->di_nextents32;
> +
> + if (xfs_sb_version_hasextcount_64bit(sbp))
> + anextents = di->di_nextents32;
> + else
> + anextents = di->di_nextents16;
> +
> printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
> - "nextents:%d anextents:%d\n"), (unsigned long long)
> + "nextents:%lu anextents:%u\n"), (unsigned long long)
> di->di_size, (unsigned long long)di->di_nblocks,
> - di->di_extsize, di->di_nextents32, (int)di->di_nextents16);
> + di->di_extsize, nextents, anextents);
> printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
> "gen:%u\n"),
> (int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
> @@ -270,6 +286,7 @@ xlog_recover_print_inode_core(
>
> STATIC void
> xlog_recover_print_inode(
> + struct xlog *log,
> struct xlog_recover_item *item)
> {
> struct xfs_inode_log_format f_buf;
> @@ -291,7 +308,7 @@ xlog_recover_print_inode(
> ASSERT(item->ri_buf[1].i_len ==
> offsetof(struct xfs_log_dinode, di_next_unlinked) ||
> item->ri_buf[1].i_len == sizeof(struct xfs_log_dinode));
> - xlog_recover_print_inode_core((struct xfs_log_dinode *)
> + xlog_recover_print_inode_core(log, (struct xfs_log_dinode *)
> item->ri_buf[1].i_addr);
>
> hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0;
> @@ -386,6 +403,7 @@ xlog_recover_print_icreate(
>
> void
> xlog_recover_print_logitem(
> + struct xlog *log,
> struct xlog_recover_item *item)
> {
> switch (ITEM_TYPE(item)) {
> @@ -396,7 +414,7 @@ xlog_recover_print_logitem(
> xlog_recover_print_icreate(item);
> break;
> case XFS_LI_INODE:
> - xlog_recover_print_inode(item);
> + xlog_recover_print_inode(log, item);
> break;
> case XFS_LI_EFD:
> xlog_recover_print_efd(item);
> @@ -442,6 +460,7 @@ xlog_recover_print_logitem(
>
> static void
> xlog_recover_print_item(
> + struct xlog *log,
> struct xlog_recover_item *item)
> {
> int i;
> @@ -507,11 +526,12 @@ xlog_recover_print_item(
> (long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len);
> }
> printf("\n");
> - xlog_recover_print_logitem(item);
> + xlog_recover_print_logitem(log, item);
> }
>
> void
> xlog_recover_print_trans(
> + struct xlog *log,
> struct xlog_recover *trans,
> struct list_head *itemq,
> int print)
> @@ -524,5 +544,5 @@ xlog_recover_print_trans(
> print_xlog_record_line();
> xlog_recover_print_trans_head(trans);
> list_for_each_entry(item, itemq, ri_list)
> - xlog_recover_print_item(item);
> + xlog_recover_print_item(log, item);
> }
> diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c
> index 2004b5a0e..c6386fb0c 100644
> --- a/logprint/log_print_trans.c
> +++ b/logprint/log_print_trans.c
> @@ -24,7 +24,7 @@ xlog_recover_do_trans(
> struct xlog_recover *trans,
> int pass)
> {
> - xlog_recover_print_trans(trans, &trans->r_itemq, 3);
> + xlog_recover_print_trans(log, trans, &trans->r_itemq, 3);
> return 0;
> }
>
> diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
> index f41a18f00..a9fca82f1 100644
> --- a/repair/bmap_repair.c
> +++ b/repair/bmap_repair.c
> @@ -536,7 +536,10 @@ rebuild_bmap(
> if (nextents == 0)
> return 0;
> (*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
> - (*dinop)->di_nextents32 = 0;
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + (*dinop)->di_nextents64 = cpu_to_be64(0);
> + else
> + (*dinop)->di_nextents32 = cpu_to_be32(0);
> libxfs_dinode_calc_crc(mp, *dinop);
> *dirty = 1;
> break;
> @@ -547,7 +550,10 @@ rebuild_bmap(
> if (nextents == 0)
> return 0;
> (*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
> - (*dinop)->di_nextents16 = 0;
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + (*dinop)->di_nextents32 = cpu_to_be32(0);
> + else
> + (*dinop)->di_nextents16 = cpu_to_be16(0);
> libxfs_dinode_calc_crc(mp, *dinop);
> *dirty = 1;
> break;
> diff --git a/repair/dinode.c b/repair/dinode.c
> index beeb9ed07..5d2dff70a 100644
> --- a/repair/dinode.c
> +++ b/repair/dinode.c
> @@ -78,7 +78,10 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
> if (anextents != 0) {
> if (no_modify)
> return(1);
> - dino->di_nextents16 = cpu_to_be16(0);
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + dino->di_nextents32 = cpu_to_be32(0);
> + else
> + dino->di_nextents16 = cpu_to_be16(0);
> }
>
> if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
> @@ -1870,7 +1873,10 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> do_warn(
> _("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
> lino, dnextents, nextents);
> - dino->di_nextents32 = cpu_to_be32(nextents);
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + dino->di_nextents64 = cpu_to_be64(nextents);
> + else
> + dino->di_nextents32 = cpu_to_be32(nextents);
> *dirty = 1;
> } else {
> do_warn(
> @@ -1894,7 +1900,10 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
> do_warn(
> _("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
> lino, dnextents, anextents);
> - dino->di_nextents16 = cpu_to_be16(anextents);
> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
> + dino->di_nextents32 = cpu_to_be32(anextents);
> + else
> + dino->di_nextents16 = cpu_to_be16(anextents);
> *dirty = 1;
> } else {
> do_warn(
> --
> 2.30.2
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths
2021-07-28 19:11 ` Darrick J. Wong
@ 2021-07-29 7:26 ` Chandan Babu R
0 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-29 7:26 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs
On 29 Jul 2021 at 00:41, Darrick J. Wong wrote:
> On Mon, Jul 26, 2021 at 05:17:23PM +0530, Chandan Babu R wrote:
>> This commit adds a new 64-bit per-inode data extent counter. However the
>> maximum number of extents that a data fork can hold is limited to 2^48
>> extents. This feature is available only when
>> XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT feature bit is enabled on the
>> filesystem. Also, enabling this feature bit causes attr fork extent counter to
>> use the 32-bit extent counter that was previously used to hold the data fork
>> extent counter. This implies that the attr fork can now occupy a maximum of
>> 2^32 extents.
>>
>> Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
>> ---
>> db/field.c | 4 ----
>> db/field.h | 2 --
>> db/inode.c | 30 +++++++++++++++++++++++++++---
>> include/libxlog.h | 6 ++++--
>> libxfs/xfs_bmap.c | 8 +++-----
>> libxfs/xfs_format.h | 15 +++++++++++++--
>> libxfs/xfs_inode_buf.c | 30 +++++++++++++++++++++++++-----
>> libxfs/xfs_inode_fork.h | 18 ++++++++++++++----
>> libxfs/xfs_log_format.h | 3 ++-
>> logprint/log_misc.c | 23 ++++++++++++++++++-----
>> logprint/log_print_all.c | 34 +++++++++++++++++++++++++++-------
>> logprint/log_print_trans.c | 2 +-
>> repair/bmap_repair.c | 10 ++++++++--
>> repair/dinode.c | 15 ++++++++++++---
>> 14 files changed, 154 insertions(+), 46 deletions(-)
>>
>> diff --git a/db/field.c b/db/field.c
>> index 51268938a..1e274ffc4 100644
>> --- a/db/field.c
>> +++ b/db/field.c
>> @@ -25,8 +25,6 @@
>> #include "symlink.h"
>>
>> const ftattr_t ftattrtab[] = {
>> - { FLDT_AEXTNUM, "aextnum", fp_num, "%d", SI(bitsz(xfs_aextnum_t)),
>> - FTARG_SIGNED, NULL, NULL },
>> { FLDT_AGBLOCK, "agblock", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
>> FTARG_DONULL, fa_agblock, NULL },
>> { FLDT_AGBLOCKNZ, "agblocknz", fp_num, "%u", SI(bitsz(xfs_agblock_t)),
>> @@ -300,8 +298,6 @@ const ftattr_t ftattrtab[] = {
>> FTARG_DONULL, fa_drtbno, NULL },
>> { FLDT_EXTLEN, "extlen", fp_num, "%u", SI(bitsz(xfs_extlen_t)), 0, NULL,
>> NULL },
>> - { FLDT_EXTNUM, "extnum", fp_num, "%d", SI(bitsz(xfs_extnum_t)),
>> - FTARG_SIGNED, NULL, NULL },
>> { FLDT_FSIZE, "fsize", fp_num, "%lld", SI(bitsz(xfs_fsize_t)),
>> FTARG_SIGNED, NULL, NULL },
>> { FLDT_INO, "ino", fp_num, "%llu", SI(bitsz(xfs_ino_t)), FTARG_DONULL,
>> diff --git a/db/field.h b/db/field.h
>> index 387c189ec..614fd0ab4 100644
>> --- a/db/field.h
>> +++ b/db/field.h
>> @@ -5,7 +5,6 @@
>> */
>>
>> typedef enum fldt {
>> - FLDT_AEXTNUM,
>> FLDT_AGBLOCK,
>> FLDT_AGBLOCKNZ,
>> FLDT_AGF,
>> @@ -143,7 +142,6 @@ typedef enum fldt {
>> FLDT_DRFSBNO,
>> FLDT_DRTBNO,
>> FLDT_EXTLEN,
>> - FLDT_EXTNUM,
>> FLDT_FSIZE,
>> FLDT_INO,
>> FLDT_INOBT,
>> diff --git a/db/inode.c b/db/inode.c
>> index 27251f02f..6f941184c 100644
>> --- a/db/inode.c
>> +++ b/db/inode.c
>> @@ -37,6 +37,8 @@ static int inode_u_muuid_count(void *obj, int startoff);
>> static int inode_u_sfdir2_count(void *obj, int startoff);
>> static int inode_u_sfdir3_count(void *obj, int startoff);
>> static int inode_u_symlink_count(void *obj, int startoff);
>> +static int inode_v3_64bitext_count(void *obj, int startoff);
>> +static int inode_v3_pad2_count(void *obj, int startoff);
>>
>> static const cmdinfo_t inode_cmd =
>> { "inode", NULL, inode_f, 0, 1, 1, "[inode#]",
>> @@ -100,8 +102,8 @@ const field_t inode_core_flds[] = {
>> { "size", FLDT_FSIZE, OI(COFF(size)), C1, 0, TYP_NONE },
>> { "nblocks", FLDT_DRFSBNO, OI(COFF(nblocks)), C1, 0, TYP_NONE },
>> { "extsize", FLDT_EXTLEN, OI(COFF(extsize)), C1, 0, TYP_NONE },
>> - { "nextents32", FLDT_EXTNUM, OI(COFF(nextents32)), C1, 0, TYP_NONE },
>> - { "nextents16", FLDT_AEXTNUM, OI(COFF(nextents16)), C1, 0, TYP_NONE },
>> + { "nextents32", FLDT_UINT32D, OI(COFF(nextents32)), C1, 0, TYP_NONE },
>> + { "nextents16", FLDT_UINT16D, OI(COFF(nextents16)), C1, 0, TYP_NONE },
>> { "forkoff", FLDT_UINT8D, OI(COFF(forkoff)), C1, 0, TYP_NONE },
>> { "aformat", FLDT_DINODE_FMT, OI(COFF(aformat)), C1, 0, TYP_NONE },
>> { "dmevmask", FLDT_UINT32X, OI(COFF(dmevmask)), C1, 0, TYP_NONE },
>> @@ -162,7 +164,10 @@ const field_t inode_v3_flds[] = {
>> { "lsn", FLDT_UINT64X, OI(COFF(lsn)), C1, 0, TYP_NONE },
>> { "flags2", FLDT_UINT64X, OI(COFF(flags2)), C1, 0, TYP_NONE },
>> { "cowextsize", FLDT_EXTLEN, OI(COFF(cowextsize)), C1, 0, TYP_NONE },
>> - { "pad2", FLDT_UINT8X, OI(OFF(pad2)), CI(12), FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
>> + { "nextents64", FLDT_UINT64D, OI(COFF(nextents64)),
>> + inode_v3_64bitext_count, FLD_COUNT, TYP_NONE },
>> + { "pad2", FLDT_UINT8X, OI(OFF(pad2)), inode_v3_pad2_count,
>> + FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
>> { "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE },
>> { "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE },
>> { "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE },
>> @@ -410,6 +415,25 @@ inode_core_projid_count(
>> return dic->di_version >= 2;
>> }
>>
>> +static int
>> +inode_v3_64bitext_count(
>> + void *obj,
>> + int startoff)
>> +{
>> + return xfs_sb_version_hasextcount_64bit(&mp->m_sb);
>> +}
>> +
>> +static int
>> +inode_v3_pad2_count(
>> + void *obj,
>> + int startoff)
>> +{
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + return 4;
>> + else
>> + return 12;
>> +}
>> +
>> static int
>> inode_f(
>> int argc,
>> diff --git a/include/libxlog.h b/include/libxlog.h
>> index adaa9963c..fe30481cf 100644
>> --- a/include/libxlog.h
>> +++ b/include/libxlog.h
>> @@ -89,13 +89,15 @@ extern int xlog_find_tail(struct xlog *log, xfs_daddr_t *head_blk,
>>
>> extern int xlog_recover(struct xlog *log, int readonly);
>> extern void xlog_recover_print_data(char *p, int len);
>> -extern void xlog_recover_print_logitem(struct xlog_recover_item *item);
>> +extern void xlog_recover_print_logitem(struct xlog *log,
>> + struct xlog_recover_item *item);
>> extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
>> extern int xlog_print_find_oldest(struct xlog *log, xfs_daddr_t *last_blk);
>>
>> /* for transactional view */
>> extern void xlog_recover_print_trans_head(struct xlog_recover *tr);
>> -extern void xlog_recover_print_trans(struct xlog_recover *trans,
>> +extern void xlog_recover_print_trans(struct xlog *log,
>> + struct xlog_recover *trans,
>> struct list_head *itemq, int print);
>> extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk,
>> xfs_daddr_t tail_blk, int pass);
>> diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c
>> index dd60d8105..155d1e935 100644
>> --- a/libxfs/xfs_bmap.c
>> +++ b/libxfs/xfs_bmap.c
>> @@ -47,18 +47,16 @@ xfs_bmap_compute_maxlevels(
>> int whichfork) /* data or attr fork */
>> {
>> xfs_extnum_t maxleafents; /* max leaf entries possible */
>> + uint64_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 */
>> 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
>> diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
>> index 6564bc135..db3085974 100644
>> --- a/libxfs/xfs_format.h
>> +++ b/libxfs/xfs_format.h
>> @@ -485,13 +485,15 @@ xfs_sb_has_ro_compat_feature(
>> #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_METADIR (1 << 5) /* metadata dir tree */
>> +#define XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT (1 << 6) /* 64-bit inode fork extent counters */
>
> Extra space here ^^^
>
>> #define XFS_SB_FEAT_INCOMPAT_ALL \
>> (XFS_SB_FEAT_INCOMPAT_FTYPE| \
>> 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_METADIR)
>> + XFS_SB_FEAT_INCOMPAT_METADIR| \
>> + XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT)
>
> Adding NREXT64 to XFS_SB_FEAT_INCOMPAT_ALL should be a separate patch
> just prior to the mkfs patch so that anyone trying to bisect the kernel
> or xfsprogs on a system with nrext64 enabled will not land in the middle
> of your patchset. We really do not want bisect runners to end up with
> half-brained tools that think they can touch the filesystem.
Ok. I will fix that and the other two nits pointed out by you.
Thanks for the review.
>
>> #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
>> static inline bool
>> @@ -591,6 +593,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp)
>> (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID);
>> }
>>
>> +static inline bool xfs_sb_version_hasextcount_64bit(struct xfs_sb *sbp)
>> +{
>> + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
>> + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT);
>> +}
>> +
>> static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp)
>> {
>> return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
>> @@ -1057,7 +1065,8 @@ typedef struct xfs_dinode {
>> __be64 di_lsn; /* flush sequence */
>> __be64 di_flags2; /* more random flags */
>> __be32 di_cowextsize; /* basic cow extent size for file */
>> - __u8 di_pad2[12]; /* more padding for future expansion */
>> + __u8 di_pad2[4]; /* more padding for future expansion */
>> + __be64 di_nextents64; /* 64-bit extent counter */
>>
>> /* fields only written to during inode creation */
>> xfs_timestamp_t di_crtime; /* time created */
>> @@ -1113,6 +1122,8 @@ enum xfs_dinode_fmt {
>> * Max values for extlen, disk inode's extent counters.
>> */
>> #define MAXEXTLEN ((uint32_t)0x1fffff) /* 21 bits */
>> +#define XFS_IFORK_EXTCNT_MAXU48 ((uint64_t)0xffffffffffff) /* Unsigned 48-bits */
>> +#define XFS_IFORK_EXTCNT_MAXU32 ((uint32_t)0xffffffff) /* Unsigned 32-bits */
>
> Nit: extra space here ^^^
>
> --D
>
>> #define XFS_IFORK_EXTCNT_MAXS32 ((int32_t)0x7fffffff) /* Signed 32-bits */
>> #define XFS_IFORK_EXTCNT_MAXS16 ((int16_t)0x7fff) /* Signed 16-bits */
>>
>> diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
>> index 95fd95cc0..25877251f 100644
>> --- a/libxfs/xfs_inode_buf.c
>> +++ b/libxfs/xfs_inode_buf.c
>> @@ -288,6 +288,7 @@ xfs_inode_to_disk(
>> struct xfs_dinode *to,
>> xfs_lsn_t lsn)
>> {
>> + struct xfs_sb *sbp = &ip->i_mount->m_sb;
>> struct inode *inode = VFS_I(ip);
>>
>> to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
>> @@ -307,11 +308,9 @@ xfs_inode_to_disk(
>> to->di_gen = cpu_to_be32(inode->i_generation);
>> to->di_mode = cpu_to_be16(inode->i_mode);
>>
>> - to->di_size = cpu_to_be64(ip->i_disk_size);
>> + 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_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
>> - to->di_nextents16 = 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);
>> @@ -331,6 +330,19 @@ xfs_inode_to_disk(
>> to->di_version = 2;
>> to->di_flushiter = cpu_to_be16(ip->i_flushiter);
>> }
>> +
>> + if (xfs_sb_version_hasextcount_64bit(sbp)) {
>> + to->di_nextents64 = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
>> + to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
>> + /*
>> + * xchk_dinode() passes an uninitialized disk inode. Hence,
>> + * clear di_nextents16 field explicitly.
>> + */
>> + to->di_nextents16 = cpu_to_be16(0);
>> + } else {
>> + to->di_nextents32 = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
>> + to->di_nextents16 = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
>> + }
>> }
>>
>> static xfs_failaddr_t
>> @@ -383,14 +395,22 @@ xfs_dfork_nextents(
>> xfs_extnum_t *nextents)
>> {
>> int error = 0;
>> + bool has_64bit_extcnt;
>> +
>> + has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
>> +
>> + if (has_64bit_extcnt && dip->di_nextents16 != 0)
>> + return -EFSCORRUPTED;
>>
>> switch (whichfork) {
>> case XFS_DATA_FORK:
>> - *nextents = be32_to_cpu(dip->di_nextents32);
>> + *nextents = has_64bit_extcnt ? be64_to_cpu(dip->di_nextents64)
>> + : be32_to_cpu(dip->di_nextents32);
>> break;
>>
>> case XFS_ATTR_FORK:
>> - *nextents = be16_to_cpu(dip->di_nextents16);
>> + *nextents = has_64bit_extcnt ? be32_to_cpu(dip->di_nextents32)
>> + : be16_to_cpu(dip->di_nextents16);
>> break;
>>
>> default:
>> diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
>> index 1eda21636..cc8145941 100644
>> --- a/libxfs/xfs_inode_fork.h
>> +++ b/libxfs/xfs_inode_fork.h
>> @@ -135,10 +135,20 @@ static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
>>
>> static inline xfs_extnum_t xfs_iext_max(struct xfs_mount *mp, int whichfork)
>> {
>> - if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK)
>> - return XFS_IFORK_EXTCNT_MAXS32;
>> - else
>> - return XFS_IFORK_EXTCNT_MAXS16;
>> + bool has_64bit_extcnt = xfs_sb_version_hasextcount_64bit(&mp->m_sb);
>> +
>> + switch (whichfork) {
>> + case XFS_DATA_FORK:
>> + case XFS_COW_FORK:
>> + return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU48 : XFS_IFORK_EXTCNT_MAXS32;
>> +
>> + case XFS_ATTR_FORK:
>> + return has_64bit_extcnt ? XFS_IFORK_EXTCNT_MAXU32 : XFS_IFORK_EXTCNT_MAXS16;
>> +
>> + default:
>> + ASSERT(0);
>> + return 0;
>> + }
>> }
>>
>> struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
>> diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
>> index ca8e4ad83..9b5d64708 100644
>> --- a/libxfs/xfs_log_format.h
>> +++ b/libxfs/xfs_log_format.h
>> @@ -420,7 +420,8 @@ struct xfs_log_dinode {
>> xfs_lsn_t di_lsn; /* flush sequence */
>> uint64_t di_flags2; /* more random flags */
>> uint32_t di_cowextsize; /* basic cow extent size for file */
>> - uint8_t di_pad2[12]; /* more padding for future expansion */
>> + uint8_t di_pad2[4]; /* more padding for future expansion */
>> + uint64_t di_nextents64; /* higher part of data fork extent count */
>>
>> /* fields only written to during inode creation */
>> xfs_log_timestamp_t di_crtime; /* time created */
>> diff --git a/logprint/log_misc.c b/logprint/log_misc.c
>> index 4e8760c43..1fb580c58 100644
>> --- a/logprint/log_misc.c
>> +++ b/logprint/log_misc.c
>> @@ -438,8 +438,11 @@ xlog_print_trans_qoff(char **ptr, uint len)
>>
>> static void
>> xlog_print_trans_inode_core(
>> + struct xfs_mount *mp,
>> struct xfs_log_dinode *ip)
>> {
>> + xfs_extnum_t nextents;
>> +
>> printf(_("INODE CORE\n"));
>> printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
>> ip->di_magic, ip->di_mode, (int)ip->di_version,
>> @@ -450,11 +453,21 @@ xlog_print_trans_inode_core(
>> xlog_extract_dinode_ts(ip->di_atime),
>> xlog_extract_dinode_ts(ip->di_mtime),
>> xlog_extract_dinode_ts(ip->di_ctime));
>> - printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
>> +
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + nextents = ip->di_nextents64;
>> + else
>> + nextents = ip->di_nextents32;
>> + printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%lx\n"),
>> (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
>> - ip->di_extsize, ip->di_nextents32);
>> - printf(_("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
>> - ip->di_nextents16, (int)ip->di_forkoff, ip->di_dmevmask,
>> + ip->di_extsize, nextents);
>> +
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + nextents = ip->di_nextents32;
>> + else
>> + nextents = ip->di_nextents16;
>> + printf(_("naextents 0x%lx forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
>> + nextents, (int)ip->di_forkoff, ip->di_dmevmask,
>> ip->di_dmstate);
>> printf(_("flags 0x%x gen 0x%x\n"),
>> ip->di_flags, ip->di_gen);
>> @@ -564,7 +577,7 @@ xlog_print_trans_inode(
>> memmove(&dino, *ptr, sizeof(dino));
>> mode = dino.di_mode & S_IFMT;
>> size = (int)dino.di_size;
>> - xlog_print_trans_inode_core(&dino);
>> + xlog_print_trans_inode_core(log->l_mp, &dino);
>> *ptr += xfs_log_dinode_size(log->l_mp);
>> skip_count--;
>>
>> diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
>> index 403c56372..b528e1c57 100644
>> --- a/logprint/log_print_all.c
>> +++ b/logprint/log_print_all.c
>> @@ -238,9 +238,14 @@ xlog_recover_print_dquot(
>>
>> STATIC void
>> xlog_recover_print_inode_core(
>> + struct xlog *log,
>> struct xfs_log_dinode *di)
>> {
>> - printf(_(" CORE inode:\n"));
>> + struct xfs_sb *sbp = &log->l_mp->m_sb;
>> + xfs_extnum_t nextents;
>> + xfs_aextnum_t anextents;
>> +
>> + printf(_(" CORE inode:\n"));
>> if (!print_inode)
>> return;
>> printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"),
>> @@ -254,10 +259,21 @@ xlog_recover_print_inode_core(
>> xlog_extract_dinode_ts(di->di_mtime),
>> xlog_extract_dinode_ts(di->di_ctime));
>> printf(_(" flushiter:%d\n"), di->di_flushiter);
>> +
>> + if (xfs_sb_version_hasextcount_64bit(sbp))
>> + nextents = di->di_nextents64;
>> + else
>> + nextents = di->di_nextents32;
>> +
>> + if (xfs_sb_version_hasextcount_64bit(sbp))
>> + anextents = di->di_nextents32;
>> + else
>> + anextents = di->di_nextents16;
>> +
>> printf(_(" size:0x%llx nblks:0x%llx exsize:%d "
>> - "nextents:%d anextents:%d\n"), (unsigned long long)
>> + "nextents:%lu anextents:%u\n"), (unsigned long long)
>> di->di_size, (unsigned long long)di->di_nblocks,
>> - di->di_extsize, di->di_nextents32, (int)di->di_nextents16);
>> + di->di_extsize, nextents, anextents);
>> printf(_(" forkoff:%d dmevmask:0x%x dmstate:%d flags:0x%x "
>> "gen:%u\n"),
>> (int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate,
>> @@ -270,6 +286,7 @@ xlog_recover_print_inode_core(
>>
>> STATIC void
>> xlog_recover_print_inode(
>> + struct xlog *log,
>> struct xlog_recover_item *item)
>> {
>> struct xfs_inode_log_format f_buf;
>> @@ -291,7 +308,7 @@ xlog_recover_print_inode(
>> ASSERT(item->ri_buf[1].i_len ==
>> offsetof(struct xfs_log_dinode, di_next_unlinked) ||
>> item->ri_buf[1].i_len == sizeof(struct xfs_log_dinode));
>> - xlog_recover_print_inode_core((struct xfs_log_dinode *)
>> + xlog_recover_print_inode_core(log, (struct xfs_log_dinode *)
>> item->ri_buf[1].i_addr);
>>
>> hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0;
>> @@ -386,6 +403,7 @@ xlog_recover_print_icreate(
>>
>> void
>> xlog_recover_print_logitem(
>> + struct xlog *log,
>> struct xlog_recover_item *item)
>> {
>> switch (ITEM_TYPE(item)) {
>> @@ -396,7 +414,7 @@ xlog_recover_print_logitem(
>> xlog_recover_print_icreate(item);
>> break;
>> case XFS_LI_INODE:
>> - xlog_recover_print_inode(item);
>> + xlog_recover_print_inode(log, item);
>> break;
>> case XFS_LI_EFD:
>> xlog_recover_print_efd(item);
>> @@ -442,6 +460,7 @@ xlog_recover_print_logitem(
>>
>> static void
>> xlog_recover_print_item(
>> + struct xlog *log,
>> struct xlog_recover_item *item)
>> {
>> int i;
>> @@ -507,11 +526,12 @@ xlog_recover_print_item(
>> (long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len);
>> }
>> printf("\n");
>> - xlog_recover_print_logitem(item);
>> + xlog_recover_print_logitem(log, item);
>> }
>>
>> void
>> xlog_recover_print_trans(
>> + struct xlog *log,
>> struct xlog_recover *trans,
>> struct list_head *itemq,
>> int print)
>> @@ -524,5 +544,5 @@ xlog_recover_print_trans(
>> print_xlog_record_line();
>> xlog_recover_print_trans_head(trans);
>> list_for_each_entry(item, itemq, ri_list)
>> - xlog_recover_print_item(item);
>> + xlog_recover_print_item(log, item);
>> }
>> diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c
>> index 2004b5a0e..c6386fb0c 100644
>> --- a/logprint/log_print_trans.c
>> +++ b/logprint/log_print_trans.c
>> @@ -24,7 +24,7 @@ xlog_recover_do_trans(
>> struct xlog_recover *trans,
>> int pass)
>> {
>> - xlog_recover_print_trans(trans, &trans->r_itemq, 3);
>> + xlog_recover_print_trans(log, trans, &trans->r_itemq, 3);
>> return 0;
>> }
>>
>> diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
>> index f41a18f00..a9fca82f1 100644
>> --- a/repair/bmap_repair.c
>> +++ b/repair/bmap_repair.c
>> @@ -536,7 +536,10 @@ rebuild_bmap(
>> if (nextents == 0)
>> return 0;
>> (*dinop)->di_format = XFS_DINODE_FMT_EXTENTS;
>> - (*dinop)->di_nextents32 = 0;
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + (*dinop)->di_nextents64 = cpu_to_be64(0);
>> + else
>> + (*dinop)->di_nextents32 = cpu_to_be32(0);
>> libxfs_dinode_calc_crc(mp, *dinop);
>> *dirty = 1;
>> break;
>> @@ -547,7 +550,10 @@ rebuild_bmap(
>> if (nextents == 0)
>> return 0;
>> (*dinop)->di_aformat = XFS_DINODE_FMT_EXTENTS;
>> - (*dinop)->di_nextents16 = 0;
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + (*dinop)->di_nextents32 = cpu_to_be32(0);
>> + else
>> + (*dinop)->di_nextents16 = cpu_to_be16(0);
>> libxfs_dinode_calc_crc(mp, *dinop);
>> *dirty = 1;
>> break;
>> diff --git a/repair/dinode.c b/repair/dinode.c
>> index beeb9ed07..5d2dff70a 100644
>> --- a/repair/dinode.c
>> +++ b/repair/dinode.c
>> @@ -78,7 +78,10 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
>> if (anextents != 0) {
>> if (no_modify)
>> return(1);
>> - dino->di_nextents16 = cpu_to_be16(0);
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + dino->di_nextents32 = cpu_to_be32(0);
>> + else
>> + dino->di_nextents16 = cpu_to_be16(0);
>> }
>>
>> if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) {
>> @@ -1870,7 +1873,10 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
>> do_warn(
>> _("correcting nextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
>> lino, dnextents, nextents);
>> - dino->di_nextents32 = cpu_to_be32(nextents);
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + dino->di_nextents64 = cpu_to_be64(nextents);
>> + else
>> + dino->di_nextents32 = cpu_to_be32(nextents);
>> *dirty = 1;
>> } else {
>> do_warn(
>> @@ -1894,7 +1900,10 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"),
>> do_warn(
>> _("correcting anextents for inode %" PRIu64 ", was %lu - counted %" PRIu64 "\n"),
>> lino, dnextents, anextents);
>> - dino->di_nextents16 = cpu_to_be16(anextents);
>> + if (xfs_sb_version_hasextcount_64bit(&mp->m_sb))
>> + dino->di_nextents32 = cpu_to_be32(anextents);
>> + else
>> + dino->di_nextents16 = cpu_to_be16(anextents);
>> *dirty = 1;
>> } else {
>> do_warn(
>> --
>> 2.30.2
>>
--
chandan
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 12/12] xfsprogs: Add extcnt64bit mkfs option
2021-07-26 11:47 [PATCH V2 00/12] xfsprogs: Extend per-inode extent counters Chandan Babu R
` (10 preceding siblings ...)
2021-07-26 11:47 ` [PATCH V2 11/12] xfsprogs: Extend per-inode extent counter widths Chandan Babu R
@ 2021-07-26 11:47 ` Chandan Babu R
11 siblings, 0 replies; 19+ messages in thread
From: Chandan Babu R @ 2021-07-26 11:47 UTC (permalink / raw)
To: linux-xfs; +Cc: Chandan Babu R, djwong
Enabling extcnt64bit option on mkfs.xfs command line extends the maximum
values of inode data and attr fork extent counters to 2^48 - 1 and 2^32 - 1
respectively. This also sets the XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT incompat
flag on the superblock preventing older kernels from mounting such a
filesystem.
Signed-off-by: Chandan Babu R <chandanrlinux@gmail.com>
---
man/man8/mkfs.xfs.8 | 7 +++++++
mkfs/xfs_mkfs.c | 23 +++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 0e06e5bea..e20f6f475 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -650,6 +650,13 @@ space over time such that no free extents are large enough to
accommodate a chunk of 64 inodes. Without this feature enabled, inode
allocations can fail with out of space errors under severe fragmented
free space conditions.
+.TP
+.BI extcnt64bit[= value]
+Extend maximum values of inode data and attr fork extent counters from 2^31 -
+1 and 2^15 - 1 to 2^48 - 1 and 2^32 - 1 respectively. If the value is
+omitted, 1 is assumed. This feature is disabled by default. This feature is
+only available for filesystems formatted with -m crc=1.
+.TP
.RE
.PP
.PD 0
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 33b27b1f5..ac2b43188 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -78,6 +78,7 @@ enum {
I_ATTR,
I_PROJID32BIT,
I_SPINODES,
+ I_EXTCNT_64BIT,
I_MAX_OPTS,
};
@@ -433,6 +434,7 @@ static struct opt_params iopts = {
[I_ATTR] = "attr",
[I_PROJID32BIT] = "projid32bit",
[I_SPINODES] = "sparse",
+ [I_EXTCNT_64BIT] = "extcnt64bit",
},
.subopt_params = {
{ .index = I_ALIGN,
@@ -481,6 +483,12 @@ static struct opt_params iopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = I_EXTCNT_64BIT,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ }
},
};
@@ -813,6 +821,7 @@ struct sb_feat_args {
bool metadir; /* XFS_SB_FEAT_INCOMPAT_METADIR */
bool nodalign;
bool nortalign;
+ bool extcnt64bit;
};
struct cli_params {
@@ -1594,6 +1603,9 @@ inode_opts_parser(
case I_SPINODES:
cli->sb_feat.spinodes = getnum(value, opts, subopt);
break;
+ case I_EXTCNT_64BIT:
+ cli->sb_feat.extcnt64bit = getnum(value, opts, subopt);
+ break;
default:
return -EINVAL;
}
@@ -2172,6 +2184,14 @@ _("metadata directory not supported without CRC support\n"));
usage();
}
cli->sb_feat.metadir = false;
+
+ if (cli->sb_feat.extcnt64bit &&
+ cli_opt_set(&iopts, I_EXTCNT_64BIT)) {
+ fprintf(stderr,
+_("64 bit extent count not supported without CRC support\n"));
+ usage();
+ }
+ cli->sb_feat.extcnt64bit = false;
}
if (!cli->sb_feat.finobt) {
@@ -3166,6 +3186,8 @@ sb_set_features(
sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
}
+ if (fp->extcnt64bit)
+ sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_EXTCOUNT_64BIT;
}
/*
@@ -3876,6 +3898,7 @@ main(
.nodalign = false,
.nortalign = false,
.bigtime = false,
+ .extcnt64bit = false,
},
};
--
2.30.2
^ permalink raw reply related [flat|nested] 19+ messages in thread