blob: 85a285b2a309825a9bf551abbeea0d5314b4dade [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. Bityutskiyf97117d2005-07-27 15:46:14 +010010 * $Id: readinode.c,v 1.131 2005/07/27 14:46:11 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
Artem B. Bityutskiyf302cd02005-07-24 16:29:59 +010023void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070024{
25 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
26
27 D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
28
29 /* We know frag->ofs <= size. That's what lookup does for us */
30 if (frag && frag->ofs != size) {
31 if (frag->ofs+frag->size >= size) {
32 D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
33 frag->size = size - frag->ofs;
34 }
35 frag = frag_next(frag);
36 }
37 while (frag && frag->ofs >= size) {
38 struct jffs2_node_frag *next = frag_next(frag);
39
40 D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
41 frag_erase(frag, list);
42 jffs2_obsolete_node_frag(c, frag);
43 frag = next;
44 }
45}
46
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +010047/*
48 * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
49 * order of increasing version.
50 */
51static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052{
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +010053 struct rb_node **p = &list->rb_node;
54 struct rb_node * parent = NULL;
55 struct jffs2_tmp_dnode_info *this;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +010057 while (*p) {
58 parent = *p;
59 this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +010061 /* There may actually be a collision here, but it doesn't
62 actually matter. As long as the two nodes with the same
63 version are together, it's all fine. */
64 if (tn->version < this->version)
65 p = &(*p)->rb_left;
66 else
67 p = &(*p)->rb_right;
68 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +010070 rb_link_node(&tn->rb, parent, p);
71 rb_insert_color(&tn->rb, list);
72}
73
74static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
75{
76 struct rb_node *this;
77 struct jffs2_tmp_dnode_info *tn;
78
79 this = list->rb_node;
80
81 /* Now at bottom of tree */
82 while (this) {
83 if (this->rb_left)
84 this = this->rb_left;
85 else if (this->rb_right)
86 this = this->rb_right;
87 else {
88 tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
89 jffs2_free_full_dnode(tn->fn);
90 jffs2_free_tmp_dnode_info(tn);
91
92 this = this->rb_parent;
93 if (!this)
94 break;
95
96 if (this->rb_left == &tn->rb)
97 this->rb_left = NULL;
98 else if (this->rb_right == &tn->rb)
99 this->rb_right = NULL;
100 else BUG();
101 }
102 }
103 list->rb_node = NULL;
104}
105
106static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
107{
108 struct jffs2_full_dirent *next;
109
110 while (fd) {
111 next = fd->next;
112 jffs2_free_full_dirent(fd);
113 fd = next;
114 }
115}
116
117/* Returns first valid node after 'ref'. May return 'ref' */
118static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
119{
120 while (ref && ref->next_in_ino) {
121 if (!ref_obsolete(ref))
122 return ref;
123 D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
124 ref = ref->next_in_ino;
125 }
126 return NULL;
127}
128
129/*
130 * Helper function for jffs2_get_inode_nodes().
131 * It is called every time an directory entry node is found.
132 *
133 * Returns: 0 on succes;
134 * 1 if the node should be marked obsolete;
135 * negative error code on failure.
136 */
137static inline int
138read_direntry(struct jffs2_sb_info *c,
139 struct jffs2_raw_node_ref *ref,
140 struct jffs2_raw_dirent *rd,
141 uint32_t read,
142 struct jffs2_full_dirent **fdp,
143 int32_t *latest_mctime,
144 uint32_t *mctime_ver)
145{
146 struct jffs2_full_dirent *fd;
147
148 /* The direntry nodes are checked during the flash scanning */
149 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
150 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
151 BUG_ON(ref_obsolete(ref));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100153 /* Sanity check */
154 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
155 printk(KERN_ERR "Error! Illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
156 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
157 return 1;
158 }
159
160 fd = jffs2_alloc_full_dirent(rd->nsize + 1);
161 if (unlikely(!fd))
162 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100164 fd->raw = ref;
165 fd->version = je32_to_cpu(rd->version);
166 fd->ino = je32_to_cpu(rd->ino);
167 fd->type = rd->type;
168
169 /* Pick out the mctime of the latest dirent */
170 if(fd->version > *mctime_ver) {
171 *mctime_ver = fd->version;
172 *latest_mctime = je32_to_cpu(rd->mctime);
173 }
174
175 /*
176 * Copy as much of the name as possible from the raw
177 * dirent we've already read from the flash.
178 */
179 if (read > sizeof(*rd))
180 memcpy(&fd->name[0], &rd->name[0],
181 min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
182
183 /* Do we need to copy any more of the name directly from the flash? */
184 if (rd->nsize + sizeof(*rd) > read) {
185 /* FIXME: point() */
186 int err;
187 int already = read - sizeof(*rd);
188
189 err = jffs2_flash_read(c, (ref_offset(ref)) + read,
190 rd->nsize - already, &read, &fd->name[already]);
191 if (unlikely(read != rd->nsize - already) && likely(!err))
192 return -EIO;
193
194 if (unlikely(err)) {
195 printk(KERN_WARNING "Read remainder of name: error %d\n", err);
196 jffs2_free_full_dirent(fd);
197 return -EIO;
198 }
199 }
200
201 fd->nhash = full_name_hash(fd->name, rd->nsize);
202 fd->next = NULL;
203 fd->name[rd->nsize] = '\0';
204
205 /*
206 * Wheee. We now have a complete jffs2_full_dirent structure, with
207 * the name in it and everything. Link it into the list
208 */
209 D1(printk(KERN_DEBUG "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino));
210
211 jffs2_add_fd_to_list(c, fd, fdp);
212
213 return 0;
214}
215
216/*
217 * Helper function for jffs2_get_inode_nodes().
218 * It is called every time an inode node is found.
219 *
220 * Returns: 0 on succes;
221 * 1 if the node should be marked obsolete;
222 * negative error code on failure.
223 */
224static inline int
225read_dnode(struct jffs2_sb_info *c,
226 struct jffs2_raw_node_ref *ref,
227 struct jffs2_raw_inode *rd,
228 uint32_t read,
229 struct rb_root *tnp,
230 int32_t *latest_mctime,
231 uint32_t *mctime_ver)
232{
233 struct jffs2_eraseblock *jeb;
234 struct jffs2_tmp_dnode_info *tn;
235
236 /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
237 BUG_ON(ref_obsolete(ref));
238
239 /* If we've never checked the CRCs on this node, check them now */
240 if (ref_flags(ref) == REF_UNCHECKED) {
241 uint32_t crc, len;
242
243 crc = crc32(0, rd, sizeof(*rd) - 8);
244 if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
245 printk(KERN_WARNING "Header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
246 ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
247 return 1;
248 }
249
250 /* Sanity checks */
251 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
252 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
253 printk(KERN_WARNING "Inode corrupted at %#08x, totlen %d, #ino %d, version %d, "
254 "isize %d, csize %d, dsize %d \n",
255 ref_offset(ref), je32_to_cpu(rd->totlen), je32_to_cpu(rd->ino),
256 je32_to_cpu(rd->version), je32_to_cpu(rd->isize),
257 je32_to_cpu(rd->csize), je32_to_cpu(rd->dsize));
258 return 1;
259 }
260
261 if (rd->compr != JFFS2_COMPR_ZERO && je32_to_cpu(rd->csize)) {
262 unsigned char *buf = NULL;
263 uint32_t pointed = 0;
264 int err;
265#ifndef __ECOS
266 if (c->mtd->point) {
267 err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize),
268 &read, &buf);
269 if (unlikely(read < je32_to_cpu(rd->csize)) && likely(!err)) {
270 D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", read));
271 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd),
272 je32_to_cpu(rd->csize));
273 } else if (unlikely(err)){
274 D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
275 } else
276 pointed = 1; /* succefully pointed to device */
277 }
278#endif
279 if(!pointed){
280 buf = kmalloc(je32_to_cpu(rd->csize), GFP_KERNEL);
281 if (!buf)
282 return -ENOMEM;
283
284 err = jffs2_flash_read(c, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize),
285 &read, buf);
286 if (unlikely(read != je32_to_cpu(rd->csize)) && likely(!err))
287 err = -EIO;
288 if (err) {
289 kfree(buf);
290 return err;
291 }
292 }
293 crc = crc32(0, buf, je32_to_cpu(rd->csize));
294 if(!pointed)
295 kfree(buf);
296#ifndef __ECOS
297 else
298 c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize));
299#endif
300
301 if (crc != je32_to_cpu(rd->data_crc)) {
302 printk(KERN_NOTICE "Data CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
303 ref_offset(ref), je32_to_cpu(rd->data_crc), crc);
304 return 1;
305 }
306
307 }
308
309 /* Mark the node as having been checked and fix the accounting accordingly */
310 jeb = &c->blocks[ref->flash_offset / c->sector_size];
311 len = ref_totlen(c, jeb, ref);
312
313 spin_lock(&c->erase_completion_lock);
314 jeb->used_size += len;
315 jeb->unchecked_size -= len;
316 c->used_size += len;
317 c->unchecked_size -= len;
318
319 /* If node covers at least a whole page, or if it starts at the
320 beginning of a page and runs to the end of the file, or if
321 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
322
323 If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
324 when the overlapping node(s) get added to the tree anyway.
325 */
326 if ((je32_to_cpu(rd->dsize) >= PAGE_CACHE_SIZE) ||
327 ( ((je32_to_cpu(rd->offset) & (PAGE_CACHE_SIZE-1))==0) &&
328 (je32_to_cpu(rd->dsize) + je32_to_cpu(rd->offset) == je32_to_cpu(rd->isize)))) {
329 D1(printk(KERN_DEBUG "Marking node at %#08x REF_PRISTINE\n", ref_offset(ref)));
330 ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
331 } else {
332 D1(printk(KERN_DEBUG "Marking node at %#08x REF_NORMAL\n", ref_offset(ref)));
333 ref->flash_offset = ref_offset(ref) | REF_NORMAL;
334 }
335 spin_unlock(&c->erase_completion_lock);
336 }
337
338 tn = jffs2_alloc_tmp_dnode_info();
339 if (!tn) {
340 D1(printk(KERN_DEBUG "alloc tn failed\n"));
341 return -ENOMEM;
342 }
343
344 tn->fn = jffs2_alloc_full_dnode();
345 if (!tn->fn) {
346 D1(printk(KERN_DEBUG "alloc fn failed\n"));
347 jffs2_free_tmp_dnode_info(tn);
348 return -ENOMEM;
349 }
350
351 tn->version = je32_to_cpu(rd->version);
352 tn->fn->ofs = je32_to_cpu(rd->offset);
353 tn->fn->raw = ref;
354
355 /* There was a bug where we wrote hole nodes out with
356 csize/dsize swapped. Deal with it */
357 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && je32_to_cpu(rd->csize))
358 tn->fn->size = je32_to_cpu(rd->csize);
359 else // normal case...
360 tn->fn->size = je32_to_cpu(rd->dsize);
361
362 D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %#04x, dsize %#04x\n",
363 ref_offset(ref), je32_to_cpu(rd->version),
364 je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize)));
365
366 jffs2_add_tn_to_tree(tn, tnp);
367
368 return 0;
369}
370
371/*
372 * Helper function for jffs2_get_inode_nodes().
373 * It is called every time an unknown node is found.
374 *
375 * Returns: 0 on succes;
376 * 1 if the node should be marked obsolete;
377 * negative error code on failure.
378 */
379static inline int
380read_unknown(struct jffs2_sb_info *c,
381 struct jffs2_raw_node_ref *ref,
382 struct jffs2_unknown_node *un,
383 uint32_t read)
384{
385 /* We don't mark unknown nodes as REF_UNCHECKED */
386 BUG_ON(ref_flags(ref) == REF_UNCHECKED);
387
388 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
389
390 if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
391
392 /* Hmmm. This should have been caught at scan time. */
393 printk(KERN_WARNING "Warning! Node header CRC failed at %#08x. "
394 "But it must have been OK earlier.\n", ref_offset(ref));
395 D1(printk(KERN_DEBUG "Node was: { %#04x, %#04x, %#08x, %#08x }\n",
396 je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
397 je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)));
398 return 1;
399 } else {
400 switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
401
402 case JFFS2_FEATURE_INCOMPAT:
403 printk(KERN_NOTICE "Unknown INCOMPAT nodetype %#04X at %#08x\n",
404 je16_to_cpu(un->nodetype), ref_offset(ref));
405 /* EEP */
406 BUG();
407 break;
408
409 case JFFS2_FEATURE_ROCOMPAT:
410 printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %#04X at %#08x\n",
411 je16_to_cpu(un->nodetype), ref_offset(ref));
412 BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
413 break;
414
415 case JFFS2_FEATURE_RWCOMPAT_COPY:
416 printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
417 je16_to_cpu(un->nodetype), ref_offset(ref));
418 break;
419
420 case JFFS2_FEATURE_RWCOMPAT_DELETE:
421 printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
422 je16_to_cpu(un->nodetype), ref_offset(ref));
423 return 1;
424 }
425 }
426
427 return 0;
428}
429
430/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
431 with this ino, returning the former in order of version */
432
433static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
434 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
435 uint32_t *highest_version, uint32_t *latest_mctime,
436 uint32_t *mctime_ver)
437{
438 struct jffs2_raw_node_ref *ref, *valid_ref;
439 struct rb_root ret_tn = RB_ROOT;
440 struct jffs2_full_dirent *ret_fd = NULL;
441 union jffs2_node_union node;
442 size_t retlen;
443 int err;
444
445 *mctime_ver = 0;
446
447 D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));
448
449 spin_lock(&c->erase_completion_lock);
450
451 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
452
453 if (!valid_ref && (f->inocache->ino != 1))
454 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
455
456 while (valid_ref) {
457 /* We can hold a pointer to a non-obsolete node without the spinlock,
458 but _obsolete_ nodes may disappear at any time, if the block
459 they're in gets erased. So if we mark 'ref' obsolete while we're
460 not holding the lock, it can go away immediately. For that reason,
461 we find the next valid node first, before processing 'ref'.
462 */
463 ref = valid_ref;
464 valid_ref = jffs2_first_valid_node(ref->next_in_ino);
465 spin_unlock(&c->erase_completion_lock);
466
467 cond_resched();
468
469 /* FIXME: point() */
470 err = jffs2_flash_read(c, (ref_offset(ref)),
471 min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
472 &retlen, (void *)&node);
473 if (err) {
474 printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
475 goto free_out;
476 }
477
478 switch (je16_to_cpu(node.u.nodetype)) {
479
480 case JFFS2_NODETYPE_DIRENT:
481 D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
482
483 if (retlen < sizeof(node.d)) {
484 printk(KERN_WARNING "Warning! Short read dirent at %#08x\n", ref_offset(ref));
485 err = -EIO;
486 goto free_out;
487 }
488
489 err = read_direntry(c, ref, &node.d, retlen, &ret_fd, latest_mctime, mctime_ver);
490 if (err == 1) {
491 jffs2_mark_node_obsolete(c, ref);
492 break;
493 } else if (unlikely(err))
494 goto free_out;
495
496 if (je32_to_cpu(node.d.version) > *highest_version)
497 *highest_version = je32_to_cpu(node.d.version);
498
499 break;
500
501 case JFFS2_NODETYPE_INODE:
502 D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
503
504 if (retlen < sizeof(node.i)) {
505 printk(KERN_WARNING "Warning! Short read dnode at %#08x\n", ref_offset(ref));
506 err = -EIO;
507 goto free_out;
508 }
509
510 err = read_dnode(c, ref, &node.i, retlen, &ret_tn, latest_mctime, mctime_ver);
511 if (err == 1) {
512 jffs2_mark_node_obsolete(c, ref);
513 break;
514 } else if (unlikely(err))
515 goto free_out;
516
517 if (je32_to_cpu(node.i.version) > *highest_version)
518 *highest_version = je32_to_cpu(node.i.version);
519
520 D1(printk(KERN_DEBUG "version %d, highest_version now %d\n",
521 je32_to_cpu(node.i.version), *highest_version));
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 break;
524
525 default:
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100526 /* Check we've managed to read at least the common node header */
527 if (retlen < sizeof(struct jffs2_unknown_node)) {
528 printk(KERN_WARNING "Warning! Short read unknown node at %#08x\n",
529 ref_offset(ref));
530 return -EIO;
531 }
532
533 err = read_unknown(c, ref, &node.u, retlen);
534 if (err == 1) {
535 jffs2_mark_node_obsolete(c, ref);
536 break;
537 } else if (unlikely(err))
538 goto free_out;
539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 }
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100541 spin_lock(&c->erase_completion_lock);
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100544 spin_unlock(&c->erase_completion_lock);
545 *tnp = ret_tn;
546 *fdp = ret_fd;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100548 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100550 free_out:
551 jffs2_free_tmp_dnode_info_list(&ret_tn);
552 jffs2_free_full_dirent_list(ret_fd);
553 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554}
555
556static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
557 struct jffs2_inode_info *f,
558 struct jffs2_raw_inode *latest_node)
559{
David Woodhouse9dee7502005-07-05 22:03:10 +0100560 struct jffs2_tmp_dnode_info *tn = NULL;
561 struct rb_root tn_list;
562 struct rb_node *rb, *repl_rb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 struct jffs2_full_dirent *fd_list;
564 struct jffs2_full_dnode *fn = NULL;
565 uint32_t crc;
566 uint32_t latest_mctime, mctime_ver;
567 uint32_t mdata_ver = 0;
568 size_t retlen;
569 int ret;
570
571 D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
572
573 /* Grab all nodes relevant to this ino */
574 ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
575
576 if (ret) {
577 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
578 if (f->inocache->state == INO_STATE_READING)
579 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
580 return ret;
581 }
582 f->dents = fd_list;
583
David Woodhouse9dee7502005-07-05 22:03:10 +0100584 rb = rb_first(&tn_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
David Woodhouse9dee7502005-07-05 22:03:10 +0100586 while (rb) {
587 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 fn = tn->fn;
589
590 if (f->metadata) {
591 if (likely(tn->version >= mdata_ver)) {
592 D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
593 jffs2_mark_node_obsolete(c, f->metadata->raw);
594 jffs2_free_full_dnode(f->metadata);
595 f->metadata = NULL;
596
597 mdata_ver = 0;
598 } else {
599 /* This should never happen. */
600 printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
601 ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
602 jffs2_mark_node_obsolete(c, fn->raw);
603 jffs2_free_full_dnode(fn);
604 /* Fill in latest_node from the metadata, not this one we're about to free... */
605 fn = f->metadata;
606 goto next_tn;
607 }
608 }
609
610 if (fn->size) {
611 jffs2_add_full_dnode_to_inode(c, f, fn);
612 } else {
613 /* Zero-sized node at end of version list. Just a metadata update */
614 D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
615 f->metadata = fn;
616 mdata_ver = tn->version;
617 }
618 next_tn:
David Woodhouse9dee7502005-07-05 22:03:10 +0100619 BUG_ON(rb->rb_left);
David Woodhouse9dee7502005-07-05 22:03:10 +0100620 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
621 /* We were then left-hand child of our parent. We need
622 to move our own right-hand child into our place. */
623 repl_rb = rb->rb_right;
624 if (repl_rb)
625 repl_rb->rb_parent = rb->rb_parent;
626 } else
627 repl_rb = NULL;
628
629 rb = rb_next(rb);
630
631 /* Remove the spent tn from the tree; don't bother rebalancing
632 but put our right-hand child in our own place. */
633 if (tn->rb.rb_parent) {
634 if (tn->rb.rb_parent->rb_left == &tn->rb)
635 tn->rb.rb_parent->rb_left = repl_rb;
636 else if (tn->rb.rb_parent->rb_right == &tn->rb)
637 tn->rb.rb_parent->rb_right = repl_rb;
638 else BUG();
639 } else if (tn->rb.rb_right)
640 tn->rb.rb_right->rb_parent = NULL;
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 jffs2_free_tmp_dnode_info(tn);
643 }
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100644 jffs2_dbg_fragtree_paranoia_check_nolock(f);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
646 if (!fn) {
647 /* No data nodes for this inode. */
648 if (f->inocache->ino != 1) {
649 printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
650 if (!fd_list) {
651 if (f->inocache->state == INO_STATE_READING)
652 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
653 return -EIO;
654 }
655 printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
656 }
657 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
658 latest_node->version = cpu_to_je32(0);
659 latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
660 latest_node->isize = cpu_to_je32(0);
661 latest_node->gid = cpu_to_je16(0);
662 latest_node->uid = cpu_to_je16(0);
663 if (f->inocache->state == INO_STATE_READING)
664 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
665 return 0;
666 }
667
668 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
669 if (ret || retlen != sizeof(*latest_node)) {
670 printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
671 ret, retlen, sizeof(*latest_node));
672 /* FIXME: If this fails, there seems to be a memory leak. Find it. */
673 up(&f->sem);
674 jffs2_do_clear_inode(c, f);
675 return ret?ret:-EIO;
676 }
677
678 crc = crc32(0, latest_node, sizeof(*latest_node)-8);
679 if (crc != je32_to_cpu(latest_node->node_crc)) {
680 printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
681 up(&f->sem);
682 jffs2_do_clear_inode(c, f);
683 return -EIO;
684 }
685
686 switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
687 case S_IFDIR:
688 if (mctime_ver > je32_to_cpu(latest_node->version)) {
689 /* The times in the latest_node are actually older than
690 mctime in the latest dirent. Cheat. */
691 latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
692 }
693 break;
694
695
696 case S_IFREG:
697 /* If it was a regular file, truncate it to the latest node's isize */
Artem B. Bityutskiyf302cd02005-07-24 16:29:59 +0100698 jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 break;
700
701 case S_IFLNK:
702 /* Hack to work around broken isize in old symlink code.
703 Remove this when dwmw2 comes to his senses and stops
704 symlinks from being an entirely gratuitous special
705 case. */
706 if (!je32_to_cpu(latest_node->isize))
707 latest_node->isize = latest_node->dsize;
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000708
709 if (f->inocache->state != INO_STATE_CHECKING) {
710 /* Symlink's inode data is the target path. Read it and
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100711 * keep in RAM to facilitate quick follow symlink
712 * operation. */
713 f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
714 if (!f->target) {
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000715 printk(KERN_WARNING "Can't allocate %d bytes of memory "
716 "for the symlink target path cache\n",
717 je32_to_cpu(latest_node->csize));
718 up(&f->sem);
719 jffs2_do_clear_inode(c, f);
720 return -ENOMEM;
721 }
722
723 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100724 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000725
726 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
727 if (retlen != je32_to_cpu(latest_node->csize))
728 ret = -EIO;
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100729 kfree(f->target);
730 f->target = NULL;
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000731 up(&f->sem);
732 jffs2_do_clear_inode(c, f);
733 return -ret;
734 }
735
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100736 f->target[je32_to_cpu(latest_node->csize)] = '\0';
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000737 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100738 f->target));
Artem B. Bityuckiy32f1a952005-03-01 10:50:52 +0000739 }
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 /* fall through... */
742
743 case S_IFBLK:
744 case S_IFCHR:
745 /* Certain inode types should have only one data node, and it's
746 kept as the metadata node */
747 if (f->metadata) {
748 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
749 f->inocache->ino, jemode_to_cpu(latest_node->mode));
750 up(&f->sem);
751 jffs2_do_clear_inode(c, f);
752 return -EIO;
753 }
754 if (!frag_first(&f->fragtree)) {
755 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
756 f->inocache->ino, jemode_to_cpu(latest_node->mode));
757 up(&f->sem);
758 jffs2_do_clear_inode(c, f);
759 return -EIO;
760 }
761 /* ASSERT: f->fraglist != NULL */
762 if (frag_next(frag_first(&f->fragtree))) {
763 printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
764 f->inocache->ino, jemode_to_cpu(latest_node->mode));
765 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
766 up(&f->sem);
767 jffs2_do_clear_inode(c, f);
768 return -EIO;
769 }
770 /* OK. We're happy */
771 f->metadata = frag_first(&f->fragtree)->node;
772 jffs2_free_node_frag(frag_first(&f->fragtree));
773 f->fragtree = RB_ROOT;
774 break;
775 }
776 if (f->inocache->state == INO_STATE_READING)
777 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
778
779 return 0;
780}
781
Artem B. Bityutskiyf97117d2005-07-27 15:46:14 +0100782/* Scan the list of all nodes present for this ino, build map of versions, etc. */
783int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
784 uint32_t ino, struct jffs2_raw_inode *latest_node)
785{
786 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
787
788 retry_inocache:
789 spin_lock(&c->inocache_lock);
790 f->inocache = jffs2_get_ino_cache(c, ino);
791
792 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
793
794 if (f->inocache) {
795 /* Check its state. We may need to wait before we can use it */
796 switch(f->inocache->state) {
797 case INO_STATE_UNCHECKED:
798 case INO_STATE_CHECKEDABSENT:
799 f->inocache->state = INO_STATE_READING;
800 break;
801
802 case INO_STATE_CHECKING:
803 case INO_STATE_GC:
804 /* If it's in either of these states, we need
805 to wait for whoever's got it to finish and
806 put it back. */
807 D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
808 ino, f->inocache->state));
809 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
810 goto retry_inocache;
811
812 case INO_STATE_READING:
813 case INO_STATE_PRESENT:
814 /* Eep. This should never happen. It can
815 happen if Linux calls read_inode() again
816 before clear_inode() has finished though. */
817 printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
818 /* Fail. That's probably better than allowing it to succeed */
819 f->inocache = NULL;
820 break;
821
822 default:
823 BUG();
824 }
825 }
826 spin_unlock(&c->inocache_lock);
827
828 if (!f->inocache && ino == 1) {
829 /* Special case - no root inode on medium */
830 f->inocache = jffs2_alloc_inode_cache();
831 if (!f->inocache) {
832 printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
833 return -ENOMEM;
834 }
835 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
836 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
837 f->inocache->ino = f->inocache->nlink = 1;
838 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
839 f->inocache->state = INO_STATE_READING;
840 jffs2_add_ino_cache(c, f->inocache);
841 }
842 if (!f->inocache) {
843 printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
844 return -ENOENT;
845 }
846
847 return jffs2_do_read_inode_internal(c, f, latest_node);
848}
849
850int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
851{
852 struct jffs2_raw_inode n;
853 struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
854 int ret;
855
856 if (!f)
857 return -ENOMEM;
858
859 memset(f, 0, sizeof(*f));
860 init_MUTEX_LOCKED(&f->sem);
861 f->inocache = ic;
862
863 ret = jffs2_do_read_inode_internal(c, f, &n);
864 if (!ret) {
865 up(&f->sem);
866 jffs2_do_clear_inode(c, f);
867 }
868 kfree (f);
869 return ret;
870}
871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
873{
874 struct jffs2_full_dirent *fd, *fds;
875 int deleted;
876
877 down(&f->sem);
878 deleted = f->inocache && !f->inocache->nlink;
879
David Woodhouse67e345d2005-02-27 23:01:36 +0000880 if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
881 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
882
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 if (f->metadata) {
884 if (deleted)
885 jffs2_mark_node_obsolete(c, f->metadata->raw);
886 jffs2_free_full_dnode(f->metadata);
887 }
888
889 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
890
Artem B. Bityutskiy2b79adc2005-07-17 12:13:51 +0100891 if (f->target) {
892 kfree(f->target);
893 f->target = NULL;
894 }
895
896 fds = f->dents;
897 while(fds) {
898 fd = fds;
899 fds = fd->next;
900 jffs2_free_full_dirent(fd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 }
902
David Woodhouse67e345d2005-02-27 23:01:36 +0000903 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
David Woodhouse67e345d2005-02-27 23:01:36 +0000905 if (f->inocache->nodes == (void *)f->inocache)
906 jffs2_del_ino_cache(c, f->inocache);
907 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908
909 up(&f->sem);
910}