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 == MTB_UFS_MAGIC && 106 (sblock.fs_version > MTB_UFS_VERSION_1 || 107 sblock.fs_version < MTB_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 fs is logged, roll the log. */ 115 if (sblock.fs_logbno) { 116 switch (rl_roll_log(argv[1])) { 117 case RL_SUCCESS: 118 /* 119 * Reread the superblock. Rolling the log may have 120 * changed it. 121 */ 122 if ((sbrr = read_sb(f, argv[1])) != 0) { 123 return (sbrr); 124 } 125 break; 126 case RL_SYSERR: 127 (void) printf("Warning: Cannot roll log for %s. %s. " 128 "Inodes will be cleared anyway.\n", 129 argv[1], strerror(errno)); 130 break; 131 default: 132 (void) printf("Cannot roll log for %s. " 133 "Inodes will be cleared anyway.\n", 134 argv[1]); 135 break; 136 } 137 } 138 139 for (i = 2; i < argc; i++) { 140 if (!isnumber(argv[i])) { 141 (void) printf("%s: is not a number\n", argv[i]); 142 status = 1; 143 continue; 144 } 145 n = atoi(argv[i]); 146 if (n == 0) { 147 (void) printf("%s: is zero\n", argv[i]); 148 status = 1; 149 continue; 150 } 151 off = fsbtodb(&sblock, itod(&sblock, n)); 152 off *= DEV_BSIZE; 153 (void) llseek(f, off, 0); 154 if (read(f, (char *)buf, sblock.fs_bsize) != sblock.fs_bsize) { 155 (void) printf("%s: read error\n", argv[i]); 156 status = 1; 157 } 158 } 159 if (status) 160 return (status+31); 161 162 /* 163 * Update the time in superblock, so fsck will check this filesystem. 164 */ 165 (void) llseek(f, (offset_t)(SBLOCK * DEV_BSIZE), 0); 166 (void) time(&t); 167 sblock.fs_time = (time32_t)t; 168 if (write(f, &sblock, SBSIZE) != SBSIZE) { 169 (void) printf("cannot update %s\n", argv[1]); 170 return (35); 171 } 172 173 for (i = 2; i < argc; i++) { 174 n = atoi(argv[i]); 175 (void) printf("clearing %u\n", n); 176 off = fsbtodb(&sblock, itod(&sblock, n)); 177 off *= DEV_BSIZE; 178 (void) llseek(f, off, 0); 179 (void) read(f, (char *)buf, sblock.fs_bsize); 180 j = itoo(&sblock, n); 181 gen = buf[j].di_gen; 182 memset(&buf[j], 0, ISIZE); 183 buf[j].di_gen = gen + 1; 184 (void) llseek(f, off, 0); 185 (void) write(f, (char *)buf, sblock.fs_bsize); 186 } 187 if (status) 188 return (status+31); 189 (void) close(f); 190 return (0); 191 } 192 193 static int 194 isnumber(const char *s) 195 { 196 int c; 197 198 while ((c = *s++) != '\0') 199 if (c < '0' || c > '9') 200 return (0); 201 return (1); 202 } 203 204 static int 205 read_sb(int fd, const char *dev) 206 { 207 (void) llseek(fd, (offset_t)(SBLOCK * DEV_BSIZE), 0); 208 if (read(fd, &sblock, SBSIZE) != SBSIZE) { 209 (void) printf("cannot read %s\n", dev); 210 return (35); 211 } else { 212 return (0); 213 } 214 } 215