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