From: Nathan Scott Date: Thu, 6 Mar 2003 06:59:34 +0000 (+0000) Subject: New xfsprogs version - enabled unwritten extents by default, new commands X-Git-Tag: v2.4.0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ca431fc5583dbc163599df37148c8de29c27109;p=thirdparty%2Fxfsprogs-dev.git New xfsprogs version - enabled unwritten extents by default, new commands in xfs_db and xfs_admin to manipulate the version extflg bit on unmounted filesystems, make xfs_db check for a dirty log before zeroing it in the uuid command, man page updates, sync'd up user/kernel code and headers. Add stripe information into xfs_bmap output. --- diff --git a/VERSION b/VERSION index c5a5def83..1b1fceb13 100644 --- a/VERSION +++ b/VERSION @@ -2,6 +2,6 @@ # This file is used by configure to get version information # PKG_MAJOR=2 -PKG_MINOR=3 -PKG_REVISION=11 +PKG_MINOR=4 +PKG_REVISION=0 PKG_BUILD=0 diff --git a/bmap/xfs_bmap.c b/bmap/xfs_bmap.c index 5db0fd410..a24dfb8f2 100644 --- a/bmap/xfs_bmap.c +++ b/bmap/xfs_bmap.c @@ -134,6 +134,7 @@ dofile(char *fname) int map_size; int loop = 0; xfs_fsop_geom_v1_t fsgeo; + int flg = 0; fd = open(fname, O_RDONLY); if (fd < 0) { @@ -326,15 +327,23 @@ dofile(char *fname) #define MINAG_WIDTH 2 #define MINTOT_WIDTH 5 #define max(a,b) (a > b ? a : b) - int agno; - off64_t agoff, bbperag; - int foff_w, boff_w, aoff_w, tot_w, agno_w; - char rbuf[32], bbuf[32], abuf[32]; +#define FLG_NULL 00000 /* Null flag */ +#define FLG_BSU 01000 /* Not on begin of stripe unit */ +#define FLG_ESU 00100 /* Not on end of stripe unit */ +#define FLG_BSW 00010 /* Not on begin of stripe width */ +#define FLG_ESW 00001 /* Not on end of stripe width */ + int agno; + off64_t agoff, bbperag; + int foff_w, boff_w, aoff_w, tot_w, agno_w; + char rbuf[32], bbuf[32], abuf[32]; + int sunit, swidth; foff_w = boff_w = aoff_w = MINRANGE_WIDTH; tot_w = MINTOT_WIDTH; bbperag = (off64_t)fsgeo.agblocks * (off64_t)fsgeo.blocksize / BBSIZE; + sunit = fsgeo.sunit; + swidth = fsgeo.swidth; /* * Go through the extents and figure out the width @@ -375,6 +384,23 @@ dofile(char *fname) aoff_w, _("AG-OFFSET"), tot_w, _("TOTAL")); for (i = 0; i < map->bmv_entries; i++) { + if (sunit) { + flg = FLG_NULL; + if (map[i + 1].bmv_block % sunit != 0) { + flg |= FLG_BSU; + } + if (((map[i + 1].bmv_block + + map[i + 1].bmv_length ) % sunit ) != 0) { + flg |= FLG_ESU; + } + if (map[i + 1].bmv_block % swidth != 0) { + flg |= FLG_BSW; + } + if (((map[i + 1].bmv_block + + map[i + 1].bmv_length ) % swidth ) != 0) { + flg |= FLG_ESW; + } + } snprintf(rbuf, sizeof(rbuf), "[%lld..%lld]:", (long long) map[i + 1].bmv_offset, (long long)(map[i + 1].bmv_offset + @@ -404,8 +430,24 @@ dofile(char *fname) agno_w, agno, aoff_w, abuf, tot_w, (long long)map[i+1].bmv_length); + if (flg == FLG_NULL) { + printf("\n"); + } else { + printf(" %-4.4o\n", flg); + } } } + if ( flg ) { + printf(_(" FLG Values:\n")); + printf(_(" %5.5o Doesn't begin on stripe unit\n"), + FLG_BSU); + printf(_(" %5.5o Doesn't end on stripe unit\n"), + FLG_ESU); + printf(_(" %5.5o Doesn't begin on stripe width\n"), + FLG_BSW); + printf(_(" %5.5o Doesn't end on stripe width\n"), + FLG_ESW); + } } free(map); return 0; diff --git a/db/agf.c b/db/agf.c index 23dcbaaed..52c6425a8 100644 --- a/db/agf.c +++ b/db/agf.c @@ -41,7 +41,7 @@ #include "io.h" #include "bit.h" #include "output.h" -#include "mount.h" +#include "init.h" static int agf_f(int argc, char **argv); static void agf_help(void); diff --git a/db/agfl.c b/db/agfl.c index 9b3bdabea..d2b943d12 100644 --- a/db/agfl.c +++ b/db/agfl.c @@ -41,7 +41,7 @@ #include "io.h" #include "bit.h" #include "output.h" -#include "mount.h" +#include "init.h" static int agfl_bno_size(void *obj, int startoff); static int agfl_f(int argc, char **argv); diff --git a/db/agi.c b/db/agi.c index 4f95fa34f..8da7cdb20 100644 --- a/db/agi.c +++ b/db/agi.c @@ -41,7 +41,7 @@ #include "io.h" #include "bit.h" #include "output.h" -#include "mount.h" +#include "init.h" static int agi_f(int argc, char **argv); static void agi_help(void); diff --git a/db/attr.c b/db/attr.c index 7432ca0cc..4c89fd68b 100644 --- a/db/attr.c +++ b/db/attr.c @@ -39,7 +39,7 @@ #include "attr.h" #include "io.h" #include "data.h" -#include "mount.h" +#include "init.h" static int attr_leaf_entries_count(void *obj, int startoff); static int attr_leaf_hdr_count(void *obj, int startoff); diff --git a/db/block.c b/db/block.c index 8a0f1c2a4..d240d59e7 100644 --- a/db/block.c +++ b/db/block.c @@ -42,7 +42,7 @@ #include "inode.h" #include "io.h" #include "output.h" -#include "mount.h" +#include "init.h" static int ablock_f(int argc, char **argv); static void ablock_help(void); diff --git a/db/bmap.c b/db/bmap.c index 7a3362f4f..5ec218df8 100644 --- a/db/bmap.c +++ b/db/bmap.c @@ -38,7 +38,7 @@ #include "io.h" #include "inode.h" #include "output.h" -#include "mount.h" +#include "init.h" static int bmap_f(int argc, char **argv); static int bmap_one_extent(xfs_bmbt_rec_64_t *ep, diff --git a/db/bmapbt.c b/db/bmapbt.c index 1c45c7ccc..2e8cefe10 100644 --- a/db/bmapbt.c +++ b/db/bmapbt.c @@ -39,7 +39,7 @@ #include "bmapbt.h" #include "print.h" #include "bit.h" -#include "mount.h" +#include "init.h" static int bmapbta_key_count(void *obj, int startoff); static int bmapbta_key_offset(void *obj, int startoff, int idx); diff --git a/db/bmroot.c b/db/bmroot.c index ae73764a0..2981fe1d6 100644 --- a/db/bmroot.c +++ b/db/bmroot.c @@ -40,7 +40,7 @@ #include "io.h" #include "print.h" #include "bit.h" -#include "mount.h" +#include "init.h" static int bmroota_key_count(void *obj, int startoff); static int bmroota_key_offset(void *obj, int startoff, int idx); diff --git a/db/bnobt.c b/db/bnobt.c index 6fbc2bf5c..b8d1aa99a 100644 --- a/db/bnobt.c +++ b/db/bnobt.c @@ -40,7 +40,7 @@ #include "io.h" #include "print.h" #include "bit.h" -#include "mount.h" +#include "init.h" static int bnobt_key_count(void *obj, int startoff); static int bnobt_key_offset(void *obj, int startoff, int idx); diff --git a/db/check.c b/db/check.c index daa0acde1..dcd83dad8 100644 --- a/db/check.c +++ b/db/check.c @@ -40,7 +40,7 @@ #include "io.h" #include "output.h" #include "type.h" -#include "mount.h" +#include "init.h" #include "malloc.h" typedef enum { diff --git a/db/cntbt.c b/db/cntbt.c index af774fcfb..f00089723 100644 --- a/db/cntbt.c +++ b/db/cntbt.c @@ -39,7 +39,7 @@ #include "cntbt.h" #include "print.h" #include "bit.h" -#include "mount.h" +#include "init.h" static int cntbt_key_count(void *obj, int startoff); static int cntbt_key_offset(void *obj, int startoff, int idx); diff --git a/db/command.c b/db/command.c index 044d097a8..28486396c 100644 --- a/db/command.c +++ b/db/command.c @@ -57,7 +57,6 @@ #include "print.h" #include "quit.h" #include "sb.h" -#include "uuid.h" #include "write.h" #include "malloc.h" #include "dquot.h" @@ -150,7 +149,6 @@ init_commands(void) print_init(); quit_init(); sb_init(); - uuid_init(); type_init(); write_init(); dquot_init(); diff --git a/db/convert.c b/db/convert.c index a9fe2b2a5..9208d6c37 100644 --- a/db/convert.c +++ b/db/convert.c @@ -35,7 +35,7 @@ #include "data.h" #include "convert.h" #include "output.h" -#include "mount.h" +#include "init.h" #define M(A) (1 << CT_ ## A) #define agblock_to_bytes(x) \ diff --git a/db/data.c b/db/data.c deleted file mode 100644 index 71ef9b680..000000000 --- a/db/data.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#include -#include "data.h" - -int blkbb; -xfs_agnumber_t cur_agno = NULLAGNUMBER; -int exitcode; -int flag_expert_mode = 0; -int flag_readonly = 0; -libxfs_init_t xfsargs; diff --git a/db/data.h b/db/data.h deleted file mode 100644 index 3c2ae89fb..000000000 --- a/db/data.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -extern int blkbb; -extern xfs_agnumber_t cur_agno; -extern int exitcode; -extern int flag_expert_mode; -extern int flag_readonly; -extern int flag_arch; -extern libxfs_init_t xfsargs; diff --git a/db/dbread.c b/db/dbread.c index 0dc6588d2..819b4bc2f 100644 --- a/db/dbread.c +++ b/db/dbread.c @@ -35,7 +35,7 @@ #include "data.h" #include "dbread.h" #include "io.h" -#include "mount.h" +#include "init.h" int dbread(void *buf, int nblocks, xfs_fileoff_t bno, int whichfork) diff --git a/db/dir.c b/db/dir.c index 8e51f050e..8a573f280 100644 --- a/db/dir.c +++ b/db/dir.c @@ -39,7 +39,7 @@ #include "dir.h" #include "io.h" #include "data.h" -#include "mount.h" +#include "init.h" static int dir_leaf_entries_count(void *obj, int startoff); static int dir_leaf_hdr_count(void *obj, int startoff); diff --git a/db/dir2.c b/db/dir2.c index c95d167bf..5531e82a7 100644 --- a/db/dir2.c +++ b/db/dir2.c @@ -38,7 +38,7 @@ #include "field.h" #include "dir.h" #include "dir2.h" -#include "mount.h" +#include "init.h" #include "data.h" static int dir2_block_hdr_count(void *obj, int startoff); diff --git a/db/dquot.c b/db/dquot.c index c58d2d546..bbd38b8c5 100644 --- a/db/dquot.c +++ b/db/dquot.c @@ -42,7 +42,7 @@ #include "field.h" #include "inode.h" #include "io.h" -#include "mount.h" +#include "init.h" #include "output.h" static int dquot_f(int argc, char **argv); diff --git a/db/faddr.c b/db/faddr.c index 8b87723f9..bf9dbf78c 100644 --- a/db/faddr.c +++ b/db/faddr.c @@ -39,7 +39,7 @@ #include "bit.h" #include "bmap.h" #include "output.h" -#include "mount.h" +#include "init.h" void fa_agblock( diff --git a/db/frag.c b/db/frag.c index 4f2eddfcc..5ec6e50ee 100644 --- a/db/frag.c +++ b/db/frag.c @@ -39,7 +39,7 @@ #include "io.h" #include "output.h" #include "type.h" -#include "mount.h" +#include "init.h" #include "malloc.h" typedef struct extent { diff --git a/db/freesp.c b/db/freesp.c index 3964fc9b6..86762aec9 100644 --- a/db/freesp.c +++ b/db/freesp.c @@ -37,7 +37,7 @@ #include "io.h" #include "type.h" #include "output.h" -#include "mount.h" +#include "init.h" #include "malloc.h" typedef struct histent diff --git a/db/init.c b/db/init.c index d12e76e32..eb8ea13c2 100644 --- a/db/init.c +++ b/db/init.c @@ -37,28 +37,39 @@ #include "init.h" #include "input.h" #include "io.h" -#include "mount.h" +#include "init.h" #include "sig.h" #include "output.h" #include "malloc.h" -char *fsdevice; -char **cmdline; -int ncmdline; +static char **cmdline; +static int ncmdline; +char *fsdevice; +int blkbb; +int exitcode; +int expert_mode; +xfs_mount_t xmount; +xfs_mount_t *mp; +libxfs_init_t x; +xfs_agnumber_t cur_agno = NULLAGNUMBER; static void usage(void) { - dbprintf("Usage: %s [-c cmd]... [-p prog] [-l logdev] [-frxV] devname\n", progname); + fprintf(stderr, _( + "Usage: %s [-frxV] [-p prog] [-l logdev] [-c cmd]... device\n"), + progname); exit(1); } void init( - int argc, - char **argv) + int argc, + char **argv) { - int c; + xfs_sb_t *sbp; + void *bufp = NULL; + int c; progname = basename(argv[0]); while ((c = getopt(argc, argv, "c:fip:rxVl:")) != EOF) { @@ -68,25 +79,22 @@ init( cmdline[ncmdline++] = optarg; break; case 'f': - xfsargs.disfile = 1; + x.disfile = 1; break; case 'i': - xfsargs.isreadonly = - (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE); - flag_readonly = 1; + x.isreadonly = (LIBXFS_ISREADONLY|LIBXFS_ISINACTIVE); break; case 'p': progname = optarg; break; case 'r': - xfsargs.isreadonly = LIBXFS_ISREADONLY; - flag_readonly = 1; + x.isreadonly = LIBXFS_ISREADONLY; break; case 'l': - xfsargs.logname = optarg; + x.logname = optarg; break; case 'x': - flag_expert_mode = 1; + expert_mode = 1; break; case 'V': printf("%s version %s\n", progname, VERSION); @@ -100,26 +108,76 @@ init( usage(); /*NOTREACHED*/ } + fsdevice = argv[optind]; - if (!xfsargs.disfile) - xfsargs.volname = fsdevice; + if (!x.disfile) + x.volname = fsdevice; else - xfsargs.dname = fsdevice; - xfsargs.notvolok = 1; - if (!libxfs_init(&xfsargs)) { - fputs("\nfatal error -- couldn't initialize XFS library\n", + x.dname = fsdevice; + x.notvolok = 1; + + if (!libxfs_init(&x)) { + fputs(_("\nfatal error -- couldn't initialize XFS library\n"), stderr); exit(1); } - mp = dbmount(); - if (mp == NULL) { - dbprintf("%s: %s is not a valid filesystem\n", + + if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) { + dbprintf(_("%s: %s is invalid (cannot read first 512 bytes)\n"), progname, fsdevice); exit(1); - /*NOTREACHED*/ } + + /* copy SB from buffer to in-core, converting architecture as we go */ + libxfs_xlate_sb(bufp, &xmount.m_sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS); + xfree(bufp); + + sbp = &xmount.m_sb; + if (sbp->sb_magicnum != XFS_SB_MAGIC) { + dbprintf(_("%s: unexpected XFS SB magic number 0x%08x\n"), + progname, sbp->sb_magicnum); + } + + mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, + LIBXFS_MOUNT_ROOTINOS | LIBXFS_MOUNT_DEBUGGER); + blkbb = 1 << mp->m_blkbb_log; + push_cur(); init_commands(); init_sig(); } + +int +main( + int argc, + char **argv) +{ + int c, i, done = 0; + char *input; + char **v; + + pushfile(stdin); + init(argc, argv); + + for (i = 0; !done && i < ncmdline; i++) { + v = breakline(cmdline[i], &c); + if (c) + done = command(c, v); + xfree(v); + } + if (cmdline) { + xfree(cmdline); + return exitcode; + } + + while (!done) { + if ((input = fetchline()) == NULL) + break; + v = breakline(input, &c); + if (c) + done = command(c, v); + doneline(input, v); + } + return exitcode; +} diff --git a/db/init.h b/db/init.h index 1d91bc355..545459821 100644 --- a/db/init.h +++ b/db/init.h @@ -30,7 +30,10 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -extern char *fsdevice; -extern char **cmdline; -extern int ncmdline; -extern void init(int argc, char **argv); +extern char *fsdevice; +extern int blkbb; +extern int exitcode; +extern int expert_mode; +extern xfs_mount_t *mp; +extern libxfs_init_t x; +extern xfs_agnumber_t cur_agno; diff --git a/db/inobt.c b/db/inobt.c index 45e83c7be..8f49704f7 100644 --- a/db/inobt.c +++ b/db/inobt.c @@ -39,7 +39,7 @@ #include "inobt.h" #include "print.h" #include "bit.h" -#include "mount.h" +#include "init.h" static int inobt_key_count(void *obj, int startoff); static int inobt_key_offset(void *obj, int startoff, int idx); diff --git a/db/inode.c b/db/inode.c index 87876d93c..766eb3eb2 100644 --- a/db/inode.c +++ b/db/inode.c @@ -43,7 +43,7 @@ #include "block.h" #include "bit.h" #include "output.h" -#include "mount.h" +#include "init.h" static int inode_a_bmbt_count(void *obj, int startoff); static int inode_a_bmx_count(void *obj, int startoff); diff --git a/db/io.c b/db/io.c index 7dd5d25d2..20c56f87f 100644 --- a/db/io.c +++ b/db/io.c @@ -40,7 +40,7 @@ #include "inode.h" #include "io.h" #include "output.h" -#include "mount.h" +#include "init.h" #include "malloc.h" static int pop_f(int argc, char **argv); @@ -448,13 +448,13 @@ write_bbs( for (j = 0; j < count; j += bbmap ? 1 : count) { if (bbmap) bbno = bbmap->b[j]; - if (lseek64(xfsargs.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { + if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { rval = errno; dbprintf("can't seek in filesystem at bb %lld\n", bbno); return rval; } c = BBTOB(bbmap ? 1 : count); - i = (int)write(xfsargs.dfd, (char *)bufp + BBTOB(j), c); + i = (int)write(x.dfd, (char *)bufp + BBTOB(j), c); if (i < 0) { rval = errno; } else if (i < c) { @@ -480,8 +480,8 @@ read_bbs( int j; int rval = EINVAL; - if (!count) - return EINVAL; + if (count <= 0) + count = 1; c = BBTOB(count); if (*bufp == NULL) @@ -491,7 +491,7 @@ read_bbs( for (j = 0; j < count; j += bbmap ? 1 : count) { if (bbmap) bbno = bbmap->b[j]; - if (lseek64(xfsargs.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { + if (lseek64(x.dfd, bbno << BBSHIFT, SEEK_SET) < 0) { rval = errno; dbprintf("can't seek in filesystem at bb %lld\n", bbno); if (*bufp == NULL) @@ -499,7 +499,7 @@ read_bbs( buf = NULL; } else { c = BBTOB(bbmap ? 1 : count); - i = (int)read(xfsargs.dfd, (char *)buf + BBTOB(j), c); + i = (int)read(x.dfd, (char *)buf + BBTOB(j), c); if (i < 0) { rval = errno; if (*bufp == NULL) diff --git a/db/main.c b/db/main.c deleted file mode 100644 index 3e182e5e6..000000000 --- a/db/main.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#include -#include "command.h" -#include "data.h" -#include "init.h" -#include "input.h" -#include "malloc.h" - -int -main( - int argc, - char **argv) -{ - int c, i, done = 0; - char *input; - char **v; - - pushfile(stdin); - init(argc, argv); - - for (i = 0; !done && i < ncmdline; i++) { - v = breakline(cmdline[i], &c); - if (c) - done = command(c, v); - xfree(v); - } - if (cmdline) { - xfree(cmdline); - return exitcode; - } - - while (!done) { - if ((input = fetchline()) == NULL) - break; - v = breakline(input, &c); - if (c) - done = command(c, v); - doneline(input, v); - } - return exitcode; -} diff --git a/db/mount.c b/db/mount.c deleted file mode 100644 index 77a8ea03b..000000000 --- a/db/mount.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#include -#include "init.h" -#include "io.h" -#include "mount.h" -#include "malloc.h" -#include "data.h" - -xfs_mount_t *mp; - -xfs_mount_t * -dbmount(void) -{ - void *bufp; - xfs_mount_t *mp; - xfs_sb_t *sbp; - - mp = xcalloc(1, sizeof(*mp)); - bufp = NULL; - if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) - return NULL; - - /* copy sb from buf to in-core, converting architecture */ - libxfs_xlate_sb(bufp, &mp->m_sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS); - xfree(bufp); - sbp = &mp->m_sb; - if (sbp->sb_magicnum != XFS_SB_MAGIC) { - fprintf(stderr,"%s: unexpected XFS SB magic number 0x%08x\n", - progname, sbp->sb_magicnum); - } - - libxfs_mount_common(mp, sbp); - libxfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); - libxfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK); - libxfs_ialloc_compute_maxlevels(mp); - - if (sbp->sb_rblocks) { - mp->m_rsumlevels = sbp->sb_rextslog + 1; - mp->m_rsumsize = - (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels * - sbp->sb_rbmblocks; - if (sbp->sb_blocksize) - mp->m_rsumsize = - roundup(mp->m_rsumsize, sbp->sb_blocksize); - } - - if (XFS_SB_VERSION_HASDIRV2(sbp)) { - libxfs_dir2_mount(mp); - } else { - libxfs_dir_mount(mp); - } - return mp; -} diff --git a/db/mount.h b/db/mount.h deleted file mode 100644 index 55aa4182d..000000000 --- a/db/mount.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -extern xfs_mount_t *dbmount(void); -extern xfs_mount_t *mp; diff --git a/db/sb.c b/db/sb.c index a478a7cea..109ebfc6c 100644 --- a/db/sb.c +++ b/db/sb.c @@ -31,6 +31,7 @@ */ #include +#include #include "command.h" #include "data.h" #include "type.h" @@ -41,19 +42,38 @@ #include "sb.h" #include "bit.h" #include "output.h" -#include "mount.h" +#include "init.h" static int sb_f(int argc, char **argv); static void sb_help(void); +static int uuid_f(int argc, char **argv); +static void uuid_help(void); +static int label_f(int argc, char **argv); +static void label_help(void); +static int version_f(int argc, char **argv); +static void version_help(void); static const cmdinfo_t sb_cmd = { "sb", NULL, sb_f, 0, 1, 1, "[agno]", "set current address to sb header", sb_help }; +static const cmdinfo_t uuid_cmd = + { "uuid", NULL, uuid_f, 0, 1, 1, "[uuid]", + "write/print FS uuid", uuid_help }; +static const cmdinfo_t label_cmd = + { "label", NULL, label_f, 0, 1, 1, "[label]", + "write/print FS label", label_help }; +static const cmdinfo_t version_cmd = + { "version", NULL, version_f, 0, 1, 1, "[feature]", + "set feature bit(s) in the sb version field", version_help }; -const field_t sb_hfld[] = { - { "", FLDT_SB, OI(0), C1, 0, TYP_NONE }, - { NULL } -}; +void +sb_init(void) +{ + add_command(&sb_cmd); + add_command(&uuid_cmd); + add_command(&label_cmd); + add_command(&version_cmd); +} #define OFF(f) bitize(offsetof(xfs_sb_t, sb_ ## f)) #define SZC(f) szcount(xfs_sb_t, sb_ ## f) @@ -105,6 +125,11 @@ const field_t sb_flds[] = { { NULL } }; +const field_t sb_hfld[] = { + { "", FLDT_SB, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + static void sb_help(void) { @@ -149,12 +174,6 @@ sb_f( return 0; } -void -sb_init(void) -{ - add_command(&sb_cmd); -} - /*ARGSUSED*/ int sb_size( @@ -164,3 +183,479 @@ sb_size( { return bitize(mp->m_sb.sb_sectsize); } + +static int +get_sb(xfs_agnumber_t agno, xfs_sb_t *sb) +{ + push_cur(); + set_cur(&typtab[TYP_SB], + XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), + XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); + + if (!iocur_top->data) { + dbprintf("can't read superblock for AG %u\n", agno); + pop_cur(); + return 0; + } + + libxfs_xlate_sb(iocur_top->data, sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS); + + if (sb->sb_magicnum != XFS_SB_MAGIC) { + dbprintf("bad sb magic # %#x in AG %u\n", + sb->sb_magicnum, agno); + return 0; + } + if (!XFS_SB_GOOD_VERSION(sb)) { + dbprintf("bad sb version # %#x in AG %u\n", + sb->sb_versionnum, agno); + return 0; + } + if (agno == 0 && sb->sb_inprogress != 0) { + dbprintf("mkfs not completed successfully\n"); + return 0; + } + return 1; +} + +/* workaround craziness in the xlog routines */ +int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } + +static int +zero_log(uuid_t *uuidp) +{ + xlog_t log; + xfs_daddr_t head_blk, tail_blk; + + if (mp->m_sb.sb_logstart) { + if (x.logdev && x.logdev != x.ddev) { + dbprintf("aborting - external log specified for FS " + "with an internal log\n"); + return 0; + } + } else { + if (!x.logdev || (x.logdev == x.ddev)) { + dbprintf("aborting - no external log specified for FS " + "with an external log\n"); + return 0; + } + } + + memset(&log, 0, sizeof(log)); + if (!x.logdev) + x.logdev = x.ddev; + x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + log.l_dev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; + log.l_logsize = BBTOB(log.l_logBBsize); + log.l_logBBsize = x.logBBsize; + log.l_logBBstart = x.logBBstart; + log.l_mp = mp; + + if (xlog_find_tail(&log, &head_blk, &tail_blk, 0)) { + dbprintf("ERROR: cannot find log head/tail, run xfs_repair\n"); + return 0; + } + if (head_blk != tail_blk) { + dbprintf( +"ERROR: The filesystem has valuable metadata changes in a log which needs to\n" +"be replayed. Mount the filesystem to replay the log, and unmount it before\n" +"re-running %s. If you are unable to mount the filesystem, then use\n" +"the xfs_repair -L option to destroy the log and attempt a repair.\n" +"Note that destroying the log may cause corruption -- please attempt a mount\n" +"of the filesystem before doing this.\n", progname); + return 0; + } + + dbprintf("Clearing log and setting UUID\n"); + + if (libxfs_log_clear(log.l_dev, + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), + (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), + uuidp, + XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, + mp->m_sb.sb_logsunit, XLOG_FMT)) { + dbprintf("ERROR: cannot clear the log\n"); + return 0; + } + return 1; +} + + +static void +uuid_help(void) +{ + dbprintf( +"\n" +" write/print FS uuid\n" +"\n" +" Example:\n" +"\n" +" 'uuid' - print UUID\n" +" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" +" 'uuid generate' - generate and write\n" +" 'uuid rewrite' - copy UUID from SB 0\n" +"\n" +"The print function checks the UUID in each SB and will warn if the UUIDs\n" +"differ between AGs (the log is not checked). The write commands will\n" +"set the uuid in all AGs to either a specified value, a newly generated\n" +"value or the value found in the first superblock (SB 0) respectively.\n" +"As a side effect of writing the UUID, the log is cleared (which is fine\n" +"on a CLEANLY unmounted FS).\n" +"\n" +); +} + +static uuid_t * +do_uuid(xfs_agnumber_t agno, uuid_t *uuid) +{ + xfs_sb_t tsb; + static uuid_t uu; + + if (!get_sb(agno, &tsb)) + return NULL; + + if (!uuid) { /* get uuid */ + memcpy(&uu, &tsb.sb_uuid, sizeof(uuid_t)); + pop_cur(); + return &uu; + } + /* set uuid */ + memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t)); + libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_UUID); + write_cur(); + return uuid; +} + +static int +uuid_f( + int argc, + char **argv) +{ + char bp[40]; + xfs_agnumber_t agno; + uuid_t uu; + uuid_t *uup = NULL; + + if (argc != 1 && argc != 2) { + dbprintf("invalid parameters\n"); + return 0; + } + + if (argc == 2) { /* WRITE UUID */ + + if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { + dbprintf("%s: not in expert mode, writing disabled\n", + progname); + return 0; + } + + if (!strcasecmp(argv[1], "generate")) { + uuid_generate(uu); + } else if (!strcasecmp(argv[1], "nil")) { + uuid_clear(uu); + } else if (!strcasecmp(argv[1], "rewrite")) { + uup = do_uuid(0, NULL); + if (!uup) { + dbprintf("failed to read UUID from AG 0\n"); + return 0; + } + memcpy(&uu, *uup, sizeof(uuid_t)); + uuid_unparse(uu, bp); + dbprintf("old UUID = %s\n", bp); + } else { + if (uuid_parse(argv[1], uu)) { + dbprintf("invalid UUID\n"); + return 0; + } + } + + /* clear the log (setting uuid) if its not dirty */ + if (!zero_log(&uu)) + return 0; + + dbprintf("writing all SBs\n"); + for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) + if (!do_uuid(agno, &uu)) { + dbprintf("failed to set UUID in AG %d\n", agno); + break; + } + + uuid_unparse(uu, bp); + dbprintf("new UUID = %s\n", bp); + return 0; + + } else { /* READ+CHECK UUID */ + + for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { + uup = do_uuid(agno, NULL); + if (!uup) { + dbprintf("failed to read UUID from AG %d\n", + agno); + return 0; + } + if (agno) { + if (memcmp(&uu, uup, sizeof(uuid_t))) { + dbprintf("warning: UUID in AG %d " + "differs to the primary SB\n", + agno); + break; + } + } else { + memcpy(uu, uup, sizeof(uuid_t)); + } + } + if (mp->m_sb.sb_logstart) { + if (x.logdev && x.logdev != x.ddev) + dbprintf("warning - external log specified " + "for FS with an internal log\n"); + } else if (!x.logdev || (x.logdev == x.ddev)) { + dbprintf("warning - no external log specified " + "for FS with an external log\n"); + } + + uuid_unparse(uu, bp); + dbprintf("UUID = %s\n", bp); + } + + return 0; +} + + +static void +label_help(void) +{ + dbprintf( +"\n" +" write/print FS label\n" +"\n" +" Example:\n" +"\n" +" 'label' - print label\n" +" 'label 123456789012' - write label\n" +" 'label --' - write an empty label\n" +"\n" +"The print function checks the label in each SB and will warn if the labels\n" +"differ between AGs. The write commands will set the label in all AGs to the\n" +"specified value. The maximum length of a label is 12 characters - use of a\n" +"longer label will result in truncation and a warning will be issued.\n" +"\n" +); +} + +static char * +do_label(xfs_agnumber_t agno, char *label) +{ + size_t len; + xfs_sb_t tsb; + static char lbl[sizeof(tsb.sb_fname) + 1]; + + if (!get_sb(agno, &tsb)) + return NULL; + + memset(&lbl[0], 0, sizeof(lbl)); + + if (!label) { /* get label */ + pop_cur(); + memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); + return &lbl[0]; + } + /* set label */ + if ((len = strlen(label)) > sizeof(tsb.sb_fname)) { + if (agno == 0) + dbprintf("%s: truncating label length from %d to %d\n", + progname, (int)len, (int)sizeof(tsb.sb_fname)); + len = sizeof(tsb.sb_fname); + } + if ( len == 2 && + (strcmp(label, "\"\"") == 0 || + strcmp(label, "''") == 0 || + strcmp(label, "--") == 0) ) + label[0] = label[1] = '\0'; + memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname)); + memcpy(&tsb.sb_fname, label, len); + memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); + libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_FNAME); + write_cur(); + return &lbl[0]; +} + +static int +label_f( + int argc, + char **argv) +{ + char *p = NULL; + xfs_sb_t sb; + xfs_agnumber_t ag; + + if (argc != 1 && argc != 2) { + dbprintf("invalid parameters\n"); + return 0; + } + + if (argc == 2) { /* WRITE LABEL */ + + if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { + dbprintf("%s: not in expert mode, writing disabled\n", + progname); + return 0; + } + + dbprintf("writing all SBs\n"); + for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) + if ((p = do_label(ag, argv[1])) == NULL) { + dbprintf("failed to set label in AG %d\n", ag); + break; + } + dbprintf("new label = \"%s\"\n", p); + + } else { /* READ LABEL */ + + for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { + p = do_label(ag, NULL); + if (!p) { + dbprintf("failed to read label in AG %d\n", ag); + return 0; + } + if (!ag) + memcpy(&sb.sb_fname, p, sizeof(sb.sb_fname)); + else if (memcmp(&sb.sb_fname, p, sizeof(sb.sb_fname))) + dbprintf("warning: AG %d label differs\n", ag); + } + dbprintf("label = \"%s\"\n", p); + } + return 0; +} + + +static void +version_help(void) +{ + dbprintf( +"\n" +" set/print feature bits in sb version\n" +"\n" +" Example:\n" +"\n" +" 'version' - print current feature bits\n" +" 'version extflg' - enable unwritten extents\n" +"\n" +"The version function prints currently enabled features for a filesystem\n" +"according to its the version field of the primary superblock.\n" +"It can also be used to enable selected features, such as support for\n" +"unwritten extents. The upated version is written into to all AGs.\n" +"\n" +); +} + +static int +do_version(xfs_agnumber_t agno, __uint16_t versionnum) +{ + xfs_sb_t tsb; + + if (!get_sb(agno, &tsb)) + return 0; + + tsb.sb_versionnum = versionnum; + libxfs_xlate_sb(iocur_top->data, &tsb, + -1, ARCH_CONVERT, XFS_SB_VERSIONNUM); + write_cur(); + return 1; +} + +static char * +version_string( + xfs_sb_t *sbp) +{ + static char s[1024]; + + if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_1) + strcpy(s, "V1"); + else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_2) + strcpy(s, "V2"); + else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_3) + strcpy(s, "V3"); + else if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) + strcpy(s, "V4"); + + if (XFS_SB_VERSION_HASATTR(sbp)) + strcat(s, ",ATTR"); + if (XFS_SB_VERSION_HASNLINK(sbp)) + strcat(s, ",NLINK"); + if (XFS_SB_VERSION_HASQUOTA(sbp)) + strcat(s, ",QUOTA"); + if (XFS_SB_VERSION_HASALIGN(sbp)) + strcat(s, ",ALIGN"); + if (XFS_SB_VERSION_HASDALIGN(sbp)) + strcat(s, ",DALIGN"); + if (XFS_SB_VERSION_HASSHARED(sbp)) + strcat(s, ",SHARED"); + if (XFS_SB_VERSION_HASDIRV2(sbp)) + strcat(s, ",DIRV2"); + if (XFS_SB_VERSION_HASLOGV2(sbp)) + strcat(s, ",LOGV2"); + if (XFS_SB_VERSION_HASEXTFLGBIT(sbp)) + strcat(s, ",EXTFLG"); + if (XFS_SB_VERSION_HASSECTOR(sbp)) + strcat(s, ",SECTOR"); + return s; +} + +static int +version_f( + int argc, + char **argv) +{ + __uint16_t version = 0; + xfs_agnumber_t ag; + + if (argc == 2) { /* WRITE VERSION */ + + if ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode) { + dbprintf("%s: not in expert mode, writing disabled\n", + progname); + return 0; + } + + /* Logic here derived from the IRIX xfs_chver(1M) script. */ + if (!strcasecmp(argv[1], "extflg")) { + switch (XFS_SB_VERSION_NUM(&mp->m_sb)) { + case XFS_SB_VERSION_1: + version = 0x0004 | XFS_SB_VERSION_EXTFLGBIT; + break; + case XFS_SB_VERSION_2: + version = 0x0014 | XFS_SB_VERSION_EXTFLGBIT; + break; + case XFS_SB_VERSION_3: + version = 0x0034 | XFS_SB_VERSION_EXTFLGBIT; + break; + case XFS_SB_VERSION_4: + if (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) + dbprintf("unwritten extents flag" + " is already enabled\n"); + else + version = mp->m_sb.sb_versionnum | + XFS_SB_VERSION_EXTFLGBIT; + break; + } + } else { + dbprintf("%s: invalid version change command \"%s\"\n", + progname, argv[1]); + return 0; + } + + if (version) { + dbprintf("writing all SBs\n"); + for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) + if (!do_version(ag, version)) { + dbprintf("failed to set versionnum " + "in AG %d\n", ag); + break; + } + mp->m_sb.sb_versionnum = version; + } + } + dbprintf("versionnum [0x%x] = %s\n", mp->m_sb.sb_versionnum, + version_string(&mp->m_sb)); + return 0; +} diff --git a/db/text.c b/db/text.c index ba603d1eb..4d1c6809d 100644 --- a/db/text.c +++ b/db/text.c @@ -43,7 +43,7 @@ #include "inode.h" #include "io.h" #include "output.h" -#include "mount.h" +#include "init.h" static void print_rawtext(void *data, int len); diff --git a/db/uuid.c b/db/uuid.c deleted file mode 100644 index 8a2b9ca35..000000000 --- a/db/uuid.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#include -#include "command.h" -#include "data.h" -#include "type.h" -#include "faddr.h" -#include "fprint.h" -#include "field.h" -#include "io.h" -#include "uuid.h" -#include "bit.h" -#include "output.h" -#include "mount.h" - -static int uuid_f(int argc, char **argv); -static void uuid_help(void); -static int label_f(int argc, char **argv); -static void label_help(void); - -static const cmdinfo_t uuid_cmd = - { "uuid", NULL, uuid_f, 0, 1, 1, "[uuid]", - "write/print FS uuid", uuid_help }; -static const cmdinfo_t label_cmd = - { "label", NULL, label_f, 0, 1, 1, "[label]", - "write/print FS label", label_help }; -static int warned; - -static void -uuid_help(void) -{ - dbprintf( -"\n" -" write/print FS uuid\n" -"\n" -" Example:\n" -"\n" -" 'uuid' - print UUID\n" -" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n" -" 'uuid generate' - generate and write\n" -" 'uuid rewrite' - copy UUID from SB 0\n" -"\n" -"The print function checks the UUID in each SB and will warn if the UUIDs\n" -"differ between AGs (the log is not checked). The write commands will\n" -"set the uuid in all AGs to either a specified value, a newly generated\n" -"value or the value found in the first superblock (SB 0) respectively.\n" -"As a side effect of writing the UUID, the log is cleared (which is fine\n" -"on a CLEANLY unmounted FS).\n" -"\n" -); -} - -static void -label_help(void) -{ - dbprintf( -"\n" -" write/print FS label\n" -"\n" -" Example:\n" -"\n" -" 'label' - print label\n" -" 'label 123456789012' - write label\n" -" 'label --' - write an empty label\n" -"\n" -"The print function checks the label in each SB and will warn if the labels\n" -"differ between AGs. The write commands will set the label in all AGs to the\n" -"specified value. The maximum length of a label is 12 characters - use of a\n" -"longer label will result in truncation and a warning will be issued.\n" -"\n" -); -} - -static int -get_sb(xfs_agnumber_t agno, xfs_sb_t *sb) -{ - push_cur(); - set_cur(&typtab[TYP_SB], - XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), - XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL); - - if (!iocur_top->data) { - dbprintf("can't read superblock for AG %u\n", agno); - pop_cur(); - return 0; - } - - libxfs_xlate_sb(iocur_top->data, sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS); - - if (sb->sb_magicnum != XFS_SB_MAGIC) { - dbprintf("bad sb magic # %#x in AG %u\n", - sb->sb_magicnum, agno); - return 0; - } - if (!XFS_SB_GOOD_VERSION(sb)) { - dbprintf("bad sb version # %#x in AG %u\n", - sb->sb_versionnum, agno); - return 0; - } - if (agno == 0 && sb->sb_inprogress != 0) { - dbprintf("mkfs not completed successfully\n"); - return 0; - } - return 1; -} - -static uuid_t * -do_uuid(xfs_agnumber_t agno, uuid_t *uuid) -{ - xfs_sb_t tsb; - static uuid_t uu; - - if (!get_sb(agno, &tsb)) - return NULL; - - if (!uuid) { /* get uuid */ - memcpy(&uu, &tsb.sb_uuid, sizeof(uuid_t)); - pop_cur(); - return &uu; - } - /* set uuid */ - memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t)); - libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_UUID); - write_cur(); - return uuid; -} - -static char * -do_label(xfs_agnumber_t agno, char *label) -{ - size_t len; - xfs_sb_t tsb; - static char lbl[sizeof(tsb.sb_fname) + 1]; - - if (!get_sb(agno, &tsb)) - return NULL; - - memset(&lbl[0], 0, sizeof(lbl)); - - if (!label) { /* get label */ - pop_cur(); - memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); - return &lbl[0]; - } - /* set label */ - if ((len = strlen(label)) > sizeof(tsb.sb_fname)) { - if (!warned++) - dbprintf("warning: truncating label from %lld to %lld " - "characters\n", - (long long)len, (long long)sizeof(tsb.sb_fname)); - len = sizeof(tsb.sb_fname); - } - if ( len == 2 && - (strcmp(label, "\"\"") == 0 || - strcmp(label, "''") == 0 || - strcmp(label, "--") == 0) ) - label[0] = label[1] = '\0'; - memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname)); - memcpy(&tsb.sb_fname, label, len); - memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname)); - libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_FNAME); - write_cur(); - return &lbl[0]; -} - -static int -uuid_f( - int argc, - char **argv) -{ - char bp[40]; - xfs_agnumber_t agno; - uuid_t uu; - uuid_t *uup=NULL; - - if (argc != 1 && argc != 2) { - dbprintf("invalid parameters\n"); - return 0; - } - - if (argc==2) { - /* write uuid */ - - if (flag_readonly || !flag_expert_mode) { - dbprintf("%s not started in read-write expert mode, writing disabled\n", - progname); - return 0; - } - - if (!strcasecmp(argv[1], "generate")) { - uuid_generate(uu); - } else if (!strcasecmp(argv[1], "nil")) { - uuid_clear(uu); - } else if (!strcasecmp(argv[1], "rewrite")) { - uup=do_uuid(0, NULL); - if (!uup) { - dbprintf("failed to read UUID from AG 0\n"); - return 0; - } - memcpy(&uu, *uup, sizeof(uuid_t)); - uuid_unparse(uu, bp); - dbprintf("old uuid = %s\n", bp); - } else { - if (uuid_parse(argv[1], uu)) { - dbprintf("invalid uuid\n"); - return 0; - } - } - - if (mp->m_sb.sb_logstart) { - if (xfsargs.logdev) { - dbprintf("external log specified for FS with internal log - aborting \n"); - return 0; - } - } else { - if (!xfsargs.logdev) { - dbprintf("no external log specified for FS with external log - aborting\n"); - return 0; - } - } - - dbprintf("clearing log and setting uuid\n"); - - /* clear log (setting uuid) */ - - if (libxfs_log_clear( - (mp->m_sb.sb_logstart)?xfsargs.ddev:xfsargs.logdev, - XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), - XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), - &uu, - XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT)) { - dbprintf("error clearing log\n"); - return 0; - } - - - dbprintf("writing all SBs\n"); - - for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) - if (!do_uuid(agno, &uu)) { - dbprintf("failed to set uuid in AG %d\n", agno); - break; - } - - uuid_unparse(uu, bp); - dbprintf("new uuid = %s\n", bp); - - return 0; - - } else { - /* get (check) uuid */ - - for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { - uup=do_uuid(agno, NULL); - if (!uup) { - dbprintf("failed to read UUID from AG %d\n", agno); - return 0; - } - if (agno) { - if (memcmp(&uu, uup, sizeof(uuid_t))) { - dbprintf("warning: uuid copies differ\n"); - break; - } - } else { - memcpy(uu, uup, sizeof(uuid_t)); - } - } - if (mp->m_sb.sb_logstart) { - if (xfsargs.logdev) - dbprintf("warning: external log specified for FS with internal log\n"); - } else { - if (!xfsargs.logdev) { - dbprintf("warning: no external log specified for FS with external log\n"); - } - } - - uuid_unparse(uu, bp); - dbprintf("uuid = %s\n", bp); - } - - return 0; -} - -static int -label_f( - int argc, - char **argv) -{ - char *p = NULL; - xfs_sb_t sb; - xfs_agnumber_t ag; - - if (argc != 1 && argc != 2) { - dbprintf("invalid parameters\n"); - return 0; - } - - if (argc==2) { /* write label */ - if (flag_readonly || !flag_expert_mode) { - dbprintf("%s not started in read-write expert mode, " - "writing disabled\n", progname); - return 0; - } - - dbprintf("writing all SBs\n"); - for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) - if ((p = do_label(ag, argv[1])) == NULL) { - dbprintf("failed to set label in AG %d\n", ag); - break; - } - dbprintf("new label = \"%s\"\n", p); - } else { /* print label */ - for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { - p = do_label(ag, NULL); - if (!p) { - dbprintf("failed to read label in AG %d\n", ag); - return 0; - } - if (!ag) - memcpy(&sb.sb_fname, p, sizeof(sb.sb_fname)); - else if (memcmp(&sb.sb_fname, p, sizeof(sb.sb_fname))) - dbprintf("warning: label in AG %d differs\n", ag); - } - dbprintf("label = \"%s\"\n", p); - } - return 0; -} - -void -uuid_init(void) -{ - warned = 0; - add_command(&label_cmd); - add_command(&uuid_cmd); -} diff --git a/db/uuid.h b/db/uuid.h deleted file mode 100644 index 4839eef30..000000000 --- a/db/uuid.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 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. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -extern void uuid_init(void); diff --git a/db/write.c b/db/write.c index cfbdcb24a..ed4cbbc2b 100644 --- a/db/write.c +++ b/db/write.c @@ -43,6 +43,7 @@ #include "field.h" #include "flist.h" #include "io.h" +#include "init.h" #include "output.h" #include "print.h" #include "write.h" @@ -58,7 +59,7 @@ static const cmdinfo_t write_cmd = void write_init(void) { - if (!flag_expert_mode) + if (!expert_mode) return; add_command(&write_cmd); @@ -105,7 +106,7 @@ write_f( pfunc_t pf; extern char *progname; - if (flag_readonly) { + if (x.isreadonly & LIBXFS_ISREADONLY) { dbprintf("%s started in read only mode, writing disabled\n", progname); return 0; diff --git a/db/xfs_admin.sh b/db/xfs_admin.sh index acf506d00..0539768c9 100755 --- a/db/xfs_admin.sh +++ b/db/xfs_admin.sh @@ -32,11 +32,12 @@ # OPTS="" -USAGE="Usage: xfs_admin [-fluV] [-L label] [-U uuid] special" +USAGE="Usage: xfs_admin [-efluV] [-L label] [-U uuid] special" -while getopts "fluL:U:V" c +while getopts "efluL:U:V" c do case $c in + e) OPTS=$OPTS" -c 'version extflg'";; f) OPTS=$OPTS" -f";; l) OPTS=$OPTS" -r -c label";; L) OPTS=$OPTS" -c 'label "$OPTARG"'";; diff --git a/debian/changelog b/debian/changelog index b3c1d1865..e22584c8e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +xfsprogs (2.4.0-1) unstable; urgency=low + + * New upstream release + * Note: unwritten extents are now enabled by default in mkfs.xfs. + + -- Nathan Scott Thu, 6 Mar 2003 12:00:38 +1100 + xfsprogs (2.3.11-1) unstable; urgency=low * Add missing build dependency on gettext (closes: #181331) diff --git a/doc/CHANGES b/doc/CHANGES index 95fb8f4c6..44791a401 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,3 +1,18 @@ +xfsprogs-2.4.0 (06 March 2002) + - Enable unwritten extents by default in mkfs.xfs. + - Add a command to xfs_db to enable unwritten extents. + - Add an option to xfs_admin to use the above command. + - Add command to xfs_db to print out the currently enabled + feature bits and version number. + - Make xfs_db slightly more robust in the presense of bad + ondisk data. + - Rationalise some xfs_db superblock-related code and the + uuid command now checks for a dirty log before zeroing. + - Add stripe alignment information to xfs_bmap. + - Sync up user/kernel source in libxfs and headers. + - Update man pages, fix a typo in the xfs_admin man page + relating to the UUID options. + xfsprogs-2.3.11 (18 February 2002) - Missed a build dependency for the Debian build process. diff --git a/include/libxfs.h b/include/libxfs.h index b15a8c02d..874acafe7 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -186,6 +186,8 @@ typedef struct xfs_mount { xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ } xfs_mount_t; +#define LIBXFS_MOUNT_ROOTINOS 0x0001 +#define LIBXFS_MOUNT_DEBUGGER 0x0002 extern xfs_mount_t *libxfs_mount (xfs_mount_t *, xfs_sb_t *, dev_t, dev_t, dev_t, int); diff --git a/include/libxlog.h b/include/libxlog.h index 2a983b7b7..bb9e71b3d 100644 --- a/include/libxlog.h +++ b/include/libxlog.h @@ -70,10 +70,13 @@ typedef struct log { /* * macros mapping kernel code to user code */ -#define STATIC static -#define EFSCORRUPTED 990 -#define XFS_ERROR(e) (e) -#define min(a,b) ((a) < (b) ? (a) : (b)) +#define STATIC static +#define EFSCORRUPTED 990 +#define XFS_ERROR(e) (e) +#define XFS_ERROR_REPORT(e,l,mp) ((void) 0) +#define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) +#define unlikely(x) (x) +#define min(a,b) ((a) < (b) ? (a) : (b)) #if (__GNUC__ < 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 95)) # define xlog_warn(fmt,args...) \ diff --git a/include/xfs_bmap_btree.h b/include/xfs_bmap_btree.h index ffa9eb0ec..be1ca0bd6 100644 --- a/include/xfs_bmap_btree.h +++ b/include/xfs_bmap_btree.h @@ -479,7 +479,6 @@ xfs_bmbt_decrement( int xfs_bmbt_delete( struct xfs_btree_cur *, - int, int *); void diff --git a/include/xfs_btree.h b/include/xfs_btree.h index 7a6857eba..87067d647 100644 --- a/include/xfs_btree.h +++ b/include/xfs_btree.h @@ -570,7 +570,9 @@ int xfs_fsb_sanity_check(struct xfs_mount *mp, xfs_fsblock_t fsb); { \ int fs_is_ok = (x); \ ASSERT(fs_is_ok); \ - if (!fs_is_ok) { \ + if (unlikely(!fs_is_ok)) { \ + XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \ + XFS_ERRLEVEL_LOW, NULL); \ error = XFS_ERROR(EFSCORRUPTED); \ goto l; \ } \ @@ -580,8 +582,11 @@ int xfs_fsb_sanity_check(struct xfs_mount *mp, xfs_fsblock_t fsb); { \ int fs_is_ok = (x); \ ASSERT(fs_is_ok); \ - if (!fs_is_ok) \ + if (unlikely(!fs_is_ok)) { \ + XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \ + XFS_ERRLEVEL_LOW, NULL); \ return XFS_ERROR(EFSCORRUPTED); \ + } \ } #endif /* __XFS_BTREE_H__ */ diff --git a/include/xfs_log.h b/include/xfs_log.h index 02955f0c0..e6c1a8a78 100644 --- a/include/xfs_log.h +++ b/include/xfs_log.h @@ -53,11 +53,11 @@ * endian issues in treating two 32 bit numbers as one 64 bit number */ static -#ifdef __GNUC__ -# if !((__GNUC__ == 2) && (__GNUC_MINOR__ == 95)) +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95) +__attribute__((unused)) /* gcc 2.95 miscompiles this when inlined */ +#else __inline__ #endif -#endif xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2, xfs_arch_t arch) { if (CYCLE_LSN(lsn1, arch) != CYCLE_LSN(lsn2, arch)) diff --git a/include/xfs_log_priv.h b/include/xfs_log_priv.h index 77c02ef65..3fd8a12bc 100644 --- a/include/xfs_log_priv.h +++ b/include/xfs_log_priv.h @@ -536,8 +536,7 @@ typedef struct log { /* common routines */ -extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp, - xlog_in_core_t *iclog); +extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); extern int xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk); extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, diff --git a/libxfs/init.c b/libxfs/init.c index 29f576788..798835b23 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -598,7 +598,7 @@ libxfs_mount( dev_t dev, dev_t logdev, dev_t rtdev, - int rrootinos) + int flags) { xfs_daddr_t d; xfs_buf_t *bp; @@ -658,7 +658,8 @@ libxfs_mount( d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { fprintf(stderr, _("%s: size check failed\n"), progname); - return NULL; + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; } /* Initialize the appropriate directory manager */ @@ -674,10 +675,12 @@ libxfs_mount( return mp; bp = libxfs_readbuf(mp->m_dev, - d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1), 1); + d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1), + !(flags & LIBXFS_MOUNT_DEBUGGER)); if (!bp) { fprintf(stderr, _("%s: data size check failed\n"), progname); - return NULL; + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; } libxfs_putbuf(bp); @@ -686,10 +689,12 @@ libxfs_mount( if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) || (!(bp = libxfs_readbuf(mp->m_logdev, d - XFS_FSB_TO_BB(mp, 1), - XFS_FSB_TO_BB(mp, 1), 1)))) { + XFS_FSB_TO_BB(mp, 1), + !(flags & LIBXFS_MOUNT_DEBUGGER)))) ) { fprintf(stderr, _("%s: log size checks failed\n"), progname); - return NULL; + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; } libxfs_putbuf(bp); } @@ -698,7 +703,8 @@ libxfs_mount( if (rtmount_init(mp)) { fprintf(stderr, _("%s: realtime device init failed\n"), progname); - return NULL; + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; } /* Allocate and initialize the per-ag data */ @@ -714,18 +720,20 @@ libxfs_mount( /* * mkfs calls mount before the root inode is allocated. */ - if (rrootinos && sbp->sb_rootino != NULLFSINO) { + if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO) { error = libxfs_iread(mp, NULL, sbp->sb_rootino, &mp->m_rootip, 0); if (error) { fprintf(stderr, _("%s: cannot read root inode (%d)\n"), progname, error); - return NULL; + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; } ASSERT(mp->m_rootip != NULL); } - if (rrootinos && rtmount_inodes(mp)) - return NULL; + if ((flags & LIBXFS_MOUNT_ROOTINOS) && rtmount_inodes(mp)) + if (!(flags & LIBXFS_MOUNT_DEBUGGER)) + return NULL; return mp; } diff --git a/libxfs/xfs.h b/libxfs/xfs.h index 39fa846c8..4efeaba9c 100644 --- a/libxfs/xfs.h +++ b/libxfs/xfs.h @@ -240,9 +240,13 @@ typedef struct { dev_t dev; } xfs_buftarg_t; #define ATTR_ROOT 0x0002 /* use attrs in root namespace */ #define ktrace_t void #define m_ddev_targp m_dev +#define unlikely(x) (x) #define kdev_none(x) (!(x)) #define KERN_WARNING #define XFS_ERROR(e) (e) +#define XFS_ERRLEVEL_LOW 1 +#define XFS_ERROR_REPORT(e,l,mp) ((void) 0) +#define XFS_CORRUPTION_ERROR(e,l,mp,m) ((void) 0) #define XFS_TEST_ERROR(expr,a,b,c) ( expr ) #define TRACE_FREE(s,a,b,x,f) ((void) 0) #define TRACE_ALLOC(s,a) ((void) 0) @@ -271,6 +275,7 @@ typedef struct { dev_t dev; } xfs_buftarg_t; #if (__GNUC__ < 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 95)) # define xfs_fs_cmn_err(a,b,msg,args...)( fprintf(stderr, msg, ## args) ) +# define cmn_err(a,msg,args...) ( fprintf(stderr, msg, ## args) ) # define printk(msg,args...) ( fprintf(stderr, msg, ## args) ) #else # define xfs_fs_cmn_err(a,b,...) ( fprintf(stderr, __VA_ARGS__) ) @@ -426,7 +431,7 @@ void xfs_bmap_insert_exlist (xfs_inode_t *, xfs_extnum_t, xfs_extnum_t, int xfs_check_nostate_extents (xfs_bmbt_rec_t *, xfs_extnum_t); void xfs_bmbt_log_ptrs (xfs_btree_cur_t *, xfs_buf_t *, int, int); void xfs_bmbt_log_keys (xfs_btree_cur_t *, xfs_buf_t *, int, int); -int xfs_bmbt_killroot (xfs_btree_cur_t *, int); +int xfs_bmbt_killroot (xfs_btree_cur_t *); int xfs_bmbt_updkey (xfs_btree_cur_t *, xfs_bmbt_key_t *, int); int xfs_bmbt_lshift (xfs_btree_cur_t *, int, int *); int xfs_bmbt_rshift (xfs_btree_cur_t *, int, int *); diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index c2ff3a7ef..57bdfbde4 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -2103,34 +2103,11 @@ xfs_alloc_read_agf( INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) && INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) && INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp); - if (XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, - XFS_RANDOM_ALLOC_READ_AGF)) { + if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, + XFS_RANDOM_ALLOC_READ_AGF))) { + XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", + XFS_ERRLEVEL_LOW, mp, agf); xfs_trans_brelse(tp, bp); -#ifdef __KERNEL__ /* additional, temporary, debugging code */ - cmn_err(CE_NOTE, - "xfs_alloc_read_agf: error in <%s> AG %d", - mp->m_fsname, agno); - if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC) - cmn_err(CE_NOTE, "bad agf_magicnum 0x%x", - INT_GET(agf->agf_magicnum, ARCH_CONVERT)); - if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT))) - cmn_err(CE_NOTE, "Bad version number 0x%x", - INT_GET(agf->agf_versionnum, ARCH_CONVERT)); - if (!(INT_GET(agf->agf_freeblks, ARCH_CONVERT) <= - INT_GET(agf->agf_length, ARCH_CONVERT))) - cmn_err(CE_NOTE, "Bad freeblks %d %d", - INT_GET(agf->agf_freeblks, ARCH_CONVERT), - INT_GET(agf->agf_length, ARCH_CONVERT)); - if (!(INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp))) - cmn_err(CE_NOTE, "Bad flfirst %d", - INT_GET(agf->agf_flfirst, ARCH_CONVERT)); - if (!(INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp))) - cmn_err(CE_NOTE, "Bad fllast %d", - INT_GET(agf->agf_fllast, ARCH_CONVERT)); - if (!(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp))) - cmn_err(CE_NOTE, "Bad flcount %d", - INT_GET(agf->agf_flcount, ARCH_CONVERT)); -#endif return XFS_ERROR(EFSCORRUPTED); } pag = &mp->m_perag[agno]; diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index a566e62a6..a912793ae 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -712,7 +712,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) count * sizeof(xfs_attr_leaf_entry_t) + INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT); if (bytes > (state->blocksize >> 1)) { - *action = 0; /* blk over 50%, dont try to join */ + *action = 0; /* blk over 50%, don't try to join */ return(0); } diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 1f0af7274..3485e4a06 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -342,7 +342,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_blockcount, &i))) goto done; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) @@ -880,13 +880,13 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount, &i))) goto done; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) goto done; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) @@ -925,7 +925,7 @@ xfs_bmap_add_extent_unwritten_real( &i))) goto done; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) @@ -965,7 +965,7 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount, &i))) goto done; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) @@ -1541,7 +1541,7 @@ xfs_bmap_add_extent_hole_real( right.br_startblock, right.br_blockcount, &i))) return error; ASSERT(i == 1); - if ((error = xfs_bmbt_delete(cur, 0, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) return error; ASSERT(i == 1); if ((error = xfs_bmbt_decrement(cur, 0, &i))) @@ -2253,8 +2253,7 @@ xfs_bmap_btree_to_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_btree_cur_t *cur, /* btree cursor */ int *logflagsp, /* inode logging flags */ - int whichfork, /* data or attr fork */ - int async) /* xaction can be async */ + int whichfork) /* data or attr fork */ { /* REFERENCED */ xfs_bmbt_block_t *cblock;/* child btree block */ @@ -2288,8 +2287,6 @@ xfs_bmap_btree_to_extents( if ((error = xfs_btree_check_lblock(cur, cblock, 0, cbp))) return error; xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); - if (!async) - xfs_trans_set_sync(tp); ip->i_d.di_nblocks--; if (XFS_IS_QUOTA_ON(mp) && ip->i_ino != mp->m_sb.sb_uquotino && @@ -2318,7 +2315,6 @@ xfs_bmap_del_extent( xfs_bmap_free_t *flist, /* list of extents to be freed */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *del, /* data to remove from extent list */ - int iflags, /* input flags */ int *logflagsp, /* inode logging flags */ int whichfork, /* data or attr fork */ int rsvd) /* OK to allocate reserved blocks */ @@ -2447,7 +2443,7 @@ xfs_bmap_del_extent( flags |= XFS_ILOG_FEXT(whichfork); break; } - if ((error = xfs_bmbt_delete(cur, iflags & XFS_BMAPI_ASYNC, &i))) + if ((error = xfs_bmbt_delete(cur, &i))) goto done; ASSERT(i == 1); break; @@ -3447,12 +3443,14 @@ xfs_bmap_read_extents( num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT); - if (i + num_recs > room) { + if (unlikely(i + num_recs > room)) { ASSERT(i + num_recs <= room); xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, (btree extents). " - "Unmount and run xfs_repair.", + "corrupt dinode %Lu, (btree extents). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); + XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", + XFS_ERRLEVEL_LOW, + ip->i_mount); goto error0; } XFS_WANT_CORRUPTED_GOTO( @@ -3480,7 +3478,10 @@ xfs_bmap_read_extents( * any "older" data bmap btree records for a * set bit in the "extent flag" position. */ - if (xfs_check_nostate_extents(temp, num_recs)) { + if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { + XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", + XFS_ERRLEVEL_LOW, + ip->i_mount); goto error0; } } @@ -3584,12 +3585,15 @@ xfs_bmapi( ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) { + mp = ip->i_mount; + if (unlikely(XFS_TEST_ERROR( + (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), + mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { + XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } - mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -4005,7 +4009,7 @@ xfs_bmapi( XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { ASSERT(wr && cur); error = xfs_bmap_btree_to_extents(tp, ip, cur, - &tmp_logflags, whichfork, 0); + &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; @@ -4080,8 +4084,11 @@ xfs_bmapi_single( xfs_bmbt_irec_t prev; /* previous extent list record */ ifp = XFS_IFORK_PTR(ip, whichfork); - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) { + if (unlikely( + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) { + XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } if (XFS_FORCED_SHUTDOWN(ip->i_mount)) @@ -4126,7 +4133,6 @@ xfs_bunmapi( xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *done) /* set if not done yet */ { - int async; /* xactions can be async */ xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_irec_t del; /* extent being deleted */ int eof; /* is deleting at eof */ @@ -4153,14 +4159,16 @@ xfs_bunmapi( whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; ifp = XFS_IFORK_PTR(ip, whichfork); - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { + if (unlikely( + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { + XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } mp = ip->i_mount; if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); - async = flags & XFS_BMAPI_ASYNC; rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; ASSERT(len > 0); ASSERT(nexts >= 0); @@ -4387,7 +4395,7 @@ xfs_bunmapi( goto error0; } error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, - flags, &tmp_logflags, whichfork, rsvd); + &tmp_logflags, whichfork, rsvd); logflags |= tmp_logflags; if (error) goto error0; @@ -4433,7 +4441,7 @@ nodelete: XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { ASSERT(cur != NULL); error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, - whichfork, async); + whichfork); logflags |= tmp_logflags; if (error) goto error0; diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index dee3e5579..39c85c44b 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -39,7 +39,6 @@ STATIC int /* error */ xfs_bmbt_delrec( xfs_btree_cur_t *cur, int level, - int async, /* deletion can be async */ int *stat) /* success/failure */ { xfs_bmbt_block_t *block; /* bmap btree block */ @@ -143,7 +142,7 @@ xfs_bmbt_delrec( if (level == cur->bc_nlevels - 1) { xfs_iroot_realloc(cur->bc_private.b.ip, -1, cur->bc_private.b.whichfork); - if ((error = xfs_bmbt_killroot(cur, async))) { + if ((error = xfs_bmbt_killroot(cur))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -177,7 +176,7 @@ xfs_bmbt_delrec( */ if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK && level == cur->bc_nlevels - 2) { - if ((error = xfs_bmbt_killroot(cur, async))) { + if ((error = xfs_bmbt_killroot(cur))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -380,8 +379,6 @@ xfs_bmbt_delrec( } xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1, cur->bc_private.b.flist, mp); - if (!async) - xfs_trans_set_sync(cur->bc_tp); cur->bc_private.b.ip->i_d.di_nblocks--; xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE); if (XFS_IS_QUOTA_ON(mp) && @@ -605,8 +602,7 @@ xfs_bmbt_insrec( STATIC int xfs_bmbt_killroot( - xfs_btree_cur_t *cur, - int async) + xfs_btree_cur_t *cur) { xfs_bmbt_block_t *block; xfs_bmbt_block_t *cblock; @@ -685,8 +681,6 @@ xfs_bmbt_killroot( memcpy(pp, cpp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*pp)); xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1, cur->bc_private.b.flist, cur->bc_mp); - if (!async) - xfs_trans_set_sync(cur->bc_tp); ip->i_d.di_nblocks--; if (XFS_IS_QUOTA_ON(cur->bc_mp) && ip->i_ino != cur->bc_mp->m_sb.sb_uquotino && @@ -1527,7 +1521,6 @@ xfs_bmbt_decrement( int /* error */ xfs_bmbt_delete( xfs_btree_cur_t *cur, - int async, /* deletion can be async */ int *stat) /* success/failure */ { int error; /* error return value */ @@ -1539,7 +1532,7 @@ xfs_bmbt_delete( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); for (level = 0, i = 2; i == 2; level++) { - if ((error = xfs_bmbt_delrec(cur, level, async, &i))) { + if ((error = xfs_bmbt_delrec(cur, level, &i))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 50f67bfd2..fb3aaafc7 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -190,15 +190,12 @@ xfs_btree_check_lblock( !INT_ISZERO(block->bb_rightsib, ARCH_CONVERT) && (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO || XFS_FSB_SANITY_CHECK(mp, INT_GET(block->bb_rightsib, ARCH_CONVERT))); - if (XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK, - XFS_RANDOM_BTREE_CHECK_LBLOCK)) { + if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK, + XFS_RANDOM_BTREE_CHECK_LBLOCK))) { if (bp) xfs_buftrace("LBTREE ERROR", bp); -#ifdef __KERNEL__ /* additional, temporary, debugging code */ - cmn_err(CE_NOTE, - "EFSCORRUPTED returned from file %s line %d", - __FILE__, __LINE__); -#endif + XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW, + mp); return XFS_ERROR(EFSCORRUPTED); } return 0; @@ -312,22 +309,13 @@ xfs_btree_check_sblock( (INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK || INT_GET(block->bb_rightsib, ARCH_CONVERT) < agflen) && !INT_ISZERO(block->bb_rightsib, ARCH_CONVERT); - if (XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, + if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK, - XFS_RANDOM_BTREE_CHECK_SBLOCK)) { + XFS_RANDOM_BTREE_CHECK_SBLOCK))) { if (bp) xfs_buftrace("SBTREE ERROR", bp); -#ifdef __KERNEL__ /* additional, temporary, debugging code */ - cmn_err(CE_NOTE, - "xfs_btree_check_sblock: Not OK:"); - cmn_err(CE_NOTE, - "magic 0x%x level %d numrecs %d leftsib %d rightsib %d", - INT_GET(block->bb_magic, ARCH_CONVERT), - INT_GET(block->bb_level, ARCH_CONVERT), - INT_GET(block->bb_numrecs, ARCH_CONVERT), - INT_GET(block->bb_leftsib, ARCH_CONVERT), - INT_GET(block->bb_rightsib, ARCH_CONVERT)); -#endif + XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW, + cur->bc_mp); return XFS_ERROR(EFSCORRUPTED); } return 0; diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index c87d964c4..427514933 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -38,6 +38,7 @@ * Routines to implement directories as Btrees of hashed names. */ +static int xfs_error_level; /*======================================================================== * Routines used for growing the Btree. @@ -780,8 +781,8 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) node = (xfs_da_intnode_t *)info; count = INT_GET(node->hdr.count, ARCH_CONVERT); if (count > (state->node_ents >> 1)) { - *action = 0; /* blk over 50%, dont try to join */ - return(0); /* blk over 50%, dont try to join */ + *action = 0; /* blk over 50%, don't try to join */ + return(0); /* blk over 50%, don't try to join */ } /* @@ -1749,8 +1750,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, error = xfs_bmap_last_offset(tp, ip, &lastoff, w); if (error) return error; - if (lastoff == 0) + if (unlikely(lastoff == 0)) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW, + mp); return XFS_ERROR(EFSCORRUPTED); + } /* * Read the last block in the btree space. */ @@ -1791,8 +1795,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; - if (INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno || - INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT)) { + if (unlikely( + INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno || + INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } @@ -1810,9 +1817,12 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w))) goto done; sib_info = sib_buf->data; - if ( INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno + if (unlikely( + INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno || INT_GET(sib_info->magic, ARCH_CONVERT) - != INT_GET(dead_info->magic, ARCH_CONVERT)) { + != INT_GET(dead_info->magic, ARCH_CONVERT))) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } @@ -1832,8 +1842,11 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) goto done; par_node = par_buf->data; - if (INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC || - (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1)) { + if (unlikely( + INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC || + (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } @@ -1843,7 +1856,9 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash; entno++) continue; - if (entno == INT_GET(par_node->hdr.count, ARCH_CONVERT)) { + if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } @@ -1868,15 +1883,20 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT); xfs_da_brelse(tp, par_buf); par_buf = NULL; - if (par_blkno == 0) { + if (unlikely(par_blkno == 0)) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) goto done; par_node = par_buf->data; - if (INT_GET(par_node->hdr.level, ARCH_CONVERT) != level || - INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) { + if (unlikely( + INT_GET(par_node->hdr.level, ARCH_CONVERT) != level || + INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) { + XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", + XFS_ERRLEVEL_LOW, mp); error = XFS_ERROR(EFSCORRUPTED); goto done; } @@ -2069,6 +2089,26 @@ xfs_da_do_buf( } if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) { error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED); + if (unlikely(error == EFSCORRUPTED)) { + if (xfs_error_level >= XFS_ERRLEVEL_LOW) { + int i; + cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n", + (long long)bno); + cmn_err(CE_ALERT, "dir: inode %lld\n", + (long long)dp->i_ino); + for (i = 0; i < nmap; i++) { + cmn_err(CE_ALERT, + "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n", + i, + mapp[i].br_startoff, + mapp[i].br_startblock, + mapp[i].br_blockcount, + mapp[i].br_state); + } + } + XFS_ERROR_REPORT("xfs_da_do_buf(1)", + XFS_ERRLEVEL_LOW, mp); + } goto exit0; } if (caller != 3 && nmap > 1) { @@ -2151,7 +2191,8 @@ xfs_da_do_buf( free = rbp->data; magic = INT_GET(info->magic, ARCH_CONVERT); magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT); - if (XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && + if (unlikely( + XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && (magic != XFS_DIR_LEAF_MAGIC) && (magic != XFS_ATTR_LEAF_MAGIC) && (magic != XFS_DIR2_LEAF1_MAGIC) && @@ -2160,8 +2201,10 @@ xfs_da_do_buf( (magic1 != XFS_DIR2_DATA_MAGIC) && (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC), mp, XFS_ERRTAG_DA_READ_BUF, - XFS_RANDOM_DA_READ_BUF)) { + XFS_RANDOM_DA_READ_BUF))) { xfs_buftrace("DA READ ERROR", rbp->bps[0]); + XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", + XFS_ERRLEVEL_LOW, mp, info); error = XFS_ERROR(EFSCORRUPTED); xfs_da_brelse(trans, rbp); nbplist = 0; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index cf1fc4b56..1b80d388e 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -87,7 +87,10 @@ xfs_dir2_block_addname( /* * Check the magic number, corrupted if wrong. */ - if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) { + if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT) + != XFS_DIR2_BLOCK_MAGIC)) { + XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", + XFS_ERRLEVEL_LOW, mp, block); xfs_da_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index bfae431b5..870a2f6cd 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -489,7 +489,9 @@ xfs_dir2_leafn_lookup_int( /* * If it has room, return it. */ - if (INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF) { + if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) { + XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", + XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) { @@ -1325,6 +1327,7 @@ xfs_dir2_node_addname_int( int findex; /* freespace entry index */ xfs_dir2_db_t foundbno=0; /* found freespace block no */ int foundindex=0; /* found freespace entry idx */ + int foundhole; /* found hole in freespace */ xfs_dir2_free_t *free=NULL; /* freespace block structure */ xfs_dir2_db_t ifbno; /* initial freespace block no */ xfs_dir2_db_t lastfbno=0; /* highest freespace block no */ @@ -1333,6 +1336,7 @@ xfs_dir2_node_addname_int( xfs_mount_t *mp; /* filesystem mount point */ int needlog; /* need to log data header */ int needscan; /* need to rescan data frees */ + int needfreesp; /* need to allocate freesp blk */ xfs_dir2_data_off_t *tagp; /* data entry tag pointer */ xfs_trans_t *tp; /* transaction pointer */ @@ -1340,6 +1344,7 @@ xfs_dir2_node_addname_int( mp = dp->i_mount; tp = args->trans; length = XFS_DIR2_DATA_ENTSIZE(args->namelen); + foundhole = 0; /* * If we came in with a freespace block that means that lookup * found an entry with our hash value. This is the freespace @@ -1429,11 +1434,12 @@ xfs_dir2_node_addname_int( * to avoid it. */ if ((error = xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, fbno), -1, &fbp, + XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { return error; } - if (fbp == NULL) { + if (unlikely(fbp == NULL)) { + foundhole = 1; continue; } free = fbp->data; @@ -1452,7 +1458,7 @@ xfs_dir2_node_addname_int( * one is empty, remember this slot. */ if (foundindex == -1 && - INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) { + INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF && !foundhole) { foundindex = findex; foundbno = fbno; } @@ -1466,7 +1472,8 @@ xfs_dir2_node_addname_int( * remember this slot. */ if (foundindex == -1 && - findex < XFS_DIR2_MAX_FREE_BESTS(mp)) { + findex < XFS_DIR2_MAX_FREE_BESTS(mp) && + !foundhole) { foundindex = findex; foundbno = fbno; } @@ -1480,69 +1487,11 @@ xfs_dir2_node_addname_int( } } } - /* - * If we don't have a data block, and there's no free slot in a - * freeblock, we need to add a new freeblock. - */ - if (dbno == -1 && foundindex == -1) { - /* - * Not allowed to allocate, so return failure. - */ - if (args->justcheck || args->total == 0) { - return XFS_ERROR(ENOSPC); - } - /* - * Add the new freeblock. - */ - if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, - &fbno))) { - return error; - } - /* - * Get a buffer for the new block. - */ - if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fbno), - -1, &fbp, XFS_DATA_FORK))) { - return error; - } - ASSERT(fbp != NULL); - /* - * Initialize the new block to be empty, and remember - * its first slot as our empty slot. - */ - free = fbp->data; - INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); - INT_SET(free->hdr.firstdb, ARCH_CONVERT, (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * - XFS_DIR2_MAX_FREE_BESTS(mp)); - INT_ZERO(free->hdr.nused, ARCH_CONVERT); - INT_ZERO(free->hdr.nvalid, ARCH_CONVERT); - foundindex = 0; - foundbno = fbno; - } - /* - * If we don't have a data block, and we don't have a freeblock buffer - * in hand (we dropped the one with the free slot in it), - * go read the freeblock again. - */ - if (dbno == -1 && fbp == NULL) { - /* - * We're going to use the empty slot we found before. - */ - findex = foundindex; - fbno = foundbno; - if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fbno), - -1, &fbp, XFS_DATA_FORK))) { - return error; - } - ASSERT(fbp != NULL); - free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); - } /* * If we don't have a data block, we need to allocate one and make * the freespace entries refer to it. */ - if (dbno == -1) { + if (unlikely(dbno == -1)) { /* * Not allowed to allocate, return failure. */ @@ -1551,7 +1500,7 @@ xfs_dir2_node_addname_int( * Drop the freespace buffer unless it came from our * caller. */ - if (fblk == NULL || fblk->bp == NULL) + if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return XFS_ERROR(ENOSPC); } @@ -1565,7 +1514,7 @@ xfs_dir2_node_addname_int( * Drop the freespace buffer unless it came from our * caller. */ - if (fblk == NULL || fblk->bp == NULL) + if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return error; } @@ -1574,21 +1523,81 @@ xfs_dir2_node_addname_int( * freespace block we have in hand, drop the one we have * and get the right one. */ - if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) { - xfs_da_brelse(tp, fbp); + needfreesp = 0; + if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno || fbp == NULL) { + if (fbp) + xfs_da_brelse(tp, fbp); if (fblk && fblk->bp) fblk->bp = NULL; fbno = XFS_DIR2_DB_TO_FDB(mp, dbno); if ((error = xfs_da_read_buf(tp, dp, - XFS_DIR2_DB_TO_DA(mp, fbno), -1, &fbp, + XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, XFS_DATA_FORK))) { xfs_da_buf_done(dbp); return error; } + + /* + * If there wasn't a freespace block, the read will + * return a NULL fbp. Allocate one later. + */ + + if(unlikely( fbp == NULL )) { + needfreesp = 1; + } else { + free = fbp->data; + ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + } + } + + /* + * If we don't have a data block, and there's no free slot in a + * freeblock, we need to add a new freeblock. + */ + if (unlikely(needfreesp || foundindex == -1)) { + /* + * Add the new freeblock. + */ + if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, + &fbno))) { + return error; + } + + if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) { + cmn_err(CE_ALERT, + "xfs_dir2_node_addname_int: needed block %lld, got %lld\n", + (long long)XFS_DIR2_DB_TO_FDB(mp, dbno), + (long long)fbno); + XFS_ERROR_REPORT("xfs_dir2_node_addname_int", + XFS_ERRLEVEL_LOW, mp); + return XFS_ERROR(EFSCORRUPTED); + } + + /* + * Get a buffer for the new block. + */ + if ((error = xfs_da_get_buf(tp, dp, + XFS_DIR2_DB_TO_DA(mp, fbno), + -1, &fbp, XFS_DATA_FORK))) { + return error; + } ASSERT(fbp != NULL); + + /* + * Initialize the new block to be empty, and remember + * its first slot as our empty slot. + */ free = fbp->data; - ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); + INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC); + INT_SET(free->hdr.firstdb, ARCH_CONVERT, + (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * + XFS_DIR2_MAX_FREE_BESTS(mp)); + INT_ZERO(free->hdr.nvalid, ARCH_CONVERT); + INT_ZERO(free->hdr.nused, ARCH_CONVERT); + foundindex = 0; + foundbno = fbno; } + /* * Set the freespace block index from the data block number. */ @@ -1630,16 +1639,17 @@ xfs_dir2_node_addname_int( * If just checking, we succeeded. */ if (args->justcheck) { - if (fblk == NULL || fblk->bp == NULL) + if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return 0; } /* * Read the data block in. */ - if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno), + if (unlikely( + error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno), -1, &dbp, XFS_DATA_FORK))) { - if (fblk == NULL || fblk->bp == NULL) + if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); return error; } @@ -1694,7 +1704,7 @@ xfs_dir2_node_addname_int( /* * If the caller didn't hand us the freespace block, drop it. */ - if (fblk == NULL || fblk->bp == NULL) + if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) xfs_da_buf_done(fbp); /* * Return the data block and offset in args, then drop the data block. @@ -1922,10 +1932,18 @@ xfs_dir2_node_trim_free( /* * Read the freespace block. */ - if ((error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -1, &bp, + if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp, XFS_DATA_FORK))) { return error; } + + /* + * There can be holes in freespace. If fo is a hole, there's + * nothing to do. + */ + if (bp == NULL) { + return 0; + } free = bp->data; ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC); /* diff --git a/libxfs/xfs_dir_leaf.c b/libxfs/xfs_dir_leaf.c index 0cdd19bbf..713744222 100644 --- a/libxfs/xfs_dir_leaf.c +++ b/libxfs/xfs_dir_leaf.c @@ -60,10 +60,11 @@ xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino) agblkno != 0 && ioff < (1 << mp->m_sb.sb_inopblog) && XFS_AGINO_TO_INO(mp, agno, agino) == ino; - if (XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, - XFS_RANDOM_DIR_INO_VALIDATE)) { + if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, + XFS_RANDOM_DIR_INO_VALIDATE))) { xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", (unsigned long long) ino); + XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } return 0; @@ -1108,7 +1109,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) + INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); if (bytes > (state->blocksize >> 1)) { - *action = 0; /* blk over 50%, dont try to join */ + *action = 0; /* blk over 50%, don't try to join */ return(0); } diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index ad925522b..4f0e80b80 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -1144,14 +1144,11 @@ xfs_ialloc_read_agi( INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC && XFS_AGI_GOOD_VERSION( INT_GET(agi->agi_versionnum, ARCH_CONVERT)); - if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, - XFS_RANDOM_IALLOC_READ_AGI)) { + if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, + XFS_RANDOM_IALLOC_READ_AGI))) { + XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW, + mp, agi); xfs_trans_brelse(tp, bp); -#ifdef __KERNEL__ /* additional, temporary, debugging code */ - cmn_err(CE_NOTE, - "EFSCORRUPTED returned from file %s line %d", - __FILE__, __LINE__); -#endif return XFS_ERROR(EFSCORRUPTED); } pag = &mp->m_perag[agno]; diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c index 602849cfb..1549451dc 100644 --- a/libxfs/xfs_inode.c +++ b/libxfs/xfs_inode.c @@ -183,13 +183,15 @@ xfs_itobp( (i << mp->m_sb.sb_inodelog)); di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); - if (XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, - XFS_RANDOM_ITOBP_INOTOBP)) { + if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, + XFS_RANDOM_ITOBP_INOTOBP))) { #ifdef DEBUG prdev("bad inode magic/vsn daddr 0x%llx #%d (magic=%x)", mp->m_dev, (unsigned long long)imap.im_blkno, i, INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); #endif + XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_LOW, + mp, dip); xfs_trans_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } @@ -233,9 +235,10 @@ xfs_iformat( XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); error = 0; - if (INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + + if (unlikely( + INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > - INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)) { + INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, extent total = %d, nblocks = %Lu." " Unmount and run xfs_repair.", @@ -244,15 +247,19 @@ xfs_iformat( + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), (unsigned long long) INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)); + XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } - if (INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize) { + if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x." " Unmount and run xfs_repair.", (unsigned long long)ip->i_ino, (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); + XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } @@ -261,8 +268,11 @@ xfs_iformat( case IFCHR: case IFBLK: case IFSOCK: - if (INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV) + if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) { + XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); + } ip->i_d.di_size = 0; ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); break; @@ -275,24 +285,26 @@ xfs_iformat( /* * no local regular files yet */ - if ((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG) { + if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG)) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode " - "(local format for regular file) %Lu. " - "Unmount and run xfs_repair.", + "corrupt inode (local format for regular file) %Lu. Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); + XFS_CORRUPTION_ERROR("xfs_iformat(4)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); - if (di_size > - XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT)) { + if (unlikely(di_size > + XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT))) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %Ld for local inode). " - "Unmount and run xfs_repair.", + "corrupt inode %Lu (bad size %Ld for local inode). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino, (long long) di_size); + XFS_CORRUPTION_ERROR("xfs_iformat(5)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } @@ -306,11 +318,14 @@ xfs_iformat( error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); break; default: + XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } break; default: + XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } if (error) { @@ -371,13 +386,13 @@ xfs_iformat_local( * is wrong and we just bail out rather than crash in * kmem_alloc() or memcpy() below. */ - if (size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) { + if (unlikely(size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu " - "(bad size %d for local fork, size = %d). " - "Unmount and run xfs_repair.", + "corrupt inode %Lu (bad size %d for local fork, size = %d). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino, size, XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)); + XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } ifp = XFS_IFORK_PTR(ip, whichfork); @@ -433,11 +448,12 @@ xfs_iformat_extents( * is wrong and we just bail out rather than crash in * kmem_alloc() or memcpy() below. */ - if (size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) { + if (unlikely(size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu ((a)extents = %d). " - "Unmount and run xfs_repair.", + "corrupt inode %Lu ((a)extents = %d). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino, nex); + XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, + ip->i_mount, dip); return XFS_ERROR(EFSCORRUPTED); } @@ -471,9 +487,13 @@ xfs_iformat_extents( whichfork); if (whichfork != XFS_DATA_FORK || XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) - if (xfs_check_nostate_extents( - ifp->if_u1.if_extents, nex)) + if (unlikely(xfs_check_nostate_extents( + ifp->if_u1.if_extents, nex))) { + XFS_ERROR_REPORT("xfs_iformat_extents(2)", + XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); + } } ifp->if_flags |= XFS_IFEXTENTS; return 0; @@ -511,14 +531,15 @@ xfs_iformat_btree( * or the number of extents is greater than the number of * blocks. */ - if (XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max + if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max || XFS_BMDR_SPACE_CALC(nrecs) > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT) - || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) { + || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, - "corrupt inode %Lu (btree). " - "Unmount and run xfs_repair.", + "corrupt inode %Lu (btree). Unmount and run xfs_repair.", (unsigned long long) ip->i_ino); + XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } @@ -789,8 +810,11 @@ xfs_iread_extents( xfs_ifork_t *ifp; size_t size; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) + if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { + XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, + ip->i_mount); return XFS_ERROR(EFSCORRUPTED); + } size = XFS_IFORK_NEXTENTS(ip, whichfork) * (uint)sizeof(xfs_bmbt_rec_t); ifp = XFS_IFORK_PTR(ip, whichfork); /* @@ -1356,7 +1380,9 @@ xfs_iflush_fork( memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); } if (whichfork == XFS_DATA_FORK) { - if (XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip)) { + if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) { + XFS_ERROR_REPORT("xfs_iflush_fork", + XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); } } diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c index b9273d6fe..637370dfa 100644 --- a/libxlog/xfs_log_recover.c +++ b/libxlog/xfs_log_recover.c @@ -1258,10 +1258,12 @@ xlog_do_recovery_pass(xlog_t *log, ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= INT_MAX)); bblks = (int) BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); /* blocks in data section */ - if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) || + if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) || (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) || (bblks <= 0) || - (blk_no > log->l_logBBsize)) { + (blk_no > log->l_logBBsize))) { + XFS_ERROR_REPORT("xlog_do_recovery_pass(1)", + XFS_ERRLEVEL_LOW, log->l_mp); error = EFSCORRUPTED; goto bread_err2; } @@ -1327,9 +1329,11 @@ xlog_do_recovery_pass(xlog_t *log, ASSERT(bblks > 0); blk_no += hblks; /* successfully read header */ - if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) || + if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) || (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) || - (bblks <= 0)) { + (bblks <= 0))) { + XFS_ERROR_REPORT("xlog_do_recovery_pass(2)", + XFS_ERRLEVEL_LOW, log->l_mp); error = EFSCORRUPTED; goto bread_err2; } diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8 index 50cfc3e6d..7034b5e5c 100644 --- a/man/man8/xfs_admin.8 +++ b/man/man8/xfs_admin.8 @@ -3,8 +3,8 @@ xfs_admin \- change parameters of an XFS filesystem .SH SYNOPSIS .nf -\f3xfs_admin\f1 [ \f3-lu\f1] [ \f3\-L \f2label\f1 ] [ \f3\-U \f2uuid\f1 ] device -\f3xfs_admin \-f\f1 [ \f3-lu\f1] [ \f3\-L \f2label\f1 ] [ \f3\-U \f2uuid\f1 ] filename +\f3xfs_admin\f1 [ \f3-elu\f1] [ \f3\-L \f2label\f1 ] [ \f3\-U \f2uuid\f1 ] device +\f3xfs_admin \-f\f1 [ \f3-elu\f1] [ \f3\-L \f2label\f1 ] [ \f3\-U \f2uuid\f1 ] filename .fi .SH DESCRIPTION .I xfs_admin @@ -24,6 +24,10 @@ and modified using the command. .SH OPTIONS .TP 5 +\f3\-e\f1 +Enables unwritten extent support on a filesystem that does not +already have this enabled. +.TP 5 \f3\-f\f1 Specifies that the filesystem image to be processed is stored in a regular file (see the \f2mkfs.xfs\f1 \f3\-d\f1 \f2file\f1 option). @@ -50,7 +54,7 @@ value for Set the UUID of the filesystem. A sample UUID looks like this: "c1b9d5a2-f162-11cf-9ece-0020afc76f16". The uuid may also be -.IR null , +.IR nil , which will set the filesystem UUID to the null UUID. The uuid may also be .IR generate , diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 839cd3c8e..4580909b3 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -436,6 +436,17 @@ superblock in the filesystem. to all secondary copies of the superblock. If no argument is given, the current filesystem UUID is printed. .TP +\f3version\f1 [ \f2extflg\f1 ] +Enable selected features for a filesystem (certain features can +be enabled on an unmounted filesystem, after +.IR mkfs.xfs (8) +has created the filesystem). +Support for unwritten extents can be enabled using the \f2extflg\f1 +option. +This option will write the version number into every copy of the +superblock in the filesystem. +If no argument is given, the current version and feature bits are printed. +.TP \f3write\f1 [ \f2field\f1 or \f2value\f1 ] ... Write a value to disk. Specific fields can be set in structures (struct mode), diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 4b708ac3c..55e97b49a 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -460,7 +460,7 @@ main( dfile = logfile = rtfile = NULL; dsize = logsize = rtsize = rtextsize = protofile = NULL; dsu = dsw = dsunit = dswidth = nodsflag = lalign = lsu = lsunit = 0; - extent_flagging = 0; + extent_flagging = 1; force_overwrite = 0; worst_freelist = 0; diff --git a/po/xfsprogs.pot b/po/xfsprogs.pot index 2bc936efd..a89fd2132 100644 --- a/po/xfsprogs.pot +++ b/po/xfsprogs.pot @@ -85,6 +85,25 @@ msgstr "" msgid "TOTAL" msgstr "" +msgid " FLG Values:\n" +msgstr "" + +#, c-format +msgid " %5.5o Doesn't begin on stripe unit\n" +msgstr "" + +#, c-format +msgid " %5.5o Doesn't end on stripe unit\n" +msgstr "" + +#, c-format +msgid " %5.5o Doesn't begin on stripe width\n" +msgstr "" + +#, c-format +msgid " %5.5o Doesn't end on stripe width\n" +msgstr "" + #, c-format msgid "" "Usage: %s [options] mountpoint\n"