# 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
int map_size;
int loop = 0;
xfs_fsop_geom_v1_t fsgeo;
+ int flg = 0;
fd = open(fname, O_RDONLY);
if (fd < 0) {
#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
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 +
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;
#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);
#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);
#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);
#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);
#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);
#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,
#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);
#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);
#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);
#include "io.h"
#include "output.h"
#include "type.h"
-#include "mount.h"
+#include "init.h"
#include "malloc.h"
typedef enum {
#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);
#include "print.h"
#include "quit.h"
#include "sb.h"
-#include "uuid.h"
#include "write.h"
#include "malloc.h"
#include "dquot.h"
print_init();
quit_init();
sb_init();
- uuid_init();
type_init();
write_init();
dquot_init();
#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) \
+++ /dev/null
-/*
- * 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 <libxfs.h>
-#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;
+++ /dev/null
-/*
- * 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;
#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)
#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);
#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);
#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);
#include "bit.h"
#include "bmap.h"
#include "output.h"
-#include "mount.h"
+#include "init.h"
void
fa_agblock(
#include "io.h"
#include "output.h"
#include "type.h"
-#include "mount.h"
+#include "init.h"
#include "malloc.h"
typedef struct extent {
#include "io.h"
#include "type.h"
#include "output.h"
-#include "mount.h"
+#include "init.h"
#include "malloc.h"
typedef struct histent
#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) {
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);
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;
+}
* 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;
#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);
#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);
#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);
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) {
int j;
int rval = EINVAL;
- if (!count)
- return EINVAL;
+ if (count <= 0)
+ count = 1;
c = BBTOB(count);
if (*bufp == NULL)
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)
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)
+++ /dev/null
-/*
- * 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 <libxfs.h>
-#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;
-}
+++ /dev/null
-/*
- * 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 <libxfs.h>
-#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;
-}
+++ /dev/null
-/*
- * 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;
*/
#include <libxfs.h>
+#include <libxlog.h>
#include "command.h"
#include "data.h"
#include "type.h"
#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)
{ NULL }
};
+const field_t sb_hfld[] = {
+ { "", FLDT_SB, OI(0), C1, 0, TYP_NONE },
+ { NULL }
+};
+
static void
sb_help(void)
{
return 0;
}
-void
-sb_init(void)
-{
- add_command(&sb_cmd);
-}
-
/*ARGSUSED*/
int
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;
+}
#include "inode.h"
#include "io.h"
#include "output.h"
-#include "mount.h"
+#include "init.h"
static void print_rawtext(void *data, int len);
+++ /dev/null
-/*
- * 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 <libxfs.h>
-#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);
-}
+++ /dev/null
-/*
- * 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);
#include "field.h"
#include "flist.h"
#include "io.h"
+#include "init.h"
#include "output.h"
#include "print.h"
#include "write.h"
void
write_init(void)
{
- if (!flag_expert_mode)
+ if (!expert_mode)
return;
add_command(&write_cmd);
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;
#
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"'";;
+xfsprogs (2.4.0-1) unstable; urgency=low
+
+ * New upstream release
+ * Note: unwritten extents are now enabled by default in mkfs.xfs.
+
+ -- Nathan Scott <nathans@debian.org> Thu, 6 Mar 2003 12:00:38 +1100
+
xfsprogs (2.3.11-1) unstable; urgency=low
* Add missing build dependency on gettext (closes: #181331)
+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.
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);
/*
* 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...) \
int
xfs_bmbt_delete(
struct xfs_btree_cur *,
- int,
int *);
void
{ \
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; \
} \
{ \
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__ */
* 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))
/* 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,
dev_t dev,
dev_t logdev,
dev_t rtdev,
- int rrootinos)
+ int flags)
{
xfs_daddr_t d;
xfs_buf_t *bp;
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 */
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);
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);
}
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 */
/*
* 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;
}
#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)
#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__) )
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 *);
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];
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);
}
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)))
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)))
&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)))
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)))
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)))
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 */
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 &&
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 */
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;
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(
* 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;
}
}
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);
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;
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))
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 */
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);
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;
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;
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 */
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;
}
*/
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;
}
}
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) &&
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;
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 &&
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 */
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;
}
!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;
(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;
* Routines to implement directories as Btrees of hashed names.
*/
+static int xfs_error_level;
/*========================================================================
* Routines used for growing the Btree.
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 */
}
/*
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.
*/
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;
}
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;
}
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;
}
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;
}
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;
}
}
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) {
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) &&
(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;
/*
* 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);
}
/*
* 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) {
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 */
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 */
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
* 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;
* 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;
}
* 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;
}
}
}
}
- /*
- * 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.
*/
* 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);
}
* 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;
}
* 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.
*/
* 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;
}
/*
* 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.
/*
* 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);
/*
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;
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);
}
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];
(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);
}
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.",
+ 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);
}
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;
/*
* 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);
}
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) {
* 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);
* 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);
}
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;
* 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);
}
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);
/*
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);
}
}
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;
}
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;
}
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
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).
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 ,
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),
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;
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"