|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.