1: #include <stdio.h>
   2: #include <sys/param.h>
   3: #include <sys/systm.h>
   4: #include <sys/dir.h>
   5: #include <sys/user.h>
   6: #include <sys/vm.h>
   7: #include <sys/proc.h>
   8: #include <sys/pte.h>
   9: #include <sys/cmap.h>
  10: #include <sys/inode.h>
  11: #include <sys/buf.h>
  12: #include <sys/text.h>
  13: #include <sys/ino.h>
  14: 
  15: struct  buf *bread();
  16: struct  buf b;
  17: char    bc[BSIZE];
  18: int bflag;
  19: 
  20: main(argc, argv)
  21:     char *argv[];
  22: {
  23:     struct dinode di;
  24:     struct inode i;
  25:     struct proc p;
  26:     struct user u;
  27:     struct text x;
  28:     struct pte *pte;
  29:     int j,k,l;
  30: 
  31:     if (argc > 1 && !strcmp(argv[1], "-b"))
  32:         argc--, argv++, bflag++;
  33:     if (argc != 3) {
  34:         fprintf(stderr, "usage: copyout [ -b ] inum disk\n");
  35:         exit(1);
  36:     }
  37:     close(0);
  38:     if (open(argv[2], 0) != 0) {
  39:         perror(argv[2]);
  40:         exit(1);
  41:     }
  42:     lseek(0, itod(atoi(argv[1])) * BSIZE + itoo(atoi(argv[1])) * sizeof (di), 0);
  43:     if (read(0, &di, sizeof (di)) != sizeof (di)) {
  44:         fprintf(stderr, "error reading inode ");
  45:         perror(argv[1]);
  46:         exit(1);
  47:     }
  48:     i.i_dev = 0;
  49:     i.i_number = atoi(argv[1]);
  50:     i.i_flag = ILOCK;
  51:     i.i_count = 1;
  52:     i.i_un.i_lastr = 0;
  53:     i.i_mode = di.di_mode;
  54:     i.i_nlink = di.di_nlink;
  55:     i.i_uid = di.di_uid;
  56:     i.i_size = di.di_size;
  57:     l3tol(i.i_un.i_addr, di.di_addr, NADDR);
  58:     p.p_textp = &x;
  59:     x.x_iptr = &i;
  60:     b.b_un.b_addr = bc;
  61:     pte = (struct pte *)calloc(btoc(i.i_size), sizeof (struct pte));
  62:     if (pte == NULL) {
  63:         fprintf(stderr, "Not enough core for block pointers\n");
  64:         exit(1);
  65:     }
  66:     vinizfod(&p, pte, 0, (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE);
  67:     l = i.i_size;
  68:     for (j = 0; j < (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE; j++)
  69:         if (bflag)
  70:             printf("#%d: block %d\n", j, pte[j].pg_pfnum);
  71:         else {
  72:             k = imin(l, BSIZE);
  73:             write(1, bread(0, pte[j].pg_pfnum)->b_un.b_words, k);
  74:             brelse(&b);
  75:             l -= BSIZE;
  76:         }
  77:     exit(0);
  78: }
  79: 
  80: int bused;
  81: 
  82: struct buf *
  83: bread(dev, blk)
  84: {
  85: 
  86:     if (bused)
  87:         abort();
  88:     bused = 1;
  89:     printf("getblk %x\n", blk);
  90:     lseek(0, blk * BSIZE, 0);
  91:     if (read(0, b.b_un.b_addr, BSIZE) != BSIZE) {
  92:         printf("block %d: ", blk);
  93:         perror("bread");
  94:     }
  95:     return (&b);
  96: }
  97: 
  98: brelse(bp)
  99: struct buf *bp;
 100: {
 101: 
 102:     if (bp != &b)
 103:         abort();
 104:     bused = 0;
 105: }
 106: 
 107: struct  buf *vbmap();
 108: /*
 109:  * Initialize the page tables for paging from an inode,
 110:  * by scouring up the indirect blocks in order.
 111:  */
 112: vinizfod(p, pte, bstart, count)
 113:     struct proc *p;
 114:     register struct pte *pte;
 115:     daddr_t bstart;
 116:     int count;
 117: {
 118:     register struct inode *ip = p->p_textp->x_iptr;
 119:     register int i;
 120:     struct buf *bp;
 121:     int indx;
 122:     register daddr_t *pp;
 123: 
 124:     while (count > 0) {
 125:         if (bstart < NADDR - 3) {
 126:             pte++->pg_pfnum = ip->i_un.i_addr[bstart];
 127:             bstart++;
 128:             count--;
 129:         } else {
 130:             bp = vbmap(ip, bstart);
 131:             indx = (bstart - (NADDR - 3)) % NINDIR;
 132:             i = imin(NINDIR - indx, count);
 133:             bstart += i;
 134:             count -= i;
 135:             if (bp) {
 136:                 pp = &bp->b_un.b_daddr[indx];
 137:                 do
 138:                     pte++->pg_pfnum = *pp++;
 139:                 while (--i > 0);
 140:                 brelse(bp);
 141:             } else
 142:                 pte += i;
 143:         }
 144:     }
 145: }
 146: 
 147: /*
 148:  * Vbmap returns a block full of indirect pointers for a given block offset
 149:  * in a file.  It returns 0 if a missing address block was encountered,
 150:  * in which case the pages can be normal zfod pages.
 151:  */
 152: struct buf *
 153: vbmap(ip, bn)
 154: register struct inode *ip;
 155: daddr_t bn;
 156: {
 157:     register i;
 158:     struct buf *bp;
 159:     int j, sh;
 160:     daddr_t nb;
 161:     dev_t dev = ip->i_dev;
 162: 
 163:     if (bn < NADDR-3)
 164:         panic("vbmap");
 165: 
 166:     /*
 167: 	 * addresses NADDR-3, NADDR-2, and NADDR-1
 168: 	 * have single, double, triple indirect blocks.
 169: 	 * the first step is to determine
 170: 	 * how many levels of indirection.
 171: 	 */
 172:     sh = 0;
 173:     nb = 1;
 174:     bn -= NADDR-3;
 175:     for (j = 3; j > 0; j--) {
 176:         sh += NSHIFT;
 177:         nb <<= NSHIFT;
 178:         if(bn < nb)
 179:             break;
 180:         bn -= nb;
 181:     }
 182:     if (j == 0)
 183:         goto noblk;
 184: 
 185:     /*
 186: 	 * fetch the address from the inode
 187: 	 */
 188:     nb = ip->i_un.i_addr[NADDR-j];
 189: 
 190:     /*
 191: 	 * fetch through the indirect blocks
 192: 	 */
 193:     for (;;) {
 194:         if (nb == 0)
 195:             return ((daddr_t)0);
 196:         bp = bread(dev, nb);
 197:         if (bp->b_flags & B_ERROR) {
 198:             brelse(bp);
 199:             goto noblk;
 200:         }
 201:         if (j == 3)
 202:             break;
 203:         j++;
 204:         sh -= NSHIFT;
 205:         i = (bn>>sh) & NMASK;
 206:         nb = bp->b_un.b_daddr[i];
 207:         brelse(bp);
 208:         if (nb == 0)
 209:             goto noblk;
 210:     }
 211:     return (bp);
 212: 
 213: noblk:
 214:     return ((struct buf *)0);
 215: }
 216: 
 217: imin(a,b)
 218: {
 219:     return (a<b?a:b);
 220: }
 221: 
 222: panic(cp)
 223: {
 224:     printf(cp);
 225:     abort();
 226: }
 227: 
 228: char vmmap[1];
 229: char version[1];

Defined functions

bread defined in line 82; used 3 times
brelse defined in line 98; used 4 times
imin defined in line 217; used 2 times
main defined in line 20; never used
panic defined in line 222; used 1 times
vbmap defined in line 152; used 2 times
vinizfod defined in line 112; used 1 times
  • in line 66

Defined variables

b defined in line 16; used 8 times
bc defined in line 17; used 1 times
  • in line 60
bflag defined in line 18; used 2 times
bused defined in line 80; used 3 times
version defined in line 229; never used
vmmap defined in line 228; never used
Last modified: 1982-06-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1349
Valid CSS Valid XHTML 1.0 Strict