1 /* $NetBSD: badsect.c,v 1.31 2008/12/29 16:03:57 christos Exp $ */
4 * Copyright (c) 1981, 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1981, 1983, 1993\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)badsect.c 8.2 (Berkeley) 5/4/95";
42 __RCSID("$NetBSD: badsect.c,v 1.31 2008/12/29 16:03:57 christos Exp $");
49 * Badsect takes a list of file-system relative sector numbers
50 * and makes files containing the blocks of which these sectors are a part.
51 * It can be used to contain sectors which have problems if these sectors
52 * are not part of the bad file for the pack (see bad144). For instance,
53 * this program can be used if the driver for the file system in question
54 * does not support bad block forwarding.
56 #include <sys/param.h>
60 #include <ufs/ufs/dinode.h>
61 #include <ufs/ufs/ufs_bswap.h>
62 #include <ufs/ffs/fs.h>
63 #include <ufs/ffs/ffs_extern.h>
86 static off_t dev_bsize
= 1;
87 static int needswap
= 0;
90 static void rdfs(off_t
, size_t, void *);
91 static int chkuse(daddr_t
, int);
93 int main(int, char *[]);
95 static const off_t sblock_try
[] = SBLOCKSEARCH
;
98 main(int argc
, char *argv
[])
101 struct stat stbuf
, devstat
;
105 char name
[MAXPATHLEN
];
106 size_t dl
= sizeof(_PATH_DEV
);
109 (void)fprintf(stderr
, "usage: %s bbdir blkno [ blkno ]\n",
113 if (chdir(argv
[1]) == -1)
114 err(1, "Cannot change directory to `%s'", argv
[1]);
116 if (stat(".", &stbuf
) == -1)
117 err(1, "Cannot stat `%s'", argv
[1]);
119 (void)strlcpy(name
, _PATH_DEV
, sizeof(name
));
120 if ((dirp
= opendir(name
)) == NULL
)
121 err(1, "Cannot opendir `%s'", argv
[1]);
123 while ((dp
= readdir(dirp
)) != NULL
) {
124 (void)strlcpy(name
+ dl
- 1, dp
->d_name
, sizeof(name
) - dl
+ 1);
125 if (stat(name
, &devstat
) == -1)
126 err(1, "Cannot stat `%s'", name
);
127 if (stbuf
.st_dev
== devstat
.st_rdev
&&
128 S_ISBLK(devstat
.st_mode
))
133 errx(1, "Cannot find dev 0%llo corresponding to %s",
134 (long long)stbuf
.st_rdev
, argv
[1]);
137 * The filesystem is mounted; use the character device instead.
138 * XXX - Assume that prepending an `r' will give us the name of
139 * the character device.
142 (void)strlcpy(name
+ dl
, dp
->d_name
, sizeof(name
) - dl
);
143 (void)closedir(dirp
); /* now *dp is invalid */
145 if ((fsi
= open(name
, O_RDONLY
)) == -1)
146 err(1, "Cannot open `%s'", argv
[1]);
151 if (sblock_try
[i
] == -1)
152 errx(1, "%s: bad superblock", name
);
153 rdfs(sblock_try
[i
], SBLOCKSIZE
, fs
);
154 switch (fs
->fs_magic
) {
160 case FS_UFS2_MAGIC_SWAPPED
:
163 case FS_UFS1_MAGIC_SWAPPED
:
171 /* Ensure we don't use 1st alternate if ffsv1 and bs=64k */
172 if (is_ufs2
|| fs
->fs_old_flags
& FS_FLAGS_UPDATED
) {
173 if (fs
->fs_sblockloc
!= sblock_try
[i
])
176 if (sblock_try
[i
] == SBLOCK_UFS2
)
182 dev_bsize
= fs
->fs_fsize
/ fsbtodb(fs
, 1);
183 for (argc
-= 2, argv
+= 2; argc
> 0; argc
--, argv
++) {
184 number
= atoi(*argv
);
185 if (chkuse(number
, 1))
187 if (mknod(*argv
, S_IFMT
|S_IRUSR
|S_IWUSR
,
188 (dev_t
)dbtofsb(fs
, number
)) == -1) {
189 warn("Cannot mknod `%s'", *argv
);
197 warnx("Don't forget to run `fsck %s'", name
);
199 warnx("File system `%s' was not modified", name
);
204 chkuse(off_t blkno
, int cnt
)
207 off_t fsbn
, bn
, fsbe
;
209 fsbn
= dbtofsb(fs
, blkno
);
211 if (fsbe
> fs
->fs_size
) {
212 warnx("block %lld out of range of file system",
217 cg
= (int)dtog(fs
, fsbn
);
218 if (fsbn
< cgdmin(fs
, cg
)) {
219 if (cg
== 0 || fsbe
> cgsblock(fs
, cg
)) {
220 warnx("block %lld in superblock area: cannot attach",
225 if (fsbe
> cgbase(fs
, cg
+ 1)) {
226 warnx("block %lld in beyond end of cylinder group: "
227 "cannot attach", (long long)blkno
);
232 rdfs(fsbtodb(fs
, cgtod(fs
, cg
)), (int)sblock
.fs_cgsize
, &acg
);
234 if (!cg_chkmagic(&acg
, needswap
)) {
235 warnx("cg %d: bad magic number", cg
);
240 bn
= dtogd(fs
, fsbn
);
241 if (isclr(cg_blksfree(&acg
, needswap
), bn
))
242 warnx("Warning: sector %lld is in use", (long long)blkno
);
248 * read a block from the file system
251 rdfs(off_t bno
, size_t size
, void *bf
)
255 if (lseek(fsi
, bno
* dev_bsize
, SEEK_SET
) == -1)
256 err(1, "seek error at block %lld", (long long)bno
);
258 switch (n
= read(fsi
, bf
, size
)) {
260 err(1, "read error at block %lld", (long long)bno
);
264 if ((size_t)n
== size
)
266 errx(1, "incomplete read at block %lld", (long long)bno
);