Lines Matching +full:node +full:- +full:version

2  * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright © 2001-2007 Red Hat, Inc.
25 * Check the data CRC of the node.
28 * 1 - if incorrect;
33 struct jffs2_raw_node_ref *ref = tn->fn->raw; in check_node_data()
40 BUG_ON(tn->csize == 0); in check_node_data()
44 len = tn->csize; in check_node_data()
47 int adj = ofs % c->wbuf_pagesize; in check_node_data()
49 adj = c->wbuf_pagesize - adj; in check_node_data()
51 if (adj >= tn->csize) { in check_node_data()
52 …dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has alrea… in check_node_data()
53 ref_offset(ref), tn->csize, ofs); in check_node_data()
58 len -= adj; in check_node_data()
61 …readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts … in check_node_data()
62 ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); in check_node_data()
67 err = mtd_point(c->mtd, ofs, len, &retlen, (void **)&buffer, NULL); in check_node_data()
69 JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); in check_node_data()
70 mtd_unpoint(c->mtd, ofs, retlen); in check_node_data()
72 if (err != -EOPNOTSUPP) in check_node_data()
81 return -ENOMEM; in check_node_data()
93 err = -EIO; in check_node_data()
99 crc = crc32(tn->partial_crc, buffer, len); in check_node_data()
104 mtd_unpoint(c->mtd, ofs, len); in check_node_data()
107 if (crc != tn->data_crc) { in check_node_data()
108 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", in check_node_data()
109 ref_offset(ref), tn->data_crc, crc); in check_node_data()
114 jeb = &c->blocks[ref->flash_offset / c->sector_size]; in check_node_data()
118 moving it while it's marked REF_PRISTINE -- GC won't happen in check_node_data()
120 ref->flash_offset |= REF_PRISTINE; in check_node_data()
122 * Mark the node as having been checked and fix the in check_node_data()
125 spin_lock(&c->erase_completion_lock); in check_node_data()
126 jeb->used_size += len; in check_node_data()
127 jeb->unchecked_size -= len; in check_node_data()
128 c->used_size += len; in check_node_data()
129 c->unchecked_size -= len; in check_node_data()
131 spin_unlock(&c->erase_completion_lock); in check_node_data()
140 mtd_unpoint(c->mtd, ofs, len); in check_node_data()
148 * Checks the node if we are in the checking stage.
154 BUG_ON(ref_obsolete(tn->fn->raw)); in check_tn_node()
157 if (ref_flags(tn->fn->raw) != REF_UNCHECKED) in check_tn_node()
160 dbg_readinode("check node %#04x-%#04x, phys offs %#08x\n", in check_tn_node()
161 tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw)); in check_tn_node()
169 jffs2_mark_node_obsolete(c, tn->fn->raw); in check_tn_node()
182 next = tn_root->rb_node; in jffs2_lookup_tn()
187 if (tn->fn->ofs < offset) in jffs2_lookup_tn()
188 next = tn->rb.rb_right; in jffs2_lookup_tn()
189 else if (tn->fn->ofs >= offset) in jffs2_lookup_tn()
190 next = tn->rb.rb_left; in jffs2_lookup_tn()
201 jffs2_mark_node_obsolete(c, tn->fn->raw); in jffs2_kill_tn()
202 jffs2_free_full_dnode(tn->fn); in jffs2_kill_tn()
207 * arbitrary order -- they may be older or newer than the nodes which
208 * are already in the tree. Where overlaps occur, the older node can
211 * with frags -- we can have multiple entries starting at the same
215 * Returns 0 if the node was handled (including marking it obsolete)
222 uint32_t fn_end = tn->fn->ofs + tn->fn->size; in jffs2_add_tn_to_tree()
225 …dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, r… in jffs2_add_tn_to_tree()
227 /* If a node has zero dsize, we only have to keep it if it might be the in jffs2_add_tn_to_tree()
228 node with highest version -- i.e. the one which will end up as f->metadata. in jffs2_add_tn_to_tree()
231 if (!tn->fn->size) { in jffs2_add_tn_to_tree()
232 if (rii->mdata_tn) { in jffs2_add_tn_to_tree()
233 if (rii->mdata_tn->version < tn->version) { in jffs2_add_tn_to_tree()
234 /* We had a candidate mdata node already */ in jffs2_add_tn_to_tree()
235 dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version); in jffs2_add_tn_to_tree()
236 jffs2_kill_tn(c, rii->mdata_tn); in jffs2_add_tn_to_tree()
239 tn->version, rii->mdata_tn->version); in jffs2_add_tn_to_tree()
244 rii->mdata_tn = tn; in jffs2_add_tn_to_tree()
245 dbg_readinode("keep new mdata with ver %d\n", tn->version); in jffs2_add_tn_to_tree()
249 /* Find the earliest node which _may_ be relevant to this one */ in jffs2_add_tn_to_tree()
250 this = jffs2_lookup_tn(&rii->tn_root, tn->fn->ofs); in jffs2_add_tn_to_tree()
252 /* If the node is coincident with another at a lower address, in jffs2_add_tn_to_tree()
253 back up until the other node is found. It may be relevant */ in jffs2_add_tn_to_tree()
254 while (this->overlapped) { in jffs2_add_tn_to_tree()
258 * We killed a node which set the overlapped in jffs2_add_tn_to_tree()
261 this->overlapped = 0; in jffs2_add_tn_to_tree()
266 …dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, th… in jffs2_add_tn_to_tree()
270 if (this->fn->ofs > fn_end) in jffs2_add_tn_to_tree()
272 dbg_readinode("Ponder this ver %d, 0x%x-0x%x\n", in jffs2_add_tn_to_tree()
273 this->version, this->fn->ofs, this->fn->size); in jffs2_add_tn_to_tree()
275 if (this->version == tn->version) { in jffs2_add_tn_to_tree()
276 /* Version number collision means REF_PRISTINE GC. Accept either of them in jffs2_add_tn_to_tree()
280 dbg_readinode("Like old node. Throw away new\n"); in jffs2_add_tn_to_tree()
285 dbg_readinode("Like new node. Throw away old\n"); in jffs2_add_tn_to_tree()
286 rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); in jffs2_add_tn_to_tree()
292 if (this->version < tn->version && in jffs2_add_tn_to_tree()
293 this->fn->ofs >= tn->fn->ofs && in jffs2_add_tn_to_tree()
294 this->fn->ofs + this->fn->size <= fn_end) { in jffs2_add_tn_to_tree()
295 /* New node entirely overlaps 'this' */ in jffs2_add_tn_to_tree()
297 dbg_readinode("new node bad CRC\n"); in jffs2_add_tn_to_tree()
302 while (this && this->fn->ofs + this->fn->size <= fn_end) { in jffs2_add_tn_to_tree()
304 if (this->version < tn->version) { in jffs2_add_tn_to_tree()
305 tn_erase(this, &rii->tn_root); in jffs2_add_tn_to_tree()
306 dbg_readinode("Kill overlapped ver %d, 0x%x-0x%x\n", in jffs2_add_tn_to_tree()
307 this->version, this->fn->ofs, in jffs2_add_tn_to_tree()
308 this->fn->ofs+this->fn->size); in jffs2_add_tn_to_tree()
316 if (this->version > tn->version && in jffs2_add_tn_to_tree()
317 this->fn->ofs <= tn->fn->ofs && in jffs2_add_tn_to_tree()
318 this->fn->ofs+this->fn->size >= fn_end) { in jffs2_add_tn_to_tree()
319 /* New node entirely overlapped by 'this' */ in jffs2_add_tn_to_tree()
321 dbg_readinode("Good CRC on old node. Kill new\n"); in jffs2_add_tn_to_tree()
326 dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); in jffs2_add_tn_to_tree()
327 tn_erase(this, &rii->tn_root); in jffs2_add_tn_to_tree()
336 obsoleted by an earlier node. Insert into the tree */ in jffs2_add_tn_to_tree()
339 struct rb_node **link = &rii->tn_root.rb_node; in jffs2_add_tn_to_tree()
345 if (tn->fn->ofs > insert_point->fn->ofs) in jffs2_add_tn_to_tree()
346 link = &insert_point->rb.rb_right; in jffs2_add_tn_to_tree()
347 else if (tn->fn->ofs < insert_point->fn->ofs || in jffs2_add_tn_to_tree()
348 tn->fn->size < insert_point->fn->size) in jffs2_add_tn_to_tree()
349 link = &insert_point->rb.rb_left; in jffs2_add_tn_to_tree()
351 link = &insert_point->rb.rb_right; in jffs2_add_tn_to_tree()
353 rb_link_node(&tn->rb, &insert_point->rb, link); in jffs2_add_tn_to_tree()
354 rb_insert_color(&tn->rb, &rii->tn_root); in jffs2_add_tn_to_tree()
361 if (this->fn->ofs + this->fn->size > tn->fn->ofs) { in jffs2_add_tn_to_tree()
362 dbg_readinode("Node is overlapped by %p (v %d, 0x%x-0x%x)\n", in jffs2_add_tn_to_tree()
363 this, this->version, this->fn->ofs, in jffs2_add_tn_to_tree()
364 this->fn->ofs+this->fn->size); in jffs2_add_tn_to_tree()
365 tn->overlapped = 1; in jffs2_add_tn_to_tree()
368 if (!this->overlapped) in jffs2_add_tn_to_tree()
374 * We killed a node which set the overlapped in jffs2_add_tn_to_tree()
377 this->overlapped = 0; in jffs2_add_tn_to_tree()
384 /* If the new node overlaps anything ahead, note it */ in jffs2_add_tn_to_tree()
386 while (this && this->fn->ofs < fn_end) { in jffs2_add_tn_to_tree()
387 this->overlapped = 1; in jffs2_add_tn_to_tree()
388 dbg_readinode("Node ver %d, 0x%x-0x%x is overlapped\n", in jffs2_add_tn_to_tree()
389 this->version, this->fn->ofs, in jffs2_add_tn_to_tree()
390 this->fn->ofs+this->fn->size); in jffs2_add_tn_to_tree()
396 /* Trivial function to remove the last node in the tree. Which by definition
397 has no right-hand child — so can be removed just by making its left-hand
402 static void eat_last(struct rb_root *root, struct rb_node *node) in eat_last() argument
404 struct rb_node *parent = rb_parent(node); in eat_last()
408 BUG_ON(node->rb_right); in eat_last()
411 link = &root->rb_node; in eat_last()
412 else if (node == parent->rb_left) in eat_last()
413 link = &parent->rb_left; in eat_last()
415 link = &parent->rb_right; in eat_last()
417 *link = node->rb_left; in eat_last()
418 if (node->rb_left) in eat_last()
419 node->rb_left->__rb_parent_color = node->__rb_parent_color; in eat_last()
422 /* We put the version tree in reverse order, so we can use the same eat_last()
426 struct rb_node **link = &ver_root->rb_node; in ver_insert()
434 if (tn->version > this_tn->version) in ver_insert()
435 link = &parent->rb_left; in ver_insert()
437 link = &parent->rb_right; in ver_insert()
439 dbg_readinode("Link new node at %p (root is %p)\n", link, ver_root); in ver_insert()
440 rb_link_node(&tn->rb, parent, link); in ver_insert()
441 rb_insert_color(&tn->rb, ver_root); in ver_insert()
448 the end, we can use the overlap markers -- we can just eat nodes which
450 sort them all into a temporary tree in version order before replaying them. */
459 if (rii->mdata_tn) { in jffs2_build_inode_fragtree()
460 dbg_readinode("potential mdata is ver %d at %p\n", rii->mdata_tn->version, rii->mdata_tn); in jffs2_build_inode_fragtree()
461 high_ver = rii->mdata_tn->version; in jffs2_build_inode_fragtree()
462 rii->latest_ref = rii->mdata_tn->fn->raw; in jffs2_build_inode_fragtree()
465 this = tn_last(&rii->tn_root); in jffs2_build_inode_fragtree()
467 dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs, in jffs2_build_inode_fragtree()
468 this->fn->ofs+this->fn->size, this->overlapped); in jffs2_build_inode_fragtree()
472 pen = tn_last(&rii->tn_root); in jffs2_build_inode_fragtree()
476 eat_last(&rii->tn_root, &last->rb); in jffs2_build_inode_fragtree()
479 if (unlikely(last->overlapped)) { in jffs2_build_inode_fragtree()
483 * We killed a node which set the overlapped in jffs2_build_inode_fragtree()
486 last->overlapped = 0; in jffs2_build_inode_fragtree()
489 /* Now we have a bunch of nodes in reverse version in jffs2_build_inode_fragtree()
491 there'll actually be only one node in the 'tree', in jffs2_build_inode_fragtree()
499 eat_last(&ver_root, &this->rb); in jffs2_build_inode_fragtree()
501 dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n", in jffs2_build_inode_fragtree()
502 this->version, this->fn->ofs, in jffs2_build_inode_fragtree()
503 this->fn->ofs+this->fn->size); in jffs2_build_inode_fragtree()
506 if (this->version > high_ver) { in jffs2_build_inode_fragtree()
511 high_ver = this->version; in jffs2_build_inode_fragtree()
512 rii->latest_ref = this->fn->raw; in jffs2_build_inode_fragtree()
514 dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n", in jffs2_build_inode_fragtree()
515 this, this->version, this->fn->ofs, in jffs2_build_inode_fragtree()
516 this->fn->ofs+this->fn->size, this->overlapped); in jffs2_build_inode_fragtree()
518 ret = jffs2_add_full_dnode_to_inode(c, f, this->fn); in jffs2_build_inode_fragtree()
522 JFFS2_ERROR("Add node to tree failed %d\n", ret); in jffs2_build_inode_fragtree()
526 jffs2_mark_node_obsolete(c, this->fn->raw); in jffs2_build_inode_fragtree()
527 jffs2_free_full_dnode(this->fn); in jffs2_build_inode_fragtree()
532 eat_last(&ver_root, &vers_next->rb); in jffs2_build_inode_fragtree()
549 jffs2_free_full_dnode(tn->fn); in jffs2_free_tmp_dnode_info_list()
561 next = fd->next; in jffs2_free_full_dirent_list()
567 /* Returns first valid node after 'ref'. May return 'ref' */
570 while (ref && ref->next_in_ino) { in jffs2_first_valid_node()
573 dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)); in jffs2_first_valid_node()
574 ref = ref->next_in_ino; in jffs2_first_valid_node()
581 * It is called every time an directory entry node is found.
596 crc = crc32(0, rd, sizeof(*rd) - 8); in read_direntry()
597 if (unlikely(crc != je32_to_cpu(rd->node_crc))) { in read_direntry()
598 JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", in read_direntry()
599 ref_offset(ref), je32_to_cpu(rd->node_crc), crc); in read_direntry()
604 /* If we've never checked the CRCs on this node, check them now */ in read_direntry()
610 if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { in read_direntry()
611 JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", in read_direntry()
612 ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); in read_direntry()
617 jeb = &c->blocks[ref->flash_offset / c->sector_size]; in read_direntry()
620 spin_lock(&c->erase_completion_lock); in read_direntry()
621 jeb->used_size += len; in read_direntry()
622 jeb->unchecked_size -= len; in read_direntry()
623 c->used_size += len; in read_direntry()
624 c->unchecked_size -= len; in read_direntry()
625 ref->flash_offset = ref_offset(ref) | dirent_node_state(rd); in read_direntry()
626 spin_unlock(&c->erase_completion_lock); in read_direntry()
629 fd = jffs2_alloc_full_dirent(rd->nsize + 1); in read_direntry()
631 return -ENOMEM; in read_direntry()
633 fd->raw = ref; in read_direntry()
634 fd->version = je32_to_cpu(rd->version); in read_direntry()
635 fd->ino = je32_to_cpu(rd->ino); in read_direntry()
636 fd->type = rd->type; in read_direntry()
638 if (fd->version > rii->highest_version) in read_direntry()
639 rii->highest_version = fd->version; in read_direntry()
642 if(fd->version > rii->mctime_ver && je32_to_cpu(rd->mctime)) { in read_direntry()
643 rii->mctime_ver = fd->version; in read_direntry()
644 rii->latest_mctime = je32_to_cpu(rd->mctime); in read_direntry()
652 memcpy(&fd->name[0], &rd->name[0], in read_direntry()
653 min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); in read_direntry()
656 if (rd->nsize + sizeof(*rd) > read) { in read_direntry()
659 int already = read - sizeof(*rd); in read_direntry()
662 rd->nsize - already, &read, &fd->name[already]); in read_direntry()
663 if (unlikely(read != rd->nsize - already) && likely(!err)) { in read_direntry()
666 rd->nsize - already, read); in read_direntry()
667 return -EIO; in read_direntry()
673 return -EIO; in read_direntry()
681 crc = crc32(0, fd->name, rd->nsize); in read_direntry()
682 if (unlikely(crc != je32_to_cpu(rd->name_crc))) { in read_direntry()
683 JFFS2_NOTICE("name CRC failed on dirent node at" in read_direntry()
685 ref_offset(ref), je32_to_cpu(rd->node_crc), crc); in read_direntry()
693 fd->nhash = full_name_hash(NULL, fd->name, rd->nsize); in read_direntry()
694 fd->next = NULL; in read_direntry()
695 fd->name[rd->nsize] = '\0'; in read_direntry()
701 jffs2_add_fd_to_list(c, fd, &rii->fds); in read_direntry()
708 * It is called every time an inode node is found.
710 * Returns: 0 on success (possibly after marking a bad node obsolete);
725 crc = crc32(0, rd, sizeof(*rd) - 8); in read_dnode()
726 if (unlikely(crc != je32_to_cpu(rd->node_crc))) { in read_dnode()
727 JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", in read_dnode()
728 ref_offset(ref), je32_to_cpu(rd->node_crc), crc); in read_dnode()
736 return -ENOMEM; in read_dnode()
739 tn->partial_crc = 0; in read_dnode()
740 csize = je32_to_cpu(rd->csize); in read_dnode()
742 /* If we've never checked the CRCs on this node, check them now */ in read_dnode()
746 if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || in read_dnode()
747 unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { in read_dnode()
748 JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); in read_dnode()
756 * of our unchecked node. But thus far, we do not in read_dnode()
757 * know whether the node is valid or obsolete. To in read_dnode()
766 * having the highest version number, so we'll be able in read_dnode()
767 * to detect whether a node is valid (i.e., it is not in read_dnode()
768 * overlapped by a node with higher version) or not. in read_dnode()
779 * fractions of c->wbuf_pagesize, and we have just read in read_dnode()
780 * the node header, it is likely that the starting part in read_dnode()
781 * of the node data is also read when we read the in read_dnode()
783 * starting part of the data of the node now, and check in read_dnode()
785 * Of course, we will not need to re-read and re-check in read_dnode()
788 * while we needed only the node header. in read_dnode()
795 len = min_t(uint32_t, rdlen - sizeof(*rd), csize); in read_dnode()
796 tn->partial_crc = crc32(0, buf, len); in read_dnode()
798 dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize); in read_dnode()
801 * and it is wrong, drop the node. */ in read_dnode()
802 if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { in read_dnode()
803 JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", in read_dnode()
804 ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); in read_dnode()
811 * We checked the header CRC. If the node has no data, adjust in read_dnode()
813 * later either when the node is marked obsolete or when its in read_dnode()
818 dbg_readinode("the node has no data.\n"); in read_dnode()
819 jeb = &c->blocks[ref->flash_offset / c->sector_size]; in read_dnode()
822 spin_lock(&c->erase_completion_lock); in read_dnode()
823 jeb->used_size += len; in read_dnode()
824 jeb->unchecked_size -= len; in read_dnode()
825 c->used_size += len; in read_dnode()
826 c->unchecked_size -= len; in read_dnode()
827 ref->flash_offset = ref_offset(ref) | REF_NORMAL; in read_dnode()
828 spin_unlock(&c->erase_completion_lock); in read_dnode()
832 tn->fn = jffs2_alloc_full_dnode(); in read_dnode()
833 if (!tn->fn) { in read_dnode()
835 ret = -ENOMEM; in read_dnode()
839 tn->version = je32_to_cpu(rd->version); in read_dnode()
840 tn->fn->ofs = je32_to_cpu(rd->offset); in read_dnode()
841 tn->data_crc = je32_to_cpu(rd->data_crc); in read_dnode()
842 tn->csize = csize; in read_dnode()
843 tn->fn->raw = ref; in read_dnode()
844 tn->overlapped = 0; in read_dnode()
846 if (tn->version > rii->highest_version) in read_dnode()
847 rii->highest_version = tn->version; in read_dnode()
851 if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize) in read_dnode()
852 tn->fn->size = csize; in read_dnode()
854 tn->fn->size = je32_to_cpu(rd->dsize); in read_dnode()
857 ref_offset(ref), je32_to_cpu(rd->version), in read_dnode()
858 je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); in read_dnode()
863 jffs2_free_full_dnode(tn->fn); in read_dnode()
869 dbg_readinode2("After adding ver %d:\n", je32_to_cpu(rd->version)); in read_dnode()
870 tn = tn_first(&rii->tn_root); in read_dnode()
872 dbg_readinode2("%p: v %d r 0x%x-0x%x ov %d\n", in read_dnode()
873 tn, tn->version, tn->fn->ofs, in read_dnode()
874 tn->fn->ofs+tn->fn->size, tn->overlapped); in read_dnode()
883 * It is called every time an unknown node is found.
892 JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", in read_unknown()
894 JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", in read_unknown()
895 je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), in read_unknown()
896 je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); in read_unknown()
901 un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); in read_unknown()
903 switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) { in read_unknown()
907 je16_to_cpu(un->nodetype), ref_offset(ref)); in read_unknown()
914 je16_to_cpu(un->nodetype), ref_offset(ref)); in read_unknown()
915 BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); in read_unknown()
920 je16_to_cpu(un->nodetype), ref_offset(ref)); in read_unknown()
925 je16_to_cpu(un->nodetype), ref_offset(ref)); in read_unknown()
943 int err, to_read = needed_len - *rdlen; in read_more()
948 int rem = to_read % c->wbuf_pagesize; in read_more()
951 to_read += c->wbuf_pagesize - rem; in read_more()
969 return -EIO; in read_more()
976 /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
979 use to take of just returning them _all_ in version order will cause us to
986 union jffs2_node_union *node; in jffs2_get_inode_nodes() local
990 rii->mctime_ver = 0; in jffs2_get_inode_nodes()
992 dbg_readinode("ino #%u\n", f->inocache->ino); in jffs2_get_inode_nodes()
994 /* FIXME: in case of NOR and available ->point() this in jffs2_get_inode_nodes()
996 len = sizeof(union jffs2_node_union) + c->wbuf_pagesize; in jffs2_get_inode_nodes()
999 return -ENOMEM; in jffs2_get_inode_nodes()
1001 spin_lock(&c->erase_completion_lock); in jffs2_get_inode_nodes()
1002 valid_ref = jffs2_first_valid_node(f->inocache->nodes); in jffs2_get_inode_nodes()
1003 if (!valid_ref && f->inocache->ino != 1) in jffs2_get_inode_nodes()
1004 JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); in jffs2_get_inode_nodes()
1006 /* We can hold a pointer to a non-obsolete node without the spinlock, in jffs2_get_inode_nodes()
1010 we find the next valid node first, before processing 'ref'. in jffs2_get_inode_nodes()
1013 valid_ref = jffs2_first_valid_node(ref->next_in_ino); in jffs2_get_inode_nodes()
1014 spin_unlock(&c->erase_completion_lock); in jffs2_get_inode_nodes()
1019 * At this point we don't know the type of the node we're going in jffs2_get_inode_nodes()
1033 * re-read the same min. I/O unit twice. in jffs2_get_inode_nodes()
1036 rem = end % c->wbuf_pagesize; in jffs2_get_inode_nodes()
1038 end += c->wbuf_pagesize - rem; in jffs2_get_inode_nodes()
1039 len = end - ref_offset(ref); in jffs2_get_inode_nodes()
1053 err = -EIO; in jffs2_get_inode_nodes()
1057 node = (union jffs2_node_union *)buf; in jffs2_get_inode_nodes()
1060 if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { in jffs2_get_inode_nodes()
1061 JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n", in jffs2_get_inode_nodes()
1062 ref_offset(ref), je16_to_cpu(node->u.magic), in jffs2_get_inode_nodes()
1063 je16_to_cpu(node->u.nodetype), in jffs2_get_inode_nodes()
1064 je32_to_cpu(node->u.totlen), in jffs2_get_inode_nodes()
1065 je32_to_cpu(node->u.hdr_crc)); in jffs2_get_inode_nodes()
1070 if (je16_to_cpu(node->u.magic) != JFFS2_MAGIC_BITMASK) { in jffs2_get_inode_nodes()
1071 /* Not a JFFS2 node, whinge and move on */ in jffs2_get_inode_nodes()
1072 JFFS2_NOTICE("Wrong magic bitmask 0x%04x in node header at %#08x.\n", in jffs2_get_inode_nodes()
1073 je16_to_cpu(node->u.magic), ref_offset(ref)); in jffs2_get_inode_nodes()
1078 switch (je16_to_cpu(node->u.nodetype)) { in jffs2_get_inode_nodes()
1089 err = read_direntry(c, ref, &node->d, retlen, rii); in jffs2_get_inode_nodes()
1104 err = read_dnode(c, ref, &node->i, len, rii); in jffs2_get_inode_nodes()
1118 err = read_unknown(c, ref, &node->u); in jffs2_get_inode_nodes()
1124 spin_lock(&c->erase_completion_lock); in jffs2_get_inode_nodes()
1127 spin_unlock(&c->erase_completion_lock); in jffs2_get_inode_nodes()
1130 f->highest_version = rii->highest_version; in jffs2_get_inode_nodes()
1132 …dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_v… in jffs2_get_inode_nodes()
1133 f->inocache->ino, rii->highest_version, rii->latest_mctime, in jffs2_get_inode_nodes()
1134 rii->mctime_ver); in jffs2_get_inode_nodes()
1138 jffs2_free_tmp_dnode_info_list(&rii->tn_root); in jffs2_get_inode_nodes()
1139 jffs2_free_full_dirent_list(rii->fds); in jffs2_get_inode_nodes()
1140 rii->fds = NULL; in jffs2_get_inode_nodes()
1154 dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino, in jffs2_do_read_inode_internal()
1155 f->inocache->pino_nlink); in jffs2_do_read_inode_internal()
1163 JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); in jffs2_do_read_inode_internal()
1164 if (f->inocache->state == INO_STATE_READING) in jffs2_do_read_inode_internal()
1165 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); in jffs2_do_read_inode_internal()
1172 f->inocache->ino, ret); in jffs2_do_read_inode_internal()
1173 if (f->inocache->state == INO_STATE_READING) in jffs2_do_read_inode_internal()
1174 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); in jffs2_do_read_inode_internal()
1176 /* FIXME: We could at least crc-check them all */ in jffs2_do_read_inode_internal()
1178 jffs2_free_full_dnode(rii.mdata_tn->fn); in jffs2_do_read_inode_internal()
1186 if (rii.mdata_tn->fn->raw == rii.latest_ref) { in jffs2_do_read_inode_internal()
1187 f->metadata = rii.mdata_tn->fn; in jffs2_do_read_inode_internal()
1195 f->dents = rii.fds; in jffs2_do_read_inode_internal()
1201 if (f->inocache->ino != 1) { in jffs2_do_read_inode_internal()
1202 JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); in jffs2_do_read_inode_internal()
1204 if (f->inocache->state == INO_STATE_READING) in jffs2_do_read_inode_internal()
1205 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); in jffs2_do_read_inode_internal()
1206 return -EIO; in jffs2_do_read_inode_internal()
1210 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); in jffs2_do_read_inode_internal()
1211 latest_node->version = cpu_to_je32(0); in jffs2_do_read_inode_internal()
1212 latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); in jffs2_do_read_inode_internal()
1213 latest_node->isize = cpu_to_je32(0); in jffs2_do_read_inode_internal()
1214 latest_node->gid = cpu_to_je16(0); in jffs2_do_read_inode_internal()
1215 latest_node->uid = cpu_to_je16(0); in jffs2_do_read_inode_internal()
1216 if (f->inocache->state == INO_STATE_READING) in jffs2_do_read_inode_internal()
1217 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); in jffs2_do_read_inode_internal()
1226 return ret ? ret : -EIO; in jffs2_do_read_inode_internal()
1229 crc = crc32(0, latest_node, sizeof(*latest_node)-8); in jffs2_do_read_inode_internal()
1230 if (crc != je32_to_cpu(latest_node->node_crc)) { in jffs2_do_read_inode_internal()
1232 f->inocache->ino, ref_offset(rii.latest_ref)); in jffs2_do_read_inode_internal()
1233 return -EIO; in jffs2_do_read_inode_internal()
1236 switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { in jffs2_do_read_inode_internal()
1238 if (rii.mctime_ver > je32_to_cpu(latest_node->version)) { in jffs2_do_read_inode_internal()
1241 latest_node->ctime = latest_node->mtime = cpu_to_je32(rii.latest_mctime); in jffs2_do_read_inode_internal()
1247 /* If it was a regular file, truncate it to the latest node's isize */ in jffs2_do_read_inode_internal()
1248 new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); in jffs2_do_read_inode_internal()
1249 if (new_size != je32_to_cpu(latest_node->isize)) { in jffs2_do_read_inode_internal()
1251 f->inocache->ino, je32_to_cpu(latest_node->isize), new_size); in jffs2_do_read_inode_internal()
1252 latest_node->isize = cpu_to_je32(new_size); in jffs2_do_read_inode_internal()
1261 if (!je32_to_cpu(latest_node->isize)) in jffs2_do_read_inode_internal()
1262 latest_node->isize = latest_node->dsize; in jffs2_do_read_inode_internal()
1264 if (f->inocache->state != INO_STATE_CHECKING) { in jffs2_do_read_inode_internal()
1268 uint32_t csize = je32_to_cpu(latest_node->csize); in jffs2_do_read_inode_internal()
1270 return -ENAMETOOLONG; in jffs2_do_read_inode_internal()
1271 f->target = kmalloc(csize + 1, GFP_KERNEL); in jffs2_do_read_inode_internal()
1272 if (!f->target) { in jffs2_do_read_inode_internal()
1274 return -ENOMEM; in jffs2_do_read_inode_internal()
1278 csize, &retlen, (char *)f->target); in jffs2_do_read_inode_internal()
1282 ret = -EIO; in jffs2_do_read_inode_internal()
1283 kfree(f->target); in jffs2_do_read_inode_internal()
1284 f->target = NULL; in jffs2_do_read_inode_internal()
1288 f->target[csize] = '\0'; in jffs2_do_read_inode_internal()
1289 dbg_readinode("symlink's target '%s' cached\n", f->target); in jffs2_do_read_inode_internal()
1296 /* Certain inode types should have only one data node, and it's in jffs2_do_read_inode_internal()
1297 kept as the metadata node */ in jffs2_do_read_inode_internal()
1298 if (f->metadata) { in jffs2_do_read_inode_internal()
1299 JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n", in jffs2_do_read_inode_internal()
1300 f->inocache->ino, jemode_to_cpu(latest_node->mode)); in jffs2_do_read_inode_internal()
1301 return -EIO; in jffs2_do_read_inode_internal()
1303 if (!frag_first(&f->fragtree)) { in jffs2_do_read_inode_internal()
1305 f->inocache->ino, jemode_to_cpu(latest_node->mode)); in jffs2_do_read_inode_internal()
1306 return -EIO; in jffs2_do_read_inode_internal()
1308 /* ASSERT: f->fraglist != NULL */ in jffs2_do_read_inode_internal()
1309 if (frag_next(frag_first(&f->fragtree))) { in jffs2_do_read_inode_internal()
1310 JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n", in jffs2_do_read_inode_internal()
1311 f->inocache->ino, jemode_to_cpu(latest_node->mode)); in jffs2_do_read_inode_internal()
1312 …/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older … in jffs2_do_read_inode_internal()
1313 return -EIO; in jffs2_do_read_inode_internal()
1316 f->metadata = frag_first(&f->fragtree)->node; in jffs2_do_read_inode_internal()
1317 jffs2_free_node_frag(frag_first(&f->fragtree)); in jffs2_do_read_inode_internal()
1318 f->fragtree = RB_ROOT; in jffs2_do_read_inode_internal()
1321 if (f->inocache->state == INO_STATE_READING) in jffs2_do_read_inode_internal()
1322 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); in jffs2_do_read_inode_internal()
1334 spin_lock(&c->inocache_lock); in jffs2_do_read_inode()
1335 f->inocache = jffs2_get_ino_cache(c, ino); in jffs2_do_read_inode()
1337 if (f->inocache) { in jffs2_do_read_inode()
1339 switch(f->inocache->state) { in jffs2_do_read_inode()
1342 f->inocache->state = INO_STATE_READING; in jffs2_do_read_inode()
1350 dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state); in jffs2_do_read_inode()
1351 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); in jffs2_do_read_inode()
1359 …JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->st… in jffs2_do_read_inode()
1361 f->inocache = NULL; in jffs2_do_read_inode()
1368 spin_unlock(&c->inocache_lock); in jffs2_do_read_inode()
1370 if (!f->inocache && ino == 1) { in jffs2_do_read_inode()
1371 /* Special case - no root inode on medium */ in jffs2_do_read_inode()
1372 f->inocache = jffs2_alloc_inode_cache(); in jffs2_do_read_inode()
1373 if (!f->inocache) { in jffs2_do_read_inode()
1375 return -ENOMEM; in jffs2_do_read_inode()
1378 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); in jffs2_do_read_inode()
1379 f->inocache->ino = f->inocache->pino_nlink = 1; in jffs2_do_read_inode()
1380 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; in jffs2_do_read_inode()
1381 f->inocache->state = INO_STATE_READING; in jffs2_do_read_inode()
1382 jffs2_add_ino_cache(c, f->inocache); in jffs2_do_read_inode()
1384 if (!f->inocache) { in jffs2_do_read_inode()
1386 return -ENOENT; in jffs2_do_read_inode()
1399 return -ENOMEM; in jffs2_do_crccheck_inode()
1401 mutex_init(&f->sem); in jffs2_do_crccheck_inode()
1402 mutex_lock(&f->sem); in jffs2_do_crccheck_inode()
1403 f->inocache = ic; in jffs2_do_crccheck_inode()
1406 mutex_unlock(&f->sem); in jffs2_do_crccheck_inode()
1418 jffs2_xattr_delete_inode(c, f->inocache); in jffs2_do_clear_inode()
1419 mutex_lock(&f->sem); in jffs2_do_clear_inode()
1420 deleted = f->inocache && !f->inocache->pino_nlink; in jffs2_do_clear_inode()
1422 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) in jffs2_do_clear_inode()
1423 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); in jffs2_do_clear_inode()
1425 if (f->metadata) { in jffs2_do_clear_inode()
1427 jffs2_mark_node_obsolete(c, f->metadata->raw); in jffs2_do_clear_inode()
1428 jffs2_free_full_dnode(f->metadata); in jffs2_do_clear_inode()
1431 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); in jffs2_do_clear_inode()
1433 fds = f->dents; in jffs2_do_clear_inode()
1436 fds = fd->next; in jffs2_do_clear_inode()
1440 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { in jffs2_do_clear_inode()
1441 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); in jffs2_do_clear_inode()
1442 if (f->inocache->nodes == (void *)f->inocache) in jffs2_do_clear_inode()
1443 jffs2_del_ino_cache(c, f->inocache); in jffs2_do_clear_inode()
1446 mutex_unlock(&f->sem); in jffs2_do_clear_inode()