From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: sandeen@redhat.com
Cc: linux-xfs@vger.kernel.org
Subject: [PATCH v2 4/7] xfs_db: dump dir/attr btrees
Date: Tue, 1 Aug 2017 08:40:53 -0700 [thread overview]
Message-ID: <20170801154053.GH4477@magnolia> (raw)
In-Reply-To: <150153523353.26081.1989249017494623271.stgit@magnolia>
Dump the directory or extended attribute btree contents.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
db/btdump.c | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
man/man8/xfs_db.8 | 1
2 files changed, 255 insertions(+), 1 deletion(-)
diff --git a/db/btdump.c b/db/btdump.c
index 3b76e17..f525a4a 100644
--- a/db/btdump.c
+++ b/db/btdump.c
@@ -32,7 +32,9 @@ btdump_help(void)
"\n"
" If the cursor points to a btree block, 'btdump' dumps the btree\n"
" downward from that block. If the cursor points to an inode,\n"
-" the data fork btree root is selected by default.\n"
+" the data fork btree root is selected by default. If the cursor\n"
+" points to a directory or extended attribute btree node, the tree\n"
+" will be printed downward from that block.\n"
"\n"
" Options:\n"
" -a -- Display an inode's extended attribute fork btree.\n"
@@ -227,6 +229,252 @@ dump_inode(
return ret;
}
+static bool
+dir_has_rightsib(
+ void *block,
+ int level)
+{
+ struct xfs_dir3_icleaf_hdr lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ if (level > 0) {
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.forw != 0;
+ }
+ M_DIROPS(mp)->leaf_hdr_from_disk(&lhdr, block);
+ return lhdr.forw != 0;
+}
+
+static int
+dir_level(
+ void *block)
+{
+ struct xfs_dir3_icleaf_hdr lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ switch (((struct xfs_da_intnode *)block)->hdr.info.magic) {
+ case cpu_to_be16(XFS_DIR2_LEAF1_MAGIC):
+ case cpu_to_be16(XFS_DIR2_LEAFN_MAGIC):
+ M_DIROPS(mp)->leaf_hdr_from_disk(&lhdr, block);
+ return 0;
+ case cpu_to_be16(XFS_DA_NODE_MAGIC):
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.level;
+ default:
+ return -1;
+ }
+}
+
+static int
+dir3_level(
+ void *block)
+{
+ struct xfs_dir3_icleaf_hdr lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ switch (((struct xfs_da_intnode *)block)->hdr.info.magic) {
+ case cpu_to_be16(XFS_DIR3_LEAF1_MAGIC):
+ case cpu_to_be16(XFS_DIR3_LEAFN_MAGIC):
+ M_DIROPS(mp)->leaf_hdr_from_disk(&lhdr, block);
+ return 0;
+ case cpu_to_be16(XFS_DA3_NODE_MAGIC):
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.level;
+ default:
+ return -1;
+ }
+}
+
+static bool
+attr_has_rightsib(
+ void *block,
+ int level)
+{
+ struct xfs_attr_leafblock lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ if (level > 0) {
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.forw != 0;
+ }
+ xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo, &lhdr, block);
+ return lhdr.hdr.info.forw != 0;
+}
+
+static int
+attr_level(
+ void *block)
+{
+ struct xfs_attr_leafblock lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ switch (((struct xfs_da_intnode *)block)->hdr.info.magic) {
+ case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
+ xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo, &lhdr, block);
+ return 0;
+ case cpu_to_be16(XFS_DA_NODE_MAGIC):
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.level;
+ default:
+ return -1;
+ }
+}
+
+static int
+attr3_level(
+ void *block)
+{
+ struct xfs_attr_leafblock lhdr;
+ struct xfs_da3_icnode_hdr nhdr;
+
+ switch (((struct xfs_da_intnode *)block)->hdr.info.magic) {
+ case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
+ xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo, &lhdr, block);
+ return 0;
+ case cpu_to_be16(XFS_DA3_NODE_MAGIC):
+ M_DIROPS(mp)->node_hdr_from_disk(&nhdr, block);
+ return nhdr.level;
+ default:
+ return -1;
+ }
+}
+
+struct dabprinter_ops {
+ const char *print_node_entries;
+ const char *print_leaf_entries;
+ const char *go_node_forward;
+ const char *go_leaf_forward;
+ const char *go_down;
+ bool (*has_rightsib)(void *, int);
+ int (*level)(void *);
+};
+
+static struct dabprinter_ops attr_print = {
+ .print_node_entries = "btree",
+ .print_leaf_entries = "entries nvlist",
+ .go_node_forward = "hdr.info.forw",
+ .go_leaf_forward = "hdr.info.forw",
+ .go_down = "btree[0].before",
+ .has_rightsib = attr_has_rightsib,
+ .level = attr_level,
+};
+
+static struct dabprinter_ops attr3_print = {
+ .print_node_entries = "btree",
+ .print_leaf_entries = "entries nvlist",
+ .go_node_forward = "hdr.info.hdr.forw",
+ .go_leaf_forward = "hdr.info.hdr.forw",
+ .go_down = "btree[0].before",
+ .has_rightsib = attr_has_rightsib,
+ .level = attr3_level,
+};
+
+static struct dabprinter_ops dir_print = {
+ .print_node_entries = "nbtree",
+ .print_leaf_entries = "lents",
+ .go_node_forward = "nhdr.info.hdr.forw",
+ .go_leaf_forward = "lhdr.info.hdr.forw",
+ .go_down = "nbtree[0].before",
+ .has_rightsib = dir_has_rightsib,
+ .level = dir_level,
+};
+
+static struct dabprinter_ops dir3_print = {
+ .print_node_entries = "nbtree",
+ .print_leaf_entries = "lents",
+ .go_node_forward = "nhdr.info.forw",
+ .go_leaf_forward = "lhdr.info.forw",
+ .go_down = "nbtree[0].before",
+ .has_rightsib = dir_has_rightsib,
+ .level = dir3_level,
+};
+
+static int
+dump_dablevel(
+ int level,
+ struct dabprinter_ops *dbp)
+{
+ xfs_daddr_t orig_daddr = iocur_top->bb;
+ xfs_daddr_t last_daddr;
+ unsigned int nr;
+ int ret;
+
+ ret = eval("push");
+ if (ret)
+ return ret;
+
+ nr = 1;
+ do {
+ last_daddr = iocur_top->bb;
+ dbprintf(_("%s level %u block %u daddr %llu\n"),
+ iocur_top->typ->name, level, nr, last_daddr);
+ ret = eval("print %s", level > 0 ? dbp->print_node_entries :
+ dbp->print_leaf_entries);
+ if (ret)
+ goto err;
+ if (dbp->has_rightsib(iocur_top->data, level)) {
+ ret = eval("addr %s", level > 0 ? dbp->go_node_forward :
+ dbp->go_leaf_forward);
+ if (ret)
+ goto err;
+ }
+ nr++;
+ } while (iocur_top->bb != orig_daddr && iocur_top->bb != last_daddr);
+
+ ret = eval("pop");
+ return ret;
+err:
+ eval("pop");
+ return ret;
+}
+
+static int
+dump_dabtree(
+ bool dump_node_blocks,
+ struct dabprinter_ops *dbp)
+{
+ xfs_daddr_t orig_daddr = iocur_top->bb;
+ xfs_daddr_t last_daddr;
+ int level;
+ int ret;
+
+ ret = eval("push");
+ if (ret)
+ return ret;
+
+ cur_agno = XFS_FSB_TO_AGNO(mp, XFS_DADDR_TO_FSB(mp, iocur_top->bb));
+ level = dbp->level(iocur_top->data);
+ if (level < 0) {
+ printf(_("Current location is not part of a dir/attr btree.\n"));
+ goto err;
+ }
+
+ do {
+ last_daddr = iocur_top->bb;
+ if (level > 0) {
+ if (dump_node_blocks) {
+ ret = dump_dablevel(level, dbp);
+ if (ret)
+ goto err;
+ }
+ ret = eval("addr %s", dbp->go_down);
+ } else {
+ ret = dump_dablevel(level, dbp);
+ }
+ if (ret)
+ goto err;
+ level--;
+ } while (level >= 0 &&
+ iocur_top->bb != orig_daddr &&
+ iocur_top->bb != last_daddr);
+
+ ret = eval("pop");
+ return ret;
+err:
+ eval("pop");
+ return ret;
+}
+
static int
btdump_f(
int argc,
@@ -234,6 +482,7 @@ btdump_f(
{
bool aflag = false;
bool iflag = false;
+ bool crc = xfs_sb_version_hascrc(&mp->m_sb);
int c;
if (cur_typ == NULL) {
@@ -276,6 +525,10 @@ btdump_f(
return dump_btree_long(iflag);
case TYP_INODE:
return dump_inode(iflag, aflag);
+ case TYP_ATTR:
+ return dump_dabtree(iflag, crc ? &attr3_print : &attr_print);
+ case TYP_DIR2:
+ return dump_dabtree(iflag, crc ? &dir3_print : &dir_print);
default:
dbprintf(_("type \"%s\" is not a btree type or inode\n"),
cur_typ->name);
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index 6a97504..b3129f7 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -335,6 +335,7 @@ area of the inode, if neither option is given then both areas are shown.
.B btdump [-a] [-i]
If the cursor points to a btree node, dump the btree from that block downward.
If instead the cursor points to an inode, dump the data fork block mapping btree if there is one.
+If the cursor points to a directory or extended attribute btree node, dump that.
By default, only records stored in the btree are dumped.
.RS 1.0i
.TP 0.4i
next prev parent reply other threads:[~2017-08-01 15:41 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-31 21:06 [PATCH 0/7] xfsprogs: 4.13 rollup Darrick J. Wong
2017-07-31 21:06 ` [PATCH 1/7] xfs: remove double-underscore integer types Darrick J. Wong
2017-07-31 21:23 ` Eric Sandeen
2017-07-31 21:25 ` Darrick J. Wong
2017-08-02 9:13 ` Carlos Maiolino
2017-08-02 16:01 ` Darrick J. Wong
2017-07-31 21:07 ` [PATCH 2/7] xfs_repair: fix symlink target length checks by changing MAXPATHLEN to XFS_SYMLINK_MAXLEN Darrick J. Wong
2017-07-31 21:42 ` Eric Sandeen
2017-08-02 9:14 ` Carlos Maiolino
2017-07-31 21:07 ` [PATCH 3/7] xfs_db: fix metadump redirection (again) Darrick J. Wong
2017-07-31 21:57 ` Eric Sandeen
2017-08-01 16:23 ` [PATCH v2 " Darrick J. Wong
2017-08-02 9:17 ` Carlos Maiolino
2017-07-31 21:07 ` [PATCH 4/7] xfs_db: dump dir/attr btrees Darrick J. Wong
2017-07-31 22:05 ` Eric Sandeen
2017-08-01 14:59 ` Darrick J. Wong
2017-08-01 15:40 ` Darrick J. Wong [this message]
2017-08-01 16:21 ` [PATCH v2 " Eric Sandeen
2017-08-02 9:22 ` Carlos Maiolino
2017-08-02 9:24 ` Carlos Maiolino
2017-08-02 16:03 ` Darrick J. Wong
2017-07-31 21:07 ` [PATCH 5/7] xfs_db: print attribute remote value blocks Darrick J. Wong
2017-08-01 17:15 ` Eric Sandeen
2017-08-01 20:29 ` Darrick J. Wong
2017-08-01 21:04 ` [PATCH v2 " Darrick J. Wong
2017-08-02 9:36 ` Carlos Maiolino
2017-07-31 21:07 ` [PATCH 6/7] xfs_db: write values into dir/attr blocks and recalculate CRCs Darrick J. Wong
2017-08-02 9:40 ` Carlos Maiolino
2017-08-03 16:02 ` Eric Sandeen
2017-08-03 16:40 ` Darrick J. Wong
2017-07-31 21:07 ` [PATCH 7/7] xfs_db: introduce fuzz command Darrick J. Wong
2017-08-02 11:06 ` Carlos Maiolino
2017-08-03 16:47 ` [PATCH 8/7] xfs_db: use TYP_F_CRC_FUNC for inodes & dquots Eric Sandeen
2017-08-03 16:58 ` Darrick J. Wong
2017-08-03 17:15 ` [PATCH 8/7 V2] " Eric Sandeen
2017-08-03 18:05 ` Darrick J. Wong
2017-08-03 17:04 ` [PATCH 9/7] xfs_db: btdump should avoid eval for push and pop of cursor Darrick J. Wong
2017-08-03 17:18 ` Eric Sandeen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170801154053.GH4477@magnolia \
--to=darrick.wong@oracle.com \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.