|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/systm.h" ! 3: #include "sys/inode.h" ! 4: #include "sys/user.h" ! 5: #include "sys/buf.h" ! 6: #include "sys/proc.h" ! 7: ! 8: /* ! 9: * Bmap defines the structure of file system storage ! 10: * by returning the physical block number on a device given the ! 11: * inode and the logical block number in a file. ! 12: * When convenient, it also leaves the physical ! 13: * block number of the next block of the file in rablock ! 14: * for use in read-ahead. ! 15: */ ! 16: daddr_t ! 17: bmap(ip, bn, rwflg) ! 18: register struct inode *ip; ! 19: daddr_t bn; ! 20: { ! 21: register daddr_t i; ! 22: struct buf *bp, *nbp; ! 23: int j, sh; ! 24: daddr_t prev; ! 25: daddr_t nb, *bap; ! 26: dev_t dev; ! 27: ! 28: if(bn < 0) { ! 29: u.u_error = EFBIG; ! 30: return((daddr_t)0); ! 31: } ! 32: dev = ip->i_dev; ! 33: rablock = 0; ! 34: ! 35: /* ! 36: * blocks 0..NADDR-4 are direct blocks ! 37: */ ! 38: if(bn < NADDR-3) { ! 39: i = bn; ! 40: nb = ip->i_un.i_addr[i]; ! 41: if(nb == 0) { ! 42: prev = (i > 0? ip->i_un.i_addr[i-1]: 0); ! 43: if(rwflg==B_READ || (bp = alloc(ip, prev))==NULL) ! 44: return((daddr_t)-1); ! 45: nb = dbtofsb(dev, bp->b_blkno); ! 46: if ((ip->i_mode&IFMT) == IFDIR) ! 47: /* ! 48: * Write directory blocks synchronously ! 49: * so they never appear with garbage in ! 50: * them on the disk. ! 51: */ ! 52: bwrite(bp); ! 53: else ! 54: bdwrite(bp); ! 55: ip->i_un.i_addr[i] = nb; ! 56: ip->i_flag |= IUPD|ICHG; ! 57: } ! 58: if(i < NADDR-4) ! 59: rablock = ip->i_un.i_addr[i+1]; ! 60: return(nb); ! 61: } ! 62: ! 63: /* ! 64: * addresses NADDR-3, NADDR-2, and NADDR-1 ! 65: * have single, double, triple indirect blocks. ! 66: * the first step is to determine ! 67: * how many levels of indirection. ! 68: */ ! 69: sh = 0; ! 70: nb = 1; ! 71: bn -= NADDR-3; ! 72: for(j=3; j>0; j--) { ! 73: sh += NSHIFT(dev); ! 74: nb <<= NSHIFT(dev); ! 75: if(bn < nb) ! 76: break; ! 77: bn -= nb; ! 78: } ! 79: if(j == 0) { ! 80: u.u_error = EFBIG; ! 81: return((daddr_t)0); ! 82: } ! 83: ! 84: /* ! 85: * fetch the first indirect block ! 86: */ ! 87: nb = ip->i_un.i_addr[NADDR-j]; ! 88: if(nb == 0) { ! 89: prev = ip->i_un.i_addr[NADDR-j-1]; ! 90: if(rwflg==B_READ || (bp = alloc(ip, prev))==NULL) ! 91: return((daddr_t)-1); ! 92: nb = dbtofsb(dev, bp->b_blkno); ! 93: /* ! 94: * Write synchronously so that indirect blocks ! 95: * never point at garbage. ! 96: */ ! 97: bwrite(bp); ! 98: ip->i_un.i_addr[NADDR-j] = nb; ! 99: ip->i_flag |= IUPD|ICHG; ! 100: } ! 101: ! 102: /* ! 103: * fetch through the indirect blocks ! 104: */ ! 105: for(; j<=3; j++) { ! 106: bp = bread(dev, nb); ! 107: if(bp->b_flags & B_ERROR) { ! 108: brelse(bp); ! 109: return((daddr_t)0); ! 110: } ! 111: bap = bp->b_un.b_daddr; ! 112: sh -= NSHIFT(dev); ! 113: i = (bn>>sh) & NMASK(dev); ! 114: nb = bap[i]; ! 115: if(nb == 0) { ! 116: prev = (i>0? bap[i-1]: 0); ! 117: if(rwflg==B_READ || (nbp = alloc(ip, prev))==NULL) { ! 118: brelse(bp); ! 119: return((daddr_t)-1); ! 120: } ! 121: nb = dbtofsb(dev, nbp->b_blkno); ! 122: if (j < 3 || (ip->i_mode&IFMT) == IFDIR) ! 123: /* ! 124: * Write synchronously so indirect blocks ! 125: * never point at garbage and blocks ! 126: * in directories never contain garbage. ! 127: */ ! 128: bwrite(nbp); ! 129: else ! 130: bdwrite(nbp); ! 131: bap[i] = nb; ! 132: bdwrite(bp); ! 133: } else ! 134: brelse(bp); ! 135: } ! 136: ! 137: /* ! 138: * calculate read-ahead. ! 139: */ ! 140: if(i < NINDIR(dev)-1) ! 141: rablock = bap[i+1]; ! 142: return(nb); ! 143: } ! 144: ! 145: /* ! 146: * Pass back c to the user at his location u_base; ! 147: * update u_base, u_count, and u_offset. Return -1 ! 148: * on the last character of the user's read. ! 149: * u_base is in the user address space unless u_segflg is set. ! 150: */ ! 151: passc(c) ! 152: register c; ! 153: { ! 154: register id; ! 155: ! 156: if((id = u.u_segflg) == SEGSYS) ! 157: *u.u_base = c; ! 158: else ! 159: if(id==SEGUINST?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) { ! 160: u.u_error = EFAULT; ! 161: return(-1); ! 162: } ! 163: u.u_count--; ! 164: u.u_offset = Lladd(u.u_offset, 1); ! 165: u.u_base++; ! 166: return(u.u_count == 0? -1: 0); ! 167: } ! 168: ! 169: /* ! 170: * Pick up and return the next character from the user's ! 171: * write call at location u_base; ! 172: * update u_base, u_count, and u_offset. Return -1 ! 173: * when u_count is exhausted. u_base is in the user's ! 174: * address space unless u_segflg is set. ! 175: */ ! 176: cpass() ! 177: { ! 178: register c, id; ! 179: ! 180: if(u.u_count == 0) ! 181: return(-1); ! 182: if((id = u.u_segflg) == SEGSYS) ! 183: c = *u.u_base; ! 184: else ! 185: if((c = id==SEGUDATA?fubyte(u.u_base):fuibyte(u.u_base)) < 0) { ! 186: u.u_error = EFAULT; ! 187: return(-1); ! 188: } ! 189: u.u_count--; ! 190: u.u_offset = Lladd(u.u_offset, 1); ! 191: u.u_base++; ! 192: return(c&0377); ! 193: } ! 194: ! 195: /* ! 196: * Routine which sets a user error; placed in ! 197: * illegal entries in the bdevsw and cdevsw tables. ! 198: */ ! 199: nodev() ! 200: { ! 201: ! 202: u.u_error = ENODEV; ! 203: } ! 204: ! 205: /* ! 206: * Null routine; placed in insignificant entries ! 207: * in the bdevsw and cdevsw tables. ! 208: */ ! 209: nulldev() ! 210: { ! 211: ! 212: } ! 213: ! 214: imin(a, b) ! 215: { ! 216: ! 217: return (a < b ? a : b); ! 218: } ! 219: ! 220: imax(a, b) ! 221: { ! 222: ! 223: return (a > b ? a : b); ! 224: } ! 225: ! 226: /* ! 227: * this should probably come out eventually ! 228: */ ! 229: struct proc * ! 230: pfind(pid) ! 231: register int pid; ! 232: { ! 233: register struct proc *p; ! 234: ! 235: for (p = proc; p < procNPROC; p++) ! 236: if (p->p_stat && p->p_pid == pid) ! 237: return (p); ! 238: return (NULL); ! 239: } ! 240: ! 241: strncmp(s1, s2, len) ! 242: register char *s1, *s2; ! 243: register len; ! 244: { ! 245: do { ! 246: if (*s1 != *s2++) ! 247: return(1); ! 248: if (*s1++ == '\0') ! 249: return(0); ! 250: } while (--len); ! 251: return(0); ! 252: } ! 253: ! 254: strcpy(to, fr) ! 255: register char *to, *fr; ! 256: { ! 257: while (*to++ = *fr++) ! 258: ; ! 259: } ! 260: ! 261: /* ! 262: * long-long support ! 263: */ ! 264: ! 265: #define M 0x80000000 ! 266: ! 267: unsigned ! 268: Lshift(ll, l) ! 269: llong_t ll; ! 270: long l; ! 271: { ! 272: return (ll.hi<<(32-l)) | (ll.lo>>l); ! 273: } ! 274: ! 275: llong_t ! 276: ltoL(l) ! 277: long l; ! 278: { ! 279: llong_t t; ! 280: ! 281: t.hi = 0; ! 282: t.lo = l; ! 283: return t; ! 284: } ! 285: ! 286: llong_t ! 287: Lladd(ll, l) ! 288: llong_t ll; ! 289: long l; ! 290: { ! 291: llong_t t; ! 292: long cin; ! 293: ! 294: t = ll; ! 295: t.lo += l; ! 296: cin = ll.lo^t.lo; ! 297: if (l>=0) { ! 298: if ((ll.lo&cin)&M) ! 299: t.hi++; ! 300: } else { ! 301: if ((~ll.lo&cin)&M) ! 302: t.hi--; ! 303: } ! 304: return t; ! 305: } ! 306: ! 307: llong_t ! 308: Luadd(ll, u) ! 309: llong_t ll; ! 310: unsigned long u; ! 311: { ! 312: llong_t t; ! 313: long cin; ! 314: ! 315: t = ll; ! 316: t.lo += u; ! 317: cin = ll.lo^t.lo; ! 318: if ((ll.lo&cin)&M) ! 319: t.hi++; ! 320: return t; ! 321: } ! 322: ! 323: llong_t ! 324: LLadd(lla, llb) ! 325: llong_t lla, llb; ! 326: { ! 327: llong_t t; ! 328: ! 329: t.hi = lla.hi+llb.hi; ! 330: t.lo = lla.lo+llb.lo; ! 331: if ((lla.lo&llb.lo | lla.lo&~t.lo | llb.lo&~t.lo)&M) ! 332: t.hi++; ! 333: return t; ! 334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.