Annotation of researchv10no/sys/os/subr.c, revision 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.