122486Sdist /* 236194Sbostic * Copyright (c) 1981, 1983 The Regents of the University of California. 336194Sbostic * All rights reserved. 436194Sbostic * 536194Sbostic * Redistribution and use in source and binary forms are permitted 636194Sbostic * provided that the above copyright notice and this paragraph are 736194Sbostic * duplicated in all such forms and that any documentation, 836194Sbostic * advertising materials, and other materials related to such 936194Sbostic * distribution and use acknowledge that the software was developed 1036194Sbostic * by the University of California, Berkeley. The name of the 1136194Sbostic * University may not be used to endorse or promote products derived 1236194Sbostic * from this software without specific prior written permission. 1336194Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436194Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536194Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622486Sdist */ 173724Sroot 1822486Sdist #ifndef lint 1922486Sdist char copyright[] = 2036194Sbostic "@(#) Copyright (c) 1981, 1983 The Regents of the University of California.\n\ 2122486Sdist All rights reserved.\n"; 2236194Sbostic #endif /* not lint */ 2322486Sdist 2422486Sdist #ifndef lint 25*38502Sbostic static char sccsid[] = "@(#)badsect.c 5.7 (Berkeley) 07/30/89"; 2636194Sbostic #endif /* not lint */ 2722486Sdist 283724Sroot /* 293724Sroot * badsect 303724Sroot * 313724Sroot * Badsect takes a list of file-system relative sector numbers 323724Sroot * and makes files containing the blocks of which these sectors are a part. 333724Sroot * It can be used to contain sectors which have problems if these sectors 343724Sroot * are not part of the bad file for the pack (see bad144). For instance, 353724Sroot * this program can be used if the driver for the file system in question 363724Sroot * does not support bad block forwarding. 373724Sroot */ 383724Sroot #include <sys/param.h> 3911272Smckusick #include <sys/dir.h> 4011272Smckusick #include <sys/stat.h> 41*38502Sbostic #include <sys/time.h> 42*38502Sbostic #include <sys/vnode.h> 43*38502Sbostic #include <ufs/fs.h> 44*38502Sbostic #include <ufs/inode.h> 4537944Sbostic #include <stdio.h> 4637944Sbostic #include <paths.h> 473724Sroot 4811272Smckusick union { 4911272Smckusick struct fs fs; 5011272Smckusick char fsx[SBSIZE]; 5111272Smckusick } ufs; 5211272Smckusick #define sblock ufs.fs 5311272Smckusick union { 5411272Smckusick struct cg cg; 5511272Smckusick char cgx[MAXBSIZE]; 5611272Smckusick } ucg; 5711272Smckusick #define acg ucg.cg 5811272Smckusick struct fs *fs; 5911272Smckusick int fso, fsi; 6011272Smckusick int errs; 6130558Smckusick long dev_bsize = 1; 6211272Smckusick 6311272Smckusick char buf[MAXBSIZE]; 6411272Smckusick 6511272Smckusick 663724Sroot main(argc, argv) 673724Sroot int argc; 6811272Smckusick char *argv[]; 693724Sroot { 7011272Smckusick daddr_t number; 7111272Smckusick struct stat stbuf, devstat; 7211272Smckusick register struct direct *dp; 7311272Smckusick DIR *dirp; 7411272Smckusick int fd; 7511272Smckusick char name[BUFSIZ]; 763724Sroot 7711272Smckusick if (argc < 3) { 7811272Smckusick fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); 7911272Smckusick exit(1); 803724Sroot } 8111272Smckusick if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) { 8211272Smckusick perror(argv[1]); 8311272Smckusick exit(2); 8411272Smckusick } 8537944Sbostic strcpy(name, _PATH_DEV); 8611272Smckusick if ((dirp = opendir(name)) == NULL) { 8711272Smckusick perror(name); 8811272Smckusick exit(3); 8911272Smckusick } 9011272Smckusick while ((dp = readdir(dirp)) != NULL) { 9111272Smckusick strcpy(&name[5], dp->d_name); 9211272Smckusick if (stat(name, &devstat) < 0) { 9311272Smckusick perror(name); 9411272Smckusick exit(4); 9511272Smckusick } 9611272Smckusick if (stbuf.st_dev == devstat.st_rdev && 9711272Smckusick (devstat.st_mode & IFMT) == IFBLK) 9811272Smckusick break; 9911272Smckusick } 10011272Smckusick closedir(dirp); 10111272Smckusick if (dp == NULL) { 10211272Smckusick printf("Cannot find dev 0%o corresponding to %s\n", 10311272Smckusick stbuf.st_rdev, argv[1]); 10411272Smckusick exit(5); 10511272Smckusick } 10611272Smckusick if ((fsi = open(name, 0)) < 0) { 10711272Smckusick perror(name); 10811272Smckusick exit(6); 10911272Smckusick } 11011272Smckusick fs = &sblock; 11130558Smckusick rdfs(SBOFF, SBSIZE, (char *)fs); 11230558Smckusick dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 11311272Smckusick for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { 11411272Smckusick number = atoi(*argv); 11511272Smckusick if (chkuse(number, 1)) 11611272Smckusick continue; 11711272Smckusick if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { 11811272Smckusick perror(*argv); 11911272Smckusick errs++; 12011272Smckusick } 12111272Smckusick } 12211272Smckusick printf("Don't forget to run ``fsck %s''\n", name); 1233724Sroot exit(errs); 1243724Sroot } 12511272Smckusick 12611272Smckusick chkuse(blkno, cnt) 12711272Smckusick daddr_t blkno; 12811272Smckusick int cnt; 12911272Smckusick { 13011272Smckusick int cg; 13111272Smckusick daddr_t fsbn, bn; 13211272Smckusick 13311272Smckusick fsbn = dbtofsb(fs, blkno); 13411272Smckusick if ((unsigned)(fsbn+cnt) > fs->fs_size) { 13511272Smckusick printf("block %d out of range of file system\n", blkno); 13611272Smckusick return (1); 13711272Smckusick } 13811272Smckusick cg = dtog(fs, fsbn); 13911272Smckusick if (fsbn < cgdmin(fs, cg)) { 14011272Smckusick if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { 14111272Smckusick printf("block %d in non-data area: cannot attach\n", 14211272Smckusick blkno); 14311272Smckusick return (1); 14411272Smckusick } 14511272Smckusick } else { 14611272Smckusick if ((fsbn+cnt) > cgbase(fs, cg+1)) { 14711272Smckusick printf("block %d in non-data area: cannot attach\n", 14811272Smckusick blkno); 14911272Smckusick return (1); 15011272Smckusick } 15111272Smckusick } 15211272Smckusick rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize, 15311272Smckusick (char *)&acg); 15434575Smckusick if (!cg_chkmagic(&acg)) { 15511272Smckusick fprintf(stderr, "cg %d: bad magic number\n", cg); 15611272Smckusick errs++; 15723722Sbloom return (1); 15811272Smckusick } 15911272Smckusick bn = dtogd(fs, fsbn); 16034575Smckusick if (isclr(cg_blksfree(&acg), bn)) 16111272Smckusick printf("Warning: sector %d is in use\n", blkno); 16211272Smckusick return (0); 16311272Smckusick } 16411272Smckusick 16511272Smckusick /* 16611272Smckusick * read a block from the file system 16711272Smckusick */ 16811272Smckusick rdfs(bno, size, bf) 16911272Smckusick int bno, size; 17011272Smckusick char *bf; 17111272Smckusick { 17211272Smckusick int n; 17311272Smckusick 17430558Smckusick if (lseek(fsi, bno * dev_bsize, 0) < 0) { 17511272Smckusick printf("seek error: %ld\n", bno); 17611272Smckusick perror("rdfs"); 17711272Smckusick exit(1); 17811272Smckusick } 17911272Smckusick n = read(fsi, bf, size); 18011272Smckusick if(n != size) { 18111272Smckusick printf("read error: %ld\n", bno); 18211272Smckusick perror("rdfs"); 18311272Smckusick exit(1); 18411272Smckusick } 18511272Smckusick } 186