1: /* 2: * Copyright (c) 1982, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)inode.h 7.1 (Berkeley) 6/4/86 7: */ 8: 9: /* 10: * The I node is the focus of all file activity in UNIX. 11: * There is a unique inode allocated for each active file, 12: * each current directory, each mounted-on file, text file, and the root. 13: * An inode is 'named' by its dev/inumber pair. (iget/iget.c) 14: * Data in icommon is read in from permanent inode on volume. 15: */ 16: 17: #define NDADDR 12 /* direct addresses in inode */ 18: #define NIADDR 3 /* indirect addresses in inode */ 19: 20: struct inode { 21: struct inode *i_chain[2]; /* must be first */ 22: u_short i_flag; 23: u_short i_count; /* reference count */ 24: dev_t i_dev; /* device where inode resides */ 25: u_short i_shlockc; /* count of shared locks on inode */ 26: u_short i_exlockc; /* count of exclusive locks on inode */ 27: ino_t i_number; /* i number, 1-to-1 with device address */ 28: long i_id; /* unique identifier */ 29: struct fs *i_fs; /* file sys associated with this inode */ 30: struct dquot *i_dquot; /* quota structure controlling this file */ 31: struct text *i_text; /* text entry, if any (should be region) */ 32: union { 33: daddr_t if_lastr; /* last read (read-ahead) */ 34: struct socket *is_socket; 35: struct { 36: struct inode *if_freef; /* free list forward */ 37: struct inode **if_freeb; /* free list back */ 38: } i_fr; 39: } i_un; 40: struct icommon 41: { 42: u_short ic_mode; /* 0: mode and type of file */ 43: short ic_nlink; /* 2: number of links to file */ 44: uid_t ic_uid; /* 4: owner's user id */ 45: gid_t ic_gid; /* 6: owner's group id */ 46: quad ic_size; /* 8: number of bytes in file */ 47: time_t ic_atime; /* 16: time last accessed */ 48: long ic_atspare; 49: time_t ic_mtime; /* 24: time last modified */ 50: long ic_mtspare; 51: time_t ic_ctime; /* 32: last time inode changed */ 52: long ic_ctspare; 53: daddr_t ic_db[NDADDR]; /* 40: disk block addresses */ 54: daddr_t ic_ib[NIADDR]; /* 88: indirect blocks */ 55: long ic_flags; /* 100: status, currently unused */ 56: long ic_blocks; /* 104: blocks actually held */ 57: long ic_spare[5]; /* 108: reserved, currently unused */ 58: } i_ic; 59: }; 60: 61: struct dinode { 62: union { 63: struct icommon di_icom; 64: char di_size[128]; 65: } di_un; 66: }; 67: 68: #define i_mode i_ic.ic_mode 69: #define i_nlink i_ic.ic_nlink 70: #define i_uid i_ic.ic_uid 71: #define i_gid i_ic.ic_gid 72: /* ugh! -- must be fixed */ 73: #ifdef vax 74: #define i_size i_ic.ic_size.val[0] 75: #endif 76: #define i_db i_ic.ic_db 77: #define i_ib i_ic.ic_ib 78: #define i_atime i_ic.ic_atime 79: #define i_mtime i_ic.ic_mtime 80: #define i_ctime i_ic.ic_ctime 81: #define i_blocks i_ic.ic_blocks 82: #define i_rdev i_ic.ic_db[0] 83: #define i_lastr i_un.if_lastr 84: #define i_socket i_un.is_socket 85: #define i_forw i_chain[0] 86: #define i_back i_chain[1] 87: #define i_freef i_un.i_fr.if_freef 88: #define i_freeb i_un.i_fr.if_freeb 89: 90: #define di_ic di_un.di_icom 91: #define di_mode di_ic.ic_mode 92: #define di_nlink di_ic.ic_nlink 93: #define di_uid di_ic.ic_uid 94: #define di_gid di_ic.ic_gid 95: #ifdef vax 96: #define di_size di_ic.ic_size.val[0] 97: #endif 98: #define di_db di_ic.ic_db 99: #define di_ib di_ic.ic_ib 100: #define di_atime di_ic.ic_atime 101: #define di_mtime di_ic.ic_mtime 102: #define di_ctime di_ic.ic_ctime 103: #define di_rdev di_ic.ic_db[0] 104: #define di_blocks di_ic.ic_blocks 105: 106: #ifdef KERNEL 107: /* 108: * Invalidate an inode. Used by the namei cache to detect stale 109: * information. At an absurd rate of 100 calls/second, the inode 110: * table invalidation should only occur once every 16 months. 111: */ 112: #define cacheinval(ip) \ 113: (ip)->i_id = ++nextinodeid; \ 114: if (nextinodeid == 0) \ 115: cacheinvalall(); 116: 117: struct inode *inode; /* the inode table itself */ 118: struct inode *inodeNINODE; /* the end of the inode table */ 119: int ninode; /* number of slots in the table */ 120: long nextinodeid; /* unique id generator */ 121: 122: struct inode *rootdir; /* pointer to inode of root directory */ 123: 124: struct inode *ialloc(); 125: struct inode *iget(); 126: #ifdef notdef 127: struct inode *ifind(); 128: #endif 129: struct inode *owner(); 130: struct inode *maknode(); 131: struct inode *namei(); 132: 133: ino_t dirpref(); 134: #endif 135: 136: /* flags */ 137: #define ILOCKED 0x1 /* inode is locked */ 138: #define IUPD 0x2 /* file has been modified */ 139: #define IACC 0x4 /* inode access time to be updated */ 140: #define IMOUNT 0x8 /* inode is mounted on */ 141: #define IWANT 0x10 /* some process waiting on lock */ 142: #define ITEXT 0x20 /* inode is pure text prototype */ 143: #define ICHG 0x40 /* inode has been changed */ 144: #define ISHLOCK 0x80 /* file has shared lock */ 145: #define IEXLOCK 0x100 /* file has exclusive lock */ 146: #define ILWAIT 0x200 /* someone waiting on file lock */ 147: #define IMOD 0x400 /* inode has been modified */ 148: #define IRENAME 0x800 /* inode is being renamed */ 149: 150: /* modes */ 151: #define IFMT 0170000 /* type of file */ 152: #define IFCHR 0020000 /* character special */ 153: #define IFDIR 0040000 /* directory */ 154: #define IFBLK 0060000 /* block special */ 155: #define IFREG 0100000 /* regular */ 156: #define IFLNK 0120000 /* symbolic link */ 157: #define IFSOCK 0140000 /* socket */ 158: 159: #define ISUID 04000 /* set user id on execution */ 160: #define ISGID 02000 /* set group id on execution */ 161: #define ISVTX 01000 /* save swapped text even after use */ 162: #define IREAD 0400 /* read, write, execute permissions */ 163: #define IWRITE 0200 164: #define IEXEC 0100 165: 166: #define ILOCK(ip) { \ 167: while ((ip)->i_flag & ILOCKED) { \ 168: (ip)->i_flag |= IWANT; \ 169: sleep((caddr_t)(ip), PINOD); \ 170: } \ 171: (ip)->i_flag |= ILOCKED; \ 172: } 173: 174: #define IUNLOCK(ip) { \ 175: (ip)->i_flag &= ~ILOCKED; \ 176: if ((ip)->i_flag&IWANT) { \ 177: (ip)->i_flag &= ~IWANT; \ 178: wakeup((caddr_t)(ip)); \ 179: } \ 180: } 181: 182: #define IUPDAT(ip, t1, t2, waitfor) { \ 183: if (ip->i_flag&(IUPD|IACC|ICHG|IMOD)) \ 184: iupdat(ip, t1, t2, waitfor); \ 185: } 186: 187: #define ITIMES(ip, t1, t2) { \ 188: if ((ip)->i_flag&(IUPD|IACC|ICHG)) { \ 189: (ip)->i_flag |= IMOD; \ 190: if ((ip)->i_flag&IACC) \ 191: (ip)->i_atime = (t1)->tv_sec; \ 192: if ((ip)->i_flag&IUPD) \ 193: (ip)->i_mtime = (t2)->tv_sec; \ 194: if ((ip)->i_flag&ICHG) \ 195: (ip)->i_ctime = time.tv_sec; \ 196: (ip)->i_flag &= ~(IACC|IUPD|ICHG); \ 197: } \ 198: }