summaryrefslogtreecommitdiffstats
path: root/src/fs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/inode.c')
-rw-r--r--src/fs/inode.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/src/fs/inode.c b/src/fs/inode.c
new file mode 100644
index 0000000..d0b1c32
--- /dev/null
+++ b/src/fs/inode.c
@@ -0,0 +1,338 @@
1/*
2 * linux/fs/inode.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#include <string.h>
8#include <sys/stat.h>
9
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/mm.h>
13#include <asm/system.h>
14
15struct m_inode inode_table[NR_INODE]={{0,},};
16
17static void read_inode(struct m_inode * inode);
18static void write_inode(struct m_inode * inode);
19
20static inline void wait_on_inode(struct m_inode * inode)
21{
22 cli();
23 while (inode->i_lock)
24 sleep_on(&inode->i_wait);
25 sti();
26}
27
28static inline void lock_inode(struct m_inode * inode)
29{
30 cli();
31 while (inode->i_lock)
32 sleep_on(&inode->i_wait);
33 inode->i_lock=1;
34 sti();
35}
36
37static inline void unlock_inode(struct m_inode * inode)
38{
39 inode->i_lock=0;
40 wake_up(&inode->i_wait);
41}
42
43void invalidate_inodes(int dev)
44{
45 int i;
46 struct m_inode * inode;
47
48 inode = 0+inode_table;
49 for(i=0 ; i<NR_INODE ; i++,inode++) {
50 wait_on_inode(inode);
51 if (inode->i_dev == dev) {
52 if (inode->i_count)
53 printk("inode in use on removed disk\n\r");
54 inode->i_dev = inode->i_dirt = 0;
55 }
56 }
57}
58
59void sync_inodes(void)
60{
61 int i;
62 struct m_inode * inode;
63
64 inode = 0+inode_table;
65 for(i=0 ; i<NR_INODE ; i++,inode++) {
66 wait_on_inode(inode);
67 if (inode->i_dirt && !inode->i_pipe)
68 write_inode(inode);
69 }
70}
71
72static int _bmap(struct m_inode * inode,int block,int create)
73{
74 struct buffer_head * bh;
75 int i;
76
77 if (block<0)
78 panic("_bmap: block<0");
79 if (block >= 7+512+512*512)
80 panic("_bmap: block>big");
81 if (block<7) {
82 if (create && !inode->i_zone[block])
83 if ((inode->i_zone[block]=new_block(inode->i_dev))) {
84 inode->i_ctime=CURRENT_TIME;
85 inode->i_dirt=1;
86 }
87 return inode->i_zone[block];
88 }
89 block -= 7;
90 if (block<512) {
91 if (create && !inode->i_zone[7])
92 if ((inode->i_zone[7]=new_block(inode->i_dev))) {
93 inode->i_dirt=1;
94 inode->i_ctime=CURRENT_TIME;
95 }
96 if (!inode->i_zone[7])
97 return 0;
98 if (!(bh = bread(inode->i_dev,inode->i_zone[7])))
99 return 0;
100 i = ((unsigned short *) (bh->b_data))[block];
101 if (create && !i)
102 if ((i=new_block(inode->i_dev))) {
103 ((unsigned short *) (bh->b_data))[block]=i;
104 bh->b_dirt=1;
105 }
106 brelse(bh);
107 return i;
108 }
109 block -= 512;
110 if (create && !inode->i_zone[8])
111 if ((inode->i_zone[8]=new_block(inode->i_dev))) {
112 inode->i_dirt=1;
113 inode->i_ctime=CURRENT_TIME;
114 }
115 if (!inode->i_zone[8])
116 return 0;
117 if (!(bh=bread(inode->i_dev,inode->i_zone[8])))
118 return 0;
119 i = ((unsigned short *)bh->b_data)[block>>9];
120 if (create && !i)
121 if ((i=new_block(inode->i_dev))) {
122 ((unsigned short *) (bh->b_data))[block>>9]=i;
123 bh->b_dirt=1;
124 }
125 brelse(bh);
126 if (!i)
127 return 0;
128 if (!(bh=bread(inode->i_dev,i)))
129 return 0;
130 i = ((unsigned short *)bh->b_data)[block&511];
131 if (create && !i)
132 if ((i=new_block(inode->i_dev))) {
133 ((unsigned short *) (bh->b_data))[block&511]=i;
134 bh->b_dirt=1;
135 }
136 brelse(bh);
137 return i;
138}
139
140int bmap(struct m_inode * inode,int block)
141{
142 return _bmap(inode,block,0);
143}
144
145int create_block(struct m_inode * inode, int block)
146{
147 return _bmap(inode,block,1);
148}
149
150void iput(struct m_inode * inode)
151{
152 if (!inode)
153 return;
154 wait_on_inode(inode);
155 if (!inode->i_count)
156 panic("iput: trying to free free inode");
157 if (inode->i_pipe) {
158 wake_up(&inode->i_wait);
159 if (--inode->i_count)
160 return;
161 free_page(inode->i_size);
162 inode->i_count=0;
163 inode->i_dirt=0;
164 inode->i_pipe=0;
165 return;
166 }
167 if (!inode->i_dev) {
168 inode->i_count--;
169 return;
170 }
171 if (S_ISBLK(inode->i_mode)) {
172 sync_dev(inode->i_zone[0]);
173 wait_on_inode(inode);
174 }
175repeat:
176 if (inode->i_count>1) {
177 inode->i_count--;
178 return;
179 }
180 if (!inode->i_nlinks) {
181 truncate(inode);
182 free_inode(inode);
183 return;
184 }
185 if (inode->i_dirt) {
186 write_inode(inode); /* we can sleep - so do again */
187 wait_on_inode(inode);
188 goto repeat;
189 }
190 inode->i_count--;
191 return;
192}
193
194struct m_inode * get_empty_inode(void)
195{
196 struct m_inode * inode;
197 static struct m_inode * last_inode = inode_table;
198 int i;
199
200 do {
201 inode = NULL;
202 for (i = NR_INODE; i ; i--) {
203 if (++last_inode >= inode_table + NR_INODE)
204 last_inode = inode_table;
205 if (!last_inode->i_count) {
206 inode = last_inode;
207 if (!inode->i_dirt && !inode->i_lock)
208 break;
209 }
210 }
211 if (!inode) {
212 for (i=0 ; i<NR_INODE ; i++)
213 printk("%04x: %6d\t",inode_table[i].i_dev,
214 inode_table[i].i_num);
215 panic("No free inodes in mem");
216 }
217 wait_on_inode(inode);
218 while (inode->i_dirt) {
219 write_inode(inode);
220 wait_on_inode(inode);
221 }
222 } while (inode->i_count);
223 memset(inode,0,sizeof(*inode));
224 inode->i_count = 1;
225 return inode;
226}
227
228struct m_inode * get_pipe_inode(void)
229{
230 struct m_inode * inode;
231
232 if (!(inode = get_empty_inode()))
233 return NULL;
234 if (!(inode->i_size=get_free_page())) {
235 inode->i_count = 0;
236 return NULL;
237 }
238 inode->i_count = 2; /* sum of readers/writers */
239 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
240 inode->i_pipe = 1;
241 return inode;
242}
243
244struct m_inode * iget(int dev,int nr)
245{
246 struct m_inode * inode, * empty;
247
248 if (!dev)
249 panic("iget with dev==0");
250 empty = get_empty_inode();
251 inode = inode_table;
252 while (inode < NR_INODE+inode_table) {
253 if (inode->i_dev != dev || inode->i_num != nr) {
254 inode++;
255 continue;
256 }
257 wait_on_inode(inode);
258 if (inode->i_dev != dev || inode->i_num != nr) {
259 inode = inode_table;
260 continue;
261 }
262 inode->i_count++;
263 if (inode->i_mount) {
264 int i;
265
266 for (i = 0 ; i<NR_SUPER ; i++)
267 if (super_block[i].s_imount==inode)
268 break;
269 if (i >= NR_SUPER) {
270 printk("Mounted inode hasn't got sb\n");
271 if (empty)
272 iput(empty);
273 return inode;
274 }
275 iput(inode);
276 dev = super_block[i].s_dev;
277 nr = ROOT_INO;
278 inode = inode_table;
279 continue;
280 }
281 if (empty)
282 iput(empty);
283 return inode;
284 }
285 if (!empty)
286 return (NULL);
287 inode=empty;
288 inode->i_dev = dev;
289 inode->i_num = nr;
290 read_inode(inode);
291 return inode;
292}
293
294static void read_inode(struct m_inode * inode)
295{
296 struct super_block * sb;
297 struct buffer_head * bh;
298 int block;
299
300 lock_inode(inode);
301 if (!(sb=get_super(inode->i_dev)))
302 panic("trying to read inode without dev");
303 block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
304 (inode->i_num-1)/INODES_PER_BLOCK;
305 if (!(bh=bread(inode->i_dev,block)))
306 panic("unable to read i-node block");
307 *(struct d_inode *)inode =
308 ((struct d_inode *)bh->b_data)
309 [(inode->i_num-1)%INODES_PER_BLOCK];
310 brelse(bh);
311 unlock_inode(inode);
312}
313
314static void write_inode(struct m_inode * inode)
315{
316 struct super_block * sb;
317 struct buffer_head * bh;
318 int block;
319
320 lock_inode(inode);
321 if (!inode->i_dirt || !inode->i_dev) {
322 unlock_inode(inode);
323 return;
324 }
325 if (!(sb=get_super(inode->i_dev)))
326 panic("trying to write inode without device");
327 block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
328 (inode->i_num-1)/INODES_PER_BLOCK;
329 if (!(bh=bread(inode->i_dev,block)))
330 panic("unable to read i-node block");
331 ((struct d_inode *)bh->b_data)
332 [(inode->i_num-1)%INODES_PER_BLOCK] =
333 *(struct d_inode *)inode;
334 bh->b_dirt=1;
335 inode->i_dirt=0;
336 brelse(bh);
337 unlock_inode(inode);
338}