public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/2] xfs_repair: improved secondary sb search
@ 2016-05-11 22:45 Bill O'Donnell
  2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Bill O'Donnell @ 2016-05-11 22:45 UTC (permalink / raw)
  To: xfs


Hello -

New iteration (v5) of this series...

Current xfs_repair uses a brute force approach to find a valid
secondary sb. This series optimizes the secondary sb search, using
similar method to determine geometry as that of xfs_mkfs. If the
faster method fails in its search, fall back to original brute force
slower search.

version history:
----
v1: http://oss.sgi.com/archives/xfs/2016-02/msg00304.html
v2: patch 2 whitespace fixups
v3: patch 2 correct functionality; style fixups
v4: patch 1,2 properly see to style and whitespace fixups
v5: patch 1 rebase to latest
----

patch 1 has some general infrastructure adjustments, moving general
topology functions from mkfs to libxcmd.

patch 2 adds the new secondary superblock search method.

Questions, comments are welcome.

Thanks-
Bill

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-11 22:45 [PATCH v5 0/2] xfs_repair: improved secondary sb search Bill O'Donnell
@ 2016-05-11 22:45 ` Bill O'Donnell
  2016-05-12 11:55   ` Christoph Hellwig
  2016-05-30  2:13   ` Dave Chinner
  2016-05-11 22:45 ` [PATCH v5 2/2] xfs_repair: new secondary superblock search method Bill O'Donnell
  2016-05-12  1:09 ` [PATCH v5 0/2] xfs_repair: improved secondary sb search Eric Sandeen
  2 siblings, 2 replies; 10+ messages in thread
From: Bill O'Donnell @ 2016-05-11 22:45 UTC (permalink / raw)
  To: xfs

Move general topology functions from xfs_mkfs to new topology
collection in libxcmd.

Signed-off-by: Bill O'Donnell <billodo@redhat.com>
---
 include/Makefile   |   1 +
 include/libxcmd.h  |  56 +++++++++
 libxcmd/Makefile   |   2 +-
 libxcmd/topology.c | 342 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 mkfs/Makefile      |   2 +-
 mkfs/xfs_mkfs.c    | 327 +-------------------------------------------------
 6 files changed, 402 insertions(+), 328 deletions(-)
 create mode 100644 include/libxcmd.h
 create mode 100644 libxcmd/topology.c

diff --git a/include/Makefile b/include/Makefile
index 5fb443a..36a9741 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -20,6 +20,7 @@ include $(TOPDIR)/include/builddefs
 
 LIBHFILES = libxfs.h \
 	libxlog.h \
+	libxcmd.h \
 	atomic.h \
 	bitops.h \
 	cache.h \
diff --git a/include/libxcmd.h b/include/libxcmd.h
new file mode 100644
index 0000000..e8d2ffc
--- /dev/null
+++ b/include/libxcmd.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * 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 __LIBXCMD_H__
+#define __LIBXCMD_H__
+
+#include "libxfs.h"
+#include <sys/time.h>
+
+/*
+ * Device topology information.
+ */
+typedef struct fs_topology {
+	int	dsunit;		/* stripe unit - data subvolume */
+	int	dswidth;	/* stripe width - data subvolume */
+	int	rtswidth;	/* stripe width - rt subvolume */
+	int	lsectorsize;	/* logical sector size &*/
+	int	psectorsize;	/* physical sector size */
+} fs_topology_t;
+
+extern void
+get_topology(
+	libxfs_init_t		*xi,
+	struct fs_topology	*ft,
+	int			force_overwrite);
+
+extern void
+calc_default_ag_geometry(
+	int		blocklog,
+	__uint64_t	dblocks,
+	int		multidisk,
+	__uint64_t	*agsize,
+	__uint64_t	*agcount);
+
+extern int
+check_overwrite(
+	const char	*device);
+
+
+
+#endif	/* __LIBXCMD_H__ */
diff --git a/libxcmd/Makefile b/libxcmd/Makefile
index 7701ed9..aab8d6d 100644
--- a/libxcmd/Makefile
+++ b/libxcmd/Makefile
@@ -10,7 +10,7 @@ LT_CURRENT = 0
 LT_REVISION = 0
 LT_AGE = 0
 
-CFILES = command.c input.c paths.c projects.c help.c quit.c
+CFILES = command.c input.c paths.c projects.c help.c quit.c topology.c
 
 ifeq ($(HAVE_GETMNTENT),yes)
 LCFLAGS += -DHAVE_GETMNTENT
diff --git a/libxcmd/topology.c b/libxcmd/topology.c
new file mode 100644
index 0000000..8b0276a
--- /dev/null
+++ b/libxcmd/topology.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
+ * 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 "libxcmd.h"
+#ifdef ENABLE_BLKID
+#  include <blkid/blkid.h>
+#endif /* ENABLE_BLKID */
+#include "xfs_multidisk.h"
+
+#define TERABYTES(count, blog)	((__uint64_t)(count) << (40 - (blog)))
+#define GIGABYTES(count, blog)	((__uint64_t)(count) << (30 - (blog)))
+#define MEGABYTES(count, blog)	((__uint64_t)(count) << (20 - (blog)))
+
+void
+calc_default_ag_geometry(
+	int		blocklog,
+	__uint64_t	dblocks,
+	int		multidisk,
+	__uint64_t	*agsize,
+	__uint64_t	*agcount)
+{
+	__uint64_t	blocks = 0;
+	int		shift = 0;
+
+	/*
+	 * First handle the high extreme - the point at which we will
+	 * always use the maximum AG size.
+	 *
+	 * This applies regardless of storage configuration.
+	 */
+	if (dblocks >= TERABYTES(32, blocklog)) {
+		blocks = XFS_AG_MAX_BLOCKS(blocklog);
+		goto done;
+	}
+
+	/*
+	 * For a single underlying storage device over 4TB in size
+	 * use the maximum AG size.  Between 128MB and 4TB, just use
+	 * 4 AGs and scale up smoothly between min/max AG sizes.
+	 */
+	if (!multidisk) {
+		if (dblocks >= TERABYTES(4, blocklog)) {
+			blocks = XFS_AG_MAX_BLOCKS(blocklog);
+			goto done;
+		} else if (dblocks >= MEGABYTES(128, blocklog)) {
+			shift = XFS_NOMULTIDISK_AGLOG;
+			goto calc_blocks;
+		}
+	}
+
+	/*
+	 * For the multidisk configs we choose an AG count based on the number
+	 * of data blocks available, trying to keep the number of AGs higher
+	 * than the single disk configurations. This makes the assumption that
+	 * larger filesystems have more parallelism available to them.
+	 */
+	shift = XFS_MULTIDISK_AGLOG;
+	if (dblocks <= GIGABYTES(512, blocklog))
+		shift--;
+	if (dblocks <= GIGABYTES(8, blocklog))
+		shift--;
+	if (dblocks < MEGABYTES(128, blocklog))
+		shift--;
+	if (dblocks < MEGABYTES(64, blocklog))
+		shift--;
+	if (dblocks < MEGABYTES(32, blocklog))
+		shift--;
+
+	/*
+	 * If dblocks is not evenly divisible by the number of
+	 * desired AGs, round "blocks" up so we don't lose the
+	 * last bit of the filesystem. The same principle applies
+	 * to the AG count, so we don't lose the last AG!
+	 */
+calc_blocks:
+	ASSERT(shift >= 0 && shift <= XFS_MULTIDISK_AGLOG);
+	blocks = dblocks >> shift;
+	if (dblocks & xfs_mask32lo(shift)) {
+		if (blocks < XFS_AG_MAX_BLOCKS(blocklog))
+		    blocks++;
+	}
+done:
+	*agsize = blocks;
+	*agcount = dblocks / blocks + (dblocks % blocks != 0);
+}
+
+/*
+ * Check for existing filesystem or partition table on device.
+ * Returns:
+ *	 1 for existing fs or partition
+ *	 0 for nothing found
+ *	-1 for internal error
+ */
+#ifdef ENABLE_BLKID
+int
+check_overwrite(
+	const char	*device)
+{
+	const char	*type;
+	blkid_probe	pr = NULL;
+	int		ret;
+	int		fd;
+	long long	size;
+	int		bsz;
+
+	if (!device || !*device)
+		return 0;
+
+	ret = -1; /* will reset on success of all setup calls */
+
+	fd = open(device, O_RDONLY);
+	if (fd < 0)
+		goto out;
+	platform_findsizes((char *)device, fd, &size, &bsz);
+	close(fd);
+
+	/* nothing to overwrite on a 0-length device */
+	if (size == 0) {
+		ret = 0;
+		goto out;
+	}
+
+	pr = blkid_new_probe_from_filename(device);
+	if (!pr)
+		goto out;
+
+	ret = blkid_probe_enable_partitions(pr, 1);
+	if (ret < 0)
+		goto out;
+
+	ret = blkid_do_fullprobe(pr);
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * Blkid returns 1 for nothing found and 0 when it finds a signature,
+	 * but we want the exact opposite, so reverse the return value here.
+	 *
+	 * In addition print some useful diagnostics about what actually is
+	 * on the device.
+	 */
+	if (ret) {
+		ret = 0;
+		goto out;
+	}
+
+	if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
+		fprintf(stderr,
+			_("%s: %s appears to contain an existing "
+			"filesystem (%s).\n"), progname, device, type);
+	} else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
+		fprintf(stderr,
+			_("%s: %s appears to contain a partition "
+			"table (%s).\n"), progname, device, type);
+	} else {
+		fprintf(stderr,
+			_("%s: %s appears to contain something weird "
+			"according to blkid\n"), progname, device);
+	}
+	ret = 1;
+out:
+	if (pr)
+		blkid_free_probe(pr);
+	if (ret == -1)
+		fprintf(stderr,
+			_("%s: probe of %s failed, cannot detect "
+			  "existing filesystem.\n"), progname, device);
+	return ret;
+}
+
+static void blkid_get_topology(
+	const char	*device,
+	int		*sunit,
+	int		*swidth,
+	int		*lsectorsize,
+	int		*psectorsize,
+	int		force_overwrite)
+{
+
+	blkid_topology tp;
+	blkid_probe pr;
+	unsigned long val;
+	struct stat statbuf;
+
+	/* can't get topology info from a file */
+	if (!stat(device, &statbuf) && S_ISREG(statbuf.st_mode)) {
+		fprintf(stderr,
+	_("%s: Warning: trying to probe topology of a file %s!\n"),
+			progname, device);
+		return;
+	}
+
+	pr = blkid_new_probe_from_filename(device);
+	if (!pr)
+		return;
+
+	tp = blkid_probe_get_topology(pr);
+	if (!tp)
+		goto out_free_probe;
+
+	val = blkid_topology_get_logical_sector_size(tp);
+	*lsectorsize = val;
+	val = blkid_topology_get_physical_sector_size(tp);
+	*psectorsize = val;
+	val = blkid_topology_get_minimum_io_size(tp);
+	*sunit = val;
+	val = blkid_topology_get_optimal_io_size(tp);
+	*swidth = val;
+
+	/*
+	 * If the reported values are the same as the physical sector size
+	 * do not bother to report anything.  It will only cause warnings
+	 * if people specify larger stripe units or widths manually.
+	 */
+	if (*sunit == *psectorsize || *swidth == *psectorsize) {
+		*sunit = 0;
+		*swidth = 0;
+	}
+
+	/*
+	 * Blkid reports the information in terms of bytes, but we want it in
+	 * terms of 512 bytes blocks (only to convert it to bytes later..)
+	 */
+	*sunit = *sunit >> 9;
+	*swidth = *swidth >> 9;
+
+	if (blkid_topology_get_alignment_offset(tp) != 0) {
+		fprintf(stderr,
+			_("warning: device is not properly aligned %s\n"),
+			device);
+
+		if (!force_overwrite) {
+			fprintf(stderr,
+				_("Use -f to force usage of a misaligned device\n"));
+
+			exit(EXIT_FAILURE);
+		}
+		/* Do not use physical sector size if the device is misaligned */
+		*psectorsize = *lsectorsize;
+	}
+
+	blkid_free_probe(pr);
+	return;
+
+out_free_probe:
+	blkid_free_probe(pr);
+	fprintf(stderr,
+		_("warning: unable to probe device topology for device %s\n"),
+		device);
+}
+#else /* ifdef ENABLE_BLKID */
+/*
+ * Without blkid, we can't do a good check for signatures.
+ * So instead of some messy attempts, just disable any checks
+ * and always return 'nothing found'.
+ */
+#  warning BLKID is disabled, so signature detection and block device\
+ access are not working!
+int
+check_overwrite(
+	const char	*device)
+{
+	return 1;
+}
+
+static void blkid_get_topology(
+	const char	*device,
+	int		*sunit,
+	int		*swidth,
+	int		*lsectorsize,
+	int		*psectorsize,
+	int		force_overwrite)
+{
+	/*
+	 * Shouldn't make any difference (no blkid = no block device access),
+	 * but make sure this dummy replacement returns with at least some
+	 * sanity.
+	 */
+	*lsectorsize = *psectorsize = 512;
+}
+
+#endif /* ENABLE_BLKID */
+
+void get_topology(
+	libxfs_init_t		*xi,
+	struct fs_topology	*ft,
+	int			force_overwrite)
+{
+	struct stat statbuf;
+	char *dfile = xi->volname ? xi->volname : xi->dname;
+
+	/*
+	 * If our target is a regular file, use platform_findsizes
+	 * to try to obtain the underlying filesystem's requirements
+	 * for direct IO; we'll set our sector size to that if possible.
+	 */
+	if (xi->disfile ||
+	    (!stat(dfile, &statbuf) && S_ISREG(statbuf.st_mode))) {
+		int fd;
+		int flags = O_RDONLY;
+		long long dummy;
+
+		/* with xi->disfile we may not have the file yet! */
+		if (xi->disfile)
+			flags |= O_CREAT;
+
+		fd = open(dfile, flags, 0666);
+		if (fd >= 0) {
+			platform_findsizes(dfile, fd, &dummy, &ft->lsectorsize);
+			close(fd);
+			ft->psectorsize = ft->lsectorsize;
+		} else
+			ft->psectorsize = ft->lsectorsize = BBSIZE;
+	} else {
+		blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth,
+				   &ft->lsectorsize, &ft->psectorsize,
+				   force_overwrite);
+	}
+
+	if (xi->rtname && !xi->risfile) {
+		int sunit, lsectorsize, psectorsize;
+
+		blkid_get_topology(xi->rtname, &sunit, &ft->rtswidth,
+				   &lsectorsize, &psectorsize, force_overwrite);
+	}
+}
diff --git a/mkfs/Makefile b/mkfs/Makefile
index 63ba4ec..f0e4ce1 100644
--- a/mkfs/Makefile
+++ b/mkfs/Makefile
@@ -10,7 +10,7 @@ LTCOMMAND = mkfs.xfs
 HFILES =
 CFILES = maxtrres.c proto.c xfs_mkfs.c
 
-LLDLIBS += $(LIBBLKID) $(LIBXFS) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
+LLDLIBS += $(LIBBLKID) $(LIBXFS) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) $(LIBXCMD)
 LTDEPENDENCIES += $(LIBXFS)
 LLDFLAGS = -static-libtool-libs
 
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 955dcfd..ad3fd77 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -22,17 +22,7 @@
 #  include <blkid/blkid.h>
 #endif /* ENABLE_BLKID */
 #include "xfs_multidisk.h"
-
-/*
- * Device topology information.
- */
-struct fs_topology {
-	int	dsunit;		/* stripe unit - data subvolume */
-	int	dswidth;	/* stripe width - data subvolume */
-	int	rtswidth;	/* stripe width - rt subvolume */
-	int	lsectorsize;	/* logical sector size &*/
-	int	psectorsize;	/* physical sector size */
-};
+#include "libxcmd.h"
 
 /*
  * Prototypes for internal functions.
@@ -777,247 +767,6 @@ calc_stripe_factors(
 		*lsunit = (int)BTOBBT(lsu);
 }
 
-/*
- * Check for existing filesystem or partition table on device.
- * Returns:
- *	 1 for existing fs or partition
- *	 0 for nothing found
- *	-1 for internal error
- */
-#ifdef ENABLE_BLKID
-static int
-check_overwrite(
-	const char	*device)
-{
-	const char	*type;
-	blkid_probe	pr = NULL;
-	int		ret;
-	int		fd;
-	long long	size;
-	int		bsz;
-
-	if (!device || !*device)
-		return 0;
-
-	ret = -1; /* will reset on success of all setup calls */
-
-	fd = open(device, O_RDONLY);
-	if (fd < 0)
-		goto out;
-	platform_findsizes((char *)device, fd, &size, &bsz);
-	close(fd);
-
-	/* nothing to overwrite on a 0-length device */
-	if (size == 0) {
-		ret = 0;
-		goto out;
-	}
-
-	pr = blkid_new_probe_from_filename(device);
-	if (!pr)
-		goto out;
-
-	ret = blkid_probe_enable_partitions(pr, 1);
-	if (ret < 0)
-		goto out;
-
-	ret = blkid_do_fullprobe(pr);
-	if (ret < 0)
-		goto out;
-
-	/*
-	 * Blkid returns 1 for nothing found and 0 when it finds a signature,
-	 * but we want the exact opposite, so reverse the return value here.
-	 *
-	 * In addition print some useful diagnostics about what actually is
-	 * on the device.
-	 */
-	if (ret) {
-		ret = 0;
-		goto out;
-	}
-
-	if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
-		fprintf(stderr,
-			_("%s: %s appears to contain an existing "
-			"filesystem (%s).\n"), progname, device, type);
-	} else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
-		fprintf(stderr,
-			_("%s: %s appears to contain a partition "
-			"table (%s).\n"), progname, device, type);
-	} else {
-		fprintf(stderr,
-			_("%s: %s appears to contain something weird "
-			"according to blkid\n"), progname, device);
-	}
-	ret = 1;
-out:
-	if (pr)
-		blkid_free_probe(pr);
-	if (ret == -1)
-		fprintf(stderr,
-			_("%s: probe of %s failed, cannot detect "
-			  "existing filesystem.\n"), progname, device);
-	return ret;
-}
-
-static void blkid_get_topology(
-	const char	*device,
-	int		*sunit,
-	int		*swidth,
-	int		*lsectorsize,
-	int		*psectorsize,
-	int		force_overwrite)
-{
-
-	blkid_topology tp;
-	blkid_probe pr;
-	unsigned long val;
-	struct stat statbuf;
-
-	/* can't get topology info from a file */
-	if (!stat(device, &statbuf) && S_ISREG(statbuf.st_mode)) {
-		fprintf(stderr,
-	_("%s: Warning: trying to probe topology of a file %s!\n"),
-			progname, device);
-		return;
-	}
-
-	pr = blkid_new_probe_from_filename(device);
-	if (!pr)
-		return;
-
-	tp = blkid_probe_get_topology(pr);
-	if (!tp)
-		goto out_free_probe;
-
-	val = blkid_topology_get_logical_sector_size(tp);
-	*lsectorsize = val;
-	val = blkid_topology_get_physical_sector_size(tp);
-	*psectorsize = val;
-	val = blkid_topology_get_minimum_io_size(tp);
-	*sunit = val;
-	val = blkid_topology_get_optimal_io_size(tp);
-	*swidth = val;
-
-	/*
-	 * If the reported values are the same as the physical sector size
-	 * do not bother to report anything.  It will only cause warnings
-	 * if people specify larger stripe units or widths manually.
-	 */
-	if (*sunit == *psectorsize || *swidth == *psectorsize) {
-		*sunit = 0;
-		*swidth = 0;
-	}
-
-	/*
-	 * Blkid reports the information in terms of bytes, but we want it in
-	 * terms of 512 bytes blocks (only to convert it to bytes later..)
-	 */
-	*sunit = *sunit >> 9;
-	*swidth = *swidth >> 9;
-
-	if (blkid_topology_get_alignment_offset(tp) != 0) {
-		fprintf(stderr,
-			_("warning: device is not properly aligned %s\n"),
-			device);
-
-		if (!force_overwrite) {
-			fprintf(stderr,
-				_("Use -f to force usage of a misaligned device\n"));
-
-			exit(EXIT_FAILURE);
-		}
-		/* Do not use physical sector size if the device is misaligned */
-		*psectorsize = *lsectorsize;
-	}
-
-	blkid_free_probe(pr);
-	return;
-
-out_free_probe:
-	blkid_free_probe(pr);
-	fprintf(stderr,
-		_("warning: unable to probe device topology for device %s\n"),
-		device);
-}
-#else /* ifdef ENABLE_BLKID */
-/*
- * Without blkid, we can't do a good check for signatures.
- * So instead of some messy attempts, just disable any checks
- * and always return 'nothing found'.
- */
-#  warning BLKID is disabled, so signature detection and block device\
- access are not working!
-static int
-check_overwrite(
-	const char	*device)
-{
-	return 1;
-}
-
-static void blkid_get_topology(
-	const char	*device,
-	int		*sunit,
-	int		*swidth,
-	int		*lsectorsize,
-	int		*psectorsize,
-	int		force_overwrite)
-{
-	/*
-	 * Shouldn't make any difference (no blkid = no block device access),
-	 * but make sure this dummy replacement returns with at least some
-	 * sanity.
-	 */
-	*lsectorsize = *psectorsize = 512;
-}
-
-#endif /* ENABLE_BLKID */
-
-static void get_topology(
-	libxfs_init_t		*xi,
-	struct fs_topology	*ft,
-	int			force_overwrite)
-{
-	struct stat statbuf;
-	char *dfile = xi->volname ? xi->volname : xi->dname;
-
-	/*
-	 * If our target is a regular file, use platform_findsizes
-	 * to try to obtain the underlying filesystem's requirements
-	 * for direct IO; we'll set our sector size to that if possible.
-	 */
-	if (xi->disfile ||
-	    (!stat(dfile, &statbuf) && S_ISREG(statbuf.st_mode))) {
-		int fd;
-		int flags = O_RDONLY;
-		long long dummy;
-
-		/* with xi->disfile we may not have the file yet! */
-		if (xi->disfile)
-			flags |= O_CREAT;
-
-		fd = open(dfile, flags, 0666);
-		if (fd >= 0) {
-			platform_findsizes(dfile, fd, &dummy, &ft->lsectorsize);
-			close(fd);
-			ft->psectorsize = ft->lsectorsize;
-		} else
-			ft->psectorsize = ft->lsectorsize = BBSIZE;
-	} else {
-		blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth,
-				   &ft->lsectorsize, &ft->psectorsize,
-				   force_overwrite);
-	}
-
-	if (xi->rtname && !xi->risfile) {
-		int sunit, lsectorsize, psectorsize;
-
-		blkid_get_topology(xi->rtname, &sunit, &ft->rtswidth,
-				   &lsectorsize, &psectorsize, force_overwrite);
-	}
-}
-
 static void
 check_device_type(
 	const char	*name,
@@ -1199,80 +948,6 @@ calc_default_imaxpct(
 	return 1;
 }
 
-
-void
-calc_default_ag_geometry(
-	int		blocklog,
-	__uint64_t	dblocks,
-	int		multidisk,
-	__uint64_t	*agsize,
-	__uint64_t	*agcount)
-{
-	__uint64_t	blocks = 0;
-	int		shift = 0;
-
-	/*
-	 * First handle the high extreme - the point at which we will
-	 * always use the maximum AG size.
-	 *
-	 * This applies regardless of storage configuration.
-	 */
-	if (dblocks >= TERABYTES(32, blocklog)) {
-		blocks = XFS_AG_MAX_BLOCKS(blocklog);
-		goto done;
-	}
-
-	/*
-	 * For a single underlying storage device over 4TB in size
-	 * use the maximum AG size.  Between 128MB and 4TB, just use
-	 * 4 AGs and scale up smoothly between min/max AG sizes.
-	 */
-	if (!multidisk) {
-		if (dblocks >= TERABYTES(4, blocklog)) {
-			blocks = XFS_AG_MAX_BLOCKS(blocklog);
-			goto done;
-		} else if (dblocks >= MEGABYTES(128, blocklog)) {
-			shift = XFS_NOMULTIDISK_AGLOG;
-			goto calc_blocks;
-		}
-	}
-
-	/*
-	 * For the multidisk configs we choose an AG count based on the number
-	 * of data blocks available, trying to keep the number of AGs higher
-	 * than the single disk configurations. This makes the assumption that
-	 * larger filesystems have more parallelism available to them.
-	 */
-	shift = XFS_MULTIDISK_AGLOG;
-	if (dblocks <= GIGABYTES(512, blocklog))
-		shift--;
-	if (dblocks <= GIGABYTES(8, blocklog))
-		shift--;
-	if (dblocks < MEGABYTES(128, blocklog))
-		shift--;
-	if (dblocks < MEGABYTES(64, blocklog))
-		shift--;
-	if (dblocks < MEGABYTES(32, blocklog))
-		shift--;
-
-	/*
-	 * If dblocks is not evenly divisible by the number of
-	 * desired AGs, round "blocks" up so we don't lose the
-	 * last bit of the filesystem. The same principle applies
-	 * to the AG count, so we don't lose the last AG!
-	 */
-calc_blocks:
-	ASSERT(shift >= 0 && shift <= XFS_MULTIDISK_AGLOG);
-	blocks = dblocks >> shift;
-	if (dblocks & xfs_mask32lo(shift)) {
-		if (blocks < XFS_AG_MAX_BLOCKS(blocklog))
-		    blocks++;
-	}
-done:
-	*agsize = blocks;
-	*agcount = dblocks / blocks + (dblocks % blocks != 0);
-}
-
 static void
 validate_ag_geometry(
 	int		blocklog,
-- 
2.5.5

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

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v5 2/2] xfs_repair: new secondary superblock search method
  2016-05-11 22:45 [PATCH v5 0/2] xfs_repair: improved secondary sb search Bill O'Donnell
  2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
@ 2016-05-11 22:45 ` Bill O'Donnell
  2016-05-12  1:09 ` [PATCH v5 0/2] xfs_repair: improved secondary sb search Eric Sandeen
  2 siblings, 0 replies; 10+ messages in thread
From: Bill O'Donnell @ 2016-05-11 22:45 UTC (permalink / raw)
  To: xfs

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 +-
 repair/Makefile |  4 ++--
 repair/sb.c     | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 70 insertions(+), 8 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/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/sb.c b/repair/sb.c
index 4eef14a..7e4708c 100644
--- a/repair/sb.c
+++ b/repair/sb.c
@@ -17,6 +17,7 @@
  */
 
 #include "libxfs.h"
+#include "libxcmd.h"
 #include "libxlog.h"
 #include "agheader.h"
 #include "globals.h"
@@ -85,10 +86,15 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest)
 }
 
 /*
- * find a secondary superblock, copy it into the sb buffer
+ * find a secondary superblock, copy it into the sb buffer.
+ * start is the point to begin reading BSIZE bytes.
+ * skip contains a byte-count of how far to advance for next read.
  */
-int
-find_secondary_sb(xfs_sb_t *rsb)
+static int
+__find_secondary_sb(
+	xfs_sb_t	*rsb,
+	__uint64_t	start,
+	__uint64_t	skip)
 {
 	xfs_off_t	off;
 	xfs_sb_t	*sb;
@@ -117,7 +123,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 = start; !done ; off += skip)  {
 		/*
 		 * read disk 1 MByte at a time.
 		 */
@@ -166,7 +172,63 @@ find_secondary_sb(xfs_sb_t *rsb)
 	}
 
 	free(sb);
-	return(retval);
+	return retval;
+}
+
+static 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;
+	dblocks = x->dsize >> (blocklog - BBSHIFT);
+	calc_default_ag_geometry(blocklog, dblocks, multidisk,
+				 agsize, agcount);
+
+	return blocklog;
+}
+
+int
+find_secondary_sb(xfs_sb_t *rsb)
+{
+	int		retval;
+	__uint64_t	agcount;
+	__uint64_t	agsize;
+	__uint64_t	skip;
+	int		blocklog;
+
+	/*
+	 * Attempt to find secondary sb with a coarse approach.
+	 * Failing that, fallback to a fine-grained approach.
+	 */
+	blocklog = guess_default_geometry(&agsize, &agcount, &x);
+
+	/*
+	 * use found ag geometry to quickly find secondary sb
+	 */
+	skip = agsize << blocklog;
+	retval = __find_secondary_sb(rsb, skip, skip);
+	if (!retval)  {
+		/*
+		 * fallback: Start at min agsize and scan all blocks
+		 */
+		retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES, BSIZE);
+	}
+	return retval;
 }
 
 /*
-- 
2.5.5

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

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 0/2] xfs_repair: improved secondary sb search
  2016-05-11 22:45 [PATCH v5 0/2] xfs_repair: improved secondary sb search Bill O'Donnell
  2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
  2016-05-11 22:45 ` [PATCH v5 2/2] xfs_repair: new secondary superblock search method Bill O'Donnell
