summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2007-03-19 13:30:56 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2007-03-19 13:30:56 +0000
commit3d458d85d1dd40139423089c1e2bf71f61f6a828 (patch)
tree5d04c9bfba970a209fa999d81d924eb9ced9a7c4 /sbin
parent8aee7db6c25d6479509af36b682b28c5e51add21 (diff)
Bits to make fsirand grok FFS2, okay millert@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fsirand/fsirand.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c
index 13844c42472..b0e0a90faa2 100644
--- a/sbin/fsirand/fsirand.c
+++ b/sbin/fsirand/fsirand.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fsirand.c,v 1.23 2007/02/20 13:55:17 jmc Exp $ */
+/* $OpenBSD: fsirand.c,v 1.24 2007/03/19 13:30:55 pedro Exp $ */
/*
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -16,10 +16,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef lint
-static char rcsid[] = "$OpenBSD: fsirand.c,v 1.23 2007/02/20 13:55:17 jmc Exp $";
-#endif /* not lint */
-
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>
@@ -46,6 +42,11 @@ extern char *__progname;
int printonly = 0, force = 0, ignorelabel = 0;
+/*
+ * Possible locations for the superblock.
+ */
+static const int sbtry[] = SBLOCKSEARCH;
+
int
main(int argc, char *argv[])
{
@@ -92,14 +93,16 @@ main(int argc, char *argv[])
int
fsirand(char *device)
{
- static struct ufs1_dinode *inodebuf;
+ struct ufs1_dinode *dp1 = NULL;
+ struct ufs2_dinode *dp2 = NULL;
+ static char *inodebuf;
static size_t oldibufsize;
size_t ibufsize;
struct fs *sblock, *tmpsblock;
ino_t inumber;
- daddr_t dblk;
+ ufs2_daddr_t sblockloc, dblk;
char sbuf[SBSIZE], sbuftmp[SBSIZE];
- int devfd, n, cg;
+ int devfd, n, cg, i;
char *devpath;
u_int32_t bsize = DEV_BSIZE;
struct disklabel label;
@@ -122,29 +125,50 @@ fsirand(char *device)
/* Read in master superblock */
(void)memset(&sbuf, 0, sizeof(sbuf));
sblock = (struct fs *)&sbuf;
- if (lseek(devfd, (off_t)SBOFF, SEEK_SET) == -1) {
- warn("Can't seek to superblock (%qd) on %s", SBOFF, devpath);
- return (1);
+
+ for (i = 0; sbtry[i] != -1; i++) {
+ sblockloc = sbtry[i];
+
+ if (lseek(devfd, (off_t)sblockloc, SEEK_SET) == -1) {
+ warn("Can't seek to superblock (%qd) on %s", sblockloc,
+ devpath);
+ return (1);
+ }
+
+ if ((n = read(devfd, (void *)sblock, SBSIZE)) != SBSIZE) {
+ warnx("Can't read superblock on %s: %s", devpath,
+ (n < SBSIZE) ? "short read" : strerror(errno));
+ return (1);
+ }
+
+ /* Find a suitable superblock */
+ if (sblock->fs_magic != FS_UFS1_MAGIC &&
+ sblock->fs_magic != FS_UFS2_MAGIC)
+ continue; /* Not a superblock */
+
+ if (sblock->fs_magic == FS_UFS2_MAGIC &&
+ sblock->fs_sblockloc != sbtry[i])
+ continue; /* Not a superblock */
+
+ break;
}
- if ((n = read(devfd, (void *)sblock, SBSIZE)) != SBSIZE) {
- warnx("Can't read superblock on %s: %s", devpath,
- (n < SBSIZE) ? "short read" : strerror(errno));
+
+ if (sbtry[i] == -1) {
+ warnx("Cannot find file system superblock");
return (1);
}
/* Simple sanity checks on the superblock */
- if (sblock->fs_magic != FS_MAGIC) {
- warnx("Bad magic number in superblock");
- return (1);
- }
if (sblock->fs_sbsize > SBSIZE) {
warnx("Superblock size is preposterous");
return (1);
}
+
if (sblock->fs_postblformat == FS_42POSTBLFMT) {
warnx("Filesystem format is too old, sorry");
return (1);
}
+
if (!force && !printonly && sblock->fs_clean != FS_ISCLEAN) {
warnx("Filesystem is not clean, fsck %s first.", devpath);
return (1);
@@ -163,7 +187,8 @@ fsirand(char *device)
: strerror(errno));
return (1);
}
- if (tmpsblock->fs_magic != FS_MAGIC) {
+ if (tmpsblock->fs_magic != FS_UFS1_MAGIC &&
+ tmpsblock->fs_magic != FS_UFS2_MAGIC) {
warnx("Bad magic number in backup superblock %d on %s",
cg + 1, devpath);
return (1);
@@ -176,9 +201,12 @@ fsirand(char *device)
}
/* XXX - should really cap buffer at 512kb or so */
- ibufsize = sizeof(struct ufs1_dinode) * sblock->fs_ipg;
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ ibufsize = sizeof(struct ufs1_dinode) * sblock->fs_ipg;
+ else
+ ibufsize = sizeof(struct ufs2_dinode) * sblock->fs_ipg;
if (oldibufsize < ibufsize) {
- struct ufs1_dinode *ib;
+ char *ib;
if ((ib = realloc(inodebuf, ibufsize)) == NULL)
errx(1, "Can't allocate memory for inode buffer");
@@ -242,12 +270,19 @@ fsirand(char *device)
}
for (n = 0; n < sblock->fs_ipg; n++, inumber++) {
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ dp1 = &((struct ufs1_dinode *)inodebuf)[n];
+ else
+ dp2 = &((struct ufs2_dinode *)inodebuf)[n];
if (inumber >= ROOTINO) {
if (printonly)
(void)printf("ino %d gen %x\n", inumber,
- inodebuf[n].di_gen);
+ sblock->fs_magic == FS_UFS1_MAGIC ?
+ dp1->di_gen : dp2->di_gen);
+ else if (sblock->fs_magic == FS_UFS1_MAGIC)
+ dp1->di_gen = arc4random();
else
- inodebuf[n].di_gen = arc4random();
+ dp2->di_gen = arc4random();
}
}