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