1 1.26 andvar /* $NetBSD: clri.c,v 1.26 2023/02/26 22:55:02 andvar Exp $ */ 2 1.9 cgd 3 1.1 cgd /* 4 1.6 mycroft * Copyright (c) 1990, 1993 5 1.6 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from software contributed to Berkeley by 8 1.1 cgd * Rich $alz of BBN Inc. 9 1.1 cgd * 10 1.1 cgd * Redistribution and use in source and binary forms, with or without 11 1.1 cgd * modification, are permitted provided that the following conditions 12 1.1 cgd * are met: 13 1.1 cgd * 1. Redistributions of source code must retain the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer. 15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer in the 17 1.1 cgd * documentation and/or other materials provided with the distribution. 18 1.16 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 cgd * may be used to endorse or promote products derived from this software 20 1.1 cgd * without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 cgd * SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.10 lukem #include <sys/cdefs.h> 36 1.1 cgd #ifndef lint 37 1.20 lukem __COPYRIGHT("@(#) Copyright (c) 1990, 1993\ 38 1.20 lukem The Regents of the University of California. All rights reserved."); 39 1.1 cgd #endif /* not lint */ 40 1.1 cgd 41 1.1 cgd #ifndef lint 42 1.9 cgd #if 0 43 1.11 lukem static char sccsid[] = "@(#)clri.c 8.3 (Berkeley) 4/28/95"; 44 1.9 cgd #else 45 1.26 andvar __RCSID("$NetBSD: clri.c,v 1.26 2023/02/26 22:55:02 andvar Exp $"); 46 1.9 cgd #endif 47 1.1 cgd #endif /* not lint */ 48 1.1 cgd 49 1.1 cgd #include <sys/param.h> 50 1.5 cgd #include <sys/time.h> 51 1.6 mycroft 52 1.6 mycroft #include <ufs/ufs/dinode.h> 53 1.12 bouyer #include <ufs/ufs/ufs_bswap.h> 54 1.6 mycroft #include <ufs/ffs/fs.h> 55 1.12 bouyer #include <ufs/ffs/ffs_extern.h> 56 1.6 mycroft 57 1.6 mycroft #include <err.h> 58 1.6 mycroft #include <errno.h> 59 1.6 mycroft #include <fcntl.h> 60 1.6 mycroft #include <stdlib.h> 61 1.6 mycroft #include <string.h> 62 1.6 mycroft #include <stdio.h> 63 1.1 cgd #include <unistd.h> 64 1.1 cgd 65 1.15 fvdl /* 66 1.15 fvdl * Possible superblock locations ordered from most to least likely. 67 1.15 fvdl */ 68 1.15 fvdl static off_t sblock_try[] = SBLOCKSEARCH; 69 1.15 fvdl off_t sblockloc; 70 1.15 fvdl 71 1.15 fvdl 72 1.6 mycroft int 73 1.19 xtraeme main(int argc, char *argv[]) 74 1.1 cgd { 75 1.10 lukem struct fs *sbp; 76 1.15 fvdl struct ufs1_dinode *ip1; 77 1.15 fvdl struct ufs2_dinode *ip2; 78 1.10 lukem int fd; 79 1.22 dholland void *ibuf; 80 1.8 mycroft int32_t generation; 81 1.6 mycroft off_t offset; 82 1.8 mycroft size_t bsize; 83 1.1 cgd int inonum; 84 1.15 fvdl char *fs, sblock[SBLOCKSIZE]; 85 1.15 fvdl int needswap = 0, is_ufs2 = 0; 86 1.12 bouyer int i, imax; 87 1.24 mlelstv long dev_bsize; 88 1.1 cgd 89 1.1 cgd if (argc < 3) { 90 1.1 cgd (void)fprintf(stderr, "usage: clri filesystem inode ...\n"); 91 1.1 cgd exit(1); 92 1.1 cgd } 93 1.1 cgd 94 1.1 cgd fs = *++argv; 95 1.1 cgd 96 1.12 bouyer 97 1.1 cgd /* get the superblock. */ 98 1.1 cgd if ((fd = open(fs, O_RDWR, 0)) < 0) 99 1.6 mycroft err(1, "%s", fs); 100 1.17 dsl for (i = 0;; i++) { 101 1.17 dsl sblockloc = sblock_try[i]; 102 1.17 dsl if (sblockloc == -1) 103 1.17 dsl errx(1, "%s: can't find superblock", fs); 104 1.17 dsl if (pread(fd, sblock, sizeof(sblock), sblockloc) != sizeof(sblock)) 105 1.15 fvdl errx(1, "%s: can't read superblock", fs); 106 1.1 cgd 107 1.15 fvdl sbp = (struct fs *)sblock; 108 1.15 fvdl switch(sbp->fs_magic) { 109 1.15 fvdl case FS_UFS2_MAGIC: 110 1.25 chs case FS_UFS2EA_MAGIC: 111 1.15 fvdl is_ufs2 = 1; 112 1.15 fvdl /*FALLTHROUGH*/ 113 1.15 fvdl case FS_UFS1_MAGIC: 114 1.17 dsl break; 115 1.15 fvdl case FS_UFS2_MAGIC_SWAPPED: 116 1.25 chs case FS_UFS2EA_MAGIC_SWAPPED: 117 1.15 fvdl is_ufs2 = 1; 118 1.15 fvdl /*FALLTHROUGH*/ 119 1.15 fvdl case FS_UFS1_MAGIC_SWAPPED: 120 1.12 bouyer needswap = 1; 121 1.17 dsl break; 122 1.15 fvdl default: 123 1.15 fvdl continue; 124 1.15 fvdl } 125 1.17 dsl 126 1.17 dsl /* check we haven't found an alternate */ 127 1.18 dsl if (is_ufs2 || sbp->fs_old_flags & FS_FLAGS_UPDATED) { 128 1.21 lukem if ((uint64_t)sblockloc != ufs_rw64(sbp->fs_sblockloc, needswap)) 129 1.17 dsl continue; 130 1.17 dsl } else { 131 1.17 dsl if (sblockloc == SBLOCK_UFS2) 132 1.17 dsl continue; 133 1.17 dsl } 134 1.17 dsl 135 1.17 dsl break; 136 1.13 ross } 137 1.12 bouyer 138 1.12 bouyer /* check that inode numbers are valid */ 139 1.12 bouyer imax = ufs_rw32(sbp->fs_ncg, needswap) * 140 1.12 bouyer ufs_rw32(sbp->fs_ipg, needswap); 141 1.12 bouyer for (i = 1; i < (argc - 1); i++) 142 1.12 bouyer if (atoi(argv[i]) <= 0 || atoi(argv[i]) >= imax) 143 1.12 bouyer errx(1, "%s is not a valid inode number", argv[i]); 144 1.12 bouyer 145 1.26 andvar /* delete clean flag in the superblock */ 146 1.17 dsl sbp->fs_clean = ufs_rw32(ufs_rw32(sbp->fs_clean, needswap) << 1, 147 1.17 dsl needswap); 148 1.15 fvdl if (lseek(fd, sblockloc, SEEK_SET) < 0) 149 1.12 bouyer err(1, "%s", fs); 150 1.12 bouyer if (write(fd, sblock, sizeof(sblock)) != sizeof(sblock)) 151 1.12 bouyer errx(1, "%s: can't rewrite superblock", fs); 152 1.12 bouyer (void)fsync(fd); 153 1.12 bouyer 154 1.12 bouyer if (needswap) 155 1.14 lukem ffs_sb_swap(sbp, sbp); 156 1.22 dholland 157 1.24 mlelstv /* compute disk block size from superblock parameters */ 158 1.24 mlelstv dev_bsize = sbp->fs_fsize / FFS_FSBTODB(sbp, 1); 159 1.24 mlelstv 160 1.1 cgd bsize = sbp->fs_bsize; 161 1.22 dholland ibuf = malloc(bsize); 162 1.22 dholland if (ibuf == NULL) { 163 1.22 dholland err(1, "malloc"); 164 1.22 dholland } 165 1.1 cgd 166 1.1 cgd /* remaining arguments are inode numbers. */ 167 1.1 cgd while (*++argv) { 168 1.1 cgd /* get the inode number. */ 169 1.12 bouyer inonum = atoi(*argv); 170 1.1 cgd (void)printf("clearing %d\n", inonum); 171 1.1 cgd 172 1.1 cgd /* read in the appropriate block. */ 173 1.6 mycroft offset = ino_to_fsba(sbp, inonum); /* inode to fs blk */ 174 1.23 dholland offset = FFS_FSBTODB(sbp, offset); /* fs blk disk blk */ 175 1.24 mlelstv offset *= dev_bsize; /* disk blk to bytes */ 176 1.1 cgd 177 1.1 cgd /* seek and read the block */ 178 1.1 cgd if (lseek(fd, offset, SEEK_SET) < 0) 179 1.6 mycroft err(1, "%s", fs); 180 1.21 lukem if ((size_t)read(fd, ibuf, bsize) != bsize) 181 1.6 mycroft err(1, "%s", fs); 182 1.1 cgd 183 1.1 cgd /* get the inode within the block. */ 184 1.15 fvdl if (is_ufs2) { 185 1.15 fvdl ip2 = &((struct ufs2_dinode *)ibuf) 186 1.15 fvdl [ino_to_fsbo(sbp, inonum)]; 187 1.15 fvdl /* clear the inode, and bump the generation count. */ 188 1.15 fvdl generation = ip2->di_gen + 1; 189 1.15 fvdl memset(ip2, 0, sizeof(*ip2)); 190 1.15 fvdl ip2->di_gen = generation; 191 1.15 fvdl } else { 192 1.15 fvdl ip1 = &((struct ufs1_dinode *)ibuf) 193 1.15 fvdl [ino_to_fsbo(sbp, inonum)]; 194 1.15 fvdl /* clear the inode, and bump the generation count. */ 195 1.15 fvdl generation = ip1->di_gen + 1; 196 1.15 fvdl memset(ip1, 0, sizeof(*ip1)); 197 1.15 fvdl ip1->di_gen = generation; 198 1.15 fvdl } 199 1.1 cgd 200 1.1 cgd /* backup and write the block */ 201 1.8 mycroft if (lseek(fd, offset, SEEK_SET) < 0) 202 1.6 mycroft err(1, "%s", fs); 203 1.21 lukem if ((size_t)write(fd, ibuf, bsize) != bsize) 204 1.6 mycroft err(1, "%s", fs); 205 1.1 cgd (void)fsync(fd); 206 1.1 cgd } 207 1.22 dholland free(ibuf); 208 1.1 cgd (void)close(fd); 209 1.1 cgd exit(0); 210 1.1 cgd } 211