11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * JFFS2 -- Journalling Flash File System, Version 2. 31da177e4SLinus Torvalds * 4c00c310eSDavid Woodhouse * Copyright © 2001-2007 Red Hat, Inc. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Created by David Woodhouse <dwmw2@infradead.org> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * For licensing information, see the file 'LICENCE' in this directory. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds */ 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <linux/kernel.h> 13737b7661SAndrew Lunn #include <linux/sched.h> 141da177e4SLinus Torvalds #include <linux/slab.h> 151da177e4SLinus Torvalds #include <linux/fs.h> 161da177e4SLinus Torvalds #include <linux/crc32.h> 171da177e4SLinus Torvalds #include <linux/pagemap.h> 181da177e4SLinus Torvalds #include <linux/mtd/mtd.h> 191da177e4SLinus Torvalds #include <linux/compiler.h> 201da177e4SLinus Torvalds #include "nodelist.h" 211da177e4SLinus Torvalds 22f97117d1SArtem B. Bityutskiy /* 23df8e96f3SDavid Woodhouse * Check the data CRC of the node. 24df8e96f3SDavid Woodhouse * 25df8e96f3SDavid Woodhouse * Returns: 0 if the data CRC is correct; 26df8e96f3SDavid Woodhouse * 1 - if incorrect; 27df8e96f3SDavid Woodhouse * error code if an error occured. 28f97117d1SArtem B. Bityutskiy */ 29df8e96f3SDavid Woodhouse static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 301da177e4SLinus Torvalds { 31df8e96f3SDavid Woodhouse struct jffs2_raw_node_ref *ref = tn->fn->raw; 32df8e96f3SDavid Woodhouse int err = 0, pointed = 0; 33df8e96f3SDavid Woodhouse struct jffs2_eraseblock *jeb; 34df8e96f3SDavid Woodhouse unsigned char *buffer; 35df8e96f3SDavid Woodhouse uint32_t crc, ofs, len; 36df8e96f3SDavid Woodhouse size_t retlen; 371da177e4SLinus Torvalds 38df8e96f3SDavid Woodhouse BUG_ON(tn->csize == 0); 391da177e4SLinus Torvalds 40df8e96f3SDavid Woodhouse if (!jffs2_is_writebuffered(c)) 41df8e96f3SDavid Woodhouse goto adj_acc; 42df8e96f3SDavid Woodhouse 43df8e96f3SDavid Woodhouse /* Calculate how many bytes were already checked */ 44df8e96f3SDavid Woodhouse ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); 45df8e96f3SDavid Woodhouse len = ofs % c->wbuf_pagesize; 46df8e96f3SDavid Woodhouse if (likely(len)) 47df8e96f3SDavid Woodhouse len = c->wbuf_pagesize - len; 48df8e96f3SDavid Woodhouse 49df8e96f3SDavid Woodhouse if (len >= tn->csize) { 50df8e96f3SDavid Woodhouse dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", 51df8e96f3SDavid Woodhouse ref_offset(ref), tn->csize, ofs); 52df8e96f3SDavid Woodhouse goto adj_acc; 53f97117d1SArtem B. Bityutskiy } 541da177e4SLinus Torvalds 55df8e96f3SDavid Woodhouse ofs += len; 56df8e96f3SDavid Woodhouse len = tn->csize - len; 57df8e96f3SDavid Woodhouse 58df8e96f3SDavid Woodhouse dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", 59df8e96f3SDavid Woodhouse ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); 60df8e96f3SDavid Woodhouse 61df8e96f3SDavid Woodhouse #ifndef __ECOS 62df8e96f3SDavid Woodhouse /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), 63df8e96f3SDavid Woodhouse * adding and jffs2_flash_read_end() interface. */ 64df8e96f3SDavid Woodhouse if (c->mtd->point) { 65df8e96f3SDavid Woodhouse err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); 66df8e96f3SDavid Woodhouse if (!err && retlen < tn->csize) { 67df8e96f3SDavid Woodhouse JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); 68df8e96f3SDavid Woodhouse c->mtd->unpoint(c->mtd, buffer, ofs, len); 69df8e96f3SDavid Woodhouse } else if (err) 70df8e96f3SDavid Woodhouse JFFS2_WARNING("MTD point failed: error code %d.\n", err); 71df8e96f3SDavid Woodhouse else 72df8e96f3SDavid Woodhouse pointed = 1; /* succefully pointed to device */ 73df8e96f3SDavid Woodhouse } 74df8e96f3SDavid Woodhouse #endif 75df8e96f3SDavid Woodhouse 76df8e96f3SDavid Woodhouse if (!pointed) { 77df8e96f3SDavid Woodhouse buffer = kmalloc(len, GFP_KERNEL); 78df8e96f3SDavid Woodhouse if (unlikely(!buffer)) 79df8e96f3SDavid Woodhouse return -ENOMEM; 80df8e96f3SDavid Woodhouse 81df8e96f3SDavid Woodhouse /* TODO: this is very frequent pattern, make it a separate 82df8e96f3SDavid Woodhouse * routine */ 83df8e96f3SDavid Woodhouse err = jffs2_flash_read(c, ofs, len, &retlen, buffer); 84df8e96f3SDavid Woodhouse if (err) { 85df8e96f3SDavid Woodhouse JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); 86df8e96f3SDavid Woodhouse goto free_out; 87df8e96f3SDavid Woodhouse } 88df8e96f3SDavid Woodhouse 89df8e96f3SDavid Woodhouse if (retlen != len) { 90df8e96f3SDavid Woodhouse JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); 91df8e96f3SDavid Woodhouse err = -EIO; 92df8e96f3SDavid Woodhouse goto free_out; 93df8e96f3SDavid Woodhouse } 94df8e96f3SDavid Woodhouse } 95df8e96f3SDavid Woodhouse 96df8e96f3SDavid Woodhouse /* Continue calculating CRC */ 97df8e96f3SDavid Woodhouse crc = crc32(tn->partial_crc, buffer, len); 98df8e96f3SDavid Woodhouse if(!pointed) 99df8e96f3SDavid Woodhouse kfree(buffer); 100df8e96f3SDavid Woodhouse #ifndef __ECOS 101df8e96f3SDavid Woodhouse else 102df8e96f3SDavid Woodhouse c->mtd->unpoint(c->mtd, buffer, ofs, len); 103df8e96f3SDavid Woodhouse #endif 104df8e96f3SDavid Woodhouse 105df8e96f3SDavid Woodhouse if (crc != tn->data_crc) { 106df8e96f3SDavid Woodhouse JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 107df8e96f3SDavid Woodhouse ofs, tn->data_crc, crc); 108df8e96f3SDavid Woodhouse return 1; 109df8e96f3SDavid Woodhouse } 110df8e96f3SDavid Woodhouse 111df8e96f3SDavid Woodhouse adj_acc: 112df8e96f3SDavid Woodhouse jeb = &c->blocks[ref->flash_offset / c->sector_size]; 113df8e96f3SDavid Woodhouse len = ref_totlen(c, jeb, ref); 114df8e96f3SDavid Woodhouse /* If it should be REF_NORMAL, it'll get marked as such when 115df8e96f3SDavid Woodhouse we build the fragtree, shortly. No need to worry about GC 116df8e96f3SDavid Woodhouse moving it while it's marked REF_PRISTINE -- GC won't happen 117df8e96f3SDavid Woodhouse till we've finished checking every inode anyway. */ 118df8e96f3SDavid Woodhouse ref->flash_offset |= REF_PRISTINE; 119df8e96f3SDavid Woodhouse /* 120df8e96f3SDavid Woodhouse * Mark the node as having been checked and fix the 121df8e96f3SDavid Woodhouse * accounting accordingly. 122df8e96f3SDavid Woodhouse */ 123df8e96f3SDavid Woodhouse spin_lock(&c->erase_completion_lock); 124df8e96f3SDavid Woodhouse jeb->used_size += len; 125df8e96f3SDavid Woodhouse jeb->unchecked_size -= len; 126df8e96f3SDavid Woodhouse c->used_size += len; 127df8e96f3SDavid Woodhouse c->unchecked_size -= len; 128df8e96f3SDavid Woodhouse jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 129df8e96f3SDavid Woodhouse spin_unlock(&c->erase_completion_lock); 130df8e96f3SDavid Woodhouse 131df8e96f3SDavid Woodhouse return 0; 132df8e96f3SDavid Woodhouse 133df8e96f3SDavid Woodhouse free_out: 134df8e96f3SDavid Woodhouse if(!pointed) 135df8e96f3SDavid Woodhouse kfree(buffer); 136df8e96f3SDavid Woodhouse #ifndef __ECOS 137df8e96f3SDavid Woodhouse else 138df8e96f3SDavid Woodhouse c->mtd->unpoint(c->mtd, buffer, ofs, len); 139df8e96f3SDavid Woodhouse #endif 140df8e96f3SDavid Woodhouse return err; 141df8e96f3SDavid Woodhouse } 142df8e96f3SDavid Woodhouse 143df8e96f3SDavid Woodhouse /* 144df8e96f3SDavid Woodhouse * Helper function for jffs2_add_older_frag_to_fragtree(). 145df8e96f3SDavid Woodhouse * 146df8e96f3SDavid Woodhouse * Checks the node if we are in the checking stage. 147df8e96f3SDavid Woodhouse */ 148df8e96f3SDavid Woodhouse static int check_tn_node(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 149df8e96f3SDavid Woodhouse { 150df8e96f3SDavid Woodhouse int ret; 151df8e96f3SDavid Woodhouse 152df8e96f3SDavid Woodhouse BUG_ON(ref_obsolete(tn->fn->raw)); 153df8e96f3SDavid Woodhouse 154df8e96f3SDavid Woodhouse /* We only check the data CRC of unchecked nodes */ 155df8e96f3SDavid Woodhouse if (ref_flags(tn->fn->raw) != REF_UNCHECKED) 156df8e96f3SDavid Woodhouse return 0; 157df8e96f3SDavid Woodhouse 158df8e96f3SDavid Woodhouse dbg_readinode("check node %#04x-%#04x, phys offs %#08x\n", 159df8e96f3SDavid Woodhouse tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw)); 160df8e96f3SDavid Woodhouse 161df8e96f3SDavid Woodhouse ret = check_node_data(c, tn); 162df8e96f3SDavid Woodhouse if (unlikely(ret < 0)) { 163df8e96f3SDavid Woodhouse JFFS2_ERROR("check_node_data() returned error: %d.\n", 164df8e96f3SDavid Woodhouse ret); 165df8e96f3SDavid Woodhouse } else if (unlikely(ret > 0)) { 166df8e96f3SDavid Woodhouse dbg_readinode("CRC error, mark it obsolete.\n"); 167df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, tn->fn->raw); 168df8e96f3SDavid Woodhouse } 169df8e96f3SDavid Woodhouse 170df8e96f3SDavid Woodhouse return ret; 171df8e96f3SDavid Woodhouse } 172df8e96f3SDavid Woodhouse 173df8e96f3SDavid Woodhouse static struct jffs2_tmp_dnode_info *jffs2_lookup_tn(struct rb_root *tn_root, uint32_t offset) 174df8e96f3SDavid Woodhouse { 175df8e96f3SDavid Woodhouse struct rb_node *next; 176df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *tn = NULL; 177df8e96f3SDavid Woodhouse 178df8e96f3SDavid Woodhouse dbg_readinode("root %p, offset %d\n", tn_root, offset); 179df8e96f3SDavid Woodhouse 180df8e96f3SDavid Woodhouse next = tn_root->rb_node; 181df8e96f3SDavid Woodhouse 182df8e96f3SDavid Woodhouse while (next) { 183df8e96f3SDavid Woodhouse tn = rb_entry(next, struct jffs2_tmp_dnode_info, rb); 184df8e96f3SDavid Woodhouse 185df8e96f3SDavid Woodhouse if (tn->fn->ofs < offset) 186df8e96f3SDavid Woodhouse next = tn->rb.rb_right; 187df8e96f3SDavid Woodhouse else if (tn->fn->ofs >= offset) 188df8e96f3SDavid Woodhouse next = tn->rb.rb_left; 189df8e96f3SDavid Woodhouse else 190df8e96f3SDavid Woodhouse break; 191df8e96f3SDavid Woodhouse } 192df8e96f3SDavid Woodhouse 193df8e96f3SDavid Woodhouse return tn; 194df8e96f3SDavid Woodhouse } 195df8e96f3SDavid Woodhouse 196df8e96f3SDavid Woodhouse 197df8e96f3SDavid Woodhouse static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 198df8e96f3SDavid Woodhouse { 199df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, tn->fn->raw); 200df8e96f3SDavid Woodhouse jffs2_free_full_dnode(tn->fn); 201df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(tn); 202df8e96f3SDavid Woodhouse } 203df8e96f3SDavid Woodhouse /* 204df8e96f3SDavid Woodhouse * This function is used when we read an inode. Data nodes arrive in 205df8e96f3SDavid Woodhouse * arbitrary order -- they may be older or newer than the nodes which 206df8e96f3SDavid Woodhouse * are already in the tree. Where overlaps occur, the older node can 207df8e96f3SDavid Woodhouse * be discarded as long as the newer passes the CRC check. We don't 208df8e96f3SDavid Woodhouse * bother to keep track of holes in this rbtree, and neither do we deal 209df8e96f3SDavid Woodhouse * with frags -- we can have multiple entries starting at the same 210df8e96f3SDavid Woodhouse * offset, and the one with the smallest length will come first in the 211df8e96f3SDavid Woodhouse * ordering. 212df8e96f3SDavid Woodhouse * 213df8e96f3SDavid Woodhouse * Returns 0 if the node was inserted 214df8e96f3SDavid Woodhouse * 1 if the node is obsolete (because we can't mark it so yet) 215df8e96f3SDavid Woodhouse * < 0 an if error occurred 216df8e96f3SDavid Woodhouse */ 217df8e96f3SDavid Woodhouse static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, 218df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii, 219df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *tn) 220df8e96f3SDavid Woodhouse { 221df8e96f3SDavid Woodhouse uint32_t fn_end = tn->fn->ofs + tn->fn->size; 22296dd8d25SDavid Woodhouse struct jffs2_tmp_dnode_info *this; 223df8e96f3SDavid Woodhouse 224df8e96f3SDavid Woodhouse dbg_readinode("insert fragment %#04x-%#04x, ver %u\n", tn->fn->ofs, fn_end, tn->version); 225df8e96f3SDavid Woodhouse 226df8e96f3SDavid Woodhouse /* If a node has zero dsize, we only have to keep if it if it might be the 227df8e96f3SDavid Woodhouse node with highest version -- i.e. the one which will end up as f->metadata. 228df8e96f3SDavid Woodhouse Note that such nodes won't be REF_UNCHECKED since there are no data to 229df8e96f3SDavid Woodhouse check anyway. */ 230df8e96f3SDavid Woodhouse if (!tn->fn->size) { 231df8e96f3SDavid Woodhouse if (rii->mdata_tn) { 232df8e96f3SDavid Woodhouse /* We had a candidate mdata node already */ 233df8e96f3SDavid Woodhouse dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version); 234df8e96f3SDavid Woodhouse jffs2_kill_tn(c, rii->mdata_tn); 235df8e96f3SDavid Woodhouse } 236df8e96f3SDavid Woodhouse rii->mdata_tn = tn; 237df8e96f3SDavid Woodhouse dbg_readinode("keep new mdata with ver %d\n", tn->version); 238df8e96f3SDavid Woodhouse return 0; 239df8e96f3SDavid Woodhouse } 240df8e96f3SDavid Woodhouse 241df8e96f3SDavid Woodhouse /* Find the earliest node which _may_ be relevant to this one */ 242df8e96f3SDavid Woodhouse this = jffs2_lookup_tn(&rii->tn_root, tn->fn->ofs); 243df8e96f3SDavid Woodhouse if (!this) { 244df8e96f3SDavid Woodhouse /* First addition to empty tree. $DEITY how I love the easy cases */ 245df8e96f3SDavid Woodhouse rb_link_node(&tn->rb, NULL, &rii->tn_root.rb_node); 246df8e96f3SDavid Woodhouse rb_insert_color(&tn->rb, &rii->tn_root); 247df8e96f3SDavid Woodhouse dbg_readinode("keep new frag\n"); 248df8e96f3SDavid Woodhouse return 0; 249df8e96f3SDavid Woodhouse } 250df8e96f3SDavid Woodhouse 251df8e96f3SDavid Woodhouse /* If the node is coincident with another at a lower address, 252df8e96f3SDavid Woodhouse back up until the other node is found. It may be relevant */ 253df8e96f3SDavid Woodhouse while (tn->overlapped) 254df8e96f3SDavid Woodhouse tn = tn_prev(tn); 255df8e96f3SDavid Woodhouse 256df8e96f3SDavid Woodhouse dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); 257df8e96f3SDavid Woodhouse 258df8e96f3SDavid Woodhouse while (this) { 259df8e96f3SDavid Woodhouse if (this->fn->ofs > fn_end) 260df8e96f3SDavid Woodhouse break; 261df8e96f3SDavid Woodhouse dbg_readinode("Ponder this ver %d, 0x%x-0x%x\n", 262df8e96f3SDavid Woodhouse this->version, this->fn->ofs, this->fn->size); 263df8e96f3SDavid Woodhouse 264df8e96f3SDavid Woodhouse if (this->version == tn->version) { 265df8e96f3SDavid Woodhouse /* Version number collision means REF_PRISTINE GC. Accept either of them 266df8e96f3SDavid Woodhouse as long as the CRC is correct. Check the one we have already... */ 267df8e96f3SDavid Woodhouse if (!check_tn_node(c, this)) { 268df8e96f3SDavid Woodhouse /* The one we already had was OK. Keep it and throw away the new one */ 269df8e96f3SDavid Woodhouse dbg_readinode("Like old node. Throw away new\n"); 270df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 271df8e96f3SDavid Woodhouse return 0; 272df8e96f3SDavid Woodhouse } else { 273df8e96f3SDavid Woodhouse /* Who cares if the new one is good; keep it for now anyway. */ 274df8e96f3SDavid Woodhouse rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 275df8e96f3SDavid Woodhouse /* Same overlapping from in front and behind */ 276df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 277df8e96f3SDavid Woodhouse dbg_readinode("Like new node. Throw away old\n"); 2781123e2a8SDavid Woodhouse goto calc_overlaps; 279df8e96f3SDavid Woodhouse } 280df8e96f3SDavid Woodhouse } 281df8e96f3SDavid Woodhouse if (this->version < tn->version && 282df8e96f3SDavid Woodhouse this->fn->ofs >= tn->fn->ofs && 283df8e96f3SDavid Woodhouse this->fn->ofs + this->fn->size <= fn_end) { 284df8e96f3SDavid Woodhouse /* New node entirely overlaps 'this' */ 285df8e96f3SDavid Woodhouse if (check_tn_node(c, tn)) { 286df8e96f3SDavid Woodhouse dbg_readinode("new node bad CRC\n"); 287df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 288df8e96f3SDavid Woodhouse return 0; 289df8e96f3SDavid Woodhouse } 290df8e96f3SDavid Woodhouse /* ... and is good. Kill 'this'... */ 291df8e96f3SDavid Woodhouse rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 292df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 293df8e96f3SDavid Woodhouse /* ... and any subsequent nodes which are also overlapped */ 294df8e96f3SDavid Woodhouse this = tn_next(tn); 295df8e96f3SDavid Woodhouse while (this && this->fn->ofs + this->fn->size < fn_end) { 296df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *next = tn_next(this); 297df8e96f3SDavid Woodhouse if (this->version < tn->version) { 298df8e96f3SDavid Woodhouse tn_erase(this, &rii->tn_root); 299df8e96f3SDavid Woodhouse dbg_readinode("Kill overlapped ver %d, 0x%x-0x%x\n", 300df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 301df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 302df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 303df8e96f3SDavid Woodhouse } 304df8e96f3SDavid Woodhouse this = next; 305df8e96f3SDavid Woodhouse } 306df8e96f3SDavid Woodhouse dbg_readinode("Done inserting new\n"); 3071123e2a8SDavid Woodhouse goto calc_overlaps; 308df8e96f3SDavid Woodhouse } 309df8e96f3SDavid Woodhouse if (this->version > tn->version && 310df8e96f3SDavid Woodhouse this->fn->ofs <= tn->fn->ofs && 311df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size >= fn_end) { 312df8e96f3SDavid Woodhouse /* New node entirely overlapped by 'this' */ 313df8e96f3SDavid Woodhouse if (!check_tn_node(c, this)) { 314df8e96f3SDavid Woodhouse dbg_readinode("Good CRC on old node. Kill new\n"); 315df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 316df8e96f3SDavid Woodhouse return 0; 317df8e96f3SDavid Woodhouse } 318df8e96f3SDavid Woodhouse /* ... but 'this' was bad. Replace it... */ 3191123e2a8SDavid Woodhouse tn->overlapped = this->overlapped; 320df8e96f3SDavid Woodhouse rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 321df8e96f3SDavid Woodhouse dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); 322df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 323df8e96f3SDavid Woodhouse return 0; 324df8e96f3SDavid Woodhouse } 325df8e96f3SDavid Woodhouse 326df8e96f3SDavid Woodhouse this = tn_next(this); 327df8e96f3SDavid Woodhouse } 32896dd8d25SDavid Woodhouse 329df8e96f3SDavid Woodhouse /* We neither completely obsoleted nor were completely 33096dd8d25SDavid Woodhouse obsoleted by an earlier node. Insert into the tree */ 331df8e96f3SDavid Woodhouse { 33296dd8d25SDavid Woodhouse struct rb_node *parent; 33396dd8d25SDavid Woodhouse struct rb_node **link = &rii->tn_root.rb_node; 33496dd8d25SDavid Woodhouse struct jffs2_tmp_dnode_info *insert_point; 335df8e96f3SDavid Woodhouse 336df8e96f3SDavid Woodhouse while (*link) { 337df8e96f3SDavid Woodhouse parent = *link; 338df8e96f3SDavid Woodhouse insert_point = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 339df8e96f3SDavid Woodhouse if (tn->fn->ofs > insert_point->fn->ofs) 340df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_right; 341df8e96f3SDavid Woodhouse else if (tn->fn->ofs < insert_point->fn->ofs || 342df8e96f3SDavid Woodhouse tn->fn->size < insert_point->fn->size) 343df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_left; 344df8e96f3SDavid Woodhouse else 345df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_right; 346df8e96f3SDavid Woodhouse } 347df8e96f3SDavid Woodhouse rb_link_node(&tn->rb, &insert_point->rb, link); 348df8e96f3SDavid Woodhouse rb_insert_color(&tn->rb, &rii->tn_root); 349df8e96f3SDavid Woodhouse } 3501123e2a8SDavid Woodhouse 3511123e2a8SDavid Woodhouse calc_overlaps: 352df8e96f3SDavid Woodhouse /* If there's anything behind that overlaps us, note it */ 353df8e96f3SDavid Woodhouse this = tn_prev(tn); 354df8e96f3SDavid Woodhouse if (this) { 355df8e96f3SDavid Woodhouse while (1) { 356df8e96f3SDavid Woodhouse if (this->fn->ofs + this->fn->size > tn->fn->ofs) { 357df8e96f3SDavid Woodhouse dbg_readinode("Node is overlapped by %p (v %d, 0x%x-0x%x)\n", 358df8e96f3SDavid Woodhouse this, this->version, this->fn->ofs, 359df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 360df8e96f3SDavid Woodhouse tn->overlapped = 1; 361df8e96f3SDavid Woodhouse break; 362df8e96f3SDavid Woodhouse } 363df8e96f3SDavid Woodhouse if (!this->overlapped) 364df8e96f3SDavid Woodhouse break; 365df8e96f3SDavid Woodhouse this = tn_prev(this); 366df8e96f3SDavid Woodhouse } 367df8e96f3SDavid Woodhouse } 368df8e96f3SDavid Woodhouse 369df8e96f3SDavid Woodhouse /* If the new node overlaps anything ahead, note it */ 370df8e96f3SDavid Woodhouse this = tn_next(tn); 371df8e96f3SDavid Woodhouse while (this && this->fn->ofs < fn_end) { 372df8e96f3SDavid Woodhouse this->overlapped = 1; 373df8e96f3SDavid Woodhouse dbg_readinode("Node ver %d, 0x%x-0x%x is overlapped\n", 374df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 375df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 376df8e96f3SDavid Woodhouse this = tn_next(this); 377df8e96f3SDavid Woodhouse } 378df8e96f3SDavid Woodhouse return 0; 379df8e96f3SDavid Woodhouse } 380df8e96f3SDavid Woodhouse 381df8e96f3SDavid Woodhouse /* Trivial function to remove the last node in the tree. Which by definition 382df8e96f3SDavid Woodhouse has no right-hand -- so can be removed just by making its only child (if 383df8e96f3SDavid Woodhouse any) take its place under its parent. */ 384df8e96f3SDavid Woodhouse static void eat_last(struct rb_root *root, struct rb_node *node) 385df8e96f3SDavid Woodhouse { 386df8e96f3SDavid Woodhouse struct rb_node *parent = rb_parent(node); 387df8e96f3SDavid Woodhouse struct rb_node **link; 388df8e96f3SDavid Woodhouse 389df8e96f3SDavid Woodhouse /* LAST! */ 390df8e96f3SDavid Woodhouse BUG_ON(node->rb_right); 391df8e96f3SDavid Woodhouse 392df8e96f3SDavid Woodhouse if (!parent) 393df8e96f3SDavid Woodhouse link = &root->rb_node; 394df8e96f3SDavid Woodhouse else if (node == parent->rb_left) 395df8e96f3SDavid Woodhouse link = &parent->rb_left; 396df8e96f3SDavid Woodhouse else 397df8e96f3SDavid Woodhouse link = &parent->rb_right; 398df8e96f3SDavid Woodhouse 399df8e96f3SDavid Woodhouse *link = node->rb_left; 400df8e96f3SDavid Woodhouse /* Colour doesn't matter now. Only the parent pointer. */ 401df8e96f3SDavid Woodhouse if (node->rb_left) 402df8e96f3SDavid Woodhouse node->rb_left->rb_parent_color = node->rb_parent_color; 403df8e96f3SDavid Woodhouse } 404df8e96f3SDavid Woodhouse 405df8e96f3SDavid Woodhouse /* We put this in reverse order, so we can just use eat_last */ 406df8e96f3SDavid Woodhouse static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn) 407df8e96f3SDavid Woodhouse { 408df8e96f3SDavid Woodhouse struct rb_node **link = &ver_root->rb_node; 409df8e96f3SDavid Woodhouse struct rb_node *parent = NULL; 410df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *this_tn; 411df8e96f3SDavid Woodhouse 412df8e96f3SDavid Woodhouse while (*link) { 413df8e96f3SDavid Woodhouse parent = *link; 414df8e96f3SDavid Woodhouse this_tn = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 415df8e96f3SDavid Woodhouse 416df8e96f3SDavid Woodhouse if (tn->version > this_tn->version) 417df8e96f3SDavid Woodhouse link = &parent->rb_left; 418df8e96f3SDavid Woodhouse else 419df8e96f3SDavid Woodhouse link = &parent->rb_right; 420df8e96f3SDavid Woodhouse } 421df8e96f3SDavid Woodhouse dbg_readinode("Link new node at %p (root is %p)\n", link, ver_root); 422df8e96f3SDavid Woodhouse rb_link_node(&tn->rb, parent, link); 423df8e96f3SDavid Woodhouse rb_insert_color(&tn->rb, ver_root); 424df8e96f3SDavid Woodhouse } 425df8e96f3SDavid Woodhouse 426df8e96f3SDavid Woodhouse /* Build final, normal fragtree from tn tree. It doesn't matter which order 427df8e96f3SDavid Woodhouse we add nodes to the real fragtree, as long as they don't overlap. And 428df8e96f3SDavid Woodhouse having thrown away the majority of overlapped nodes as we went, there 429df8e96f3SDavid Woodhouse really shouldn't be many sets of nodes which do overlap. If we start at 430df8e96f3SDavid Woodhouse the end, we can use the overlap markers -- we can just eat nodes which 431df8e96f3SDavid Woodhouse aren't overlapped, and when we encounter nodes which _do_ overlap we 432df8e96f3SDavid Woodhouse sort them all into a temporary tree in version order before replaying them. */ 433df8e96f3SDavid Woodhouse static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, 434df8e96f3SDavid Woodhouse struct jffs2_inode_info *f, 435df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 436df8e96f3SDavid Woodhouse { 437df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *pen, *last, *this; 438df8e96f3SDavid Woodhouse struct rb_root ver_root = RB_ROOT; 439df8e96f3SDavid Woodhouse uint32_t high_ver = 0; 440df8e96f3SDavid Woodhouse 441df8e96f3SDavid Woodhouse if (rii->mdata_tn) { 442df8e96f3SDavid Woodhouse dbg_readinode("potential mdata is ver %d at %p\n", rii->mdata_tn->version, rii->mdata_tn); 443df8e96f3SDavid Woodhouse high_ver = rii->mdata_tn->version; 444df8e96f3SDavid Woodhouse rii->latest_ref = rii->mdata_tn->fn->raw; 445df8e96f3SDavid Woodhouse } 446df8e96f3SDavid Woodhouse #ifdef JFFS2_DBG_READINODE_MESSAGES 447df8e96f3SDavid Woodhouse this = tn_last(&rii->tn_root); 448df8e96f3SDavid Woodhouse while (this) { 449df8e96f3SDavid Woodhouse dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs, 450df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size, this->overlapped); 451df8e96f3SDavid Woodhouse this = tn_prev(this); 452df8e96f3SDavid Woodhouse } 453df8e96f3SDavid Woodhouse #endif 454df8e96f3SDavid Woodhouse pen = tn_last(&rii->tn_root); 455df8e96f3SDavid Woodhouse while ((last = pen)) { 456df8e96f3SDavid Woodhouse pen = tn_prev(last); 457df8e96f3SDavid Woodhouse 458df8e96f3SDavid Woodhouse eat_last(&rii->tn_root, &last->rb); 459df8e96f3SDavid Woodhouse ver_insert(&ver_root, last); 460df8e96f3SDavid Woodhouse 461df8e96f3SDavid Woodhouse if (unlikely(last->overlapped)) 462df8e96f3SDavid Woodhouse continue; 463df8e96f3SDavid Woodhouse 464df8e96f3SDavid Woodhouse /* Now we have a bunch of nodes in reverse version 465df8e96f3SDavid Woodhouse order, in the tree at ver_root. Most of the time, 466df8e96f3SDavid Woodhouse there'll actually be only one node in the 'tree', 467df8e96f3SDavid Woodhouse in fact. */ 468df8e96f3SDavid Woodhouse this = tn_last(&ver_root); 469df8e96f3SDavid Woodhouse 470df8e96f3SDavid Woodhouse while (this) { 471df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *vers_next; 472df8e96f3SDavid Woodhouse int ret; 473df8e96f3SDavid Woodhouse vers_next = tn_prev(this); 474df8e96f3SDavid Woodhouse eat_last(&ver_root, &this->rb); 475df8e96f3SDavid Woodhouse if (check_tn_node(c, this)) { 4761123e2a8SDavid Woodhouse dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n", 477df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 478df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 479df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 480df8e96f3SDavid Woodhouse } else { 481df8e96f3SDavid Woodhouse if (this->version > high_ver) { 482df8e96f3SDavid Woodhouse /* Note that this is different from the other 483df8e96f3SDavid Woodhouse highest_version, because this one is only 484df8e96f3SDavid Woodhouse counting _valid_ nodes which could give the 485df8e96f3SDavid Woodhouse latest inode metadata */ 486df8e96f3SDavid Woodhouse high_ver = this->version; 487df8e96f3SDavid Woodhouse rii->latest_ref = this->fn->raw; 488df8e96f3SDavid Woodhouse } 4891123e2a8SDavid Woodhouse dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n", 490df8e96f3SDavid Woodhouse this, this->version, this->fn->ofs, 491df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size, this->overlapped); 492df8e96f3SDavid Woodhouse 493df8e96f3SDavid Woodhouse ret = jffs2_add_full_dnode_to_inode(c, f, this->fn); 494df8e96f3SDavid Woodhouse if (ret) { 495df8e96f3SDavid Woodhouse /* Free the nodes in vers_root; let the caller 496df8e96f3SDavid Woodhouse deal with the rest */ 497df8e96f3SDavid Woodhouse JFFS2_ERROR("Add node to tree failed %d\n", ret); 498df8e96f3SDavid Woodhouse while (1) { 499df8e96f3SDavid Woodhouse vers_next = tn_prev(this); 500df8e96f3SDavid Woodhouse if (check_tn_node(c, this)) 501df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, this->fn->raw); 502df8e96f3SDavid Woodhouse jffs2_free_full_dnode(this->fn); 503df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(this); 504df8e96f3SDavid Woodhouse this = vers_next; 505df8e96f3SDavid Woodhouse if (!this) 506df8e96f3SDavid Woodhouse break; 507df8e96f3SDavid Woodhouse eat_last(&ver_root, &vers_next->rb); 508df8e96f3SDavid Woodhouse } 509df8e96f3SDavid Woodhouse return ret; 510df8e96f3SDavid Woodhouse } 511df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(this); 512df8e96f3SDavid Woodhouse } 513df8e96f3SDavid Woodhouse this = vers_next; 514df8e96f3SDavid Woodhouse } 515df8e96f3SDavid Woodhouse } 516df8e96f3SDavid Woodhouse return 0; 517f97117d1SArtem B. Bityutskiy } 518f97117d1SArtem B. Bityutskiy 519f97117d1SArtem B. Bityutskiy static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) 520f97117d1SArtem B. Bityutskiy { 521f97117d1SArtem B. Bityutskiy struct rb_node *this; 522f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 523f97117d1SArtem B. Bityutskiy 524f97117d1SArtem B. Bityutskiy this = list->rb_node; 525f97117d1SArtem B. Bityutskiy 526f97117d1SArtem B. Bityutskiy /* Now at bottom of tree */ 527f97117d1SArtem B. Bityutskiy while (this) { 528f97117d1SArtem B. Bityutskiy if (this->rb_left) 529f97117d1SArtem B. Bityutskiy this = this->rb_left; 530f97117d1SArtem B. Bityutskiy else if (this->rb_right) 531f97117d1SArtem B. Bityutskiy this = this->rb_right; 532f97117d1SArtem B. Bityutskiy else { 533f97117d1SArtem B. Bityutskiy tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb); 534f97117d1SArtem B. Bityutskiy jffs2_free_full_dnode(tn->fn); 535f97117d1SArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 536f97117d1SArtem B. Bityutskiy 53721f1d5fcSDavid Woodhouse this = rb_parent(this); 538f97117d1SArtem B. Bityutskiy if (!this) 5391da177e4SLinus Torvalds break; 5401da177e4SLinus Torvalds 541f97117d1SArtem B. Bityutskiy if (this->rb_left == &tn->rb) 542f97117d1SArtem B. Bityutskiy this->rb_left = NULL; 543f97117d1SArtem B. Bityutskiy else if (this->rb_right == &tn->rb) 544f97117d1SArtem B. Bityutskiy this->rb_right = NULL; 545f97117d1SArtem B. Bityutskiy else BUG(); 546f97117d1SArtem B. Bityutskiy } 547f97117d1SArtem B. Bityutskiy } 548f97117d1SArtem B. Bityutskiy list->rb_node = NULL; 549f97117d1SArtem B. Bityutskiy } 5501da177e4SLinus Torvalds 551f97117d1SArtem B. Bityutskiy static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 552f97117d1SArtem B. Bityutskiy { 553f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *next; 554f97117d1SArtem B. Bityutskiy 555f97117d1SArtem B. Bityutskiy while (fd) { 556f97117d1SArtem B. Bityutskiy next = fd->next; 557f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 558f97117d1SArtem B. Bityutskiy fd = next; 559f97117d1SArtem B. Bityutskiy } 560f97117d1SArtem B. Bityutskiy } 561f97117d1SArtem B. Bityutskiy 562f97117d1SArtem B. Bityutskiy /* Returns first valid node after 'ref'. May return 'ref' */ 563f97117d1SArtem B. Bityutskiy static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref) 564f97117d1SArtem B. Bityutskiy { 565f97117d1SArtem B. Bityutskiy while (ref && ref->next_in_ino) { 566f97117d1SArtem B. Bityutskiy if (!ref_obsolete(ref)) 567f97117d1SArtem B. Bityutskiy return ref; 568733802d9SArtem B. Bityutskiy dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)); 569f97117d1SArtem B. Bityutskiy ref = ref->next_in_ino; 570f97117d1SArtem B. Bityutskiy } 571f97117d1SArtem B. Bityutskiy return NULL; 572f97117d1SArtem B. Bityutskiy } 573f97117d1SArtem B. Bityutskiy 574f97117d1SArtem B. Bityutskiy /* 575f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 576f97117d1SArtem B. Bityutskiy * It is called every time an directory entry node is found. 577f97117d1SArtem B. Bityutskiy * 578f97117d1SArtem B. Bityutskiy * Returns: 0 on succes; 579f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 580f97117d1SArtem B. Bityutskiy * negative error code on failure. 581f97117d1SArtem B. Bityutskiy */ 5821e0da3cbSArtem B. Bityutskiy static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 583df8e96f3SDavid Woodhouse struct jffs2_raw_dirent *rd, size_t read, 584df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 585f97117d1SArtem B. Bityutskiy { 586f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *fd; 5871046d880SDavid Woodhouse uint32_t crc; 588f97117d1SArtem B. Bityutskiy 589f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 590f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 591f97117d1SArtem B. Bityutskiy 5921046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 5931046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 5941046d880SDavid Woodhouse JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", 5951046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 596df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 597df8e96f3SDavid Woodhouse return 0; 5981046d880SDavid Woodhouse } 5991046d880SDavid Woodhouse 6001046d880SDavid Woodhouse /* If we've never checked the CRCs on this node, check them now */ 6011046d880SDavid Woodhouse if (ref_flags(ref) == REF_UNCHECKED) { 6021046d880SDavid Woodhouse struct jffs2_eraseblock *jeb; 6031046d880SDavid Woodhouse int len; 6041046d880SDavid Woodhouse 605f97117d1SArtem B. Bityutskiy /* Sanity check */ 606f97117d1SArtem B. Bityutskiy if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 607e0d60137SArtem B. Bityutskiy JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 608f97117d1SArtem B. Bityutskiy ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 609df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 610df8e96f3SDavid Woodhouse return 0; 611f97117d1SArtem B. Bityutskiy } 612f97117d1SArtem B. Bityutskiy 6131046d880SDavid Woodhouse jeb = &c->blocks[ref->flash_offset / c->sector_size]; 6141046d880SDavid Woodhouse len = ref_totlen(c, jeb, ref); 6151046d880SDavid Woodhouse 6161046d880SDavid Woodhouse spin_lock(&c->erase_completion_lock); 6171046d880SDavid Woodhouse jeb->used_size += len; 6181046d880SDavid Woodhouse jeb->unchecked_size -= len; 6191046d880SDavid Woodhouse c->used_size += len; 6201046d880SDavid Woodhouse c->unchecked_size -= len; 6211046d880SDavid Woodhouse ref->flash_offset = ref_offset(ref) | REF_PRISTINE; 6221046d880SDavid Woodhouse spin_unlock(&c->erase_completion_lock); 6231046d880SDavid Woodhouse } 6241046d880SDavid Woodhouse 625f97117d1SArtem B. Bityutskiy fd = jffs2_alloc_full_dirent(rd->nsize + 1); 626f97117d1SArtem B. Bityutskiy if (unlikely(!fd)) 627f97117d1SArtem B. Bityutskiy return -ENOMEM; 628f97117d1SArtem B. Bityutskiy 629f97117d1SArtem B. Bityutskiy fd->raw = ref; 630f97117d1SArtem B. Bityutskiy fd->version = je32_to_cpu(rd->version); 631f97117d1SArtem B. Bityutskiy fd->ino = je32_to_cpu(rd->ino); 632f97117d1SArtem B. Bityutskiy fd->type = rd->type; 633f97117d1SArtem B. Bityutskiy 634df8e96f3SDavid Woodhouse if (fd->version > rii->highest_version) 635df8e96f3SDavid Woodhouse rii->highest_version = fd->version; 636df8e96f3SDavid Woodhouse 637f97117d1SArtem B. Bityutskiy /* Pick out the mctime of the latest dirent */ 638df8e96f3SDavid Woodhouse if(fd->version > rii->mctime_ver && je32_to_cpu(rd->mctime)) { 639df8e96f3SDavid Woodhouse rii->mctime_ver = fd->version; 640df8e96f3SDavid Woodhouse rii->latest_mctime = je32_to_cpu(rd->mctime); 641f97117d1SArtem B. Bityutskiy } 642f97117d1SArtem B. Bityutskiy 643f97117d1SArtem B. Bityutskiy /* 644f97117d1SArtem B. Bityutskiy * Copy as much of the name as possible from the raw 645f97117d1SArtem B. Bityutskiy * dirent we've already read from the flash. 646f97117d1SArtem B. Bityutskiy */ 647f97117d1SArtem B. Bityutskiy if (read > sizeof(*rd)) 648f97117d1SArtem B. Bityutskiy memcpy(&fd->name[0], &rd->name[0], 649f97117d1SArtem B. Bityutskiy min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); 650f97117d1SArtem B. Bityutskiy 651f97117d1SArtem B. Bityutskiy /* Do we need to copy any more of the name directly from the flash? */ 652f97117d1SArtem B. Bityutskiy if (rd->nsize + sizeof(*rd) > read) { 653f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 654f97117d1SArtem B. Bityutskiy int err; 655f97117d1SArtem B. Bityutskiy int already = read - sizeof(*rd); 656f97117d1SArtem B. Bityutskiy 657f97117d1SArtem B. Bityutskiy err = jffs2_flash_read(c, (ref_offset(ref)) + read, 658f97117d1SArtem B. Bityutskiy rd->nsize - already, &read, &fd->name[already]); 659f97117d1SArtem B. Bityutskiy if (unlikely(read != rd->nsize - already) && likely(!err)) 660f97117d1SArtem B. Bityutskiy return -EIO; 661f97117d1SArtem B. Bityutskiy 662f97117d1SArtem B. Bityutskiy if (unlikely(err)) { 663e0d60137SArtem B. Bityutskiy JFFS2_ERROR("read remainder of name: error %d\n", err); 664f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 665f97117d1SArtem B. Bityutskiy return -EIO; 666f97117d1SArtem B. Bityutskiy } 667f97117d1SArtem B. Bityutskiy } 668f97117d1SArtem B. Bityutskiy 669f97117d1SArtem B. Bityutskiy fd->nhash = full_name_hash(fd->name, rd->nsize); 670f97117d1SArtem B. Bityutskiy fd->next = NULL; 671f97117d1SArtem B. Bityutskiy fd->name[rd->nsize] = '\0'; 672f97117d1SArtem B. Bityutskiy 673f97117d1SArtem B. Bityutskiy /* 674f97117d1SArtem B. Bityutskiy * Wheee. We now have a complete jffs2_full_dirent structure, with 675f97117d1SArtem B. Bityutskiy * the name in it and everything. Link it into the list 676f97117d1SArtem B. Bityutskiy */ 677df8e96f3SDavid Woodhouse jffs2_add_fd_to_list(c, fd, &rii->fds); 678f97117d1SArtem B. Bityutskiy 679f97117d1SArtem B. Bityutskiy return 0; 680f97117d1SArtem B. Bityutskiy } 681f97117d1SArtem B. Bityutskiy 682f97117d1SArtem B. Bityutskiy /* 683f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 684f97117d1SArtem B. Bityutskiy * It is called every time an inode node is found. 685f97117d1SArtem B. Bityutskiy * 686df8e96f3SDavid Woodhouse * Returns: 0 on success; 687f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 688f97117d1SArtem B. Bityutskiy * negative error code on failure. 689f97117d1SArtem B. Bityutskiy */ 6901e0da3cbSArtem B. Bityutskiy static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 691df8e96f3SDavid Woodhouse struct jffs2_raw_inode *rd, int rdlen, 692df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 693f97117d1SArtem B. Bityutskiy { 694f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 6951e0da3cbSArtem B. Bityutskiy uint32_t len, csize; 6961e0da3cbSArtem B. Bityutskiy int ret = 1; 6971046d880SDavid Woodhouse uint32_t crc; 698f97117d1SArtem B. Bityutskiy 699f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 700f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 701f97117d1SArtem B. Bityutskiy 7021046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 7031046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 7041046d880SDavid Woodhouse JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", 7051046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 706df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 707df8e96f3SDavid Woodhouse return 0; 7081046d880SDavid Woodhouse } 7091046d880SDavid Woodhouse 7101e0da3cbSArtem B. Bityutskiy tn = jffs2_alloc_tmp_dnode_info(); 7111e0da3cbSArtem B. Bityutskiy if (!tn) { 712fb6a82c9SRandy Dunlap JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); 7131e0da3cbSArtem B. Bityutskiy return -ENOMEM; 7141e0da3cbSArtem B. Bityutskiy } 7151e0da3cbSArtem B. Bityutskiy 7161e0da3cbSArtem B. Bityutskiy tn->partial_crc = 0; 7171e0da3cbSArtem B. Bityutskiy csize = je32_to_cpu(rd->csize); 7181e0da3cbSArtem B. Bityutskiy 719f97117d1SArtem B. Bityutskiy /* If we've never checked the CRCs on this node, check them now */ 720f97117d1SArtem B. Bityutskiy if (ref_flags(ref) == REF_UNCHECKED) { 721f97117d1SArtem B. Bityutskiy 722f97117d1SArtem B. Bityutskiy /* Sanity checks */ 723f97117d1SArtem B. Bityutskiy if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 724f97117d1SArtem B. Bityutskiy unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 725e0d60137SArtem B. Bityutskiy JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); 726737b7661SAndrew Lunn jffs2_dbg_dump_node(c, ref_offset(ref)); 7271e0da3cbSArtem B. Bityutskiy goto free_out; 728f97117d1SArtem B. Bityutskiy } 729f97117d1SArtem B. Bityutskiy 7301e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c) && csize != 0) { 7311e0da3cbSArtem B. Bityutskiy /* At this point we are supposed to check the data CRC 7321e0da3cbSArtem B. Bityutskiy * of our unchecked node. But thus far, we do not 7331e0da3cbSArtem B. Bityutskiy * know whether the node is valid or obsolete. To 7341e0da3cbSArtem B. Bityutskiy * figure this out, we need to walk all the nodes of 7351e0da3cbSArtem B. Bityutskiy * the inode and build the inode fragtree. We don't 7361e0da3cbSArtem B. Bityutskiy * want to spend time checking data of nodes which may 7371e0da3cbSArtem B. Bityutskiy * later be found to be obsolete. So we put off the full 7381e0da3cbSArtem B. Bityutskiy * data CRC checking until we have read all the inode 7391e0da3cbSArtem B. Bityutskiy * nodes and have started building the fragtree. 7401e0da3cbSArtem B. Bityutskiy * 7411e0da3cbSArtem B. Bityutskiy * The fragtree is being built starting with nodes 7421e0da3cbSArtem B. Bityutskiy * having the highest version number, so we'll be able 7431e0da3cbSArtem B. Bityutskiy * to detect whether a node is valid (i.e., it is not 7441e0da3cbSArtem B. Bityutskiy * overlapped by a node with higher version) or not. 7451e0da3cbSArtem B. Bityutskiy * And we'll be able to check only those nodes, which 7461e0da3cbSArtem B. Bityutskiy * are not obsolete. 7471e0da3cbSArtem B. Bityutskiy * 7481e0da3cbSArtem B. Bityutskiy * Of course, this optimization only makes sense in case 7491e0da3cbSArtem B. Bityutskiy * of NAND flashes (or other flashes whith 7501e0da3cbSArtem B. Bityutskiy * !jffs2_can_mark_obsolete()), since on NOR flashes 7511e0da3cbSArtem B. Bityutskiy * nodes are marked obsolete physically. 7521e0da3cbSArtem B. Bityutskiy * 7531e0da3cbSArtem B. Bityutskiy * Since NAND flashes (or other flashes with 7541e0da3cbSArtem B. Bityutskiy * jffs2_is_writebuffered(c)) are anyway read by 7551e0da3cbSArtem B. Bityutskiy * fractions of c->wbuf_pagesize, and we have just read 7561e0da3cbSArtem B. Bityutskiy * the node header, it is likely that the starting part 7571e0da3cbSArtem B. Bityutskiy * of the node data is also read when we read the 7581e0da3cbSArtem B. Bityutskiy * header. So we don't mind to check the CRC of the 7591e0da3cbSArtem B. Bityutskiy * starting part of the data of the node now, and check 7601e0da3cbSArtem B. Bityutskiy * the second part later (in jffs2_check_node_data()). 7611e0da3cbSArtem B. Bityutskiy * Of course, we will not need to re-read and re-check 7621e0da3cbSArtem B. Bityutskiy * the NAND page which we have just read. This is why we 7631e0da3cbSArtem B. Bityutskiy * read the whole NAND page at jffs2_get_inode_nodes(), 7641e0da3cbSArtem B. Bityutskiy * while we needed only the node header. 7651e0da3cbSArtem B. Bityutskiy */ 7661e0da3cbSArtem B. Bityutskiy unsigned char *buf; 767f97117d1SArtem B. Bityutskiy 7681e0da3cbSArtem B. Bityutskiy /* 'buf' will point to the start of data */ 7691e0da3cbSArtem B. Bityutskiy buf = (unsigned char *)rd + sizeof(*rd); 7701e0da3cbSArtem B. Bityutskiy /* len will be the read data length */ 7711e0da3cbSArtem B. Bityutskiy len = min_t(uint32_t, rdlen - sizeof(*rd), csize); 772280562b2SArtem B. Bityutskiy tn->partial_crc = crc32(0, buf, len); 773f97117d1SArtem B. Bityutskiy 774733802d9SArtem B. Bityutskiy dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize); 775f97117d1SArtem B. Bityutskiy 7761e0da3cbSArtem B. Bityutskiy /* If we actually calculated the whole data CRC 7771e0da3cbSArtem B. Bityutskiy * and it is wrong, drop the node. */ 7783c091337SArtem B. Bityutskiy if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { 77939243508SArtem B. Bityutskiy JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 78039243508SArtem B. Bityutskiy ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); 7811e0da3cbSArtem B. Bityutskiy goto free_out; 78239243508SArtem B. Bityutskiy } 783f97117d1SArtem B. Bityutskiy 7841e0da3cbSArtem B. Bityutskiy } else if (csize == 0) { 7851e0da3cbSArtem B. Bityutskiy /* 7861e0da3cbSArtem B. Bityutskiy * We checked the header CRC. If the node has no data, adjust 7871e0da3cbSArtem B. Bityutskiy * the space accounting now. For other nodes this will be done 7881e0da3cbSArtem B. Bityutskiy * later either when the node is marked obsolete or when its 7891e0da3cbSArtem B. Bityutskiy * data is checked. 7901e0da3cbSArtem B. Bityutskiy */ 7911e0da3cbSArtem B. Bityutskiy struct jffs2_eraseblock *jeb; 7921e0da3cbSArtem B. Bityutskiy 793733802d9SArtem B. Bityutskiy dbg_readinode("the node has no data.\n"); 794f97117d1SArtem B. Bityutskiy jeb = &c->blocks[ref->flash_offset / c->sector_size]; 795f97117d1SArtem B. Bityutskiy len = ref_totlen(c, jeb, ref); 796f97117d1SArtem B. Bityutskiy 797f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 798f97117d1SArtem B. Bityutskiy jeb->used_size += len; 799f97117d1SArtem B. Bityutskiy jeb->unchecked_size -= len; 800f97117d1SArtem B. Bityutskiy c->used_size += len; 801f97117d1SArtem B. Bityutskiy c->unchecked_size -= len; 802f97117d1SArtem B. Bityutskiy ref->flash_offset = ref_offset(ref) | REF_NORMAL; 803f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 804f97117d1SArtem B. Bityutskiy } 805f97117d1SArtem B. Bityutskiy } 806f97117d1SArtem B. Bityutskiy 807f97117d1SArtem B. Bityutskiy tn->fn = jffs2_alloc_full_dnode(); 808f97117d1SArtem B. Bityutskiy if (!tn->fn) { 809e0d60137SArtem B. Bityutskiy JFFS2_ERROR("alloc fn failed\n"); 8101e0da3cbSArtem B. Bityutskiy ret = -ENOMEM; 8111e0da3cbSArtem B. Bityutskiy goto free_out; 812f97117d1SArtem B. Bityutskiy } 813f97117d1SArtem B. Bityutskiy 814f97117d1SArtem B. Bityutskiy tn->version = je32_to_cpu(rd->version); 815f97117d1SArtem B. Bityutskiy tn->fn->ofs = je32_to_cpu(rd->offset); 8161e0da3cbSArtem B. Bityutskiy tn->data_crc = je32_to_cpu(rd->data_crc); 8171e0da3cbSArtem B. Bityutskiy tn->csize = csize; 818f97117d1SArtem B. Bityutskiy tn->fn->raw = ref; 819df8e96f3SDavid Woodhouse tn->overlapped = 0; 820df8e96f3SDavid Woodhouse 821df8e96f3SDavid Woodhouse if (tn->version > rii->highest_version) 822df8e96f3SDavid Woodhouse rii->highest_version = tn->version; 823f97117d1SArtem B. Bityutskiy 824f97117d1SArtem B. Bityutskiy /* There was a bug where we wrote hole nodes out with 825f97117d1SArtem B. Bityutskiy csize/dsize swapped. Deal with it */ 8261e0da3cbSArtem B. Bityutskiy if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize) 8271e0da3cbSArtem B. Bityutskiy tn->fn->size = csize; 828f97117d1SArtem B. Bityutskiy else // normal case... 829f97117d1SArtem B. Bityutskiy tn->fn->size = je32_to_cpu(rd->dsize); 830f97117d1SArtem B. Bityutskiy 831733802d9SArtem B. Bityutskiy dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", 832280562b2SArtem B. Bityutskiy ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); 833f97117d1SArtem B. Bityutskiy 834df8e96f3SDavid Woodhouse ret = jffs2_add_tn_to_tree(c, rii, tn); 835f97117d1SArtem B. Bityutskiy 836df8e96f3SDavid Woodhouse if (ret) { 837df8e96f3SDavid Woodhouse jffs2_free_full_dnode(tn->fn); 8381e0da3cbSArtem B. Bityutskiy free_out: 8391e0da3cbSArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 8401e0da3cbSArtem B. Bityutskiy return ret; 841f97117d1SArtem B. Bityutskiy } 842df8e96f3SDavid Woodhouse #ifdef JFFS2_DBG_READINODE_MESSAGES 8431123e2a8SDavid Woodhouse dbg_readinode("After adding ver %d:\n", je32_to_cpu(rd->version)); 844df8e96f3SDavid Woodhouse tn = tn_first(&rii->tn_root); 845df8e96f3SDavid Woodhouse while (tn) { 846df8e96f3SDavid Woodhouse dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n", 847df8e96f3SDavid Woodhouse tn, tn->version, tn->fn->ofs, 848df8e96f3SDavid Woodhouse tn->fn->ofs+tn->fn->size, tn->overlapped); 849df8e96f3SDavid Woodhouse tn = tn_next(tn); 850df8e96f3SDavid Woodhouse } 851df8e96f3SDavid Woodhouse #endif 852df8e96f3SDavid Woodhouse return 0; 853df8e96f3SDavid Woodhouse } 854f97117d1SArtem B. Bityutskiy 855f97117d1SArtem B. Bityutskiy /* 856f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 857f97117d1SArtem B. Bityutskiy * It is called every time an unknown node is found. 858f97117d1SArtem B. Bityutskiy * 8593877f0b6SDavid Woodhouse * Returns: 0 on success; 860f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 861f97117d1SArtem B. Bityutskiy * negative error code on failure. 862f97117d1SArtem B. Bityutskiy */ 8631e0da3cbSArtem B. Bityutskiy static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) 864f97117d1SArtem B. Bityutskiy { 865f97117d1SArtem B. Bityutskiy /* We don't mark unknown nodes as REF_UNCHECKED */ 866c7258a44SDavid Woodhouse if (ref_flags(ref) == REF_UNCHECKED) { 867c7258a44SDavid Woodhouse JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", 868c7258a44SDavid Woodhouse ref_offset(ref)); 869c7258a44SDavid Woodhouse JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", 870c7258a44SDavid Woodhouse je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), 871c7258a44SDavid Woodhouse je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); 872df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 873df8e96f3SDavid Woodhouse return 0; 874c7258a44SDavid Woodhouse } 875f97117d1SArtem B. Bityutskiy 876f97117d1SArtem B. Bityutskiy un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); 877f97117d1SArtem B. Bityutskiy 878f97117d1SArtem B. Bityutskiy switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) { 879f97117d1SArtem B. Bityutskiy 880f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_INCOMPAT: 881e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n", 882f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 883f97117d1SArtem B. Bityutskiy /* EEP */ 884f97117d1SArtem B. Bityutskiy BUG(); 885f97117d1SArtem B. Bityutskiy break; 886f97117d1SArtem B. Bityutskiy 887f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_ROCOMPAT: 888e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n", 889f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 890f97117d1SArtem B. Bityutskiy BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); 891f97117d1SArtem B. Bityutskiy break; 892f97117d1SArtem B. Bityutskiy 893f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_COPY: 894e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n", 895f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 896f97117d1SArtem B. Bityutskiy break; 897f97117d1SArtem B. Bityutskiy 898f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_DELETE: 899e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", 900f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 901df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 902df8e96f3SDavid Woodhouse return 0; 903f97117d1SArtem B. Bityutskiy } 904f97117d1SArtem B. Bityutskiy 905f97117d1SArtem B. Bityutskiy return 0; 906f97117d1SArtem B. Bityutskiy } 907f97117d1SArtem B. Bityutskiy 9081e0da3cbSArtem B. Bityutskiy /* 9091e0da3cbSArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 9101e0da3cbSArtem B. Bityutskiy * The function detects whether more data should be read and reads it if yes. 9111e0da3cbSArtem B. Bityutskiy * 9121e0da3cbSArtem B. Bityutskiy * Returns: 0 on succes; 9131e0da3cbSArtem B. Bityutskiy * negative error code on failure. 9141e0da3cbSArtem B. Bityutskiy */ 9151e0da3cbSArtem B. Bityutskiy static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 91610731f83SArtem Bityutskiy int needed_len, int *rdlen, unsigned char *buf) 9171e0da3cbSArtem B. Bityutskiy { 91810731f83SArtem Bityutskiy int err, to_read = needed_len - *rdlen; 9191e0da3cbSArtem B. Bityutskiy size_t retlen; 9201e0da3cbSArtem B. Bityutskiy uint32_t offs; 9211e0da3cbSArtem B. Bityutskiy 9221e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 92310731f83SArtem Bityutskiy int rem = to_read % c->wbuf_pagesize; 9241e0da3cbSArtem B. Bityutskiy 92510731f83SArtem Bityutskiy if (rem) 92610731f83SArtem Bityutskiy to_read += c->wbuf_pagesize - rem; 92710731f83SArtem Bityutskiy } 9281e0da3cbSArtem B. Bityutskiy 9291e0da3cbSArtem B. Bityutskiy /* We need to read more data */ 9301e0da3cbSArtem B. Bityutskiy offs = ref_offset(ref) + *rdlen; 9311e0da3cbSArtem B. Bityutskiy 93210731f83SArtem Bityutskiy dbg_readinode("read more %d bytes\n", to_read); 9331e0da3cbSArtem B. Bityutskiy 93410731f83SArtem Bityutskiy err = jffs2_flash_read(c, offs, to_read, &retlen, buf + *rdlen); 9351e0da3cbSArtem B. Bityutskiy if (err) { 9361e0da3cbSArtem B. Bityutskiy JFFS2_ERROR("can not read %d bytes from 0x%08x, " 93710731f83SArtem Bityutskiy "error code: %d.\n", to_read, offs, err); 9381e0da3cbSArtem B. Bityutskiy return err; 9391e0da3cbSArtem B. Bityutskiy } 9401e0da3cbSArtem B. Bityutskiy 94110731f83SArtem Bityutskiy if (retlen < to_read) { 942fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", 94310731f83SArtem Bityutskiy offs, retlen, to_read); 9441e0da3cbSArtem B. Bityutskiy return -EIO; 9451e0da3cbSArtem B. Bityutskiy } 9461e0da3cbSArtem B. Bityutskiy 94710731f83SArtem Bityutskiy *rdlen += to_read; 9481e0da3cbSArtem B. Bityutskiy return 0; 9491e0da3cbSArtem B. Bityutskiy } 9501e0da3cbSArtem B. Bityutskiy 951f97117d1SArtem B. Bityutskiy /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated 952df8e96f3SDavid Woodhouse with this ino. Perform a preliminary ordering on data nodes, throwing away 953df8e96f3SDavid Woodhouse those which are completely obsoleted by newer ones. The naïve approach we 954df8e96f3SDavid Woodhouse use to take of just returning them _all_ in version order will cause us to 955df8e96f3SDavid Woodhouse run out of memory in certain degenerate cases. */ 956f97117d1SArtem B. Bityutskiy static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 957df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 958f97117d1SArtem B. Bityutskiy { 959f97117d1SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref, *valid_ref; 9601e0da3cbSArtem B. Bityutskiy unsigned char *buf = NULL; 9611e0da3cbSArtem B. Bityutskiy union jffs2_node_union *node; 962f97117d1SArtem B. Bityutskiy size_t retlen; 9631e0da3cbSArtem B. Bityutskiy int len, err; 964f97117d1SArtem B. Bityutskiy 965df8e96f3SDavid Woodhouse rii->mctime_ver = 0; 966f97117d1SArtem B. Bityutskiy 967733802d9SArtem B. Bityutskiy dbg_readinode("ino #%u\n", f->inocache->ino); 968f97117d1SArtem B. Bityutskiy 9691e0da3cbSArtem B. Bityutskiy /* FIXME: in case of NOR and available ->point() this 9701e0da3cbSArtem B. Bityutskiy * needs to be fixed. */ 97110731f83SArtem Bityutskiy len = sizeof(union jffs2_node_union) + c->wbuf_pagesize; 9721e0da3cbSArtem B. Bityutskiy buf = kmalloc(len, GFP_KERNEL); 9731e0da3cbSArtem B. Bityutskiy if (!buf) 9741e0da3cbSArtem B. Bityutskiy return -ENOMEM; 9751e0da3cbSArtem B. Bityutskiy 976f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 977f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(f->inocache->nodes); 9781e0da3cbSArtem B. Bityutskiy if (!valid_ref && f->inocache->ino != 1) 9791e0da3cbSArtem B. Bityutskiy JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); 980f97117d1SArtem B. Bityutskiy while (valid_ref) { 981f97117d1SArtem B. Bityutskiy /* We can hold a pointer to a non-obsolete node without the spinlock, 982f97117d1SArtem B. Bityutskiy but _obsolete_ nodes may disappear at any time, if the block 983f97117d1SArtem B. Bityutskiy they're in gets erased. So if we mark 'ref' obsolete while we're 984f97117d1SArtem B. Bityutskiy not holding the lock, it can go away immediately. For that reason, 985f97117d1SArtem B. Bityutskiy we find the next valid node first, before processing 'ref'. 986f97117d1SArtem B. Bityutskiy */ 987f97117d1SArtem B. Bityutskiy ref = valid_ref; 988f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(ref->next_in_ino); 989f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 990f97117d1SArtem B. Bityutskiy 991f97117d1SArtem B. Bityutskiy cond_resched(); 992f97117d1SArtem B. Bityutskiy 9931e0da3cbSArtem B. Bityutskiy /* 9941e0da3cbSArtem B. Bityutskiy * At this point we don't know the type of the node we're going 9951e0da3cbSArtem B. Bityutskiy * to read, so we do not know the size of its header. In order 99610731f83SArtem Bityutskiy * to minimize the amount of flash IO we assume the header is 99710731f83SArtem Bityutskiy * of size = JFFS2_MIN_NODE_HEADER. 9981e0da3cbSArtem B. Bityutskiy */ 9991e0da3cbSArtem B. Bityutskiy len = JFFS2_MIN_NODE_HEADER; 100010731f83SArtem Bityutskiy if (jffs2_is_writebuffered(c)) { 100110731f83SArtem Bityutskiy int end, rem; 100210731f83SArtem Bityutskiy 100310731f83SArtem Bityutskiy /* 100410731f83SArtem Bityutskiy * We are about to read JFFS2_MIN_NODE_HEADER bytes, 100510731f83SArtem Bityutskiy * but this flash has some minimal I/O unit. It is 100610731f83SArtem Bityutskiy * possible that we'll need to read more soon, so read 100710731f83SArtem Bityutskiy * up to the next min. I/O unit, in order not to 100810731f83SArtem Bityutskiy * re-read the same min. I/O unit twice. 100910731f83SArtem Bityutskiy */ 101010731f83SArtem Bityutskiy end = ref_offset(ref) + len; 101110731f83SArtem Bityutskiy rem = end % c->wbuf_pagesize; 101210731f83SArtem Bityutskiy if (rem) 101310731f83SArtem Bityutskiy end += c->wbuf_pagesize - rem; 101410731f83SArtem Bityutskiy len = end - ref_offset(ref); 10151e0da3cbSArtem B. Bityutskiy } 10161e0da3cbSArtem B. Bityutskiy 1017733802d9SArtem B. Bityutskiy dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); 10181e0da3cbSArtem B. Bityutskiy 1019f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 102010731f83SArtem Bityutskiy err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, buf); 1021f97117d1SArtem B. Bityutskiy if (err) { 10221e0da3cbSArtem B. Bityutskiy JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err); 1023f97117d1SArtem B. Bityutskiy goto free_out; 1024f97117d1SArtem B. Bityutskiy } 1025f97117d1SArtem B. Bityutskiy 10261e0da3cbSArtem B. Bityutskiy if (retlen < len) { 1027fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", ref_offset(ref), retlen, len); 1028f97117d1SArtem B. Bityutskiy err = -EIO; 1029f97117d1SArtem B. Bityutskiy goto free_out; 1030f97117d1SArtem B. Bityutskiy } 1031f97117d1SArtem B. Bityutskiy 103210731f83SArtem Bityutskiy node = (union jffs2_node_union *)buf; 10331e0da3cbSArtem B. Bityutskiy 10343877f0b6SDavid Woodhouse /* No need to mask in the valid bit; it shouldn't be invalid */ 10353877f0b6SDavid Woodhouse if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { 10363877f0b6SDavid Woodhouse JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n", 10373877f0b6SDavid Woodhouse ref_offset(ref), je16_to_cpu(node->u.magic), 10383877f0b6SDavid Woodhouse je16_to_cpu(node->u.nodetype), 10393877f0b6SDavid Woodhouse je32_to_cpu(node->u.totlen), 10403877f0b6SDavid Woodhouse je32_to_cpu(node->u.hdr_crc)); 10413877f0b6SDavid Woodhouse jffs2_dbg_dump_node(c, ref_offset(ref)); 10423877f0b6SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 10433877f0b6SDavid Woodhouse goto cont; 10443877f0b6SDavid Woodhouse } 10450dec4c8bSJoakim Tjernlund if (je16_to_cpu(node->u.magic) != JFFS2_MAGIC_BITMASK) { 10460dec4c8bSJoakim Tjernlund /* Not a JFFS2 node, whinge and move on */ 10470dec4c8bSJoakim Tjernlund JFFS2_NOTICE("Wrong magic bitmask 0x%04x in node header at %#08x.\n", 10480dec4c8bSJoakim Tjernlund je16_to_cpu(node->u.magic), ref_offset(ref)); 1049c7258a44SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 1050c7258a44SDavid Woodhouse goto cont; 1051c7258a44SDavid Woodhouse } 10523877f0b6SDavid Woodhouse 10531e0da3cbSArtem B. Bityutskiy switch (je16_to_cpu(node->u.nodetype)) { 10541e0da3cbSArtem B. Bityutskiy 10551e0da3cbSArtem B. Bityutskiy case JFFS2_NODETYPE_DIRENT: 10561e0da3cbSArtem B. Bityutskiy 10571e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) { 105810731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf); 10591e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 10601e0da3cbSArtem B. Bityutskiy goto free_out; 10611e0da3cbSArtem B. Bityutskiy } 10621e0da3cbSArtem B. Bityutskiy 1063df8e96f3SDavid Woodhouse err = read_direntry(c, ref, &node->d, retlen, rii); 1064df8e96f3SDavid Woodhouse if (unlikely(err)) 1065f97117d1SArtem B. Bityutskiy goto free_out; 1066f97117d1SArtem B. Bityutskiy 1067f97117d1SArtem B. Bityutskiy break; 1068f97117d1SArtem B. Bityutskiy 1069f97117d1SArtem B. Bityutskiy case JFFS2_NODETYPE_INODE: 1070f97117d1SArtem B. Bityutskiy 10711e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) { 107210731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf); 10731e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 1074f97117d1SArtem B. Bityutskiy goto free_out; 1075f97117d1SArtem B. Bityutskiy } 1076f97117d1SArtem B. Bityutskiy 1077df8e96f3SDavid Woodhouse err = read_dnode(c, ref, &node->i, len, rii); 1078df8e96f3SDavid Woodhouse if (unlikely(err)) 1079f97117d1SArtem B. Bityutskiy goto free_out; 1080f97117d1SArtem B. Bityutskiy 10811da177e4SLinus Torvalds break; 10821da177e4SLinus Torvalds 10831da177e4SLinus Torvalds default: 10841e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) { 108510731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf); 10861e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 10871e0da3cbSArtem B. Bityutskiy goto free_out; 10881da177e4SLinus Torvalds } 10891da177e4SLinus Torvalds 10901e0da3cbSArtem B. Bityutskiy err = read_unknown(c, ref, &node->u); 1091f97117d1SArtem B. Bityutskiy if (err == 1) { 1092f97117d1SArtem B. Bityutskiy jffs2_mark_node_obsolete(c, ref); 1093f97117d1SArtem B. Bityutskiy break; 1094f97117d1SArtem B. Bityutskiy } else if (unlikely(err)) 1095f97117d1SArtem B. Bityutskiy goto free_out; 1096f97117d1SArtem B. Bityutskiy 10971da177e4SLinus Torvalds } 10983877f0b6SDavid Woodhouse cont: 1099f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 11001da177e4SLinus Torvalds } 11011e0da3cbSArtem B. Bityutskiy 1102f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 11031e0da3cbSArtem B. Bityutskiy kfree(buf); 1104f97117d1SArtem B. Bityutskiy 1105df8e96f3SDavid Woodhouse f->highest_version = rii->highest_version; 1106df8e96f3SDavid Woodhouse 1107733802d9SArtem B. Bityutskiy dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n", 1108df8e96f3SDavid Woodhouse f->inocache->ino, rii->highest_version, rii->latest_mctime, 1109df8e96f3SDavid Woodhouse rii->mctime_ver); 1110f97117d1SArtem B. Bityutskiy return 0; 1111f97117d1SArtem B. Bityutskiy 1112f97117d1SArtem B. Bityutskiy free_out: 1113df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info_list(&rii->tn_root); 1114df8e96f3SDavid Woodhouse jffs2_free_full_dirent_list(rii->fds); 1115df8e96f3SDavid Woodhouse rii->fds = NULL; 11161e0da3cbSArtem B. Bityutskiy kfree(buf); 1117f97117d1SArtem B. Bityutskiy return err; 11181da177e4SLinus Torvalds } 11191da177e4SLinus Torvalds 11201da177e4SLinus Torvalds static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 11211da177e4SLinus Torvalds struct jffs2_inode_info *f, 11221da177e4SLinus Torvalds struct jffs2_raw_inode *latest_node) 11231da177e4SLinus Torvalds { 1124df8e96f3SDavid Woodhouse struct jffs2_readinode_info rii; 112561c4b237SDavid Woodhouse uint32_t crc, new_size; 11261da177e4SLinus Torvalds size_t retlen; 11271da177e4SLinus Torvalds int ret; 11281da177e4SLinus Torvalds 1129733802d9SArtem B. Bityutskiy dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); 11301da177e4SLinus Torvalds 1131df8e96f3SDavid Woodhouse memset(&rii, 0, sizeof(rii)); 1132df8e96f3SDavid Woodhouse 11331da177e4SLinus Torvalds /* Grab all nodes relevant to this ino */ 1134df8e96f3SDavid Woodhouse ret = jffs2_get_inode_nodes(c, f, &rii); 11351da177e4SLinus Torvalds 11361da177e4SLinus Torvalds if (ret) { 1137e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); 11381da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11391da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 11401da177e4SLinus Torvalds return ret; 11411da177e4SLinus Torvalds } 11421da177e4SLinus Torvalds 1143df8e96f3SDavid Woodhouse ret = jffs2_build_inode_fragtree(c, f, &rii); 11441e0da3cbSArtem B. Bityutskiy if (ret) { 1145df8e96f3SDavid Woodhouse JFFS2_ERROR("Failed to build final fragtree for inode #%u: error %d\n", 1146df8e96f3SDavid Woodhouse f->inocache->ino, ret); 1147df8e96f3SDavid Woodhouse if (f->inocache->state == INO_STATE_READING) 1148df8e96f3SDavid Woodhouse jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 1149df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info_list(&rii.tn_root); 1150df8e96f3SDavid Woodhouse /* FIXME: We could at least crc-check them all */ 1151df8e96f3SDavid Woodhouse if (rii.mdata_tn) { 1152df8e96f3SDavid Woodhouse jffs2_free_full_dnode(rii.mdata_tn->fn); 1153df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(rii.mdata_tn); 1154df8e96f3SDavid Woodhouse rii.mdata_tn = NULL; 11551e0da3cbSArtem B. Bityutskiy } 1156df8e96f3SDavid Woodhouse return ret; 11571da177e4SLinus Torvalds } 1158df8e96f3SDavid Woodhouse 1159df8e96f3SDavid Woodhouse if (rii.mdata_tn) { 1160df8e96f3SDavid Woodhouse if (rii.mdata_tn->fn->raw == rii.latest_ref) { 1161df8e96f3SDavid Woodhouse f->metadata = rii.mdata_tn->fn; 1162df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(rii.mdata_tn); 1163df8e96f3SDavid Woodhouse } else { 1164df8e96f3SDavid Woodhouse jffs2_kill_tn(c, rii.mdata_tn); 1165df8e96f3SDavid Woodhouse } 1166df8e96f3SDavid Woodhouse rii.mdata_tn = NULL; 1167df8e96f3SDavid Woodhouse } 1168df8e96f3SDavid Woodhouse 1169df8e96f3SDavid Woodhouse f->dents = rii.fds; 1170df8e96f3SDavid Woodhouse 1171e0c8e42fSArtem B. Bityutskiy jffs2_dbg_fragtree_paranoia_check_nolock(f); 11721da177e4SLinus Torvalds 1173df8e96f3SDavid Woodhouse if (unlikely(!rii.latest_ref)) { 11741da177e4SLinus Torvalds /* No data nodes for this inode. */ 11751da177e4SLinus Torvalds if (f->inocache->ino != 1) { 1176e0d60137SArtem B. Bityutskiy JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); 1177df8e96f3SDavid Woodhouse if (!rii.fds) { 11781da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11791da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 11801da177e4SLinus Torvalds return -EIO; 11811da177e4SLinus Torvalds } 1182e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("but it has children so we fake some modes for it\n"); 11831da177e4SLinus Torvalds } 11841da177e4SLinus Torvalds latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); 11851da177e4SLinus Torvalds latest_node->version = cpu_to_je32(0); 11861da177e4SLinus Torvalds latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); 11871da177e4SLinus Torvalds latest_node->isize = cpu_to_je32(0); 11881da177e4SLinus Torvalds latest_node->gid = cpu_to_je16(0); 11891da177e4SLinus Torvalds latest_node->uid = cpu_to_je16(0); 11901da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11911da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 11921da177e4SLinus Torvalds return 0; 11931da177e4SLinus Torvalds } 11941da177e4SLinus Torvalds 1195df8e96f3SDavid Woodhouse ret = jffs2_flash_read(c, ref_offset(rii.latest_ref), sizeof(*latest_node), &retlen, (void *)latest_node); 11961da177e4SLinus Torvalds if (ret || retlen != sizeof(*latest_node)) { 1197e0d60137SArtem B. Bityutskiy JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", 11981da177e4SLinus Torvalds ret, retlen, sizeof(*latest_node)); 11991da177e4SLinus Torvalds /* FIXME: If this fails, there seems to be a memory leak. Find it. */ 12001da177e4SLinus Torvalds up(&f->sem); 12011da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12021da177e4SLinus Torvalds return ret?ret:-EIO; 12031da177e4SLinus Torvalds } 12041da177e4SLinus Torvalds 12051da177e4SLinus Torvalds crc = crc32(0, latest_node, sizeof(*latest_node)-8); 12061da177e4SLinus Torvalds if (crc != je32_to_cpu(latest_node->node_crc)) { 1207e0d60137SArtem B. Bityutskiy JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", 1208df8e96f3SDavid Woodhouse f->inocache->ino, ref_offset(rii.latest_ref)); 12091da177e4SLinus Torvalds up(&f->sem); 12101da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12111da177e4SLinus Torvalds return -EIO; 12121da177e4SLinus Torvalds } 12131da177e4SLinus Torvalds 12141da177e4SLinus Torvalds switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { 12151da177e4SLinus Torvalds case S_IFDIR: 1216df8e96f3SDavid Woodhouse if (rii.mctime_ver > je32_to_cpu(latest_node->version)) { 12171da177e4SLinus Torvalds /* The times in the latest_node are actually older than 12181da177e4SLinus Torvalds mctime in the latest dirent. Cheat. */ 1219df8e96f3SDavid Woodhouse latest_node->ctime = latest_node->mtime = cpu_to_je32(rii.latest_mctime); 12201da177e4SLinus Torvalds } 12211da177e4SLinus Torvalds break; 12221da177e4SLinus Torvalds 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds case S_IFREG: 12251da177e4SLinus Torvalds /* If it was a regular file, truncate it to the latest node's isize */ 122661c4b237SDavid Woodhouse new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 122761c4b237SDavid Woodhouse if (new_size != je32_to_cpu(latest_node->isize)) { 122861c4b237SDavid Woodhouse JFFS2_WARNING("Truncating ino #%u to %d bytes failed because it only had %d bytes to start with!\n", 122961c4b237SDavid Woodhouse f->inocache->ino, je32_to_cpu(latest_node->isize), new_size); 123061c4b237SDavid Woodhouse latest_node->isize = cpu_to_je32(new_size); 123161c4b237SDavid Woodhouse } 12321da177e4SLinus Torvalds break; 12331da177e4SLinus Torvalds 12341da177e4SLinus Torvalds case S_IFLNK: 12351da177e4SLinus Torvalds /* Hack to work around broken isize in old symlink code. 12361da177e4SLinus Torvalds Remove this when dwmw2 comes to his senses and stops 12371da177e4SLinus Torvalds symlinks from being an entirely gratuitous special 12381da177e4SLinus Torvalds case. */ 12391da177e4SLinus Torvalds if (!je32_to_cpu(latest_node->isize)) 12401da177e4SLinus Torvalds latest_node->isize = latest_node->dsize; 124132f1a95dSArtem B. Bityuckiy 124232f1a95dSArtem B. Bityuckiy if (f->inocache->state != INO_STATE_CHECKING) { 124332f1a95dSArtem B. Bityuckiy /* Symlink's inode data is the target path. Read it and 12442b79adccSArtem B. Bityutskiy * keep in RAM to facilitate quick follow symlink 12452b79adccSArtem B. Bityutskiy * operation. */ 12462b79adccSArtem B. Bityutskiy f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); 12472b79adccSArtem B. Bityutskiy if (!f->target) { 1248e0d60137SArtem B. Bityutskiy JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize)); 124932f1a95dSArtem B. Bityuckiy up(&f->sem); 125032f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 125132f1a95dSArtem B. Bityuckiy return -ENOMEM; 125232f1a95dSArtem B. Bityuckiy } 125332f1a95dSArtem B. Bityuckiy 1254df8e96f3SDavid Woodhouse ret = jffs2_flash_read(c, ref_offset(rii.latest_ref) + sizeof(*latest_node), 12552b79adccSArtem B. Bityutskiy je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); 125632f1a95dSArtem B. Bityuckiy 125732f1a95dSArtem B. Bityuckiy if (ret || retlen != je32_to_cpu(latest_node->csize)) { 125832f1a95dSArtem B. Bityuckiy if (retlen != je32_to_cpu(latest_node->csize)) 125932f1a95dSArtem B. Bityuckiy ret = -EIO; 12602b79adccSArtem B. Bityutskiy kfree(f->target); 12612b79adccSArtem B. Bityutskiy f->target = NULL; 126232f1a95dSArtem B. Bityuckiy up(&f->sem); 126332f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 126432f1a95dSArtem B. Bityuckiy return -ret; 126532f1a95dSArtem B. Bityuckiy } 126632f1a95dSArtem B. Bityuckiy 12672b79adccSArtem B. Bityutskiy f->target[je32_to_cpu(latest_node->csize)] = '\0'; 1268733802d9SArtem B. Bityutskiy dbg_readinode("symlink's target '%s' cached\n", f->target); 126932f1a95dSArtem B. Bityuckiy } 127032f1a95dSArtem B. Bityuckiy 12711da177e4SLinus Torvalds /* fall through... */ 12721da177e4SLinus Torvalds 12731da177e4SLinus Torvalds case S_IFBLK: 12741da177e4SLinus Torvalds case S_IFCHR: 12751da177e4SLinus Torvalds /* Certain inode types should have only one data node, and it's 12761da177e4SLinus Torvalds kept as the metadata node */ 12771da177e4SLinus Torvalds if (f->metadata) { 1278e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n", 12791da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 12801da177e4SLinus Torvalds up(&f->sem); 12811da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12821da177e4SLinus Torvalds return -EIO; 12831da177e4SLinus Torvalds } 12841da177e4SLinus Torvalds if (!frag_first(&f->fragtree)) { 1285e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n", 12861da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 12871da177e4SLinus Torvalds up(&f->sem); 12881da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12891da177e4SLinus Torvalds return -EIO; 12901da177e4SLinus Torvalds } 12911da177e4SLinus Torvalds /* ASSERT: f->fraglist != NULL */ 12921da177e4SLinus Torvalds if (frag_next(frag_first(&f->fragtree))) { 1293e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n", 12941da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 12951da177e4SLinus Torvalds /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ 12961da177e4SLinus Torvalds up(&f->sem); 12971da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12981da177e4SLinus Torvalds return -EIO; 12991da177e4SLinus Torvalds } 13001da177e4SLinus Torvalds /* OK. We're happy */ 13011da177e4SLinus Torvalds f->metadata = frag_first(&f->fragtree)->node; 13021da177e4SLinus Torvalds jffs2_free_node_frag(frag_first(&f->fragtree)); 13031da177e4SLinus Torvalds f->fragtree = RB_ROOT; 13041da177e4SLinus Torvalds break; 13051da177e4SLinus Torvalds } 13061da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 13071da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 13081da177e4SLinus Torvalds 13091da177e4SLinus Torvalds return 0; 13101da177e4SLinus Torvalds } 13111da177e4SLinus Torvalds 1312f97117d1SArtem B. Bityutskiy /* Scan the list of all nodes present for this ino, build map of versions, etc. */ 1313f97117d1SArtem B. Bityutskiy int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 1314f97117d1SArtem B. Bityutskiy uint32_t ino, struct jffs2_raw_inode *latest_node) 1315f97117d1SArtem B. Bityutskiy { 1316733802d9SArtem B. Bityutskiy dbg_readinode("read inode #%u\n", ino); 1317f97117d1SArtem B. Bityutskiy 1318f97117d1SArtem B. Bityutskiy retry_inocache: 1319f97117d1SArtem B. Bityutskiy spin_lock(&c->inocache_lock); 1320f97117d1SArtem B. Bityutskiy f->inocache = jffs2_get_ino_cache(c, ino); 1321f97117d1SArtem B. Bityutskiy 1322f97117d1SArtem B. Bityutskiy if (f->inocache) { 1323f97117d1SArtem B. Bityutskiy /* Check its state. We may need to wait before we can use it */ 1324f97117d1SArtem B. Bityutskiy switch(f->inocache->state) { 1325f97117d1SArtem B. Bityutskiy case INO_STATE_UNCHECKED: 1326f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKEDABSENT: 1327f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 1328f97117d1SArtem B. Bityutskiy break; 1329f97117d1SArtem B. Bityutskiy 1330f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKING: 1331f97117d1SArtem B. Bityutskiy case INO_STATE_GC: 1332f97117d1SArtem B. Bityutskiy /* If it's in either of these states, we need 1333f97117d1SArtem B. Bityutskiy to wait for whoever's got it to finish and 1334f97117d1SArtem B. Bityutskiy put it back. */ 1335733802d9SArtem B. Bityutskiy dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state); 1336f97117d1SArtem B. Bityutskiy sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 1337f97117d1SArtem B. Bityutskiy goto retry_inocache; 1338f97117d1SArtem B. Bityutskiy 1339f97117d1SArtem B. Bityutskiy case INO_STATE_READING: 1340f97117d1SArtem B. Bityutskiy case INO_STATE_PRESENT: 1341f97117d1SArtem B. Bityutskiy /* Eep. This should never happen. It can 1342f97117d1SArtem B. Bityutskiy happen if Linux calls read_inode() again 1343f97117d1SArtem B. Bityutskiy before clear_inode() has finished though. */ 1344e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); 1345f97117d1SArtem B. Bityutskiy /* Fail. That's probably better than allowing it to succeed */ 1346f97117d1SArtem B. Bityutskiy f->inocache = NULL; 1347f97117d1SArtem B. Bityutskiy break; 1348f97117d1SArtem B. Bityutskiy 1349f97117d1SArtem B. Bityutskiy default: 1350f97117d1SArtem B. Bityutskiy BUG(); 1351f97117d1SArtem B. Bityutskiy } 1352f97117d1SArtem B. Bityutskiy } 1353f97117d1SArtem B. Bityutskiy spin_unlock(&c->inocache_lock); 1354f97117d1SArtem B. Bityutskiy 1355f97117d1SArtem B. Bityutskiy if (!f->inocache && ino == 1) { 1356f97117d1SArtem B. Bityutskiy /* Special case - no root inode on medium */ 1357f97117d1SArtem B. Bityutskiy f->inocache = jffs2_alloc_inode_cache(); 1358f97117d1SArtem B. Bityutskiy if (!f->inocache) { 1359e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot allocate inocache for root inode\n"); 1360f97117d1SArtem B. Bityutskiy return -ENOMEM; 1361f97117d1SArtem B. Bityutskiy } 1362733802d9SArtem B. Bityutskiy dbg_readinode("creating inocache for root inode\n"); 1363f97117d1SArtem B. Bityutskiy memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); 1364f97117d1SArtem B. Bityutskiy f->inocache->ino = f->inocache->nlink = 1; 1365f97117d1SArtem B. Bityutskiy f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 1366f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 1367f97117d1SArtem B. Bityutskiy jffs2_add_ino_cache(c, f->inocache); 1368f97117d1SArtem B. Bityutskiy } 1369f97117d1SArtem B. Bityutskiy if (!f->inocache) { 1370e0d60137SArtem B. Bityutskiy JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); 1371f97117d1SArtem B. Bityutskiy return -ENOENT; 1372f97117d1SArtem B. Bityutskiy } 1373f97117d1SArtem B. Bityutskiy 1374f97117d1SArtem B. Bityutskiy return jffs2_do_read_inode_internal(c, f, latest_node); 1375f97117d1SArtem B. Bityutskiy } 1376f97117d1SArtem B. Bityutskiy 1377f97117d1SArtem B. Bityutskiy int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 1378f97117d1SArtem B. Bityutskiy { 1379f97117d1SArtem B. Bityutskiy struct jffs2_raw_inode n; 13803d375d9eSYan Burman struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL); 1381f97117d1SArtem B. Bityutskiy int ret; 1382f97117d1SArtem B. Bityutskiy 1383f97117d1SArtem B. Bityutskiy if (!f) 1384f97117d1SArtem B. Bityutskiy return -ENOMEM; 1385f97117d1SArtem B. Bityutskiy 1386f97117d1SArtem B. Bityutskiy init_MUTEX_LOCKED(&f->sem); 1387f97117d1SArtem B. Bityutskiy f->inocache = ic; 1388f97117d1SArtem B. Bityutskiy 1389f97117d1SArtem B. Bityutskiy ret = jffs2_do_read_inode_internal(c, f, &n); 1390f97117d1SArtem B. Bityutskiy if (!ret) { 1391f97117d1SArtem B. Bityutskiy up(&f->sem); 1392f97117d1SArtem B. Bityutskiy jffs2_do_clear_inode(c, f); 1393f97117d1SArtem B. Bityutskiy } 1394f97117d1SArtem B. Bityutskiy kfree (f); 1395f97117d1SArtem B. Bityutskiy return ret; 1396f97117d1SArtem B. Bityutskiy } 1397f97117d1SArtem B. Bityutskiy 13981da177e4SLinus Torvalds void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) 13991da177e4SLinus Torvalds { 14001da177e4SLinus Torvalds struct jffs2_full_dirent *fd, *fds; 14011da177e4SLinus Torvalds int deleted; 14021da177e4SLinus Torvalds 1403c7afb0f9SKaiGai Kohei jffs2_clear_acl(f); 1404355ed4e1SKaiGai Kohei jffs2_xattr_delete_inode(c, f->inocache); 14051da177e4SLinus Torvalds down(&f->sem); 14061da177e4SLinus Torvalds deleted = f->inocache && !f->inocache->nlink; 14071da177e4SLinus Torvalds 140867e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 140967e345d1SDavid Woodhouse jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); 141067e345d1SDavid Woodhouse 14111da177e4SLinus Torvalds if (f->metadata) { 14121da177e4SLinus Torvalds if (deleted) 14131da177e4SLinus Torvalds jffs2_mark_node_obsolete(c, f->metadata->raw); 14141da177e4SLinus Torvalds jffs2_free_full_dnode(f->metadata); 14151da177e4SLinus Torvalds } 14161da177e4SLinus Torvalds 14171da177e4SLinus Torvalds jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 14181da177e4SLinus Torvalds 14192b79adccSArtem B. Bityutskiy if (f->target) { 14202b79adccSArtem B. Bityutskiy kfree(f->target); 14212b79adccSArtem B. Bityutskiy f->target = NULL; 142232f1a95dSArtem B. Bityuckiy } 14231da177e4SLinus Torvalds 14242b79adccSArtem B. Bityutskiy fds = f->dents; 14251da177e4SLinus Torvalds while(fds) { 14261da177e4SLinus Torvalds fd = fds; 14271da177e4SLinus Torvalds fds = fd->next; 14281da177e4SLinus Torvalds jffs2_free_full_dirent(fd); 14291da177e4SLinus Torvalds } 14301da177e4SLinus Torvalds 143167e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 14321da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 143367e345d1SDavid Woodhouse if (f->inocache->nodes == (void *)f->inocache) 143467e345d1SDavid Woodhouse jffs2_del_ino_cache(c, f->inocache); 143567e345d1SDavid Woodhouse } 14361da177e4SLinus Torvalds 14371da177e4SLinus Torvalds up(&f->sem); 14381da177e4SLinus Torvalds } 1439