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 125a528957SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 135a528957SJoe Perches 141da177e4SLinus Torvalds #include <linux/kernel.h> 15737b7661SAndrew Lunn #include <linux/sched.h> 161da177e4SLinus Torvalds #include <linux/slab.h> 171da177e4SLinus Torvalds #include <linux/fs.h> 181da177e4SLinus Torvalds #include <linux/crc32.h> 191da177e4SLinus Torvalds #include <linux/pagemap.h> 201da177e4SLinus Torvalds #include <linux/mtd/mtd.h> 211da177e4SLinus Torvalds #include <linux/compiler.h> 221da177e4SLinus Torvalds #include "nodelist.h" 231da177e4SLinus Torvalds 24f97117d1SArtem B. Bityutskiy /* 25df8e96f3SDavid Woodhouse * Check the data CRC of the node. 26df8e96f3SDavid Woodhouse * 27df8e96f3SDavid Woodhouse * Returns: 0 if the data CRC is correct; 28df8e96f3SDavid Woodhouse * 1 - if incorrect; 2925985edcSLucas De Marchi * error code if an error occurred. 30f97117d1SArtem B. Bityutskiy */ 31df8e96f3SDavid Woodhouse static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 321da177e4SLinus Torvalds { 33df8e96f3SDavid Woodhouse struct jffs2_raw_node_ref *ref = tn->fn->raw; 34df8e96f3SDavid Woodhouse int err = 0, pointed = 0; 35df8e96f3SDavid Woodhouse struct jffs2_eraseblock *jeb; 36df8e96f3SDavid Woodhouse unsigned char *buffer; 37df8e96f3SDavid Woodhouse uint32_t crc, ofs, len; 38df8e96f3SDavid Woodhouse size_t retlen; 391da177e4SLinus Torvalds 40df8e96f3SDavid Woodhouse BUG_ON(tn->csize == 0); 411da177e4SLinus Torvalds 42df8e96f3SDavid Woodhouse /* Calculate how many bytes were already checked */ 43df8e96f3SDavid Woodhouse ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); 4492525726SDavid Woodhouse len = tn->csize; 45df8e96f3SDavid Woodhouse 4692525726SDavid Woodhouse if (jffs2_is_writebuffered(c)) { 4792525726SDavid Woodhouse int adj = ofs % c->wbuf_pagesize; 4892525726SDavid Woodhouse if (likely(adj)) 4992525726SDavid Woodhouse adj = c->wbuf_pagesize - adj; 5092525726SDavid Woodhouse 5192525726SDavid Woodhouse if (adj >= tn->csize) { 52df8e96f3SDavid Woodhouse dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", 53df8e96f3SDavid Woodhouse ref_offset(ref), tn->csize, ofs); 54df8e96f3SDavid Woodhouse goto adj_acc; 55f97117d1SArtem B. Bityutskiy } 561da177e4SLinus Torvalds 5792525726SDavid Woodhouse ofs += adj; 5892525726SDavid Woodhouse len -= adj; 5992525726SDavid Woodhouse } 60df8e96f3SDavid Woodhouse 61df8e96f3SDavid 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", 62df8e96f3SDavid Woodhouse ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); 63df8e96f3SDavid Woodhouse 64df8e96f3SDavid Woodhouse #ifndef __ECOS 65df8e96f3SDavid Woodhouse /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), 66df8e96f3SDavid Woodhouse * adding and jffs2_flash_read_end() interface. */ 6710934478SArtem Bityutskiy err = mtd_point(c->mtd, ofs, len, &retlen, (void **)&buffer, NULL); 68c2056e1eSAlexey Korolev if (!err && retlen < len) { 69df8e96f3SDavid Woodhouse JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); 707219778aSArtem Bityutskiy mtd_unpoint(c->mtd, ofs, retlen); 7110934478SArtem Bityutskiy } else if (err) { 7210934478SArtem Bityutskiy if (err != -EOPNOTSUPP) 73df8e96f3SDavid Woodhouse JFFS2_WARNING("MTD point failed: error code %d.\n", err); 7410934478SArtem Bityutskiy } else 75df8e96f3SDavid Woodhouse pointed = 1; /* succefully pointed to device */ 76df8e96f3SDavid Woodhouse #endif 77df8e96f3SDavid Woodhouse 78df8e96f3SDavid Woodhouse if (!pointed) { 79df8e96f3SDavid Woodhouse buffer = kmalloc(len, GFP_KERNEL); 80df8e96f3SDavid Woodhouse if (unlikely(!buffer)) 81df8e96f3SDavid Woodhouse return -ENOMEM; 82df8e96f3SDavid Woodhouse 83df8e96f3SDavid Woodhouse /* TODO: this is very frequent pattern, make it a separate 84df8e96f3SDavid Woodhouse * routine */ 85df8e96f3SDavid Woodhouse err = jffs2_flash_read(c, ofs, len, &retlen, buffer); 86df8e96f3SDavid Woodhouse if (err) { 87df8e96f3SDavid Woodhouse JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); 88df8e96f3SDavid Woodhouse goto free_out; 89df8e96f3SDavid Woodhouse } 90df8e96f3SDavid Woodhouse 91df8e96f3SDavid Woodhouse if (retlen != len) { 92df8e96f3SDavid Woodhouse JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); 93df8e96f3SDavid Woodhouse err = -EIO; 94df8e96f3SDavid Woodhouse goto free_out; 95df8e96f3SDavid Woodhouse } 96df8e96f3SDavid Woodhouse } 97df8e96f3SDavid Woodhouse 98df8e96f3SDavid Woodhouse /* Continue calculating CRC */ 99df8e96f3SDavid Woodhouse crc = crc32(tn->partial_crc, buffer, len); 100df8e96f3SDavid Woodhouse if(!pointed) 101df8e96f3SDavid Woodhouse kfree(buffer); 102df8e96f3SDavid Woodhouse #ifndef __ECOS 103df8e96f3SDavid Woodhouse else 1047219778aSArtem Bityutskiy mtd_unpoint(c->mtd, ofs, len); 105df8e96f3SDavid Woodhouse #endif 106df8e96f3SDavid Woodhouse 107df8e96f3SDavid Woodhouse if (crc != tn->data_crc) { 108df8e96f3SDavid Woodhouse JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 109b2e25235SDavid Woodhouse ref_offset(ref), tn->data_crc, crc); 110df8e96f3SDavid Woodhouse return 1; 111df8e96f3SDavid Woodhouse } 112df8e96f3SDavid Woodhouse 113df8e96f3SDavid Woodhouse adj_acc: 114df8e96f3SDavid Woodhouse jeb = &c->blocks[ref->flash_offset / c->sector_size]; 115df8e96f3SDavid Woodhouse len = ref_totlen(c, jeb, ref); 116df8e96f3SDavid Woodhouse /* If it should be REF_NORMAL, it'll get marked as such when 117df8e96f3SDavid Woodhouse we build the fragtree, shortly. No need to worry about GC 118df8e96f3SDavid Woodhouse moving it while it's marked REF_PRISTINE -- GC won't happen 119df8e96f3SDavid Woodhouse till we've finished checking every inode anyway. */ 120df8e96f3SDavid Woodhouse ref->flash_offset |= REF_PRISTINE; 121df8e96f3SDavid Woodhouse /* 122df8e96f3SDavid Woodhouse * Mark the node as having been checked and fix the 123df8e96f3SDavid Woodhouse * accounting accordingly. 124df8e96f3SDavid Woodhouse */ 125df8e96f3SDavid Woodhouse spin_lock(&c->erase_completion_lock); 126df8e96f3SDavid Woodhouse jeb->used_size += len; 127df8e96f3SDavid Woodhouse jeb->unchecked_size -= len; 128df8e96f3SDavid Woodhouse c->used_size += len; 129df8e96f3SDavid Woodhouse c->unchecked_size -= len; 130df8e96f3SDavid Woodhouse jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 131df8e96f3SDavid Woodhouse spin_unlock(&c->erase_completion_lock); 132df8e96f3SDavid Woodhouse 133df8e96f3SDavid Woodhouse return 0; 134df8e96f3SDavid Woodhouse 135df8e96f3SDavid Woodhouse free_out: 136df8e96f3SDavid Woodhouse if(!pointed) 137df8e96f3SDavid Woodhouse kfree(buffer); 138df8e96f3SDavid Woodhouse #ifndef __ECOS 139df8e96f3SDavid Woodhouse else 1407219778aSArtem Bityutskiy mtd_unpoint(c->mtd, ofs, len); 141df8e96f3SDavid Woodhouse #endif 142df8e96f3SDavid Woodhouse return err; 143df8e96f3SDavid Woodhouse } 144df8e96f3SDavid Woodhouse 145df8e96f3SDavid Woodhouse /* 146df8e96f3SDavid Woodhouse * Helper function for jffs2_add_older_frag_to_fragtree(). 147df8e96f3SDavid Woodhouse * 148df8e96f3SDavid Woodhouse * Checks the node if we are in the checking stage. 149df8e96f3SDavid Woodhouse */ 150df8e96f3SDavid Woodhouse static int check_tn_node(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 151df8e96f3SDavid Woodhouse { 152df8e96f3SDavid Woodhouse int ret; 153df8e96f3SDavid Woodhouse 154df8e96f3SDavid Woodhouse BUG_ON(ref_obsolete(tn->fn->raw)); 155df8e96f3SDavid Woodhouse 156df8e96f3SDavid Woodhouse /* We only check the data CRC of unchecked nodes */ 157df8e96f3SDavid Woodhouse if (ref_flags(tn->fn->raw) != REF_UNCHECKED) 158df8e96f3SDavid Woodhouse return 0; 159df8e96f3SDavid Woodhouse 160df8e96f3SDavid Woodhouse dbg_readinode("check node %#04x-%#04x, phys offs %#08x\n", 161df8e96f3SDavid Woodhouse tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw)); 162df8e96f3SDavid Woodhouse 163df8e96f3SDavid Woodhouse ret = check_node_data(c, tn); 164df8e96f3SDavid Woodhouse if (unlikely(ret < 0)) { 165df8e96f3SDavid Woodhouse JFFS2_ERROR("check_node_data() returned error: %d.\n", 166df8e96f3SDavid Woodhouse ret); 167df8e96f3SDavid Woodhouse } else if (unlikely(ret > 0)) { 168df8e96f3SDavid Woodhouse dbg_readinode("CRC error, mark it obsolete.\n"); 169df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, tn->fn->raw); 170df8e96f3SDavid Woodhouse } 171df8e96f3SDavid Woodhouse 172df8e96f3SDavid Woodhouse return ret; 173df8e96f3SDavid Woodhouse } 174df8e96f3SDavid Woodhouse 175df8e96f3SDavid Woodhouse static struct jffs2_tmp_dnode_info *jffs2_lookup_tn(struct rb_root *tn_root, uint32_t offset) 176df8e96f3SDavid Woodhouse { 177df8e96f3SDavid Woodhouse struct rb_node *next; 178df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *tn = NULL; 179df8e96f3SDavid Woodhouse 180df8e96f3SDavid Woodhouse dbg_readinode("root %p, offset %d\n", tn_root, offset); 181df8e96f3SDavid Woodhouse 182df8e96f3SDavid Woodhouse next = tn_root->rb_node; 183df8e96f3SDavid Woodhouse 184df8e96f3SDavid Woodhouse while (next) { 185df8e96f3SDavid Woodhouse tn = rb_entry(next, struct jffs2_tmp_dnode_info, rb); 186df8e96f3SDavid Woodhouse 187df8e96f3SDavid Woodhouse if (tn->fn->ofs < offset) 188df8e96f3SDavid Woodhouse next = tn->rb.rb_right; 189df8e96f3SDavid Woodhouse else if (tn->fn->ofs >= offset) 190df8e96f3SDavid Woodhouse next = tn->rb.rb_left; 191df8e96f3SDavid Woodhouse else 192df8e96f3SDavid Woodhouse break; 193df8e96f3SDavid Woodhouse } 194df8e96f3SDavid Woodhouse 195df8e96f3SDavid Woodhouse return tn; 196df8e96f3SDavid Woodhouse } 197df8e96f3SDavid Woodhouse 198df8e96f3SDavid Woodhouse 199df8e96f3SDavid Woodhouse static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) 200df8e96f3SDavid Woodhouse { 201df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, tn->fn->raw); 202df8e96f3SDavid Woodhouse jffs2_free_full_dnode(tn->fn); 203df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(tn); 204df8e96f3SDavid Woodhouse } 205df8e96f3SDavid Woodhouse /* 206df8e96f3SDavid Woodhouse * This function is used when we read an inode. Data nodes arrive in 207df8e96f3SDavid Woodhouse * arbitrary order -- they may be older or newer than the nodes which 208df8e96f3SDavid Woodhouse * are already in the tree. Where overlaps occur, the older node can 209df8e96f3SDavid Woodhouse * be discarded as long as the newer passes the CRC check. We don't 210df8e96f3SDavid Woodhouse * bother to keep track of holes in this rbtree, and neither do we deal 211df8e96f3SDavid Woodhouse * with frags -- we can have multiple entries starting at the same 212df8e96f3SDavid Woodhouse * offset, and the one with the smallest length will come first in the 213df8e96f3SDavid Woodhouse * ordering. 214df8e96f3SDavid Woodhouse * 21514c6381eSDavid Woodhouse * Returns 0 if the node was handled (including marking it obsolete) 216df8e96f3SDavid Woodhouse * < 0 an if error occurred 217df8e96f3SDavid Woodhouse */ 218df8e96f3SDavid Woodhouse static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, 219df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii, 220df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *tn) 221df8e96f3SDavid Woodhouse { 222df8e96f3SDavid Woodhouse uint32_t fn_end = tn->fn->ofs + tn->fn->size; 2234c41bd0eSThomas Gleixner struct jffs2_tmp_dnode_info *this, *ptn; 224df8e96f3SDavid Woodhouse 225fcf3cafbSDavid Woodhouse dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); 226df8e96f3SDavid Woodhouse 227df8e96f3SDavid Woodhouse /* If a node has zero dsize, we only have to keep if it if it might be the 228df8e96f3SDavid Woodhouse node with highest version -- i.e. the one which will end up as f->metadata. 229df8e96f3SDavid Woodhouse Note that such nodes won't be REF_UNCHECKED since there are no data to 230df8e96f3SDavid Woodhouse check anyway. */ 231df8e96f3SDavid Woodhouse if (!tn->fn->size) { 232df8e96f3SDavid Woodhouse if (rii->mdata_tn) { 2330477d24eSDavid Woodhouse if (rii->mdata_tn->version < tn->version) { 234df8e96f3SDavid Woodhouse /* We had a candidate mdata node already */ 235df8e96f3SDavid Woodhouse dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version); 236df8e96f3SDavid Woodhouse jffs2_kill_tn(c, rii->mdata_tn); 2370477d24eSDavid Woodhouse } else { 2380477d24eSDavid Woodhouse dbg_readinode("kill new mdata with ver %d (older than existing %d\n", 2390477d24eSDavid Woodhouse tn->version, rii->mdata_tn->version); 2400477d24eSDavid Woodhouse jffs2_kill_tn(c, tn); 2410477d24eSDavid Woodhouse return 0; 2420477d24eSDavid Woodhouse } 243df8e96f3SDavid Woodhouse } 244df8e96f3SDavid Woodhouse rii->mdata_tn = tn; 245df8e96f3SDavid Woodhouse dbg_readinode("keep new mdata with ver %d\n", tn->version); 246df8e96f3SDavid Woodhouse return 0; 247df8e96f3SDavid Woodhouse } 248df8e96f3SDavid Woodhouse 249df8e96f3SDavid Woodhouse /* Find the earliest node which _may_ be relevant to this one */ 250df8e96f3SDavid Woodhouse this = jffs2_lookup_tn(&rii->tn_root, tn->fn->ofs); 2511c979645SDavid Woodhouse if (this) { 252df8e96f3SDavid Woodhouse /* If the node is coincident with another at a lower address, 253df8e96f3SDavid Woodhouse back up until the other node is found. It may be relevant */ 2544c41bd0eSThomas Gleixner while (this->overlapped) { 2554c41bd0eSThomas Gleixner ptn = tn_prev(this); 2564c41bd0eSThomas Gleixner if (!ptn) { 2574c41bd0eSThomas Gleixner /* 2584c41bd0eSThomas Gleixner * We killed a node which set the overlapped 2594c41bd0eSThomas Gleixner * flags during the scan. Fix it up. 2604c41bd0eSThomas Gleixner */ 2614c41bd0eSThomas Gleixner this->overlapped = 0; 2624c41bd0eSThomas Gleixner break; 2634c41bd0eSThomas Gleixner } 2644c41bd0eSThomas Gleixner this = ptn; 2654c41bd0eSThomas Gleixner } 266df8e96f3SDavid Woodhouse dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); 2671c979645SDavid Woodhouse } 268df8e96f3SDavid Woodhouse 269df8e96f3SDavid Woodhouse while (this) { 270df8e96f3SDavid Woodhouse if (this->fn->ofs > fn_end) 271df8e96f3SDavid Woodhouse break; 272df8e96f3SDavid Woodhouse dbg_readinode("Ponder this ver %d, 0x%x-0x%x\n", 273df8e96f3SDavid Woodhouse this->version, this->fn->ofs, this->fn->size); 274df8e96f3SDavid Woodhouse 275df8e96f3SDavid Woodhouse if (this->version == tn->version) { 276df8e96f3SDavid Woodhouse /* Version number collision means REF_PRISTINE GC. Accept either of them 277df8e96f3SDavid Woodhouse as long as the CRC is correct. Check the one we have already... */ 278df8e96f3SDavid Woodhouse if (!check_tn_node(c, this)) { 279df8e96f3SDavid Woodhouse /* The one we already had was OK. Keep it and throw away the new one */ 280df8e96f3SDavid Woodhouse dbg_readinode("Like old node. Throw away new\n"); 281df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 282df8e96f3SDavid Woodhouse return 0; 283df8e96f3SDavid Woodhouse } else { 284df8e96f3SDavid Woodhouse /* Who cares if the new one is good; keep it for now anyway. */ 285df8e96f3SDavid Woodhouse dbg_readinode("Like new node. Throw away old\n"); 286fcf3cafbSDavid Woodhouse rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); 287fcf3cafbSDavid Woodhouse jffs2_kill_tn(c, this); 288fcf3cafbSDavid Woodhouse /* Same overlapping from in front and behind */ 289fcf3cafbSDavid Woodhouse return 0; 290df8e96f3SDavid Woodhouse } 291df8e96f3SDavid Woodhouse } 292df8e96f3SDavid Woodhouse if (this->version < tn->version && 293df8e96f3SDavid Woodhouse this->fn->ofs >= tn->fn->ofs && 294df8e96f3SDavid Woodhouse this->fn->ofs + this->fn->size <= fn_end) { 295df8e96f3SDavid Woodhouse /* New node entirely overlaps 'this' */ 296df8e96f3SDavid Woodhouse if (check_tn_node(c, tn)) { 297df8e96f3SDavid Woodhouse dbg_readinode("new node bad CRC\n"); 298df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 299df8e96f3SDavid Woodhouse return 0; 300df8e96f3SDavid Woodhouse } 301fcf3cafbSDavid Woodhouse /* ... and is good. Kill 'this' and any subsequent nodes which are also overlapped */ 3021c979645SDavid Woodhouse while (this && this->fn->ofs + this->fn->size <= fn_end) { 303df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *next = tn_next(this); 304df8e96f3SDavid Woodhouse if (this->version < tn->version) { 305df8e96f3SDavid Woodhouse tn_erase(this, &rii->tn_root); 306df8e96f3SDavid Woodhouse dbg_readinode("Kill overlapped ver %d, 0x%x-0x%x\n", 307df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 308df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 309df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 310df8e96f3SDavid Woodhouse } 311df8e96f3SDavid Woodhouse this = next; 312df8e96f3SDavid Woodhouse } 313fcf3cafbSDavid Woodhouse dbg_readinode("Done killing overlapped nodes\n"); 3141c979645SDavid Woodhouse continue; 315df8e96f3SDavid Woodhouse } 316df8e96f3SDavid Woodhouse if (this->version > tn->version && 317df8e96f3SDavid Woodhouse this->fn->ofs <= tn->fn->ofs && 318df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size >= fn_end) { 319df8e96f3SDavid Woodhouse /* New node entirely overlapped by 'this' */ 320df8e96f3SDavid Woodhouse if (!check_tn_node(c, this)) { 321df8e96f3SDavid Woodhouse dbg_readinode("Good CRC on old node. Kill new\n"); 322df8e96f3SDavid Woodhouse jffs2_kill_tn(c, tn); 323df8e96f3SDavid Woodhouse return 0; 324df8e96f3SDavid Woodhouse } 325df8e96f3SDavid Woodhouse /* ... but 'this' was bad. Replace it... */ 326df8e96f3SDavid Woodhouse dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); 327fcf3cafbSDavid Woodhouse tn_erase(this, &rii->tn_root); 328df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 329fcf3cafbSDavid Woodhouse break; 330df8e96f3SDavid Woodhouse } 331df8e96f3SDavid Woodhouse 332df8e96f3SDavid Woodhouse this = tn_next(this); 333df8e96f3SDavid Woodhouse } 33496dd8d25SDavid Woodhouse 335df8e96f3SDavid Woodhouse /* We neither completely obsoleted nor were completely 33696dd8d25SDavid Woodhouse obsoleted by an earlier node. Insert into the tree */ 337df8e96f3SDavid Woodhouse { 33896dd8d25SDavid Woodhouse struct rb_node *parent; 33996dd8d25SDavid Woodhouse struct rb_node **link = &rii->tn_root.rb_node; 3401c979645SDavid Woodhouse struct jffs2_tmp_dnode_info *insert_point = NULL; 341df8e96f3SDavid Woodhouse 342df8e96f3SDavid Woodhouse while (*link) { 343df8e96f3SDavid Woodhouse parent = *link; 344df8e96f3SDavid Woodhouse insert_point = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 345df8e96f3SDavid Woodhouse if (tn->fn->ofs > insert_point->fn->ofs) 346df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_right; 347df8e96f3SDavid Woodhouse else if (tn->fn->ofs < insert_point->fn->ofs || 348df8e96f3SDavid Woodhouse tn->fn->size < insert_point->fn->size) 349df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_left; 350df8e96f3SDavid Woodhouse else 351df8e96f3SDavid Woodhouse link = &insert_point->rb.rb_right; 352df8e96f3SDavid Woodhouse } 353df8e96f3SDavid Woodhouse rb_link_node(&tn->rb, &insert_point->rb, link); 354df8e96f3SDavid Woodhouse rb_insert_color(&tn->rb, &rii->tn_root); 355df8e96f3SDavid Woodhouse } 3561123e2a8SDavid Woodhouse 357df8e96f3SDavid Woodhouse /* If there's anything behind that overlaps us, note it */ 358df8e96f3SDavid Woodhouse this = tn_prev(tn); 359df8e96f3SDavid Woodhouse if (this) { 360df8e96f3SDavid Woodhouse while (1) { 361df8e96f3SDavid Woodhouse if (this->fn->ofs + this->fn->size > tn->fn->ofs) { 362df8e96f3SDavid Woodhouse dbg_readinode("Node is overlapped by %p (v %d, 0x%x-0x%x)\n", 363df8e96f3SDavid Woodhouse this, this->version, this->fn->ofs, 364df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 365df8e96f3SDavid Woodhouse tn->overlapped = 1; 366df8e96f3SDavid Woodhouse break; 367df8e96f3SDavid Woodhouse } 368df8e96f3SDavid Woodhouse if (!this->overlapped) 369df8e96f3SDavid Woodhouse break; 3704c41bd0eSThomas Gleixner 3714c41bd0eSThomas Gleixner ptn = tn_prev(this); 3724c41bd0eSThomas Gleixner if (!ptn) { 3734c41bd0eSThomas Gleixner /* 3744c41bd0eSThomas Gleixner * We killed a node which set the overlapped 3754c41bd0eSThomas Gleixner * flags during the scan. Fix it up. 3764c41bd0eSThomas Gleixner */ 3774c41bd0eSThomas Gleixner this->overlapped = 0; 3784c41bd0eSThomas Gleixner break; 3794c41bd0eSThomas Gleixner } 3804c41bd0eSThomas Gleixner this = ptn; 381df8e96f3SDavid Woodhouse } 382df8e96f3SDavid Woodhouse } 383df8e96f3SDavid Woodhouse 384df8e96f3SDavid Woodhouse /* If the new node overlaps anything ahead, note it */ 385df8e96f3SDavid Woodhouse this = tn_next(tn); 386df8e96f3SDavid Woodhouse while (this && this->fn->ofs < fn_end) { 387df8e96f3SDavid Woodhouse this->overlapped = 1; 388df8e96f3SDavid Woodhouse dbg_readinode("Node ver %d, 0x%x-0x%x is overlapped\n", 389df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 390df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 391df8e96f3SDavid Woodhouse this = tn_next(this); 392df8e96f3SDavid Woodhouse } 393df8e96f3SDavid Woodhouse return 0; 394df8e96f3SDavid Woodhouse } 395df8e96f3SDavid Woodhouse 396df8e96f3SDavid Woodhouse /* Trivial function to remove the last node in the tree. Which by definition 397bf7ad8eeSMichel Lespinasse has no right-hand child — so can be removed just by making its left-hand 398bf7ad8eeSMichel Lespinasse child (if any) take its place under its parent. Since this is only done 399bf7ad8eeSMichel Lespinasse when we're consuming the whole tree, there's no need to use rb_erase() 400bf7ad8eeSMichel Lespinasse and let it worry about adjusting colours and balancing the tree. That 401bf7ad8eeSMichel Lespinasse would just be a waste of time. */ 402df8e96f3SDavid Woodhouse static void eat_last(struct rb_root *root, struct rb_node *node) 403df8e96f3SDavid Woodhouse { 404df8e96f3SDavid Woodhouse struct rb_node *parent = rb_parent(node); 405df8e96f3SDavid Woodhouse struct rb_node **link; 406df8e96f3SDavid Woodhouse 407df8e96f3SDavid Woodhouse /* LAST! */ 408df8e96f3SDavid Woodhouse BUG_ON(node->rb_right); 409df8e96f3SDavid Woodhouse 410df8e96f3SDavid Woodhouse if (!parent) 411df8e96f3SDavid Woodhouse link = &root->rb_node; 412df8e96f3SDavid Woodhouse else if (node == parent->rb_left) 413df8e96f3SDavid Woodhouse link = &parent->rb_left; 414df8e96f3SDavid Woodhouse else 415df8e96f3SDavid Woodhouse link = &parent->rb_right; 416df8e96f3SDavid Woodhouse 417df8e96f3SDavid Woodhouse *link = node->rb_left; 418df8e96f3SDavid Woodhouse if (node->rb_left) 419bf7ad8eeSMichel Lespinasse node->rb_left->__rb_parent_color = node->__rb_parent_color; 420df8e96f3SDavid Woodhouse } 421df8e96f3SDavid Woodhouse 422bf7ad8eeSMichel Lespinasse /* We put the version tree in reverse order, so we can use the same eat_last() 423bf7ad8eeSMichel Lespinasse function that we use to consume the tmpnode tree (tn_root). */ 424df8e96f3SDavid Woodhouse static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn) 425df8e96f3SDavid Woodhouse { 426df8e96f3SDavid Woodhouse struct rb_node **link = &ver_root->rb_node; 427df8e96f3SDavid Woodhouse struct rb_node *parent = NULL; 428df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *this_tn; 429df8e96f3SDavid Woodhouse 430df8e96f3SDavid Woodhouse while (*link) { 431df8e96f3SDavid Woodhouse parent = *link; 432df8e96f3SDavid Woodhouse this_tn = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 433df8e96f3SDavid Woodhouse 434df8e96f3SDavid Woodhouse if (tn->version > this_tn->version) 435df8e96f3SDavid Woodhouse link = &parent->rb_left; 436df8e96f3SDavid Woodhouse else 437df8e96f3SDavid Woodhouse link = &parent->rb_right; 438df8e96f3SDavid Woodhouse } 439df8e96f3SDavid Woodhouse dbg_readinode("Link new node at %p (root is %p)\n", link, ver_root); 440df8e96f3SDavid Woodhouse rb_link_node(&tn->rb, parent, link); 441df8e96f3SDavid Woodhouse rb_insert_color(&tn->rb, ver_root); 442df8e96f3SDavid Woodhouse } 443df8e96f3SDavid Woodhouse 444df8e96f3SDavid Woodhouse /* Build final, normal fragtree from tn tree. It doesn't matter which order 445df8e96f3SDavid Woodhouse we add nodes to the real fragtree, as long as they don't overlap. And 446df8e96f3SDavid Woodhouse having thrown away the majority of overlapped nodes as we went, there 447df8e96f3SDavid Woodhouse really shouldn't be many sets of nodes which do overlap. If we start at 448df8e96f3SDavid Woodhouse the end, we can use the overlap markers -- we can just eat nodes which 449df8e96f3SDavid Woodhouse aren't overlapped, and when we encounter nodes which _do_ overlap we 450df8e96f3SDavid Woodhouse sort them all into a temporary tree in version order before replaying them. */ 451df8e96f3SDavid Woodhouse static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, 452df8e96f3SDavid Woodhouse struct jffs2_inode_info *f, 453df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 454df8e96f3SDavid Woodhouse { 455df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *pen, *last, *this; 456df8e96f3SDavid Woodhouse struct rb_root ver_root = RB_ROOT; 457df8e96f3SDavid Woodhouse uint32_t high_ver = 0; 458df8e96f3SDavid Woodhouse 459df8e96f3SDavid Woodhouse if (rii->mdata_tn) { 460df8e96f3SDavid Woodhouse dbg_readinode("potential mdata is ver %d at %p\n", rii->mdata_tn->version, rii->mdata_tn); 461df8e96f3SDavid Woodhouse high_ver = rii->mdata_tn->version; 462df8e96f3SDavid Woodhouse rii->latest_ref = rii->mdata_tn->fn->raw; 463df8e96f3SDavid Woodhouse } 464df8e96f3SDavid Woodhouse #ifdef JFFS2_DBG_READINODE_MESSAGES 465df8e96f3SDavid Woodhouse this = tn_last(&rii->tn_root); 466df8e96f3SDavid Woodhouse while (this) { 467df8e96f3SDavid Woodhouse dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs, 468df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size, this->overlapped); 469df8e96f3SDavid Woodhouse this = tn_prev(this); 470df8e96f3SDavid Woodhouse } 471df8e96f3SDavid Woodhouse #endif 472df8e96f3SDavid Woodhouse pen = tn_last(&rii->tn_root); 473df8e96f3SDavid Woodhouse while ((last = pen)) { 474df8e96f3SDavid Woodhouse pen = tn_prev(last); 475df8e96f3SDavid Woodhouse 476df8e96f3SDavid Woodhouse eat_last(&rii->tn_root, &last->rb); 477df8e96f3SDavid Woodhouse ver_insert(&ver_root, last); 478df8e96f3SDavid Woodhouse 4794c41bd0eSThomas Gleixner if (unlikely(last->overlapped)) { 4804c41bd0eSThomas Gleixner if (pen) 481df8e96f3SDavid Woodhouse continue; 4824c41bd0eSThomas Gleixner /* 4834c41bd0eSThomas Gleixner * We killed a node which set the overlapped 4844c41bd0eSThomas Gleixner * flags during the scan. Fix it up. 4854c41bd0eSThomas Gleixner */ 4864c41bd0eSThomas Gleixner last->overlapped = 0; 4874c41bd0eSThomas Gleixner } 488df8e96f3SDavid Woodhouse 489df8e96f3SDavid Woodhouse /* Now we have a bunch of nodes in reverse version 490df8e96f3SDavid Woodhouse order, in the tree at ver_root. Most of the time, 491df8e96f3SDavid Woodhouse there'll actually be only one node in the 'tree', 492df8e96f3SDavid Woodhouse in fact. */ 493df8e96f3SDavid Woodhouse this = tn_last(&ver_root); 494df8e96f3SDavid Woodhouse 495df8e96f3SDavid Woodhouse while (this) { 496df8e96f3SDavid Woodhouse struct jffs2_tmp_dnode_info *vers_next; 497df8e96f3SDavid Woodhouse int ret; 498df8e96f3SDavid Woodhouse vers_next = tn_prev(this); 499df8e96f3SDavid Woodhouse eat_last(&ver_root, &this->rb); 500df8e96f3SDavid Woodhouse if (check_tn_node(c, this)) { 5011123e2a8SDavid Woodhouse dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n", 502df8e96f3SDavid Woodhouse this->version, this->fn->ofs, 503df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size); 504df8e96f3SDavid Woodhouse jffs2_kill_tn(c, this); 505df8e96f3SDavid Woodhouse } else { 506df8e96f3SDavid Woodhouse if (this->version > high_ver) { 507df8e96f3SDavid Woodhouse /* Note that this is different from the other 508df8e96f3SDavid Woodhouse highest_version, because this one is only 509df8e96f3SDavid Woodhouse counting _valid_ nodes which could give the 510df8e96f3SDavid Woodhouse latest inode metadata */ 511df8e96f3SDavid Woodhouse high_ver = this->version; 512df8e96f3SDavid Woodhouse rii->latest_ref = this->fn->raw; 513df8e96f3SDavid Woodhouse } 5141123e2a8SDavid Woodhouse dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n", 515df8e96f3SDavid Woodhouse this, this->version, this->fn->ofs, 516df8e96f3SDavid Woodhouse this->fn->ofs+this->fn->size, this->overlapped); 517df8e96f3SDavid Woodhouse 518df8e96f3SDavid Woodhouse ret = jffs2_add_full_dnode_to_inode(c, f, this->fn); 519df8e96f3SDavid Woodhouse if (ret) { 520df8e96f3SDavid Woodhouse /* Free the nodes in vers_root; let the caller 521df8e96f3SDavid Woodhouse deal with the rest */ 522df8e96f3SDavid Woodhouse JFFS2_ERROR("Add node to tree failed %d\n", ret); 523df8e96f3SDavid Woodhouse while (1) { 524df8e96f3SDavid Woodhouse vers_next = tn_prev(this); 525df8e96f3SDavid Woodhouse if (check_tn_node(c, this)) 526df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, this->fn->raw); 527df8e96f3SDavid Woodhouse jffs2_free_full_dnode(this->fn); 528df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(this); 529df8e96f3SDavid Woodhouse this = vers_next; 530df8e96f3SDavid Woodhouse if (!this) 531df8e96f3SDavid Woodhouse break; 532df8e96f3SDavid Woodhouse eat_last(&ver_root, &vers_next->rb); 533df8e96f3SDavid Woodhouse } 534df8e96f3SDavid Woodhouse return ret; 535df8e96f3SDavid Woodhouse } 536df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(this); 537df8e96f3SDavid Woodhouse } 538df8e96f3SDavid Woodhouse this = vers_next; 539df8e96f3SDavid Woodhouse } 540df8e96f3SDavid Woodhouse } 541df8e96f3SDavid Woodhouse return 0; 542f97117d1SArtem B. Bityutskiy } 543f97117d1SArtem B. Bityutskiy 544f97117d1SArtem B. Bityutskiy static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) 545f97117d1SArtem B. Bityutskiy { 546e8bbeeb7SCody P Schafer struct jffs2_tmp_dnode_info *tn, *next; 547f97117d1SArtem B. Bityutskiy 548e8bbeeb7SCody P Schafer rbtree_postorder_for_each_entry_safe(tn, next, list, rb) { 549f97117d1SArtem B. Bityutskiy jffs2_free_full_dnode(tn->fn); 550f97117d1SArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 551f97117d1SArtem B. Bityutskiy } 552e8bbeeb7SCody P Schafer 553bcc54e2aSVenkatesh Pallipadi *list = RB_ROOT; 554f97117d1SArtem B. Bityutskiy } 5551da177e4SLinus Torvalds 556f97117d1SArtem B. Bityutskiy static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 557f97117d1SArtem B. Bityutskiy { 558f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *next; 559f97117d1SArtem B. Bityutskiy 560f97117d1SArtem B. Bityutskiy while (fd) { 561f97117d1SArtem B. Bityutskiy next = fd->next; 562f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 563f97117d1SArtem B. Bityutskiy fd = next; 564f97117d1SArtem B. Bityutskiy } 565f97117d1SArtem B. Bityutskiy } 566f97117d1SArtem B. Bityutskiy 567f97117d1SArtem B. Bityutskiy /* Returns first valid node after 'ref'. May return 'ref' */ 568f97117d1SArtem B. Bityutskiy static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref) 569f97117d1SArtem B. Bityutskiy { 570f97117d1SArtem B. Bityutskiy while (ref && ref->next_in_ino) { 571f97117d1SArtem B. Bityutskiy if (!ref_obsolete(ref)) 572f97117d1SArtem B. Bityutskiy return ref; 573733802d9SArtem B. Bityutskiy dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)); 574f97117d1SArtem B. Bityutskiy ref = ref->next_in_ino; 575f97117d1SArtem B. Bityutskiy } 576f97117d1SArtem B. Bityutskiy return NULL; 577f97117d1SArtem B. Bityutskiy } 578f97117d1SArtem B. Bityutskiy 579f97117d1SArtem B. Bityutskiy /* 580f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 581f97117d1SArtem B. Bityutskiy * It is called every time an directory entry node is found. 582f97117d1SArtem B. Bityutskiy * 58314c6381eSDavid Woodhouse * Returns: 0 on success; 584f97117d1SArtem B. Bityutskiy * negative error code on failure. 585f97117d1SArtem B. Bityutskiy */ 5861e0da3cbSArtem B. Bityutskiy static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 587df8e96f3SDavid Woodhouse struct jffs2_raw_dirent *rd, size_t read, 588df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 589f97117d1SArtem B. Bityutskiy { 590f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *fd; 5911046d880SDavid Woodhouse uint32_t crc; 592f97117d1SArtem B. Bityutskiy 593f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 594f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 595f97117d1SArtem B. Bityutskiy 5961046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 5971046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 5981046d880SDavid Woodhouse JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", 5991046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 600df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 601df8e96f3SDavid Woodhouse return 0; 6021046d880SDavid Woodhouse } 6031046d880SDavid Woodhouse 6041046d880SDavid Woodhouse /* If we've never checked the CRCs on this node, check them now */ 6051046d880SDavid Woodhouse if (ref_flags(ref) == REF_UNCHECKED) { 6061046d880SDavid Woodhouse struct jffs2_eraseblock *jeb; 6071046d880SDavid Woodhouse int len; 6081046d880SDavid Woodhouse 609f97117d1SArtem B. Bityutskiy /* Sanity check */ 610f97117d1SArtem B. Bityutskiy if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 611e0d60137SArtem B. Bityutskiy JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 612f97117d1SArtem B. Bityutskiy ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 613df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 614df8e96f3SDavid Woodhouse return 0; 615f97117d1SArtem B. Bityutskiy } 616f97117d1SArtem B. Bityutskiy 6171046d880SDavid Woodhouse jeb = &c->blocks[ref->flash_offset / c->sector_size]; 6181046d880SDavid Woodhouse len = ref_totlen(c, jeb, ref); 6191046d880SDavid Woodhouse 6201046d880SDavid Woodhouse spin_lock(&c->erase_completion_lock); 6211046d880SDavid Woodhouse jeb->used_size += len; 6221046d880SDavid Woodhouse jeb->unchecked_size -= len; 6231046d880SDavid Woodhouse c->used_size += len; 6241046d880SDavid Woodhouse c->unchecked_size -= len; 62543dfa07fSDavid Woodhouse ref->flash_offset = ref_offset(ref) | dirent_node_state(rd); 6261046d880SDavid Woodhouse spin_unlock(&c->erase_completion_lock); 6271046d880SDavid Woodhouse } 6281046d880SDavid Woodhouse 629f97117d1SArtem B. Bityutskiy fd = jffs2_alloc_full_dirent(rd->nsize + 1); 630f97117d1SArtem B. Bityutskiy if (unlikely(!fd)) 631f97117d1SArtem B. Bityutskiy return -ENOMEM; 632f97117d1SArtem B. Bityutskiy 633f97117d1SArtem B. Bityutskiy fd->raw = ref; 634f97117d1SArtem B. Bityutskiy fd->version = je32_to_cpu(rd->version); 635f97117d1SArtem B. Bityutskiy fd->ino = je32_to_cpu(rd->ino); 636f97117d1SArtem B. Bityutskiy fd->type = rd->type; 637f97117d1SArtem B. Bityutskiy 638df8e96f3SDavid Woodhouse if (fd->version > rii->highest_version) 639df8e96f3SDavid Woodhouse rii->highest_version = fd->version; 640df8e96f3SDavid Woodhouse 641f97117d1SArtem B. Bityutskiy /* Pick out the mctime of the latest dirent */ 642df8e96f3SDavid Woodhouse if(fd->version > rii->mctime_ver && je32_to_cpu(rd->mctime)) { 643df8e96f3SDavid Woodhouse rii->mctime_ver = fd->version; 644df8e96f3SDavid Woodhouse rii->latest_mctime = je32_to_cpu(rd->mctime); 645f97117d1SArtem B. Bityutskiy } 646f97117d1SArtem B. Bityutskiy 647f97117d1SArtem B. Bityutskiy /* 648f97117d1SArtem B. Bityutskiy * Copy as much of the name as possible from the raw 649f97117d1SArtem B. Bityutskiy * dirent we've already read from the flash. 650f97117d1SArtem B. Bityutskiy */ 651f97117d1SArtem B. Bityutskiy if (read > sizeof(*rd)) 652f97117d1SArtem B. Bityutskiy memcpy(&fd->name[0], &rd->name[0], 653f97117d1SArtem B. Bityutskiy min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); 654f97117d1SArtem B. Bityutskiy 655f97117d1SArtem B. Bityutskiy /* Do we need to copy any more of the name directly from the flash? */ 656f97117d1SArtem B. Bityutskiy if (rd->nsize + sizeof(*rd) > read) { 657f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 658f97117d1SArtem B. Bityutskiy int err; 659f97117d1SArtem B. Bityutskiy int already = read - sizeof(*rd); 660f97117d1SArtem B. Bityutskiy 661f97117d1SArtem B. Bityutskiy err = jffs2_flash_read(c, (ref_offset(ref)) + read, 662f97117d1SArtem B. Bityutskiy rd->nsize - already, &read, &fd->name[already]); 663f97117d1SArtem B. Bityutskiy if (unlikely(read != rd->nsize - already) && likely(!err)) 664f97117d1SArtem B. Bityutskiy return -EIO; 665f97117d1SArtem B. Bityutskiy 666f97117d1SArtem B. Bityutskiy if (unlikely(err)) { 667e0d60137SArtem B. Bityutskiy JFFS2_ERROR("read remainder of name: error %d\n", err); 668f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 669f97117d1SArtem B. Bityutskiy return -EIO; 670f97117d1SArtem B. Bityutskiy } 671f97117d1SArtem B. Bityutskiy } 672f97117d1SArtem B. Bityutskiy 673f97117d1SArtem B. Bityutskiy fd->nhash = full_name_hash(fd->name, rd->nsize); 674f97117d1SArtem B. Bityutskiy fd->next = NULL; 675f97117d1SArtem B. Bityutskiy fd->name[rd->nsize] = '\0'; 676f97117d1SArtem B. Bityutskiy 677f97117d1SArtem B. Bityutskiy /* 678f97117d1SArtem B. Bityutskiy * Wheee. We now have a complete jffs2_full_dirent structure, with 679f97117d1SArtem B. Bityutskiy * the name in it and everything. Link it into the list 680f97117d1SArtem B. Bityutskiy */ 681df8e96f3SDavid Woodhouse jffs2_add_fd_to_list(c, fd, &rii->fds); 682f97117d1SArtem B. Bityutskiy 683f97117d1SArtem B. Bityutskiy return 0; 684f97117d1SArtem B. Bityutskiy } 685f97117d1SArtem B. Bityutskiy 686f97117d1SArtem B. Bityutskiy /* 687f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 688f97117d1SArtem B. Bityutskiy * It is called every time an inode node is found. 689f97117d1SArtem B. Bityutskiy * 69014c6381eSDavid Woodhouse * Returns: 0 on success (possibly after marking a bad node obsolete); 691f97117d1SArtem B. Bityutskiy * negative error code on failure. 692f97117d1SArtem B. Bityutskiy */ 6931e0da3cbSArtem B. Bityutskiy static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 694df8e96f3SDavid Woodhouse struct jffs2_raw_inode *rd, int rdlen, 695df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 696f97117d1SArtem B. Bityutskiy { 697f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 6981e0da3cbSArtem B. Bityutskiy uint32_t len, csize; 69914c6381eSDavid Woodhouse int ret = 0; 7001046d880SDavid Woodhouse uint32_t crc; 701f97117d1SArtem B. Bityutskiy 702f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 703f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 704f97117d1SArtem B. Bityutskiy 7051046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 7061046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 7071046d880SDavid Woodhouse JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", 7081046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 709df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 710df8e96f3SDavid Woodhouse return 0; 7111046d880SDavid Woodhouse } 7121046d880SDavid Woodhouse 7131e0da3cbSArtem B. Bityutskiy tn = jffs2_alloc_tmp_dnode_info(); 7141e0da3cbSArtem B. Bityutskiy if (!tn) { 715fb6a82c9SRandy Dunlap JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); 7161e0da3cbSArtem B. Bityutskiy return -ENOMEM; 7171e0da3cbSArtem B. Bityutskiy } 7181e0da3cbSArtem B. Bityutskiy 7191e0da3cbSArtem B. Bityutskiy tn->partial_crc = 0; 7201e0da3cbSArtem B. Bityutskiy csize = je32_to_cpu(rd->csize); 7211e0da3cbSArtem B. Bityutskiy 722f97117d1SArtem B. Bityutskiy /* If we've never checked the CRCs on this node, check them now */ 723f97117d1SArtem B. Bityutskiy if (ref_flags(ref) == REF_UNCHECKED) { 724f97117d1SArtem B. Bityutskiy 725f97117d1SArtem B. Bityutskiy /* Sanity checks */ 726f97117d1SArtem B. Bityutskiy if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 727f97117d1SArtem B. Bityutskiy unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 728e0d60137SArtem B. Bityutskiy JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); 729737b7661SAndrew Lunn jffs2_dbg_dump_node(c, ref_offset(ref)); 73014c6381eSDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 7311e0da3cbSArtem B. Bityutskiy goto free_out; 732f97117d1SArtem B. Bityutskiy } 733f97117d1SArtem B. Bityutskiy 7341e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c) && csize != 0) { 7351e0da3cbSArtem B. Bityutskiy /* At this point we are supposed to check the data CRC 7361e0da3cbSArtem B. Bityutskiy * of our unchecked node. But thus far, we do not 7371e0da3cbSArtem B. Bityutskiy * know whether the node is valid or obsolete. To 7381e0da3cbSArtem B. Bityutskiy * figure this out, we need to walk all the nodes of 7391e0da3cbSArtem B. Bityutskiy * the inode and build the inode fragtree. We don't 7401e0da3cbSArtem B. Bityutskiy * want to spend time checking data of nodes which may 7411e0da3cbSArtem B. Bityutskiy * later be found to be obsolete. So we put off the full 7421e0da3cbSArtem B. Bityutskiy * data CRC checking until we have read all the inode 7431e0da3cbSArtem B. Bityutskiy * nodes and have started building the fragtree. 7441e0da3cbSArtem B. Bityutskiy * 7451e0da3cbSArtem B. Bityutskiy * The fragtree is being built starting with nodes 7461e0da3cbSArtem B. Bityutskiy * having the highest version number, so we'll be able 7471e0da3cbSArtem B. Bityutskiy * to detect whether a node is valid (i.e., it is not 7481e0da3cbSArtem B. Bityutskiy * overlapped by a node with higher version) or not. 7491e0da3cbSArtem B. Bityutskiy * And we'll be able to check only those nodes, which 7501e0da3cbSArtem B. Bityutskiy * are not obsolete. 7511e0da3cbSArtem B. Bityutskiy * 7521e0da3cbSArtem B. Bityutskiy * Of course, this optimization only makes sense in case 753e1b8513dSRobert P. J. Day * of NAND flashes (or other flashes with 7541e0da3cbSArtem B. Bityutskiy * !jffs2_can_mark_obsolete()), since on NOR flashes 7551e0da3cbSArtem B. Bityutskiy * nodes are marked obsolete physically. 7561e0da3cbSArtem B. Bityutskiy * 7571e0da3cbSArtem B. Bityutskiy * Since NAND flashes (or other flashes with 7581e0da3cbSArtem B. Bityutskiy * jffs2_is_writebuffered(c)) are anyway read by 7591e0da3cbSArtem B. Bityutskiy * fractions of c->wbuf_pagesize, and we have just read 7601e0da3cbSArtem B. Bityutskiy * the node header, it is likely that the starting part 7611e0da3cbSArtem B. Bityutskiy * of the node data is also read when we read the 7621e0da3cbSArtem B. Bityutskiy * header. So we don't mind to check the CRC of the 7631e0da3cbSArtem B. Bityutskiy * starting part of the data of the node now, and check 7641e0da3cbSArtem B. Bityutskiy * the second part later (in jffs2_check_node_data()). 7651e0da3cbSArtem B. Bityutskiy * Of course, we will not need to re-read and re-check 7661e0da3cbSArtem B. Bityutskiy * the NAND page which we have just read. This is why we 7671e0da3cbSArtem B. Bityutskiy * read the whole NAND page at jffs2_get_inode_nodes(), 7681e0da3cbSArtem B. Bityutskiy * while we needed only the node header. 7691e0da3cbSArtem B. Bityutskiy */ 7701e0da3cbSArtem B. Bityutskiy unsigned char *buf; 771f97117d1SArtem B. Bityutskiy 7721e0da3cbSArtem B. Bityutskiy /* 'buf' will point to the start of data */ 7731e0da3cbSArtem B. Bityutskiy buf = (unsigned char *)rd + sizeof(*rd); 7741e0da3cbSArtem B. Bityutskiy /* len will be the read data length */ 7751e0da3cbSArtem B. Bityutskiy len = min_t(uint32_t, rdlen - sizeof(*rd), csize); 776280562b2SArtem B. Bityutskiy tn->partial_crc = crc32(0, buf, len); 777f97117d1SArtem B. Bityutskiy 778733802d9SArtem B. Bityutskiy dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize); 779f97117d1SArtem B. Bityutskiy 7801e0da3cbSArtem B. Bityutskiy /* If we actually calculated the whole data CRC 7811e0da3cbSArtem B. Bityutskiy * and it is wrong, drop the node. */ 7823c091337SArtem B. Bityutskiy if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { 78339243508SArtem B. Bityutskiy JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 78439243508SArtem B. Bityutskiy ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); 78514c6381eSDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 7861e0da3cbSArtem B. Bityutskiy goto free_out; 78739243508SArtem B. Bityutskiy } 788f97117d1SArtem B. Bityutskiy 7891e0da3cbSArtem B. Bityutskiy } else if (csize == 0) { 7901e0da3cbSArtem B. Bityutskiy /* 7911e0da3cbSArtem B. Bityutskiy * We checked the header CRC. If the node has no data, adjust 7921e0da3cbSArtem B. Bityutskiy * the space accounting now. For other nodes this will be done 7931e0da3cbSArtem B. Bityutskiy * later either when the node is marked obsolete or when its 7941e0da3cbSArtem B. Bityutskiy * data is checked. 7951e0da3cbSArtem B. Bityutskiy */ 7961e0da3cbSArtem B. Bityutskiy struct jffs2_eraseblock *jeb; 7971e0da3cbSArtem B. Bityutskiy 798733802d9SArtem B. Bityutskiy dbg_readinode("the node has no data.\n"); 799f97117d1SArtem B. Bityutskiy jeb = &c->blocks[ref->flash_offset / c->sector_size]; 800f97117d1SArtem B. Bityutskiy len = ref_totlen(c, jeb, ref); 801f97117d1SArtem B. Bityutskiy 802f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 803f97117d1SArtem B. Bityutskiy jeb->used_size += len; 804f97117d1SArtem B. Bityutskiy jeb->unchecked_size -= len; 805f97117d1SArtem B. Bityutskiy c->used_size += len; 806f97117d1SArtem B. Bityutskiy c->unchecked_size -= len; 807f97117d1SArtem B. Bityutskiy ref->flash_offset = ref_offset(ref) | REF_NORMAL; 808f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 809f97117d1SArtem B. Bityutskiy } 810f97117d1SArtem B. Bityutskiy } 811f97117d1SArtem B. Bityutskiy 812f97117d1SArtem B. Bityutskiy tn->fn = jffs2_alloc_full_dnode(); 813f97117d1SArtem B. Bityutskiy if (!tn->fn) { 814e0d60137SArtem B. Bityutskiy JFFS2_ERROR("alloc fn failed\n"); 8151e0da3cbSArtem B. Bityutskiy ret = -ENOMEM; 8161e0da3cbSArtem B. Bityutskiy goto free_out; 817f97117d1SArtem B. Bityutskiy } 818f97117d1SArtem B. Bityutskiy 819f97117d1SArtem B. Bityutskiy tn->version = je32_to_cpu(rd->version); 820f97117d1SArtem B. Bityutskiy tn->fn->ofs = je32_to_cpu(rd->offset); 8211e0da3cbSArtem B. Bityutskiy tn->data_crc = je32_to_cpu(rd->data_crc); 8221e0da3cbSArtem B. Bityutskiy tn->csize = csize; 823f97117d1SArtem B. Bityutskiy tn->fn->raw = ref; 824df8e96f3SDavid Woodhouse tn->overlapped = 0; 825df8e96f3SDavid Woodhouse 826df8e96f3SDavid Woodhouse if (tn->version > rii->highest_version) 827df8e96f3SDavid Woodhouse rii->highest_version = tn->version; 828f97117d1SArtem B. Bityutskiy 829f97117d1SArtem B. Bityutskiy /* There was a bug where we wrote hole nodes out with 830f97117d1SArtem B. Bityutskiy csize/dsize swapped. Deal with it */ 8311e0da3cbSArtem B. Bityutskiy if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize) 8321e0da3cbSArtem B. Bityutskiy tn->fn->size = csize; 833f97117d1SArtem B. Bityutskiy else // normal case... 834f97117d1SArtem B. Bityutskiy tn->fn->size = je32_to_cpu(rd->dsize); 835f97117d1SArtem B. Bityutskiy 8362c61cb25SDavid Woodhouse dbg_readinode2("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", 8372c61cb25SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->version), 8382c61cb25SDavid Woodhouse je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); 839f97117d1SArtem B. Bityutskiy 840df8e96f3SDavid Woodhouse ret = jffs2_add_tn_to_tree(c, rii, tn); 841f97117d1SArtem B. Bityutskiy 842df8e96f3SDavid Woodhouse if (ret) { 843df8e96f3SDavid Woodhouse jffs2_free_full_dnode(tn->fn); 8441e0da3cbSArtem B. Bityutskiy free_out: 8451e0da3cbSArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 8461e0da3cbSArtem B. Bityutskiy return ret; 847f97117d1SArtem B. Bityutskiy } 8482c61cb25SDavid Woodhouse #ifdef JFFS2_DBG_READINODE2_MESSAGES 8492c61cb25SDavid Woodhouse dbg_readinode2("After adding ver %d:\n", je32_to_cpu(rd->version)); 850df8e96f3SDavid Woodhouse tn = tn_first(&rii->tn_root); 851df8e96f3SDavid Woodhouse while (tn) { 8522c61cb25SDavid Woodhouse dbg_readinode2("%p: v %d r 0x%x-0x%x ov %d\n", 853df8e96f3SDavid Woodhouse tn, tn->version, tn->fn->ofs, 854df8e96f3SDavid Woodhouse tn->fn->ofs+tn->fn->size, tn->overlapped); 855df8e96f3SDavid Woodhouse tn = tn_next(tn); 856df8e96f3SDavid Woodhouse } 857df8e96f3SDavid Woodhouse #endif 858df8e96f3SDavid Woodhouse return 0; 859df8e96f3SDavid Woodhouse } 860f97117d1SArtem B. Bityutskiy 861f97117d1SArtem B. Bityutskiy /* 862f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 863f97117d1SArtem B. Bityutskiy * It is called every time an unknown node is found. 864f97117d1SArtem B. Bityutskiy * 8653877f0b6SDavid Woodhouse * Returns: 0 on success; 866f97117d1SArtem B. Bityutskiy * negative error code on failure. 867f97117d1SArtem B. Bityutskiy */ 8681e0da3cbSArtem B. Bityutskiy static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) 869f97117d1SArtem B. Bityutskiy { 870f97117d1SArtem B. Bityutskiy /* We don't mark unknown nodes as REF_UNCHECKED */ 871c7258a44SDavid Woodhouse if (ref_flags(ref) == REF_UNCHECKED) { 872c7258a44SDavid Woodhouse JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", 873c7258a44SDavid Woodhouse ref_offset(ref)); 874c7258a44SDavid Woodhouse JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", 875c7258a44SDavid Woodhouse je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), 876c7258a44SDavid Woodhouse je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); 877df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 878df8e96f3SDavid Woodhouse return 0; 879c7258a44SDavid Woodhouse } 880f97117d1SArtem B. Bityutskiy 881f97117d1SArtem B. Bityutskiy un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); 882f97117d1SArtem B. Bityutskiy 883f97117d1SArtem B. Bityutskiy switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) { 884f97117d1SArtem B. Bityutskiy 885f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_INCOMPAT: 886e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n", 887f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 888f97117d1SArtem B. Bityutskiy /* EEP */ 889f97117d1SArtem B. Bityutskiy BUG(); 890f97117d1SArtem B. Bityutskiy break; 891f97117d1SArtem B. Bityutskiy 892f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_ROCOMPAT: 893e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n", 894f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 895f97117d1SArtem B. Bityutskiy BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); 896f97117d1SArtem B. Bityutskiy break; 897f97117d1SArtem B. Bityutskiy 898f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_COPY: 899e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n", 900f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 901f97117d1SArtem B. Bityutskiy break; 902f97117d1SArtem B. Bityutskiy 903f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_DELETE: 904e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", 905f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 906df8e96f3SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 907df8e96f3SDavid Woodhouse return 0; 908f97117d1SArtem B. Bityutskiy } 909f97117d1SArtem B. Bityutskiy 910f97117d1SArtem B. Bityutskiy return 0; 911f97117d1SArtem B. Bityutskiy } 912f97117d1SArtem B. Bityutskiy 9131e0da3cbSArtem B. Bityutskiy /* 9141e0da3cbSArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 9151e0da3cbSArtem B. Bityutskiy * The function detects whether more data should be read and reads it if yes. 9161e0da3cbSArtem B. Bityutskiy * 917af901ca1SAndré Goddard Rosa * Returns: 0 on success; 9181e0da3cbSArtem B. Bityutskiy * negative error code on failure. 9191e0da3cbSArtem B. Bityutskiy */ 9201e0da3cbSArtem B. Bityutskiy static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 92110731f83SArtem Bityutskiy int needed_len, int *rdlen, unsigned char *buf) 9221e0da3cbSArtem B. Bityutskiy { 92310731f83SArtem Bityutskiy int err, to_read = needed_len - *rdlen; 9241e0da3cbSArtem B. Bityutskiy size_t retlen; 9251e0da3cbSArtem B. Bityutskiy uint32_t offs; 9261e0da3cbSArtem B. Bityutskiy 9271e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 92810731f83SArtem Bityutskiy int rem = to_read % c->wbuf_pagesize; 9291e0da3cbSArtem B. Bityutskiy 93010731f83SArtem Bityutskiy if (rem) 93110731f83SArtem Bityutskiy to_read += c->wbuf_pagesize - rem; 93210731f83SArtem Bityutskiy } 9331e0da3cbSArtem B. Bityutskiy 9341e0da3cbSArtem B. Bityutskiy /* We need to read more data */ 9351e0da3cbSArtem B. Bityutskiy offs = ref_offset(ref) + *rdlen; 9361e0da3cbSArtem B. Bityutskiy 93710731f83SArtem Bityutskiy dbg_readinode("read more %d bytes\n", to_read); 9381e0da3cbSArtem B. Bityutskiy 93910731f83SArtem Bityutskiy err = jffs2_flash_read(c, offs, to_read, &retlen, buf + *rdlen); 9401e0da3cbSArtem B. Bityutskiy if (err) { 9411e0da3cbSArtem B. Bityutskiy JFFS2_ERROR("can not read %d bytes from 0x%08x, " 94210731f83SArtem Bityutskiy "error code: %d.\n", to_read, offs, err); 9431e0da3cbSArtem B. Bityutskiy return err; 9441e0da3cbSArtem B. Bityutskiy } 9451e0da3cbSArtem B. Bityutskiy 94610731f83SArtem Bityutskiy if (retlen < to_read) { 947fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", 94810731f83SArtem Bityutskiy offs, retlen, to_read); 9491e0da3cbSArtem B. Bityutskiy return -EIO; 9501e0da3cbSArtem B. Bityutskiy } 9511e0da3cbSArtem B. Bityutskiy 95210731f83SArtem Bityutskiy *rdlen += to_read; 9531e0da3cbSArtem B. Bityutskiy return 0; 9541e0da3cbSArtem B. Bityutskiy } 9551e0da3cbSArtem B. Bityutskiy 956f97117d1SArtem B. Bityutskiy /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated 957df8e96f3SDavid Woodhouse with this ino. Perform a preliminary ordering on data nodes, throwing away 958df8e96f3SDavid Woodhouse those which are completely obsoleted by newer ones. The naïve approach we 959df8e96f3SDavid Woodhouse use to take of just returning them _all_ in version order will cause us to 960df8e96f3SDavid Woodhouse run out of memory in certain degenerate cases. */ 961f97117d1SArtem B. Bityutskiy static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 962df8e96f3SDavid Woodhouse struct jffs2_readinode_info *rii) 963f97117d1SArtem B. Bityutskiy { 964f97117d1SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref, *valid_ref; 9651e0da3cbSArtem B. Bityutskiy unsigned char *buf = NULL; 9661e0da3cbSArtem B. Bityutskiy union jffs2_node_union *node; 967f97117d1SArtem B. Bityutskiy size_t retlen; 9681e0da3cbSArtem B. Bityutskiy int len, err; 969f97117d1SArtem B. Bityutskiy 970df8e96f3SDavid Woodhouse rii->mctime_ver = 0; 971f97117d1SArtem B. Bityutskiy 972733802d9SArtem B. Bityutskiy dbg_readinode("ino #%u\n", f->inocache->ino); 973f97117d1SArtem B. Bityutskiy 9741e0da3cbSArtem B. Bityutskiy /* FIXME: in case of NOR and available ->point() this 9751e0da3cbSArtem B. Bityutskiy * needs to be fixed. */ 97610731f83SArtem Bityutskiy len = sizeof(union jffs2_node_union) + c->wbuf_pagesize; 9771e0da3cbSArtem B. Bityutskiy buf = kmalloc(len, GFP_KERNEL); 9781e0da3cbSArtem B. Bityutskiy if (!buf) 9791e0da3cbSArtem B. Bityutskiy return -ENOMEM; 9801e0da3cbSArtem B. Bityutskiy 981f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 982f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(f->inocache->nodes); 9831e0da3cbSArtem B. Bityutskiy if (!valid_ref && f->inocache->ino != 1) 9841e0da3cbSArtem B. Bityutskiy JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); 985f97117d1SArtem B. Bityutskiy while (valid_ref) { 986f97117d1SArtem B. Bityutskiy /* We can hold a pointer to a non-obsolete node without the spinlock, 987f97117d1SArtem B. Bityutskiy but _obsolete_ nodes may disappear at any time, if the block 988f97117d1SArtem B. Bityutskiy they're in gets erased. So if we mark 'ref' obsolete while we're 989f97117d1SArtem B. Bityutskiy not holding the lock, it can go away immediately. For that reason, 990f97117d1SArtem B. Bityutskiy we find the next valid node first, before processing 'ref'. 991f97117d1SArtem B. Bityutskiy */ 992f97117d1SArtem B. Bityutskiy ref = valid_ref; 993f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(ref->next_in_ino); 994f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 995f97117d1SArtem B. Bityutskiy 996f97117d1SArtem B. Bityutskiy cond_resched(); 997f97117d1SArtem B. Bityutskiy 9981e0da3cbSArtem B. Bityutskiy /* 9991e0da3cbSArtem B. Bityutskiy * At this point we don't know the type of the node we're going 10001e0da3cbSArtem B. Bityutskiy * to read, so we do not know the size of its header. In order 100110731f83SArtem Bityutskiy * to minimize the amount of flash IO we assume the header is 100210731f83SArtem Bityutskiy * of size = JFFS2_MIN_NODE_HEADER. 10031e0da3cbSArtem B. Bityutskiy */ 10041e0da3cbSArtem B. Bityutskiy len = JFFS2_MIN_NODE_HEADER; 100510731f83SArtem Bityutskiy if (jffs2_is_writebuffered(c)) { 100610731f83SArtem Bityutskiy int end, rem; 100710731f83SArtem Bityutskiy 100810731f83SArtem Bityutskiy /* 100910731f83SArtem Bityutskiy * We are about to read JFFS2_MIN_NODE_HEADER bytes, 101010731f83SArtem Bityutskiy * but this flash has some minimal I/O unit. It is 101110731f83SArtem Bityutskiy * possible that we'll need to read more soon, so read 101210731f83SArtem Bityutskiy * up to the next min. I/O unit, in order not to 101310731f83SArtem Bityutskiy * re-read the same min. I/O unit twice. 101410731f83SArtem Bityutskiy */ 101510731f83SArtem Bityutskiy end = ref_offset(ref) + len; 101610731f83SArtem Bityutskiy rem = end % c->wbuf_pagesize; 101710731f83SArtem Bityutskiy if (rem) 101810731f83SArtem Bityutskiy end += c->wbuf_pagesize - rem; 101910731f83SArtem Bityutskiy len = end - ref_offset(ref); 10201e0da3cbSArtem B. Bityutskiy } 10211e0da3cbSArtem B. Bityutskiy 1022733802d9SArtem B. Bityutskiy dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); 10231e0da3cbSArtem B. Bityutskiy 1024f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 102510731f83SArtem Bityutskiy err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, buf); 1026f97117d1SArtem B. Bityutskiy if (err) { 1027df2e301fSJean Delvare JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ref_offset(ref), err); 1028f97117d1SArtem B. Bityutskiy goto free_out; 1029f97117d1SArtem B. Bityutskiy } 1030f97117d1SArtem B. Bityutskiy 10311e0da3cbSArtem B. Bityutskiy if (retlen < len) { 1032fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", ref_offset(ref), retlen, len); 1033f97117d1SArtem B. Bityutskiy err = -EIO; 1034f97117d1SArtem B. Bityutskiy goto free_out; 1035f97117d1SArtem B. Bityutskiy } 1036f97117d1SArtem B. Bityutskiy 103710731f83SArtem Bityutskiy node = (union jffs2_node_union *)buf; 10381e0da3cbSArtem B. Bityutskiy 10393877f0b6SDavid Woodhouse /* No need to mask in the valid bit; it shouldn't be invalid */ 10403877f0b6SDavid Woodhouse if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { 10413877f0b6SDavid Woodhouse JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n", 10423877f0b6SDavid Woodhouse ref_offset(ref), je16_to_cpu(node->u.magic), 10433877f0b6SDavid Woodhouse je16_to_cpu(node->u.nodetype), 10443877f0b6SDavid Woodhouse je32_to_cpu(node->u.totlen), 10453877f0b6SDavid Woodhouse je32_to_cpu(node->u.hdr_crc)); 10463877f0b6SDavid Woodhouse jffs2_dbg_dump_node(c, ref_offset(ref)); 10473877f0b6SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 10483877f0b6SDavid Woodhouse goto cont; 10493877f0b6SDavid Woodhouse } 10500dec4c8bSJoakim Tjernlund if (je16_to_cpu(node->u.magic) != JFFS2_MAGIC_BITMASK) { 10510dec4c8bSJoakim Tjernlund /* Not a JFFS2 node, whinge and move on */ 10520dec4c8bSJoakim Tjernlund JFFS2_NOTICE("Wrong magic bitmask 0x%04x in node header at %#08x.\n", 10530dec4c8bSJoakim Tjernlund je16_to_cpu(node->u.magic), ref_offset(ref)); 1054c7258a44SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 1055c7258a44SDavid Woodhouse goto cont; 1056c7258a44SDavid Woodhouse } 10573877f0b6SDavid Woodhouse 10581e0da3cbSArtem B. Bityutskiy switch (je16_to_cpu(node->u.nodetype)) { 10591e0da3cbSArtem B. Bityutskiy 10601e0da3cbSArtem B. Bityutskiy case JFFS2_NODETYPE_DIRENT: 10611e0da3cbSArtem B. Bityutskiy 1062ea55d307SArtem Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent) && 1063ea55d307SArtem Bityutskiy len < sizeof(struct jffs2_raw_dirent)) { 106410731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf); 10651e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 10661e0da3cbSArtem B. Bityutskiy goto free_out; 10671e0da3cbSArtem B. Bityutskiy } 10681e0da3cbSArtem B. Bityutskiy 1069df8e96f3SDavid Woodhouse err = read_direntry(c, ref, &node->d, retlen, rii); 1070df8e96f3SDavid Woodhouse if (unlikely(err)) 1071f97117d1SArtem B. Bityutskiy goto free_out; 1072f97117d1SArtem B. Bityutskiy 1073f97117d1SArtem B. Bityutskiy break; 1074f97117d1SArtem B. Bityutskiy 1075f97117d1SArtem B. Bityutskiy case JFFS2_NODETYPE_INODE: 1076f97117d1SArtem B. Bityutskiy 1077ea55d307SArtem Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode) && 1078ea55d307SArtem Bityutskiy len < sizeof(struct jffs2_raw_inode)) { 107910731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf); 10801e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 1081f97117d1SArtem B. Bityutskiy goto free_out; 1082f97117d1SArtem B. Bityutskiy } 1083f97117d1SArtem B. Bityutskiy 1084df8e96f3SDavid Woodhouse err = read_dnode(c, ref, &node->i, len, rii); 1085df8e96f3SDavid Woodhouse if (unlikely(err)) 1086f97117d1SArtem B. Bityutskiy goto free_out; 1087f97117d1SArtem B. Bityutskiy 10881da177e4SLinus Torvalds break; 10891da177e4SLinus Torvalds 10901da177e4SLinus Torvalds default: 1091ea55d307SArtem Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node) && 1092ea55d307SArtem Bityutskiy len < sizeof(struct jffs2_unknown_node)) { 109310731f83SArtem Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf); 10941e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 10951e0da3cbSArtem B. Bityutskiy goto free_out; 10961da177e4SLinus Torvalds } 10971da177e4SLinus Torvalds 10981e0da3cbSArtem B. Bityutskiy err = read_unknown(c, ref, &node->u); 109914c6381eSDavid Woodhouse if (unlikely(err)) 1100f97117d1SArtem B. Bityutskiy goto free_out; 1101f97117d1SArtem B. Bityutskiy 11021da177e4SLinus Torvalds } 11033877f0b6SDavid Woodhouse cont: 1104f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 11051da177e4SLinus Torvalds } 11061e0da3cbSArtem B. Bityutskiy 1107f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 11081e0da3cbSArtem B. Bityutskiy kfree(buf); 1109f97117d1SArtem B. Bityutskiy 1110df8e96f3SDavid Woodhouse f->highest_version = rii->highest_version; 1111df8e96f3SDavid Woodhouse 1112733802d9SArtem B. Bityutskiy dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n", 1113df8e96f3SDavid Woodhouse f->inocache->ino, rii->highest_version, rii->latest_mctime, 1114df8e96f3SDavid Woodhouse rii->mctime_ver); 1115f97117d1SArtem B. Bityutskiy return 0; 1116f97117d1SArtem B. Bityutskiy 1117f97117d1SArtem B. Bityutskiy free_out: 1118df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info_list(&rii->tn_root); 1119df8e96f3SDavid Woodhouse jffs2_free_full_dirent_list(rii->fds); 1120df8e96f3SDavid Woodhouse rii->fds = NULL; 11211e0da3cbSArtem B. Bityutskiy kfree(buf); 1122f97117d1SArtem B. Bityutskiy return err; 11231da177e4SLinus Torvalds } 11241da177e4SLinus Torvalds 11251da177e4SLinus Torvalds static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 11261da177e4SLinus Torvalds struct jffs2_inode_info *f, 11271da177e4SLinus Torvalds struct jffs2_raw_inode *latest_node) 11281da177e4SLinus Torvalds { 1129df8e96f3SDavid Woodhouse struct jffs2_readinode_info rii; 113061c4b237SDavid Woodhouse uint32_t crc, new_size; 11311da177e4SLinus Torvalds size_t retlen; 11321da177e4SLinus Torvalds int ret; 11331da177e4SLinus Torvalds 113427c72b04SDavid Woodhouse dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino, 113527c72b04SDavid Woodhouse f->inocache->pino_nlink); 11361da177e4SLinus Torvalds 1137df8e96f3SDavid Woodhouse memset(&rii, 0, sizeof(rii)); 1138df8e96f3SDavid Woodhouse 11391da177e4SLinus Torvalds /* Grab all nodes relevant to this ino */ 1140df8e96f3SDavid Woodhouse ret = jffs2_get_inode_nodes(c, f, &rii); 11411da177e4SLinus Torvalds 11421da177e4SLinus Torvalds if (ret) { 1143e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); 11441da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11451da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 11461da177e4SLinus Torvalds return ret; 11471da177e4SLinus Torvalds } 11481da177e4SLinus Torvalds 1149df8e96f3SDavid Woodhouse ret = jffs2_build_inode_fragtree(c, f, &rii); 11501e0da3cbSArtem B. Bityutskiy if (ret) { 1151df8e96f3SDavid Woodhouse JFFS2_ERROR("Failed to build final fragtree for inode #%u: error %d\n", 1152df8e96f3SDavid Woodhouse f->inocache->ino, ret); 1153df8e96f3SDavid Woodhouse if (f->inocache->state == INO_STATE_READING) 1154df8e96f3SDavid Woodhouse jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 1155df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info_list(&rii.tn_root); 1156df8e96f3SDavid Woodhouse /* FIXME: We could at least crc-check them all */ 1157df8e96f3SDavid Woodhouse if (rii.mdata_tn) { 1158df8e96f3SDavid Woodhouse jffs2_free_full_dnode(rii.mdata_tn->fn); 1159df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(rii.mdata_tn); 1160df8e96f3SDavid Woodhouse rii.mdata_tn = NULL; 11611e0da3cbSArtem B. Bityutskiy } 1162df8e96f3SDavid Woodhouse return ret; 11631da177e4SLinus Torvalds } 1164df8e96f3SDavid Woodhouse 1165df8e96f3SDavid Woodhouse if (rii.mdata_tn) { 1166df8e96f3SDavid Woodhouse if (rii.mdata_tn->fn->raw == rii.latest_ref) { 1167df8e96f3SDavid Woodhouse f->metadata = rii.mdata_tn->fn; 1168df8e96f3SDavid Woodhouse jffs2_free_tmp_dnode_info(rii.mdata_tn); 1169df8e96f3SDavid Woodhouse } else { 1170df8e96f3SDavid Woodhouse jffs2_kill_tn(c, rii.mdata_tn); 1171df8e96f3SDavid Woodhouse } 1172df8e96f3SDavid Woodhouse rii.mdata_tn = NULL; 1173df8e96f3SDavid Woodhouse } 1174df8e96f3SDavid Woodhouse 1175df8e96f3SDavid Woodhouse f->dents = rii.fds; 1176df8e96f3SDavid Woodhouse 1177e0c8e42fSArtem B. Bityutskiy jffs2_dbg_fragtree_paranoia_check_nolock(f); 11781da177e4SLinus Torvalds 1179df8e96f3SDavid Woodhouse if (unlikely(!rii.latest_ref)) { 11801da177e4SLinus Torvalds /* No data nodes for this inode. */ 11811da177e4SLinus Torvalds if (f->inocache->ino != 1) { 1182e0d60137SArtem B. Bityutskiy JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); 1183df8e96f3SDavid Woodhouse if (!rii.fds) { 11841da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11851da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 11861da177e4SLinus Torvalds return -EIO; 11871da177e4SLinus Torvalds } 1188e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("but it has children so we fake some modes for it\n"); 11891da177e4SLinus Torvalds } 11901da177e4SLinus Torvalds latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); 11911da177e4SLinus Torvalds latest_node->version = cpu_to_je32(0); 11921da177e4SLinus Torvalds latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); 11931da177e4SLinus Torvalds latest_node->isize = cpu_to_je32(0); 11941da177e4SLinus Torvalds latest_node->gid = cpu_to_je16(0); 11951da177e4SLinus Torvalds latest_node->uid = cpu_to_je16(0); 11961da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 11971da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 11981da177e4SLinus Torvalds return 0; 11991da177e4SLinus Torvalds } 12001da177e4SLinus Torvalds 1201df8e96f3SDavid Woodhouse ret = jffs2_flash_read(c, ref_offset(rii.latest_ref), sizeof(*latest_node), &retlen, (void *)latest_node); 12021da177e4SLinus Torvalds if (ret || retlen != sizeof(*latest_node)) { 1203e0d60137SArtem B. Bityutskiy JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", 12041da177e4SLinus Torvalds ret, retlen, sizeof(*latest_node)); 12051da177e4SLinus Torvalds /* FIXME: If this fails, there seems to be a memory leak. Find it. */ 1206ced22070SDavid Woodhouse mutex_unlock(&f->sem); 12071da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12081da177e4SLinus Torvalds return ret?ret:-EIO; 12091da177e4SLinus Torvalds } 12101da177e4SLinus Torvalds 12111da177e4SLinus Torvalds crc = crc32(0, latest_node, sizeof(*latest_node)-8); 12121da177e4SLinus Torvalds if (crc != je32_to_cpu(latest_node->node_crc)) { 1213e0d60137SArtem B. Bityutskiy JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", 1214df8e96f3SDavid Woodhouse f->inocache->ino, ref_offset(rii.latest_ref)); 1215ced22070SDavid Woodhouse mutex_unlock(&f->sem); 12161da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12171da177e4SLinus Torvalds return -EIO; 12181da177e4SLinus Torvalds } 12191da177e4SLinus Torvalds 12201da177e4SLinus Torvalds switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { 12211da177e4SLinus Torvalds case S_IFDIR: 1222df8e96f3SDavid Woodhouse if (rii.mctime_ver > je32_to_cpu(latest_node->version)) { 12231da177e4SLinus Torvalds /* The times in the latest_node are actually older than 12241da177e4SLinus Torvalds mctime in the latest dirent. Cheat. */ 1225df8e96f3SDavid Woodhouse latest_node->ctime = latest_node->mtime = cpu_to_je32(rii.latest_mctime); 12261da177e4SLinus Torvalds } 12271da177e4SLinus Torvalds break; 12281da177e4SLinus Torvalds 12291da177e4SLinus Torvalds 12301da177e4SLinus Torvalds case S_IFREG: 12311da177e4SLinus Torvalds /* If it was a regular file, truncate it to the latest node's isize */ 123261c4b237SDavid Woodhouse new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 123361c4b237SDavid Woodhouse if (new_size != je32_to_cpu(latest_node->isize)) { 123461c4b237SDavid Woodhouse JFFS2_WARNING("Truncating ino #%u to %d bytes failed because it only had %d bytes to start with!\n", 123561c4b237SDavid Woodhouse f->inocache->ino, je32_to_cpu(latest_node->isize), new_size); 123661c4b237SDavid Woodhouse latest_node->isize = cpu_to_je32(new_size); 123761c4b237SDavid Woodhouse } 12381da177e4SLinus Torvalds break; 12391da177e4SLinus Torvalds 12401da177e4SLinus Torvalds case S_IFLNK: 12411da177e4SLinus Torvalds /* Hack to work around broken isize in old symlink code. 12421da177e4SLinus Torvalds Remove this when dwmw2 comes to his senses and stops 12431da177e4SLinus Torvalds symlinks from being an entirely gratuitous special 12441da177e4SLinus Torvalds case. */ 12451da177e4SLinus Torvalds if (!je32_to_cpu(latest_node->isize)) 12461da177e4SLinus Torvalds latest_node->isize = latest_node->dsize; 124732f1a95dSArtem B. Bityuckiy 124832f1a95dSArtem B. Bityuckiy if (f->inocache->state != INO_STATE_CHECKING) { 124932f1a95dSArtem B. Bityuckiy /* Symlink's inode data is the target path. Read it and 12502b79adccSArtem B. Bityutskiy * keep in RAM to facilitate quick follow symlink 12512b79adccSArtem B. Bityutskiy * operation. */ 12527c80c352SXi Wang uint32_t csize = je32_to_cpu(latest_node->csize); 12537c80c352SXi Wang if (csize > JFFS2_MAX_NAME_LEN) { 12547c80c352SXi Wang mutex_unlock(&f->sem); 12557c80c352SXi Wang jffs2_do_clear_inode(c, f); 12567c80c352SXi Wang return -ENAMETOOLONG; 12577c80c352SXi Wang } 1258b6778fd7SXi Wang f->target = kmalloc(csize + 1, GFP_KERNEL); 12592b79adccSArtem B. Bityutskiy if (!f->target) { 1260b6778fd7SXi Wang JFFS2_ERROR("can't allocate %u bytes of memory for the symlink target path cache\n", csize); 1261ced22070SDavid Woodhouse mutex_unlock(&f->sem); 126232f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 126332f1a95dSArtem B. Bityuckiy return -ENOMEM; 126432f1a95dSArtem B. Bityuckiy } 126532f1a95dSArtem B. Bityuckiy 1266df8e96f3SDavid Woodhouse ret = jffs2_flash_read(c, ref_offset(rii.latest_ref) + sizeof(*latest_node), 1267b6778fd7SXi Wang csize, &retlen, (char *)f->target); 126832f1a95dSArtem B. Bityuckiy 1269b6778fd7SXi Wang if (ret || retlen != csize) { 1270b6778fd7SXi Wang if (retlen != csize) 127132f1a95dSArtem B. Bityuckiy ret = -EIO; 12722b79adccSArtem B. Bityutskiy kfree(f->target); 12732b79adccSArtem B. Bityutskiy f->target = NULL; 1274ced22070SDavid Woodhouse mutex_unlock(&f->sem); 127532f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 1276e670e41aSRoel Kluin return ret; 127732f1a95dSArtem B. Bityuckiy } 127832f1a95dSArtem B. Bityuckiy 1279b6778fd7SXi Wang f->target[csize] = '\0'; 1280733802d9SArtem B. Bityutskiy dbg_readinode("symlink's target '%s' cached\n", f->target); 128132f1a95dSArtem B. Bityuckiy } 128232f1a95dSArtem B. Bityuckiy 12831da177e4SLinus Torvalds /* fall through... */ 12841da177e4SLinus Torvalds 12851da177e4SLinus Torvalds case S_IFBLK: 12861da177e4SLinus Torvalds case S_IFCHR: 12871da177e4SLinus Torvalds /* Certain inode types should have only one data node, and it's 12881da177e4SLinus Torvalds kept as the metadata node */ 12891da177e4SLinus Torvalds if (f->metadata) { 1290e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n", 12911da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 1292ced22070SDavid Woodhouse mutex_unlock(&f->sem); 12931da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 12941da177e4SLinus Torvalds return -EIO; 12951da177e4SLinus Torvalds } 12961da177e4SLinus Torvalds if (!frag_first(&f->fragtree)) { 1297e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n", 12981da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 1299ced22070SDavid Woodhouse mutex_unlock(&f->sem); 13001da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 13011da177e4SLinus Torvalds return -EIO; 13021da177e4SLinus Torvalds } 13031da177e4SLinus Torvalds /* ASSERT: f->fraglist != NULL */ 13041da177e4SLinus Torvalds if (frag_next(frag_first(&f->fragtree))) { 1305e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n", 13061da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 13071da177e4SLinus Torvalds /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ 1308ced22070SDavid Woodhouse mutex_unlock(&f->sem); 13091da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 13101da177e4SLinus Torvalds return -EIO; 13111da177e4SLinus Torvalds } 13121da177e4SLinus Torvalds /* OK. We're happy */ 13131da177e4SLinus Torvalds f->metadata = frag_first(&f->fragtree)->node; 13141da177e4SLinus Torvalds jffs2_free_node_frag(frag_first(&f->fragtree)); 13151da177e4SLinus Torvalds f->fragtree = RB_ROOT; 13161da177e4SLinus Torvalds break; 13171da177e4SLinus Torvalds } 13181da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 13191da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 13201da177e4SLinus Torvalds 13211da177e4SLinus Torvalds return 0; 13221da177e4SLinus Torvalds } 13231da177e4SLinus Torvalds 1324f97117d1SArtem B. Bityutskiy /* Scan the list of all nodes present for this ino, build map of versions, etc. */ 1325f97117d1SArtem B. Bityutskiy int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 1326f97117d1SArtem B. Bityutskiy uint32_t ino, struct jffs2_raw_inode *latest_node) 1327f97117d1SArtem B. Bityutskiy { 1328733802d9SArtem B. Bityutskiy dbg_readinode("read inode #%u\n", ino); 1329f97117d1SArtem B. Bityutskiy 1330f97117d1SArtem B. Bityutskiy retry_inocache: 1331f97117d1SArtem B. Bityutskiy spin_lock(&c->inocache_lock); 1332f97117d1SArtem B. Bityutskiy f->inocache = jffs2_get_ino_cache(c, ino); 1333f97117d1SArtem B. Bityutskiy 1334f97117d1SArtem B. Bityutskiy if (f->inocache) { 1335f97117d1SArtem B. Bityutskiy /* Check its state. We may need to wait before we can use it */ 1336f97117d1SArtem B. Bityutskiy switch(f->inocache->state) { 1337f97117d1SArtem B. Bityutskiy case INO_STATE_UNCHECKED: 1338f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKEDABSENT: 1339f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 1340f97117d1SArtem B. Bityutskiy break; 1341f97117d1SArtem B. Bityutskiy 1342f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKING: 1343f97117d1SArtem B. Bityutskiy case INO_STATE_GC: 1344f97117d1SArtem B. Bityutskiy /* If it's in either of these states, we need 1345f97117d1SArtem B. Bityutskiy to wait for whoever's got it to finish and 1346f97117d1SArtem B. Bityutskiy put it back. */ 1347733802d9SArtem B. Bityutskiy dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state); 1348f97117d1SArtem B. Bityutskiy sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 1349f97117d1SArtem B. Bityutskiy goto retry_inocache; 1350f97117d1SArtem B. Bityutskiy 1351f97117d1SArtem B. Bityutskiy case INO_STATE_READING: 1352f97117d1SArtem B. Bityutskiy case INO_STATE_PRESENT: 1353f97117d1SArtem B. Bityutskiy /* Eep. This should never happen. It can 1354f97117d1SArtem B. Bityutskiy happen if Linux calls read_inode() again 1355f97117d1SArtem B. Bityutskiy before clear_inode() has finished though. */ 1356e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); 1357f97117d1SArtem B. Bityutskiy /* Fail. That's probably better than allowing it to succeed */ 1358f97117d1SArtem B. Bityutskiy f->inocache = NULL; 1359f97117d1SArtem B. Bityutskiy break; 1360f97117d1SArtem B. Bityutskiy 1361f97117d1SArtem B. Bityutskiy default: 1362f97117d1SArtem B. Bityutskiy BUG(); 1363f97117d1SArtem B. Bityutskiy } 1364f97117d1SArtem B. Bityutskiy } 1365f97117d1SArtem B. Bityutskiy spin_unlock(&c->inocache_lock); 1366f97117d1SArtem B. Bityutskiy 1367f97117d1SArtem B. Bityutskiy if (!f->inocache && ino == 1) { 1368f97117d1SArtem B. Bityutskiy /* Special case - no root inode on medium */ 1369f97117d1SArtem B. Bityutskiy f->inocache = jffs2_alloc_inode_cache(); 1370f97117d1SArtem B. Bityutskiy if (!f->inocache) { 1371e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot allocate inocache for root inode\n"); 1372f97117d1SArtem B. Bityutskiy return -ENOMEM; 1373f97117d1SArtem B. Bityutskiy } 1374733802d9SArtem B. Bityutskiy dbg_readinode("creating inocache for root inode\n"); 1375f97117d1SArtem B. Bityutskiy memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); 137627c72b04SDavid Woodhouse f->inocache->ino = f->inocache->pino_nlink = 1; 1377f97117d1SArtem B. Bityutskiy f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 1378f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 1379f97117d1SArtem B. Bityutskiy jffs2_add_ino_cache(c, f->inocache); 1380f97117d1SArtem B. Bityutskiy } 1381f97117d1SArtem B. Bityutskiy if (!f->inocache) { 1382e0d60137SArtem B. Bityutskiy JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); 1383f97117d1SArtem B. Bityutskiy return -ENOENT; 1384f97117d1SArtem B. Bityutskiy } 1385f97117d1SArtem B. Bityutskiy 1386f97117d1SArtem B. Bityutskiy return jffs2_do_read_inode_internal(c, f, latest_node); 1387f97117d1SArtem B. Bityutskiy } 1388f97117d1SArtem B. Bityutskiy 1389f97117d1SArtem B. Bityutskiy int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 1390f97117d1SArtem B. Bityutskiy { 1391f97117d1SArtem B. Bityutskiy struct jffs2_raw_inode n; 13923d375d9eSYan Burman struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL); 1393f97117d1SArtem B. Bityutskiy int ret; 1394f97117d1SArtem B. Bityutskiy 1395f97117d1SArtem B. Bityutskiy if (!f) 1396f97117d1SArtem B. Bityutskiy return -ENOMEM; 1397f97117d1SArtem B. Bityutskiy 1398ced22070SDavid Woodhouse mutex_init(&f->sem); 1399ced22070SDavid Woodhouse mutex_lock(&f->sem); 1400f97117d1SArtem B. Bityutskiy f->inocache = ic; 1401f97117d1SArtem B. Bityutskiy 1402f97117d1SArtem B. Bityutskiy ret = jffs2_do_read_inode_internal(c, f, &n); 1403f97117d1SArtem B. Bityutskiy if (!ret) { 1404ced22070SDavid Woodhouse mutex_unlock(&f->sem); 1405f97117d1SArtem B. Bityutskiy jffs2_do_clear_inode(c, f); 1406f97117d1SArtem B. Bityutskiy } 14078c5a0366SJean-Christophe DUBOIS jffs2_xattr_do_crccheck_inode(c, ic); 1408f97117d1SArtem B. Bityutskiy kfree (f); 1409f97117d1SArtem B. Bityutskiy return ret; 1410f97117d1SArtem B. Bityutskiy } 1411f97117d1SArtem B. Bityutskiy 14121da177e4SLinus Torvalds void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) 14131da177e4SLinus Torvalds { 14141da177e4SLinus Torvalds struct jffs2_full_dirent *fd, *fds; 14151da177e4SLinus Torvalds int deleted; 14161da177e4SLinus Torvalds 1417355ed4e1SKaiGai Kohei jffs2_xattr_delete_inode(c, f->inocache); 1418ced22070SDavid Woodhouse mutex_lock(&f->sem); 141927c72b04SDavid Woodhouse deleted = f->inocache && !f->inocache->pino_nlink; 14201da177e4SLinus Torvalds 142167e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 142267e345d1SDavid Woodhouse jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); 142367e345d1SDavid Woodhouse 14241da177e4SLinus Torvalds if (f->metadata) { 14251da177e4SLinus Torvalds if (deleted) 14261da177e4SLinus Torvalds jffs2_mark_node_obsolete(c, f->metadata->raw); 14271da177e4SLinus Torvalds jffs2_free_full_dnode(f->metadata); 14281da177e4SLinus Torvalds } 14291da177e4SLinus Torvalds 14301da177e4SLinus Torvalds jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 14311da177e4SLinus Torvalds 14322b79adccSArtem B. Bityutskiy if (f->target) { 14332b79adccSArtem B. Bityutskiy kfree(f->target); 14342b79adccSArtem B. Bityutskiy f->target = NULL; 143532f1a95dSArtem B. Bityuckiy } 14361da177e4SLinus Torvalds 14372b79adccSArtem B. Bityutskiy fds = f->dents; 14381da177e4SLinus Torvalds while(fds) { 14391da177e4SLinus Torvalds fd = fds; 14401da177e4SLinus Torvalds fds = fd->next; 14411da177e4SLinus Torvalds jffs2_free_full_dirent(fd); 14421da177e4SLinus Torvalds } 14431da177e4SLinus Torvalds 144467e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 14451da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 144667e345d1SDavid Woodhouse if (f->inocache->nodes == (void *)f->inocache) 144767e345d1SDavid Woodhouse jffs2_del_ino_cache(c, f->inocache); 144867e345d1SDavid Woodhouse } 14491da177e4SLinus Torvalds 1450ced22070SDavid Woodhouse mutex_unlock(&f->sem); 14511da177e4SLinus Torvalds } 1452