On Wed, Feb 01, 2023 at 06:21:47PM +0100, Andrey Albershteyn wrote: > flist_find_ftyp() searches for the field of the requested type. The > first found field/path is returned. However, this doesn't work when > there are multiple fields of the same type. For example, attr3 type > have a few CRC fields. Leaf block (xfs_attr_leaf_hdr -> > xfs_da3_blkinfo) and remote value block (xfs_attr3_rmt_hdr) both > have CRC but goes under attr3 type. This causes 'crc' command to be > unable to find CRC field when we are at remote attribute block as it > tries to use leaf block CRC path: > > $ dd if=/dev/zero bs=4k count=10 | tr '\000' '1' > test.img > $ touch test.file > $ setfattr -n user.bigattr -v "$(cat test.img)" test.file > > $ # CRC of the leaf block > $ xfs_db -r -x /dev/sda5 -c 'inode 132' -c 'ablock 0' -c 'crc' > Verifying CRC: > hdr.info.crc = 0x102b5cbf (correct) > > $ # CRC of the remote value block > $ xfs_db -r -x /dev/sda5 -c 'inode 132' -c 'ablock 1' -c 'crc' > field info not found > parsing error > > Solve this by making flist_find_ftyp() to also check that field in > question have non-zero count (exist at the current block). > > Signed-off-by: Andrey Albershteyn <aalbersh@xxxxxxxxxx> > --- > db/crc.c | 2 +- > db/flist.c | 13 ++++++++++--- > db/flist.h | 3 ++- > 3 files changed, 13 insertions(+), 5 deletions(-) > > diff --git a/db/crc.c b/db/crc.c > index 7428b916..1c73f980 100644 > --- a/db/crc.c > +++ b/db/crc.c > @@ -114,7 +114,7 @@ crc_f( > } > > /* Search for a CRC field */ > - fl = flist_find_ftyp(fields, FLDT_CRC); > + fl = flist_find_ftyp(fields, FLDT_CRC, iocur_top->data, 0); > if (!fl) { > dbprintf(_("No CRC field found for type %s\n"), cur_typ->name); > return 0; > diff --git a/db/flist.c b/db/flist.c > index 0bb6474c..d275abfe 100644 > --- a/db/flist.c > +++ b/db/flist.c > @@ -408,11 +408,14 @@ flist_split( > */ > flist_t * > flist_find_ftyp( > - const field_t *fields, > - fldt_t type) > + const field_t *fields, > + fldt_t type, > + void *obj, > + int startoff) > { > flist_t *fl; > const field_t *f; > + int count; > const ftattr_t *fa; > > for (f = fields; f->name; f++) { > @@ -420,11 +423,15 @@ flist_find_ftyp( > fl->fld = f; > if (f->ftyp == type) > return fl; > + count = fcount(f, obj, startoff); > + if (!count) { > + continue; > + } Minor nit: no need for curly braces here. With that cleaned up, Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> --D > fa = &ftattrtab[f->ftyp]; > if (fa->subfld) { > flist_t *nfl; > > - nfl = flist_find_ftyp(fa->subfld, type); > + nfl = flist_find_ftyp(fa->subfld, type, obj, startoff); > if (nfl) { > fl->child = nfl; > return fl; > diff --git a/db/flist.h b/db/flist.h > index f0772378..e327a360 100644 > --- a/db/flist.h > +++ b/db/flist.h > @@ -38,4 +38,5 @@ extern int flist_parse(const struct field *fields, flist_t *fl, void *obj, > int startoff); > extern void flist_print(flist_t *fl); > extern flist_t *flist_scan(char *name); > -extern flist_t *flist_find_ftyp(const field_t *fields, fldt_t type); > +extern flist_t *flist_find_ftyp(const field_t *fields, fldt_t type, void *obj, > + int startoff); > -- > 2.31.1 >