home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / wizards / 5352 < prev    next >
Encoding:
Text File  |  1992-12-31  |  6.1 KB  |  277 lines

  1. Path: sparky!uunet!cs.utexas.edu!sun-barr!male.EBay.Sun.COM!jethro.Corp.Sun.COM!exodus.Eng.Sun.COM!appserv.Eng.Sun.COM!slovax.Eng.Sun.COM!lm
  2. From: lm@slovax.Eng.Sun.COM (Larry McVoy)
  3. Newsgroups: comp.unix.wizards
  4. Subject: Re: file system layout
  5. Date: 31 Dec 1992 22:47:35 GMT
  6. Organization: Sun Microsystems, Inc.  Mt. View, Ca.
  7. Lines: 265
  8. Message-ID: <lk6u47INN47f@appserv.Eng.Sun.COM>
  9. References: <1992Dec30.163131.17280@ll.mit.edu>
  10. NNTP-Posting-Host: slovax
  11.  
  12. singer@ll.mit.edu (Matthew R. Singer) writes:
  13. : If I were to pre-write a file a Sun disk, is there a simple way to find out
  14. : what blocks on the disk the file system has allocated for it.  
  15.  
  16. Yup.  Source included below.  This is essentialy the read path of UFS. 
  17. Pretty simple, eh?  I saw a perl script that did this once - now that's 
  18. cool.
  19.  
  20. : Since I 
  21. : am writing just one big file on a newly formatted disk, it should be 
  22. : contiguous (right?).
  23.  
  24. Nope.  Even though I wacked it to do contig allocation when it can, it
  25. still switches cylinder groups every meg or so.  I suppose you could
  26. dick around with the tuning parameters to make one mondo cyl group.
  27.  
  28.  
  29. If you want more info on the SunOS UFS, send mail like so
  30.  
  31.     Mail archives@slovax.eng.sun.com
  32.     Subject: fs_cluster
  33.     ^D
  34.  
  35. That will send you the clustering paper.  (Yeah, I gotta get netlib.)
  36.  
  37. --lm
  38.  
  39. Here's the code.  
  40.  
  41.  
  42. #include <stdio.h>
  43. #include <sys/param.h>
  44. #include <sys/time.h>
  45. #include <sys/vnode.h>
  46. #ifdef    svr4
  47. #include <sys/fs/ufs_fs.h>
  48. #include <sys/fs/ufs_inode.h>
  49. #define    DEV
  50. #else
  51. #include <ufs/fs.h>
  52. #include <ufs/inode.h>
  53. #include <sys/dir.h>
  54. #endif
  55. #include <sys/stat.h>
  56.  
  57. #define SECTORSIZE    512
  58. #define SUPERADDR    (16*SECTORSIZE)
  59.  
  60. union {
  61.     char    sb_buffer[SBSIZE];
  62.     struct    fs fs;
  63. } sb;
  64. union {
  65.     char    i_buffer[MAXBSIZE];
  66.     struct dinode dinode[MAXBSIZE/sizeof(struct dinode)];
  67. } di;
  68. char    *cmdname;
  69. void    *malloc();
  70. int    block;    /* global because I'm too lazy to pass a pointer */
  71.  
  72. main(argc, argv)
  73.     int    argc;
  74.     char    *argv[];
  75. {
  76.     struct    stat    statb;
  77.     struct    fs    *fsp;
  78.     struct    dinode    *ip;
  79.     char    *file;
  80.     int    *blk;
  81.     int    size;
  82.     int    devfd;
  83.     int    inode;
  84.     int    offset;
  85.     int    seekaddr;
  86.     int    i, j;
  87.     int    extent;
  88.  
  89.     cmdname = argv[0];
  90.     if (argc != 2 && argc != 3) {
  91.         fprintf(stderr, "Usage: %s file [diskdev]\n", cmdname);
  92.         exit(1);
  93.     }
  94.     file = argv[1];
  95.     if (stat(file, &statb) == -1) {
  96.         fprintf(stderr, "File %s not found\n", file);
  97.         exit(1);
  98.     }
  99.     sync();
  100.     inode = statb.st_ino;
  101.     if (argc == 3) {
  102.         devfd = open(argv[2], 0);
  103. #ifndef    DEV
  104.     } else {
  105.         devfd = getdev(statb.st_dev);
  106. #endif
  107.     }
  108.     if (lseek(devfd, SUPERADDR, 0) == -1) {
  109.         fprintf(stderr, "Seek to superblock failed\n");
  110.         exit(1);
  111.     }
  112.     fsp = &sb.fs;
  113.     if (read(devfd, sb.sb_buffer, SBSIZE) == -1) {
  114.         fprintf(stderr, "Read of superblock failed\n");
  115.         exit(1);
  116.     }
  117.     if (fsp->fs_magic != FS_MAGIC) {
  118.         fprintf(stderr, "Not a superblock\n");
  119.         exit(1);
  120.     }
  121.     block = itod(fsp, inode);
  122.     offset = itoo(fsp, inode);
  123.     seekaddr = fsbtodb(fsp, block) * SECTORSIZE;
  124.     if (lseek(devfd, seekaddr, 0) == -1) {
  125.         fprintf(stderr, "Seek to block %d offset %d failed\n", 
  126.             block, offset);
  127.         exit(1);
  128.     }
  129.     if (read(devfd, di.i_buffer, fsp->fs_bsize) == -1) {
  130.         fprintf(stderr, "Read of inode %d failed\n", inode);
  131.         exit(1);
  132.     }
  133.     ip = &di.dinode[offset];
  134.     /* fprintf(stderr, "ncg %d rotor %d\n", fsp->fs_ncg, fsp->fs_cgrotor);*/
  135.     /* printf("%d\n", fsp->fs_fpg); */
  136.     size = ip->di_size;
  137.     for (i = 0; i < NDADDR && size > 0; ) {
  138.         extent = findextent(fsp, &ip->di_db[i], NDADDR - i);
  139.         printf("off=%dK block=%d extent=%dK\n", 
  140.             i * fsp->fs_bsize / 1024, ip->di_db[i],
  141.             extent * fsp->fs_bsize / 1024);
  142.         i += extent ? extent : 1;
  143.         if (i * fsp->fs_bsize >= size)
  144.             exit(0);
  145.     }
  146.     block = NDADDR;
  147.     blk = (int *) malloc(fsp->fs_bsize);
  148.     /*
  149.      * block of pointers
  150.      */
  151.     doblk(devfd, fsbtodb(fsp, ip->di_ib[0]) * SECTORSIZE, fsp, size);
  152.     /*
  153.      * Block of pointers to pointers
  154.      */
  155.     if (lseek(devfd, fsbtodb(fsp, ip->di_ib[1]) * SECTORSIZE, 0) == -1) {
  156.         fprintf(stderr, "Seek to indirect block %d failed\n",
  157.             fsbtodb(fsp, ip->di_ib[1]));
  158.         exit(1);
  159.     }
  160.     if (read(devfd, (char *) blk, fsp->fs_bsize) != fsp->fs_bsize) {
  161.         fprintf(stderr, "Read of indirect block %d failed\n",
  162.             fsbtodb(fsp, ip->di_ib[1]));
  163.         exit(1);
  164.     }
  165.     for (j = 0; j < NINDIR(fsp); j++) {
  166.         doblk(devfd, fsbtodb(fsp, blk[j]) * SECTORSIZE, fsp, size);
  167.     }
  168.     /*
  169.      * Too lazy to do this
  170.      */
  171.     printf("Quitting early\n");
  172.     exit(0);
  173.     /*NOTREACHED*/
  174. }
  175.  
  176. doblk(fd, loc, fsp, size)
  177.     struct    fs    *fsp;
  178. {
  179.     int    *blk;
  180.     int    j;
  181.     int    extent;
  182.  
  183.     if (lseek(fd, loc, 0) != loc) {
  184.         perror("lseek");
  185.         exit(0);
  186.     }
  187.     blk = (int*)malloc(fsp->fs_bsize);
  188.     if (read(fd, (char*)blk, fsp->fs_bsize) != fsp->fs_bsize) {
  189.         perror("read");
  190.         exit(0);
  191.     }
  192.     for (j = 0; j < NINDIR(fsp); ) {
  193.         if (extent = findextent(fsp, &blk[j], NINDIR(fsp) - j)) {
  194.             printf("off=%dK block=%d extent=%dK\n",
  195.                 block * fsp->fs_bsize / 1024, 
  196.                 blk[j], extent * fsp->fs_bsize / 1024);
  197.             block += extent;
  198.             j += extent;
  199.         } else {
  200.             printf("off=%dK HOLE\n", block * fsp->fs_bsize / 1024);
  201.             block += 1;
  202.             j += 1;
  203.         }
  204.         if (block * fsp->fs_bsize >= size)
  205.             exit(0);
  206.     }
  207. }
  208.  
  209. #ifndef    DEV
  210. getdev(dev)
  211.     dev_t dev;
  212. {
  213.     DIR *dirp;
  214.     struct direct *dp;
  215.     struct stat statb;
  216.     char buf[100];
  217.     int fd;
  218.  
  219.     dirp = opendir("/dev");
  220.     if (dirp == NULL) {
  221.         fprintf(stderr, "cannot open /dev\n");
  222.         exit(1);
  223.     }
  224.     while (dp = readdir(dirp)) {
  225.         if (dp->d_fileno == 0) {
  226.             continue;
  227.         }
  228.         sprintf(buf, "/dev/%s", dp->d_name);
  229.         if (stat(buf, &statb) == -1) {
  230.             continue;
  231.         }
  232.         if (statb.st_rdev == dev && (statb.st_mode & IFMT) == IFBLK) {
  233.             sprintf(buf, "/dev/r%s", dp->d_name);
  234.             fd = open(buf, 0);
  235.             if (fd < 0) {
  236.                 fprintf(stderr, "cannot open %s\n", buf);
  237.                 exit(1);
  238.             }
  239.             closedir(dirp);
  240.             return (fd);
  241.         }
  242.     }
  243.     fprintf(stderr, "Device %x not found (NFS file?).\n", dev & 0xffff);
  244.     exit(1);
  245.     /*NOTREACHED*/
  246. }
  247. #endif
  248.  
  249. static int
  250. findextent(fs, sbp, n)
  251.     struct fs *fs;
  252.     daddr_t *sbp;
  253.     register int n;
  254. {
  255.     register daddr_t bn, nextbn;
  256.     register daddr_t *bp;
  257.     register int diff;
  258.  
  259.     if (n <= 0)
  260.         return (0);
  261.     bn = *sbp;
  262.     if (bn == 0)
  263.         return (0);
  264.     diff = fs->fs_frag;
  265.     bp = sbp;
  266.     while (--n > 0) {
  267.         nextbn = *(bp + 1);
  268.         if (nextbn == 0 || bn + diff != nextbn)
  269.             break;
  270.         bn = nextbn;
  271.         bp++;
  272.     }
  273.     return ((int)(bp - sbp) + 1);
  274. }
  275. ---
  276. Larry McVoy            (415) 336-7627             lm@sun.com
  277.