clri.c revision 102431
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1990, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * This code is derived from software contributed to Berkeley by 61558Srgrimes * Rich $alz of BBN Inc. 71558Srgrimes * 81558Srgrimes * Redistribution and use in source and binary forms, with or without 91558Srgrimes * modification, are permitted provided that the following conditions 101558Srgrimes * are met: 111558Srgrimes * 1. Redistributions of source code must retain the above copyright 121558Srgrimes * notice, this list of conditions and the following disclaimer. 131558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141558Srgrimes * notice, this list of conditions and the following disclaimer in the 151558Srgrimes * documentation and/or other materials provided with the distribution. 161558Srgrimes * 3. All advertising materials mentioning features or use of this software 171558Srgrimes * must display the following acknowledgement: 181558Srgrimes * This product includes software developed by the University of 191558Srgrimes * California, Berkeley and its contributors. 201558Srgrimes * 4. Neither the name of the University nor the names of its contributors 211558Srgrimes * may be used to endorse or promote products derived from this software 221558Srgrimes * without specific prior written permission. 231558Srgrimes * 241558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341558Srgrimes * SUCH DAMAGE. 351558Srgrimes */ 361558Srgrimes 371558Srgrimes#ifndef lint 3836630Scharnierstatic const char copyright[] = 391558Srgrimes"@(#) Copyright (c) 1990, 1993\n\ 401558Srgrimes The Regents of the University of California. All rights reserved.\n"; 411558Srgrimes#endif /* not lint */ 421558Srgrimes 431558Srgrimes#ifndef lint 4436630Scharnier#if 0 451558Srgrimesstatic char sccsid[] = "@(#)clri.c 8.2 (Berkeley) 9/23/93"; 4636630Scharnier#endif 471558Srgrimes#endif /* not lint */ 481558Srgrimes 4999364Smarkm#include <sys/cdefs.h> 5099364Smarkm__FBSDID("$FreeBSD: head/sbin/clri/clri.c 102431 2002-08-26 03:56:23Z trhodes $"); 5199364Smarkm 521558Srgrimes#include <sys/param.h> 5396478Sphk#include <sys/disklabel.h> 541558Srgrimes 551558Srgrimes#include <ufs/ufs/dinode.h> 561558Srgrimes#include <ufs/ffs/fs.h> 571558Srgrimes 581558Srgrimes#include <err.h> 591558Srgrimes#include <fcntl.h> 601558Srgrimes#include <stdlib.h> 611558Srgrimes#include <string.h> 621558Srgrimes#include <stdio.h> 631558Srgrimes#include <unistd.h> 641558Srgrimes 6598542Smckusick/* 6698542Smckusick * Possible superblock locations ordered from most to least likely. 6798542Smckusick */ 6898542Smckusickstatic int sblock_try[] = SBLOCKSEARCH; 6998542Smckusick 7036630Scharnierstatic void 7136630Scharnierusage(void) 7236630Scharnier{ 73102431Strhodes (void)fprintf(stderr, "usage: clri special_device inode_number ...\n"); 7436630Scharnier exit(1); 7536630Scharnier} 7636630Scharnier 771558Srgrimesint 7899364Smarkmmain(int argc, char *argv[]) 791558Srgrimes{ 8092753Simp struct fs *sbp; 8198542Smckusick struct ufs1_dinode *dp1; 8298542Smckusick struct ufs2_dinode *dp2; 8398542Smckusick char *ibuf[MAXBSIZE]; 841558Srgrimes long generation, bsize; 851558Srgrimes off_t offset; 8698542Smckusick int i, fd, inonum; 8798542Smckusick char *fs, sblock[SBLOCKSIZE]; 881558Srgrimes 8936630Scharnier if (argc < 3) 9036630Scharnier usage(); 911558Srgrimes 921558Srgrimes fs = *++argv; 931558Srgrimes 941558Srgrimes /* get the superblock. */ 951558Srgrimes if ((fd = open(fs, O_RDWR, 0)) < 0) 961558Srgrimes err(1, "%s", fs); 9798542Smckusick for (i = 0; sblock_try[i] != -1; i++) { 9898542Smckusick if (lseek(fd, (off_t)(sblock_try[i]), SEEK_SET) < 0) 9998542Smckusick err(1, "%s", fs); 10098542Smckusick if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock)) 10198542Smckusick errx(1, "%s: can't read superblock", fs); 10298542Smckusick sbp = (struct fs *)sblock; 10398542Smckusick if ((sbp->fs_magic == FS_UFS1_MAGIC || 10498542Smckusick (sbp->fs_magic == FS_UFS2_MAGIC && 10598542Smckusick sbp->fs_sblockloc == numfrags(sbp, sblock_try[i]))) && 10698542Smckusick sbp->fs_bsize <= MAXBSIZE && 10799364Smarkm sbp->fs_bsize >= (int)sizeof(struct fs)) 10898542Smckusick break; 10998542Smckusick } 11098542Smckusick if (sblock_try[i] == -1) { 111102431Strhodes fprintf(stderr, "Cannot find special_device\n"); 11298542Smckusick exit(2); 11398542Smckusick } 1141558Srgrimes bsize = sbp->fs_bsize; 1151558Srgrimes 1161558Srgrimes /* remaining arguments are inode numbers. */ 1171558Srgrimes while (*++argv) { 1181558Srgrimes /* get the inode number. */ 11926438Scharnier if ((inonum = atoi(*argv)) <= 0) 12036630Scharnier errx(1, "%s is not a valid inode number", *argv); 1211558Srgrimes (void)printf("clearing %d\n", inonum); 1221558Srgrimes 1231558Srgrimes /* read in the appropriate block. */ 1241558Srgrimes offset = ino_to_fsba(sbp, inonum); /* inode to fs blk */ 1251558Srgrimes offset = fsbtodb(sbp, offset); /* fs blk disk blk */ 1261558Srgrimes offset *= DEV_BSIZE; /* disk blk to bytes */ 1271558Srgrimes 1281558Srgrimes /* seek and read the block */ 1291558Srgrimes if (lseek(fd, offset, SEEK_SET) < 0) 1301558Srgrimes err(1, "%s", fs); 1311558Srgrimes if (read(fd, ibuf, bsize) != bsize) 1321558Srgrimes err(1, "%s", fs); 1331558Srgrimes 13498542Smckusick if (sbp->fs_magic == FS_UFS2_MAGIC) { 13598542Smckusick /* get the inode within the block. */ 13698542Smckusick dp2 = &(((struct ufs2_dinode *)ibuf) 13798542Smckusick [ino_to_fsbo(sbp, inonum)]); 1381558Srgrimes 13998542Smckusick /* clear the inode, and bump the generation count. */ 14098542Smckusick generation = dp2->di_gen + 1; 14198542Smckusick memset(dp2, 0, sizeof(*dp2)); 14298542Smckusick dp2->di_gen = generation; 14398542Smckusick } else { 14498542Smckusick /* get the inode within the block. */ 14598542Smckusick dp1 = &(((struct ufs1_dinode *)ibuf) 14698542Smckusick [ino_to_fsbo(sbp, inonum)]); 1471558Srgrimes 14898542Smckusick /* clear the inode, and bump the generation count. */ 14998542Smckusick generation = dp1->di_gen + 1; 15098542Smckusick memset(dp1, 0, sizeof(*dp1)); 15198542Smckusick dp1->di_gen = generation; 15298542Smckusick } 15398542Smckusick 1541558Srgrimes /* backup and write the block */ 1551558Srgrimes if (lseek(fd, (off_t)-bsize, SEEK_CUR) < 0) 1561558Srgrimes err(1, "%s", fs); 1571558Srgrimes if (write(fd, ibuf, bsize) != bsize) 1581558Srgrimes err(1, "%s", fs); 1591558Srgrimes (void)fsync(fd); 1601558Srgrimes } 1611558Srgrimes (void)close(fd); 1621558Srgrimes exit(0); 1631558Srgrimes} 164