* [[PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method
@ 2016-02-10 1:34 Bill O'Donnell
2016-02-10 4:49 ` [PATCH " Eric Sandeen
0 siblings, 1 reply; 4+ messages in thread
From: Bill O'Donnell @ 2016-02-10 1:34 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 +-
include/libxcmd.h | 4 +++-
libxcmd/topology.c | 35 ++++++++++++++++++++++++++++----
repair/Makefile | 4 ++--
repair/sb.c | 58 ++++++++++++++++++++++++++++++++++++++++++++----------
5 files changed, 85 insertions(+), 18 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..b98d9b9 100644
--- a/libxcmd/topology.c
+++ b/libxcmd/topology.c
@@ -192,7 +192,8 @@ out:
return ret;
}
-static void blkid_get_topology(
+static void
+blkid_get_topology(
const char *device,
int *sunit,
int *swidth,
@@ -284,7 +285,8 @@ check_overwrite(
return 1;
}
-static void blkid_get_topology(
+static void
+blkid_get_topology(
const char *device,
int *sunit,
int *swidth,
@@ -302,8 +304,8 @@ static void blkid_get_topology(
#endif /* ENABLE_BLKID */
-
-void get_topology(
+void
+get_topology(
libxfs_init_t *xi,
struct fs_topology *ft,
int force_overwrite)
@@ -346,3 +348,28 @@ void get_topology(
&lsectorsize, &psectorsize, force_overwrite);
}
}
+
+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;
+}
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..8bc246e 100644
--- a/repair/sb.c
+++ b/repair/sb.c
@@ -22,6 +22,7 @@
#include "globals.h"
#include "protos.h"
#include "err_protos.h"
+#include "libxcmd.h"
#define BSIZE (1024 * 1024)
@@ -85,10 +86,11 @@ 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.
+ * skipsize units is bytes, it contains either the agsize in bytes
+ * (if known), or the minimum agsize in bytes if agsize unknown.
*/
-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;
@@ -99,9 +101,9 @@ find_secondary_sb(xfs_sb_t *rsb)
int dirty;
int retval;
int bsize;
+ int readsize;
do_warn(_("\nattempting to find secondary superblock...\n"));
-
sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
if (!sb) {
do_error(
@@ -113,13 +115,16 @@ find_secondary_sb(xfs_sb_t *rsb)
retval = 0;
dirty = 0;
bsize = 0;
+ readsize = 0;
/*
* 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 += readsize) {
/*
- * read disk 1 MByte at a time.
+ * read disk using readsize interval
+ * (either the bytecount of actual agsize or bsize if
+ * agsize undetermined.)
*/
if (lseek64(x.dfd, off, SEEK_SET) != off) {
done = 1;
@@ -128,9 +133,13 @@ find_secondary_sb(xfs_sb_t *rsb)
if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) {
done = 1;
}
-
+ if (skipsize == XFS_AG_MIN_BYTES) {
+ readsize = bsize;
+ }
+ else {
+ readsize = skipsize;
+ }
do_warn(".");
-
/*
* check the buffer 512 bytes at a time since
* we don't know how big the sectors really are.
@@ -164,9 +173,38 @@ find_secondary_sb(xfs_sb_t *rsb)
}
}
}
-
free(sb);
- return(retval);
+ return retval;
+}
+
+int
+find_secondary_sb(xfs_sb_t *rsb)
+{
+ int retval;
+ __uint64_t skipsize;
+ __uint64_t agcount;
+ __uint64_t agsize;
+ int blocklog;
+
+ /*
+ * 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.
+ */
+ blocklog = guess_default_geometry(&agsize, &agcount, x);
+
+ /*
+ * use found ag geometry to quickly find secondary sb
+ */
+ skipsize = agsize << blocklog;
+ 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;
}
/*
--
2.5.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method
2016-02-10 1:34 [[PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method Bill O'Donnell
@ 2016-02-10 4:49 ` Eric Sandeen
2016-02-10 15:43 ` Bill O'Donnell
0 siblings, 1 reply; 4+ messages in thread
From: Eric Sandeen @ 2016-02-10 4:49 UTC (permalink / raw)
To: xfs
On 2/9/16 7:34 PM, Bill O'Donnell wrote:
> 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 | 35 ++++++++++++++++++++++++++++----
> repair/Makefile | 4 ++--
> repair/sb.c | 58 ++++++++++++++++++++++++++++++++++++++++++++----------
> 5 files changed, 85 insertions(+), 18 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..b98d9b9 100644
> --- a/libxcmd/topology.c
> +++ b/libxcmd/topology.c
> @@ -192,7 +192,8 @@ out:
> return ret;
> }
>
> -static void blkid_get_topology(
> +static void
> +blkid_get_topology(
> const char *device,
> int *sunit,
> int *swidth,
> @@ -284,7 +285,8 @@ check_overwrite(
> return 1;
> }
>
> -static void blkid_get_topology(
> +static void
> +blkid_get_topology(
> const char *device,
> int *sunit,
> int *swidth,
> @@ -302,8 +304,8 @@ static void blkid_get_topology(
>
> #endif /* ENABLE_BLKID */
>
> -
> -void get_topology(
> +void
> +get_topology(
> libxfs_init_t *xi,
> struct fs_topology *ft,
> int force_overwrite)
> @@ -346,3 +348,28 @@ void get_topology(
> &lsectorsize, &psectorsize, force_overwrite);
> }
> }
> +
> +int
> +guess_default_geometry(__uint64_t *agsize, __uint64_t *agcount,
> + libxfs_init_t x)
> +{
> + struct fs_topology ft;
> + int blocklog;
When in Rome: :)
int
guess_default_geometry(
__uint64_t *agsize,
__uint64_t *agcount,
libxfs_init_t x)
{
...
(sorry, forgot to mention that last time, but other functions in the
file are laid out this way; it is easier to read)
> + __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;
> +}
> 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..8bc246e 100644
> --- a/repair/sb.c
> +++ b/repair/sb.c
> @@ -22,6 +22,7 @@
> #include "globals.h"
> #include "protos.h"
> #include "err_protos.h"
> +#include "libxcmd.h"
Nitpick, we usually include that right after libxfs.h.
> #define BSIZE (1024 * 1024)
>
> @@ -85,10 +86,11 @@ 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.
> + * skipsize units is bytes, it contains either the agsize in bytes
> + * (if known), or the minimum agsize in bytes if agsize unknown.
> */
Ok, so this is a little confused. There are actually 3 relevant
parameters here:
1) The place to start reading
2) The number of bytes to read at that point
3) How far to seek forward for the next read
In the old world, it's:
1) XFS_MIN_AG_BYTES
2) BSIZE (1MB)
3) BSIZE (i.e. it does sequential reads)
In the new world, it's:
1) the guessed AG size (skipsize?)
2) BSIZE (more than we need, but not expensive, so leave it)
3) the guessed AG size (skipsize)
You really have 2 different pieces of info: Where to do the first read,
and how far forward to skip for the next read. I don't think you
can convey that with a single argument, "skipsize."
> -int
> -find_secondary_sb(xfs_sb_t *rsb)
> +static int __find_secondary_sb(xfs_sb_t *rsb, __uint64_t skipsize)
better to format as:
static int
__find_secondary_sb(
xfs_sb_t *rsb,
__uint64_t skipsize)
{
but ...
> {
> xfs_off_t off;
> xfs_sb_t *sb;
> @@ -99,9 +101,9 @@ find_secondary_sb(xfs_sb_t *rsb)
> int dirty;
> int retval;
> int bsize;
> + int readsize;
>
> do_warn(_("\nattempting to find secondary superblock...\n"));
> -
> sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
> if (!sb) {
> do_error(
> @@ -113,13 +115,16 @@ find_secondary_sb(xfs_sb_t *rsb)
> retval = 0;
> dirty = 0;
> bsize = 0;
> + readsize = 0;
>
> /*
> * 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 += readsize) {
> /*
> - * read disk 1 MByte at a time.
we are actually still doing that, read(x.dfd, sb, BSIZE), so I'd
leave the comment...
> + * read disk using readsize interval
> + * (either the bytecount of actual agsize or bsize if
> + * agsize undetermined.)
> */
> if (lseek64(x.dfd, off, SEEK_SET) != off) {
> done = 1;
> @@ -128,9 +133,13 @@ find_secondary_sb(xfs_sb_t *rsb)
> if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) {
> done = 1;
> }
> -
> + if (skipsize == XFS_AG_MIN_BYTES) {
> + readsize = bsize;
> + }
> + else {
better as:
} else {
> + readsize = skipsize;
> + }
I wouldn't call this "readsize" - we are only ever reading BSIZE at a time.
This is how much we advance each loop, so skipsize is a bit better.
But the _functional_ problem here is that it is possible and permissible
to have a filesystem with an AG size of XFS_AG_MIN_BYTES (16MB).
So if you guessed a default geometry with an agsize of XFS_AG_MIN_BYTES,
you've gone back to the fine-grained scanning. The fs probably isn't
very big as a result, so it's not the end of the world, but ...
see below.
> do_warn(".");
> -
> /*
> * check the buffer 512 bytes at a time since
> * we don't know how big the sectors really are.
> @@ -164,9 +173,38 @@ find_secondary_sb(xfs_sb_t *rsb)
> }
> }
> }
> -
> free(sb);
> - return(retval);
> + return retval;
> +}
> +
> +int
> +find_secondary_sb(xfs_sb_t *rsb)
> +{
> + int retval;
> + __uint64_t skipsize;
> + __uint64_t agcount;
> + __uint64_t agsize;
> + int blocklog;
> +
> + /*
> + * 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.
> + */
> + blocklog = guess_default_geometry(&agsize, &agcount, x);
> +
> + /*
> + * use found ag geometry to quickly find secondary sb
> + */
> + skipsize = agsize << blocklog;
> + 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;
> }
I'd make __find_secondary_sb() take (sb, start, skip) i.e. send in
this:
> + retval = __find_secondary_sb(rsb, agsize, agsize);
> + if (!retval) {
> + /*
> + * fallback: use minimum agsize for skipsize
> + */
> + retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES, BSIZE);
> + }
and the function is something like:
static int
__find_secondary_sb(
xfs_sb_t *rsb,
xfs_off_t start,
xfs_off_t skip)
{
...
for (done = 0, off = start; !done ; off += skip) {
...
if (lseek64(x.dfd, off, SEEK_SET) != off)
done = 1;
if (!done && (read(x.dfd, sb, BSIZE)) <= 0)
done = 1;
because you really can't deduce both the starting point and the skip-ahead
size from just one parameter.
-Eric
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method
2016-02-10 4:49 ` [PATCH " Eric Sandeen
@ 2016-02-10 15:43 ` Bill O'Donnell
2016-02-10 15:51 ` Eric Sandeen
0 siblings, 1 reply; 4+ messages in thread
From: Bill O'Donnell @ 2016-02-10 15:43 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs
On Tue, Feb 09, 2016 at 10:49:20PM -0600, Eric Sandeen wrote:
> On 2/9/16 7:34 PM, Bill O'Donnell wrote:
> > 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 | 35 ++++++++++++++++++++++++++++----
> > repair/Makefile | 4 ++--
> > repair/sb.c | 58 ++++++++++++++++++++++++++++++++++++++++++++----------
> > 5 files changed, 85 insertions(+), 18 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..b98d9b9 100644
> > --- a/libxcmd/topology.c
> > +++ b/libxcmd/topology.c
> > @@ -192,7 +192,8 @@ out:
> > return ret;
> > }
> >
> > -static void blkid_get_topology(
> > +static void
> > +blkid_get_topology(
> > const char *device,
> > int *sunit,
> > int *swidth,
> > @@ -284,7 +285,8 @@ check_overwrite(
> > return 1;
> > }
> >
> > -static void blkid_get_topology(
> > +static void
> > +blkid_get_topology(
> > const char *device,
> > int *sunit,
> > int *swidth,
> > @@ -302,8 +304,8 @@ static void blkid_get_topology(
> >
> > #endif /* ENABLE_BLKID */
> >
> > -
> > -void get_topology(
> > +void
> > +get_topology(
> > libxfs_init_t *xi,
> > struct fs_topology *ft,
> > int force_overwrite)
> > @@ -346,3 +348,28 @@ void get_topology(
> > &lsectorsize, &psectorsize, force_overwrite);
> > }
> > }
> > +
> > +int
> > +guess_default_geometry(__uint64_t *agsize, __uint64_t *agcount,
> > + libxfs_init_t x)
> > +{
> > + struct fs_topology ft;
> > + int blocklog;
>
> When in Rome: :)
>
> int
> guess_default_geometry(
> __uint64_t *agsize,
> __uint64_t *agcount,
> libxfs_init_t x)
> {
> ...
>
> (sorry, forgot to mention that last time, but other functions in the
> file are laid out this way; it is easier to read)
>
> > + __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;
> > +}
> > 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..8bc246e 100644
> > --- a/repair/sb.c
> > +++ b/repair/sb.c
> > @@ -22,6 +22,7 @@
> > #include "globals.h"
> > #include "protos.h"
> > #include "err_protos.h"
> > +#include "libxcmd.h"
>
> Nitpick, we usually include that right after libxfs.h.
>
> > #define BSIZE (1024 * 1024)
> >
> > @@ -85,10 +86,11 @@ 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.
> > + * skipsize units is bytes, it contains either the agsize in bytes
> > + * (if known), or the minimum agsize in bytes if agsize unknown.
> > */
>
> Ok, so this is a little confused. There are actually 3 relevant
> parameters here:
>
> 1) The place to start reading
> 2) The number of bytes to read at that point
> 3) How far to seek forward for the next read
>
> In the old world, it's:
>
> 1) XFS_MIN_AG_BYTES
> 2) BSIZE (1MB)
> 3) BSIZE (i.e. it does sequential reads)
>
> In the new world, it's:
>
> 1) the guessed AG size (skipsize?)
> 2) BSIZE (more than we need, but not expensive, so leave it)
> 3) the guessed AG size (skipsize)
>
> You really have 2 different pieces of info: Where to do the first read,
> and how far forward to skip for the next read. I don't think you
> can convey that with a single argument, "skipsize."
>
> > -int
> > -find_secondary_sb(xfs_sb_t *rsb)
> > +static int __find_secondary_sb(xfs_sb_t *rsb, __uint64_t skipsize)
>
> better to format as:
>
> static int
> __find_secondary_sb(
> xfs_sb_t *rsb,
> __uint64_t skipsize)
> {
>
> but ...
>
> > {
> > xfs_off_t off;
> > xfs_sb_t *sb;
> > @@ -99,9 +101,9 @@ find_secondary_sb(xfs_sb_t *rsb)
> > int dirty;
> > int retval;
> > int bsize;
> > + int readsize;
> >
> > do_warn(_("\nattempting to find secondary superblock...\n"));
> > -
> > sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
> > if (!sb) {
> > do_error(
> > @@ -113,13 +115,16 @@ find_secondary_sb(xfs_sb_t *rsb)
> > retval = 0;
> > dirty = 0;
> > bsize = 0;
> > + readsize = 0;
> >
> > /*
> > * 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 += readsize) {
> > /*
> > - * read disk 1 MByte at a time.
>
> we are actually still doing that, read(x.dfd, sb, BSIZE), so I'd
> leave the comment...
>
> > + * read disk using readsize interval
> > + * (either the bytecount of actual agsize or bsize if
> > + * agsize undetermined.)
>
>
> > */
> > if (lseek64(x.dfd, off, SEEK_SET) != off) {
> > done = 1;
> > @@ -128,9 +133,13 @@ find_secondary_sb(xfs_sb_t *rsb)
> > if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) {
> > done = 1;
> > }
> > -
> > + if (skipsize == XFS_AG_MIN_BYTES) {
> > + readsize = bsize;
> > + }
> > + else {
>
> better as:
> } else {
>
> > + readsize = skipsize;
> > + }
>
> I wouldn't call this "readsize" - we are only ever reading BSIZE at a time.
> This is how much we advance each loop, so skipsize is a bit better.
>
> But the _functional_ problem here is that it is possible and permissible
> to have a filesystem with an AG size of XFS_AG_MIN_BYTES (16MB).
>
> So if you guessed a default geometry with an agsize of XFS_AG_MIN_BYTES,
> you've gone back to the fine-grained scanning. The fs probably isn't
> very big as a result, so it's not the end of the world, but ...
> see below.
>
> > do_warn(".");
> > -
> > /*
> > * check the buffer 512 bytes at a time since
> > * we don't know how big the sectors really are.
> > @@ -164,9 +173,38 @@ find_secondary_sb(xfs_sb_t *rsb)
> > }
> > }
> > }
> > -
> > free(sb);
> > - return(retval);
> > + return retval;
> > +}
> > +
> > +int
> > +find_secondary_sb(xfs_sb_t *rsb)
> > +{
> > + int retval;
> > + __uint64_t skipsize;
> > + __uint64_t agcount;
> > + __uint64_t agsize;
> > + int blocklog;
> > +
> > + /*
> > + * 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.
> > + */
> > + blocklog = guess_default_geometry(&agsize, &agcount, x);
> > +
> > + /*
> > + * use found ag geometry to quickly find secondary sb
> > + */
> > + skipsize = agsize << blocklog;
> > + 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;
> > }
>
> I'd make __find_secondary_sb() take (sb, start, skip) i.e. send in
> this:
>
> > + retval = __find_secondary_sb(rsb, agsize, agsize);
> > + if (!retval) {
> > + /*
> > + * fallback: use minimum agsize for skipsize
> > + */
> > + retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES, BSIZE);
> > + }
>
> and the function is something like:
>
> static int
> __find_secondary_sb(
> xfs_sb_t *rsb,
> xfs_off_t start,
> xfs_off_t skip)
>
> {
>
> ...
>
> for (done = 0, off = start; !done ; off += skip) {
> ...
> if (lseek64(x.dfd, off, SEEK_SET) != off)
> done = 1;
>
> if (!done && (read(x.dfd, sb, BSIZE)) <= 0)
> done = 1;
But, bsize is used here:
...
* check the buffer 512 bytes at a time since
* we don't know how big the sectors really are.
*/
for (i = 0; !done && i < bsize; i += BBSIZE) {
...
so, don't we still need to populate bsize? Or does it make more
sense to just use BBSIZE in the conditional, ala:
for (i = 0; !done && i < BBSIZE; i += BBSIZE)
>
>
> because you really can't deduce both the starting point and the skip-ahead
> size from just one parameter.
Agreed.
Thanks for your thorough reviews :)
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] 4+ messages in thread
* Re: [PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method
2016-02-10 15:43 ` Bill O'Donnell
@ 2016-02-10 15:51 ` Eric Sandeen
0 siblings, 0 replies; 4+ messages in thread
From: Eric Sandeen @ 2016-02-10 15:51 UTC (permalink / raw)
To: Bill O'Donnell; +Cc: xfs
On 2/10/16 9:43 AM, Bill O'Donnell wrote:
>> I'd make __find_secondary_sb() take (sb, start, skip) i.e. send in
>> > this:
>> >
>>> > > + retval = __find_secondary_sb(rsb, agsize, agsize);
>>> > > + if (!retval) {
>>> > > + /*
>>> > > + * fallback: use minimum agsize for skipsize
>>> > > + */
>>> > > + retval = __find_secondary_sb(rsb, XFS_AG_MIN_BYTES, BSIZE);
>>> > > + }
>> >
>> > and the function is something like:
>> >
>> > static int
>> > __find_secondary_sb(
>> > xfs_sb_t *rsb,
>> > xfs_off_t start,
>> > xfs_off_t skip)
>> >
>> > {
>> >
>> > ...
>> >
>> > for (done = 0, off = start; !done ; off += skip) {
>> > ...
>> > if (lseek64(x.dfd, off, SEEK_SET) != off)
>> > done = 1;
>> >
>> > if (!done && (read(x.dfd, sb, BSIZE)) <= 0)
>> > done = 1;
> But, bsize is used here:
> ...
> * check the buffer 512 bytes at a time since
> * we don't know how big the sectors really are.
> */
> for (i = 0; !done && i < bsize; i += BBSIZE) {
> ...
> so, don't we still need to populate bsize? Or does it make more
> sense to just use BBSIZE in the conditional, ala:
> for (i = 0; !done && i < BBSIZE; i += BBSIZE)
Oh, right, sorry. yes, keep the assignment:
if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) {
That handles a short read at the end; we ask for BSIZE, actually
read bsize, and then we need to iterate over what actually got read
(bsize).
BSIZE, bsize ... clear as mud. :(
-Eric
>> >
>> >
>> > because you really can't deduce both the starting point and the skip-ahead
>> > size from just one parameter.
> Agreed.
> Thanks for your thorough reviews :)
> Bill
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-02-10 15:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-10 1:34 [[PATCH 2/2 v2] xfs_repair: new secondary superblock search method] xfs_repair: new secondary superblock search method Bill O'Donnell
2016-02-10 4:49 ` [PATCH " Eric Sandeen
2016-02-10 15:43 ` Bill O'Donnell
2016-02-10 15:51 ` Eric Sandeen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox