Annotation of researchv10no/sys/os/fio.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/user.h"
        !             3: #include "sys/filsys.h"
        !             4: #include "sys/file.h"
        !             5: #include "sys/conf.h"
        !             6: #include "sys/inode.h"
        !             7: #include "sys/stream.h"
        !             8: #include "sys/buf.h"
        !             9: #include "sys/acct.h"
        !            10: 
        !            11: /*
        !            12:  * Convert a user supplied
        !            13:  * file descriptor into a pointer
        !            14:  * to a file structure.
        !            15:  * Only task is to check range
        !            16:  * of the descriptor.
        !            17:  */
        !            18: 
        !            19: #ifndef getf   /* done inline */
        !            20: 
        !            21: struct file *
        !            22: getf(f)
        !            23: register int f;
        !            24: {
        !            25:        register struct file *fp;
        !            26: 
        !            27:        if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL)
        !            28:                return (NULL);
        !            29:        return (fp);
        !            30: }
        !            31: 
        !            32: #endif
        !            33: 
        !            34: /*
        !            35:  * Internal form of close.
        !            36:  * Decrement reference count on
        !            37:  * file structure.
        !            38:  * Decrement reference count on the inode following
        !            39:  * removal to the referencing file structure.
        !            40:  */
        !            41: closef(fp)
        !            42: register struct file *fp;
        !            43: {
        !            44:        struct inode *ip;
        !            45: 
        !            46:        if(fp == NULL)
        !            47:                return;
        !            48:        if (fp->f_count > 1) {
        !            49:                fp->f_count--;
        !            50:                return;
        !            51:        }
        !            52:        ip = fp->f_inode;
        !            53:        plock(ip);
        !            54:        iput(ip);
        !            55:        fp->f_count = 0;
        !            56: }
        !            57: 
        !            58: /*
        !            59:  * close the file opened on ip
        !            60:  * called from iput when last reference is removed;
        !            61:  * ip is locked, and i_count == 1
        !            62:  *
        !            63:  * free files with no links;
        !            64:  * call device driver for special files
        !            65:  */
        !            66: 
        !            67: extern int rootfstyp;
        !            68: extern dev_t rootdev;
        !            69: 
        !            70: closei(ip)
        !            71: register struct inode *ip;
        !            72: {
        !            73:        register dev_t dev;
        !            74:        register int (*cfunc)();
        !            75: 
        !            76:        if (ip->i_sptr)
        !            77:                stclose(ip, 1);
        !            78:        if ((ip->i_flag & IOPEN) == 0)
        !            79:                return;
        !            80:        ip->i_flag &=~ IOPEN;
        !            81:        if(ip->i_fstyp)         /* temporary hack */
        !            82:                return;
        !            83:        dev = (dev_t)ip->i_un.i_rdev;
        !            84:        switch(ip->i_mode & IFMT) {
        !            85: 
        !            86:        case IFCHR:
        !            87:                cfunc = cdevsw[major(dev)]->d_close;
        !            88:                break;
        !            89: 
        !            90:        case IFBLK:
        !            91:                if (rootfstyp == 0 && rootdev == dev)   /* awful hack: root is not open */
        !            92:                        return;
        !            93:                bflush(dev);
        !            94:                binval(dev);
        !            95:                cfunc = bdevsw[major(dev)]->d_close;
        !            96:                break;
        !            97: 
        !            98:        default:
        !            99:                return;
        !           100:        }
        !           101:        (*cfunc)(dev);
        !           102: }
        !           103: 
        !           104: /*
        !           105:  * the default open routine for the file system switch entry `t_open'
        !           106:  */
        !           107: struct inode *
        !           108: nullopen(ip, rw)
        !           109:        struct inode *ip;
        !           110: {
        !           111:        return(ip);
        !           112: }
        !           113: 
        !           114: /*
        !           115:  * openi called to allow handler
        !           116:  * of special files to initialize and
        !           117:  * validate before actual IO.
        !           118:  * returns the inode,
        !           119:  * NULL if error.
        !           120:  * may return an alternate inode,
        !           121:  * in which event the original has been put.
        !           122:  *
        !           123:  * responsibilities of open routines (fs and stream):
        !           124:  * if an inode is returned, it is unlocked,
        !           125:  * and any other inode has been put.
        !           126:  * if an error happens, NULL is returned and ip is put.
        !           127:  */
        !           128: struct inode *
        !           129: openi(ip, rw)
        !           130: register struct inode *ip;
        !           131: {
        !           132:        register dev_t dev;
        !           133: 
        !           134:        dev = (dev_t)ip->i_un.i_rdev;
        !           135:        if (ip->i_sptr)                 /* stream is attached */
        !           136:                ip = stopen(cdevsw[major(dev)]->qinfo, dev, rw, ip);
        !           137:        else
        !           138:                ip = (*fstypsw[ip->i_fstyp]->t_open)(ip, rw);
        !           139:        if (ip)
        !           140:                ip->i_flag |= IOPEN;
        !           141:        else if (u.u_error == 0)                /* temporary firewall */
        !           142:                panic("openi");
        !           143:        return (ip);
        !           144: }
        !           145: 
        !           146: /*
        !           147:  * Check mode permission on inode pointer.
        !           148:  * Mode is READ, WRITE or EXEC.
        !           149:  * In the case of WRITE, the
        !           150:  * read-only status of the file
        !           151:  * system is checked.
        !           152:  * Also in WRITE, prototype text
        !           153:  * segments cannot be written.
        !           154:  * The mode is shifted to select
        !           155:  * the owner/group/other fields.
        !           156:  * The super user is granted all
        !           157:  * permissions.
        !           158:  */
        !           159: access(ip, mode)
        !           160: register struct inode *ip;
        !           161: {
        !           162:        register m;
        !           163:        register short *gp;
        !           164: 
        !           165:        m = mode;
        !           166:        if(m == IWRITE) {
        !           167:                if(ip->i_fstyp==0 && ip->i_un.i_bufp->b_un.b_filsys->s_ronly != 0) {
        !           168:                        u.u_error = EROFS;
        !           169:                        return(1);
        !           170:                }
        !           171:                if (ip->i_flag&ITEXT)           /* try to free text */
        !           172:                        xrele(ip);
        !           173:                if(ip->i_flag & ITEXT) {
        !           174:                        u.u_error = ETXTBSY;
        !           175:                        return(1);
        !           176:                }
        !           177:        }
        !           178:        if(u.u_uid == 0)
        !           179:                return(0);
        !           180:        if(u.u_uid != ip->i_uid) {
        !           181:                m >>= 3;
        !           182:                if(u.u_gid == ip->i_gid)
        !           183:                        goto found;
        !           184:                gp = u.u_groups;
        !           185:                for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
        !           186:                        if (ip->i_gid == *gp)
        !           187:                                goto found;
        !           188:                m >>= 3;
        !           189:        }
        !           190: found:
        !           191:        if((ip->i_mode&m) != 0)
        !           192:                return(0);
        !           193: 
        !           194:        u.u_error = EACCES;
        !           195:        return(1);
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * check inode ownership.
        !           200:  * succeeds if the current user owns the file,
        !           201:  * or is the super-user.
        !           202:  */
        !           203: accowner(ip)
        !           204: register struct inode *ip;
        !           205: {
        !           206: 
        !           207:        if(u.u_uid == ip->i_uid)
        !           208:                return(1);
        !           209:        if(suser())
        !           210:                return(1);
        !           211:        return(0);
        !           212: }
        !           213: 
        !           214: /*
        !           215:  *  Return 0 if the file isn't open for writing, 1 if it is
        !           216:  */
        !           217: writers(ip)
        !           218:        register struct inode *ip;
        !           219: {
        !           220:        register struct file *fp;
        !           221: 
        !           222:        for (fp = file; fp < fileNFILE; fp++)
        !           223:                if (fp->f_count!=0 && fp->f_inode==ip && (fp->f_flag&FWRITE))
        !           224:                        return(1);
        !           225:        return(0);
        !           226: }
        !           227: 
        !           228: /*
        !           229:  *  Control concurrent access to a file.  The possibile types are:
        !           230:  *  - 1 writer and n readers   (I1WNR)
        !           231:  *  - 1 writer or n readers    (ILCKD)
        !           232:  *  The file pointers are searched.  If an open with the given mode
        !           233:  *  would result in a violation, errno is set to ECONC.
        !           234:  */
        !           235: concurrency(ip, mode)
        !           236:        register struct inode *ip;
        !           237:        int mode;
        !           238: {
        !           239:        switch(ip->i_mode&ICCTYP) {
        !           240:        case ISYNC:
        !           241:                if ((mode&FWRITE) && writers(ip))
        !           242:                        u.u_error = ECONC;
        !           243:                break;
        !           244:        case IEXCL:
        !           245:                if ((mode&FWRITE) || writers(ip))
        !           246:                        u.u_error = ECONC;
        !           247:                break;
        !           248:        }
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * Test if the current user is the
        !           253:  * super user.
        !           254:  */
        !           255: suser()
        !           256: {
        !           257: 
        !           258:        if(u.u_uid == 0) {
        !           259:                u.u_acflag |= ASU;
        !           260:                return(1);
        !           261:        }
        !           262:        u.u_error = EPERM;
        !           263:        return(0);
        !           264: }
        !           265: 
        !           266: /*
        !           267:  * Allocate a user file descriptor.
        !           268:  */
        !           269: ufalloc()
        !           270: {
        !           271:        register i;
        !           272: 
        !           273:        for(i=0; i<NOFILE; i++)
        !           274:                if(u.u_ofile[i] == NULL) {
        !           275:                        u.u_r.r_val1 = i;
        !           276:                        u.u_pofile[i] = 0;
        !           277:                        return(i);
        !           278:                }
        !           279:        u.u_error = EMFILE;
        !           280:        return(-1);
        !           281: }
        !           282: 
        !           283: struct file *lastf;
        !           284: /*
        !           285:  * Allocate a user file descriptor
        !           286:  * and a file structure.
        !           287:  * Initialize the descriptor
        !           288:  * to point at the file structure.
        !           289:  */
        !           290: struct file *
        !           291: falloc()
        !           292: {
        !           293:        register struct file *fp;
        !           294:        register i;
        !           295: 
        !           296:        i = ufalloc();
        !           297:        if (i < 0)
        !           298:                return(NULL);
        !           299:        if ((fp = allocfile()) == NULL) {
        !           300:                u.u_error = ENFILE;
        !           301:                return(NULL);
        !           302:        }
        !           303:        u.u_ofile[i] = fp;
        !           304:        return (fp);
        !           305: }
        !           306: 
        !           307: /*
        !           308:  * allocate file structure
        !           309:  */
        !           310: struct file *
        !           311: allocfile()
        !           312: {
        !           313:        register struct file *fp;
        !           314: 
        !           315:        if (lastf == 0)
        !           316:                lastf = file;
        !           317:        for (fp = lastf; fp < fileNFILE; fp++)
        !           318:                if (fp->f_count == 0)
        !           319:                        goto gotit;
        !           320:        for (fp = file; fp < lastf; fp++)
        !           321:                if (fp->f_count == 0)
        !           322:                        goto gotit;
        !           323:        tablefull("file");
        !           324:        return (NULL);
        !           325: gotit:
        !           326:        lastf = fp + 1;
        !           327:        fp->f_count++;
        !           328:        fp->f_offset = ltoL(0);
        !           329:        return(fp);
        !           330: }

unix.superglobalmegacorp.com

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