1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * clri filsys inumber ... 39 */ 40 41 #include <unistd.h> 42 #include <stdlib.h> 43 #include <stdio.h> 44 #include <errno.h> 45 #include <fcntl.h> 46 #include <string.h> 47 48 #include <sys/param.h> 49 #include <sys/types.h> 50 #include <sys/mntent.h> 51 52 #include <sys/vnode.h> 53 #include <sys/fs/ufs_inode.h> 54 #include <sys/fs/ufs_fs.h> 55 56 #include "roll_log.h" 57 58 #define ISIZE (sizeof (struct dinode)) 59 #define NI (MAXBSIZE/ISIZE) 60 61 static struct dinode buf[NI]; 62 63 static union { 64 char dummy[SBSIZE]; 65 struct fs sblk; 66 } sb_un; 67 #define sblock sb_un.sblk 68 69 static int status; 70 71 static int read_sb(int fd, const char *dev); 72 static int isnumber(const char *s); 73 74 int 75 main(int argc, char *argv[]) 76 { 77 int i, f; 78 unsigned int n; 79 int j; 80 offset_t off; 81 int32_t gen; 82 time_t t; 83 int sbrr; 84 85 if (argc < 3) { 86 (void) printf("ufs usage: clri filsys inumber ...\n"); 87 return (35); 88 } 89 f = open64(argv[1], 2); 90 if (f < 0) { 91 (void) printf("cannot open %s\n", argv[1]); 92 return (35); 93 } 94 95 if ((sbrr = read_sb(f, argv[1])) != 0) { 96 return (sbrr); 97 } 98 99 if ((sblock.fs_magic != FS_MAGIC) && 100 (sblock.fs_magic != MTB_UFS_MAGIC)) { 101 (void) printf("bad super block magic number\n"); 102 return (35); 103 } 104 105 if (sblock.fs_magic == FS_MAGIC && 106 (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 107 sblock.fs_version != UFS_VERSION_MIN)) { 108 (void) printf( 109 "unrecognized version of UFS on-disk format: %d\n", 110 sblock.fs_version); 111 return (35); 112 } 113 114 if (sblock.fs_magic == MTB_UFS_MAGIC && 115 (sblock.fs_version > MTB_UFS_VERSION_1 || 116 sblock.fs_version < MTB_UFS_VERSION_MIN)) { 117 (void) printf( 118 "unrecognized version of UFS on-disk format: %d\n", 119 sblock.fs_version); 120 return (35); 121 } 122 123 /* If fs is logged, roll the log. */ 124 if (sblock.fs_logbno) { 125 switch (rl_roll_log(argv[1])) { 126 case RL_SUCCESS: 127 /* 128 * Reread the superblock. Rolling the log may have 129 * changed it. 130 */ 131 if ((sbrr = read_sb(f, argv[1])) != 0) { 132 return (sbrr); 133 } 134 break; 135 case RL_SYSERR: 136 (void) printf("Warning: Cannot roll log for %s. %s. " 137 "Inodes will be cleared anyway.\n", 138 argv[1], strerror(errno)); 139 break; 140 default: 141 (void) printf("Cannot roll log for %s. " 142 "Inodes will be cleared anyway.\n", 143 argv[1]); 144 break; 145 } 146 } 147 148 for (i = 2; i < argc; i++) { 149 if (!isnumber(argv[i])) { 150 (void) printf("%s: is not a number\n", argv[i]); 151 status = 1; 152 continue; 153 } 154 n = atoi(argv[i]); 155 if (n == 0) { 156 (void) printf("%s: is zero\n", argv[i]); 157 status = 1; 158 continue; 159 } 160 off = fsbtodb(&sblock, itod(&sblock, n)); 161 off *= DEV_BSIZE; 162 (void) llseek(f, off, 0); 163 if (read(f, (char *)buf, sblock.fs_bsize) != sblock.fs_bsize) { 164 (void) printf("%s: read error\n", argv[i]); 165 status = 1; 166 } 167 } 168 if (status) 169 return (status+31); 170 171 /* 172 * Update the time in superblock, so fsck will check this filesystem. 173 */ 174 (void) llseek(f, (offset_t)(SBLOCK * DEV_BSIZE), 0); 175 (void) time(&t); 176 sblock.fs_time = (time32_t)t; 177 if (write(f, &sblock, SBSIZE) != SBSIZE) { 178 (void) printf("cannot update %s\n", argv[1]); 179 return (35); 180 } 181 182 for (i = 2; i < argc; i++) { 183 n = atoi(argv[i]); 184 (void) printf("clearing %u\n", n); 185 off = fsbtodb(&sblock, itod(&sblock, n)); 186 off *= DEV_BSIZE; 187 (void) llseek(f, off, 0); 188 (void) read(f, (char *)buf, sblock.fs_bsize); 189 j = itoo(&sblock, n); 190 gen = buf[j].di_gen; 191 memset(&buf[j], 0, ISIZE); 192 buf[j].di_gen = gen + 1; 193 (void) llseek(f, off, 0); 194 (void) write(f, (char *)buf, sblock.fs_bsize); 195 } 196 if (status) 197 return (status+31); 198 (void) close(f); 199 return (0); 200 } 201 202 static int 203 isnumber(const char *s) 204 { 205 int c; 206 207 while ((c = *s++) != '\0') 208 if (c < '0' || c > '9') 209 return (0); 210 return (1); 211 } 212 213 static int 214 read_sb(int fd, const char *dev) 215 { 216 (void) llseek(fd, (offset_t)(SBLOCK * DEV_BSIZE), 0); 217 if (read(fd, &sblock, SBSIZE) != SBSIZE) { 218 (void) printf("cannot read %s\n", dev); 219 return (35); 220 } else { 221 return (0); 222 } 223 } 224