xfs
[Top] [All Lists]

[PATCH 07/15] xfs_db: metadump should copy the reflink btree too

To: david@xxxxxxxxxxxxx, darrick.wong@xxxxxxxxxx
Subject: [PATCH 07/15] xfs_db: metadump should copy the reflink btree too
From: "Darrick J. Wong" <darrick.wong@xxxxxxxxxx>
Date: Mon, 29 Jun 2015 20:26:24 -0700
Cc: xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <20150630032538.572.20293.stgit@xxxxxxxxxxxxxxxx>
References: <20150630032538.572.20293.stgit@xxxxxxxxxxxxxxxx>
User-agent: StGit/0.17.1-dirty
Teach metadump to copy the reflink btree.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 db/metadump.c |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)


diff --git a/db/metadump.c b/db/metadump.c
index cca9b49..29d93c9 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -397,6 +397,78 @@ copy_free_cnt_btree(
        return scan_btree(agno, root, levels, TYP_CNTBT, agf, scanfunc_freesp);
 }
 
+static int
+scanfunc_rlbt(
+       struct xfs_btree_block  *block,
+       xfs_agnumber_t          agno,
+       xfs_agblock_t           agbno,
+       int                     level,
+       typnm_t                 btype,
+       void                    *arg)
+{
+       xfs_reflink_ptr_t       *pp;
+       int                     i;
+       int                     numrecs;
+
+       if (level == 0)
+               return 1;
+
+       numrecs = be16_to_cpu(block->bb_numrecs);
+       if (numrecs > mp->m_rlbt_mxr[1]) {
+               if (show_warnings)
+                       print_warning("invalid numrecs (%u) in %s block %u/%u",
+                               numrecs, typtab[btype].name, agno, agbno);
+               return 1;
+       }
+
+       pp = XFS_REFLINK_PTR_ADDR(block, 1, mp->m_rlbt_mxr[1]);
+       for (i = 0; i < numrecs; i++) {
+               if (!valid_bno(agno, be32_to_cpu(pp[i]))) {
+                       if (show_warnings)
+                               print_warning("invalid block number (%u/%u) "
+                                       "in %s block %u/%u",
+                                       agno, be32_to_cpu(pp[i]),
+                                       typtab[btype].name, agno, agbno);
+                       continue;
+               }
+               if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg,
+                               scanfunc_rlbt))
+                       return 0;
+       }
+       return 1;
+}
+
+static int
+copy_reflink_btree(
+       xfs_agnumber_t  agno,
+       xfs_agf_t       *agf)
+{
+       xfs_agblock_t   root;
+       int             levels;
+
+       if (!xfs_sb_version_hasreflink(&mp->m_sb))
+               return 0;
+
+       root = be32_to_cpu(agf->agf_reflink_root);
+       levels = be32_to_cpu(agf->agf_reflink_level);
+
+       /* validate root and levels before processing the tree */
+       if (root == 0 || root > mp->m_sb.sb_agblocks) {
+               if (show_warnings)
+                       print_warning("invalid block number (%u) in bnobt "
+                                       "root in agf %u", root, agno);
+               return 1;
+       }
+       if (levels >= XFS_BTREE_MAXLEVELS) {
+               if (show_warnings)
+                       print_warning("invalid level (%u) in bnobt root "
+                                       "in agf %u", levels, agno);
+               return 1;
+       }
+
+       return scan_btree(agno, root, levels, TYP_RLBT, agf, scanfunc_rlbt);
+}
+
 /* filename and extended attribute obfuscation routines */
 
 struct name_ent {
@@ -2125,6 +2197,8 @@ scan_ag(
                        goto pop_out;
                if (!copy_free_cnt_btree(agno, agf))
                        goto pop_out;
+               if (!copy_reflink_btree(agno, agf))
+                       goto pop_out;
        }
 
        /* copy inode btrees and the inodes and their associated metadata */

<Prev in Thread] Current Thread [Next in Thread>