]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_db: update buffer size when new type is set
authorBill O'Donnell <billodo@redhat.com>
Thu, 29 Jun 2017 18:05:00 +0000 (13:05 -0500)
committerEric Sandeen <sandeen@redhat.com>
Thu, 29 Jun 2017 18:05:00 +0000 (13:05 -0500)
xfs_db doesn't take sector size into account when setting type.
This can result in an errant crc. For example, with a sector size
of 4096:

xfs_db> agi 0
xfs_db> p crc
crc = 0xab85043e (correct)
xfs_db> daddr
current daddr is 16
xfs_db> daddr 42
xfs_db> daddr 16
xfs_db> type agi
Metadata CRC error detected at xfs_agi block 0x10/0x200
xfs_db> p crc
crc = 0xab85043e (bad)

When xfs_db sets the new daddr in daddr_f, it does so with one
BBSIZE sector (512). Changing the type doesn't change the size
of the current buffer in iocur_top, so the checksum is calculated
on the wrong length for the type (when the actual sector size > BBSIZE (512).

For types with fields, reread the buffer to pick up the correct size for
the new type when it gets set. Facilitate the reread by setting the cursor
with set_cur().

Signed-off-by: Bill O'Donnell <billodo@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
[sandeen: fix up long line, clarify subject & comments]
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/io.c

diff --git a/db/io.c b/db/io.c
index 9918a51d04a1ed2d3f3c61891216950fb98ee227..a001bad5ea115566baa82822bc06942d372a34e2 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -28,6 +28,7 @@
 #include "init.h"
 #include "malloc.h"
 #include "crc.h"
+#include "bit.h"
 
 static int     pop_f(int argc, char **argv);
 static void     pop_help(void);
@@ -616,6 +617,13 @@ set_iocur_type(
 {
        struct xfs_buf  *bp = iocur_top->bp;
 
+       /* adjust buffer size for types with fields & hence fsize() */
+       if (t->fields) {
+               int bb_count;   /* type's size in basic blocks */
+
+               bb_count = BTOBB(byteize(fsize(t->fields, iocur_top->data, 0, 0)));
+               set_cur(t, iocur_top->bb, bb_count, DB_RING_IGN, NULL);
+       }
        iocur_top->typ = t;
 
        /* verify the buffer if the type has one. */