xref: /illumos-gate/usr/src/cmd/fs.d/ufs/clri/clri.c (revision 68d61a2a)
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