@ 2016-05-12  1:09 ` Eric Sandeen
  2 siblings, 0 replies; 10+ messages in thread
From: Eric Sandeen @ 2016-05-12  1:09 UTC (permalink / raw)
  To: xfs

Ok, just a rebase, and all the code moves match current upstream,
so for both patches:

Reviewed-by: Eric Sandeen <sandeen@sandeen.net>

On 5/11/16 5:45 PM, Bill O'Donnell wrote:
> 
> Hello -
> 
> New iteration (v5) of this series...
> 
> Current xfs_repair uses a brute force approach to find a valid
> secondary sb. This series optimizes the secondary sb search, using
> similar method to determine geometry as that of xfs_mkfs. If the
> faster method fails in its search, fall back to original brute force
> slower search.
> 
> version history:
> ----
> v1: http://oss.sgi.com/archives/xfs/2016-02/msg00304.html
> v2: patch 2 whitespace fixups
> v3: patch 2 correct functionality; style fixups
> v4: patch 1,2 properly see to style and whitespace fixups
> v5: patch 1 rebase to latest
> ----
> 
> patch 1 has some general infrastructure adjustments, moving general
> topology functions from mkfs to libxcmd.
> 
> patch 2 adds the new secondary superblock search method.
> 
> Questions, comments are welcome.
> 
> Thanks-
> Bill
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
> 

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
@ 2016-05-12 11:55   ` Christoph Hellwig
  2016-05-12 12:20     ` Bill O'Donnell
  2016-05-30  2:13   ` Dave Chinner
  1 sibling, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2016-05-12 11:55 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: xfs

