diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2007-05-21 18:13:12 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2007-05-21 18:13:12 +0000 |
commit | a4aafbbab023fe1852b260663cef709a5c6627c8 (patch) | |
tree | 97a050b84dd7fd3179c72ed896ab26b21eb6ab1c /sbin | |
parent | cc4b0c9b2b77a29e638c8e8ec7082a854fa4edba (diff) |
Add ffs2 support. Adapted from the ufs2 changes in FreeBSD and NetBSD.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/clri/clri.c | 129 |
1 files changed, 77 insertions, 52 deletions
diff --git a/sbin/clri/clri.c b/sbin/clri/clri.c index ecf51b86a8a..f0a6dbe6f66 100644 --- a/sbin/clri/clri.c +++ b/sbin/clri/clri.c @@ -1,5 +1,5 @@ -/* $OpenBSD: clri.c,v 1.10 2004/01/25 19:18:54 deraadt Exp $ */ -/* $NetBSD: clri.c,v 1.9 1995/03/18 14:54:33 cgd Exp $ */ +/* $OpenBSD: clri.c,v 1.11 2007/05/21 18:13:11 millert Exp $ */ +/* $NetBSD: clri.c,v 1.19 2005/01/20 15:50:47 xtraeme Exp $ */ /* * Copyright (c) 1990, 1993 @@ -33,71 +33,98 @@ * SUCH DAMAGE. */ +#if 0 #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1990, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -#if 0 static char sccsid[] = "@(#)clri.c 8.2 (Berkeley) 9/23/93"; -#else -static char rcsid[] = "$OpenBSD: clri.c,v 1.10 2004/01/25 19:18:54 deraadt Exp $"; -#endif #endif /* not lint */ +#endif #include <sys/param.h> -#include <sys/time.h> #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> #include <err.h> -#include <errno.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <unistd.h> +/* + * Possible superblock locations ordered from most to least likely. + */ +static int sblock_try[] = SBLOCKSEARCH; + +static void +usage(void) +{ + (void)fprintf(stderr, "usage: clri special_device inode_number ...\n"); + exit(1); +} + int main(int argc, char *argv[]) { - struct ufs1_dinode ibuf[MAXBSIZE / sizeof (struct ufs1_dinode)]; - char *fs, sblock[SBSIZE]; - struct ufs1_dinode *ip; + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; struct fs *sbp; - int fd, inonum; - off_t offset; + char *ibuf[MAXBSIZE]; + char *fs, sblock[SBLOCKSIZE]; size_t bsize; + off_t offset; + int i, fd, imax, inonum; - if (argc < 3) { - fprintf(stderr, "usage: clri filesystem inode ...\n"); - return (1); - } + if (argc < 3) + usage(); fs = *++argv; + sbp = NULL; /* get the superblock. */ if ((fd = open(fs, O_RDWR, 0)) < 0) err(1, "%s", fs); - if (lseek(fd, (off_t)(SBLOCK * DEV_BSIZE), SEEK_SET) < 0) - err(1, "%s", fs); - if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock)) - errx(1, "%s: can't read superblock", fs); - - sbp = (struct fs *)sblock; - if (sbp->fs_magic != FS_MAGIC) - errx(1, "%s: superblock magic number 0x%x, not 0x%x", - fs, sbp->fs_magic, FS_MAGIC); + for (i = 0; sblock_try[i] != -1; i++) { + offset = (off_t)(sblock_try[i]); + if (pread(fd, sblock, sizeof(sblock), offset) != sizeof(sblock)) + err(1, "%s: can't read superblock", fs); + sbp = (struct fs *)sblock; + if ((sbp->fs_magic == FS_UFS1_MAGIC || + (sbp->fs_magic == FS_UFS2_MAGIC && + sbp->fs_sblockloc == sblock_try[i])) && + sbp->fs_bsize <= MAXBSIZE && + sbp->fs_bsize >= (int)sizeof(struct fs)) + break; + } + if (sblock_try[i] == -1) + errx(2, "cannot find file system superblock"); bsize = sbp->fs_bsize; + /* check that inode numbers are valid */ + imax = sbp->fs_ncg * sbp->fs_ipg; + for (i = 1; i < (argc - 1); i++) { + if (atoi(argv[i]) <= 0 || atoi(argv[i]) >= imax) + errx(1, "%s is not a valid inode number", argv[i]); + } + + /* clear the clean flag in the superblock */ + if (sbp->fs_inodefmt >= FS_44INODEFMT) { + sbp->fs_clean = 0; + if (pwrite(fd, sblock, sizeof(sblock), offset) != sizeof(sblock)) + err(1, "%s: can't update superblock", fs); + (void)fsync(fd); + } + /* remaining arguments are inode numbers. */ while (*++argv) { /* get the inode number. */ - if ((inonum = atoi(*argv)) <= 0) - errx(1, "%s is not a valid inode number", *argv); + inonum = atoi(*argv); (void)printf("clearing %d\n", inonum); /* read in the appropriate block. */ @@ -106,34 +133,32 @@ main(int argc, char *argv[]) offset *= DEV_BSIZE; /* disk blk to bytes */ /* seek and read the block */ - if (lseek(fd, offset, SEEK_SET) < 0) + if (pread(fd, ibuf, bsize, offset) != bsize) err(1, "%s", fs); - if (read(fd, ibuf, bsize) != bsize) - err(1, "%s", fs); - - /* get the inode within the block. */ - ip = &ibuf[ino_to_fsbo(sbp, inonum)]; - /* clear the inode, and bump the generation count. */ - memset(ip, 0, sizeof(*ip)); - ip->di_gen = arc4random(); + if (sbp->fs_magic == FS_UFS2_MAGIC) { + /* get the inode within the block. */ + dp2 = &(((struct ufs2_dinode *)ibuf) + [ino_to_fsbo(sbp, inonum)]); + + /* clear the inode, and bump the generation count. */ + memset(dp2, 0, sizeof(*dp2)); + dp2->di_gen = arc4random(); + } else { + /* get the inode within the block. */ + dp1 = &(((struct ufs1_dinode *)ibuf) + [ino_to_fsbo(sbp, inonum)]); + + /* clear the inode, and bump the generation count. */ + memset(dp1, 0, sizeof(*dp1)); + dp1->di_gen = arc4random(); + } /* backup and write the block */ - if (lseek(fd, offset, SEEK_SET) < 0) - err(1, "%s", fs); - if (write(fd, ibuf, bsize) != bsize) + if (pwrite(fd, ibuf, bsize, offset) != bsize) err(1, "%s", fs); (void)fsync(fd); - - if (sbp->fs_inodefmt >= FS_44INODEFMT) { - /* update after each inode cleared */ - sbp->fs_clean = 0; - if (lseek(fd, (off_t)(SBLOCK * DEV_BSIZE), SEEK_SET) < 0) - err(1, "%s", fs); - if (write(fd, sblock, sizeof(sblock)) != sizeof(sblock)) - errx(1, "%s: can't update superblock", fs); - } } - - return close(fd); + (void)close(fd); + exit(0); } |