]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs_db: fix type conversions
authorDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jun 2026 01:04:28 +0000 (18:04 -0700)
committerAndrey Albershteyn <aalbersh@kernel.org>
Tue, 30 Jun 2026 09:50:55 +0000 (11:50 +0200)
While debugging rtrefcount problems, I noticed the following brokenness
in the debugger:

 # xfs_db /dev/sdf -c 'path -m /rtgroups/0.refcount' -c 'type text' -c print -c stack
 000:  24 84 4b 15 74 55 00 00 c0 5d 40 15 74 55 00 00  ..K.tU......tU..
 010:  48 9c 4b 15 74 55 00 00 00 00 00 00 00 00 00 00  H.K.tU..........
 020:  50 f3 41 15 74 55 00 00 01 00 00 00 01 00 00 00  P.A.tU..........
 030:  00 00 00 00 00 00 00 00 61 9c 4b 15 74 55 00 00  ........a.K.tU..
 040:  4f 9c 4b 15 74 55 00 00 00 00 00 00 00 00 00 00  O.K.tU..........
 050:  43 9e 4b 15 74 55 00 00 00 00 00 00 00 00 00 00  C.K.tU..........
 060:  c0 fc 41 15 74 55 00 00 00 00 00 00 00 00 00 00  ..A.tU..........
 070:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 080:  f1 9d 4b 15 74 55 00 00 90 f7 41 15 74 55 00 00  ..K.tU....A.tU..
 090:  c4 9e 4b 15 74 55 00 00 00 00 00 00 00 00 00 00  ..K.tU..........
 0a0:  80 0f 42 15 74 55 00 00 00 00 00 00 ff ff ff ff  ..B.tU..........
 0b0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 0c0:  d5 9e 4b 15 74 55 00 00 00 0c 42 15 74 55 00 00  ..K.tU....B.tU..
 0d0:  d0 06 00 00 00 00 00 00 40 00 00 00 00 00 00 00  ................
 0e0:  90 87 fe 23 74 55 00 00 01 00 00 00 ad 7f 00 00  ....tU..........
 0f0:  00 00 00 00 00 00 00 00 80 83 fe 23 74 55 00 00  ............tU..
 100:  c0 7f fe 23 74 55 00 00 00 00 00 00 00 00 00 00  ....tU..........
 110:  00 00 00 00 00 00 22 9d 41 00 00 00 00 00 00 00  ........A.......
 120:  2f 75 73 72 2f 73 68 61 72 65 2f 6c 6f 63 61 6c  .usr.share.local
 130:  65 2f 65 6e 2e 55 54 46 2d 38 2e 75 74 66 38 2f  e.en.UTF.8.utf8.
 140:  4c 43 5f 4d 45 53 53 41 47 45 53 2f 78 66 73 70  LC.MESSAGES.xfsp
 150:  72 6f 67 73 2e 6d 6f 00 51 00 00 00 00 00 00 00  rogs.mo.Q.......
 160:  20 95 fe 23 74 55 00 00 01 00 00 00 ad 7f 00 00  ....tU..........
 170:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 180:  80 83 fe 23 74 55 00 00 e0 94 fe 23 74 55 00 00  ....tU......tU..
 190:  c0 7f fe 23 74 55 00 00 00 00 00 00 00 00 00 00  ....tU..........
 1a0:  00 00 00 00 00 00 22 9d 41 00 00 00 00 00 00 00  ........A.......
 1b0:  e9 3f 42 57 05 00 00 00 5a 01 d3 41 44 71 76 92  ..BW....Z..ADqv.
 1c0:  65 2f 65 6e 5f 55 53 2e 55 54 46 2d 38 2f 4c 43  e.en.US.UTF.8.LC
 1d0:  5f 4d 45 53 53 41 47 45 53 2f 78 66 73 70 72 6f  .MESSAGES.xfspro
 1e0:  67 73 2e 6d 6f 00 00 28 21 00 00 00 00 00 00 00  gs.mo...........
 1f0:  09 48 bc 74 71 55 00 00 5a 01 d3 41 44 71 76 92  .H.tqU..Z..ADqv.
 1:
         byte offset 2642479104, length 512
         buffer block 5161088 (fsbno 1064976), 1 bb
         inode 8519812, dir inode -1, type text

The rtrefcount btree inode is not *so* corrupt that it's full of random
i18n garbage; valgrind confirms that we're walking off the end of
iocur_top->buf.  Looking at what set_iocur_type does, I think it should
be (re)reading the existing buffer while preserving the existing
boff/len fields.  Instead, it resets the buffer size to 1 fssector, but,
oddly, preserving boff (and not len).  This is why we go off the end of
the buffer.

After fixing, I get:

 # xfs_db /dev/sdf -c 'path -m /rtgroups/0.refcount' -c 'type text' -c print -c stack
 000:  49 4e 80 00 03 05 00 08 00 00 00 00 00 00 00 00  IN..............
 010:  00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00  ................
 020:  35 ed d7 36 1e e0 aa 20 35 ed d7 36 1e e0 aa 20  5..6....5..6....
 030:  35 ed d7 36 1e e0 ae 08 00 00 00 00 00 00 00 00  5..6............

Truncated for brevity; this is much better.

Cc: linux-xfs@vger.kernel.org # v5.18.0
Fixes: 0d376f6cf1799b ("xfs_db: take BB cluster offset into account when using 'type' cmd")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
db/io.c

diff --git a/db/io.c b/db/io.c
index 3841c0dcb86eada13e33c8f937784f045cacef69..fc9a25d4102482dce2d52ce43b6ce27955a78a27 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -682,8 +682,9 @@ set_iocur_type(
        const typ_t     *type)
 {
        /* type's size in basic blocks */
-       int             bb_count = BTOBB(mp->m_sb.sb_sectsize);
+       int             bb_count = iocur_top->blen;
        int             boff = iocur_top->boff;
+       int             len = iocur_top->len;
 
        /*
         * Inodes are special; verifier checks all inodes in the chunk, the
@@ -704,11 +705,15 @@ set_iocur_type(
        }
 
        /* adjust buffer size for types with fields & hence fsize() */
-       if (type->fields)
+       if (type->fields) {
                bb_count = BTOBB(byteize(fsize(type->fields,
                                       iocur_top->data, 0, 0)));
+               len = BBTOB(bb_count);
+       }
+
        set_cur(type, iocur_top->bb, bb_count, DB_RING_IGN, NULL);
        set_cur_boff(boff);
+       iocur_top->len = len;
 }
 
 static void