ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / jffs2 / readinode.c
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001-2003 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <dwmw2@redhat.com>
7  *
8  * For licensing information, see the file 'LICENCE' in this directory.
9  *
10  * $Id: readinode.c,v 1.107 2003/10/04 08:33:06 dwmw2 Exp $
11  *
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/fs.h>
17 #include <linux/crc32.h>
18 #include <linux/pagemap.h>
19 #include <linux/mtd/mtd.h>
20 #include <linux/compiler.h>
21 #include "nodelist.h"
22
23 static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
24
25 #if CONFIG_JFFS2_FS_DEBUG >= 1
26 static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
27 {
28         struct jffs2_node_frag *this = frag_first(list);
29         uint32_t lastofs = 0;
30         int buggy = 0;
31
32         while(this) {
33                 if (this->node)
34                         printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
35                                this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw),
36                                this, frag_left(this), frag_right(this), frag_parent(this));
37                 else 
38                         printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs, 
39                                this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this));
40                 if (this->ofs != lastofs)
41                         buggy = 1;
42                 lastofs = this->ofs+this->size;
43                 this = frag_next(this);
44         }
45         if (buggy && !permitbug) {
46                 printk(KERN_CRIT "Frag tree got a hole in it\n");
47                 BUG();
48         }
49 }
50
51 void jffs2_print_frag_list(struct jffs2_inode_info *f)
52 {
53         jffs2_print_fragtree(&f->fragtree, 0);
54
55         if (f->metadata) {
56                 printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
57         }
58 }
59 #endif /* D1 */
60
61 static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
62 {
63         if (this->node) {
64                 this->node->frags--;
65                 if (!this->node->frags) {
66                         /* The node has no valid frags left. It's totally obsoleted */
67                         D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
68                                   ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size));
69                         jffs2_mark_node_obsolete(c, this->node->raw);
70                         jffs2_free_full_dnode(this->node);
71                 } else {
72                         D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
73                                   ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size,
74                                   this->node->frags));
75                         mark_ref_normal(this->node->raw);
76                 }
77                 
78         }
79         jffs2_free_node_frag(this);
80 }
81
82 /* Given an inode, probably with existing list of fragments, add the new node
83  * to the fragment list.
84  */
85 int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
86 {
87         int ret;
88         struct jffs2_node_frag *newfrag;
89
90         D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
91
92         newfrag = jffs2_alloc_node_frag();
93         if (unlikely(!newfrag))
94                 return -ENOMEM;
95
96         D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
97                   fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
98         
99         if (unlikely(!fn->size)) {
100                 jffs2_free_node_frag(newfrag);
101                 return 0;
102         }
103
104         newfrag->ofs = fn->ofs;
105         newfrag->size = fn->size;
106         newfrag->node = fn;
107         newfrag->node->frags = 1;
108
109         ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
110         if (ret)
111                 return ret;
112
113         /* If we now share a page with other nodes, mark either previous
114            or next node REF_NORMAL, as appropriate.  */
115         if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
116                 struct jffs2_node_frag *prev = frag_prev(newfrag);
117
118                 mark_ref_normal(fn->raw);
119                 /* If we don't start at zero there's _always_ a previous */     
120                 if (prev->node)
121                         mark_ref_normal(prev->node->raw);
122         }
123
124         if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
125                 struct jffs2_node_frag *next = frag_next(newfrag);
126                 
127                 if (next) {
128                         mark_ref_normal(fn->raw);
129                         if (next->node)
130                                 mark_ref_normal(next->node->raw);
131                 }
132         }
133         D2(jffs2_print_frag_list(f));
134         return 0;
135 }
136
137 /* Doesn't set inode->i_size */
138 static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag)
139 {
140         struct jffs2_node_frag *this;
141         uint32_t lastend;
142
143         /* Skip all the nodes which are completed before this one starts */
144         this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
145
146         if (this) {
147                 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
148                           this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
149                 lastend = this->ofs + this->size;
150         } else {
151                 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n"));
152                 lastend = 0;
153         }
154                           
155         /* See if we ran off the end of the list */
156         if (lastend <= newfrag->ofs) {
157                 /* We did */
158
159                 /* Check if 'this' node was on the same page as the new node.
160                    If so, both 'this' and the new node get marked REF_NORMAL so
161                    the GC can take a look.
162                 */
163                 if ((lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
164                         if (this->node)
165                                 mark_ref_normal(this->node->raw);
166                         mark_ref_normal(newfrag->node->raw);
167                 }
168
169                 if (lastend < newfrag->node->ofs) {
170                         /* ... and we need to put a hole in before the new node */
171                         struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
172                         if (!holefrag) {
173                                 jffs2_free_node_frag(newfrag);
174                                 return -ENOMEM;
175                         }
176                         holefrag->ofs = lastend;
177                         holefrag->size = newfrag->node->ofs - lastend;
178                         holefrag->node = NULL;
179                         if (this) {
180                                 /* By definition, the 'this' node has no right-hand child, 
181                                    because there are no frags with offset greater than it.
182                                    So that's where we want to put the hole */
183                                 D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this));
184                                 rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
185                         } else {
186                                 D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag));
187                                 rb_link_node(&holefrag->rb, NULL, &list->rb_node);
188                         }
189                         rb_insert_color(&holefrag->rb, list);
190                         this = holefrag;
191                 }
192                 if (this) {
193                         /* By definition, the 'this' node has no right-hand child, 
194                            because there are no frags with offset greater than it.
195                            So that's where we want to put the hole */
196                         D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
197                         rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);                      
198                 } else {
199                         D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
200                         rb_link_node(&newfrag->rb, NULL, &list->rb_node);
201                 }
202                 rb_insert_color(&newfrag->rb, list);
203                 return 0;
204         }
205
206         D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", 
207                   this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
208
209         /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
210          * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs  
211          */
212         if (newfrag->ofs > this->ofs) {
213                 /* This node isn't completely obsoleted. The start of it remains valid */
214
215                 /* Mark the new node and the partially covered node REF_NORMAL -- let
216                    the GC take a look at them */
217                 mark_ref_normal(newfrag->node->raw);
218                 if (this->node)
219                         mark_ref_normal(this->node->raw);
220
221                 if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
222                         /* The new node splits 'this' frag into two */
223                         struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
224                         if (!newfrag2) {
225                                 jffs2_free_node_frag(newfrag);
226                                 return -ENOMEM;
227                         }
228                         D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
229                         if (this->node)
230                                 printk("phys 0x%08x\n", ref_offset(this->node->raw));
231                         else 
232                                 printk("hole\n");
233                            )
234                         
235                         /* New second frag pointing to this's node */
236                         newfrag2->ofs = newfrag->ofs + newfrag->size;
237                         newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
238                         newfrag2->node = this->node;
239                         if (this->node)
240                                 this->node->frags++;
241
242                         /* Adjust size of original 'this' */
243                         this->size = newfrag->ofs - this->ofs;
244
245                         /* Now, we know there's no node with offset
246                            greater than this->ofs but smaller than
247                            newfrag2->ofs or newfrag->ofs, for obvious
248                            reasons. So we can do a tree insert from
249                            'this' to insert newfrag, and a tree insert
250                            from newfrag to insert newfrag2. */
251                         jffs2_fragtree_insert(newfrag, this);
252                         rb_insert_color(&newfrag->rb, list);
253                         
254                         jffs2_fragtree_insert(newfrag2, newfrag);
255                         rb_insert_color(&newfrag2->rb, list);
256                         
257                         return 0;
258                 }
259                 /* New node just reduces 'this' frag in size, doesn't split it */
260                 this->size = newfrag->ofs - this->ofs;
261
262                 /* Again, we know it lives down here in the tree */
263                 jffs2_fragtree_insert(newfrag, this);
264                 rb_insert_color(&newfrag->rb, list);
265         } else {
266                 /* New frag starts at the same point as 'this' used to. Replace 
267                    it in the tree without doing a delete and insertion */
268                 D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
269                           newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
270                           this, this->ofs, this->ofs+this->size));
271         
272                 rb_replace_node(&this->rb, &newfrag->rb, list);
273                 
274                 if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
275                         D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
276                         jffs2_obsolete_node_frag(c, this);
277                 } else {
278                         this->ofs += newfrag->size;
279                         this->size -= newfrag->size;
280
281                         jffs2_fragtree_insert(this, newfrag);
282                         rb_insert_color(&this->rb, list);
283                         return 0;
284                 }
285         }
286         /* OK, now we have newfrag added in the correct place in the tree, but
287            frag_next(newfrag) may be a fragment which is overlapped by it 
288         */
289         while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
290                 /* 'this' frag is obsoleted completely. */
291                 D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size));
292                 rb_erase(&this->rb, list);
293                 jffs2_obsolete_node_frag(c, this);
294         }
295         /* Now we're pointing at the first frag which isn't totally obsoleted by 
296            the new frag */
297
298         if (!this || newfrag->ofs + newfrag->size == this->ofs) {
299                 return 0;
300         }
301         /* Still some overlap but we don't need to move it in the tree */
302         this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
303         this->ofs = newfrag->ofs + newfrag->size;
304
305         /* And mark them REF_NORMAL so the GC takes a look at them */
306         if (this->node)
307                 mark_ref_normal(this->node->raw);
308         mark_ref_normal(newfrag->node->raw);
309
310         return 0;
311 }
312
313 void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
314 {
315         struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
316
317         D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
318
319         /* We know frag->ofs <= size. That's what lookup does for us */
320         if (frag && frag->ofs != size) {
321                 if (frag->ofs+frag->size >= size) {
322                         D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
323                         frag->size = size - frag->ofs;
324                 }
325                 frag = frag_next(frag);
326         }
327         while (frag && frag->ofs >= size) {
328                 struct jffs2_node_frag *next = frag_next(frag);
329
330                 D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
331                 frag_erase(frag, list);
332                 jffs2_obsolete_node_frag(c, frag);
333                 frag = next;
334         }
335 }
336
337 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
338
339 static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 
340                                         struct jffs2_inode_info *f,
341                                         struct jffs2_raw_inode *latest_node);
342
343 int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 
344                         uint32_t ino, struct jffs2_raw_inode *latest_node)
345 {
346         D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
347
348  retry_inocache:
349         spin_lock(&c->inocache_lock);
350         f->inocache = jffs2_get_ino_cache(c, ino);
351
352         D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
353
354         if (f->inocache) {
355                 /* Check its state. We may need to wait before we can use it */
356                 switch(f->inocache->state) {
357                 case INO_STATE_UNCHECKED:
358                 case INO_STATE_CHECKEDABSENT:
359                         f->inocache->state = INO_STATE_READING;
360                         break;
361                         
362                 case INO_STATE_CHECKING:
363                 case INO_STATE_GC:
364                         /* If it's in either of these states, we need
365                            to wait for whoever's got it to finish and
366                            put it back. */
367                         D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
368                                   ino, f->inocache->state));
369                         sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
370                         goto retry_inocache;
371
372                 case INO_STATE_READING:
373                 case INO_STATE_PRESENT:
374                         /* Eep. This should never happen. It can
375                         happen if Linux calls read_inode() again
376                         before clear_inode() has finished though. */
377                         printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
378                         /* Fail. That's probably better than allowing it to succeed */
379                         f->inocache = NULL;
380                         break;
381
382                 default:
383                         BUG();
384                 }
385         }
386         spin_unlock(&c->inocache_lock);
387         if (!f->inocache && ino == 1) {
388                 /* Special case - no root inode on medium */
389                 f->inocache = jffs2_alloc_inode_cache();
390                 if (!f->inocache) {
391                         printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
392                         return -ENOMEM;
393                 }
394                 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
395                 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
396                 f->inocache->ino = f->inocache->nlink = 1;
397                 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
398                 f->inocache->state = INO_STATE_READING;
399                 jffs2_add_ino_cache(c, f->inocache);
400         }
401         if (!f->inocache) {
402                 printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
403                 return -ENOENT;
404         }
405
406         return jffs2_do_read_inode_internal(c, f, latest_node);
407 }
408
409 int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
410 {
411         struct jffs2_raw_inode n;
412         struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
413         int ret;
414
415         if (!f)
416                 return -ENOMEM;
417
418         memset(f, 0, sizeof(*f));
419         init_MUTEX_LOCKED(&f->sem);
420         f->inocache = ic;
421
422         ret = jffs2_do_read_inode_internal(c, f, &n);
423         if (!ret) {
424                 up(&f->sem);
425                 jffs2_do_clear_inode(c, f);
426         }
427         kfree (f);
428         return ret;
429 }
430
431 static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 
432                                         struct jffs2_inode_info *f,
433                                         struct jffs2_raw_inode *latest_node)
434 {
435         struct jffs2_tmp_dnode_info *tn_list, *tn;
436         struct jffs2_full_dirent *fd_list;
437         struct jffs2_full_dnode *fn = NULL;
438         uint32_t crc;
439         uint32_t latest_mctime, mctime_ver;
440         uint32_t mdata_ver = 0;
441         size_t retlen;
442         int ret;
443
444         D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
445
446         /* Grab all nodes relevant to this ino */
447         ret = jffs2_get_inode_nodes(c, f->inocache->ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
448
449         if (ret) {
450                 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
451                 if (f->inocache->state == INO_STATE_READING)
452                         jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
453                 return ret;
454         }
455         f->dents = fd_list;
456
457         while (tn_list) {
458                 tn = tn_list;
459
460                 fn = tn->fn;
461
462                 if (f->metadata) {
463                         if (tn->version > mdata_ver) {
464                                 D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
465                                 jffs2_mark_node_obsolete(c, f->metadata->raw);
466                                 jffs2_free_full_dnode(f->metadata);
467                                 f->metadata = NULL;
468                                 
469                                 mdata_ver = 0;
470                         } else {
471                                 D1(printk(KERN_DEBUG "Er. New metadata at 0x%08x with ver %d is actually older than previous %d\n",
472                                        ref_offset(f->metadata->raw), tn->version, mdata_ver));
473                                 jffs2_mark_node_obsolete(c, fn->raw);
474                                 jffs2_free_full_dnode(fn);
475                                 goto next_tn;
476                         }
477                 }
478
479                 if (fn->size) {
480                         jffs2_add_full_dnode_to_inode(c, f, fn);
481                 } else {
482                         /* Zero-sized node at end of version list. Just a metadata update */
483                         D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
484                         f->metadata = fn;
485                         mdata_ver = tn->version;
486                 }
487         next_tn:
488                 tn_list = tn->next;
489                 jffs2_free_tmp_dnode_info(tn);
490         }
491         if (!fn) {
492                 /* No data nodes for this inode. */
493                 if (f->inocache->ino != 1) {
494                         printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
495                         if (!fd_list) {
496                                 if (f->inocache->state == INO_STATE_READING)
497                                         jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
498                                 return -EIO;
499                         }
500                         printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
501                 }
502                 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
503                 latest_node->version = cpu_to_je32(0);
504                 latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
505                 latest_node->isize = cpu_to_je32(0);
506                 latest_node->gid = cpu_to_je16(0);
507                 latest_node->uid = cpu_to_je16(0);
508                 if (f->inocache->state == INO_STATE_READING)
509                         jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
510                 return 0;
511         }
512
513         ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
514         if (ret || retlen != sizeof(*latest_node)) {
515                 printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
516                        ret, retlen, sizeof(*latest_node));
517                 /* FIXME: If this fails, there seems to be a memory leak. Find it. */
518                 up(&f->sem);
519                 jffs2_do_clear_inode(c, f);
520                 return ret?ret:-EIO;
521         }
522
523         crc = crc32(0, latest_node, sizeof(*latest_node)-8);
524         if (crc != je32_to_cpu(latest_node->node_crc)) {
525                 printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
526                 up(&f->sem);
527                 jffs2_do_clear_inode(c, f);
528                 return -EIO;
529         }
530
531         switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
532         case S_IFDIR:
533                 if (mctime_ver > je32_to_cpu(latest_node->version)) {
534                         /* The times in the latest_node are actually older than
535                            mctime in the latest dirent. Cheat. */
536                         latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
537                 }
538                 break;
539
540                         
541         case S_IFREG:
542                 /* If it was a regular file, truncate it to the latest node's isize */
543                 jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));
544                 break;
545
546         case S_IFLNK:
547                 /* Hack to work around broken isize in old symlink code.
548                    Remove this when dwmw2 comes to his senses and stops
549                    symlinks from being an entirely gratuitous special
550                    case. */
551                 if (!je32_to_cpu(latest_node->isize))
552                         latest_node->isize = latest_node->dsize;
553                 /* fall through... */
554
555         case S_IFBLK:
556         case S_IFCHR:
557                 /* Certain inode types should have only one data node, and it's
558                    kept as the metadata node */
559                 if (f->metadata) {
560                         printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
561                                f->inocache->ino, jemode_to_cpu(latest_node->mode));
562                         up(&f->sem);
563                         jffs2_do_clear_inode(c, f);
564                         return -EIO;
565                 }
566                 if (!frag_first(&f->fragtree)) {
567                         printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
568                                f->inocache->ino, jemode_to_cpu(latest_node->mode));
569                         up(&f->sem);
570                         jffs2_do_clear_inode(c, f);
571                         return -EIO;
572                 }
573                 /* ASSERT: f->fraglist != NULL */
574                 if (frag_next(frag_first(&f->fragtree))) {
575                         printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
576                                f->inocache->ino, jemode_to_cpu(latest_node->mode));
577                         /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
578                         up(&f->sem);
579                         jffs2_do_clear_inode(c, f);
580                         return -EIO;
581                 }
582                 /* OK. We're happy */
583                 f->metadata = frag_first(&f->fragtree)->node;
584                 jffs2_free_node_frag(frag_first(&f->fragtree));
585                 f->fragtree = RB_ROOT;
586                 break;
587         }
588         if (f->inocache->state == INO_STATE_READING)
589                 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
590
591         return 0;
592 }
593
594 void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
595 {
596         struct jffs2_full_dirent *fd, *fds;
597         /* I don't think we care about the potential race due to reading this
598            without f->sem. It can never get undeleted. */
599         int deleted = f->inocache && !f->inocache->nlink;
600
601         /* If it's a deleted inode, grab the alloc_sem. This prevents
602            jffs2_garbage_collect_pass() from deciding that it wants to
603            garbage collect one of the nodes we're just about to mark 
604            obsolete -- by the time we drop alloc_sem and return, all
605            the nodes are marked obsolete, and jffs2_g_c_pass() won't
606            call iget() for the inode in question.
607
608            We also used to do this to keep the temporary BUG() in 
609            jffs2_mark_node_obsolete() from triggering. 
610         */
611         if(deleted)
612                 down(&c->alloc_sem);
613
614         down(&f->sem);
615
616         if (f->metadata) {
617                 if (deleted)
618                         jffs2_mark_node_obsolete(c, f->metadata->raw);
619                 jffs2_free_full_dnode(f->metadata);
620         }
621
622         jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
623
624         fds = f->dents;
625
626         while(fds) {
627                 fd = fds;
628                 fds = fd->next;
629                 jffs2_free_full_dirent(fd);
630         }
631
632         if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
633                 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
634
635         up(&f->sem);
636
637         if(deleted)
638                 up(&c->alloc_sem);
639 }