Annotation of researchv10no/sys/os/subr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.