I still think libxfs would be the better place, but otherwise this looks
fine in general.

> +#ifdef ENABLE_BLKID
> +#  include <blkid/blkid.h>
> +#endif /* ENABLE_BLKID */
> +#include "xfs_multidisk.h"

But what tree is this against?  I can't find a xfs_multidisk.h in
the master branch, nor in this patch?

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-12 11:55   ` Christoph Hellwig
@ 2016-05-12 12:20     ` Bill O'Donnell
  2016-05-12 14:47       ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Bill O'Donnell @ 2016-05-12 12:20 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: xfs

On Thu, May 12, 2016 at 04:55:13AM -0700, Christoph Hellwig wrote:
> I still think libxfs would be the better place, but otherwise this looks
> fine in general.
> 
> > +#ifdef ENABLE_BLKID
> > +#  include <blkid/blkid.h>
> > +#endif /* ENABLE_BLKID */
> > +#include "xfs_multidisk.h"
> 
> But what tree is this against?  I can't find a xfs_multidisk.h in
> the master branch, nor in this patch?

xfs_multidisk.h came about a few days ago (4a32b9e928b80)
git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git



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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-12 12:20     ` Bill O'Donnell
@ 2016-05-12 14:47       ` Christoph Hellwig
  2016-05-12 15:04         ` Eric Sandeen
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2016-05-12 14:47 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: Christoph Hellwig, xfs

On Thu, May 12, 2016 at 07:20:39AM -0500, Bill O'Donnell wrote:
> xfs_multidisk.h came about a few days ago (4a32b9e928b80)
> git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git

Gah, looks like I'm stuck on the oss.sgi.com repo..

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-12 14:47       ` Christoph Hellwig
@ 2016-05-12 15:04         ` Eric Sandeen
  2016-05-12 21:42           ` Dave Chinner
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Sandeen @ 2016-05-12 15:04 UTC (permalink / raw)
  To: xfs

