1 /* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright © 2001-2007 Red Hat, Inc. 5 * 6 * Created by David Woodhouse <dwmw2@infradead.org> 7 * 8 * For licensing information, see the file 'LICENCE' in this directory. 9 * 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/slab.h> 14 #include <linux/crc32.h> 15 #include <linux/pagemap.h> 16 #include <linux/mtd/mtd.h> 17 #include <linux/compiler.h> 18 #include "nodelist.h" 19 #include "compr.h" 20 21 int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 22 struct jffs2_full_dnode *fd, unsigned char *buf, 23 int ofs, int len) 24 { 25 struct jffs2_raw_inode *ri; 26 size_t readlen; 27 uint32_t crc; 28 unsigned char *decomprbuf = NULL; 29 unsigned char *readbuf = NULL; 30 int ret = 0; 31 32 ri = jffs2_alloc_raw_inode(); 33 if (!ri) 34 return -ENOMEM; 35 36 ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri); 37 if (ret) { 38 jffs2_free_raw_inode(ri); 39 pr_warn("Error reading node from 0x%08x: %d\n", 40 ref_offset(fd->raw), ret); 41 return ret; 42 } 43 if (readlen != sizeof(*ri)) { 44 jffs2_free_raw_inode(ri); 45 pr_warn("Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", 46 ref_offset(fd->raw), sizeof(*ri), readlen); 47 return -EIO; 48 } 49 crc = crc32(0, ri, sizeof(*ri)-8); 50 51 jffs2_dbg(1, "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", 52 ref_offset(fd->raw), je32_to_cpu(ri->node_crc), 53 crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize), 54 je32_to_cpu(ri->offset), buf); 55 if (crc != je32_to_cpu(ri->node_crc)) { 56 pr_warn("Node CRC %08x != calculated CRC %08x for node at %08x\n", 57 je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); 58 ret = -EIO; 59 goto out_ri; 60 } 61 /* There was a bug where we wrote hole nodes out with csize/dsize 62 swapped. Deal with it */ 63 if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) && 64 je32_to_cpu(ri->csize)) { 65 ri->dsize = ri->csize; 66 ri->csize = cpu_to_je32(0); 67 } 68 69 D1(if(ofs + len > je32_to_cpu(ri->dsize)) { 70 pr_warn("jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", 71 len, ofs, je32_to_cpu(ri->dsize)); 72 ret = -EINVAL; 73 goto out_ri; 74 }); 75 76 77 if (ri->compr == JFFS2_COMPR_ZERO) { 78 memset(buf, 0, len); 79 goto out_ri; 80 } 81 82 /* Cases: 83 Reading whole node and it's uncompressed - read directly to buffer provided, check CRC. 84 Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided 85 Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy 86 Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy 87 */ 88 if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) { 89 readbuf = buf; 90 } else { 91 readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL); 92 if (!readbuf) { 93 ret = -ENOMEM; 94 goto out_ri; 95 } 96 } 97 if (ri->compr != JFFS2_COMPR_NONE) { 98 if (len < je32_to_cpu(ri->dsize)) { 99 decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); 100 if (!decomprbuf) { 101 ret = -ENOMEM; 102 goto out_readbuf; 103 } 104 } else { 105 decomprbuf = buf; 106 } 107 } else { 108 decomprbuf = readbuf; 109 } 110 111 jffs2_dbg(2, "Read %d bytes to %p\n", je32_to_cpu(ri->csize), 112 readbuf); 113 ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri), 114 je32_to_cpu(ri->csize), &readlen, readbuf); 115 116 if (!ret && readlen != je32_to_cpu(ri->csize)) 117 ret = -EIO; 118 if (ret) 119 goto out_decomprbuf; 120 121 crc = crc32(0, readbuf, je32_to_cpu(ri->csize)); 122 if (crc != je32_to_cpu(ri->data_crc)) { 123 pr_warn("Data CRC %08x != calculated CRC %08x for node at %08x\n", 124 je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); 125 ret = -EIO; 126 goto out_decomprbuf; 127 } 128 jffs2_dbg(2, "Data CRC matches calculated CRC %08x\n", crc); 129 if (ri->compr != JFFS2_COMPR_NONE) { 130 jffs2_dbg(2, "Decompress %d bytes from %p to %d bytes at %p\n", 131 je32_to_cpu(ri->csize), readbuf, 132 je32_to_cpu(ri->dsize), decomprbuf); 133 ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize)); 134 if (ret) { 135 pr_warn("Error: jffs2_decompress returned %d\n", ret); 136 goto out_decomprbuf; 137 } 138 } 139 140 if (len < je32_to_cpu(ri->dsize)) { 141 memcpy(buf, decomprbuf+ofs, len); 142 } 143 out_decomprbuf: 144 if(decomprbuf != buf && decomprbuf != readbuf) 145 kfree(decomprbuf); 146 out_readbuf: 147 if(readbuf != buf) 148 kfree(readbuf); 149 out_ri: 150 jffs2_free_raw_inode(ri); 151 152 return ret; 153 } 154 155 int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 156 unsigned char *buf, uint32_t offset, uint32_t len) 157 { 158 uint32_t end = offset + len; 159 struct jffs2_node_frag *frag; 160 int ret; 161 162 jffs2_dbg(1, "%s(): ino #%u, range 0x%08x-0x%08x\n", 163 __func__, f->inocache->ino, offset, offset + len); 164 165 frag = jffs2_lookup_node_frag(&f->fragtree, offset); 166 167 /* XXX FIXME: Where a single physical node actually shows up in two 168 frags, we read it twice. Don't do that. */ 169 /* Now we're pointing at the first frag which overlaps our page 170 * (or perhaps is before it, if we've been asked to read off the 171 * end of the file). */ 172 while(offset < end) { 173 jffs2_dbg(2, "%s(): offset %d, end %d\n", 174 __func__, offset, end); 175 if (unlikely(!frag || frag->ofs > offset || 176 frag->ofs + frag->size <= offset)) { 177 uint32_t holesize = end - offset; 178 if (frag && frag->ofs > offset) { 179 jffs2_dbg(1, "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", 180 f->inocache->ino, frag->ofs, offset); 181 holesize = min(holesize, frag->ofs - offset); 182 } 183 jffs2_dbg(1, "Filling non-frag hole from %d-%d\n", 184 offset, offset + holesize); 185 memset(buf, 0, holesize); 186 buf += holesize; 187 offset += holesize; 188 continue; 189 } else if (unlikely(!frag->node)) { 190 uint32_t holeend = min(end, frag->ofs + frag->size); 191 jffs2_dbg(1, "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", 192 offset, holeend, frag->ofs, 193 frag->ofs + frag->size); 194 memset(buf, 0, holeend - offset); 195 buf += holeend - offset; 196 offset = holeend; 197 frag = frag_next(frag); 198 continue; 199 } else { 200 uint32_t readlen; 201 uint32_t fragofs; /* offset within the frag to start reading */ 202 203 fragofs = offset - frag->ofs; 204 readlen = min(frag->size - fragofs, end - offset); 205 jffs2_dbg(1, "Reading %d-%d from node at 0x%08x (%d)\n", 206 frag->ofs+fragofs, 207 frag->ofs + fragofs+readlen, 208 ref_offset(frag->node->raw), 209 ref_flags(frag->node->raw)); 210 ret = jffs2_read_dnode(c, f, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen); 211 jffs2_dbg(2, "node read done\n"); 212 if (ret) { 213 jffs2_dbg(1, "%s(): error %d\n", 214 __func__, ret); 215 memset(buf, 0, readlen); 216 return ret; 217 } 218 buf += readlen; 219 offset += readlen; 220 frag = frag_next(frag); 221 jffs2_dbg(2, "node read was OK. Looping\n"); 222 } 223 } 224 return 0; 225 } 226 227