|
|
1.1 ! root 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];
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.