All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Bill O'Donnell" <billodo@redhat.com>
To: xfs@oss.sgi.com
Subject: [PATCH 2/2] xfs_repair: new secondary superblock search method
Date: Tue,  9 Feb 2016 11:13:08 -0600	[thread overview]
Message-ID: <1455037988-7213-3-git-send-email-billodo@redhat.com> (raw)
In-Reply-To: <1455037988-7213-1-git-send-email-billodo@redhat.com>

Optimize secondary sb search, using similar method to find
fs geometry as that of xfs_mkfs. If this faster method fails
in finding a secondary sb, fall back to original brute force
slower search.

Signed-off-by: Bill O'Donnell <billodo@redhat.com>
---
 Makefile           |  2 +-
 include/libxcmd.h  |  4 +++-
 libxcmd/topology.c | 28 +++++++++++++++++++++++++++-
 repair/Makefile    |  4 ++--
 repair/phase1.c    | 25 +++++++++++++++++++++++--
 repair/protos.h    |  2 +-
 repair/sb.c        | 27 +++++++++++++++++++++------
 7 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile
index fca0a42..1d60d9c 100644
--- a/Makefile
+++ b/Makefile
@@ -80,7 +80,7 @@ fsr: libhandle
 growfs: libxcmd
 io: libxcmd libhandle
 quota: libxcmd
-repair: libxlog
+repair: libxlog libxcmd
 copy: libxlog
 
 ifeq ($(HAVE_BUILDDEFS), yes)
diff --git a/include/libxcmd.h b/include/libxcmd.h
index df7046e..b140adb 100644
--- a/include/libxcmd.h
+++ b/include/libxcmd.h
@@ -50,6 +50,8 @@ extern int
 check_overwrite(
 	char		*device);
 
-
+extern int guess_default_geometry(__uint64_t *agsize,
+				  __uint64_t *agcount,
+				  libxfs_init_t x);
 
 #endif	/* __LIBXCMD_H__ */
diff --git a/libxcmd/topology.c b/libxcmd/topology.c
index 0eeea28..4a8ab8b 100644
--- a/libxcmd/topology.c
+++ b/libxcmd/topology.c
@@ -302,7 +302,6 @@ static void blkid_get_topology(
 
 #endif /* ENABLE_BLKID */
 
-
 void get_topology(
 	libxfs_init_t		*xi,
 	struct fs_topology	*ft,
@@ -346,3 +345,30 @@ void get_topology(
 				   &lsectorsize, &psectorsize, force_overwrite);
 	}
 }
+
+/*
+ * Use this macro before we have superblock and mount structure
+ */
+#define	DTOBT(d)	((xfs_rfsblock_t)((d) >> (blocklog - BBSHIFT)))
+
+int guess_default_geometry(__uint64_t *agsize, __uint64_t *agcount, libxfs_init_t x) {
+	struct fs_topology ft;
+	int blocklog;
+	__uint64_t      dblocks;
+	int             multidisk;
+        memset(&ft, 0, sizeof(ft));
+        get_topology(&x, &ft, 1);
+
+        /*
+	 * get geometry from get_topology result.
+	 * Use default block size (2^12)
+	 */
+        blocklog = 12;
+        multidisk = ft.dswidth | ft.dsunit;
+	printf("x.dsize = %lu\n",(long unsigned int)x.dsize);
+        dblocks = DTOBT(x.dsize);
+        calc_default_ag_geometry(blocklog, dblocks, multidisk,
+                                 agsize, agcount);
+
+	return(blocklog);
+}
diff --git a/repair/Makefile b/repair/Makefile
index 251722b..d24ab1f 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -20,8 +20,8 @@ CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \
 	progress.c prefetch.c rt.c sb.c scan.c threads.c \
 	versions.c xfs_repair.c
 
-LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
-LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG)
+LLDLIBS = $(LIBBLKID) $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) $(LIBXCMD)
+LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) $(LIBXCMD)
 LLDFLAGS = -static-libtool-libs
 
 default: depend $(LTCOMMAND)
diff --git a/repair/phase1.c b/repair/phase1.c
index 126d0b3..c27033d 100644
--- a/repair/phase1.c
+++ b/repair/phase1.c
@@ -21,6 +21,7 @@
 #include "agheader.h"
 #include "protos.h"
 #include "err_protos.h"
+#include "libxcmd.h"
 
 static void
 no_sb(void)
@@ -47,6 +48,9 @@ alloc_ag_buf(int size)
  */
 #define MAX_SECTSIZE		(512 * 1024)
 
+extern libxfs_init_t x;
+
+
 /* ARGSUSED */
 void
 phase1(xfs_mount_t *mp)
@@ -54,6 +58,10 @@ phase1(xfs_mount_t *mp)
 	xfs_sb_t		*sb;
 	char			*ag_bp;
 	int			rval;
+	int			blocklog;
+	__uint64_t		agcount;
+	__uint64_t		agsize;
+	__uint64_t		skipsize;
 
 	do_log(_("Phase 1 - find and verify superblock...\n"));
 