On 5/12/16 9:47 AM, Christoph Hellwig wrote:
> On Thu, May 12, 2016 at 07:20:39AM -0500, Bill O'Donnell wrote:
>> xfs_multidisk.h came about a few days ago (4a32b9e928b80)
>> git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git
> 
> Gah, looks like I'm stuck on the oss.sgi.com repo..

We really need to kill that.

-Eric

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-12 15:04         ` Eric Sandeen
@ 2016-05-12 21:42           ` Dave Chinner
  0 siblings, 0 replies; 10+ messages in thread
From: Dave Chinner @ 2016-05-12 21:42 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: xfs

On Thu, May 12, 2016 at 10:04:50AM -0500, Eric Sandeen wrote:
> On 5/12/16 9:47 AM, Christoph Hellwig wrote:
> > On Thu, May 12, 2016 at 07:20:39AM -0500, Bill O'Donnell wrote:
> >> xfs_multidisk.h came about a few days ago (4a32b9e928b80)
> >> git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git
> > 
> > Gah, looks like I'm stuck on the oss.sgi.com repo..
> 
> We really need to kill that.

I only update xfsprogs on oss at releases. All dev happens on the
kernel.org repo. Before we kill oss.sgi.com we have to sort out how
to get release tarballs up on kernel.org. I'm pretty we can do that
'kup', but I haven't had time to work out the process needed to do
that. This is really the only thing keeping us on oss.sgi.com.

