Upgrading to GitLab 12.0.2.

Commit bc67fb2f authored by Valentin Vidic's avatar Valentin Vidic

New upstream version 3.1.10

parent 8d3ce90d
*.swp
Makefile.in
aclocal.m4
autoconf
autoheader
autom4te.cache
automake
compile
configure
config.guess
config.log
config.sub
config.status
config.rpath
Makefile
depcomp
install-sh
libtoolize
ltmain.sh
libtool
make/stamp-h1
m4
make/clusterautoconfig.h*
missing
ylwrap
cscope.out
.gdb_history
*.pc
.deps
.libs
*.o
*.la
*.lo
gfs2/convert/gfs2_convert
gfs2/edit/gfs2_edit
gfs2/libgfs2/gfs2l
gfs2/libgfs2/parser.c
gfs2/libgfs2/parser.h
gfs2/libgfs2/lexer.c
gfs2/libgfs2/lexer.h
gfs2/fsck/fsck.gfs2
gfs2/glocktop/glocktop
gfs2/mkfs/mkfs.gfs2
gfs2/mkfs/gfs2_grow
gfs2/mkfs/gfs2_jadd
gfs2/tune/tunegfs2
test-driver
tests/check_meta
tests/check_rgrp
tests/nukerg
tests/testvol
tests/testsuite.log
tests/testsuite.dir
tests/testsuite.trs
tests/atconfig
tests/atlocal
tests/package.m4
tests/testsuite
ABOUT-NLS
po/Makevars.template
po/POTFILES
po/stamp-po
po/remove-potcdate.sed
po/Makefile.in.in
po/Rules-quot
po/boldquot.sed
po/insert-header.sin
po/quot.sed
po/remove-potcdate.sin
EXTRA_DIST = autogen.sh README.build
EXTRA_DIST = autogen.sh README
AUTOMAKE_OPTIONS = foreign
......
gfs2-utils
----------
This package contains the tools needed to create, check, manipulate and analyze
gfs2 filesystems, along with important scripts required to support gfs2
clusters.
Build instructions
------------------
The following development packages are required to build gfs2-utils:
o autoconf
o automake
o libtool
o GNU make
o ncurses
o gettext
o bison
o flex
o zlib
o libblkid
o libuuid
o check (optional, enables unit tests)
The kernel header include/linux/gfs2-ondisk.h and its dependencies are also
required.
To build gfs2-utils, run the following commands:
$ ./autogen.sh
$ ./configure
$ make
See ./configure --help for more build configuration options.
Test Suite
----------
To run the test suite, use:
$ make check
See doc/README.tests for more details regarding the test suite.
Installation
------------
gfs2-utils requires the following libraries:
o zlib
o ncurses
o libblkid
o libuuid
To install gfs2-utils, run:
# make install
Support scripts
---------------
The following scripts (located in gfs2/scripts) are used to complete
the userland portion of the gfs2 withdraw feature using uevents. They
will be installed by 'make install' to these directories by default:
82-gfs2-withdraw.rules in /usr/lib/udev/rules.d/
gfs2_withdraw_helper in /usr/sbin/
See also doc/README.contributing for details on submitting patches.
To build this source tree, you will need:
- automake
- GNU make
- GCC tool chain
Plus the following libraries:
ncurses (for gfs2_edit)
gettext
bison
flex
zlib
libblkid
check (optional, enables the test suite)
To build gfs2-utils, run the following commands:
./autogen.sh
./configure
make
To run the test suite:
make check
To install gfs2-utils, run:
make install
The following scripts (located in gfs2/scripts) are used to complete
the userland portion of the gfs2 withdraw feature using uevents. They
will be installed by 'make install' to these directories by default:
82-gfs2-withdraw.rules in /usr/lib/udev/rules.d/
gfs2_withdraw_helper in /usr/sbin/
See also doc/README.contributing for details on submitting patches and
doc/README.tests for more details regarding the test suite.
......@@ -92,6 +92,10 @@ AC_ARG_ENABLE([debug],
AC_ARG_ENABLE([gcov],
AC_HELP_STRING([--enable-gcov],[enable coverage instrumentation [default=no]]),
[], [enable_gcov="no"])
AC_ARG_ENABLE([gprof],
AC_HELP_STRING([--enable-gprof],[enable profiling instrumentation [default=no]]),
[], [enable_gprof="no"])
# We use the Check framework for unit tests
PKG_CHECK_MODULES([check], [check >= 0.9.8],
......@@ -101,6 +105,9 @@ AM_CONDITIONAL([HAVE_CHECK], [test "x$have_check" = "xyes"])
PKG_CHECK_MODULES([zlib],[zlib])
PKG_CHECK_MODULES([blkid],[blkid])
PKG_CHECK_MODULES([uuid],[uuid],
[have_uuid=yes],
[have_uuid=no])
# old versions of ncurses don't ship pkg-config files
PKG_CHECK_MODULES([ncurses],[ncurses],,
......@@ -122,7 +129,8 @@ AC_CHECK_HEADER([linux/fs.h], [], [AC_MSG_ERROR([Unable to find linux/fs.h])])
AC_CHECK_HEADER([linux/types.h], [], [AC_MSG_ERROR([Unable to find linux/types.h])])
AC_CHECK_HEADER([linux/limits.h], [], [AC_MSG_ERROR([Unable to find linux/limits.h])])
AC_CHECK_HEADER([linux/gfs2_ondisk.h], [], [AC_MSG_ERROR([Unable to find linux/gfs2_ondisk.h])])
AC_CHECK_MEMBER([struct gfs2_sb.sb_uuid], [], [], [[#include <linux/gfs2_ondisk.h>]])
AC_CHECK_MEMBER([struct gfs2_sb.sb_uuid], [sb_has_uuid=yes], [sb_has_uuid=no],
[[#include <linux/gfs2_ondisk.h>]])
AC_CHECK_MEMBER([struct gfs2_leaf.lf_inode],[AC_DEFINE([GFS2_HAS_LEAF_HINTS],[],[Leaf block hints])],
[], [[#include <linux/gfs2_ondisk.h>]])
AC_CHECK_MEMBER([struct gfs2_dirent.de_rahead],[AC_DEFINE([GFS2_HAS_DE_RAHEAD],[],[Dirent readahead field])],
......@@ -130,6 +138,11 @@ AC_CHECK_MEMBER([struct gfs2_dirent.de_rahead],[AC_DEFINE([GFS2_HAS_DE_RAHEAD],[
AC_CHECK_MEMBER([struct gfs2_dirent.de_cookie],[AC_DEFINE([GFS2_HAS_DE_COOKIE],[],[Dirent cookie field])],
[], [[#include <linux/gfs2_ondisk.h>]])
# libuuid is only required if struct gfs2_sb.sb_uuid exists
if test "$sb_has_uuid" = "yes" -a "$have_uuid" = "no"; then
AC_MSG_ERROR([libuuid is required for this version of gfs2])
fi
# *FLAGS handling
ENV_CFLAGS="$CFLAGS"
ENV_CPPFLAGS="$CPPFLAGS"
......@@ -139,8 +152,10 @@ ENV_LDFLAGS="$LDFLAGS"
if test "x${enable_debug}" = xyes; then
AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
OPT_CFLAGS="-O0"
OPT_CPPFLAGS=""
else
OPT_CFLAGS="-O2"
OPT_CPPFLAGS="-D_FORTIFY_SOURCE=2"
fi
# gdb flags
......@@ -162,6 +177,14 @@ if test "x${enable_gcov}" = xyes; then
OPT_CFLAGS="-O0 $GCOV_CFLAGS"
fi
if test "x${enable_gprof}" = xyes; then
GPROF_CFLAGS="-pg"
if ! cc_supports_flag $GPROF_CFLAGS; then
AC_MSG_ERROR([your compiler does not support gprof instrumentation])
fi
OPT_CFLAGS="$OPT_CFLAGS $GPROF_CFLAGS"
fi
# extra warnings
EXTRA_WARNINGS=""
......@@ -191,7 +214,7 @@ for j in $WARNLIST; do
done
CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS $EXTRA_WARNINGS $WERROR_CFLAGS"
CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS"
CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS $OPT_CPPFLAGS"
LDFLAGS="$ENV_LDFLAGS"
AC_CONFIG_TESTDIR([tests], [gfs2/libgfs2:gfs2/mkfs:gfs2/fsck:gfs2/edit:gfs2/convert:gfs2/tune:tests])
......@@ -226,6 +249,7 @@ echo " udevdir : $udevdir"
echo " ------------------"
echo " debug build : $enable_debug"
echo " C unit tests : $have_check"
echo " gprof build : $enable_gprof"
echo " gcov build : $enable_gcov"
echo
echo "Now run 'make' to build and 'make check' to run tests"
......@@ -6,9 +6,9 @@ Here are some brief guidelines to follow when contributing to gfs2-utils.
Translations
------------
We use the Transifex translation service:
We use the Zanata translation service:
https://transifex.com/projects/p/gfs2-utils/
https://fedora.zanata.org/project/view/gfs2-utils
See the documentation there for submitting translations.
......@@ -25,7 +25,7 @@ We use git for managing our source code and we assume here that you're familiar
with git. Patches should apply cleanly to the latest master branch of
gfs2-utils.git
http://git.fedorahosted.org/cgit/gfs2-utils.git
https://pagure.io/gfs2-utils
For ease of review and maintenance each of your patches should address a single
issue and if there are multiple issues please consider spreading your work over
......
......@@ -8,3 +8,4 @@ gfs2_convert_CPPFLAGS = \
-I$(top_srcdir)/gfs2/libgfs2
gfs2_convert_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la
gfs2_convert_LDFLAGS = $(uuid_LIBS)
......@@ -1070,11 +1070,11 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
bh = bread(sbp, block);
if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) {/* if it is an dinode */
/* Skip the rindex and jindex inodes for now. */
if (block != rindex_addr && block != jindex_addr)
if (block != rindex_addr && block != jindex_addr) {
error = adjust_inode(sbp, bh);
if (error) {
if (error)
return error;
}
}
} else { /* It's metadata, but not an inode, so fix the bitmap. */
int blk, buf_offset;
int bitmap_byte; /* byte within the bitmap to fix */
......
......@@ -22,10 +22,12 @@ gfs2_edit_CPPFLAGS = \
gfs2_edit_CFLAGS = \
$(ncurses_CFLAGS) \
$(zlib_CFLAGS)
$(zlib_CFLAGS) \
$(uuid_CFLAGS)
gfs2_edit_LDFLAGS = \
$(ncurses_LIBS) \
$(zlib_LIBS)
$(zlib_LIBS) \
$(uuid_LIBS)
gfs2_edit_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la
......@@ -20,6 +20,9 @@
#include "extended.h"
#include "gfs2hex.h"
#include "libgfs2.h"
#ifdef GFS2_HAS_UUID
#include <uuid.h>
#endif
#define pv(struct, member, fmt, fmt2) do { \
print_it(" "#member, fmt, fmt2, struct->member); \
......@@ -415,7 +418,12 @@ static void gfs2_sb_print2(struct gfs2_sb *sbp2)
gfs2_inum_print2("license ", &gfs1_license_di);
}
#ifdef GFS2_HAS_UUID
print_it(" sb_uuid", "%s", NULL, str_uuid(sbp2->sb_uuid));
{
char readable_uuid[36+1];
uuid_unparse(sbp2->sb_uuid, readable_uuid);
print_it(" sb_uuid", "%s", NULL, readable_uuid);
}
#endif
}
......
......@@ -2158,7 +2158,7 @@ static void usage(void)
fprintf(stderr,"If only the device is specified, it enters into hexedit mode.\n");
fprintf(stderr,"identify - prints out only the block type, not the details.\n");
fprintf(stderr,"printsavedmeta - prints out the saved metadata blocks from a savemeta file.\n");
fprintf(stderr,"savemeta <file_system> <file> - save off your metadata for analysis and debugging.\n");
fprintf(stderr,"savemeta <file_system> <file.gz> - save off your metadata for analysis and debugging.\n");
fprintf(stderr," (The intelligent way: assume bitmap is correct).\n");
fprintf(stderr,"savemetaslow - save off your metadata for analysis and debugging. The SLOW way (block by block).\n");
fprintf(stderr,"savergs - save off only the resource group information (rindex and rgs).\n");
......@@ -2167,6 +2167,7 @@ static void usage(void)
fprintf(stderr,"rgflags rgnum [new flags] - print or modify flags for rg #rgnum (0 - X)\n");
fprintf(stderr,"rgbitmaps <rgnum> - print out the bitmaps for rgrp "
"rgnum.\n");
fprintf(stderr,"rgrepair - find and repair damaged rgrp.\n");
fprintf(stderr,"-V prints version number.\n");
fprintf(stderr,"-c 1 selects alternate color scheme 1\n");
fprintf(stderr,"-d prints details (for printing journals)\n");
......@@ -2226,8 +2227,8 @@ static void usage(void)
fprintf(stderr," gfs2_edit -p quota find di /dev/x/y\n");
fprintf(stderr," To set the Resource Group flags for rg #7 to 3.\n");
fprintf(stderr," gfs2_edit rgflags 7 3 /dev/sdc2\n");
fprintf(stderr," To save off all metadata for /dev/vg/lv without compression:\n");
fprintf(stderr," gfs2_edit savemeta -z 0 /dev/vg/lv /tmp/metasave\n");
fprintf(stderr," To save off all metadata for /dev/vg/lv:\n");
fprintf(stderr," gfs2_edit savemeta /dev/vg/lv /tmp/metasave.gz\n");
}/* usage */
/**
......@@ -2259,6 +2260,135 @@ static void getgziplevel(char *argv[], int *i)
(*i)++;
}
static int count_dinode_blks(struct rgrp_tree *rgd, int bitmap,
struct gfs2_buffer_head *rbh)
{
struct gfs2_buffer_head *tbh;
uint64_t b;
int dinodes = 0;
char *byte, cur_state, new_state;
int bit, off;
if (bitmap)
off = sizeof(struct gfs2_meta_header);
else
off = sizeof(struct gfs2_rgrp);
for (b = 0; b < rgd->bits[bitmap].bi_len << GFS2_BIT_SIZE; b++) {
tbh = bread(&sbd, rgd->ri.ri_data0 +
rgd->bits[bitmap].bi_start + b);
byte = rbh->b_data + off + (b / GFS2_NBBY);
bit = (b % GFS2_NBBY) * GFS2_BIT_SIZE;
if (gfs2_check_meta(tbh, GFS2_METATYPE_DI) == 0) {
dinodes++;
new_state = GFS2_BLKST_DINODE;
} else {
new_state = GFS2_BLKST_USED;
}
cur_state = (*byte >> bit) & GFS2_BIT_MASK;
*byte ^= cur_state << bit;
*byte |= new_state << bit;
brelse(tbh);
}
bmodified(rbh);
return dinodes;
}
static int count_dinode_bits(struct gfs2_buffer_head *rbh)
{
uint64_t blk;
struct gfs2_meta_header *mh = (struct gfs2_meta_header *)rbh->b_data;
char *byte;
int bit;
int dinodes = 0;
if (be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG)
blk = sizeof(struct gfs2_rgrp);
else
blk = sizeof(struct gfs2_meta_header);
for (; blk < sbd.bsize; blk++) {
byte = rbh->b_data + (blk / GFS2_NBBY);
bit = (blk % GFS2_NBBY) * GFS2_BIT_SIZE;
if (((*byte >> bit) & GFS2_BIT_MASK) == GFS2_BLKST_DINODE)
dinodes++;
}
return dinodes;
}
static void rg_repair(void)
{
struct gfs2_buffer_head *rbh;
struct rgrp_tree *rgd;
struct osi_node *n;
int b;
int rgs_fixed = 0;
int dinodes_found = 0, dinodes_total = 0;
/* Walk through the resource groups saving everything within */
for (n = osi_first(&sbd.rgtree); n; n = osi_next(n)) {
rgd = (struct rgrp_tree *)n;
if (gfs2_rgrp_read(&sbd, rgd) == 0) { /* was read in okay */
gfs2_rgrp_relse(rgd);
continue; /* ignore it */
}
/* If we get here, it's because we have an rgrp in the rindex
file that can't be read in. So attempt to repair it.
If we find a damaged rgrp or bitmap, fix the metadata.
Then scan all its blocks: if we find a dinode, set the
repaired bitmap to GFS2_BLKST_DINODE. Set all others to
GFS2_BLKST_USED so fsck can sort it out. If we set them
to FREE, fsck would just nuke it all. */
printf("Resource group at block %llu (0x%llx) appears to be "
"damaged. Attempting to fix it (in reverse order).\n",
(unsigned long long)rgd->ri.ri_addr,
(unsigned long long)rgd->ri.ri_addr);
for (b = rgd->ri.ri_length - 1; b >= 0; b--) {
int mtype = (b ? GFS2_METATYPE_RB : GFS2_METATYPE_RG);
struct gfs2_meta_header *mh;
printf("Bitmap #%d:", b);
rbh = bread(&sbd, rgd->ri.ri_addr + b);
if (gfs2_check_meta(rbh, mtype)) { /* wrong type */
printf("Damaged. Repairing...");
/* Fix the meta header */
memset(rbh->b_data, 0, sbd.bsize);
mh = (struct gfs2_meta_header *)rbh->b_data;
mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
mh->mh_type = cpu_to_be32(mtype);
if (b)
mh->mh_format =
cpu_to_be32(GFS2_FORMAT_RB);
else
mh->mh_format =
cpu_to_be32(GFS2_FORMAT_RG);
bmodified(rbh);
/* Count the dinode blocks */
dinodes_found = count_dinode_blks(rgd, b, rbh);
} else { /* bitmap info is okay: tally it. */
printf("Undamaged. Analyzing...");
dinodes_found = count_dinode_bits(rbh);
}
printf("Dinodes found: %d\n", dinodes_found);
dinodes_total += dinodes_found;
if (b == 0) { /* rgrp itself was damaged */
rgd->rg.rg_dinodes = dinodes_total;
rgd->rg.rg_free = 0;
}
brelse(rbh);
}
rgs_fixed++;
}
if (rgs_fixed)
printf("%d resource groups fixed.\n"
"You should run fsck.gfs2 to reconcile the bitmaps.\n",
rgs_fixed);
else
printf("All resource groups are okay. No repairs needed.\n");
exit(0);
}
/* ------------------------------------------------------------------------ */
/* parameterpass1 - pre-processing for command-line parameters */
/* ------------------------------------------------------------------------ */
......@@ -2307,6 +2437,8 @@ static void parameterpass1(int argc, char *argv[], int i)
termlines = 0;
else if (!strcmp(argv[i], "rgflags"))
termlines = 0;
else if (!strcmp(argv[i], "rgrepair"))
termlines = 0;
else if (!strcmp(argv[i], "rg"))
termlines = 0;
else if (!strcasecmp(argv[i], "-x"))
......@@ -2483,6 +2615,8 @@ static void process_parameters(int argc, char *argv[], int pass)
for (bmap = 0; bmap < rgd->ri.ri_length; bmap++)
push_block(rgblk + bmap);
}
else if (!strcmp(argv[i], "rgrepair"))
rg_repair();
else if (!strcasecmp(argv[i], "savemeta")) {
getgziplevel(argv, &i);
savemeta(argv[i+2], 0, gziplevel);
......
This diff is collapsed.
......@@ -35,4 +35,7 @@ fsck_gfs2_CPPFLAGS = \
-I$(top_srcdir)/gfs2/include \
-I$(top_srcdir)/gfs2/libgfs2
fsck_gfs2_LDADD = $(top_builddir)/gfs2/libgfs2/libgfs2.la
fsck_gfs2_LDADD = \
$(top_builddir)/gfs2/libgfs2/libgfs2.la
fsck_gfs2_LDFLAGS = \
$(uuid_LIBS)
......@@ -79,7 +79,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
void *private)
{
int q;
int removed_lastmeta;
int removed_lastmeta = 0;
if (!valid_block_ip(ip, block))
return meta_error;
......
......@@ -106,6 +106,12 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
must have been converted from gfs2_convert. */
};
struct error_block {
uint64_t metablk; /* metadata block where error was found */
int metaoff; /* offset in that metadata block where error found */
uint64_t errblk; /* error block */
};
extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block);
extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
struct rgrp_tree *rgd,
......
......@@ -88,33 +88,33 @@ int incr_link_count(struct gfs2_inum no, struct gfs2_inode *ip,
di = dirtree_find(no.no_addr);
if (di) {
if (di->dinode.no_formal_ino != no.no_formal_ino)
return 1;
return incr_link_ino_mismatch;
di->counted_links++;
whyincr(no.no_addr, why, referenced_from, di->counted_links);
return 0;
return incr_link_good;
}
ii = inodetree_find(no.no_addr);
/* If the list has entries, look for one that matches inode_no */
if (ii) {
if (ii->di_num.no_formal_ino != no.no_formal_ino)
return 1;
return incr_link_ino_mismatch;
ii->counted_links++;
whyincr(no.no_addr, why, referenced_from, ii->counted_links);
return 0;
return incr_link_good;
}
if (link1_type(&clink1map, no.no_addr) != 1) {
link1_set(&clink1map, no.no_addr, 1);
whyincr(no.no_addr, why, referenced_from, 1);
return 0;
return incr_link_good;
}
link_ip = fsck_load_inode(ip->i_sbd, no.no_addr);
/* Check formal ino against dinode before adding to inode tree. */
if (no.no_formal_ino != ip->i_di.di_num.no_formal_ino) {
if (no.no_formal_ino != link_ip->i_di.di_num.no_formal_ino) {
fsck_inode_put(&link_ip);
return 1;
return incr_link_ino_mismatch; /* inode mismatch */
}
/* Move it from the link1 maps to a real inode tree entry */
link1_set(&nlink1map, no.no_addr, 0);
......@@ -130,7 +130,7 @@ int incr_link_count(struct gfs2_inum no, struct gfs2_inode *ip,
(unsigned long long)referenced_from,
(unsigned long long)no.no_addr);
fsck_inode_put(&link_ip);
return -1;
return incr_link_bad;
}
ii->di_num = link_ip->i_di.di_num;
fsck_inode_put(&link_ip);
......@@ -138,7 +138,11 @@ int incr_link_count(struct gfs2_inum no, struct gfs2_inode *ip,
nlink1map */
ii->counted_links = 2;
whyincr(no.no_addr, why, referenced_from, ii->counted_links);
return 0;
/* We transitioned a dentry link count from 1 to 2, and we know it's
not a directory. But the new reference has the correct formal
inode number, so the first reference is suspect: we need to
check it in case it's a bad reference, and not just a hard link. */
return incr_link_check_orig;
}
#define whydecr(no_addr, why, referenced_from, counted_links) \
......
......@@ -4,6 +4,13 @@
extern struct gfs2_bmap nlink1map; /* map of dinodes with nlink == 1 */
extern struct gfs2_bmap clink1map; /* map of dinodes w/counted links == 1 */
enum {
incr_link_bad = -1,
incr_link_good = 0,
incr_link_ino_mismatch = 1,
incr_link_check_orig = 2,
};
int link1_set(struct gfs2_bmap *bmap, uint64_t bblock, int mark);
int set_di_nlink(struct gfs2_inode *ip);
int incr_link_count(struct gfs2_inum no, struct gfs2_inode *ip,
......
......@@ -170,9 +170,12 @@ static int check_statfs(struct gfs2_sbd *sdp)
/* Read the current statfs values */
count = gfs2_readi(sdp->md.statfs, buf, 0,
sdp->md.statfs->i_di.di_size);
if (count == sizeof(struct gfs2_statfs_change))
gfs2_statfs_change_in(&sc, buf);
if (count != sizeof(struct gfs2_statfs_change)) {
log_err(_("Failed to read statfs values (%d of %"PRIu64" read)\n"),
count, (uint64_t)sdp->md.statfs->i_di.di_size);
return FSCK_ERROR;
}
gfs2_statfs_change_in(&sc, buf);
/* Calculate the real values from the rgrp information */
sdp->blks_total = 0;
sdp->blks_alloced = 0;
......
......@@ -40,9 +40,14 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
{"free", "data", "unlinked", "inode", "reserved"},
/* gfs1 descriptions: */
{"free", "data", "free meta", "metadata", "reserved"}};
static struct rgrp_tree *prevrgd = NULL;
if (rgd == NULL || !rgrp_contains_block(rgd, blk))
if (prevrgd && rgrp_contains_block(prevrgd, blk)) {
rgd = prevrgd;
} else if (rgd == NULL || !rgrp_contains_block(rgd, blk)) {
rgd = gfs2_blk2rgrpd(sdp, blk);
prevrgd = rgd;
}
gfs1rg = (struct gfs_rgrp *)&rgd->rg;
......@@ -1387,7 +1392,7 @@ error_undo: /* undo what we've done so far for this block */
*/
static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
struct gfs2_buffer_head *bh, int head_size,
uint64_t *blks_checked, uint64_t *error_blk)
uint64_t *blks_checked, struct error_block *error_blk)
{
int error = 0, rc = 0;
uint64_t block, *ptr;
......@@ -1418,21 +1423,36 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
log_info("\n");
if (rc < 0) {
/* A fatal error trumps a non-fatal one. */
if ((*error_blk == 0) || (rc < error)) {
log_debug(_("Fatal error on block 0x"
"%llx preempts non-fatal "
"error on block 0x%llx\n"),
if ((error_blk->errblk == 0) ||
(rc < error)) {
log_debug(_("Fatal error on metadata "
"block 0x%llx, offset "
"0x%x, referencing block "
"0x%llx preempts non-fatal"
" error on block 0x%llx\n"),
(unsigned long long)metablock,
(int)(ptr - ptr_start),
(unsigned long long)block,
(unsigned long long)*error_blk);
*error_blk = block;
(unsigned long long)error_blk->errblk);
error_blk->metablk = metablock;
error_blk->metaoff = ptr - ptr_start;
error_blk->errblk = block;
}
log_info(_("Unrecoverable "));
} else { /* nonfatal error */
if ((*error_blk) == 0)
*error_blk = block;
if (error_blk->errblk == 0) {
error_blk->metablk = metablock;
error_blk->metaoff = ptr - ptr_start;
error_blk->errblk = block;
}
}
log_info(_("data block error %d on block %llu "
"(0x%llx).\n"), rc,
log_info(_("data block error %d on metadata block "
"%lld (0x%llx), offset %d (0x%x), "
"referencing data block %lld (0x%llx).\n"),
rc, (unsigned long long)metablock,
(unsigned long long)metablock,
(int)(ptr - ptr_start),
(int)(ptr - ptr_start),
(unsigned long long)block,
(unsigned long long)block);
error = rc;
......@@ -1445,8 +1465,9 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
}
static int undo_check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
uint64_t metablock,
uint64_t *ptr_start, char *ptr_end,
uint64_t error_blk, int error)
struct error_block *error_blk, int error)
{
int rc = 0;
uint64_t block, *ptr;
......@@ -1460,19 +1481,27 @@ static int undo_check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
if (skip_this_pass || fsck_abort)