122486Sdist /* 236194Sbostic * Copyright (c) 1981, 1983 The Regents of the University of California. 336194Sbostic * All rights reserved. 436194Sbostic * 542698Sbostic * %sccs.include.redist.c% 622486Sdist */ 73724Sroot 822486Sdist #ifndef lint 922486Sdist char copyright[] = 1036194Sbostic "@(#) Copyright (c) 1981, 1983 The Regents of the University of California.\n\ 1122486Sdist All rights reserved.\n"; 1236194Sbostic #endif /* not lint */ 1322486Sdist 1422486Sdist #ifndef lint 15*57994Sralph static char sccsid[] = "@(#)badsect.c 5.11 (Berkeley) 02/15/93"; 1636194Sbostic #endif /* not lint */ 1722486Sdist 183724Sroot /* 193724Sroot * badsect 203724Sroot * 213724Sroot * Badsect takes a list of file-system relative sector numbers 223724Sroot * and makes files containing the blocks of which these sectors are a part. 233724Sroot * It can be used to contain sectors which have problems if these sectors 243724Sroot * are not part of the bad file for the pack (see bad144). For instance, 253724Sroot * this program can be used if the driver for the file system in question 263724Sroot * does not support bad block forwarding. 273724Sroot */ 283724Sroot #include <sys/param.h> 2911272Smckusick #include <sys/dir.h> 3011272Smckusick #include <sys/stat.h> 3151613Sbostic #include <ufs/ffs/fs.h> 3251613Sbostic #include <ufs/ufs/dinode.h> 33*57994Sralph #include <unistd.h> 3437944Sbostic #include <stdio.h> 3537944Sbostic #include <paths.h> 363724Sroot 3711272Smckusick union { 3811272Smckusick struct fs fs; 3911272Smckusick char fsx[SBSIZE]; 4011272Smckusick } ufs; 4111272Smckusick #define sblock ufs.fs 4211272Smckusick union { 4311272Smckusick struct cg cg; 4411272Smckusick char cgx[MAXBSIZE]; 4511272Smckusick } ucg; 4611272Smckusick #define acg ucg.cg 4711272Smckusick struct fs *fs; 4811272Smckusick int fso, fsi; 4911272Smckusick int errs; 5030558Smckusick long dev_bsize = 1; 5111272Smckusick 5211272Smckusick char buf[MAXBSIZE]; 5311272Smckusick 5411272Smckusick 553724Sroot main(argc, argv) 563724Sroot int argc; 5711272Smckusick char *argv[]; 583724Sroot { 5911272Smckusick daddr_t number; 6011272Smckusick struct stat stbuf, devstat; 6111272Smckusick register struct direct *dp; 6211272Smckusick DIR *dirp; 6311272Smckusick int fd; 6411272Smckusick char name[BUFSIZ]; 653724Sroot 6611272Smckusick if (argc < 3) { 6711272Smckusick fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n"); 6811272Smckusick exit(1); 693724Sroot } 7011272Smckusick if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) { 7111272Smckusick perror(argv[1]); 7211272Smckusick exit(2); 7311272Smckusick } 7437944Sbostic strcpy(name, _PATH_DEV); 7511272Smckusick if ((dirp = opendir(name)) == NULL) { 7611272Smckusick perror(name); 7711272Smckusick exit(3); 7811272Smckusick } 7911272Smckusick while ((dp = readdir(dirp)) != NULL) { 8011272Smckusick strcpy(&name[5], dp->d_name); 8111272Smckusick if (stat(name, &devstat) < 0) { 8211272Smckusick perror(name); 8311272Smckusick exit(4); 8411272Smckusick } 8511272Smckusick if (stbuf.st_dev == devstat.st_rdev && 8611272Smckusick (devstat.st_mode & IFMT) == IFBLK) 8711272Smckusick break; 8811272Smckusick } 8911272Smckusick closedir(dirp); 9011272Smckusick if (dp == NULL) { 9111272Smckusick printf("Cannot find dev 0%o corresponding to %s\n", 9211272Smckusick stbuf.st_rdev, argv[1]); 9311272Smckusick exit(5); 9411272Smckusick } 9511272Smckusick if ((fsi = open(name, 0)) < 0) { 9611272Smckusick perror(name); 9711272Smckusick exit(6); 9811272Smckusick } 9911272Smckusick fs = &sblock; 10030558Smckusick rdfs(SBOFF, SBSIZE, (char *)fs); 10130558Smckusick dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 10211272Smckusick for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { 10311272Smckusick number = atoi(*argv); 10411272Smckusick if (chkuse(number, 1)) 10511272Smckusick continue; 10611272Smckusick if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) { 10711272Smckusick perror(*argv); 10811272Smckusick errs++; 10911272Smckusick } 11011272Smckusick } 11111272Smckusick printf("Don't forget to run ``fsck %s''\n", name); 1123724Sroot exit(errs); 1133724Sroot } 11411272Smckusick 11511272Smckusick chkuse(blkno, cnt) 11611272Smckusick daddr_t blkno; 11711272Smckusick int cnt; 11811272Smckusick { 11911272Smckusick int cg; 12011272Smckusick daddr_t fsbn, bn; 12111272Smckusick 12211272Smckusick fsbn = dbtofsb(fs, blkno); 12311272Smckusick if ((unsigned)(fsbn+cnt) > fs->fs_size) { 12411272Smckusick printf("block %d out of range of file system\n", blkno); 12511272Smckusick return (1); 12611272Smckusick } 12711272Smckusick cg = dtog(fs, fsbn); 12811272Smckusick if (fsbn < cgdmin(fs, cg)) { 12911272Smckusick if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) { 13011272Smckusick printf("block %d in non-data area: cannot attach\n", 13111272Smckusick blkno); 13211272Smckusick return (1); 13311272Smckusick } 13411272Smckusick } else { 13511272Smckusick if ((fsbn+cnt) > cgbase(fs, cg+1)) { 13611272Smckusick printf("block %d in non-data area: cannot attach\n", 13711272Smckusick blkno); 13811272Smckusick return (1); 13911272Smckusick } 14011272Smckusick } 14111272Smckusick rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize, 14211272Smckusick (char *)&acg); 14334575Smckusick if (!cg_chkmagic(&acg)) { 14411272Smckusick fprintf(stderr, "cg %d: bad magic number\n", cg); 14511272Smckusick errs++; 14623722Sbloom return (1); 14711272Smckusick } 14811272Smckusick bn = dtogd(fs, fsbn); 14934575Smckusick if (isclr(cg_blksfree(&acg), bn)) 15011272Smckusick printf("Warning: sector %d is in use\n", blkno); 15111272Smckusick return (0); 15211272Smckusick } 15311272Smckusick 15411272Smckusick /* 15511272Smckusick * read a block from the file system 15611272Smckusick */ 15711272Smckusick rdfs(bno, size, bf) 158*57994Sralph daddr_t bno; 159*57994Sralph int size; 16011272Smckusick char *bf; 16111272Smckusick { 16211272Smckusick int n; 16311272Smckusick 164*57994Sralph if (lseek(fsi, (off_t)bno * dev_bsize, SEEK_SET) < 0) { 16511272Smckusick printf("seek error: %ld\n", bno); 16611272Smckusick perror("rdfs"); 16711272Smckusick exit(1); 16811272Smckusick } 16911272Smckusick n = read(fsi, bf, size); 170*57994Sralph if (n != size) { 17111272Smckusick printf("read error: %ld\n", bno); 17211272Smckusick perror("rdfs"); 17311272Smckusick exit(1); 17411272Smckusick } 17511272Smckusick } 176