public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
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

  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