6400: #
6401: #include "../param.h"
6402: #include "../conf.h"
6403: #include "../inode.h"
6404: #include "../user.h"
6405: #include "../buf.h"
6406: #include "../systm.h"
6407:
6408: /* Bmap defines the structure of file system storage
6409: * by returning the physical block number on a device given the
6410: * inode and the logical block number in a file.
6411: * When convenient, it also leaves the physical
6412: * block number of the next block of the file in rablock
6413: * for use in read-ahead.
6414: */
6415: bmap(ip, bn)
6416: struct inode *ip;
6417: int bn;
6418: {
6419: register *bp, *bap, nb;
6420: int *nbp, d, i;
6421:
6422: d = ip->i_dev;
6423: if(bn & ~077777) {
6424: u.u_error = EFBIG;
6425: return(0);
6426: }
6427: if((ip->i_mode&ILARG) == 0) {
6428:
6429: /* small file algorithm */
6430:
6431: if((bn & ~7) != 0) {
6432:
6433: /* convert small to large */
6434:
6435: if ((bp = alloc(d)) == NULL)
6436: return(NULL);
6437: bap = bp->b_addr;
6438: for(i=0; i<8; i++) {
6439: *bap++ = ip->i_addr[i];
6440: ip->i_addr[i] = 0;
6441: }
6442: ip->i_addr[0] = bp->b_blkno;
6443: bdwrite(bp);
6444: ip->i_mode =| ILARG;
6445: goto large;
6446: }
6447: nb = ip->i_addr[bn];
6448: if(nb == 0 && (bp = alloc(d)) != NULL) {
6449: bdwrite(bp);
6450: nb = bp->b_blkno;
6451: ip->i_addr[bn] = nb;
6452: ip->i_flag =| IUPD;
6453: }
6454: rablock = 0;
6455: if (bn<7)
6456: rablock = ip->i_addr[bn+1];
6457: return(nb);
6458: }
6459:
6460: /* large file algorithm */
6461:
6462: large:
6463: i = bn>>8;
6464: if(bn & 0174000)
6465: i = 7;
6466: if((nb=ip->i_addr[i]) == 0) {
6467: ip->i_flag =| IUPD;
6468: if ((bp = alloc(d)) == NULL)
6469: return(NULL);
6470: ip->i_addr[i] = bp->b_blkno;
6471: } else
6472: bp = bread(d, nb);
6473: bap = bp->b_addr;
6474:
6475: /* "huge" fetch of double indirect block */
6476:
6477: if(i == 7) {
6478: i = ((bn>>8) & 0377) - 7;
6479: if((nb=bap[i]) == 0) {
6480: if((nbp = alloc(d)) == NULL) {
6481: brelse(bp);
6482: return(NULL);
6483: }
6484: bap[i] = nbp->b_blkno;
6485: bdwrite(bp);
6486: } else {
6487: brelse(bp);
6488: nbp = bread(d, nb);
6489: }
6490: bp = nbp;
6491: bap = bp->b_addr;
6492: }
6493:
6494: /* normal indirect fetch */
6495:
6496: i = bn & 0377;
6497: if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
6498: nb = nbp->b_blkno;
6499: bap[i] = nb;
6500: bdwrite(nbp);
6501: bdwrite(bp);
6502: } else
6503: brelse(bp);
6504: rablock = 0;
6505: if(i < 255)
6506: rablock = bap[i+1];
6507: return(nb);
6508: }
6509: /* --------------------------- */
6510:
6511: /*
6512: * Pass back c to the user at his location u_base;
6513: * update u_base, u_count, and u_offset. Return -1
6514: * on the last character of the user's read.
6515: * u_base is in the user address space unless u_segflg is set.
6516: */
6517: passc(c)
6518: char c;
6519: {
6520:
6521: if(u.u_segflg)
6522: *u.u_base = c; else
6523: if(subyte(u.u_base, c) < 0) {
6524: u.u_error = EFAULT;
6525: return(-1);
6526: }
6527: u.u_count--;
6528: if(++u.u_offset[1] == 0)
6529: u.u_offset[0]++;
6530: u.u_base++;
6531: return(u.u_count == 0? -1: 0);
6532: }
6533: /* --------------------------- */
6534:
6535: /*
6536: * Pick up and return the next character from the user's
6537: * write call at location u_base;
6538: * update u_base, u_count, and u_offset. Return -1
6539: * when u_count is exhausted. u_base is in the user's
6540: * address space unless u_segflg is set.
6541: */
6542: cpass()
6543: {
6544: register c;
6545:
6546: if(u.u_count == 0)
6547: return(-1);
6548: if(u.u_segflg)
6549: c = *u.u_base; else
6550: if((c=fubyte(u.u_base)) < 0) {
6551: u.u_error = EFAULT;
6552: return(-1);
6553: }
6554: u.u_count--;
6555: if(++u.u_offset[1] == 0)
6556: u.u_offset[0]++;
6557: u.u_base++;
6558: return(c&0377);
6559: }
6560: /* --------------------------- */
6561:
6562: /*
6563: * Routine which sets a user error; placed in
6564: * illegal entries in the bdevsw and cdevsw tables.
6565: */
6566: nodev()
6567: {
6568:
6569: u.u_error = ENODEV;
6570: }
6571: /* --------------------------- */
6572:
6573: /*
6574: * Null routine; placed in insignificant entries
6575: * in the bdevsw and cdevsw tables.
6576: */
6577: nulldev()
6578: {
6579: }
6580: /* --------------------------- */
6581:
6582: /*
6583: * copy count words from from to to.
6584: */
6585: bcopy(from, to, count)
6586: int *from, *to;
6587: {
6588: register *a, *b, c;
6589:
6590: a = from;
6591: b = to;
6592: c = count;
6593: do
6594: *b++ = *a++;
6595: while(--c);
6596: }
6597: /* --------------------------- */