This source file includes following definitions.
- inode_init
- wait_on_inode
- lock_inode
- unlock_inode
- clear_inode
- fs_may_mount
- fs_may_umount
- write_inode
- read_inode
- notify_change
- bmap
- invalidate_inodes
- sync_inodes
- iput
- get_empty_inode
- get_pipe_inode
- iget
- __wait_on_inode
1
2
3
4
5
6
7 #include <linux/stat.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/mm.h>
11 #include <linux/string.h>
12
13 #include <asm/system.h>
14
15 static struct inode * inode_table;
16 static struct inode * last_inode;
17 static struct wait_queue * inode_wait = NULL;
18
19 unsigned long inode_init(unsigned long start, unsigned long end)
20 {
21 start += 0x0000000f;
22 start &= 0xfffffff0;
23 inode_table = (struct inode *) start;
24 last_inode = inode_table;
25 start = (unsigned long) (inode_table + NR_INODE);
26 memset(inode_table,0,NR_INODE*sizeof(struct inode));
27 return start;
28 }
29
30 static void __wait_on_inode(struct inode *);
31
32 static inline void wait_on_inode(struct inode * inode)
33 {
34 if (inode->i_lock)
35 __wait_on_inode(inode);
36 }
37
38 static inline void lock_inode(struct inode * inode)
39 {
40 wait_on_inode(inode);
41 inode->i_lock = 1;
42 }
43
44 static inline void unlock_inode(struct inode * inode)
45 {
46 inode->i_lock = 0;
47 wake_up(&inode->i_wait);
48 }
49
50
51
52
53
54
55
56
57
58
59
60
61
62 void clear_inode(struct inode * inode)
63 {
64 struct wait_queue * wait;
65
66 wait_on_inode(inode);
67 wait = ((volatile struct inode *) inode)->i_wait;
68 memset(inode,0,sizeof(*inode));
69 ((volatile struct inode *) inode)->i_wait = wait;
70 }
71
72 int fs_may_mount(dev_t dev)
73 {
74 struct inode * inode;
75
76 for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
77 if (inode->i_dev != dev)
78 continue;
79 if (inode->i_count || inode->i_dirt || inode->i_lock)
80 return 0;
81 clear_inode(inode);
82 }
83 return 1;
84 }
85
86 int fs_may_umount(dev_t dev, struct inode * mount_root)
87 {
88 struct inode * inode;
89
90 for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
91 if (inode->i_dev==dev && inode->i_count)
92 if (inode == mount_root && inode->i_count == 1)
93 continue;
94 else
95 return 0;
96 }
97 return 1;
98 }
99
100 static void write_inode(struct inode * inode)
101 {
102 if (!inode->i_dirt)
103 return;
104 wait_on_inode(inode);
105 if (!inode->i_dirt)
106 return;
107 if (!inode->i_sb || !inode->i_sb->s_op || !inode->i_sb->s_op->write_inode) {
108 inode->i_dirt = 0;
109 return;
110 }
111 inode->i_lock = 1;
112 inode->i_sb->s_op->write_inode(inode);
113 unlock_inode(inode);
114 }
115
116 static void read_inode(struct inode * inode)
117 {
118 lock_inode(inode);
119 if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode)
120 inode->i_sb->s_op->read_inode(inode);
121 unlock_inode(inode);
122 }
123
124
125
126
127
128
129
130
131
132 int notify_change(int flags, struct inode * inode)
133 {
134 if (inode->i_sb && inode->i_sb->s_op &&
135 inode->i_sb->s_op->notify_change)
136 return inode->i_sb->s_op->notify_change(flags, inode);
137 return 0;
138 }
139
140
141
142
143
144
145
146
147
148
149
150 int bmap(struct inode * inode, int block)
151 {
152 if (inode->i_op && inode->i_op->bmap)
153 return inode->i_op->bmap(inode,block);
154 return 0;
155 }
156
157 void invalidate_inodes(dev_t dev)
158 {
159 int i;
160 struct inode * inode;
161
162 inode = 0+inode_table;
163 for(i=0 ; i<NR_INODE ; i++,inode++) {
164 wait_on_inode(inode);
165 if (inode->i_dev == dev) {
166 if (inode->i_count) {
167 printk("VFS: inode busy on removed device %d/%d\n",
168 MAJOR(dev), MINOR(dev));
169 continue;
170 }
171 clear_inode(inode);
172 }
173 }
174 }
175
176 void sync_inodes(dev_t dev)
177 {
178 struct inode * inode;
179
180 for(inode = 0+inode_table ; inode < NR_INODE+inode_table ; inode++) {
181 if (dev && inode->i_dev != dev)
182 continue;
183 wait_on_inode(inode);
184 if (inode->i_dirt)
185 write_inode(inode);
186 }
187 }
188
189 void iput(struct inode * inode)
190 {
191 if (!inode)
192 return;
193 wait_on_inode(inode);
194 if (!inode->i_count) {
195 printk("VFS: iput: trying to free free inode\n");
196 printk("VFS: device %d/%d, inode %d, mode=0%07o\n",
197 MAJOR(inode->i_rdev), MINOR(inode->i_rdev),
198 inode->i_ino, inode->i_mode);
199 return;
200 }
201 if (inode->i_pipe) {
202 wake_up(&PIPE_READ_WAIT(*inode));
203 wake_up(&PIPE_WRITE_WAIT(*inode));
204 }
205 repeat:
206 if (inode->i_count>1) {
207 inode->i_count--;
208 return;
209 }
210 wake_up(&inode_wait);
211 if (inode->i_pipe) {
212 unsigned long page = (unsigned long) PIPE_BASE(*inode);
213 PIPE_BASE(*inode) = NULL;
214 free_page(page);
215 }
216 if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
217 inode->i_sb->s_op->put_inode(inode);
218 if (!inode->i_nlink)
219 return;
220 }
221 if (inode->i_dirt) {
222 write_inode(inode);
223 wait_on_inode(inode);
224 goto repeat;
225 }
226 inode->i_count--;
227 return;
228 }
229
230 struct inode * get_empty_inode(void)
231 {
232 struct inode * inode;
233 int i;
234
235 repeat:
236 inode = NULL;
237 for (i = NR_INODE; i ; i--) {
238 if (++last_inode >= inode_table + NR_INODE)
239 last_inode = inode_table;
240 if (!last_inode->i_count) {
241 inode = last_inode;
242 if (!inode->i_dirt && !inode->i_lock)
243 break;
244 }
245 }
246 if (!inode) {
247 printk("VFS: No free inodes - contact Linus\n");
248 sleep_on(&inode_wait);
249 goto repeat;
250 }
251 if (inode->i_lock) {
252 wait_on_inode(inode);
253 goto repeat;
254 }
255 if (inode->i_dirt) {
256 write_inode(inode);
257 goto repeat;
258 }
259 if (inode->i_count)
260 goto repeat;
261 clear_inode(inode);
262 inode->i_count = 1;
263 inode->i_nlink = 1;
264 return inode;
265 }
266
267 struct inode * get_pipe_inode(void)
268 {
269 struct inode * inode;
270
271 if (!(inode = get_empty_inode()))
272 return NULL;
273 if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
274 inode->i_count = 0;
275 return NULL;
276 }
277 inode->i_count = 2;
278 PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
279 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
280 PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
281 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
282 inode->i_pipe = 1;
283 inode->i_mode |= S_IFIFO;
284 inode->i_uid = current->euid;
285 inode->i_gid = current->egid;
286 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
287 return inode;
288 }
289
290 struct inode * iget(struct super_block * sb,int nr)
291 {
292 struct inode * inode, * empty;
293
294 if (!sb)
295 panic("VFS: iget with sb==NULL");
296 empty = get_empty_inode();
297 inode = inode_table;
298 while (inode < NR_INODE+inode_table) {
299 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
300 inode++;
301 continue;
302 }
303 wait_on_inode(inode);
304 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
305 inode = inode_table;
306 continue;
307 }
308 inode->i_count++;
309 if (inode->i_mount) {
310 int i;
311
312 for (i = 0 ; i<NR_SUPER ; i++)
313 if (super_block[i].s_covered==inode)
314 break;
315 if (i >= NR_SUPER) {
316 printk("VFS: Mounted inode hasn't got sb\n");
317 if (empty) {
318 if (last_inode > inode_table)
319 --last_inode;
320 else
321 last_inode
322 = inode_table + NR_INODE;
323 iput(empty);
324 }
325 return inode;
326 }
327 iput(inode);
328 if (!(inode = super_block[i].s_mounted))
329 printk("VFS: Mounted device %d/%d has no rootinode\n",
330 MAJOR(inode->i_dev), MINOR(inode->i_dev));
331 else {
332 inode->i_count++;
333 wait_on_inode(inode);
334 }
335 }
336 if (empty) {
337 if (last_inode > inode_table)
338 --last_inode;
339 else
340 last_inode
341 = inode_table + NR_INODE;
342 iput(empty);
343 }
344 return inode;
345 }
346 if (!empty)
347 return (NULL);
348 inode = empty;
349 inode->i_sb = sb;
350 inode->i_dev = sb->s_dev;
351 inode->i_ino = nr;
352 inode->i_flags = sb->s_flags;
353 read_inode(inode);
354 return inode;
355 }
356
357
358
359
360
361
362
363 static void __wait_on_inode(struct inode * inode)
364 {
365 struct wait_queue wait = { current, NULL };
366
367 add_wait_queue(&inode->i_wait, &wait);
368 repeat:
369 current->state = TASK_UNINTERRUPTIBLE;
370 if (inode->i_lock) {
371 schedule();
372 goto repeat;
373 }
374 remove_wait_queue(&inode->i_wait, &wait);
375 current->state = TASK_RUNNING;
376 }