@@ -65,6 +73,18 @@ phase1(xfs_mount_t *mp)
 	lost_quotas = 0;
 
 	/*
+	 * divine the geometry ;)
+	 */
+	blocklog = guess_default_geometry(&agsize, &agcount, x);
+
+	/*
+	 * use found ag geometry to quickly find secondary sb
+	 */
+	skipsize = agsize << blocklog;
+	do_log("agsize = %d  agcount = %d  skipsize = %d\n",
+	       (int)agsize, (int)agcount, (int)skipsize);
+
+	/*
 	 * get AG 0 into ag header buf
 	 */
 	ag_bp = alloc_ag_buf(MAX_SECTSIZE);
@@ -80,14 +100,15 @@ phase1(xfs_mount_t *mp)
 	if (rval != XR_OK)  {
 		do_warn(_("bad primary superblock - %s !!!\n"),
 			err_string(rval));
-		if (!find_secondary_sb(sb))
+
+		if (!find_secondary_sb(sb, skipsize))
 			no_sb();
 		primary_sb_modified = 1;
 	} else if ((rval = verify_set_primary_sb(sb, 0,
 					&primary_sb_modified)) != XR_OK)  {
 		do_warn(_("couldn't verify primary superblock - %s !!!\n"),
 			err_string(rval));
-		if (!find_secondary_sb(sb))
+		if (!find_secondary_sb(sb, skipsize))
 			no_sb();
 		primary_sb_modified = 1;
 	}
diff --git a/repair/protos.h b/repair/protos.h
index 9d5a2a6..d96373e 100644
--- a/repair/protos.h
+++ b/repair/protos.h
@@ -31,7 +31,7 @@ int	get_sb(xfs_sb_t			*sbp,
 void	write_primary_sb(xfs_sb_t	*sbp,
 			int		size);
 
-int	find_secondary_sb(xfs_sb_t	*sb);
+int	find_secondary_sb(xfs_sb_t	*sb, __uint64_t skipsize);
 
 struct fs_geometry;
 void	get_sb_geometry(struct fs_geometry	*geo,
diff --git a/repair/sb.c b/repair/sb.c
index 4eef14a..4386479 100644
--- a/repair/sb.c
+++ b/repair/sb.c
@@ -87,8 +87,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest)
 /*
  * find a secondary superblock, copy it into the sb buffer
  */
-int
-find_secondary_sb(xfs_sb_t *rsb)
+static int __find_secondary_sb(xfs_sb_t *rsb, __uint64_t skipsize )
 {
 	xfs_off_t	off;
 	xfs_sb_t	*sb;
@@ -101,7 +100,6 @@ find_secondary_sb(xfs_sb_t *rsb)
 	int		bsize;
 
 	do_warn(_("\nattempting to find secondary superblock...\n"));
-
 	sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
 	if (!sb) {
 		do_error(
@@ -117,7 +115,7 @@ find_secondary_sb(xfs_sb_t *rsb)
 	/*
 	 * skip first sector since we know that's bad
 	 */
-	for (done = 0, off = XFS_AG_MIN_BYTES; !done ; off += bsize)  {
+	for (done = 0, off = skipsize; !done ; off += bsize)  {
 		/*
 		 * read disk 1 MByte at a time.
 		 */
@@ -130,7 +128,6 @@ find_secondary_sb(xfs_sb_t *rsb)
 		}
 
 		do_warn(".");
-
 		/*
 		 * check the buffer 512 bytes at a time since
 		 * we don't know how big the sectors really are.
@@ -164,11 +161,29 @@ find_secondary_sb(xfs_sb_t *rsb)
 			}
 		}
 	}
-
 	free(sb);
 	return(retval);
 }
 
+int
+find_secondary_sb(xfs_sb_t *rsb, __uint64_t skipsize)
+{
+	int		retval;
+
+	/*
+	 * Attempt to find secondary sb with a coarse approach,
+	 * using a large skipsize (agsize in bytes). Failing that,
+	 * fallback to the fine-grained approach using min agsize.
+	 */
+	retval = __find_secondary_sb(rsb, skipsize);
+	if (!retval)
+		/*
+		 * fallback: use minimum agsize for skipsize
+		 */
+		retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES);
+	return(retval);
+}
+
 /*
  * Calculate what the inode alignment field ought to be based on internal
  * superblock info and determine if it is valid.
-- 
2.5.0

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2016-02-09 17:13 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-09 17:13 [PATCH 0/2] xfs_repair: improved secondary sb search Bill O'Donnell
2016-02-09 17:13 ` [PATCH 1/2] libxcmd: generalize topology functions Bill O'Donnell
2016-02-09 17:13 ` Bill O'Donnell [this message]
2016-02-09 19:05   ` [PATCH 2/2] xfs_repair: new secondary superblock search method Eric Sandeen
2016-02-09 19:14     ` 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=1455037988-7213-3-git-send-email-billodo@redhat.com \
    --to=billodo@redhat.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 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.