11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * JFFS2 -- Journalling Flash File System, Version 2. 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2001-2003 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 * 10182ec4eeSThomas Gleixner * $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $ 111da177e4SLinus Torvalds * 121da177e4SLinus Torvalds */ 131da177e4SLinus Torvalds 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 /* 25f97117d1SArtem B. Bityutskiy * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in 26f97117d1SArtem B. Bityutskiy * order of increasing version. 27f97117d1SArtem B. Bityutskiy */ 28f97117d1SArtem B. Bityutskiy static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) 291da177e4SLinus Torvalds { 30f97117d1SArtem B. Bityutskiy struct rb_node **p = &list->rb_node; 31f97117d1SArtem B. Bityutskiy struct rb_node * parent = NULL; 32f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *this; 331da177e4SLinus Torvalds 34f97117d1SArtem B. Bityutskiy while (*p) { 35f97117d1SArtem B. Bityutskiy parent = *p; 36f97117d1SArtem B. Bityutskiy this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); 371da177e4SLinus Torvalds 38f97117d1SArtem B. Bityutskiy /* There may actually be a collision here, but it doesn't 39f97117d1SArtem B. Bityutskiy actually matter. As long as the two nodes with the same 40f97117d1SArtem B. Bityutskiy version are together, it's all fine. */ 411e0da3cbSArtem B. Bityutskiy if (tn->version > this->version) 42f97117d1SArtem B. Bityutskiy p = &(*p)->rb_left; 43f97117d1SArtem B. Bityutskiy else 44f97117d1SArtem B. Bityutskiy p = &(*p)->rb_right; 45f97117d1SArtem B. Bityutskiy } 461da177e4SLinus Torvalds 47f97117d1SArtem B. Bityutskiy rb_link_node(&tn->rb, parent, p); 48f97117d1SArtem B. Bityutskiy rb_insert_color(&tn->rb, list); 49f97117d1SArtem B. Bityutskiy } 50f97117d1SArtem B. Bityutskiy 51f97117d1SArtem B. Bityutskiy static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) 52f97117d1SArtem B. Bityutskiy { 53f97117d1SArtem B. Bityutskiy struct rb_node *this; 54f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 55f97117d1SArtem B. Bityutskiy 56f97117d1SArtem B. Bityutskiy this = list->rb_node; 57f97117d1SArtem B. Bityutskiy 58f97117d1SArtem B. Bityutskiy /* Now at bottom of tree */ 59f97117d1SArtem B. Bityutskiy while (this) { 60f97117d1SArtem B. Bityutskiy if (this->rb_left) 61f97117d1SArtem B. Bityutskiy this = this->rb_left; 62f97117d1SArtem B. Bityutskiy else if (this->rb_right) 63f97117d1SArtem B. Bityutskiy this = this->rb_right; 64f97117d1SArtem B. Bityutskiy else { 65f97117d1SArtem B. Bityutskiy tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb); 66f97117d1SArtem B. Bityutskiy jffs2_free_full_dnode(tn->fn); 67f97117d1SArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 68f97117d1SArtem B. Bityutskiy 6921f1d5fcSDavid Woodhouse this = rb_parent(this); 70f97117d1SArtem B. Bityutskiy if (!this) 711da177e4SLinus Torvalds break; 721da177e4SLinus Torvalds 73f97117d1SArtem B. Bityutskiy if (this->rb_left == &tn->rb) 74f97117d1SArtem B. Bityutskiy this->rb_left = NULL; 75f97117d1SArtem B. Bityutskiy else if (this->rb_right == &tn->rb) 76f97117d1SArtem B. Bityutskiy this->rb_right = NULL; 77f97117d1SArtem B. Bityutskiy else BUG(); 78f97117d1SArtem B. Bityutskiy } 79f97117d1SArtem B. Bityutskiy } 80f97117d1SArtem B. Bityutskiy list->rb_node = NULL; 81f97117d1SArtem B. Bityutskiy } 821da177e4SLinus Torvalds 83f97117d1SArtem B. Bityutskiy static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 84f97117d1SArtem B. Bityutskiy { 85f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *next; 86f97117d1SArtem B. Bityutskiy 87f97117d1SArtem B. Bityutskiy while (fd) { 88f97117d1SArtem B. Bityutskiy next = fd->next; 89f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 90f97117d1SArtem B. Bityutskiy fd = next; 91f97117d1SArtem B. Bityutskiy } 92f97117d1SArtem B. Bityutskiy } 93f97117d1SArtem B. Bityutskiy 94f97117d1SArtem B. Bityutskiy /* Returns first valid node after 'ref'. May return 'ref' */ 95f97117d1SArtem B. Bityutskiy static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref) 96f97117d1SArtem B. Bityutskiy { 97f97117d1SArtem B. Bityutskiy while (ref && ref->next_in_ino) { 98f97117d1SArtem B. Bityutskiy if (!ref_obsolete(ref)) 99f97117d1SArtem B. Bityutskiy return ref; 100733802d9SArtem B. Bityutskiy dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)); 101f97117d1SArtem B. Bityutskiy ref = ref->next_in_ino; 102f97117d1SArtem B. Bityutskiy } 103f97117d1SArtem B. Bityutskiy return NULL; 104f97117d1SArtem B. Bityutskiy } 105f97117d1SArtem B. Bityutskiy 106f97117d1SArtem B. Bityutskiy /* 107f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 108f97117d1SArtem B. Bityutskiy * It is called every time an directory entry node is found. 109f97117d1SArtem B. Bityutskiy * 110f97117d1SArtem B. Bityutskiy * Returns: 0 on succes; 111f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 112f97117d1SArtem B. Bityutskiy * negative error code on failure. 113f97117d1SArtem B. Bityutskiy */ 1141e0da3cbSArtem B. Bityutskiy static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 1150ef675d4SAtsushi Nemoto struct jffs2_raw_dirent *rd, size_t read, struct jffs2_full_dirent **fdp, 1161e0da3cbSArtem B. Bityutskiy uint32_t *latest_mctime, uint32_t *mctime_ver) 117f97117d1SArtem B. Bityutskiy { 118f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *fd; 1191046d880SDavid Woodhouse uint32_t crc; 120f97117d1SArtem B. Bityutskiy 121f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 122f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 123f97117d1SArtem B. Bityutskiy 1241046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 1251046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 1261046d880SDavid Woodhouse JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", 1271046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 1281046d880SDavid Woodhouse return 1; 1291046d880SDavid Woodhouse } 1301046d880SDavid Woodhouse 1311046d880SDavid Woodhouse /* If we've never checked the CRCs on this node, check them now */ 1321046d880SDavid Woodhouse if (ref_flags(ref) == REF_UNCHECKED) { 1331046d880SDavid Woodhouse struct jffs2_eraseblock *jeb; 1341046d880SDavid Woodhouse int len; 1351046d880SDavid Woodhouse 136f97117d1SArtem B. Bityutskiy /* Sanity check */ 137f97117d1SArtem B. Bityutskiy if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { 138e0d60137SArtem B. Bityutskiy JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", 139f97117d1SArtem B. Bityutskiy ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); 140f97117d1SArtem B. Bityutskiy return 1; 141f97117d1SArtem B. Bityutskiy } 142f97117d1SArtem B. Bityutskiy 1431046d880SDavid Woodhouse jeb = &c->blocks[ref->flash_offset / c->sector_size]; 1441046d880SDavid Woodhouse len = ref_totlen(c, jeb, ref); 1451046d880SDavid Woodhouse 1461046d880SDavid Woodhouse spin_lock(&c->erase_completion_lock); 1471046d880SDavid Woodhouse jeb->used_size += len; 1481046d880SDavid Woodhouse jeb->unchecked_size -= len; 1491046d880SDavid Woodhouse c->used_size += len; 1501046d880SDavid Woodhouse c->unchecked_size -= len; 1511046d880SDavid Woodhouse ref->flash_offset = ref_offset(ref) | REF_PRISTINE; 1521046d880SDavid Woodhouse spin_unlock(&c->erase_completion_lock); 1531046d880SDavid Woodhouse } 1541046d880SDavid Woodhouse 155f97117d1SArtem B. Bityutskiy fd = jffs2_alloc_full_dirent(rd->nsize + 1); 156f97117d1SArtem B. Bityutskiy if (unlikely(!fd)) 157f97117d1SArtem B. Bityutskiy return -ENOMEM; 158f97117d1SArtem B. Bityutskiy 159f97117d1SArtem B. Bityutskiy fd->raw = ref; 160f97117d1SArtem B. Bityutskiy fd->version = je32_to_cpu(rd->version); 161f97117d1SArtem B. Bityutskiy fd->ino = je32_to_cpu(rd->ino); 162f97117d1SArtem B. Bityutskiy fd->type = rd->type; 163f97117d1SArtem B. Bityutskiy 164f97117d1SArtem B. Bityutskiy /* Pick out the mctime of the latest dirent */ 1653a69e0cdSArtem B. Bityutskiy if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) { 166f97117d1SArtem B. Bityutskiy *mctime_ver = fd->version; 167f97117d1SArtem B. Bityutskiy *latest_mctime = je32_to_cpu(rd->mctime); 168f97117d1SArtem B. Bityutskiy } 169f97117d1SArtem B. Bityutskiy 170f97117d1SArtem B. Bityutskiy /* 171f97117d1SArtem B. Bityutskiy * Copy as much of the name as possible from the raw 172f97117d1SArtem B. Bityutskiy * dirent we've already read from the flash. 173f97117d1SArtem B. Bityutskiy */ 174f97117d1SArtem B. Bityutskiy if (read > sizeof(*rd)) 175f97117d1SArtem B. Bityutskiy memcpy(&fd->name[0], &rd->name[0], 176f97117d1SArtem B. Bityutskiy min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); 177f97117d1SArtem B. Bityutskiy 178f97117d1SArtem B. Bityutskiy /* Do we need to copy any more of the name directly from the flash? */ 179f97117d1SArtem B. Bityutskiy if (rd->nsize + sizeof(*rd) > read) { 180f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 181f97117d1SArtem B. Bityutskiy int err; 182f97117d1SArtem B. Bityutskiy int already = read - sizeof(*rd); 183f97117d1SArtem B. Bityutskiy 184f97117d1SArtem B. Bityutskiy err = jffs2_flash_read(c, (ref_offset(ref)) + read, 185f97117d1SArtem B. Bityutskiy rd->nsize - already, &read, &fd->name[already]); 186f97117d1SArtem B. Bityutskiy if (unlikely(read != rd->nsize - already) && likely(!err)) 187f97117d1SArtem B. Bityutskiy return -EIO; 188f97117d1SArtem B. Bityutskiy 189f97117d1SArtem B. Bityutskiy if (unlikely(err)) { 190e0d60137SArtem B. Bityutskiy JFFS2_ERROR("read remainder of name: error %d\n", err); 191f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent(fd); 192f97117d1SArtem B. Bityutskiy return -EIO; 193f97117d1SArtem B. Bityutskiy } 194f97117d1SArtem B. Bityutskiy } 195f97117d1SArtem B. Bityutskiy 196f97117d1SArtem B. Bityutskiy fd->nhash = full_name_hash(fd->name, rd->nsize); 197f97117d1SArtem B. Bityutskiy fd->next = NULL; 198f97117d1SArtem B. Bityutskiy fd->name[rd->nsize] = '\0'; 199f97117d1SArtem B. Bityutskiy 200f97117d1SArtem B. Bityutskiy /* 201f97117d1SArtem B. Bityutskiy * Wheee. We now have a complete jffs2_full_dirent structure, with 202f97117d1SArtem B. Bityutskiy * the name in it and everything. Link it into the list 203f97117d1SArtem B. Bityutskiy */ 204f97117d1SArtem B. Bityutskiy jffs2_add_fd_to_list(c, fd, fdp); 205f97117d1SArtem B. Bityutskiy 206f97117d1SArtem B. Bityutskiy return 0; 207f97117d1SArtem B. Bityutskiy } 208f97117d1SArtem B. Bityutskiy 209f97117d1SArtem B. Bityutskiy /* 210f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 211f97117d1SArtem B. Bityutskiy * It is called every time an inode node is found. 212f97117d1SArtem B. Bityutskiy * 213f97117d1SArtem B. Bityutskiy * Returns: 0 on succes; 214f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 215f97117d1SArtem B. Bityutskiy * negative error code on failure. 216f97117d1SArtem B. Bityutskiy */ 2171e0da3cbSArtem B. Bityutskiy static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 2181e0da3cbSArtem B. Bityutskiy struct jffs2_raw_inode *rd, struct rb_root *tnp, int rdlen, 2191e0da3cbSArtem B. Bityutskiy uint32_t *latest_mctime, uint32_t *mctime_ver) 220f97117d1SArtem B. Bityutskiy { 221f97117d1SArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 2221e0da3cbSArtem B. Bityutskiy uint32_t len, csize; 2231e0da3cbSArtem B. Bityutskiy int ret = 1; 2241046d880SDavid Woodhouse uint32_t crc; 225f97117d1SArtem B. Bityutskiy 226f97117d1SArtem B. Bityutskiy /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ 227f97117d1SArtem B. Bityutskiy BUG_ON(ref_obsolete(ref)); 228f97117d1SArtem B. Bityutskiy 2291046d880SDavid Woodhouse crc = crc32(0, rd, sizeof(*rd) - 8); 2301046d880SDavid Woodhouse if (unlikely(crc != je32_to_cpu(rd->node_crc))) { 2311046d880SDavid Woodhouse JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", 2321046d880SDavid Woodhouse ref_offset(ref), je32_to_cpu(rd->node_crc), crc); 2331046d880SDavid Woodhouse return 1; 2341046d880SDavid Woodhouse } 2351046d880SDavid Woodhouse 2361e0da3cbSArtem B. Bityutskiy tn = jffs2_alloc_tmp_dnode_info(); 2371e0da3cbSArtem B. Bityutskiy if (!tn) { 238fb6a82c9SRandy Dunlap JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn)); 2391e0da3cbSArtem B. Bityutskiy return -ENOMEM; 2401e0da3cbSArtem B. Bityutskiy } 2411e0da3cbSArtem B. Bityutskiy 2421e0da3cbSArtem B. Bityutskiy tn->partial_crc = 0; 2431e0da3cbSArtem B. Bityutskiy csize = je32_to_cpu(rd->csize); 2441e0da3cbSArtem B. Bityutskiy 245f97117d1SArtem B. Bityutskiy /* If we've never checked the CRCs on this node, check them now */ 246f97117d1SArtem B. Bityutskiy if (ref_flags(ref) == REF_UNCHECKED) { 247f97117d1SArtem B. Bityutskiy 248f97117d1SArtem B. Bityutskiy /* Sanity checks */ 249f97117d1SArtem B. Bityutskiy if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || 250f97117d1SArtem B. Bityutskiy unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { 251e0d60137SArtem B. Bityutskiy JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); 252737b7661SAndrew Lunn jffs2_dbg_dump_node(c, ref_offset(ref)); 2531e0da3cbSArtem B. Bityutskiy goto free_out; 254f97117d1SArtem B. Bityutskiy } 255f97117d1SArtem B. Bityutskiy 2561e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c) && csize != 0) { 2571e0da3cbSArtem B. Bityutskiy /* At this point we are supposed to check the data CRC 2581e0da3cbSArtem B. Bityutskiy * of our unchecked node. But thus far, we do not 2591e0da3cbSArtem B. Bityutskiy * know whether the node is valid or obsolete. To 2601e0da3cbSArtem B. Bityutskiy * figure this out, we need to walk all the nodes of 2611e0da3cbSArtem B. Bityutskiy * the inode and build the inode fragtree. We don't 2621e0da3cbSArtem B. Bityutskiy * want to spend time checking data of nodes which may 2631e0da3cbSArtem B. Bityutskiy * later be found to be obsolete. So we put off the full 2641e0da3cbSArtem B. Bityutskiy * data CRC checking until we have read all the inode 2651e0da3cbSArtem B. Bityutskiy * nodes and have started building the fragtree. 2661e0da3cbSArtem B. Bityutskiy * 2671e0da3cbSArtem B. Bityutskiy * The fragtree is being built starting with nodes 2681e0da3cbSArtem B. Bityutskiy * having the highest version number, so we'll be able 2691e0da3cbSArtem B. Bityutskiy * to detect whether a node is valid (i.e., it is not 2701e0da3cbSArtem B. Bityutskiy * overlapped by a node with higher version) or not. 2711e0da3cbSArtem B. Bityutskiy * And we'll be able to check only those nodes, which 2721e0da3cbSArtem B. Bityutskiy * are not obsolete. 2731e0da3cbSArtem B. Bityutskiy * 2741e0da3cbSArtem B. Bityutskiy * Of course, this optimization only makes sense in case 2751e0da3cbSArtem B. Bityutskiy * of NAND flashes (or other flashes whith 2761e0da3cbSArtem B. Bityutskiy * !jffs2_can_mark_obsolete()), since on NOR flashes 2771e0da3cbSArtem B. Bityutskiy * nodes are marked obsolete physically. 2781e0da3cbSArtem B. Bityutskiy * 2791e0da3cbSArtem B. Bityutskiy * Since NAND flashes (or other flashes with 2801e0da3cbSArtem B. Bityutskiy * jffs2_is_writebuffered(c)) are anyway read by 2811e0da3cbSArtem B. Bityutskiy * fractions of c->wbuf_pagesize, and we have just read 2821e0da3cbSArtem B. Bityutskiy * the node header, it is likely that the starting part 2831e0da3cbSArtem B. Bityutskiy * of the node data is also read when we read the 2841e0da3cbSArtem B. Bityutskiy * header. So we don't mind to check the CRC of the 2851e0da3cbSArtem B. Bityutskiy * starting part of the data of the node now, and check 2861e0da3cbSArtem B. Bityutskiy * the second part later (in jffs2_check_node_data()). 2871e0da3cbSArtem B. Bityutskiy * Of course, we will not need to re-read and re-check 2881e0da3cbSArtem B. Bityutskiy * the NAND page which we have just read. This is why we 2891e0da3cbSArtem B. Bityutskiy * read the whole NAND page at jffs2_get_inode_nodes(), 2901e0da3cbSArtem B. Bityutskiy * while we needed only the node header. 2911e0da3cbSArtem B. Bityutskiy */ 2921e0da3cbSArtem B. Bityutskiy unsigned char *buf; 293f97117d1SArtem B. Bityutskiy 2941e0da3cbSArtem B. Bityutskiy /* 'buf' will point to the start of data */ 2951e0da3cbSArtem B. Bityutskiy buf = (unsigned char *)rd + sizeof(*rd); 2961e0da3cbSArtem B. Bityutskiy /* len will be the read data length */ 2971e0da3cbSArtem B. Bityutskiy len = min_t(uint32_t, rdlen - sizeof(*rd), csize); 298280562b2SArtem B. Bityutskiy tn->partial_crc = crc32(0, buf, len); 299f97117d1SArtem B. Bityutskiy 300733802d9SArtem B. Bityutskiy dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize); 301f97117d1SArtem B. Bityutskiy 3021e0da3cbSArtem B. Bityutskiy /* If we actually calculated the whole data CRC 3031e0da3cbSArtem B. Bityutskiy * and it is wrong, drop the node. */ 3043c091337SArtem B. Bityutskiy if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { 30539243508SArtem B. Bityutskiy JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", 30639243508SArtem B. Bityutskiy ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); 3071e0da3cbSArtem B. Bityutskiy goto free_out; 30839243508SArtem B. Bityutskiy } 309f97117d1SArtem B. Bityutskiy 3101e0da3cbSArtem B. Bityutskiy } else if (csize == 0) { 3111e0da3cbSArtem B. Bityutskiy /* 3121e0da3cbSArtem B. Bityutskiy * We checked the header CRC. If the node has no data, adjust 3131e0da3cbSArtem B. Bityutskiy * the space accounting now. For other nodes this will be done 3141e0da3cbSArtem B. Bityutskiy * later either when the node is marked obsolete or when its 3151e0da3cbSArtem B. Bityutskiy * data is checked. 3161e0da3cbSArtem B. Bityutskiy */ 3171e0da3cbSArtem B. Bityutskiy struct jffs2_eraseblock *jeb; 3181e0da3cbSArtem B. Bityutskiy 319733802d9SArtem B. Bityutskiy dbg_readinode("the node has no data.\n"); 320f97117d1SArtem B. Bityutskiy jeb = &c->blocks[ref->flash_offset / c->sector_size]; 321f97117d1SArtem B. Bityutskiy len = ref_totlen(c, jeb, ref); 322f97117d1SArtem B. Bityutskiy 323f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 324f97117d1SArtem B. Bityutskiy jeb->used_size += len; 325f97117d1SArtem B. Bityutskiy jeb->unchecked_size -= len; 326f97117d1SArtem B. Bityutskiy c->used_size += len; 327f97117d1SArtem B. Bityutskiy c->unchecked_size -= len; 328f97117d1SArtem B. Bityutskiy ref->flash_offset = ref_offset(ref) | REF_NORMAL; 329f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 330f97117d1SArtem B. Bityutskiy } 331f97117d1SArtem B. Bityutskiy } 332f97117d1SArtem B. Bityutskiy 333f97117d1SArtem B. Bityutskiy tn->fn = jffs2_alloc_full_dnode(); 334f97117d1SArtem B. Bityutskiy if (!tn->fn) { 335e0d60137SArtem B. Bityutskiy JFFS2_ERROR("alloc fn failed\n"); 3361e0da3cbSArtem B. Bityutskiy ret = -ENOMEM; 3371e0da3cbSArtem B. Bityutskiy goto free_out; 338f97117d1SArtem B. Bityutskiy } 339f97117d1SArtem B. Bityutskiy 340f97117d1SArtem B. Bityutskiy tn->version = je32_to_cpu(rd->version); 341f97117d1SArtem B. Bityutskiy tn->fn->ofs = je32_to_cpu(rd->offset); 3421e0da3cbSArtem B. Bityutskiy tn->data_crc = je32_to_cpu(rd->data_crc); 3431e0da3cbSArtem B. Bityutskiy tn->csize = csize; 344f97117d1SArtem B. Bityutskiy tn->fn->raw = ref; 345f97117d1SArtem B. Bityutskiy 346f97117d1SArtem B. Bityutskiy /* There was a bug where we wrote hole nodes out with 347f97117d1SArtem B. Bityutskiy csize/dsize swapped. Deal with it */ 3481e0da3cbSArtem B. Bityutskiy if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize) 3491e0da3cbSArtem B. Bityutskiy tn->fn->size = csize; 350f97117d1SArtem B. Bityutskiy else // normal case... 351f97117d1SArtem B. Bityutskiy tn->fn->size = je32_to_cpu(rd->dsize); 352f97117d1SArtem B. Bityutskiy 353733802d9SArtem B. Bityutskiy dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", 354280562b2SArtem B. Bityutskiy ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); 355f97117d1SArtem B. Bityutskiy 356f97117d1SArtem B. Bityutskiy jffs2_add_tn_to_tree(tn, tnp); 357f97117d1SArtem B. Bityutskiy 358f97117d1SArtem B. Bityutskiy return 0; 3591e0da3cbSArtem B. Bityutskiy 3601e0da3cbSArtem B. Bityutskiy free_out: 3611e0da3cbSArtem B. Bityutskiy jffs2_free_tmp_dnode_info(tn); 3621e0da3cbSArtem B. Bityutskiy return ret; 363f97117d1SArtem B. Bityutskiy } 364f97117d1SArtem B. Bityutskiy 365f97117d1SArtem B. Bityutskiy /* 366f97117d1SArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 367f97117d1SArtem B. Bityutskiy * It is called every time an unknown node is found. 368f97117d1SArtem B. Bityutskiy * 3693877f0b6SDavid Woodhouse * Returns: 0 on success; 370f97117d1SArtem B. Bityutskiy * 1 if the node should be marked obsolete; 371f97117d1SArtem B. Bityutskiy * negative error code on failure. 372f97117d1SArtem B. Bityutskiy */ 3731e0da3cbSArtem B. Bityutskiy static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) 374f97117d1SArtem B. Bityutskiy { 375f97117d1SArtem B. Bityutskiy /* We don't mark unknown nodes as REF_UNCHECKED */ 376f97117d1SArtem B. Bityutskiy BUG_ON(ref_flags(ref) == REF_UNCHECKED); 377f97117d1SArtem B. Bityutskiy 378f97117d1SArtem B. Bityutskiy un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); 379f97117d1SArtem B. Bityutskiy 380f97117d1SArtem B. Bityutskiy switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) { 381f97117d1SArtem B. Bityutskiy 382f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_INCOMPAT: 383e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n", 384f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 385f97117d1SArtem B. Bityutskiy /* EEP */ 386f97117d1SArtem B. Bityutskiy BUG(); 387f97117d1SArtem B. Bityutskiy break; 388f97117d1SArtem B. Bityutskiy 389f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_ROCOMPAT: 390e0d60137SArtem B. Bityutskiy JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n", 391f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 392f97117d1SArtem B. Bityutskiy BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); 393f97117d1SArtem B. Bityutskiy break; 394f97117d1SArtem B. Bityutskiy 395f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_COPY: 396e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n", 397f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 398f97117d1SArtem B. Bityutskiy break; 399f97117d1SArtem B. Bityutskiy 400f97117d1SArtem B. Bityutskiy case JFFS2_FEATURE_RWCOMPAT_DELETE: 401e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", 402f97117d1SArtem B. Bityutskiy je16_to_cpu(un->nodetype), ref_offset(ref)); 403f97117d1SArtem B. Bityutskiy return 1; 404f97117d1SArtem B. Bityutskiy } 405f97117d1SArtem B. Bityutskiy 406f97117d1SArtem B. Bityutskiy return 0; 407f97117d1SArtem B. Bityutskiy } 408f97117d1SArtem B. Bityutskiy 4091e0da3cbSArtem B. Bityutskiy /* 4101e0da3cbSArtem B. Bityutskiy * Helper function for jffs2_get_inode_nodes(). 4111e0da3cbSArtem B. Bityutskiy * The function detects whether more data should be read and reads it if yes. 4121e0da3cbSArtem B. Bityutskiy * 4131e0da3cbSArtem B. Bityutskiy * Returns: 0 on succes; 4141e0da3cbSArtem B. Bityutskiy * negative error code on failure. 4151e0da3cbSArtem B. Bityutskiy */ 4161e0da3cbSArtem B. Bityutskiy static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, 4171e0da3cbSArtem B. Bityutskiy int right_size, int *rdlen, unsigned char *buf, unsigned char *bufstart) 4181e0da3cbSArtem B. Bityutskiy { 4191e0da3cbSArtem B. Bityutskiy int right_len, err, len; 4201e0da3cbSArtem B. Bityutskiy size_t retlen; 4211e0da3cbSArtem B. Bityutskiy uint32_t offs; 4221e0da3cbSArtem B. Bityutskiy 4231e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 4241e0da3cbSArtem B. Bityutskiy right_len = c->wbuf_pagesize - (bufstart - buf); 4251e0da3cbSArtem B. Bityutskiy if (right_size + (int)(bufstart - buf) > c->wbuf_pagesize) 4261e0da3cbSArtem B. Bityutskiy right_len += c->wbuf_pagesize; 4271e0da3cbSArtem B. Bityutskiy } else 4281e0da3cbSArtem B. Bityutskiy right_len = right_size; 4291e0da3cbSArtem B. Bityutskiy 4301e0da3cbSArtem B. Bityutskiy if (*rdlen == right_len) 4311e0da3cbSArtem B. Bityutskiy return 0; 4321e0da3cbSArtem B. Bityutskiy 4331e0da3cbSArtem B. Bityutskiy /* We need to read more data */ 4341e0da3cbSArtem B. Bityutskiy offs = ref_offset(ref) + *rdlen; 4351e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 4361e0da3cbSArtem B. Bityutskiy bufstart = buf + c->wbuf_pagesize; 4371e0da3cbSArtem B. Bityutskiy len = c->wbuf_pagesize; 4381e0da3cbSArtem B. Bityutskiy } else { 4391e0da3cbSArtem B. Bityutskiy bufstart = buf + *rdlen; 4401e0da3cbSArtem B. Bityutskiy len = right_size - *rdlen; 4411e0da3cbSArtem B. Bityutskiy } 4421e0da3cbSArtem B. Bityutskiy 443733802d9SArtem B. Bityutskiy dbg_readinode("read more %d bytes\n", len); 4441e0da3cbSArtem B. Bityutskiy 4451e0da3cbSArtem B. Bityutskiy err = jffs2_flash_read(c, offs, len, &retlen, bufstart); 4461e0da3cbSArtem B. Bityutskiy if (err) { 4471e0da3cbSArtem B. Bityutskiy JFFS2_ERROR("can not read %d bytes from 0x%08x, " 4481e0da3cbSArtem B. Bityutskiy "error code: %d.\n", len, offs, err); 4491e0da3cbSArtem B. Bityutskiy return err; 4501e0da3cbSArtem B. Bityutskiy } 4511e0da3cbSArtem B. Bityutskiy 4521e0da3cbSArtem B. Bityutskiy if (retlen < len) { 453fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", 4541e0da3cbSArtem B. Bityutskiy offs, retlen, len); 4551e0da3cbSArtem B. Bityutskiy return -EIO; 4561e0da3cbSArtem B. Bityutskiy } 4571e0da3cbSArtem B. Bityutskiy 4581e0da3cbSArtem B. Bityutskiy *rdlen = right_len; 4591e0da3cbSArtem B. Bityutskiy 4601e0da3cbSArtem B. Bityutskiy return 0; 4611e0da3cbSArtem B. Bityutskiy } 4621e0da3cbSArtem B. Bityutskiy 463f97117d1SArtem B. Bityutskiy /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated 464f97117d1SArtem B. Bityutskiy with this ino, returning the former in order of version */ 465f97117d1SArtem B. Bityutskiy static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 466f97117d1SArtem B. Bityutskiy struct rb_root *tnp, struct jffs2_full_dirent **fdp, 467f97117d1SArtem B. Bityutskiy uint32_t *highest_version, uint32_t *latest_mctime, 468f97117d1SArtem B. Bityutskiy uint32_t *mctime_ver) 469f97117d1SArtem B. Bityutskiy { 470f97117d1SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref, *valid_ref; 471f97117d1SArtem B. Bityutskiy struct rb_root ret_tn = RB_ROOT; 472f97117d1SArtem B. Bityutskiy struct jffs2_full_dirent *ret_fd = NULL; 4731e0da3cbSArtem B. Bityutskiy unsigned char *buf = NULL; 4741e0da3cbSArtem B. Bityutskiy union jffs2_node_union *node; 475f97117d1SArtem B. Bityutskiy size_t retlen; 4761e0da3cbSArtem B. Bityutskiy int len, err; 477f97117d1SArtem B. Bityutskiy 478f97117d1SArtem B. Bityutskiy *mctime_ver = 0; 479f97117d1SArtem B. Bityutskiy 480733802d9SArtem B. Bityutskiy dbg_readinode("ino #%u\n", f->inocache->ino); 481f97117d1SArtem B. Bityutskiy 4821e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 4831e0da3cbSArtem B. Bityutskiy /* 4841e0da3cbSArtem B. Bityutskiy * If we have the write buffer, we assume the minimal I/O unit 4851e0da3cbSArtem B. Bityutskiy * is c->wbuf_pagesize. We implement some optimizations which in 4861e0da3cbSArtem B. Bityutskiy * this case and we need a temporary buffer of size = 4871e0da3cbSArtem B. Bityutskiy * 2*c->wbuf_pagesize bytes (see comments in read_dnode()). 4881e0da3cbSArtem B. Bityutskiy * Basically, we want to read not only the node header, but the 4891e0da3cbSArtem B. Bityutskiy * whole wbuf (NAND page in case of NAND) or 2, if the node 4901e0da3cbSArtem B. Bityutskiy * header overlaps the border between the 2 wbufs. 4911e0da3cbSArtem B. Bityutskiy */ 4921e0da3cbSArtem B. Bityutskiy len = 2*c->wbuf_pagesize; 4931e0da3cbSArtem B. Bityutskiy } else { 4941e0da3cbSArtem B. Bityutskiy /* 4951e0da3cbSArtem B. Bityutskiy * When there is no write buffer, the size of the temporary 4961e0da3cbSArtem B. Bityutskiy * buffer is the size of the larges node header. 4971e0da3cbSArtem B. Bityutskiy */ 4981e0da3cbSArtem B. Bityutskiy len = sizeof(union jffs2_node_union); 4991e0da3cbSArtem B. Bityutskiy } 5001e0da3cbSArtem B. Bityutskiy 5011e0da3cbSArtem B. Bityutskiy /* FIXME: in case of NOR and available ->point() this 5021e0da3cbSArtem B. Bityutskiy * needs to be fixed. */ 5031e0da3cbSArtem B. Bityutskiy buf = kmalloc(len, GFP_KERNEL); 5041e0da3cbSArtem B. Bityutskiy if (!buf) 5051e0da3cbSArtem B. Bityutskiy return -ENOMEM; 5061e0da3cbSArtem B. Bityutskiy 507f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 508f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(f->inocache->nodes); 5091e0da3cbSArtem B. Bityutskiy if (!valid_ref && f->inocache->ino != 1) 5101e0da3cbSArtem B. Bityutskiy JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); 511f97117d1SArtem B. Bityutskiy while (valid_ref) { 5121e0da3cbSArtem B. Bityutskiy unsigned char *bufstart; 5131e0da3cbSArtem B. Bityutskiy 514f97117d1SArtem B. Bityutskiy /* We can hold a pointer to a non-obsolete node without the spinlock, 515f97117d1SArtem B. Bityutskiy but _obsolete_ nodes may disappear at any time, if the block 516f97117d1SArtem B. Bityutskiy they're in gets erased. So if we mark 'ref' obsolete while we're 517f97117d1SArtem B. Bityutskiy not holding the lock, it can go away immediately. For that reason, 518f97117d1SArtem B. Bityutskiy we find the next valid node first, before processing 'ref'. 519f97117d1SArtem B. Bityutskiy */ 520f97117d1SArtem B. Bityutskiy ref = valid_ref; 521f97117d1SArtem B. Bityutskiy valid_ref = jffs2_first_valid_node(ref->next_in_ino); 522f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 523f97117d1SArtem B. Bityutskiy 524f97117d1SArtem B. Bityutskiy cond_resched(); 525f97117d1SArtem B. Bityutskiy 5261e0da3cbSArtem B. Bityutskiy /* 5271e0da3cbSArtem B. Bityutskiy * At this point we don't know the type of the node we're going 5281e0da3cbSArtem B. Bityutskiy * to read, so we do not know the size of its header. In order 5291e0da3cbSArtem B. Bityutskiy * to minimize the amount of flash IO we assume the node has 5301e0da3cbSArtem B. Bityutskiy * size = JFFS2_MIN_NODE_HEADER. 5311e0da3cbSArtem B. Bityutskiy */ 5321e0da3cbSArtem B. Bityutskiy if (jffs2_is_writebuffered(c)) { 5331e0da3cbSArtem B. Bityutskiy /* 5341e0da3cbSArtem B. Bityutskiy * We treat 'buf' as 2 adjacent wbufs. We want to 5351e0da3cbSArtem B. Bityutskiy * adjust bufstart such as it points to the 5361e0da3cbSArtem B. Bityutskiy * beginning of the node within this wbuf. 5371e0da3cbSArtem B. Bityutskiy */ 5381e0da3cbSArtem B. Bityutskiy bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize); 5391e0da3cbSArtem B. Bityutskiy /* We will read either one wbuf or 2 wbufs. */ 5401e0da3cbSArtem B. Bityutskiy len = c->wbuf_pagesize - (bufstart - buf); 54139243508SArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER + (int)(bufstart - buf) > c->wbuf_pagesize) { 54239243508SArtem B. Bityutskiy /* The header spans the border of the first wbuf */ 5431e0da3cbSArtem B. Bityutskiy len += c->wbuf_pagesize; 5441e0da3cbSArtem B. Bityutskiy } 5451e0da3cbSArtem B. Bityutskiy } else { 5461e0da3cbSArtem B. Bityutskiy bufstart = buf; 5471e0da3cbSArtem B. Bityutskiy len = JFFS2_MIN_NODE_HEADER; 5481e0da3cbSArtem B. Bityutskiy } 5491e0da3cbSArtem B. Bityutskiy 550733802d9SArtem B. Bityutskiy dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); 5511e0da3cbSArtem B. Bityutskiy 552f97117d1SArtem B. Bityutskiy /* FIXME: point() */ 5531e0da3cbSArtem B. Bityutskiy err = jffs2_flash_read(c, ref_offset(ref), len, 5541e0da3cbSArtem B. Bityutskiy &retlen, bufstart); 555f97117d1SArtem B. Bityutskiy if (err) { 5561e0da3cbSArtem B. Bityutskiy JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err); 557f97117d1SArtem B. Bityutskiy goto free_out; 558f97117d1SArtem B. Bityutskiy } 559f97117d1SArtem B. Bityutskiy 5601e0da3cbSArtem B. Bityutskiy if (retlen < len) { 561fb6a82c9SRandy Dunlap JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", ref_offset(ref), retlen, len); 562f97117d1SArtem B. Bityutskiy err = -EIO; 563f97117d1SArtem B. Bityutskiy goto free_out; 564f97117d1SArtem B. Bityutskiy } 565f97117d1SArtem B. Bityutskiy 5661e0da3cbSArtem B. Bityutskiy node = (union jffs2_node_union *)bufstart; 5671e0da3cbSArtem B. Bityutskiy 5683877f0b6SDavid Woodhouse /* No need to mask in the valid bit; it shouldn't be invalid */ 5693877f0b6SDavid Woodhouse if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { 5703877f0b6SDavid Woodhouse JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n", 5713877f0b6SDavid Woodhouse ref_offset(ref), je16_to_cpu(node->u.magic), 5723877f0b6SDavid Woodhouse je16_to_cpu(node->u.nodetype), 5733877f0b6SDavid Woodhouse je32_to_cpu(node->u.totlen), 5743877f0b6SDavid Woodhouse je32_to_cpu(node->u.hdr_crc)); 5753877f0b6SDavid Woodhouse jffs2_dbg_dump_node(c, ref_offset(ref)); 5763877f0b6SDavid Woodhouse jffs2_mark_node_obsolete(c, ref); 5773877f0b6SDavid Woodhouse goto cont; 5783877f0b6SDavid Woodhouse } 5793877f0b6SDavid Woodhouse 5801e0da3cbSArtem B. Bityutskiy switch (je16_to_cpu(node->u.nodetype)) { 5811e0da3cbSArtem B. Bityutskiy 5821e0da3cbSArtem B. Bityutskiy case JFFS2_NODETYPE_DIRENT: 5831e0da3cbSArtem B. Bityutskiy 5841e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) { 5851e0da3cbSArtem B. Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart); 5861e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 5871e0da3cbSArtem B. Bityutskiy goto free_out; 5881e0da3cbSArtem B. Bityutskiy } 5891e0da3cbSArtem B. Bityutskiy 5901e0da3cbSArtem B. Bityutskiy err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver); 591f97117d1SArtem B. Bityutskiy if (err == 1) { 592f97117d1SArtem B. Bityutskiy jffs2_mark_node_obsolete(c, ref); 593f97117d1SArtem B. Bityutskiy break; 594f97117d1SArtem B. Bityutskiy } else if (unlikely(err)) 595f97117d1SArtem B. Bityutskiy goto free_out; 596f97117d1SArtem B. Bityutskiy 5971e0da3cbSArtem B. Bityutskiy if (je32_to_cpu(node->d.version) > *highest_version) 5981e0da3cbSArtem B. Bityutskiy *highest_version = je32_to_cpu(node->d.version); 599f97117d1SArtem B. Bityutskiy 600f97117d1SArtem B. Bityutskiy break; 601f97117d1SArtem B. Bityutskiy 602f97117d1SArtem B. Bityutskiy case JFFS2_NODETYPE_INODE: 603f97117d1SArtem B. Bityutskiy 6041e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) { 6051e0da3cbSArtem B. Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart); 6061e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 607f97117d1SArtem B. Bityutskiy goto free_out; 608f97117d1SArtem B. Bityutskiy } 609f97117d1SArtem B. Bityutskiy 6101e0da3cbSArtem B. Bityutskiy err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver); 611f97117d1SArtem B. Bityutskiy if (err == 1) { 612f97117d1SArtem B. Bityutskiy jffs2_mark_node_obsolete(c, ref); 613f97117d1SArtem B. Bityutskiy break; 614f97117d1SArtem B. Bityutskiy } else if (unlikely(err)) 615f97117d1SArtem B. Bityutskiy goto free_out; 616f97117d1SArtem B. Bityutskiy 6171e0da3cbSArtem B. Bityutskiy if (je32_to_cpu(node->i.version) > *highest_version) 6181e0da3cbSArtem B. Bityutskiy *highest_version = je32_to_cpu(node->i.version); 619f97117d1SArtem B. Bityutskiy 6201da177e4SLinus Torvalds break; 6211da177e4SLinus Torvalds 6221da177e4SLinus Torvalds default: 6231e0da3cbSArtem B. Bityutskiy if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) { 6241e0da3cbSArtem B. Bityutskiy err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart); 6251e0da3cbSArtem B. Bityutskiy if (unlikely(err)) 6261e0da3cbSArtem B. Bityutskiy goto free_out; 6271da177e4SLinus Torvalds } 6281da177e4SLinus Torvalds 6291e0da3cbSArtem B. Bityutskiy err = read_unknown(c, ref, &node->u); 630f97117d1SArtem B. Bityutskiy if (err == 1) { 631f97117d1SArtem B. Bityutskiy jffs2_mark_node_obsolete(c, ref); 632f97117d1SArtem B. Bityutskiy break; 633f97117d1SArtem B. Bityutskiy } else if (unlikely(err)) 634f97117d1SArtem B. Bityutskiy goto free_out; 635f97117d1SArtem B. Bityutskiy 6361da177e4SLinus Torvalds } 6373877f0b6SDavid Woodhouse cont: 638f97117d1SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock); 6391da177e4SLinus Torvalds } 6401e0da3cbSArtem B. Bityutskiy 641f97117d1SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock); 642f97117d1SArtem B. Bityutskiy *tnp = ret_tn; 643f97117d1SArtem B. Bityutskiy *fdp = ret_fd; 6441e0da3cbSArtem B. Bityutskiy kfree(buf); 645f97117d1SArtem B. Bityutskiy 646733802d9SArtem B. Bityutskiy dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n", 6471e0da3cbSArtem B. Bityutskiy f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver); 648f97117d1SArtem B. Bityutskiy return 0; 649f97117d1SArtem B. Bityutskiy 650f97117d1SArtem B. Bityutskiy free_out: 651f97117d1SArtem B. Bityutskiy jffs2_free_tmp_dnode_info_list(&ret_tn); 652f97117d1SArtem B. Bityutskiy jffs2_free_full_dirent_list(ret_fd); 6531e0da3cbSArtem B. Bityutskiy kfree(buf); 654f97117d1SArtem B. Bityutskiy return err; 6551da177e4SLinus Torvalds } 6561da177e4SLinus Torvalds 6571da177e4SLinus Torvalds static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 6581da177e4SLinus Torvalds struct jffs2_inode_info *f, 6591da177e4SLinus Torvalds struct jffs2_raw_inode *latest_node) 6601da177e4SLinus Torvalds { 6611e0da3cbSArtem B. Bityutskiy struct jffs2_tmp_dnode_info *tn; 6629dee7503SDavid Woodhouse struct rb_root tn_list; 6639dee7503SDavid Woodhouse struct rb_node *rb, *repl_rb; 6641da177e4SLinus Torvalds struct jffs2_full_dirent *fd_list; 6651e0da3cbSArtem B. Bityutskiy struct jffs2_full_dnode *fn, *first_fn = NULL; 6661da177e4SLinus Torvalds uint32_t crc; 6671da177e4SLinus Torvalds uint32_t latest_mctime, mctime_ver; 6681da177e4SLinus Torvalds size_t retlen; 6691da177e4SLinus Torvalds int ret; 6701da177e4SLinus Torvalds 671733802d9SArtem B. Bityutskiy dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* Grab all nodes relevant to this ino */ 6741da177e4SLinus Torvalds ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); 6751da177e4SLinus Torvalds 6761da177e4SLinus Torvalds if (ret) { 677e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); 6781da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 6791da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 6801da177e4SLinus Torvalds return ret; 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds f->dents = fd_list; 6831da177e4SLinus Torvalds 6849dee7503SDavid Woodhouse rb = rb_first(&tn_list); 6851da177e4SLinus Torvalds 6869dee7503SDavid Woodhouse while (rb) { 6871e0da3cbSArtem B. Bityutskiy cond_resched(); 6889dee7503SDavid Woodhouse tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); 6891da177e4SLinus Torvalds fn = tn->fn; 6901e0da3cbSArtem B. Bityutskiy ret = 1; 691733802d9SArtem B. Bityutskiy dbg_readinode("consider node ver %u, phys offset " 6921e0da3cbSArtem B. Bityutskiy "%#08x(%d), range %u-%u.\n", tn->version, 6931e0da3cbSArtem B. Bityutskiy ref_offset(fn->raw), ref_flags(fn->raw), 6941e0da3cbSArtem B. Bityutskiy fn->ofs, fn->ofs + fn->size); 6951da177e4SLinus Torvalds 6961da177e4SLinus Torvalds if (fn->size) { 6971e0da3cbSArtem B. Bityutskiy ret = jffs2_add_older_frag_to_fragtree(c, f, tn); 6981e0da3cbSArtem B. Bityutskiy /* TODO: the error code isn't checked, check it */ 6991e0da3cbSArtem B. Bityutskiy jffs2_dbg_fragtree_paranoia_check_nolock(f); 7001e0da3cbSArtem B. Bityutskiy BUG_ON(ret < 0); 7011e0da3cbSArtem B. Bityutskiy if (!first_fn && ret == 0) 7021e0da3cbSArtem B. Bityutskiy first_fn = fn; 7031e0da3cbSArtem B. Bityutskiy } else if (!first_fn) { 7041e0da3cbSArtem B. Bityutskiy first_fn = fn; 7051da177e4SLinus Torvalds f->metadata = fn; 7061e0da3cbSArtem B. Bityutskiy ret = 0; /* Prevent freeing the metadata update node */ 7071e0da3cbSArtem B. Bityutskiy } else 7081e0da3cbSArtem B. Bityutskiy jffs2_mark_node_obsolete(c, fn->raw); 7091e0da3cbSArtem B. Bityutskiy 7109dee7503SDavid Woodhouse BUG_ON(rb->rb_left); 71121f1d5fcSDavid Woodhouse if (rb_parent(rb) && rb_parent(rb)->rb_left == rb) { 7129dee7503SDavid Woodhouse /* We were then left-hand child of our parent. We need 7131e0da3cbSArtem B. Bityutskiy * to move our own right-hand child into our place. */ 7149dee7503SDavid Woodhouse repl_rb = rb->rb_right; 7159dee7503SDavid Woodhouse if (repl_rb) 71621f1d5fcSDavid Woodhouse rb_set_parent(repl_rb, rb_parent(rb)); 7179dee7503SDavid Woodhouse } else 7189dee7503SDavid Woodhouse repl_rb = NULL; 7199dee7503SDavid Woodhouse 7209dee7503SDavid Woodhouse rb = rb_next(rb); 7219dee7503SDavid Woodhouse 7229dee7503SDavid Woodhouse /* Remove the spent tn from the tree; don't bother rebalancing 7231e0da3cbSArtem B. Bityutskiy * but put our right-hand child in our own place. */ 72421f1d5fcSDavid Woodhouse if (rb_parent(&tn->rb)) { 72521f1d5fcSDavid Woodhouse if (rb_parent(&tn->rb)->rb_left == &tn->rb) 72621f1d5fcSDavid Woodhouse rb_parent(&tn->rb)->rb_left = repl_rb; 72721f1d5fcSDavid Woodhouse else if (rb_parent(&tn->rb)->rb_right == &tn->rb) 72821f1d5fcSDavid Woodhouse rb_parent(&tn->rb)->rb_right = repl_rb; 7299dee7503SDavid Woodhouse else BUG(); 7309dee7503SDavid Woodhouse } else if (tn->rb.rb_right) 73121f1d5fcSDavid Woodhouse rb_set_parent(tn->rb.rb_right, NULL); 7329dee7503SDavid Woodhouse 7331da177e4SLinus Torvalds jffs2_free_tmp_dnode_info(tn); 7341e0da3cbSArtem B. Bityutskiy if (ret) { 735733802d9SArtem B. Bityutskiy dbg_readinode("delete dnode %u-%u.\n", 7361e0da3cbSArtem B. Bityutskiy fn->ofs, fn->ofs + fn->size); 7371e0da3cbSArtem B. Bityutskiy jffs2_free_full_dnode(fn); 7381e0da3cbSArtem B. Bityutskiy } 7391da177e4SLinus Torvalds } 740e0c8e42fSArtem B. Bityutskiy jffs2_dbg_fragtree_paranoia_check_nolock(f); 7411da177e4SLinus Torvalds 7421e0da3cbSArtem B. Bityutskiy BUG_ON(first_fn && ref_obsolete(first_fn->raw)); 7431e0da3cbSArtem B. Bityutskiy 7441e0da3cbSArtem B. Bityutskiy fn = first_fn; 7451e0da3cbSArtem B. Bityutskiy if (unlikely(!first_fn)) { 7461da177e4SLinus Torvalds /* No data nodes for this inode. */ 7471da177e4SLinus Torvalds if (f->inocache->ino != 1) { 748e0d60137SArtem B. Bityutskiy JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); 7491da177e4SLinus Torvalds if (!fd_list) { 7501da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 7511da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 7521da177e4SLinus Torvalds return -EIO; 7531da177e4SLinus Torvalds } 754e0d60137SArtem B. Bityutskiy JFFS2_NOTICE("but it has children so we fake some modes for it\n"); 7551da177e4SLinus Torvalds } 7561da177e4SLinus Torvalds latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); 7571da177e4SLinus Torvalds latest_node->version = cpu_to_je32(0); 7581da177e4SLinus Torvalds latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); 7591da177e4SLinus Torvalds latest_node->isize = cpu_to_je32(0); 7601da177e4SLinus Torvalds latest_node->gid = cpu_to_je16(0); 7611da177e4SLinus Torvalds latest_node->uid = cpu_to_je16(0); 7621da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 7631da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 7641da177e4SLinus Torvalds return 0; 7651da177e4SLinus Torvalds } 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node); 7681da177e4SLinus Torvalds if (ret || retlen != sizeof(*latest_node)) { 769e0d60137SArtem B. Bityutskiy JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", 7701da177e4SLinus Torvalds ret, retlen, sizeof(*latest_node)); 7711da177e4SLinus Torvalds /* FIXME: If this fails, there seems to be a memory leak. Find it. */ 7721da177e4SLinus Torvalds up(&f->sem); 7731da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 7741da177e4SLinus Torvalds return ret?ret:-EIO; 7751da177e4SLinus Torvalds } 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds crc = crc32(0, latest_node, sizeof(*latest_node)-8); 7781da177e4SLinus Torvalds if (crc != je32_to_cpu(latest_node->node_crc)) { 779e0d60137SArtem B. Bityutskiy JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", 780e0d60137SArtem B. Bityutskiy f->inocache->ino, ref_offset(fn->raw)); 7811da177e4SLinus Torvalds up(&f->sem); 7821da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 7831da177e4SLinus Torvalds return -EIO; 7841da177e4SLinus Torvalds } 7851da177e4SLinus Torvalds 7861da177e4SLinus Torvalds switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { 7871da177e4SLinus Torvalds case S_IFDIR: 7881da177e4SLinus Torvalds if (mctime_ver > je32_to_cpu(latest_node->version)) { 7891da177e4SLinus Torvalds /* The times in the latest_node are actually older than 7901da177e4SLinus Torvalds mctime in the latest dirent. Cheat. */ 7911da177e4SLinus Torvalds latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime); 7921da177e4SLinus Torvalds } 7931da177e4SLinus Torvalds break; 7941da177e4SLinus Torvalds 7951da177e4SLinus Torvalds 7961da177e4SLinus Torvalds case S_IFREG: 7971da177e4SLinus Torvalds /* If it was a regular file, truncate it to the latest node's isize */ 798f302cd02SArtem B. Bityutskiy jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 7991da177e4SLinus Torvalds break; 8001da177e4SLinus Torvalds 8011da177e4SLinus Torvalds case S_IFLNK: 8021da177e4SLinus Torvalds /* Hack to work around broken isize in old symlink code. 8031da177e4SLinus Torvalds Remove this when dwmw2 comes to his senses and stops 8041da177e4SLinus Torvalds symlinks from being an entirely gratuitous special 8051da177e4SLinus Torvalds case. */ 8061da177e4SLinus Torvalds if (!je32_to_cpu(latest_node->isize)) 8071da177e4SLinus Torvalds latest_node->isize = latest_node->dsize; 80832f1a95dSArtem B. Bityuckiy 80932f1a95dSArtem B. Bityuckiy if (f->inocache->state != INO_STATE_CHECKING) { 81032f1a95dSArtem B. Bityuckiy /* Symlink's inode data is the target path. Read it and 8112b79adccSArtem B. Bityutskiy * keep in RAM to facilitate quick follow symlink 8122b79adccSArtem B. Bityutskiy * operation. */ 8132b79adccSArtem B. Bityutskiy f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); 8142b79adccSArtem B. Bityutskiy if (!f->target) { 815e0d60137SArtem B. Bityutskiy JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize)); 81632f1a95dSArtem B. Bityuckiy up(&f->sem); 81732f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 81832f1a95dSArtem B. Bityuckiy return -ENOMEM; 81932f1a95dSArtem B. Bityuckiy } 82032f1a95dSArtem B. Bityuckiy 82132f1a95dSArtem B. Bityuckiy ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), 8222b79adccSArtem B. Bityutskiy je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); 82332f1a95dSArtem B. Bityuckiy 82432f1a95dSArtem B. Bityuckiy if (ret || retlen != je32_to_cpu(latest_node->csize)) { 82532f1a95dSArtem B. Bityuckiy if (retlen != je32_to_cpu(latest_node->csize)) 82632f1a95dSArtem B. Bityuckiy ret = -EIO; 8272b79adccSArtem B. Bityutskiy kfree(f->target); 8282b79adccSArtem B. Bityutskiy f->target = NULL; 82932f1a95dSArtem B. Bityuckiy up(&f->sem); 83032f1a95dSArtem B. Bityuckiy jffs2_do_clear_inode(c, f); 83132f1a95dSArtem B. Bityuckiy return -ret; 83232f1a95dSArtem B. Bityuckiy } 83332f1a95dSArtem B. Bityuckiy 8342b79adccSArtem B. Bityutskiy f->target[je32_to_cpu(latest_node->csize)] = '\0'; 835733802d9SArtem B. Bityutskiy dbg_readinode("symlink's target '%s' cached\n", f->target); 83632f1a95dSArtem B. Bityuckiy } 83732f1a95dSArtem B. Bityuckiy 8381da177e4SLinus Torvalds /* fall through... */ 8391da177e4SLinus Torvalds 8401da177e4SLinus Torvalds case S_IFBLK: 8411da177e4SLinus Torvalds case S_IFCHR: 8421da177e4SLinus Torvalds /* Certain inode types should have only one data node, and it's 8431da177e4SLinus Torvalds kept as the metadata node */ 8441da177e4SLinus Torvalds if (f->metadata) { 845e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n", 8461da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 8471da177e4SLinus Torvalds up(&f->sem); 8481da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 8491da177e4SLinus Torvalds return -EIO; 8501da177e4SLinus Torvalds } 8511da177e4SLinus Torvalds if (!frag_first(&f->fragtree)) { 852e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n", 8531da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 8541da177e4SLinus Torvalds up(&f->sem); 8551da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 8561da177e4SLinus Torvalds return -EIO; 8571da177e4SLinus Torvalds } 8581da177e4SLinus Torvalds /* ASSERT: f->fraglist != NULL */ 8591da177e4SLinus Torvalds if (frag_next(frag_first(&f->fragtree))) { 860e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n", 8611da177e4SLinus Torvalds f->inocache->ino, jemode_to_cpu(latest_node->mode)); 8621da177e4SLinus Torvalds /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ 8631da177e4SLinus Torvalds up(&f->sem); 8641da177e4SLinus Torvalds jffs2_do_clear_inode(c, f); 8651da177e4SLinus Torvalds return -EIO; 8661da177e4SLinus Torvalds } 8671da177e4SLinus Torvalds /* OK. We're happy */ 8681da177e4SLinus Torvalds f->metadata = frag_first(&f->fragtree)->node; 8691da177e4SLinus Torvalds jffs2_free_node_frag(frag_first(&f->fragtree)); 8701da177e4SLinus Torvalds f->fragtree = RB_ROOT; 8711da177e4SLinus Torvalds break; 8721da177e4SLinus Torvalds } 8731da177e4SLinus Torvalds if (f->inocache->state == INO_STATE_READING) 8741da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); 8751da177e4SLinus Torvalds 8761da177e4SLinus Torvalds return 0; 8771da177e4SLinus Torvalds } 8781da177e4SLinus Torvalds 879f97117d1SArtem B. Bityutskiy /* Scan the list of all nodes present for this ino, build map of versions, etc. */ 880f97117d1SArtem B. Bityutskiy int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 881f97117d1SArtem B. Bityutskiy uint32_t ino, struct jffs2_raw_inode *latest_node) 882f97117d1SArtem B. Bityutskiy { 883733802d9SArtem B. Bityutskiy dbg_readinode("read inode #%u\n", ino); 884f97117d1SArtem B. Bityutskiy 885f97117d1SArtem B. Bityutskiy retry_inocache: 886f97117d1SArtem B. Bityutskiy spin_lock(&c->inocache_lock); 887f97117d1SArtem B. Bityutskiy f->inocache = jffs2_get_ino_cache(c, ino); 888f97117d1SArtem B. Bityutskiy 889f97117d1SArtem B. Bityutskiy if (f->inocache) { 890f97117d1SArtem B. Bityutskiy /* Check its state. We may need to wait before we can use it */ 891f97117d1SArtem B. Bityutskiy switch(f->inocache->state) { 892f97117d1SArtem B. Bityutskiy case INO_STATE_UNCHECKED: 893f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKEDABSENT: 894f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 895f97117d1SArtem B. Bityutskiy break; 896f97117d1SArtem B. Bityutskiy 897f97117d1SArtem B. Bityutskiy case INO_STATE_CHECKING: 898f97117d1SArtem B. Bityutskiy case INO_STATE_GC: 899f97117d1SArtem B. Bityutskiy /* If it's in either of these states, we need 900f97117d1SArtem B. Bityutskiy to wait for whoever's got it to finish and 901f97117d1SArtem B. Bityutskiy put it back. */ 902733802d9SArtem B. Bityutskiy dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state); 903f97117d1SArtem B. Bityutskiy sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); 904f97117d1SArtem B. Bityutskiy goto retry_inocache; 905f97117d1SArtem B. Bityutskiy 906f97117d1SArtem B. Bityutskiy case INO_STATE_READING: 907f97117d1SArtem B. Bityutskiy case INO_STATE_PRESENT: 908f97117d1SArtem B. Bityutskiy /* Eep. This should never happen. It can 909f97117d1SArtem B. Bityutskiy happen if Linux calls read_inode() again 910f97117d1SArtem B. Bityutskiy before clear_inode() has finished though. */ 911e0d60137SArtem B. Bityutskiy JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); 912f97117d1SArtem B. Bityutskiy /* Fail. That's probably better than allowing it to succeed */ 913f97117d1SArtem B. Bityutskiy f->inocache = NULL; 914f97117d1SArtem B. Bityutskiy break; 915f97117d1SArtem B. Bityutskiy 916f97117d1SArtem B. Bityutskiy default: 917f97117d1SArtem B. Bityutskiy BUG(); 918f97117d1SArtem B. Bityutskiy } 919f97117d1SArtem B. Bityutskiy } 920f97117d1SArtem B. Bityutskiy spin_unlock(&c->inocache_lock); 921f97117d1SArtem B. Bityutskiy 922f97117d1SArtem B. Bityutskiy if (!f->inocache && ino == 1) { 923f97117d1SArtem B. Bityutskiy /* Special case - no root inode on medium */ 924f97117d1SArtem B. Bityutskiy f->inocache = jffs2_alloc_inode_cache(); 925f97117d1SArtem B. Bityutskiy if (!f->inocache) { 926e0d60137SArtem B. Bityutskiy JFFS2_ERROR("cannot allocate inocache for root inode\n"); 927f97117d1SArtem B. Bityutskiy return -ENOMEM; 928f97117d1SArtem B. Bityutskiy } 929733802d9SArtem B. Bityutskiy dbg_readinode("creating inocache for root inode\n"); 930f97117d1SArtem B. Bityutskiy memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); 931f97117d1SArtem B. Bityutskiy f->inocache->ino = f->inocache->nlink = 1; 932f97117d1SArtem B. Bityutskiy f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 933f97117d1SArtem B. Bityutskiy f->inocache->state = INO_STATE_READING; 934f97117d1SArtem B. Bityutskiy jffs2_add_ino_cache(c, f->inocache); 935f97117d1SArtem B. Bityutskiy } 936f97117d1SArtem B. Bityutskiy if (!f->inocache) { 937e0d60137SArtem B. Bityutskiy JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); 938f97117d1SArtem B. Bityutskiy return -ENOENT; 939f97117d1SArtem B. Bityutskiy } 940f97117d1SArtem B. Bityutskiy 941f97117d1SArtem B. Bityutskiy return jffs2_do_read_inode_internal(c, f, latest_node); 942f97117d1SArtem B. Bityutskiy } 943f97117d1SArtem B. Bityutskiy 944f97117d1SArtem B. Bityutskiy int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 945f97117d1SArtem B. Bityutskiy { 946f97117d1SArtem B. Bityutskiy struct jffs2_raw_inode n; 947f97117d1SArtem B. Bityutskiy struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL); 948f97117d1SArtem B. Bityutskiy int ret; 949f97117d1SArtem B. Bityutskiy 950f97117d1SArtem B. Bityutskiy if (!f) 951f97117d1SArtem B. Bityutskiy return -ENOMEM; 952f97117d1SArtem B. Bityutskiy 953f97117d1SArtem B. Bityutskiy memset(f, 0, sizeof(*f)); 954f97117d1SArtem B. Bityutskiy init_MUTEX_LOCKED(&f->sem); 955f97117d1SArtem B. Bityutskiy f->inocache = ic; 956f97117d1SArtem B. Bityutskiy 957f97117d1SArtem B. Bityutskiy ret = jffs2_do_read_inode_internal(c, f, &n); 958f97117d1SArtem B. Bityutskiy if (!ret) { 959f97117d1SArtem B. Bityutskiy up(&f->sem); 960f97117d1SArtem B. Bityutskiy jffs2_do_clear_inode(c, f); 961f97117d1SArtem B. Bityutskiy } 962f97117d1SArtem B. Bityutskiy kfree (f); 963f97117d1SArtem B. Bityutskiy return ret; 964f97117d1SArtem B. Bityutskiy } 965f97117d1SArtem B. Bityutskiy 9661da177e4SLinus Torvalds void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) 9671da177e4SLinus Torvalds { 9681da177e4SLinus Torvalds struct jffs2_full_dirent *fd, *fds; 9691da177e4SLinus Torvalds int deleted; 9701da177e4SLinus Torvalds 971c7afb0f9SKaiGai Kohei jffs2_clear_acl(f); 972355ed4e1SKaiGai Kohei jffs2_xattr_delete_inode(c, f->inocache); 9731da177e4SLinus Torvalds down(&f->sem); 9741da177e4SLinus Torvalds deleted = f->inocache && !f->inocache->nlink; 9751da177e4SLinus Torvalds 97667e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 97767e345d1SDavid Woodhouse jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); 97867e345d1SDavid Woodhouse 9791da177e4SLinus Torvalds if (f->metadata) { 9801da177e4SLinus Torvalds if (deleted) 9811da177e4SLinus Torvalds jffs2_mark_node_obsolete(c, f->metadata->raw); 9821da177e4SLinus Torvalds jffs2_free_full_dnode(f->metadata); 9831da177e4SLinus Torvalds } 9841da177e4SLinus Torvalds 9851da177e4SLinus Torvalds jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 9861da177e4SLinus Torvalds 9872b79adccSArtem B. Bityutskiy if (f->target) { 9882b79adccSArtem B. Bityutskiy kfree(f->target); 9892b79adccSArtem B. Bityutskiy f->target = NULL; 99032f1a95dSArtem B. Bityuckiy } 9911da177e4SLinus Torvalds 9922b79adccSArtem B. Bityutskiy fds = f->dents; 9931da177e4SLinus Torvalds while(fds) { 9941da177e4SLinus Torvalds fd = fds; 9951da177e4SLinus Torvalds fds = fd->next; 9961da177e4SLinus Torvalds jffs2_free_full_dirent(fd); 9971da177e4SLinus Torvalds } 9981da177e4SLinus Torvalds 99967e345d1SDavid Woodhouse if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { 10001da177e4SLinus Torvalds jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 100167e345d1SDavid Woodhouse if (f->inocache->nodes == (void *)f->inocache) 100267e345d1SDavid Woodhouse jffs2_del_ino_cache(c, f->inocache); 100367e345d1SDavid Woodhouse } 10041da177e4SLinus Torvalds 10051da177e4SLinus Torvalds up(&f->sem); 10061da177e4SLinus Torvalds } 1007