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 /* 36 * clri filsys inumber ... 37 */ 38 39 #include <unistd.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <string.h> 45 46 #include <sys/param.h> 47 #include <sys/types.h> 48 #include <sys/mntent.h> 49 50 #include <sys/vnode.h> 51 #include <sys/fs/ufs_inode.h> 52 #include <sys/fs/ufs_fs.h> 53 54 #include "roll_log.h" 55 56 #define ISIZE (sizeof (struct dinode)) 57 #define NI (MAXBSIZE/ISIZE) 58 59 static struct dinode buf[NI]; 60 61 static union { 62 char dummy[SBSIZE]; 63 struct fs sblk; 64 } sb_un; 65 #define sblock sb_un.sblk 66 67 static int status; 68 69 static int read_sb(int fd, const char *dev); 70 static int isnumber(const char *s); 71 72 int 73 main(int argc, char *argv[]) 74 { 75 int i, f; 76 unsigned int n; 77 int j; 78 offset_t off; 79 int32_t gen; 80 time_t t; 81 int sbrr; 82 83 if (argc < 3) { 84 (void) printf("ufs usage: clri filsys inumber ...\n"); 85 return (35); 86 } 87 f = open64(argv[1], 2); 88 if (f < 0) { 89 (void) printf("cannot open %s\n", argv[1]); 90 return (35); 91 } 92 93 if ((sbrr = read_sb(f, argv[1])) != 0) { 94 return (sbrr); 95 } 96 97 if ((sblock.fs_magic != FS_MAGIC) && 98 (sblock.fs_magic != MTB_UFS_MAGIC)) { 99 (void) printf("bad super block magic number\n"); 100 return (35); 101 } 102 103 if (sblock.fs_magic == FS_MAGIC && 104 (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 105 sblock.fs_version != UFS_VERSION_MIN)) { 106 (void) printf( 107 "unrecognized version of UFS on-disk format: %d\n", 108 sblock.fs_version); 109 return (35); 110 } 111 112 if (sblock.fs_magic == MTB_UFS_MAGIC && 113 (sblock.fs_version > MTB_UFS_VERSION_1 || 114 sblock.fs_version < MTB_UFS_VERSION_MIN)) { 115 (void) printf( 116 "unrecognized version of UFS on-disk format: %d\n", 117 sblock.fs_version); 118 return (35); 119 } 120 121 /* If fs is logged, roll the log. */ 122 if (sblock.fs_logbno) { 123 switch (rl_roll_log(argv[1])) { 124 case RL_SUCCESS: 125 /* 126 * Reread the superblock. Rolling the log may have 127 * changed it. 128 */ 129 if ((sbrr = read_sb(f, argv[1])) != 0) { 130 return (sbrr); 131 } 132 break; 133 case RL_SYSERR: 134 (void) printf("Warning: Cannot roll log for %s. %s. " 135 "Inodes will be cleared anyway.\n", 136 argv[1], strerror(errno)); 137 break; 138 default: 139 (void) printf("Cannot roll log for %s. " 140 "Inodes will be cleared anyway.\n", 141 argv[1]); 142 break; 143 } 144 } 145 146 for (i = 2; i < argc; i++) { 147 if (!isnumber(argv[i])) { 148 (void) printf("%s: is not a number\n", argv[i]); 149 status = 1; 150 continue; 151 } 152 n = atoi(argv[i]); 153 if (n == 0) { 154 (void) printf("%s: is zero\n", argv[i]); 155 status = 1; 156 continue; 157 } 158 off = fsbtodb(&sblock, itod(&sblock, n)); 159 off *= DEV_BSIZE; 160 (void) llseek(f, off, 0); 161 if (read(f, (char *)buf, sblock.fs_bsize) != sblock.fs_bsize) { 162 (void) printf("%s: read error\n", argv[i]); 163 status = 1; 164 } 165 } 166 if (status) 167 return (status+31); 168 169 /* 170 * Update the time in superblock, so fsck will check this filesystem. 171 */ 172 (void) llseek(f, (offset_t)(SBLOCK * DEV_BSIZE), 0); 173 (void) time(&t); 174 sblock.fs_time = (time32_t)t; 175 if (write(f, &sblock, SBSIZE) != SBSIZE) { 176 (void) printf("cannot update %s\n", argv[1]); 177 return (35); 178 } 179 180 for (i = 2; i < argc; i++) { 181 n = atoi(argv[i]); 182 (void) printf("clearing %u\n", n); 183 off = fsbtodb(&sblock, itod(&sblock, n)); 184 off *= DEV_BSIZE; 185 (void) llseek(f, off, 0); 186 (void) read(f, (char *)buf, sblock.fs_bsize); 187 j = itoo(&sblock, n); 188 gen = buf[j].di_gen; 189 memset(&buf[j], 0, ISIZE); 190 buf[j].di_gen = gen + 1; 191 (void) llseek(f, off, 0); 192 (void) write(f, (char *)buf, sblock.fs_bsize); 193 } 194 if (status) 195 return (status+31); 196 (void) close(f); 197 return (0); 198 } 199 200 static int 201 isnumber(const char *s) 202 { 203 int c; 204 205 while ((c = *s++) != '\0') 206 if (c < '0' || c > '9') 207 return (0); 208 return (1); 209 } 210 211 static int 212 read_sb(int fd, const char *dev) 213 { 214 (void) llseek(fd, (offset_t)(SBLOCK * DEV_BSIZE), 0); 215 if (read(fd, &sblock, SBSIZE) != SBSIZE) { 216 (void) printf("cannot read %s\n", dev); 217 return (35); 218 } else { 219 return (0); 220 } 221 } 222