From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: david@fromorbit.com, darrick.wong@oracle.com
Cc: xfs@oss.sgi.com
Subject: [PATCH 29/51] xfs_repair: collect reverse-mapping data for refcount/rmap tree rebuilding
Date: Tue, 06 Oct 2015 22:08:19 -0700 [thread overview]
Message-ID: <20151007050819.1504.30373.stgit@birch.djwong.org> (raw)
In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org>
Collect reverse-mapping data for the entire filesystem so that we can
later check and rebuild the reference count tree and the reverse mapping
tree.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
repair/Makefile | 4 +
repair/dinode.c | 9 ++
repair/phase4.c | 5 +
repair/rmap.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++
repair/rmap.h | 30 ++++++++
repair/xfs_repair.c | 4 +
6 files changed, 245 insertions(+), 2 deletions(-)
create mode 100644 repair/rmap.c
create mode 100644 repair/rmap.h
diff --git a/repair/Makefile b/repair/Makefile
index 82cba8e..7239a9e 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -11,14 +11,14 @@ LTCOMMAND = xfs_repair
HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h btree.h \
dinode.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \
- progress.h scan.h versions.h prefetch.h threads.h slab.h
+ progress.h scan.h versions.h prefetch.h threads.h slab.h rmap.h
CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \
dino_chunks.c dinode.c dir2.c globals.c incore.c \
incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \
phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c \
progress.c prefetch.c rt.c sb.c scan.c threads.c \
- versions.c xfs_repair.c slab.c
+ versions.c xfs_repair.c slab.c rmap.c
LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG)
diff --git a/repair/dinode.c b/repair/dinode.c
index e81c245..2c0a421 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -30,6 +30,8 @@
#include "attr_repair.h"
#include "bmap.h"
#include "threads.h"
+#include "slab.h"
+#include "rmap.h"
/*
* gettext lookups for translations of strings use mutexes internally to
@@ -779,6 +781,13 @@ _("illegal state %d in block map %" PRIu64 "\n"),
state, b);
}
}
+ if (collect_rmaps) { /* && !check_dups */
+ error = add_rmap(mp, ino, whichfork, &irec);
+ if (error)
+ do_error(
+_("couldn't add reverse mapping\n")
+ );
+ }
*tot += irec.br_blockcount;
}
error = 0;
diff --git a/repair/phase4.c b/repair/phase4.c
index 1a7d7b5..bc43cd8 100644
--- a/repair/phase4.c
+++ b/repair/phase4.c
@@ -30,7 +30,10 @@
#include "versions.h"
#include "dir2.h"
#include "progress.h"
+#include "slab.h"
+#include "rmap.h"
+bool collect_rmaps = false;
/*
* null out quota inode fields in sb if they point to non-existent inodes.
@@ -170,6 +173,8 @@ phase4(xfs_mount_t *mp)
int ag_hdr_block;
int bstate;
+ if (needs_rmap_work(mp))
+ collect_rmaps = true;
ag_hdr_block = howmany(ag_hdr_len, mp->m_sb.sb_blocksize);
do_log(_("Phase 4 - check for duplicate blocks...\n"));
diff --git a/repair/rmap.c b/repair/rmap.c
new file mode 100644
index 0000000..1a73dbb
--- /dev/null
+++ b/repair/rmap.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015 Oracle.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libxfs.h>
+#include "btree.h"
+#include "err_protos.h"
+#include "libxlog.h"
+#include "incore.h"
+#include "globals.h"
+#include "dinode.h"
+#include "slab.h"
+#include "rmap.h"
+
+#undef RMAP_DEBUG
+
+#ifdef RMAP_DEBUG
+# define dbg_printf(f, a...) do {printf(f, ## a); fflush(stdout); } while (0)
+#else
+# define dbg_printf(f, a...)
+#endif
+
+/* per-AG rmap object anchor */
+struct xfs_ag_rmap {
+ struct xfs_slab *ar_rmaps; /* rmap observations, p4 */
+};
+
+static struct xfs_ag_rmap *ag_rmaps;
+
+/*
+ * Compare rmap observations for array sorting.
+ */
+static int
+rmap_compare(
+ const void *a,
+ const void *b)
+{
+ const struct xfs_rmap_irec *pa;
+ const struct xfs_rmap_irec *pb;
+
+ pa = a; pb = b;
+ if (pa->rm_startblock < pb->rm_startblock)
+ return -1;
+ else if (pa->rm_startblock > pb->rm_startblock)
+ return 1;
+ else if (pa->rm_owner < pb->rm_owner)
+ return -1;
+ else if (pa->rm_owner > pb->rm_owner)
+ return 1;
+ else if (pa->rm_offset < pb->rm_offset)
+ return -1;
+ else if (pa->rm_offset > pb->rm_offset)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * needs_rmap_work() -- Return true if we must reconstruct either the
+ * reference count or reverse mapping trees.
+ *
+ * @mp: XFS mount object
+ */
+bool
+needs_rmap_work(
+ struct xfs_mount *mp)
+{
+ return xfs_sb_version_hasrmapbt(&mp->m_sb);
+}
+
+/**
+ * init_rmaps() -- Initialize per-AG reverse map data.
+ *
+ * @mp: XFS mount object
+ */
+void
+init_rmaps(
+ struct xfs_mount *mp)
+{
+ xfs_agnumber_t i;
+ int error;
+
+ if (!needs_rmap_work(mp))
+ return;
+
+ ag_rmaps = calloc(mp->m_sb.sb_agcount, sizeof(struct xfs_ag_rmap));
+ if (!ag_rmaps)
+ do_error(_("couldn't allocate per-AG reverse map roots\n"));
+
+ for (i = 0; i < mp->m_sb.sb_agcount; i++) {
+ error = init_slab(&ag_rmaps[i].ar_rmaps,
+ sizeof(struct xfs_rmap_irec));
+ if (error)
+ do_error(
+_("Insufficient memory while allocating reverse mapping slabs."));
+ }
+}
+
+/**
+ * free_rmaps() -- Free the per-AG reverse-mapping data.
+ *
+ * @mp: XFS mount object
+ */
+void
+free_rmaps(
+ struct xfs_mount *mp)
+{
+ xfs_agnumber_t i;
+
+ if (!needs_rmap_work(mp))
+ return;
+
+ for (i = 0; i < mp->m_sb.sb_agcount; i++) {
+ free_slab(&ag_rmaps[i].ar_rmaps);
+ }
+ free(ag_rmaps);
+ ag_rmaps = NULL;
+}
+
+/**
+ * add_rmap() -- Add an observation about a physical block mapping for later
+ * btree reconstruction.
+ *
+ * @mp: XFS mount object.
+ * @ino: The inode number associated with the extent mapping.
+ * @whichfork: Data or attribute fork?
+ * @irec: The extent mapping to record.
+ */
+int
+add_rmap(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ int whichfork,
+ struct xfs_bmbt_irec *irec)
+{
+ struct xfs_slab *rmaps;
+ struct xfs_rmap_irec rmap;
+ xfs_agnumber_t agno;
+ xfs_agblock_t agbno;
+
+ if (!needs_rmap_work(mp))
+ return 0;
+
+ agno = XFS_FSB_TO_AGNO(mp, irec->br_startblock);
+ agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
+ ASSERT(agno != NULLAGNUMBER);
+ ASSERT(agno < mp->m_sb.sb_agcount);
+ ASSERT(agbno + irec->br_blockcount <= mp->m_sb.sb_agblocks);
+ ASSERT(ino != NULLFSINO);
+ ASSERT(whichfork == XFS_DATA_FORK || whichfork == XFS_ATTR_FORK);
+
+ rmaps = ag_rmaps[agno].ar_rmaps;
+ rmap.rm_owner = ino;
+ rmap.rm_offset = irec->br_startoff;
+ if (whichfork == XFS_ATTR_FORK)
+ rmap.rm_offset |= XFS_RMAP_OFF_ATTR;
+ rmap.rm_startblock = agbno;
+ rmap.rm_blockcount = irec->br_blockcount;
+ if (irec->br_state == XFS_EXT_UNWRITTEN)
+ rmap.rm_blockcount |= XFS_RMAP_LEN_UNWRITTEN;
+ return slab_add(rmaps, &rmap);
+}
+
+#ifdef RMAP_DEBUG
+static void
+dump_rmap(
+ const char *msg,
+ xfs_agnumber_t agno,
+ struct xfs_rmap_irec *rmap)
+{
+ printf("%s: %p agno=%u pblk=%llu ino=%llu lblk=%llu len=%u\n", msg,
+ rmap,
+ (unsigned)agno,
+ (unsigned long long)rmap->rm_startblock,
+ (unsigned long long)rmap->rm_owner,
+ (unsigned long long)rmap->rm_offset,
+ (unsigned)rmap->rm_blockcount);
+}
+#else
+# define dump_rmap(m, a, r)
+#endif
diff --git a/repair/rmap.h b/repair/rmap.h
new file mode 100644
index 0000000..be3d357
--- /dev/null
+++ b/repair/rmap.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Oracle.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef RMAP_H_
+#define RMAP_H_
+
+extern bool collect_rmaps;
+
+extern bool needs_rmap_work(struct xfs_mount *);
+
+extern void init_rmaps(struct xfs_mount *);
+extern void free_rmaps(struct xfs_mount *);
+
+extern int add_rmap(struct xfs_mount *, xfs_ino_t, int, struct xfs_bmbt_irec *);
+
+#endif /* RMAP_H_ */
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index a464cd3..f4289c0 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -31,6 +31,8 @@
#include "threads.h"
#include "progress.h"
#include "dinode.h"
+#include "slab.h"
+#include "rmap.h"
#define rounddown(x, y) (((x)/(y))*(y))
@@ -790,6 +792,7 @@ main(int argc, char **argv)
init_bmaps(mp);
incore_ino_init(mp);
incore_ext_init(mp);
+ init_rmaps(mp);
/* initialize random globals now that we know the fs geometry */
inodes_per_block = mp->m_sb.sb_inopblock;
@@ -823,6 +826,7 @@ main(int argc, char **argv)
/*
* Done with the block usage maps, toss them...
*/
+ free_rmaps(mp);
free_bmaps(mp);
if (!bad_ino_btree) {
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2015-10-07 5:08 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-07 5:05 [RFCv3 00/51] xfsprogs: add reverse-mapping, reflink, and dedupe support Darrick J. Wong
2015-10-07 5:05 ` [PATCH 01/51] libxcmd: provide a common function to report command runtimes Darrick J. Wong
2015-10-13 17:48 ` Christoph Hellwig
2015-10-13 22:39 ` Darrick J. Wong
2015-10-14 5:35 ` [PATCH v2 " Darrick J. Wong
2015-10-14 7:31 ` Christoph Hellwig
2015-10-07 5:05 ` [PATCH 02/51] libxfs: add reflink and dedupe ioctls Darrick J. Wong
2015-10-07 5:05 ` [PATCH 03/51] xfs_io: support reflink and dedupe of file ranges Darrick J. Wong
2015-10-14 5:36 ` [PATCH v2 " Darrick J. Wong
2015-11-09 7:54 ` Christoph Hellwig
2015-11-09 18:33 ` Darrick J. Wong
2015-11-09 18:57 ` Darrick J. Wong
2015-11-09 21:35 ` Dave Chinner
2015-11-10 6:27 ` Darrick J. Wong
2015-10-07 5:05 ` [PATCH 04/51] xfs_io: unshare blocks via fallocate Darrick J. Wong
2015-10-07 5:05 ` [PATCH 05/51] xfs_db: enable blocktrash for checksummed filesystems Darrick J. Wong
2015-10-07 5:05 ` [PATCH 06/51] xfs_db: trash the block at the top of the cursor stack Darrick J. Wong
2015-10-07 5:05 ` [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Darrick J. Wong
2015-10-14 17:08 ` Christoph Hellwig
2015-10-14 18:20 ` Darrick J. Wong
2015-10-14 18:23 ` Christoph Hellwig
2015-10-14 19:52 ` Darrick J. Wong
2015-10-14 21:26 ` Dave Chinner
2015-10-07 5:06 ` [PATCH 08/51] libxfs: reorder xfs_bmap_add_free args Darrick J. Wong
2015-10-07 5:06 ` [PATCH 09/51] libxfs: add the reverse-mapping btree Darrick J. Wong
2015-10-07 5:06 ` [PATCH 10/51] libxfs: resync xfs_prealloc_blocks with the kernel Darrick J. Wong
2015-10-07 5:06 ` [PATCH 11/51] xfs: rmap btree transaction reservations Darrick J. Wong
2015-10-07 5:06 ` [PATCH 12/51] xfs: rmap btree requires more reserved free space Darrick J. Wong
2015-10-07 5:06 ` [PATCH 13/51] libxfs: propagate a bunch of case changes to mkfs and repair Darrick J. Wong
2015-10-07 5:06 ` [PATCH 14/51] libxfs: fix min freelist length calculation Darrick J. Wong
2015-10-07 5:06 ` [PATCH 15/51] libxfs: add the RMAP CRC to the xfs_magics list Darrick J. Wong
2015-10-07 5:06 ` [PATCH 16/51] libxfs: enhance rmapbt definition to support reflink Darrick J. Wong
2015-10-07 5:07 ` [PATCH 17/51] libxfs: refactor short btree block verification Darrick J. Wong
2015-10-07 5:07 ` [PATCH 18/51] xfs: don't update rmapbt when fixing agfl Darrick J. Wong
2015-10-07 5:07 ` [PATCH 19/51] libxfs: implement XFS_IOC_SWAPEXT when rmap btree is enabled Darrick J. Wong
2015-10-07 5:07 ` [PATCH 20/51] xfs_db: display rmap btree contents Darrick J. Wong
2015-10-07 5:07 ` [PATCH 21/51] xfs_dump: display enhanced rmapbt fields Darrick J. Wong
2015-10-07 5:07 ` [PATCH 22/51] xfs_db: check rmapbt Darrick J. Wong
2015-10-07 5:07 ` [PATCH 23/51] xfs_db: copy the rmap btree Darrick J. Wong
2015-10-07 5:07 ` [PATCH 24/51] xfs_growfs: report rmapbt presence Darrick J. Wong
2015-10-07 5:07 ` [PATCH 25/51] xfs_repair: use rmap btree data to check block types Darrick J. Wong
2015-10-07 5:08 ` [PATCH 26/51] xfs_repair: mask off length appropriately Darrick J. Wong
2015-10-07 5:08 ` [PATCH 27/51] xfs_repair: fix fino_bno calculation when rmapbt is enabled Darrick J. Wong
2015-10-07 5:08 ` [PATCH 28/51] xfs_repair: create a slab API for allocating arrays in large chunks Darrick J. Wong
2015-10-07 5:08 ` Darrick J. Wong [this message]
2015-10-07 5:08 ` [PATCH 30/51] xfs_repair: record and merge raw rmap data Darrick J. Wong
2015-10-07 5:08 ` [PATCH 31/51] xfs_repair: add inode bmbt block rmaps Darrick J. Wong
2015-10-07 5:08 ` [PATCH 32/51] xfs_repair: add fixed-location per-AG rmaps Darrick J. Wong
2015-10-21 21:08 ` Darrick J. Wong
2015-10-07 5:08 ` [PATCH 33/51] xfs_repair: check existing rmapbt entries against observed rmaps Darrick J. Wong
2015-10-07 5:08 ` [PATCH 34/51] xfs_repair: rebuild reverse-mapping btree Darrick J. Wong
2015-10-07 5:09 ` [PATCH 35/51] xfs_repair: add per-AG btree blocks to rmap data and add to rmapbt Darrick J. Wong
2015-10-07 5:09 ` [PATCH 36/51] mkfs.xfs: Create rmapbt filesystems Darrick J. Wong
2015-10-07 5:09 ` [PATCH 37/51] xfs_mkfs: initialize extra fields during mkfs Darrick J. Wong
2015-10-07 5:09 ` [PATCH 38/51] libxfs: add support for refcount btrees Darrick J. Wong
2015-10-07 5:09 ` [PATCH 39/51] xfs_db: dump refcount btree data Darrick J. Wong
2015-10-07 5:09 ` [PATCH 40/51] xfs_db: add support for checking the refcount btree Darrick J. Wong
2015-10-07 5:09 ` [PATCH 41/51] xfs_db: metadump should copy the refcount btree too Darrick J. Wong
2015-10-07 5:09 ` [PATCH 42/51] xfs_growfs: report the presence of the reflink feature Darrick J. Wong
2015-10-07 5:09 ` [PATCH 43/51] xfs_repair: check the existing refcount btree Darrick J. Wong
2015-10-07 5:09 ` [PATCH 44/51] xfs_repair: handle multiple owners of data blocks Darrick J. Wong
2015-10-07 5:10 ` [PATCH 45/51] xfs_repair: process reverse-mapping data into refcount data Darrick J. Wong
2015-10-07 5:10 ` [PATCH 46/51] xfs_repair: record reflink inode state Darrick J. Wong
2015-10-07 5:10 ` [PATCH 47/51] xfs_repair: fix inode reflink flags Darrick J. Wong
2015-10-07 5:10 ` [PATCH 48/51] xfs_repair: check the refcount btree against our observed reference counts when -n Darrick J. Wong
2015-10-07 5:10 ` [PATCH 49/51] xfs_repair: rebuild the refcount btree Darrick J. Wong
2015-10-07 5:10 ` [PATCH 50/51] mkfs.xfs: format reflink enabled filesystems Darrick J. Wong
2015-10-07 5:10 ` [PATCH 51/51] mkfs: hack around not having enough log blocks Darrick J. Wong
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=20151007050819.1504.30373.stgit@birch.djwong.org \
--to=darrick.wong@oracle.com \
--cc=david@fromorbit.com \
--cc=xfs@oss.sgi.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox