1 /* 2 * Copyright (c) 1982 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 * @(#)dinode.h 6.8 (Berkeley) 06/08/85 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 union { 32 daddr_t if_lastr; /* last read (read-ahead) */ 33 struct socket *is_socket; 34 struct { 35 struct inode *if_freef; /* free list forward */ 36 struct inode **if_freeb; /* free list back */ 37 } i_fr; 38 } i_un; 39 struct icommon 40 { 41 u_short ic_mode; /* 0: mode and type of file */ 42 short ic_nlink; /* 2: number of links to file */ 43 short ic_uid; /* 4: owner's user id */ 44 short ic_gid; /* 6: owner's group id */ 45 quad ic_size; /* 8: number of bytes in file */ 46 time_t ic_atime; /* 16: time last accessed */ 47 long ic_atspare; 48 time_t ic_mtime; /* 24: time last modified */ 49 long ic_mtspare; 50 time_t ic_ctime; /* 32: last time inode changed */ 51 long ic_ctspare; 52 daddr_t ic_db[NDADDR]; /* 40: disk block addresses */ 53 daddr_t ic_ib[NIADDR]; /* 88: indirect blocks */ 54 long ic_flags; /* 100: status, currently unused */ 55 long ic_blocks; /* 104: blocks actually held */ 56 long ic_spare[5]; /* 108: reserved, currently unused */ 57 } i_ic; 58 }; 59 60 struct dinode { 61 union { 62 struct icommon di_icom; 63 char di_size[128]; 64 } di_un; 65 }; 66 67 #define i_mode i_ic.ic_mode 68 #define i_nlink i_ic.ic_nlink 69 #define i_uid i_ic.ic_uid 70 #define i_gid i_ic.ic_gid 71 /* ugh! -- must be fixed */ 72 #ifdef vax 73 #define i_size i_ic.ic_size.val[0] 74 #endif 75 #define i_db i_ic.ic_db 76 #define i_ib i_ic.ic_ib 77 #define i_atime i_ic.ic_atime 78 #define i_mtime i_ic.ic_mtime 79 #define i_ctime i_ic.ic_ctime 80 #define i_blocks i_ic.ic_blocks 81 #define i_rdev i_ic.ic_db[0] 82 #define i_lastr i_un.if_lastr 83 #define i_socket i_un.is_socket 84 #define i_forw i_chain[0] 85 #define i_back i_chain[1] 86 #define i_freef i_un.i_fr.if_freef 87 #define i_freeb i_un.i_fr.if_freeb 88 89 #define di_ic di_un.di_icom 90 #define di_mode di_ic.ic_mode 91 #define di_nlink di_ic.ic_nlink 92 #define di_uid di_ic.ic_uid 93 #define di_gid di_ic.ic_gid 94 #ifdef vax 95 #define di_size di_ic.ic_size.val[0] 96 #endif 97 #define di_db di_ic.ic_db 98 #define di_ib di_ic.ic_ib 99 #define di_atime di_ic.ic_atime 100 #define di_mtime di_ic.ic_mtime 101 #define di_ctime di_ic.ic_ctime 102 #define di_rdev di_ic.ic_db[0] 103 #define di_blocks di_ic.ic_blocks 104 105 #ifdef KERNEL 106 /* 107 * Invalidate an inode. Used by the namei cache to detect stale 108 * information. At an absurd rate of 100 calls/second, the inode 109 * table invalidation should only occur once every 16 months. 110 */ 111 #define cacheinval(ip) \ 112 (ip)->i_id = ++nextinodeid; \ 113 if (nextinodeid == 0) \ 114 cacheinvalall(); 115 116 struct inode *inode; /* the inode table itself */ 117 struct inode *inodeNINODE; /* the end of the inode table */ 118 int ninode; /* number of slots in the table */ 119 long nextinodeid; /* unique id generator */ 120 121 struct inode *rootdir; /* pointer to inode of root directory */ 122 123 struct inode *ialloc(); 124 struct inode *iget(); 125 #ifdef notdef 126 struct inode *ifind(); 127 #endif 128 struct inode *owner(); 129 struct inode *maknode(); 130 struct inode *namei(); 131 132 ino_t dirpref(); 133 #endif 134 135 /* flags */ 136 #define ILOCKED 0x1 /* inode is locked */ 137 #define IUPD 0x2 /* file has been modified */ 138 #define IACC 0x4 /* inode access time to be updated */ 139 #define IMOUNT 0x8 /* inode is mounted on */ 140 #define IWANT 0x10 /* some process waiting on lock */ 141 #define ITEXT 0x20 /* inode is pure text prototype */ 142 #define ICHG 0x40 /* inode has been changed */ 143 #define ISHLOCK 0x80 /* file has shared lock */ 144 #define IEXLOCK 0x100 /* file has exclusive lock */ 145 #define ILWAIT 0x200 /* someone waiting on file lock */ 146 #define IMOD 0x400 /* inode has been modified */ 147 #define IRENAME 0x800 /* inode is being renamed */ 148 #define IXMOD 0x8000 /* inode is text, but impure (XXX) */ 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 } 199