aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Albershteyn <aalbersh@redhat.com>2023-02-08 12:02:22 +0100
committerCarlos Maiolino <cem@kernel.org>2023-02-24 15:08:39 +0100
commita0d79cb37a36f44507038100f7ea1d8706e02f63 (patch)
tree7449408435bac961bca447aa033f3d93204876c1
parentb1faed5f7875a69d475d64942d74456079fc178d (diff)
downloadxfsprogs-dev-a0d79cb37a36f44507038100f7ea1d8706e02f63.tar.gz
xfs_db: make flist_find_ftyp() to check for field existance on disk
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@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r--db/crc.c2
-rw-r--r--db/flist.c12
-rw-r--r--db/flist.h3
3 files changed, 12 insertions, 5 deletions
diff --git a/db/crc.c b/db/crc.c
index 7428b9160a..1c73f98036 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 0bb6474c3a..c81d229ab9 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,14 @@ flist_find_ftyp(
fl->fld = f;
if (f->ftyp == type)
return fl;
+ count = fcount(f, obj, startoff);
+ if (!count)
+ continue;
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 f07723787d..e327a36042 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);