Re: [PATCH V4 13/20] xfsprogs: Introduce per-inode 64-bit extent counters

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Dec 14, 2021 at 02:18:04PM +0530, Chandan Babu R wrote:
> This commit introduces new fields in the on-disk inode format to support
> 64-bit data fork extent counters and 32-bit attribute fork extent
> counters. The new fields will be used only when an inode has
> XFS_DIFLAG2_NREXT64 flag set. Otherwise we continue to use the regular 32-bit
> data fork extent counters and 16-bit attribute fork extent counters.
> 
> Signed-off-by: Chandan Babu R <chandan.babu@xxxxxxxxxx>
> Suggested-by: Dave Chinner <dchinner@xxxxxxxxxx>
> ---
>  db/field.c               |   4 -
>  db/field.h               |   2 -
>  db/inode.c               | 170 ++++++++++++++++++++++++++++++++++++++-
>  libxfs/xfs_format.h      |  22 ++++-
>  libxfs/xfs_inode_buf.c   |  27 ++++++-
>  libxfs/xfs_inode_fork.h  |  10 ++-
>  libxfs/xfs_log_format.h  |  22 ++++-
>  logprint/log_misc.c      |  20 ++++-
>  logprint/log_print_all.c |  18 ++++-
>  repair/dinode.c          |  18 ++++-
>  10 files changed, 279 insertions(+), 34 deletions(-)
> 
> diff --git a/db/field.c b/db/field.c
> index 51268938..1e274ffc 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 387c189e..614fd0ab 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 b1f92d36..226797be 100644
> --- a/db/inode.c
> +++ b/db/inode.c
> @@ -27,6 +27,14 @@ static int	inode_core_nlinkv2_count(void *obj, int startoff);
>  static int	inode_core_onlink_count(void *obj, int startoff);
>  static int	inode_core_projid_count(void *obj, int startoff);
>  static int	inode_core_nlinkv1_count(void *obj, int startoff);
> +static int	inode_core_big_dextcnt_count(void *obj, int startoff);
> +static int	inode_core_v3_pad_count(void *obj, int startoff);
> +static int	inode_core_v2_pad_count(void *obj, int startoff);
> +static int	inode_core_flushiter_count(void *obj, int startoff);
> +static int	inode_core_big_aextcnt_count(void *obj, int startoff);
> +static int	inode_core_nrext64_pad_count(void *obj, int startoff);
> +static int	inode_core_nextents_count(void *obj, int startoff);
> +static int	inode_core_anextents_count(void *obj, int startoff);
>  static int	inode_f(int argc, char **argv);
>  static int	inode_u_offset(void *obj, int startoff, int idx);
>  static int	inode_u_bmbt_count(void *obj, int startoff);
> @@ -90,18 +98,30 @@ const field_t	inode_core_flds[] = {
>  	  inode_core_projid_count, FLD_COUNT, TYP_NONE },
>  	{ "projid_hi", FLDT_UINT16D, OI(COFF(projid_hi)),
>  	  inode_core_projid_count, FLD_COUNT, TYP_NONE },
> -	{ "pad", FLDT_UINT8X, OI(OFF(pad)), CI(6), FLD_ARRAY|FLD_SKIPALL, TYP_NONE },
> +	{ "big_dextcnt", FLDT_UINT64D, OI(COFF(big_dextcnt)),

Any reason we don't leave the display names as nextents and naextents?
I think fstests has a fair amount of hardcoded xfs_db output, right?

> +	  inode_core_big_dextcnt_count, FLD_COUNT, TYP_NONE },
> +	{ "v3_pad", FLDT_UINT8X, OI(OFF(v3_pad)),
> +	  inode_core_v3_pad_count, FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
> +	{ "v2_pad", FLDT_UINT8X, OI(OFF(v2_pad)),
> +	  inode_core_v2_pad_count, FLD_ARRAY|FLD_COUNT|FLD_SKIPALL, TYP_NONE },
>  	{ "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE },
>  	{ "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE },
> -	{ "flushiter", FLDT_UINT16D, OI(COFF(flushiter)), C1, 0, TYP_NONE },
> +	{ "flushiter", FLDT_UINT16D, OI(COFF(flushiter)),
> +	  inode_core_flushiter_count, FLD_COUNT, TYP_NONE },
>  	{ "atime", FLDT_TIMESTAMP, OI(COFF(atime)), C1, 0, TYP_NONE },
>  	{ "mtime", FLDT_TIMESTAMP, OI(COFF(mtime)), C1, 0, TYP_NONE },
>  	{ "ctime", FLDT_TIMESTAMP, OI(COFF(ctime)), C1, 0, TYP_NONE },
>  	{ "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 },
> +	{ "big_aextcnt", FLDT_UINT32D, OI(COFF(big_aextcnt)),
> +	  inode_core_big_aextcnt_count, FLD_COUNT, TYP_NONE },
> +	{ "nrext64_pad", FLDT_UINT16D, OI(COFF(nrext64_pad)),
> +	  inode_core_nrext64_pad_count, FLD_COUNT, TYP_NONE },
> +	{ "nextents", FLDT_UINT32D, OI(COFF(nextents)),
> +	  inode_core_nextents_count, FLD_COUNT, TYP_NONE },
> +	{ "naextents", FLDT_UINT16D, OI(COFF(anextents)),
> +	  inode_core_anextents_count, FLD_COUNT, 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 },
> @@ -403,6 +423,148 @@ inode_core_projid_count(
>  	return dic->di_version >= 2;
>  }
>  
> +static int
> +inode_core_big_dextcnt_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if (dic->di_version == 3 &&
> +		(be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))

(dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64)) ?

(I forget, does userspace's version of those macros elide constants?)

--D

> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static int
> +inode_core_v3_pad_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if ((dic->di_version == 3)
> +		&& !(be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))
> +		return 8;
> +	else
> +		return 0;
> +}
> +
> +static int
> +inode_core_v2_pad_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if (dic->di_version == 3)
> +		return 0;
> +	else
> +		return 6;
> +}
> +
> +static int
> +inode_core_flushiter_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if (dic->di_version == 3)
> +		return 0;
> +	else
> +		return 1;
> +}
> +
> +static int
> +inode_core_big_aextcnt_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if (dic->di_version == 3 &&
> +		(be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static int
> +inode_core_nrext64_pad_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if (dic->di_version == 3 &&
> +		(be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +static int
> +inode_core_nextents_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if ((dic->di_version == 3)
> +		&& (be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))
> +		return 0;
> +	else
> +		return 1;
> +}
> +
> +static int
> +inode_core_anextents_count(
> +	void			*obj,
> +	int			startoff)
> +{
> +	struct xfs_dinode	*dic;
> +
> +	ASSERT(startoff == 0);
> +	ASSERT(obj == iocur_top->data);
> +	dic = obj;
> +
> +	if ((dic->di_version == 3)
> +		&& (be64_to_cpu(dic->di_flags2) & XFS_DIFLAG2_NREXT64))
> +		return 0;
> +	else
> +		return 1;
> +}
> +
>  static int
>  inode_f(
>  	int		argc,
> diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
> index bdd13ec9..d4c962fc 100644
> --- a/libxfs/xfs_format.h
> +++ b/libxfs/xfs_format.h
> @@ -980,16 +980,30 @@ typedef struct xfs_dinode {
>  	__be32		di_nlink;	/* number of links to file */
>  	__be16		di_projid_lo;	/* lower part of owner's project id */
>  	__be16		di_projid_hi;	/* higher part owner's project id */
> -	__u8		di_pad[6];	/* unused, zeroed space */
> -	__be16		di_flushiter;	/* incremented on flush */
> +	union {
> +		__be64	di_big_dextcnt;	/* NREXT64 data extents */
> +		__u8	di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
> +		struct {
> +			__u8	di_v2_pad[6];	/* V2 inode zeroed space */
> +			__be16	di_flushiter;	/* V2 inode incremented on flush */
> +		};
> +	};
>  	xfs_timestamp_t	di_atime;	/* time last accessed */
>  	xfs_timestamp_t	di_mtime;	/* time last modified */
>  	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
>  	__be64		di_size;	/* number of bytes in file */
>  	__be64		di_nblocks;	/* # of direct & btree blocks used */
>  	__be32		di_extsize;	/* basic/minimum extent size for file */
> -	__be32		di_nextents;	/* number of extents in data fork */
> -	__be16		di_anextents;	/* number of extents in attribute fork*/
> +	union {
> +		struct {
> +			__be32	di_big_aextcnt; /* NREXT64 attr extents */
> +			__be16	di_nrext64_pad; /* NREXT64 unused, zero */
> +		} __packed;
> +		struct {
> +			__be32	di_nextents;	/* !NREXT64 data extents */
> +			__be16	di_anextents;	/* !NREXT64 attr extents */
> +		} __packed;
> +	};
>  	__u8		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>  	__s8		di_aformat;	/* format of attr fork's data */
>  	__be32		di_dmevmask;	/* DMIG event mask */
> diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
> index 9bddf790..5c6de73b 100644
> --- a/libxfs/xfs_inode_buf.c
> +++ b/libxfs/xfs_inode_buf.c
> @@ -276,6 +276,25 @@ xfs_inode_to_disk_ts(
>  	return ts;
>  }
>  
> +static inline void
> +xfs_inode_to_disk_iext_counters(
> +	struct xfs_inode	*ip,
> +	struct xfs_dinode	*to)
> +{
> +	if (xfs_inode_has_nrext64(ip)) {
> +		to->di_big_dextcnt = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
> +		to->di_big_aextcnt = cpu_to_be32(xfs_ifork_nextents(ip->i_afp));
> +		/*
> +		 * We might be upgrading the inode to use larger extent counters
> +		 * than was previously used. Hence zero the unused field.
> +		 */
> +		to->di_nrext64_pad = cpu_to_be16(0);
> +	} else {
> +		to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> +		to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
> +	}
> +}
> +
>  void
>  xfs_inode_to_disk(
>  	struct xfs_inode	*ip,
> @@ -293,7 +312,6 @@ xfs_inode_to_disk(
>  	to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
>  	to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
>  
> -	memset(to->di_pad, 0, sizeof(to->di_pad));
>  	to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
>  	to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
>  	to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
> @@ -304,8 +322,6 @@ xfs_inode_to_disk(
>  	to->di_size = cpu_to_be64(ip->i_disk_size);
>  	to->di_nblocks = cpu_to_be64(ip->i_nblocks);
>  	to->di_extsize = cpu_to_be32(ip->i_extsize);
> -	to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
> -	to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
>  	to->di_forkoff = ip->i_forkoff;
>  	to->di_aformat = xfs_ifork_format(ip->i_afp);
>  	to->di_flags = cpu_to_be16(ip->i_diflags);
> @@ -320,11 +336,14 @@ xfs_inode_to_disk(
>  		to->di_lsn = cpu_to_be64(lsn);
>  		memset(to->di_pad2, 0, sizeof(to->di_pad2));
>  		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
> -		to->di_flushiter = 0;
> +		memset(to->di_v3_pad, 0, sizeof(to->di_v3_pad));
>  	} else {
>  		to->di_version = 2;
>  		to->di_flushiter = cpu_to_be16(ip->i_flushiter);
> +		memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
>  	}
> +
> +	xfs_inode_to_disk_iext_counters(ip, to);
>  }
>  
>  static xfs_failaddr_t
> diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
> index 7d5f0015..03036a2c 100644
> --- a/libxfs/xfs_inode_fork.h
> +++ b/libxfs/xfs_inode_fork.h
> @@ -156,14 +156,20 @@ static inline xfs_extnum_t
>  xfs_dfork_data_extents(
>  	struct xfs_dinode	*dip)
>  {
> -	return be32_to_cpu(dip->di_nextents);
> +	if (xfs_dinode_has_nrext64(dip))
> +		return be64_to_cpu(dip->di_big_dextcnt);
> +	else
> +		return be32_to_cpu(dip->di_nextents);
>  }
>  
>  static inline xfs_extnum_t
>  xfs_dfork_attr_extents(
>  	struct xfs_dinode	*dip)
>  {
> -	return be16_to_cpu(dip->di_anextents);
> +	if (xfs_dinode_has_nrext64(dip))
> +		return be32_to_cpu(dip->di_big_aextcnt);
> +	else
> +		return be16_to_cpu(dip->di_anextents);
>  }
>  
>  static inline xfs_extnum_t
> diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
> index c13608aa..8f8c9869 100644
> --- a/libxfs/xfs_log_format.h
> +++ b/libxfs/xfs_log_format.h
> @@ -388,16 +388,30 @@ struct xfs_log_dinode {
>  	uint32_t	di_nlink;	/* number of links to file */
>  	uint16_t	di_projid_lo;	/* lower part of owner's project id */
>  	uint16_t	di_projid_hi;	/* higher part of owner's project id */
> -	uint8_t		di_pad[6];	/* unused, zeroed space */
> -	uint16_t	di_flushiter;	/* incremented on flush */
> +	union {
> +		uint64_t	di_big_dextcnt;	/* NREXT64 data extents */
> +		uint8_t		di_v3_pad[8];	/* !NREXT64 V3 inode zeroed space */
> +		struct {
> +			uint8_t	di_v2_pad[6];	/* V2 inode zeroed space */
> +			uint16_t di_flushiter;	/* V2 inode incremented on flush */
> +		};
> +	};
>  	xfs_log_timestamp_t di_atime;	/* time last accessed */
>  	xfs_log_timestamp_t di_mtime;	/* time last modified */
>  	xfs_log_timestamp_t di_ctime;	/* time created/inode modified */
>  	xfs_fsize_t	di_size;	/* number of bytes in file */
>  	xfs_rfsblock_t	di_nblocks;	/* # of direct & btree blocks used */
>  	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
> -	uint32_t	di_nextents;	/* number of extents in data fork */
> -	uint16_t	di_anextents;	/* number of extents in attribute fork*/
> +	union {
> +		struct {
> +			uint32_t  di_big_aextcnt; /* NREXT64 attr extents */
> +			uint16_t  di_nrext64_pad; /* NREXT64 unused, zero */
> +		} __packed;
> +		struct {
> +			uint32_t  di_nextents;    /* !NREXT64 data extents */
> +			uint16_t  di_anextents;   /* !NREXT64 attr extents */
> +		} __packed;
> +	};
>  	uint8_t		di_forkoff;	/* attr fork offs, <<3 for 64b align */
>  	int8_t		di_aformat;	/* format of attr fork's data */
>  	uint32_t	di_dmevmask;	/* DMIG event mask */
> diff --git a/logprint/log_misc.c b/logprint/log_misc.c
> index 35e926a3..721c2eb5 100644
> --- a/logprint/log_misc.c
> +++ b/logprint/log_misc.c
> @@ -440,6 +440,8 @@ static void
>  xlog_print_trans_inode_core(
>  	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 +452,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 (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
> +	    nextents = ip->di_big_dextcnt;
> +    else
> +	    nextents = ip->di_nextents;
> +    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_nextents);
> -    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_extsize, nextents);
> +
> +    if (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
> +	    nextents = ip->di_big_aextcnt;
> +    else
> +	    nextents = ip->di_anextents;
> +    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);
> diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
> index c9c453f6..5e387f38 100644
> --- a/logprint/log_print_all.c
> +++ b/logprint/log_print_all.c
> @@ -240,7 +240,10 @@ STATIC void
>  xlog_recover_print_inode_core(
>  	struct xfs_log_dinode	*di)
>  {
> -	printf(_("	CORE inode:\n"));
> +	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 +257,19 @@ 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 (di->di_flags2 & XFS_DIFLAG2_NREXT64) {
> +		nextents = di->di_big_dextcnt;
> +		anextents = di->di_big_aextcnt;
> +	} else {
> +		nextents = di->di_nextents;
> +		anextents = di->di_anextents;
> +	}
> +
>  	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_nextents, (int)di->di_anextents);
> +	       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,
> diff --git a/repair/dinode.c b/repair/dinode.c
> index 0df84e48..3be2e1d5 100644
> --- a/repair/dinode.c
> +++ b/repair/dinode.c
> @@ -71,7 +71,12 @@ _("would have cleared inode %" PRIu64 " attributes\n"), ino_num);
>  	if (xfs_dfork_attr_extents(dino) != 0) {
>  		if (no_modify)
>  			return(1);
> -		dino->di_anextents = cpu_to_be16(0);
> +
> +		if (xfs_dinode_has_nrext64(dino))
> +			dino->di_big_aextcnt = 0;
> +		else
> +			dino->di_anextents = 0;
> +
>  	}
>  
>  	if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS)  {
> @@ -1818,7 +1823,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_nextents = cpu_to_be32(nextents);
> +			if (xfs_dinode_has_nrext64(dino))
> +				dino->di_big_dextcnt = cpu_to_be64(nextents);
> +			else
> +				dino->di_nextents = cpu_to_be32(nextents);
>  			*dirty = 1;
>  		} else  {
>  			do_warn(
> @@ -1841,7 +1849,11 @@ _("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_anextents = cpu_to_be16(anextents);
> +			if (xfs_dinode_has_nrext64(dino))
> +				dino->di_big_aextcnt = cpu_to_be32(anextents);
> +			else
> +				dino->di_anextents = cpu_to_be16(anextents);
> +
>  			*dirty = 1;
>  		} else  {
>  			do_warn(
> -- 
> 2.30.2
> 



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux