1*11272Smckusick static char *sccsid = "@(#)badsect.c 4.3 (Berkeley) 83/02/24"; 23724Sroot 33724Sroot /* 43724Sroot * badsect 53724Sroot * 63724Sroot * Badsect takes a list of file-system relative sector numbers 73724Sroot * and makes files containing the blocks of which these sectors are a part. 83724Sroot * It can be used to contain sectors which have problems if these sectors 93724Sroot * are not part of the bad file for the pack (see bad144). For instance, 103724Sroot * this program can be used if the driver for the file system in question 113724Sroot * does not support bad block forwarding. 123724Sroot */ 13*11272Smckusick #include <stdio.h> 143724Sroot #include <sys/param.h> 15*11272Smckusick #include <sys/fs.h> 16*11272Smckusick #include <sys/dir.h> 17*11272Smckusick #include <sys/stat.h> 18*11272Smckusick #include <sys/inode.h> 193724Sroot 20*11272Smckusick union { 21*11272Smckusick struct fs fs; 22*11272Smckusick char fsx[SBSIZE]; 23*11272Smckusick } ufs; 24*11272Smckusick #define sblock ufs.fs 25*11272Smckusick union { 26*11272Smckusick struct cg cg; 27*11272Smckusick char cgx[MAXBSIZE]; 28*11272Smckusick } ucg; 29*11272Smckusick #define acg ucg.cg 30*11272Smckusick struct fs *fs; 31*11272Smckusick int fso, fsi; 32*11272Smckusick int errs; 33*11272Smckusick 34*11272Smckusick char buf[MAXBSIZE]; 35*11272Smckusick 36*11272Smckusick 373724Sroot main(argc, argv) 383724Sroot int argc; 39*11272Smckusick char *argv[]; 403724Sroot { 41*11272Smckusick daddr_t number; 42*11272Smckusick struct stat stbuf, devstat; 43*11272Smckusick register struct direct *dp; 44*11272Smckusick DIR *dirp; 45*11272Smckusick int fd; 46*11272Smckusick char name[BUFSIZ]; 473724Sroot 48*11272Smckusick if (argc < 3) { 49*11272Smckusick fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); 50*11272Smckusick exit(1); 513724Sroot } 52*11272Smckusick if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) { 53*11272Smckusick perror(argv[1]); 54*11272Smckusick exit(2); 55*11272Smckusick } 56*11272Smckusick strcpy(name, "/dev/"); 57*11272Smckusick if ((dirp = opendir(name)) == NULL) { 58*11272Smckusick perror(name); 59*11272Smckusick exit(3); 60*11272Smckusick } 61*11272Smckusick while ((dp = readdir(dirp)) != NULL) { 62*11272Smckusick strcpy(&name[5], dp->d_name); 63*11272Smckusick if (stat(name, &devstat) < 0) { 64*11272Smckusick perror(name); 65*11272Smckusick exit(4); 66*11272Smckusick } 67*11272Smckusick if (stbuf.st_dev == devstat.st_rdev && 68*11272Smckusick (devstat.st_mode & IFMT) == IFBLK) 69*11272Smckusick break; 70*11272Smckusick } 71*11272Smckusick closedir(dirp); 72*11272Smckusick if (dp == NULL) { 73*11272Smckusick printf("Cannot find dev 0%o corresponding to %s\n", 74*11272Smckusick stbuf.st_rdev, argv[1]); 75*11272Smckusick exit(5); 76*11272Smckusick } 77*11272Smckusick if ((fsi = open(name, 0)) < 0) { 78*11272Smckusick perror(name); 79*11272Smckusick exit(6); 80*11272Smckusick } 81*11272Smckusick fs = &sblock; 82*11272Smckusick rdfs(SBLOCK, SBSIZE, (char *)fs); 83*11272Smckusick for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { 84*11272Smckusick number = atoi(*argv); 85*11272Smckusick if (chkuse(number, 1)) 86*11272Smckusick continue; 87*11272Smckusick if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { 88*11272Smckusick perror(*argv); 89*11272Smckusick errs++; 90*11272Smckusick } 91*11272Smckusick } 92*11272Smckusick printf("Don't forget to run ``fsck %s''\n", name); 933724Sroot exit(errs); 943724Sroot } 95*11272Smckusick 96*11272Smckusick chkuse(blkno, cnt) 97*11272Smckusick daddr_t blkno; 98*11272Smckusick int cnt; 99*11272Smckusick { 100*11272Smckusick int cg; 101*11272Smckusick daddr_t fsbn, bn; 102*11272Smckusick 103*11272Smckusick fsbn = dbtofsb(fs, blkno); 104*11272Smckusick if ((unsigned)(fsbn+cnt) > fs->fs_size) { 105*11272Smckusick printf("block %d out of range of file system\n", blkno); 106*11272Smckusick return (1); 107*11272Smckusick } 108*11272Smckusick cg = dtog(fs, fsbn); 109*11272Smckusick if (fsbn < cgdmin(fs, cg)) { 110*11272Smckusick if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { 111*11272Smckusick printf("block %d in non-data area: cannot attach\n", 112*11272Smckusick blkno); 113*11272Smckusick return (1); 114*11272Smckusick } 115*11272Smckusick } else { 116*11272Smckusick if ((fsbn+cnt) > cgbase(fs, cg+1)) { 117*11272Smckusick printf("block %d in non-data area: cannot attach\n", 118*11272Smckusick blkno); 119*11272Smckusick return (1); 120*11272Smckusick } 121*11272Smckusick } 122*11272Smckusick rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize, 123*11272Smckusick (char *)&acg); 124*11272Smckusick if (acg.cg_magic != CG_MAGIC) { 125*11272Smckusick fprintf(stderr, "cg %d: bad magic number\n", cg); 126*11272Smckusick errs++; 127*11272Smckusick return; 128*11272Smckusick } 129*11272Smckusick bn = dtogd(fs, fsbn); 130*11272Smckusick if (isclr(acg.cg_free, bn)) 131*11272Smckusick printf("Warning: sector %d is in use\n", blkno); 132*11272Smckusick return (0); 133*11272Smckusick } 134*11272Smckusick 135*11272Smckusick /* 136*11272Smckusick * read a block from the file system 137*11272Smckusick */ 138*11272Smckusick rdfs(bno, size, bf) 139*11272Smckusick int bno, size; 140*11272Smckusick char *bf; 141*11272Smckusick { 142*11272Smckusick int n; 143*11272Smckusick 144*11272Smckusick if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) { 145*11272Smckusick printf("seek error: %ld\n", bno); 146*11272Smckusick perror("rdfs"); 147*11272Smckusick exit(1); 148*11272Smckusick } 149*11272Smckusick n = read(fsi, bf, size); 150*11272Smckusick if(n != size) { 151*11272Smckusick printf("read error: %ld\n", bno); 152*11272Smckusick perror("rdfs"); 153*11272Smckusick exit(1); 154*11272Smckusick } 155*11272Smckusick } 156