Annotation of researchv9/sys.vax/sys/iget.c, revision 1.1.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.