2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright © 2001-2007 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@infradead.org>
8 * For licensing information, see the file 'LICENCE' in this directory.
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>
21 int jffs2_read_dnode(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
22 struct jffs2_full_dnode
*fd
, unsigned char *buf
,
25 struct jffs2_raw_inode
*ri
;
28 unsigned char *decomprbuf
= NULL
;
29 unsigned char *readbuf
= NULL
;
32 ri
= jffs2_alloc_raw_inode();
36 ret
= jffs2_flash_read(c
, ref_offset(fd
->raw
), sizeof(*ri
), &readlen
, (char *)ri
);
38 jffs2_free_raw_inode(ri
);
39 pr_warn("Error reading node from 0x%08x: %d\n",
40 ref_offset(fd
->raw
), ret
);
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
);
49 crc
= crc32(0, ri
, sizeof(*ri
)-8);
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
));
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);
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
));
77 if (ri
->compr
== JFFS2_COMPR_ZERO
) {
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
88 if (ri
->compr
== JFFS2_COMPR_NONE
&& len
== je32_to_cpu(ri
->dsize
)) {
91 readbuf
= kmalloc(je32_to_cpu(ri
->csize
), GFP_KERNEL
);
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
);
108 decomprbuf
= readbuf
;
111 jffs2_dbg(2, "Read %d bytes to %p\n", je32_to_cpu(ri
->csize
),
113 ret
= jffs2_flash_read(c
, (ref_offset(fd
->raw
)) + sizeof(*ri
),
114 je32_to_cpu(ri
->csize
), &readlen
, readbuf
);
116 if (!ret
&& readlen
!= je32_to_cpu(ri
->csize
))
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
));
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
));
135 pr_warn("Error: jffs2_decompress returned %d\n", ret
);
140 if (len
< je32_to_cpu(ri
->dsize
)) {
141 memcpy(buf
, decomprbuf
+ofs
, len
);
144 if(decomprbuf
!= buf
&& decomprbuf
!= readbuf
)
150 jffs2_free_raw_inode(ri
);
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
)
158 uint32_t end
= offset
+ len
;
159 struct jffs2_node_frag
*frag
;
162 jffs2_dbg(1, "%s(): ino #%u, range 0x%08x-0x%08x\n",
163 __func__
, f
->inocache
->ino
, offset
, offset
+ len
);
165 frag
= jffs2_lookup_node_frag(&f
->fragtree
, offset
);
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
);
183 jffs2_dbg(1, "Filling non-frag hole from %d-%d\n",
184 offset
, offset
+ holesize
);
185 memset(buf
, 0, holesize
);
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
;
197 frag
= frag_next(frag
);
201 uint32_t fragofs
; /* offset within the frag to start reading */
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",
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");
213 jffs2_dbg(1, "%s(): error %d\n",
215 memset(buf
, 0, readlen
);
220 frag
= frag_next(frag
);
221 jffs2_dbg(2, "node read was OK. Looping\n");
This page took 0.040905 seconds and 5 git commands to generate.