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