diff options
author | Chandan Babu R <chandan.babu@oracle.com> | 2022-06-22 14:28:52 -0500 |
---|---|---|
committer | Eric Sandeen <sandeen@sandeen.net> | 2022-06-22 14:28:52 -0500 |
commit | 8be26c6a172f5738539b931db06fb911ecf7be4e (patch) | |
tree | 89b663358aa92f1688a40275058b9a2861dafdd0 | |
parent | 5a8b4d6a60dffd4f09e4e30e488c8289d1813388 (diff) | |
download | xfsprogs-dev-8be26c6a172f5738539b931db06fb911ecf7be4e.tar.gz |
xfs: Introduce per-inode 64-bit extent counters
Source kernel commit: 52a4a14842ef940e5bab1c949e5adc8f027327dc
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.
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Suggested-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | db/field.c | 4 | ||||
-rw-r--r-- | db/field.h | 2 | ||||
-rw-r--r-- | db/inode.c | 217 | ||||
-rw-r--r-- | libxfs/xfs_format.h | 33 | ||||
-rw-r--r-- | libxfs/xfs_inode_buf.c | 49 | ||||
-rw-r--r-- | libxfs/xfs_inode_fork.h | 6 | ||||
-rw-r--r-- | libxfs/xfs_log_format.h | 33 | ||||
-rw-r--r-- | logprint/log_misc.c | 21 | ||||
-rw-r--r-- | logprint/log_print_all.c | 16 | ||||
-rw-r--r-- | repair/dinode.c | 16 |
10 files changed, 361 insertions, 36 deletions
diff --git a/db/field.c b/db/field.c index 1d873d518a..6a25b87246 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 387c189ec8..614fd0ab41 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 3fbf1db060..c9b506b905 100644 --- a/db/inode.c +++ b/db/inode.c @@ -27,6 +27,16 @@ 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_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_nrext64_pad_count(void *obj, int startoff); +static int inode_core_nextents_offset(void *obj, int startoff, int idx); +static int inode_core_nextents32_count(void *obj, int startoff); +static int inode_core_nextents64_count(void *obj, int startoff); +static int inode_core_anextents_offset(void *obj, int startoff, int idx); +static int inode_core_anextents16_count(void *obj, int startoff); +static int inode_core_anextents32_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); @@ -82,26 +92,42 @@ const field_t inode_core_flds[] = { { "format", FLDT_DINODE_FMT, OI(COFF(format)), C1, 0, TYP_NONE }, { "nlinkv1", FLDT_UINT16D, OI(COFF(onlink)), inode_core_nlinkv1_count, FLD_COUNT, TYP_NONE }, - { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count, - FLD_COUNT, TYP_NONE }, { "onlink", FLDT_UINT16D, OI(COFF(onlink)), inode_core_onlink_count, FLD_COUNT, TYP_NONE }, + { "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE }, + { "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE }, + { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count, + FLD_COUNT, TYP_NONE }, { "projid_lo", FLDT_UINT16D, OI(COFF(projid_lo)), 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 }, - { "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 }, + /* union 1 */ + { "nextents", FLDT_UINT64D, inode_core_nextents_offset, + inode_core_nextents64_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "v3_pad", FLDT_UINT64D, OI(OFF(v3_pad)), + inode_core_v3_pad_count, 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 }, + { "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 }, + /* union 2 */ + { "nextents", FLDT_UINT32D, inode_core_nextents_offset, + inode_core_nextents32_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "naextents", FLDT_UINT16D, inode_core_anextents_offset, + inode_core_anextents16_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "naextents", FLDT_UINT32D, inode_core_anextents_offset, + inode_core_anextents32_count, FLD_OFFSET|FLD_COUNT, TYP_NONE }, + { "nrext64_pad", FLDT_UINT16D, OI(COFF(nrext64_pad)), + inode_core_nrext64_pad_count, FLD_COUNT|FLD_SKIPALL, 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 }, @@ -402,6 +428,181 @@ inode_core_projid_count( } 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) + && !(dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_NREXT64))) + return 1; + + 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; + + 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; + + return 1; +} + +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 (xfs_dinode_has_large_extent_counts(dic)) + return 1; + + return 0; +} + +static int +inode_core_nextents_offset( + void *obj, + int startoff, + int idx) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(idx == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return COFF(big_nextents); + + return COFF(nextents); +} + +static int +inode_core_nextents32_count( + void *obj, + int startoff) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return 0; + + return 1; +} + +static int +inode_core_nextents64_count( + void *obj, + int startoff) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return 1; + + return 0; +} + +static int +inode_core_anextents_offset( + void *obj, + int startoff, + int idx) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(idx == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return COFF(big_anextents); + + return COFF(anextents); +} + +static int +inode_core_anextents16_count( + void *obj, + int startoff) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return 0; + + return 1; +} + +static int +inode_core_anextents32_count( + void *obj, + int startoff) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (xfs_dinode_has_large_extent_counts(dic)) + return 1; + + return 0; +} + +static int inode_f( int argc, char **argv) diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index eb85bc9b22..82b404c99b 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -792,16 +792,41 @@ 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 { + /* Number of data fork extents if NREXT64 is set */ + __be64 di_big_nextents; + + /* Padding for V3 inodes without NREXT64 set. */ + __be64 di_v3_pad; + + /* Padding and inode flush counter for V2 inodes. */ + struct { + __u8 di_v2_pad[6]; + __be16 di_flushiter; + }; + }; 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 { + /* + * For V2 inodes and V3 inodes without NREXT64 set, this + * is the number of data and attr fork extents. + */ + struct { + __be32 di_nextents; + __be16 di_anextents; + } __packed; + + /* Number of attr fork extents if NREXT64 is set. */ + struct { + __be32 di_big_anextents; + __be16 di_nrext64_pad; + } __packed; + } __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 deb143171f..bb0f8a7dd2 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_large_extent_counts(ip)) { + to->di_big_nextents = cpu_to_be64(xfs_ifork_nextents(&ip->i_df)); + to->di_big_anextents = 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; + to->di_v3_pad = 0; } 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 @@ -395,6 +414,24 @@ xfs_dinode_verify_forkoff( return NULL; } +static xfs_failaddr_t +xfs_dinode_verify_nrext64( + struct xfs_mount *mp, + struct xfs_dinode *dip) +{ + if (xfs_dinode_has_large_extent_counts(dip)) { + if (!xfs_has_large_extent_counts(mp)) + return __this_address; + if (dip->di_nrext64_pad != 0) + return __this_address; + } else if (dip->di_version >= 3) { + if (dip->di_v3_pad != 0) + return __this_address; + } + + return NULL; +} + xfs_failaddr_t xfs_dinode_verify( struct xfs_mount *mp, @@ -439,6 +476,10 @@ xfs_dinode_verify( if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0) return __this_address; + fa = xfs_dinode_verify_nrext64(mp, dip); + if (fa) + return fa; + nextents = xfs_dfork_data_extents(dip); naextents = xfs_dfork_attr_extents(dip); nblocks = be64_to_cpu(dip->di_nblocks); diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h index 967837a888..fd5c3c2d77 100644 --- a/libxfs/xfs_inode_fork.h +++ b/libxfs/xfs_inode_fork.h @@ -158,6 +158,9 @@ static inline xfs_extnum_t xfs_dfork_data_extents( struct xfs_dinode *dip) { + if (xfs_dinode_has_large_extent_counts(dip)) + return be64_to_cpu(dip->di_big_nextents); + return be32_to_cpu(dip->di_nextents); } @@ -165,6 +168,9 @@ static inline xfs_extnum_t xfs_dfork_attr_extents( struct xfs_dinode *dip) { + if (xfs_dinode_has_large_extent_counts(dip)) + return be32_to_cpu(dip->di_big_anextents); + return be16_to_cpu(dip->di_anextents); } diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h index fd66e70248..12234a880e 100644 --- a/libxfs/xfs_log_format.h +++ b/libxfs/xfs_log_format.h @@ -388,16 +388,41 @@ 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 { + /* Number of data fork extents if NREXT64 is set */ + uint64_t di_big_nextents; + + /* Padding for V3 inodes without NREXT64 set. */ + uint64_t di_v3_pad; + + /* Padding and inode flush counter for V2 inodes. */ + 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 { + /* + * For V2 inodes and V3 inodes without NREXT64 set, this + * is the number of data and attr fork extents. + */ + struct { + uint32_t di_nextents; + uint16_t di_anextents; + } __packed; + + /* Number of attr fork extents if NREXT64 is set. */ + struct { + uint32_t di_big_anextents; + uint16_t di_nrext64_pad; + } __packed; + } __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 35e926a3ba..8aeb39b973 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,12 +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_nextents; + 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_dmstate); + ip->di_extsize, nextents); + + if (ip->di_flags2 & XFS_DIFLAG2_NREXT64) + nextents = ip->di_big_anextents; + 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); if (ip->di_version == 3) { diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c index 182b9d53aa..f601f429f7 100644 --- a/logprint/log_print_all.c +++ b/logprint/log_print_all.c @@ -240,9 +240,21 @@ STATIC void xlog_recover_print_inode_core( struct xfs_log_dinode *di) { + xfs_extnum_t nextents; + xfs_aextnum_t anextents; + printf(_(" CORE inode:\n")); if (!print_inode) return; + + if (di->di_flags2 & XFS_DIFLAG2_NREXT64) { + nextents = di->di_big_nextents; + anextents = di->di_big_anextents; + } else { + nextents = di->di_nextents; + anextents = di->di_anextents; + } + printf(_(" magic:%c%c mode:0x%x ver:%d format:%d\n"), (di->di_magic>>8) & 0xff, di->di_magic & 0xff, di->di_mode, di->di_version, di->di_format); @@ -255,9 +267,9 @@ xlog_recover_print_inode_core( xlog_extract_dinode_ts(di->di_ctime)); printf(_(" flushiter:%d\n"), di->di_flushiter); printf(_(" size:0x%llx nblks:0x%llx exsize:%d " - "nextents:%d anextents:%d\n"), (unsigned long long) + "nextents:" PRIu64 " 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 21d428a019..04e7f83e82 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -74,7 +74,11 @@ _("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_large_extent_counts(dino)) + dino->di_big_anextents = 0; + else + dino->di_anextents = 0; } if (dino->di_aformat != XFS_DINODE_FMT_EXTENTS) { @@ -1826,7 +1830,10 @@ _("too many data fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"), do_warn( _("correcting nextents for inode %" PRIu64 ", was %" PRIu64 " - counted %" PRIu64 "\n"), lino, dnextents, nextents); - dino->di_nextents = cpu_to_be32(nextents); + if (xfs_dinode_has_large_extent_counts(dino)) + dino->di_big_nextents = cpu_to_be64(nextents); + else + dino->di_nextents = cpu_to_be32(nextents); *dirty = 1; } else { do_warn( @@ -1849,7 +1856,10 @@ _("too many attr fork extents (%" PRIu64 ") in inode %" PRIu64 "\n"), do_warn( _("correcting anextents for inode %" PRIu64 ", was %" PRIu64 " - counted %" PRIu64 "\n"), lino, danextents, anextents); - dino->di_anextents = cpu_to_be16(anextents); + if (xfs_dinode_has_large_extent_counts(dino)) + dino->di_big_anextents = cpu_to_be32(anextents); + else + dino->di_anextents = cpu_to_be16(anextents); *dirty = 1; } else { do_warn( |