I'm also not sure what to do with all the tarballs from previous
releases that are on oss. I think I can regenerate all the recent
releases (e.g. 3.2.0 onwards) without much trouble, but the older
releases might be more of an issue. More investigation needed.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v5 1/2] libxcmd: generalize topology functions
  2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
  2016-05-12 11:55   ` Christoph Hellwig
@ 2016-05-30  2:13   ` Dave Chinner
  1 sibling, 0 replies; 10+ messages in thread
From: Dave Chinner @ 2016-05-30  2:13 UTC (permalink / raw)
  To: Bill O'Donnell; +Cc: xfs

On Wed, May 11, 2016 at 05:45:16PM -0500, Bill O'Donnell wrote:
> Move general topology functions from xfs_mkfs to new topology
> collection in libxcmd.
> 
> Signed-off-by: Bill O'Donnell <billodo@redhat.com>

FYI, this patch breaks 'make deb'.

I don't expect anyone to know this - the debian/rules build script
has a special hand-rolled mkfs build for the debian installer. This
new libxcmd dependency also needs to be described in that script.
I've fixed that up, but it's also pointed out a couple of other
things to do with dependencies:

> diff --git a/mkfs/Makefile b/mkfs/Makefile
> index 63ba4ec..f0e4ce1 100644
> --- a/mkfs/Makefile
> +++ b/mkfs/Makefile
> @@ -10,7 +10,7 @@ LTCOMMAND = mkfs.xfs
>  HFILES =
>  CFILES = maxtrres.c proto.c xfs_mkfs.c
>  
> -LLDLIBS += $(LIBBLKID) $(LIBXFS) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
> +LLDLIBS += $(LIBBLKID) $(LIBXFS) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) $(LIBXCMD)
>  LTDEPENDENCIES += $(LIBXFS)
>  LLDFLAGS = -static-libtool-libs

