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 * 4. Neither the name of the University nor the names of its contributors 171558Srgrimes * may be used to endorse or promote products derived from this software 181558Srgrimes * without specific prior written permission. 191558Srgrimes * 201558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301558Srgrimes * SUCH DAMAGE. 311558Srgrimes */ 321558Srgrimes 33114589Sobrien#if 0 341558Srgrimes#ifndef lint 3536630Scharnierstatic const char copyright[] = 361558Srgrimes"@(#) Copyright (c) 1990, 1993\n\ 371558Srgrimes The Regents of the University of California. All rights reserved.\n"; 381558Srgrimes#endif /* not lint */ 391558Srgrimes 401558Srgrimes#ifndef lint 411558Srgrimesstatic char sccsid[] = "@(#)clri.c 8.2 (Berkeley) 9/23/93"; 42114589Sobrien#endif /* not lint */ 4336630Scharnier#endif 44146757Scharnier 4599364Smarkm#include <sys/cdefs.h> 4699364Smarkm__FBSDID("$FreeBSD$"); 4799364Smarkm 481558Srgrimes#include <sys/param.h> 4996478Sphk#include <sys/disklabel.h> 501558Srgrimes 511558Srgrimes#include <ufs/ufs/dinode.h> 521558Srgrimes#include <ufs/ffs/fs.h> 531558Srgrimes 541558Srgrimes#include <err.h> 551558Srgrimes#include <fcntl.h> 561558Srgrimes#include <stdlib.h> 571558Srgrimes#include <string.h> 581558Srgrimes#include <stdio.h> 591558Srgrimes#include <unistd.h> 601558Srgrimes 6198542Smckusick/* 6298542Smckusick * Possible superblock locations ordered from most to least likely. 6398542Smckusick */ 6498542Smckusickstatic int sblock_try[] = SBLOCKSEARCH; 6598542Smckusick 6636630Scharnierstatic void 6736630Scharnierusage(void) 6836630Scharnier{ 69102431Strhodes (void)fprintf(stderr, "usage: clri special_device inode_number ...\n"); 7036630Scharnier exit(1); 7136630Scharnier} 7236630Scharnier 731558Srgrimesint 7499364Smarkmmain(int argc, char *argv[]) 751558Srgrimes{ 7692753Simp struct fs *sbp; 7798542Smckusick struct ufs1_dinode *dp1; 7898542Smckusick struct ufs2_dinode *dp2; 7998542Smckusick char *ibuf[MAXBSIZE]; 801558Srgrimes long generation, bsize; 811558Srgrimes off_t offset; 8298542Smckusick int i, fd, inonum; 8398542Smckusick char *fs, sblock[SBLOCKSIZE]; 84173764Sjb void *v = ibuf; 851558Srgrimes 8636630Scharnier if (argc < 3) 8736630Scharnier usage(); 881558Srgrimes 891558Srgrimes fs = *++argv; 90146757Scharnier sbp = NULL; 911558Srgrimes 921558Srgrimes /* get the superblock. */ 931558Srgrimes if ((fd = open(fs, O_RDWR, 0)) < 0) 941558Srgrimes err(1, "%s", fs); 9598542Smckusick for (i = 0; sblock_try[i] != -1; i++) { 9698542Smckusick if (lseek(fd, (off_t)(sblock_try[i]), SEEK_SET) < 0) 9798542Smckusick err(1, "%s", fs); 9898542Smckusick if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock)) 9998542Smckusick errx(1, "%s: can't read superblock", fs); 10098542Smckusick sbp = (struct fs *)sblock; 10198542Smckusick if ((sbp->fs_magic == FS_UFS1_MAGIC || 10298542Smckusick (sbp->fs_magic == FS_UFS2_MAGIC && 103107294Smckusick sbp->fs_sblockloc == sblock_try[i])) && 10498542Smckusick sbp->fs_bsize <= MAXBSIZE && 10599364Smarkm sbp->fs_bsize >= (int)sizeof(struct fs)) 10698542Smckusick break; 10798542Smckusick } 108146757Scharnier if (sblock_try[i] == -1) 109146757Scharnier errx(2, "cannot find file system superblock"); 1101558Srgrimes bsize = sbp->fs_bsize; 1111558Srgrimes 1121558Srgrimes /* remaining arguments are inode numbers. */ 1131558Srgrimes while (*++argv) { 1141558Srgrimes /* get the inode number. */ 11526438Scharnier if ((inonum = atoi(*argv)) <= 0) 11636630Scharnier errx(1, "%s is not a valid inode number", *argv); 1171558Srgrimes (void)printf("clearing %d\n", inonum); 1181558Srgrimes 1191558Srgrimes /* read in the appropriate block. */ 1201558Srgrimes offset = ino_to_fsba(sbp, inonum); /* inode to fs blk */ 1211558Srgrimes offset = fsbtodb(sbp, offset); /* fs blk disk blk */ 1221558Srgrimes offset *= DEV_BSIZE; /* disk blk to bytes */ 1231558Srgrimes 1241558Srgrimes /* seek and read the block */ 1251558Srgrimes if (lseek(fd, offset, SEEK_SET) < 0) 1261558Srgrimes err(1, "%s", fs); 1271558Srgrimes if (read(fd, ibuf, bsize) != bsize) 1281558Srgrimes err(1, "%s", fs); 1291558Srgrimes 13098542Smckusick if (sbp->fs_magic == FS_UFS2_MAGIC) { 13198542Smckusick /* get the inode within the block. */ 132173764Sjb dp2 = &(((struct ufs2_dinode *)v) 13398542Smckusick [ino_to_fsbo(sbp, inonum)]); 1341558Srgrimes 13598542Smckusick /* clear the inode, and bump the generation count. */ 13698542Smckusick generation = dp2->di_gen + 1; 13798542Smckusick memset(dp2, 0, sizeof(*dp2)); 13898542Smckusick dp2->di_gen = generation; 13998542Smckusick } else { 14098542Smckusick /* get the inode within the block. */ 141173764Sjb dp1 = &(((struct ufs1_dinode *)v) 14298542Smckusick [ino_to_fsbo(sbp, inonum)]); 1431558Srgrimes 14498542Smckusick /* clear the inode, and bump the generation count. */ 14598542Smckusick generation = dp1->di_gen + 1; 14698542Smckusick memset(dp1, 0, sizeof(*dp1)); 14798542Smckusick dp1->di_gen = generation; 14898542Smckusick } 14998542Smckusick 1501558Srgrimes /* backup and write the block */ 1511558Srgrimes if (lseek(fd, (off_t)-bsize, SEEK_CUR) < 0) 1521558Srgrimes err(1, "%s", fs); 1531558Srgrimes if (write(fd, ibuf, bsize) != bsize) 1541558Srgrimes err(1, "%s", fs); 1551558Srgrimes (void)fsync(fd); 1561558Srgrimes } 1571558Srgrimes (void)close(fd); 1581558Srgrimes exit(0); 1591558Srgrimes} 160