aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill O'Donnell <billodo@redhat.com>2017-06-29 13:05:00 -0500
committerEric Sandeen <sandeen@redhat.com>2017-06-29 13:05:00 -0500
commit55f224baf83d71b3d2cc24e6387d9f1f6a5a1eda (patch)
treee8958e955f76f5a599a625b62e5a93087e675ea0
parentf77f9908851ed2fcfa91734e2d69dec62ba25603 (diff)
downloadxfsprogs-dev-55f224baf83d71b3d2cc24e6387d9f1f6a5a1eda.tar.gz
xfs_db: update buffer size when new type is set
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>
-rw-r--r--db/io.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/db/io.c b/db/io.c
index 9918a51d04..a001bad5ea 100644
--- 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. */