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