badsect.c revision 1.10
1/*	$NetBSD: badsect.c,v 1.10 1995/03/18 14:54:28 cgd Exp $	*/
2
3/*
4 * Copyright (c) 1981, 1983, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the University of
18 *	California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37static char copyright[] =
38"@(#) Copyright (c) 1981, 1983, 1993\n\
39	The Regents of the University of California.  All rights reserved.\n";
40#endif /* not lint */
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)badsect.c	8.1 (Berkeley) 6/5/93";
45#else
46static char rcsid[] = "$NetBSD: badsect.c,v 1.10 1995/03/18 14:54:28 cgd Exp $";
47#endif
48#endif /* not lint */
49
50/*
51 * badsect
52 *
53 * Badsect takes a list of file-system relative sector numbers
54 * and makes files containing the blocks of which these sectors are a part.
55 * It can be used to contain sectors which have problems if these sectors
56 * are not part of the bad file for the pack (see bad144).  For instance,
57 * this program can be used if the driver for the file system in question
58 * does not support bad block forwarding.
59 */
60#include <sys/param.h>
61#include <sys/dir.h>
62#include <sys/stat.h>
63
64#include <ufs/ffs/fs.h>
65#include <ufs/ufs/dinode.h>
66
67#include <fcntl.h>
68#include <paths.h>
69#include <stdio.h>
70#include <stdlib.h>
71#include <string.h>
72#include <unistd.h>
73
74union {
75	struct	fs fs;
76	char	fsx[SBSIZE];
77} ufs;
78#define sblock	ufs.fs
79union {
80	struct	cg cg;
81	char	cgx[MAXBSIZE];
82} ucg;
83#define	acg	ucg.cg
84struct	fs *fs;
85int	fso, fsi;
86int	errs;
87long	dev_bsize = 1;
88
89char buf[MAXBSIZE];
90
91void	rdfs __P((daddr_t, int, char *));
92int	chkuse __P((daddr_t, int));
93
94int
95main(argc, argv)
96	int argc;
97	char *argv[];
98{
99	daddr_t number;
100	struct stat stbuf, devstat;
101	register struct direct *dp;
102	DIR *dirp;
103	char name[BUFSIZ];
104
105	if (argc < 3) {
106		fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n");
107		exit(1);
108	}
109	if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) {
110		perror(argv[1]);
111		exit(2);
112	}
113	strcpy(name, _PATH_DEV);
114	if ((dirp = opendir(name)) == NULL) {
115		perror(name);
116		exit(3);
117	}
118	while ((dp = readdir(dirp)) != NULL) {
119		strcpy(&name[5], dp->d_name);
120		if (stat(name, &devstat) < 0) {
121			perror(name);
122			exit(4);
123		}
124		if (stbuf.st_dev == devstat.st_rdev &&
125		    S_ISBLK(devstat.st_mode))
126			break;
127	}
128	closedir(dirp);
129	if (dp == NULL) {
130		printf("Cannot find dev 0%o corresponding to %s\n",
131			stbuf.st_rdev, argv[1]);
132		exit(5);
133	}
134	if ((fsi = open(name, 0)) < 0) {
135		perror(name);
136		exit(6);
137	}
138	fs = &sblock;
139	rdfs(SBOFF, SBSIZE, (char *)fs);
140	dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
141	for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
142		number = atoi(*argv);
143		if (chkuse(number, 1))
144			continue;
145		if (mknod(*argv, S_IFMT|S_IRUSR|S_IWUSR,
146		    dbtofsb(fs, number)) < 0) {
147			perror(*argv);
148			errs++;
149		}
150	}
151	printf("Don't forget to run ``fsck %s''\n", name);
152	exit(errs);
153}
154
155int
156chkuse(blkno, cnt)
157	daddr_t blkno;
158	int cnt;
159{
160	int cg;
161	daddr_t fsbn, bn;
162
163	fsbn = dbtofsb(fs, blkno);
164	if ((unsigned)(fsbn+cnt) > fs->fs_size) {
165		printf("block %d out of range of file system\n", blkno);
166		return (1);
167	}
168	cg = dtog(fs, fsbn);
169	if (fsbn < cgdmin(fs, cg)) {
170		if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) {
171			printf("block %d in non-data area: cannot attach\n",
172				blkno);
173			return (1);
174		}
175	} else {
176		if ((fsbn+cnt) > cgbase(fs, cg+1)) {
177			printf("block %d in non-data area: cannot attach\n",
178				blkno);
179			return (1);
180		}
181	}
182	rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize,
183	    (char *)&acg);
184	if (!cg_chkmagic(&acg)) {
185		fprintf(stderr, "cg %d: bad magic number\n", cg);
186		errs++;
187		return (1);
188	}
189	bn = dtogd(fs, fsbn);
190	if (isclr(cg_blksfree(&acg), bn))
191		printf("Warning: sector %d is in use\n", blkno);
192	return (0);
193}
194
195/*
196 * read a block from the file system
197 */
198void
199rdfs(bno, size, bf)
200	daddr_t bno;
201	int size;
202	char *bf;
203{
204	int n;
205
206	if (lseek(fsi, (off_t)bno * dev_bsize, SEEK_SET) < 0) {
207		printf("seek error: %ld\n", bno);
208		perror("rdfs");
209		exit(1);
210	}
211	n = read(fsi, bf, size);
212	if (n != size) {
213		printf("read error: %ld\n", bno);
214		perror("rdfs");
215		exit(1);
216	}
217}
218