1*23419Smckusick /* 2*23419Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23419Smckusick * All rights reserved. The Berkeley software License Agreement 4*23419Smckusick * specifies the terms and conditions for redistribution. 5*23419Smckusick * 6*23419Smckusick * @(#)inode.h 6.8 (Berkeley) 06/08/85 7*23419Smckusick */ 858Sbill 958Sbill /* 104814Swnj * The I node is the focus of all file activity in UNIX. 114814Swnj * There is a unique inode allocated for each active file, 124814Swnj * each current directory, each mounted-on file, text file, and the root. 134814Swnj * An inode is 'named' by its dev/inumber pair. (iget/iget.c) 146565Smckusic * Data in icommon is read in from permanent inode on volume. 1558Sbill */ 1658Sbill 179182Ssam #define NDADDR 12 /* direct addresses in inode */ 189182Ssam #define NIADDR 3 /* indirect addresses in inode */ 196565Smckusic 204814Swnj struct inode { 217333Skre struct inode *i_chain[2]; /* must be first */ 227703Ssam u_short i_flag; 237452Skre u_short i_count; /* reference count */ 2458Sbill dev_t i_dev; /* device where inode resides */ 259182Ssam u_short i_shlockc; /* count of shared locks on inode */ 269182Ssam u_short i_exlockc; /* count of exclusive locks on inode */ 2758Sbill ino_t i_number; /* i number, 1-to-1 with device address */ 2816646Ssam long i_id; /* unique identifier */ 296565Smckusic struct fs *i_fs; /* file sys associated with this inode */ 307452Skre struct dquot *i_dquot; /* quota structure controlling this file */ 3158Sbill union { 326565Smckusic daddr_t if_lastr; /* last read (read-ahead) */ 336565Smckusic struct socket *is_socket; 347333Skre struct { 357333Skre struct inode *if_freef; /* free list forward */ 367333Skre struct inode **if_freeb; /* free list back */ 377333Skre } i_fr; 3858Sbill } i_un; 396565Smckusic struct icommon 406565Smckusic { 416565Smckusic u_short ic_mode; /* 0: mode and type of file */ 426565Smckusic short ic_nlink; /* 2: number of links to file */ 436565Smckusic short ic_uid; /* 4: owner's user id */ 446565Smckusic short ic_gid; /* 6: owner's group id */ 459182Ssam quad ic_size; /* 8: number of bytes in file */ 469182Ssam time_t ic_atime; /* 16: time last accessed */ 479182Ssam long ic_atspare; 489182Ssam time_t ic_mtime; /* 24: time last modified */ 499182Ssam long ic_mtspare; 5010854Ssam time_t ic_ctime; /* 32: last time inode changed */ 519182Ssam long ic_ctspare; 529182Ssam daddr_t ic_db[NDADDR]; /* 40: disk block addresses */ 539182Ssam daddr_t ic_ib[NIADDR]; /* 88: indirect blocks */ 549182Ssam long ic_flags; /* 100: status, currently unused */ 5512650Ssam long ic_blocks; /* 104: blocks actually held */ 5612650Ssam long ic_spare[5]; /* 108: reserved, currently unused */ 576565Smckusic } i_ic; 5858Sbill }; 5958Sbill 606565Smckusic struct dinode { 616565Smckusic union { 626565Smckusic struct icommon di_icom; 639182Ssam char di_size[128]; 646565Smckusic } di_un; 656565Smckusic }; 666565Smckusic 676565Smckusic #define i_mode i_ic.ic_mode 686565Smckusic #define i_nlink i_ic.ic_nlink 696565Smckusic #define i_uid i_ic.ic_uid 706565Smckusic #define i_gid i_ic.ic_gid 719790Ssam /* ugh! -- must be fixed */ 729790Ssam #ifdef vax 739182Ssam #define i_size i_ic.ic_size.val[0] 749790Ssam #endif 756565Smckusic #define i_db i_ic.ic_db 766565Smckusic #define i_ib i_ic.ic_ib 776565Smckusic #define i_atime i_ic.ic_atime 786565Smckusic #define i_mtime i_ic.ic_mtime 796565Smckusic #define i_ctime i_ic.ic_ctime 8012650Ssam #define i_blocks i_ic.ic_blocks 816565Smckusic #define i_rdev i_ic.ic_db[0] 826565Smckusic #define i_lastr i_un.if_lastr 839005Sroot #define i_socket i_un.is_socket 847333Skre #define i_forw i_chain[0] 857333Skre #define i_back i_chain[1] 867333Skre #define i_freef i_un.i_fr.if_freef 877333Skre #define i_freeb i_un.i_fr.if_freeb 886565Smckusic 896565Smckusic #define di_ic di_un.di_icom 906565Smckusic #define di_mode di_ic.ic_mode 916565Smckusic #define di_nlink di_ic.ic_nlink 926565Smckusic #define di_uid di_ic.ic_uid 936565Smckusic #define di_gid di_ic.ic_gid 949790Ssam #ifdef vax 959182Ssam #define di_size di_ic.ic_size.val[0] 969790Ssam #endif 976565Smckusic #define di_db di_ic.ic_db 986565Smckusic #define di_ib di_ic.ic_ib 996565Smckusic #define di_atime di_ic.ic_atime 1006565Smckusic #define di_mtime di_ic.ic_mtime 1016565Smckusic #define di_ctime di_ic.ic_ctime 1026565Smckusic #define di_rdev di_ic.ic_db[0] 10312650Ssam #define di_blocks di_ic.ic_blocks 1046565Smckusic 10558Sbill #ifdef KERNEL 10616737Smckusick /* 10716737Smckusick * Invalidate an inode. Used by the namei cache to detect stale 10816737Smckusick * information. At an absurd rate of 100 calls/second, the inode 10916737Smckusick * table invalidation should only occur once every 16 months. 11016737Smckusick */ 11116737Smckusick #define cacheinval(ip) \ 11216737Smckusick (ip)->i_id = ++nextinodeid; \ 11316737Smckusick if (nextinodeid == 0) \ 11417703Smckusick cacheinvalall(); 11516737Smckusick 1168691Sroot struct inode *inode; /* the inode table itself */ 1178691Sroot struct inode *inodeNINODE; /* the end of the inode table */ 1188691Sroot int ninode; /* number of slots in the table */ 11916646Ssam long nextinodeid; /* unique id generator */ 12058Sbill 1216565Smckusic struct inode *rootdir; /* pointer to inode of root directory */ 12258Sbill 12358Sbill struct inode *ialloc(); 12458Sbill struct inode *iget(); 1259182Ssam #ifdef notdef 1269182Ssam struct inode *ifind(); 1279182Ssam #endif 12858Sbill struct inode *owner(); 12958Sbill struct inode *maknode(); 13058Sbill struct inode *namei(); 1319182Ssam 1329182Ssam ino_t dirpref(); 13358Sbill #endif 13458Sbill 13558Sbill /* flags */ 1368467Sroot #define ILOCKED 0x1 /* inode is locked */ 1377703Ssam #define IUPD 0x2 /* file has been modified */ 1387703Ssam #define IACC 0x4 /* inode access time to be updated */ 1397703Ssam #define IMOUNT 0x8 /* inode is mounted on */ 1407703Ssam #define IWANT 0x10 /* some process waiting on lock */ 1417703Ssam #define ITEXT 0x20 /* inode is pure text prototype */ 1427703Ssam #define ICHG 0x40 /* inode has been changed */ 1439182Ssam #define ISHLOCK 0x80 /* file has shared lock */ 1449182Ssam #define IEXLOCK 0x100 /* file has exclusive lock */ 1457703Ssam #define ILWAIT 0x200 /* someone waiting on file lock */ 14616057Skarels #define IMOD 0x400 /* inode has been modified */ 14716775Smckusick #define IRENAME 0x800 /* inode is being renamed */ 14817555Skarels #define IXMOD 0x8000 /* inode is text, but impure (XXX) */ 14958Sbill 15058Sbill /* modes */ 1516565Smckusic #define IFMT 0170000 /* type of file */ 1526565Smckusic #define IFCHR 0020000 /* character special */ 1536565Smckusic #define IFDIR 0040000 /* directory */ 1546565Smckusic #define IFBLK 0060000 /* block special */ 1556565Smckusic #define IFREG 0100000 /* regular */ 1566565Smckusic #define IFLNK 0120000 /* symbolic link */ 1578990Sroot #define IFSOCK 0140000 /* socket */ 1588990Sroot 1596565Smckusic #define ISUID 04000 /* set user id on execution */ 1606565Smckusic #define ISGID 02000 /* set group id on execution */ 1616565Smckusic #define ISVTX 01000 /* save swapped text even after use */ 1626565Smckusic #define IREAD 0400 /* read, write, execute permissions */ 1636565Smckusic #define IWRITE 0200 1646565Smckusic #define IEXEC 0100 1658467Sroot 1668467Sroot #define ILOCK(ip) { \ 1678467Sroot while ((ip)->i_flag & ILOCKED) { \ 1688467Sroot (ip)->i_flag |= IWANT; \ 1698467Sroot sleep((caddr_t)(ip), PINOD); \ 1708467Sroot } \ 1718467Sroot (ip)->i_flag |= ILOCKED; \ 1728467Sroot } 1738467Sroot 1748467Sroot #define IUNLOCK(ip) { \ 1758467Sroot (ip)->i_flag &= ~ILOCKED; \ 1768467Sroot if ((ip)->i_flag&IWANT) { \ 1778467Sroot (ip)->i_flag &= ~IWANT; \ 1788467Sroot wakeup((caddr_t)(ip)); \ 1798467Sroot } \ 1808467Sroot } 1818467Sroot 1828467Sroot #define IUPDAT(ip, t1, t2, waitfor) { \ 18316057Skarels if (ip->i_flag&(IUPD|IACC|ICHG|IMOD)) \ 1848467Sroot iupdat(ip, t1, t2, waitfor); \ 1858467Sroot } 18616057Skarels 18716057Skarels #define ITIMES(ip, t1, t2) { \ 18816057Skarels if ((ip)->i_flag&(IUPD|IACC|ICHG)) { \ 18916057Skarels (ip)->i_flag |= IMOD; \ 19016057Skarels if ((ip)->i_flag&IACC) \ 19116057Skarels (ip)->i_atime = (t1)->tv_sec; \ 19216057Skarels if ((ip)->i_flag&IUPD) \ 19316057Skarels (ip)->i_mtime = (t2)->tv_sec; \ 19416057Skarels if ((ip)->i_flag&ICHG) \ 19516057Skarels (ip)->i_ctime = time.tv_sec; \ 19616057Skarels (ip)->i_flag &= ~(IACC|IUPD|ICHG); \ 19716057Skarels } \ 19816057Skarels } 199