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