Annotation of researchv9/sys.vax/sys/iget.c, revision 1.1

1.1     ! root        1: /*     iget.c  4.4     81/03/08        */
        !             2: 
        !             3: #include "../h/param.h"
        !             4: #include "../h/systm.h"
        !             5: #include "../h/mount.h"
        !             6: #include "../h/dir.h"
        !             7: #include "../h/user.h"
        !             8: #include "../h/inode.h"
        !             9: #include "../h/ino.h"
        !            10: #include "../h/filsys.h"
        !            11: #include "../h/conf.h"
        !            12: #include "../h/buf.h"
        !            13: #include "../h/trace.h"
        !            14: #include "../h/proc.h"
        !            15: 
        !            16: #define        INOHSZ  63
        !            17: /* INOHASH can't depend on fstype as long as unmount changes fstyp to err-fs */
        !            18: #define        INOHASH(dev, ino)       (((dev)+(ino))%INOHSZ)
        !            19: struct inode *inohash[INOHSZ];
        !            20: struct inode *ifreel;
        !            21: 
        !            22: /*
        !            23:  * Initialize hash links for inodes
        !            24:  * and build inode free list.
        !            25:  */
        !            26: ihinit()
        !            27: {
        !            28:        register int i;
        !            29:        register struct inode *ip = inode;
        !            30: 
        !            31:        ifreel = inode;
        !            32:        for (i = 0; i < ninode-1; i++, ip++)
        !            33:                ip->i_hlink = ip + 1;
        !            34:        ip->i_hlink = NULL;
        !            35:        for (i = 0; i < INOHSZ; i++)
        !            36:                inohash[i] = NULL;
        !            37: }
        !            38: 
        !            39: /*
        !            40:  * Find an inode if it is incore.
        !            41:  * This is the equivalent, for inodes,
        !            42:  * of ``incore'' in bio.c or ``pfind'' in subr.c.
        !            43:  */
        !            44: struct inode *
        !            45: ifind(hp, ino)
        !            46: register struct inode *hp;
        !            47: register ino_t ino;
        !            48: {
        !            49:        register struct inode *ip;
        !            50: 
        !            51:        for (ip = inohash[INOHASH(hp->i_dev,ino)]; ip; ip = ip->i_hlink)
        !            52:                if (ino==ip->i_number && hp->i_dev==ip->i_dev && hp->i_fstyp==ip->i_fstyp)
        !            53:                        return (ip);
        !            54:        return ((struct inode *)0);
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * default entry for file system switch entry `t_get'
        !            59:  * put the inode, set errno, and return null.
        !            60:  */
        !            61: struct inode *
        !            62: nullget(fip, dev, ino, ip)
        !            63:        struct inode *fip;
        !            64:        dev_t dev;
        !            65:        ino_t ino;
        !            66:        struct inode *ip;
        !            67: {
        !            68:        iput(ip);
        !            69:        u.u_error = ENXIO;
        !            70:        return(NULL);
        !            71: }
        !            72: 
        !            73: 
        !            74: /*
        !            75:  * Look up an inode by filsys, i-number.
        !            76:  * filsys is denoted by some inode in that filesystem.
        !            77:  * If it is in core (in the inode structure),
        !            78:  * honor the locking protocol.
        !            79:  * If it is not in core, read it in from the
        !            80:  * specified device.
        !            81:  * If the inode is mounted on, perform
        !            82:  * the indicated indirection.
        !            83:  * In all cases, a pointer to a locked
        !            84:  * inode structure is returned.
        !            85:  *
        !            86:  * panic: iget mroot -- if the mounted file
        !            87:  *     system root is missing
        !            88:  *     "cannot happen"
        !            89:  */
        !            90: struct inode *
        !            91: iget(fip, dev, ino)
        !            92: register struct inode *fip;
        !            93: dev_t dev;
        !            94: register ino_t ino;
        !            95: {
        !            96:        register struct inode *ip;
        !            97:        register int slot;
        !            98: 
        !            99: loop:
        !           100:        slot = INOHASH(dev, ino);
        !           101:        for (ip = inohash[slot]; ip; ip = ip->i_hlink) {
        !           102:                if(ino == ip->i_number && dev == ip->i_dev
        !           103:                        && fip->i_fstyp == ip->i_fstyp) {
        !           104: mloop:
        !           105:                        if((ip->i_flag&ILOCK) != 0) {
        !           106:                                ip->i_flag |= IWANT;
        !           107:                                ip->i_count++;  /* don't move! */
        !           108:                                sleep((caddr_t)ip, PINOD);
        !           109:                                ip->i_count--;
        !           110:                                goto loop;
        !           111:                        }
        !           112:                        if((ip->i_flag&IMOUNT) != 0) {
        !           113:                                if (ip->i_mroot == NULL)
        !           114:                                        panic("iget mroot");
        !           115:                                ip = ip->i_mroot;
        !           116:                                goto mloop;
        !           117:                        }
        !           118:                        ip->i_count++;
        !           119:                        ip->i_flag |= ILOCK;
        !           120:                        return(ip);
        !           121:                }
        !           122:        }
        !           123:        if(ifreel == NULL) {
        !           124:                tablefull("inode");
        !           125:                u.u_error = ENFILE;
        !           126:                return(NULL);
        !           127:        }
        !           128:        ip = ifreel;
        !           129:        ifreel = ip->i_hlink;
        !           130:        ip->i_hlink = inohash[slot];
        !           131:        inohash[slot] = ip;
        !           132:        ip->i_dev = dev;
        !           133:        ip->i_fstyp = fip->i_fstyp;
        !           134:        ip->i_number = ino;
        !           135:        ip->i_flag = ILOCK;
        !           136:        ip->i_count++;
        !           137:        ip->i_sptr = NULL;
        !           138:        ip->i_mroot = NULL;
        !           139:        ip->i_mpoint = fip->i_mpoint;   /* namei will fill in */
        !           140:        return((*fstypsw[fip->i_fstyp].t_get)(fip, dev, ino, ip));
        !           141: }
        !           142: 
        !           143: /*
        !           144:  * Decrement reference count of
        !           145:  * an inode structure.
        !           146:  * On the last reference,
        !           147:  * write the inode out and if necessary,
        !           148:  * truncate and deallocate the file.
        !           149:  */
        !           150: 
        !           151: iput(ip)
        !           152: register struct inode *ip;
        !           153: {
        !           154:        register int i;
        !           155:        register struct inode *jp;
        !           156: 
        !           157:        if(ip->i_count == 1) {
        !           158:                ip->i_flag |= ILOCK;
        !           159:                if(ip->i_nlink <= 0)
        !           160:                        (*fstypsw[ip->i_fstyp].t_free)(ip);
        !           161:                (*fstypsw[ip->i_fstyp].t_put)(ip);
        !           162:                i = INOHASH(ip->i_dev, ip->i_number);
        !           163:                if (inohash[i] == ip)
        !           164:                        inohash[i] = ip->i_hlink;
        !           165:                else {
        !           166:                        for (jp = inohash[i]; jp; jp = jp->i_hlink)
        !           167:                                if (jp->i_hlink == ip) {
        !           168:                                        jp->i_hlink = ip->i_hlink;
        !           169:                                        goto done;
        !           170:                                }
        !           171:                        panic("iput");
        !           172:                }
        !           173: done:
        !           174:                prele(ip);
        !           175:                ip->i_hlink = ifreel;
        !           176:                ifreel = ip;
        !           177:                ip->i_flag = 0;
        !           178:                ip->i_number = 0;
        !           179:        } else if(ip->i_count == 0) {
        !           180:                panic("i_count==0");
        !           181:                printf("i_count==0, ip %x dev %x ino %d fstyp %d\n", ip, ip->i_dev,
        !           182:                        ip->i_number, ip->i_fstyp);
        !           183:                return; /* that leaves the turkey locked (for safety) */
        !           184:        } else
        !           185:                prele(ip);
        !           186:        ip->i_count--;
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * Check accessed and update flags on
        !           191:  * an inode structure.
        !           192:  * If any is on, update the inode
        !           193:  * with the current time.
        !           194:  * If waitfor is given, then must insure
        !           195:  * i/o order so wait for write to complete.
        !           196:  */
        !           197: iupdat(ip, ta, tm, waitfor)
        !           198: register struct inode *ip;
        !           199: time_t *ta, *tm;
        !           200: int waitfor;
        !           201: {
        !           202: 
        !           203:        if((ip->i_flag&(IUPD|IACC|ICHG)) != 0)
        !           204:                (*fstypsw[ip->i_fstyp].t_updat)(ip, ta, tm, waitfor);
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * create a non-disk inode for a file system type;
        !           209:  * the inode returned is plocked and must be either
        !           210:  * iput or prele'sed.
        !           211:  */
        !           212: struct inode *
        !           213: ifake(fstyp)
        !           214:        int fstyp;
        !           215: {
        !           216:        struct inode *ip;
        !           217:        static ino_t ino=0;
        !           218:        ino_t inostart;
        !           219:        struct inode pi;                /* primer */
        !           220: 
        !           221:        pi.i_dev = 0;
        !           222:        pi.i_fstyp = fstyp;
        !           223:        for(inostart=ino;;) {
        !           224:                ip = iget(&pi, 0, ino);
        !           225:                if (ip == NULL)
        !           226:                        return(NULL);
        !           227:                if (ip->i_count == 1)
        !           228:                        break;
        !           229:                /*
        !           230:                 *  This inode is still in use - pick another
        !           231:                 */
        !           232:                iput(ip);
        !           233:                /*
        !           234:                 *  Make sure we haven't gone through all the inodes
        !           235:                 */
        !           236:                if (inostart==++ino) {
        !           237:                        tablefull("fake inode");
        !           238:                        u.u_error = ENFILE;
        !           239:                        return(NULL);
        !           240:                }
        !           241:        }
        !           242:        ip->i_mode = IFREG | (0666 & ~u.u_cmask);
        !           243:        ip->i_uid = u.u_uid;
        !           244:        ip->i_gid = u.u_gid;
        !           245:        ip->i_un.i_rdev = (dev_t)0;
        !           246:        ino = inostart+1;
        !           247:        return(ip);
        !           248: }

unix.superglobalmegacorp.com

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