stu@jpusa1.UUCP (Stu Heiss) (11/07/89)
Here's a utility to help discover what file was affected when you have a hard disk error. Assuming you know the block number where the error occured, this utility will examine a filesystem and map inodes to data block numbers printing lines in the form of: inum: blocknum blocknum blocknum... For example, let's suppose block 12345 is bad as indicated by a kernal error message and the filesystem is /usr. You would do the following: # mapino /dev/usr | grep 12345 and note the inode. Then: # ncheck -i inum /dev/usr to get the pathname. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # mapino.c # This archive created: Tue Nov 7 05:03:44 1989 # By: stu (JPUSA - Chicago, IL) export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'mapino.c'" '(3296 characters)' if test -f 'mapino.c' then echo shar: "will not over-write existing file 'mapino.c'" else sed 's/^X//' << \SHAR_EOFmapino.c > 'mapino.c' X#include <stdio.h> X#include <sys/types.h> X#include <sys/param.h> X#include <sys/filsys.h> X#include <sys/ino.h> X Xint fd; Xint retcode=0; Xstruct filsys sb; Xino_t maxino; Xdaddr_t loblk, hiblk; Xstruct dinode *dinodes; Xextern char *calloc(); X X#define DBLKSIZ 1024 X#define nel(x) (sizeof(x)/sizeof(x[0])) X#define iblk x._iblk X#define buff x._buff Xunion x { X char _buff[DBLKSIZ]; X daddr_t _iblk[DBLKSIZ/sizeof(daddr_t)]; X}; X X#define MININO 2 X#define E_INO 2 X#define E_BLK 4 X X#define dptr(ino) (&dinodes[(ino)-1]) X Xgoodino(ino) Xino_t ino; X{ X if (ino >= MININO && ino < maxino) return 1; X fprintf(stderr,"impossible ino %d\n",ino); X retcode |= E_INO; X return 0; X} X Xgoodblk(blk) Xdaddr_t blk; X{ X if (blk >= loblk && blk < hiblk) return 1; X fprintf(stderr,"impossible block %ld\n",blk); X retcode |= E_BLK; X return 0; X} X Xtind(l) Xdaddr_t l; X{ X int i; X union x x; X d_seek((off_t)l); X if (read(fd,buff,sizeof(buff)) == -1) { X fprintf(stderr,"triple indirect blk=%ld ",l); X perror("read"); X exit(1); X } X for (i = 0; i < nel(iblk); ++i) { X if (iblk[i] == 0) X break; X if (goodblk(iblk[i])) X dind(iblk[i]); X } X} X Xdind(l) Xdaddr_t l; X{ X int i; X union x x; X d_seek((off_t)l); X if (read(fd,buff,sizeof(buff)) == -1) { X fprintf(stderr,"double indirect blk=%ld ",l); X perror("read"); X exit(1); X } X for (i = 0; i < nel(iblk); ++i) { X if (iblk[i] == 0) X break; X if (goodblk(iblk[i])) X sind(iblk[i]); X } X} X Xsind(l) Xdaddr_t l; X{ X int i; X union x x; X d_seek((off_t)l); X if (read(fd,buff,sizeof(buff)) == -1) { X fprintf(stderr,"single indirect blk=%ld ",l); X perror("read"); X exit(1); X } X for (i = 0; i < nel(iblk); ++i) { X if (iblk[i] == 0) X break; X if (goodblk(iblk[i])) Xprintf(" %ld",iblk[i]); X } X} X Xdoblkno(ino) Xino_t ino; X{ X struct dinode *d; X daddr_t blk[13]; X X if (goodino((ino_t)ino)) { X d = dptr(ino); X l3tol(blk, d->di_addr, 13); X doinode((ino_t)ino,blk); X } X} X Xdoinode(ino,blk) Xino_t ino; Xdaddr_t *blk; X{ X int i; X struct dinode *d = dptr(ino); Xprintf("ino=%d:",ino); X for (i = 0; i < 13; ++i) { X if (blk[i] == 0) X break; X if (i < 10) { Xif (goodblk(blk[i])) printf(" %ld",blk[i]); X } else if (i == 10) { X if (goodblk(blk[i])) X sind(blk[i]); X } else if (i == 11) { X if (goodblk(blk[i])) X dind(blk[i]); X } else if (i == 12) { X if (goodblk(blk[i])) X tind(blk[i]); X } X } Xprintf("\n"); X} X Xopenspecial(s) Xchar *s; X{ X if ((fd = open(s,0)) == -1) { X fprintf(stderr,"dev=%s ",s); X perror("open"); X exit(1); X } X d_seek((off_t)1); X if (read(fd,&sb,sizeof(sb)) == -1) { X perror("read superblock"); X exit(1); X } X maxino = (sb.s_isize -2)*(DBLKSIZ/sizeof(struct dinode)); X loblk = sb.s_isize; X hiblk = sb.s_fsize; X if ((dinodes = (struct dinode *)calloc(maxino,sizeof(struct dinode))) == 0) { X perror("calloc"); X exit(1); X } X d_seek((off_t)2); X if (read(fd,dinodes,maxino * sizeof(struct dinode)) == -1) { X perror("read inode table"); X exit(1); X } X} X Xd_seek(n) Xoff_t n; X{ X lseek(fd,(off_t)(n * DBLKSIZ),0); X} X Xmain(ac,av) Xint ac; Xchar **av; X{ X char *special; X ino_t ino; X if (ac < 2) { X fprintf(stderr,"usage: %s special [ino...]\n",av[0]); X exit(1); X } X special = *++av; X --ac; X openspecial(special); X if (ac == 1) X for (ino = MININO; ino < maxino; ++ino) X doblkno((ino_t)ino); X else X while (ac-- > 1) X doblkno((ino_t)atoi(*++av)); X exit(retcode); X} SHAR_EOFmapino.c if test 54120 -ne "`sum < 'mapino.c' | sed 's/ .*//'`" then echo shar: "possible error transmitting 'mapino.c'" '(sum should have been 54120)' echo shar: "trying 'sum -r'" if test 04082 -ne "`sum -r < 'mapino.c' | sed 's/ .*//'`" then echo shar: "probable error transmitting 'mapino.c'" '(sum should have been 04082)' echo shar: "trying 'wc -c'" if test 3296 -ne "`wc -c < 'mapino.c'`" then echo shar: "error transmitting 'mapino.c'" '(should have been 3296 characters)' else echo shar: "wc was ok" fi fi fi chmod 644 'mapino.c' fi exit 0 # End of shell archive -- Stu Heiss - gargoyle.uchicago.edu!jpusa1.uucp!stu, stu@jpusa1.chi.il.us