home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / unix / bsd / 10148 < prev    next >
Encoding:
Internet Message Format  |  1992-12-13  |  23.1 KB

  1. Path: sparky!uunet!cs.utexas.edu!sun-barr!ames!pacbell.com!hoptoad!curt
  2. From: curt@hoptoad.uucp (Curt Mayer)
  3. Newsgroups: comp.unix.bsd
  4. Subject: Almost Free Symbolic Links (source code)
  5. Message-ID: <39777@hoptoad.uucp>
  6. Date: 13 Dec 92 02:45:58 GMT
  7. Distribution: world
  8. Organization: kernel hackers R us
  9. Lines: 828
  10. Keywords: symlink data in inode block list
  11. Summary: cute hack
  12.  
  13. ---------cut anywhere near here----------
  14. : To unbundle, sh this file
  15. #!/bin/sh
  16. mkdir .
  17. echo ./README
  18. cat >./README <<'@@@ Fin de ./README'
  19. this cruddy but complete hack answers one of the objections to symlinks:
  20. that they are slow, and cost an entire frag. symlinks of less than length
  21. 60 are stored in the inode itself. symlinks longer than this are still
  22. in the inode. to make the illusion of normality complete, dump and fsck
  23. are hacked. additionally, I made dumpfs verbose to excess.
  24.  
  25. stability is perfect, having been in since 0.1 came out.
  26.  
  27. to create fast symlinks, just put FASTLINKS in your kernel options, reconfig
  28. and rebuild.
  29. if you try to read a filesystem containing fast links with a kernel not built
  30. for them, you just get an einval when you reference any fast link. I call that
  31. a soft failure. a floppy boot disk needn't contain any symlinks anyway.
  32.  
  33. share and enjoy.
  34.  
  35. legalese:
  36. hack, slash, and redistribute all you want, just don't claim you wrote it.
  37.  
  38. @@@ Fin de ./README
  39. echo ./dump.diffs
  40. cat >./dump.diffs <<'@@@ Fin de ./dump.diffs'
  41. diff -c /usr/src/sbin/dump/dumptraverse.c /usr/src/sbin/dump.new/dumptraverse.c
  42. *** /usr/src/sbin/dump/dumptraverse.c    Wed Apr 24 17:55:03 1991
  43. --- /usr/src/sbin/dump.new/dumptraverse.c    Mon Nov  2 21:50:31 1992
  44. ***************
  45. *** 308,313 ****
  46. --- 308,320 ----
  47.           writeheader(ino);
  48.           return;
  49.       }
  50. +     if (DFASTLINK(*dp)) {
  51. +         spcl.c_addr[0] = 1;
  52. +         spcl.c_count = 1;
  53. +         writeheader(ino);
  54. +         writerec(dp->di_symlink);
  55. +         return;
  56. +     }
  57.       if (dp->di_size > NDADDR * sblock->fs_bsize)
  58.           cnt = NDADDR * sblock->fs_frag;
  59.       else
  60. @@@ Fin de ./dump.diffs
  61. echo ./fsck.diffs
  62. cat >./fsck.diffs <<'@@@ Fin de ./fsck.diffs'
  63. diff -c /usr/src/sbin/fsck/inode.c /usr/src/sbin/fsck.new/inode.c
  64. *** /usr/src/sbin/fsck/inode.c    Sat Apr 20 14:39:03 1991
  65. --- /usr/src/sbin/fsck.new/inode.c    Thu Oct 29 23:43:25 1992
  66. ***************
  67. *** 58,64 ****
  68.           idesc->id_fix = DONTKNOW;
  69.       idesc->id_entryno = 0;
  70.       idesc->id_filesize = dp->di_size;
  71. !     if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR)
  72.           return (KEEPON);
  73.       dino = *dp;
  74.       ndb = howmany(dino.di_size, sblock.fs_bsize);
  75. --- 58,65 ----
  76.           idesc->id_fix = DONTKNOW;
  77.       idesc->id_entryno = 0;
  78.       idesc->id_filesize = dp->di_size;
  79. !     if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR ||
  80. !         DFASTLINK(*dp))
  81.           return (KEEPON);
  82.       dino = *dp;
  83.       ndb = howmany(dino.di_size, sblock.fs_bsize);
  84. diff -c /usr/src/sbin/fsck/pass1.c /usr/src/sbin/fsck.new/pass1.c
  85. *** /usr/src/sbin/fsck/pass1.c    Sat Apr 20 14:39:04 1991
  86. --- /usr/src/sbin/fsck.new/pass1.c    Tue Nov  3 02:24:23 1992
  87. ***************
  88. *** 101,106 ****
  89. --- 101,113 ----
  90.                   continue;
  91.               }
  92.               lastino = inumber;
  93. +             /* is fast symlink? */
  94. +             if (DFASTLINK(*dp)) {
  95. +                 lncntp[inumber] = dp->di_nlink;
  96. +                 statemap[inumber] = FSTATE;
  97. +                 n_files++;
  98. +                 continue;
  99. +             }
  100.               if (/* dp->di_size < 0 || */
  101.                   dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
  102.                   if (debug)
  103. diff -c /usr/src/sbin/fsck/pass5.c /usr/src/sbin/fsck.new/pass5.c
  104. *** /usr/src/sbin/fsck/pass5.c    Sat Apr 20 14:39:05 1991
  105. --- /usr/src/sbin/fsck.new/pass5.c    Fri Oct 30 02:20:20 1992
  106. ***************
  107. *** 109,118 ****
  108. --- 109,122 ----
  109.           dmax = dbase + fs->fs_fpg;
  110.           if (dmax > fs->fs_size)
  111.               dmax = fs->fs_size;
  112. + #ifdef notdef
  113.           if (now > cg->cg_time)
  114.               newcg->cg_time = cg->cg_time;
  115.           else
  116.               newcg->cg_time = now;
  117. + #else
  118. +         newcg->cg_time = cg->cg_time;
  119. + #endif
  120.           newcg->cg_cgx = c;
  121.           if (c == fs->fs_ncg - 1)
  122.               newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
  123. @@@ Fin de ./fsck.diffs
  124. echo ./ufs.diffs
  125. cat >./ufs.diffs <<'@@@ Fin de ./ufs.diffs'
  126. diff -c /usr/src/sys.386bsd/ufs/dinode.h /usr/src/sys.386bsd/ufs.new/dinode.h
  127. *** /usr/src/sys.386bsd/ufs/dinode.h    Tue Dec 24 14:24:20 1991
  128. --- /usr/src/sys.386bsd/ufs.new/dinode.h    Thu Oct 29 21:17:53 1992
  129. ***************
  130. *** 41,46 ****
  131. --- 41,48 ----
  132.   #define    NDADDR    12        /* direct addresses in inode */
  133.   #define    NIADDR    3        /* indirect addresses in inode */
  134.   
  135. + #define    MAXFASTLINK    (((NDADDR+NIADDR) * sizeof(daddr_t)) - 1)
  136.   struct dinode {
  137.       u_short    di_mode;    /*  0: mode and type of file */
  138.       short    di_nlink;    /*  2: number of links to file */
  139. ***************
  140. *** 53,60 ****
  141.       long    di_mtspare;
  142.       time_t    di_ctime;    /* 32: last time inode changed */
  143.       long    di_ctspare;
  144. !     daddr_t    di_db[NDADDR];    /* 40: disk block addresses */
  145. !     daddr_t    di_ib[NIADDR];    /* 88: indirect blocks */
  146.       long    di_flags;    /* 100: status, currently unused */
  147.       long    di_blocks;    /* 104: blocks actually held */
  148.       long    di_gen;        /* 108: generation number */
  149. --- 55,67 ----
  150.       long    di_mtspare;
  151.       time_t    di_ctime;    /* 32: last time inode changed */
  152.       long    di_ctspare;
  153. !     union {
  154. !         struct {
  155. !             daddr_t    di_udb[NDADDR];    /* 40: disk block addresses */
  156. !             daddr_t    di_uib[NIADDR];    /* 88: indirect blocks */
  157. !         } di_addr;
  158. !         char di_usymlink[MAXFASTLINK];
  159. !     } di_un;
  160.       long    di_flags;    /* 100: status, currently unused */
  161.       long    di_blocks;    /* 104: blocks actually held */
  162.       long    di_gen;        /* 108: generation number */
  163. ***************
  164. *** 61,66 ****
  165. --- 68,77 ----
  166.       long    di_spare[4];    /* 112: reserved, currently unused */
  167.   };
  168.   
  169. + #define    di_db        di_un.di_addr.di_udb
  170. + #define    di_ib        di_un.di_addr.di_uib
  171. + #define    di_symlink    di_un.di_usymlink
  172.   #if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */
  173.   #define    di_size        di_qsize.val[0]
  174.   #else /* BYTE_ORDER == BIG_ENDIAN */
  175. ***************
  176. *** 84,86 ****
  177. --- 95,103 ----
  178.   #define    IREAD        0400        /* read permission */
  179.   #define    IWRITE        0200        /* write permission */
  180.   #define    IEXEC        0100        /* execute permission */
  181. + #define    DFASTLINK(di) \
  182. +     ((((di).di_mode & IFMT) == IFLNK) && \
  183. +         ((di).di_size <= MAXFASTLINK) && \
  184. +         ((di).di_size == (di).di_spare[0]))
  185. diff -c /usr/src/sys.386bsd/ufs/inode.h /usr/src/sys.386bsd/ufs.new/inode.h
  186. *** /usr/src/sys.386bsd/ufs/inode.h    Tue Dec 24 14:24:20 1991
  187. --- /usr/src/sys.386bsd/ufs.new/inode.h    Thu Oct 29 21:17:15 1992
  188. ***************
  189. *** 67,72 ****
  190. --- 67,74 ----
  191.       struct    dinode i_din;    /* the on-disk dinode */
  192.   };
  193.   
  194. + #define    FASTLINK(ip)    (DFASTLINK((ip)->i_din))
  195. + #define    i_symlink    i_din.di_symlink
  196.   #define    i_mode        i_din.di_mode
  197.   #define    i_nlink        i_din.di_nlink
  198.   #define    i_uid        i_din.di_uid
  199. diff -c /usr/src/sys.386bsd/ufs/ufs_inode.c /usr/src/sys.386bsd/ufs.new/ufs_inode.c
  200. *** /usr/src/sys.386bsd/ufs/ufs_inode.c    Tue Dec 24 14:24:20 1991
  201. --- /usr/src/sys.386bsd/ufs.new/ufs_inode.c    Thu Oct 29 21:16:02 1992
  202. ***************
  203. *** 406,411 ****
  204. --- 406,418 ----
  205.       struct inode tip;
  206.   
  207.       vnode_pager_setsize(ITOV(oip), length);
  208. +     if (FASTLINK(oip)) {
  209. +         if (length != 0)
  210. +             panic("itrunc fastlink to non-zero");
  211. +         bzero(oip->i_symlink, MAXFASTLINK);
  212. +         oip->i_size = 0;
  213. +         oip->i_din.di_spare[0] = 0;
  214. +     }
  215.       if (oip->i_size <= length) {
  216.           oip->i_flag |= ICHG|IUPD;
  217.           error = iupdat(oip, &time, &time, 1);
  218. diff -c /usr/src/sys.386bsd/ufs/ufs_vnops.c /usr/src/sys.386bsd/ufs.new/ufs_vnops.c
  219. *** /usr/src/sys.386bsd/ufs/ufs_vnops.c    Tue Dec 24 14:24:21 1991
  220. --- /usr/src/sys.386bsd/ufs.new/ufs_vnops.c    Thu Oct 29 21:28:34 1992
  221. ***************
  222. *** 31,36 ****
  223. --- 31,44 ----
  224.    * SUCH DAMAGE.
  225.    *
  226.    *    @(#)ufs_vnops.c    7.64 (Berkeley) 5/16/91
  227. +  *
  228. +  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
  229. +  * --------------------         -----   ----------------------
  230. +  * CURRENT PATCH LEVEL:         1       00007
  231. +  * --------------------         -----   ----------------------
  232. +  *
  233. +  * 20 Aug 92    David Greenman        Fixed incorrect setting of B_AGE after
  234. +  *                    each read to improve cache performance
  235.    */
  236.   
  237.   #include "param.h"
  238. ***************
  239. *** 497,504 ****
  240. --- 505,514 ----
  241.               return (error);
  242.           }
  243.           error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
  244. + #if OMIT    /* 20 Aug 92*/
  245.           if (n + on == fs->fs_bsize || uio->uio_offset == ip->i_size)
  246.               bp->b_flags |= B_AGE;
  247. + #endif    /* OMIT*/
  248.           brelse(bp);
  249.       } while (error == 0 && uio->uio_resid > 0 && n != 0);
  250.       return (error);
  251. ***************
  252. *** 1267,1278 ****
  253.       struct proc *p;
  254.   {
  255.       struct inode *ip;
  256.       int error;
  257.   
  258.       error = maknode(IFLNK | vap->va_mode, ndp, &ip);
  259.       if (error)
  260.           return (error);
  261. !     error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0,
  262.           UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0,
  263.           (struct proc *)0);
  264.       iput(ip);
  265. --- 1277,1298 ----
  266.       struct proc *p;
  267.   {
  268.       struct inode *ip;
  269. +     int len = strlen(target);
  270.       int error;
  271.   
  272.       error = maknode(IFLNK | vap->va_mode, ndp, &ip);
  273.       if (error)
  274.           return (error);
  275. ! #ifdef FASTLINKS
  276. !     if (len <= MAXFASTLINK) {
  277. !         ip->i_din.di_spare[0] = len;
  278. !         ip->i_size = len;
  279. !         bcopy(target, ip->i_symlink, len);
  280. !         ip->i_flag |= ICHG;
  281. !         error = iupdat(ip, &time, &time, 1);
  282. !     } else
  283. ! #endif
  284. !     error = vn_rdwr(UIO_WRITE, ITOV(ip), target, len, (off_t)0,
  285.           UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0,
  286.           (struct proc *)0);
  287.       iput(ip);
  288. ***************
  289. *** 1314,1321 ****
  290.       struct uio *uiop;
  291.       struct ucred *cred;
  292.   {
  293. !     return (ufs_read(vp, uiop, 0, cred));
  294.   }
  295.   
  296.   /*
  297. --- 1334,1344 ----
  298.       struct uio *uiop;
  299.       struct ucred *cred;
  300.   {
  301. !     struct inode *ip = VTOI(vp);
  302. !     if (FASTLINK(ip))
  303. !         return (uiomove(ip->i_symlink, ip->i_size, uiop));
  304. !     else
  305. !         return (ufs_read(vp, uiop, 0, cred));
  306.   }
  307.   
  308.   /*
  309. @@@ Fin de ./ufs.diffs
  310. mkdir ./usr
  311. mkdir ./usr/src
  312. mkdir ./usr/src/sbin
  313. mkdir ./usr/src/sbin/dumpfs
  314. echo ./usr/src/sbin/dumpfs/dumpfs.c
  315. cat >./usr/src/sbin/dumpfs/dumpfs.c <<'@@@ Fin de ./usr/src/sbin/dumpfs/dumpfs.c'
  316. #define    EXTREME
  317. /*
  318.  * Copyright (c) 1983 The Regents of the University of California.
  319.  * All rights reserved.
  320.  *
  321.  * Redistribution and use in source and binary forms, with or without
  322.  * modification, are permitted provided that the following conditions
  323.  * are met:
  324.  * 1. Redistributions of source code must retain the above copyright
  325.  *    notice, this list of conditions and the following disclaimer.
  326.  * 2. Redistributions in binary form must reproduce the above copyright
  327.  *    notice, this list of conditions and the following disclaimer in the
  328.  *    documentation and/or other materials provided with the distribution.
  329.  * 3. All advertising materials mentioning features or use of this software
  330.  *    must display the following acknowledgement:
  331.  *    This product includes software developed by the University of
  332.  *    California, Berkeley and its contributors.
  333.  * 4. Neither the name of the University nor the names of its contributors
  334.  *    may be used to endorse or promote products derived from this software
  335.  *    without specific prior written permission.
  336.  *
  337.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  338.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  339.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  340.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  341.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  342.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  343.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  344.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  345.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  346.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  347.  * SUCH DAMAGE.
  348.  */
  349. /*
  350.  * added much verbose hackery in conjunction with fast symlinks.
  351.  * curt mayer, 11 Dec 1992
  352.  */
  353.  
  354. #ifndef lint
  355. char copyright[] =
  356. "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
  357.  All rights reserved.\n";
  358. #endif /* not lint */
  359.  
  360. #ifndef lint
  361. static char sccsid[] = "@(#)dumpfs.c    5.10 (Berkeley) 6/1/90";
  362. #endif /* not lint */
  363.  
  364. #include <sys/param.h>
  365. #include <ufs/dinode.h>
  366. #include <ufs/dir.h>
  367. #include <ufs/fs.h>
  368.  
  369. #include <stdio.h>
  370. #include <fstab.h>
  371.  
  372. /*
  373.  * dumpfs
  374.  */
  375.  
  376. union {
  377.     struct fs fs;
  378.     char pad[MAXBSIZE];
  379. } fsun;
  380. #define    afs    fsun.fs
  381.  
  382. union {
  383.     struct cg cg;
  384.     char pad[MAXBSIZE];
  385. } cgun;
  386. #define    acg    cgun.cg
  387.  
  388. struct dinode *din;
  389.  
  390. extern char *malloc();
  391.  
  392. long    dev_bsize = 1;
  393.  
  394. main(argc, argv)
  395.     char **argv;
  396. {
  397.     register struct fstab *fs;
  398.  
  399.     argc--, argv++;
  400.     if (argc < 1) {
  401.         fprintf(stderr, "usage: dumpfs fs ...\n");
  402.         exit(1);
  403.     }
  404.     for (; argc > 0; argv++, argc--) {
  405.         fs = getfsfile(*argv);
  406.         if (fs == 0)
  407.             dumpfs(*argv);
  408.         else
  409.             dumpfs(fs->fs_spec);
  410.     }
  411. }
  412.  
  413. dumpfs(name)
  414.     char *name;
  415. {
  416.     int c, i, j, k, size;
  417.  
  418.     close(0);
  419.     if (open(name, 0) != 0) {
  420.         perror(name);
  421.         return;
  422.     }
  423.     lseek(0, SBOFF, 0);
  424.     if (read(0, &afs, SBSIZE) != SBSIZE) {
  425.         perror(name);
  426.         return;
  427.     }
  428.     if (afs.fs_postblformat == FS_42POSTBLFMT)
  429.         afs.fs_nrpos = 8;
  430.     dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1);
  431.     if (afs.fs_inopb > 0 && afs.fs_inopb <= 1024) {
  432.         din = (struct dinode *)
  433.             malloc(afs.fs_inopb * sizeof(struct dinode));
  434.     }
  435.     printf("magic\t%x\tformat\t%s\ttime\t%s", afs.fs_magic,
  436.         afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic",
  437.         ctime(&afs.fs_time));
  438.     printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
  439.         afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir,
  440.         afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree);
  441.     printf("ncg\t%d\tncyl\t%d\tsize\t%d\tblocks\t%d\n",
  442.         afs.fs_ncg, afs.fs_ncyl, afs.fs_size, afs.fs_dsize);
  443.     printf("bsize\t%d\tshift\t%d\tmask\t0x%08x\n",
  444.         afs.fs_bsize, afs.fs_bshift, afs.fs_bmask);
  445.     printf("fsize\t%d\tshift\t%d\tmask\t0x%08x\n",
  446.         afs.fs_fsize, afs.fs_fshift, afs.fs_fmask);
  447.     printf("frag\t%d\tshift\t%d\tfsbtodb\t%d\n",
  448.         afs.fs_frag, afs.fs_fragshift, afs.fs_fsbtodb);
  449.     printf("cpg\t%d\tbpg\t%d\tfpg\t%d\tipg\t%d\n",
  450.         afs.fs_cpg, afs.fs_fpg / afs.fs_frag, afs.fs_fpg, afs.fs_ipg);
  451.     printf("minfree\t%d%%\toptim\t%s\tmaxcontig %d\tmaxbpg\t%d\n",
  452.         afs.fs_minfree, afs.fs_optim == FS_OPTSPACE ? "space" : "time",
  453.         afs.fs_maxcontig, afs.fs_maxbpg);
  454.     printf("rotdelay %dms\theadswitch %dus\ttrackseek %dus\trps\t%d\n",
  455.         afs.fs_rotdelay, afs.fs_headswitch, afs.fs_trkseek, afs.fs_rps);
  456.     printf("ntrak\t%d\tnsect\t%d\tnpsect\t%d\tspc\t%d\n",
  457.         afs.fs_ntrak, afs.fs_nsect, afs.fs_npsect, afs.fs_spc);
  458.     printf("trackskew %d\tinterleave %d\n",
  459.         afs.fs_trackskew, afs.fs_interleave);
  460.     printf("nindir\t%d\tinopb\t%d\tnspf\t%d\n",
  461.         afs.fs_nindir, afs.fs_inopb, afs.fs_nspf);
  462.     printf("sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n",
  463.         afs.fs_sblkno, afs.fs_cblkno, afs.fs_iblkno, afs.fs_dblkno);
  464.     printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n",
  465.         afs.fs_sbsize, afs.fs_cgsize, afs.fs_cgoffset, afs.fs_cgmask);
  466.     printf("csaddr\t%d\tcssize\t%d\tshift\t%d\tmask\t0x%08x\n",
  467.         afs.fs_csaddr, afs.fs_cssize, afs.fs_csshift, afs.fs_csmask);
  468.     printf("cgrotor\t%d\tfmod\t%d\tronly\t%d\n",
  469.         afs.fs_cgrotor, afs.fs_fmod, afs.fs_ronly);
  470.     if (afs.fs_cpc != 0)
  471.         printf("blocks available in each of %d rotational positions",
  472.              afs.fs_nrpos);
  473.     else
  474.         printf("insufficient space to maintain rotational tables\n");
  475.     for (c = 0; c < afs.fs_cpc; c++) {
  476.         printf("\ncylinder number %d:", c);
  477.         for (i = 0; i < afs.fs_nrpos; i++) {
  478.             if (fs_postbl(&afs, c)[i] == -1)
  479.                 continue;
  480.             printf("\n   position %d:\t", i);
  481.             for (j = fs_postbl(&afs, c)[i], k = 1; ;
  482.                  j += fs_rotbl(&afs)[j], k++) {
  483.                 printf("%5d", j);
  484.                 if (k % 12 == 0)
  485.                     printf("\n\t\t");
  486.                 if (fs_rotbl(&afs)[j] == 0)
  487.                     break;
  488.             }
  489.         }
  490.     }
  491.     printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t");
  492.     for (i = 0, j = 0; i < afs.fs_cssize; i += afs.fs_bsize, j++) {
  493.         size = afs.fs_cssize - i < afs.fs_bsize ?
  494.             afs.fs_cssize - i : afs.fs_bsize;
  495.         afs.fs_csp[j] = (struct csum *)calloc(1, size);
  496.         lseek(0, fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag)) *
  497.             dev_bsize, 0);
  498.         if (read(0, afs.fs_csp[j], size) != size) {
  499.             perror(name);
  500.             return;
  501.         }
  502.     }
  503.     for (i = 0; i < afs.fs_ncg; i++) {
  504.         struct csum *cs = &afs.fs_cs(&afs, i);
  505.         if (i && i % 4 == 0)
  506.             printf("\n\t");
  507.         printf("(%d,%d,%d,%d) ",
  508.             cs->cs_nbfree, cs->cs_ndir, cs->cs_nifree, cs->cs_nffree);
  509.     }
  510.     printf("\n");
  511.     if (afs.fs_ncyl % afs.fs_cpg) {
  512.         printf("cylinders in last group %d\n",
  513.             i = afs.fs_ncyl % afs.fs_cpg);
  514.         printf("blocks in last group %d\n",
  515.             i * afs.fs_spc / NSPB(&afs));
  516.     }
  517.     printf("\n");
  518.     for (i = 0; i < afs.fs_ncg; i++)
  519.         dumpcg(name, i);
  520.     close(0);
  521. };
  522.  
  523. static char xxbuf[11];
  524.  
  525. char *
  526. modestr(k)
  527. unsigned short k;
  528. {
  529.     int type, i, mode;
  530.  
  531.     type = ((k & IFMT) >> 12) & 0xf;
  532.     xxbuf[0] = ".=c.d.b.-.l.s..."[type];
  533.     for (i = 0; i < 3; i++) {
  534.         mode = (k << (i * 3)) & (IREAD | IWRITE | IEXEC);
  535.         xxbuf[1 + (i * 3) + 0] = (mode & IREAD) ? 'r' : '-';
  536.         xxbuf[1 + (i * 3) + 1] = (mode & IWRITE) ? 'w' : '-';
  537.         xxbuf[1 + (i * 3) + 2] = (mode & IEXEC) ? 'x' : '-';
  538.     }
  539.     if (k & ISUID) xxbuf[1 + (0 * 3) + 2] = 's';
  540.     if (k & ISGID) xxbuf[1 + (1 * 3) + 2] = 's';
  541.     if (k & ISVTX) xxbuf[1 + (2 * 3) + 2] = 's';
  542.     xxbuf[10] = '\0';
  543.     return (xxbuf);    
  544. }
  545.  
  546. dumpcg(name, c)
  547.     char *name;
  548.     int c;
  549. {
  550.     int i, j;
  551.  
  552.     printf("\ncg %d:\n", c);
  553.     lseek(0, fsbtodb(&afs, cgtod(&afs, c)) * dev_bsize, 0);
  554.     i = lseek(0, 0, 1);
  555.     if (read(0, (char *)&acg, afs.fs_bsize) != afs.fs_bsize) {
  556.         printf("dumpfs: %s: error reading cg\n", name);
  557.         return;
  558.     }
  559.     printf("magic\t%x\ttell\t%x\ttime\t%s",
  560.         afs.fs_postblformat == FS_42POSTBLFMT ?
  561.         ((struct ocg *)&acg)->cg_magic : acg.cg_magic,
  562.         i, ctime(&acg.cg_time));
  563.     printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n",
  564.         acg.cg_cgx, acg.cg_ncyl, acg.cg_niblk, acg.cg_ndblk);
  565.     printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
  566.         acg.cg_cs.cs_nbfree, acg.cg_cs.cs_ndir,
  567.         acg.cg_cs.cs_nifree, acg.cg_cs.cs_nffree);
  568.     printf("rotor\t%d\tirotor\t%d\tfrotor\t%d\nfrsum",
  569.         acg.cg_rotor, acg.cg_irotor, acg.cg_frotor);
  570.     for (i = 1, j = 0; i < afs.fs_frag; i++) {
  571.         printf("\t%d", acg.cg_frsum[i]);
  572.         j += i * acg.cg_frsum[i];
  573.     }
  574.     printf("\nsum of frsum: %d\niused:\t", j);
  575.     pbits(c * afs.fs_ipg, cg_inosused(&acg), afs.fs_ipg);
  576.     printf("free:\t");
  577.     pbits(c * afs.fs_fpg, cg_blksfree(&acg), afs.fs_fpg);
  578.     printf("b:\n");
  579.     for (i = 0; i < afs.fs_cpg; i++) {
  580.         if (cg_blktot(&acg)[i] == 0)
  581.             continue;
  582.         printf("   c%d:\t(%d)\t", i, cg_blktot(&acg)[i]);
  583.         for (j = 0; j < afs.fs_nrpos; j++) {
  584.             if (afs.fs_cpc > 0 &&
  585.                 fs_postbl(&afs, i % afs.fs_cpc)[j] == -1)
  586.                 continue;
  587.             printf(" %d", cg_blks(&afs, &acg, i)[j]);
  588.         }
  589.         printf("\n");
  590.     }
  591.     if (din)
  592.         dumpinodes(c, name);
  593. };
  594.  
  595. dumpinodes(c, name)
  596. int c;
  597. char *name;
  598. {
  599.     int i, j, k, l, m;
  600.  
  601.     printf("inum\tmode\t\tlinks\tuid\tgid\tblocks\tsize\n");
  602.     for (i = 0; i < acg.cg_niblk; i += INOPB(&afs)) {
  603.         j = (afs.fs_ipg * c) + i;
  604.         lseek(0, (fsbtodb(&afs, itod(&afs, j)) * dev_bsize), 0);
  605.         if (read(0, (char *)din, INOPB(&afs) * sizeof(struct dinode)) != 
  606.             INOPB(&afs) * sizeof(struct dinode)) {
  607.             printf("dumpfs: %s: error reading inode\n", name);
  608.             return;
  609.         }
  610.         for (k = 0; k < INOPB(&afs); k++) {
  611. #ifdef EXTREME
  612.             int l, m;
  613.             char *p;
  614.             char c;
  615. #endif
  616.             if (!din[k].di_mode)
  617.                 continue;
  618. #ifdef EXTREME
  619.             p = (char *)&din[k];
  620.             for (l = 0; l < sizeof(din[k]); l += 16) {
  621.                 for (m = 0; m < 16; m++) {
  622.                     printf("%02x ", p[l+m] & 0xff);
  623.                 }
  624.                 printf("  ");
  625.                 for (m = 0; m < 16; m++) {
  626.                     c = p[l+m];
  627.                     if (c < 0x20 || c > 0x7e) c = '.';
  628.                     printf("%c", c);
  629.                 }
  630.                 printf("\n");
  631.             }
  632.             printf("\n");
  633. #endif
  634.             printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\n\t",
  635.                 j + k, modestr(din[k].di_mode),
  636.                 din[k].di_nlink, 
  637.                 din[k].di_uid,  din[k].di_gid, 
  638.                 din[k].di_blocks, din[k].di_size);
  639.  
  640.             /* dump fast symlink */
  641.             if (((din[k].di_mode & IFMT) == IFLNK) &&
  642.                 (din[k].di_size <= MAXFASTLINK) &&
  643.                 (din[k].di_size == din[k].di_spare[0])) {
  644.                 printf("%s\n\n", din[k].di_symlink);
  645.                 continue;
  646.             }
  647.  
  648.             /* dump cdev/bdev */
  649.             if (((din[k].di_mode & IFMT) == IFCHR) ||
  650.                 ((din[k].di_mode & IFMT) == IFBLK)) {
  651.                 printf("major %d minor %d (0x%x)\n\n", 
  652.                     major(din[k].di_rdev),
  653.                     minor(din[k].di_rdev),
  654.                     minor(din[k].di_rdev));
  655.                 continue;
  656.             }
  657.             
  658.             /* dump normal symlink */
  659.             if (((din[k].di_mode & IFMT) == IFLNK) &&
  660.                 ((din[k].di_size > MAXFASTLINK) ||
  661.                  (din[k].di_size != din[k].di_spare[0]))) {
  662.                 dumpsymlink(din[k].di_db[0], din[k].di_size, 
  663.                     name);
  664.             }
  665.  
  666.             /* dump directory */
  667.             if (((din[k].di_mode & IFMT) == IFDIR)) {
  668.                 printf("ino\tname\n\t");
  669.                 for (l = 0; l < NDADDR; l++) {
  670.                     dumpdirblk(din[k].di_db[l], 
  671.                         dblksize(&afs,&din[k], l), 
  672.                         name);
  673.                 }
  674.                 if (din[k].di_ib[0]) {
  675.                     printf("huge directory\n");
  676.                 }
  677.                 printf("\n\t");
  678.             }
  679.  
  680.             /* dump direct blocks */
  681.             for (m = NDADDR - 1; m >= 0; m--) {
  682.                 if (din[k].di_db[m] != 0)
  683.                     break;
  684.             }
  685.             for (l = 0 ; l <= m; l++) {
  686.                 printf("%d\t", din[k].di_db[l]);
  687.                 if (((l + 1) % 8) == 0) printf("\n\t");
  688.             }
  689.             if ((l % 8) != 0)
  690.                 printf("\n");
  691.             printf("\n");
  692.  
  693.             /* dump indirect blocks */
  694.             for (m = NIADDR - 1; m >= 0; m--) {
  695.                 if (din[k].di_ib[m] != 0)
  696.                     break;
  697.             }
  698.             for (l = 0 ; l <= m; l++) {
  699.                 dumpindir(l, din[k].di_ib[l], name);
  700.             }
  701.         }
  702.     }
  703. }
  704.  
  705. dumpdirblk(b, bs, name)
  706. int b;
  707. int bs;
  708. char *name;
  709. {
  710.     char *s, *p;
  711.     struct direct *d;
  712.  
  713.     if (!b)
  714.         return;
  715.  
  716.     lseek(0, fsbtodb(&afs, b) * dev_bsize, 0);
  717.     s = malloc(bs);
  718.     if (!s) {
  719.         printf("malloc failed\n");
  720.         return;
  721.     }
  722.     if (read(0, s, bs) != bs) {
  723.         printf("dumpfs: %s: error reading directory block\n", name);
  724.     }
  725.     for (p = s; p < &s[bs]; p += d->d_reclen) {
  726.         d = (struct direct *)p;
  727.         if (d->d_reclen > DIRSIZ(d))
  728.             continue;
  729.         printf("%d\t%s\n\t", d->d_ino, d->d_name);
  730.     }
  731. }
  732.  
  733. dumpsymlink(b, len, name)
  734. int b;
  735. int len;
  736. char *name;
  737. {
  738.     int i;
  739.     int m;
  740.     char *s;
  741.  
  742.     lseek(0, fsbtodb(&afs, b) * dev_bsize, 0);
  743.     s = malloc(afs.fs_bsize);
  744.     if (!s) {
  745.         printf("malloc failed\n");
  746.         return;
  747.     }
  748.     if (read(0, s, afs.fs_bsize) != afs.fs_bsize) {
  749.         printf("dumpfs: %s: error reading symlink block\n", name);
  750.     }
  751.     s[len] = '\0';
  752.     printf("%s\n\t", s);
  753.     free(s);
  754. }
  755.  
  756. dumpindir(d, b, name)
  757. int d;
  758. int b;
  759. char *name;
  760. {
  761.     daddr_t *indirs;
  762.     int i;
  763.     int m;
  764.  
  765.     printf("\tI%d %d:\n", d, b);
  766.     if (b == 0)
  767.         return;
  768.  
  769.     indirs = (daddr_t *)malloc(afs.fs_nindir * sizeof(daddr_t));
  770.     lseek(0, fsbtodb(&afs, b) * dev_bsize, 0);
  771.     if (read(0, (char *)indirs, afs.fs_nindir * sizeof(daddr_t)) != 
  772.         afs.fs_nindir * sizeof(daddr_t)) {
  773.         printf("dumpfs: %s: error reading indirect block\n", name);
  774.     }
  775.     if (d == 0) {
  776.         printf("\t");
  777.         
  778.         for (m = afs.fs_nindir - 1; m >= 0; m--) {
  779.             if (indirs[m] != 0)
  780.                 break;
  781.         }
  782.         for (i = 0; i <= m; i++) {
  783.             printf("%d\t", indirs[i]);
  784.             if (((i + 1) % 8) == 0) printf("\n\t");
  785.         }
  786.         if ((i % 8) != 0)
  787.             printf("\n");
  788.         printf("\n");
  789.     } else {
  790.         for (m = afs.fs_nindir - 1; m >= 0; m--) {
  791.             if (indirs[m] != 0)
  792.                 break;
  793.         }
  794.         for (i = 0; i <= m; i++) {
  795.             dumpindir(d - 1, indirs[i], name);
  796.         }
  797.     }
  798.     free((char *)indirs);
  799. }
  800.  
  801. pbits(base, cp, max)
  802.     int base;
  803.     register char *cp;
  804.     int max;
  805. {
  806.     register int i;
  807.     int count = 0, j;
  808.     int width = 0;
  809.  
  810.     for (i = 0; i < max; i++)
  811.         if (isset(cp, i)) {
  812.             if (count) {
  813.                 width += printf(",");
  814.                 if (width > 55) {
  815.                     printf("\n\t");
  816.                     width = 0;
  817.                 }
  818.             }
  819.             count++;
  820.             width += printf("%d", i+base);
  821.             j = i;
  822.             while ((i+1)<max && isset(cp, i+1))
  823.                 i++;
  824.             if (i != j)
  825.                 width += printf("-%d", i+base);
  826.         }
  827.     printf("\n");
  828. }
  829. @@@ Fin de ./usr/src/sbin/dumpfs/dumpfs.c
  830. exit 0
  831. ---------cut anywhere near here----------
  832. -- 
  833.     curt mayer
  834.         curt@toad.com
  835.         415-387-0217 home
  836.