mkfs.xfs also needs the build dependency on libxcmd to be expressed
in LTDEPENDENCIES. It's just lucky that other targets have already
expressed such "libxfs + libxcmd" dependencies as that ensured
libxcmd was already built before mkfs tries to link against it.
Blind luck strikes again!

Those top level build dependencies are expressed in the top level
Makefile like so:

--- a/Makefile
+++ b/Makefile
@@ -82,6 +82,7 @@ io: libxcmd libhandle
 quota: libxcmd
 repair: libxlog
 copy: libxlog
+mkfs: libxcmd
 
 ifeq ($(HAVE_BUILDDEFS), yes)
 include $(BUILDRULES)

I've fixed these problems because I need to build .deb packages to
deploy changes for testing.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-05-30  2:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-11 22:45 [PATCH v5 0/2] xfs_repair: improved secondary sb search Bill O'Donnell
2016-05-11 22:45 ` [PATCH v5 1/2] libxcmd: generalize topology functions Bill O'Donnell
2016-05-12 11:55   ` Christoph Hellwig
2016-05-12 12:20     ` Bill O'Donnell
2016-05-12 14:47       ` Christoph Hellwig
2016-05-12 15:04         ` Eric Sandeen
2016-05-12 21:42           ` Dave Chinner
2016-05-30  2:13   ` Dave Chinner
2016-05-11 22:45 ` [PATCH v5 2/2] xfs_repair: new secondary superblock search method Bill O'Donnell
2016-05-12  1:09 ` [PATCH v5 0/2] xfs_repair: improved secondary sb search Eric Sandeen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox