[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/fs/inode.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  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 
 15 struct m_inode inode_table[NR_INODE]={{0,},};
 16 
 17 static void read_inode(struct m_inode * inode);
 18 static void write_inode(struct m_inode * inode);
 19 
 20 static 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 
 28 static 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 
 37 static inline void unlock_inode(struct m_inode * inode)
 38 {
 39         inode->i_lock=0;
 40         wake_up(&inode->i_wait);
 41 }
 42 
 43 void 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 
 59 void 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 
 72 static 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 
140 int bmap(struct m_inode * inode,int block)
141 {
142         return _bmap(inode,block,0);
143 }
144 
145 int create_block(struct m_inode * inode, int block)
146 {
147         return _bmap(inode,block,1);
148 }
149                 
150 void 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         }
175 repeat:
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 
194 struct 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 
228 struct 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 
244 struct 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 
294 static 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 
314 static 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 }
339 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.