xref: /csrg-svn/sbin/badsect/badsect.c (revision 36194)
1 /*
2  * Copyright (c) 1981, 1983 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1981, 1983 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)badsect.c	5.5 (Berkeley) 11/01/88";
26 #endif /* not lint */
27 
28 /*
29  * badsect
30  *
31  * Badsect takes a list of file-system relative sector numbers
32  * and makes files containing the blocks of which these sectors are a part.
33  * It can be used to contain sectors which have problems if these sectors
34  * are not part of the bad file for the pack (see bad144).  For instance,
35  * this program can be used if the driver for the file system in question
36  * does not support bad block forwarding.
37  */
38 #include <stdio.h>
39 #include <sys/param.h>
40 #include <sys/fs.h>
41 #include <sys/dir.h>
42 #include <sys/stat.h>
43 #include <sys/inode.h>
44 
45 union {
46 	struct	fs fs;
47 	char	fsx[SBSIZE];
48 } ufs;
49 #define sblock	ufs.fs
50 union {
51 	struct	cg cg;
52 	char	cgx[MAXBSIZE];
53 } ucg;
54 #define	acg	ucg.cg
55 struct	fs *fs;
56 int	fso, fsi;
57 int	errs;
58 long	dev_bsize = 1;
59 
60 char buf[MAXBSIZE];
61 
62 
63 main(argc, argv)
64 	int argc;
65 	char *argv[];
66 {
67 	daddr_t number;
68 	struct stat stbuf, devstat;
69 	register struct direct *dp;
70 	DIR *dirp;
71 	int fd;
72 	char name[BUFSIZ];
73 
74 	if (argc < 3) {
75 		fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n");
76 		exit(1);
77 	}
78 	if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) {
79 		perror(argv[1]);
80 		exit(2);
81 	}
82 	strcpy(name, "/dev/");
83 	if ((dirp = opendir(name)) == NULL) {
84 		perror(name);
85 		exit(3);
86 	}
87 	while ((dp = readdir(dirp)) != NULL) {
88 		strcpy(&name[5], dp->d_name);
89 		if (stat(name, &devstat) < 0) {
90 			perror(name);
91 			exit(4);
92 		}
93 		if (stbuf.st_dev == devstat.st_rdev &&
94 		    (devstat.st_mode & IFMT) == IFBLK)
95 			break;
96 	}
97 	closedir(dirp);
98 	if (dp == NULL) {
99 		printf("Cannot find dev 0%o corresponding to %s\n",
100 			stbuf.st_rdev, argv[1]);
101 		exit(5);
102 	}
103 	if ((fsi = open(name, 0)) < 0) {
104 		perror(name);
105 		exit(6);
106 	}
107 	fs = &sblock;
108 	rdfs(SBOFF, SBSIZE, (char *)fs);
109 	dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
110 	for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
111 		number = atoi(*argv);
112 		if (chkuse(number, 1))
113 			continue;
114 		if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) {
115 			perror(*argv);
116 			errs++;
117 		}
118 	}
119 	printf("Don't forget to run ``fsck %s''\n", name);
120 	exit(errs);
121 }
122 
123 chkuse(blkno, cnt)
124 	daddr_t blkno;
125 	int cnt;
126 {
127 	int cg;
128 	daddr_t fsbn, bn;
129 
130 	fsbn = dbtofsb(fs, blkno);
131 	if ((unsigned)(fsbn+cnt) > fs->fs_size) {
132 		printf("block %d out of range of file system\n", blkno);
133 		return (1);
134 	}
135 	cg = dtog(fs, fsbn);
136 	if (fsbn < cgdmin(fs, cg)) {
137 		if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) {
138 			printf("block %d in non-data area: cannot attach\n",
139 				blkno);
140 			return (1);
141 		}
142 	} else {
143 		if ((fsbn+cnt) > cgbase(fs, cg+1)) {
144 			printf("block %d in non-data area: cannot attach\n",
145 				blkno);
146 			return (1);
147 		}
148 	}
149 	rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize,
150 	    (char *)&acg);
151 	if (!cg_chkmagic(&acg)) {
152 		fprintf(stderr, "cg %d: bad magic number\n", cg);
153 		errs++;
154 		return (1);
155 	}
156 	bn = dtogd(fs, fsbn);
157 	if (isclr(cg_blksfree(&acg), bn))
158 		printf("Warning: sector %d is in use\n", blkno);
159 	return (0);
160 }
161 
162 /*
163  * read a block from the file system
164  */
165 rdfs(bno, size, bf)
166 	int bno, size;
167 	char *bf;
168 {
169 	int n;
170 
171 	if (lseek(fsi, bno * dev_bsize, 0) < 0) {
172 		printf("seek error: %ld\n", bno);
173 		perror("rdfs");
174 		exit(1);
175 	}
176 	n = read(fsi, bf, size);
177 	if(n != size) {
178 		printf("read error: %ld\n", bno);
179 		perror("rdfs");
180 		exit(1);
181 	}
182 }
183