]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/jffs2/read.c
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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/crc32.h>
17 #include <linux/pagemap.h>
18 #include <linux/mtd/mtd.h>
19 #include <linux/compiler.h>
23 int jffs2_read_dnode(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
24 struct jffs2_full_dnode
*fd
, unsigned char *buf
,
27 struct jffs2_raw_inode
*ri
;
30 unsigned char *decomprbuf
= NULL
;
31 unsigned char *readbuf
= NULL
;
34 ri
= jffs2_alloc_raw_inode();
38 ret
= jffs2_flash_read(c
, ref_offset(fd
->raw
), sizeof(*ri
), &readlen
, (char *)ri
);
40 jffs2_free_raw_inode(ri
);
41 pr_warn("Error reading node from 0x%08x: %d\n",
42 ref_offset(fd
->raw
), ret
);
45 if (readlen
!= sizeof(*ri
)) {
46 jffs2_free_raw_inode(ri
);
47 pr_warn("Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
48 ref_offset(fd
->raw
), sizeof(*ri
), readlen
);
51 crc
= crc32(0, ri
, sizeof(*ri
)-8);
53 jffs2_dbg(1, "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n",
54 ref_offset(fd
->raw
), je32_to_cpu(ri
->node_crc
),
55 crc
, je32_to_cpu(ri
->dsize
), je32_to_cpu(ri
->csize
),
56 je32_to_cpu(ri
->offset
), buf
);
57 if (crc
!= je32_to_cpu(ri
->node_crc
)) {
58 pr_warn("Node CRC %08x != calculated CRC %08x for node at %08x\n",
59 je32_to_cpu(ri
->node_crc
), crc
, ref_offset(fd
->raw
));
63 /* There was a bug where we wrote hole nodes out with csize/dsize
64 swapped. Deal with it */
65 if (ri
->compr
== JFFS2_COMPR_ZERO
&& !je32_to_cpu(ri
->dsize
) &&
66 je32_to_cpu(ri
->csize
)) {
67 ri
->dsize
= ri
->csize
;
68 ri
->csize
= cpu_to_je32(0);
71 D1(if(ofs
+ len
> je32_to_cpu(ri
->dsize
)) {
72 pr_warn("jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n",
73 len
, ofs
, je32_to_cpu(ri
->dsize
));
79 if (ri
->compr
== JFFS2_COMPR_ZERO
) {
85 Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
86 Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
87 Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
88 Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
90 if (ri
->compr
== JFFS2_COMPR_NONE
&& len
== je32_to_cpu(ri
->dsize
)) {
93 readbuf
= kmalloc(je32_to_cpu(ri
->csize
), GFP_KERNEL
);
99 if (ri
->compr
!= JFFS2_COMPR_NONE
) {
100 if (len
< je32_to_cpu(ri
->dsize
)) {
101 decomprbuf
= kmalloc(je32_to_cpu(ri
->dsize
), GFP_KERNEL
);
110 decomprbuf
= readbuf
;
113 jffs2_dbg(2, "Read %d bytes to %p\n", je32_to_cpu(ri
->csize
),
115 ret
= jffs2_flash_read(c
, (ref_offset(fd
->raw
)) + sizeof(*ri
),
116 je32_to_cpu(ri
->csize
), &readlen
, readbuf
);
118 if (!ret
&& readlen
!= je32_to_cpu(ri
->csize
))
123 crc
= crc32(0, readbuf
, je32_to_cpu(ri
->csize
));
124 if (crc
!= je32_to_cpu(ri
->data_crc
)) {
125 pr_warn("Data CRC %08x != calculated CRC %08x for node at %08x\n",
126 je32_to_cpu(ri
->data_crc
), crc
, ref_offset(fd
->raw
));
130 jffs2_dbg(2, "Data CRC matches calculated CRC %08x\n", crc
);
131 if (ri
->compr
!= JFFS2_COMPR_NONE
) {
132 jffs2_dbg(2, "Decompress %d bytes from %p to %d bytes at %p\n",
133 je32_to_cpu(ri
->csize
), readbuf
,
134 je32_to_cpu(ri
->dsize
), decomprbuf
);
135 ret
= jffs2_decompress(c
, f
, ri
->compr
| (ri
->usercompr
<< 8), readbuf
, decomprbuf
, je32_to_cpu(ri
->csize
), je32_to_cpu(ri
->dsize
));
137 pr_warn("Error: jffs2_decompress returned %d\n", ret
);
142 if (len
< je32_to_cpu(ri
->dsize
)) {
143 memcpy(buf
, decomprbuf
+ofs
, len
);
146 if(decomprbuf
!= buf
&& decomprbuf
!= readbuf
)
152 jffs2_free_raw_inode(ri
);
157 int jffs2_read_inode_range(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
158 unsigned char *buf
, uint32_t offset
, uint32_t len
)
160 uint32_t end
= offset
+ len
;
161 struct jffs2_node_frag
*frag
;
164 jffs2_dbg(1, "%s(): ino #%u, range 0x%08x-0x%08x\n",
165 __func__
, f
->inocache
->ino
, offset
, offset
+ len
);
167 frag
= jffs2_lookup_node_frag(&f
->fragtree
, offset
);
169 /* XXX FIXME: Where a single physical node actually shows up in two
170 frags, we read it twice. Don't do that. */
171 /* Now we're pointing at the first frag which overlaps our page
172 * (or perhaps is before it, if we've been asked to read off the
173 * end of the file). */
174 while(offset
< end
) {
175 jffs2_dbg(2, "%s(): offset %d, end %d\n",
176 __func__
, offset
, end
);
177 if (unlikely(!frag
|| frag
->ofs
> offset
||
178 frag
->ofs
+ frag
->size
<= offset
)) {
179 uint32_t holesize
= end
- offset
;
180 if (frag
&& frag
->ofs
> offset
) {
181 jffs2_dbg(1, "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
182 f
->inocache
->ino
, frag
->ofs
, offset
);
183 holesize
= min(holesize
, frag
->ofs
- offset
);
185 jffs2_dbg(1, "Filling non-frag hole from %d-%d\n",
186 offset
, offset
+ holesize
);
187 memset(buf
, 0, holesize
);
191 } else if (unlikely(!frag
->node
)) {
192 uint32_t holeend
= min(end
, frag
->ofs
+ frag
->size
);
193 jffs2_dbg(1, "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n",
194 offset
, holeend
, frag
->ofs
,
195 frag
->ofs
+ frag
->size
);
196 memset(buf
, 0, holeend
- offset
);
197 buf
+= holeend
- offset
;
199 frag
= frag_next(frag
);
203 uint32_t fragofs
; /* offset within the frag to start reading */
205 fragofs
= offset
- frag
->ofs
;
206 readlen
= min(frag
->size
- fragofs
, end
- offset
);
207 jffs2_dbg(1, "Reading %d-%d from node at 0x%08x (%d)\n",
209 frag
->ofs
+ fragofs
+readlen
,
210 ref_offset(frag
->node
->raw
),
211 ref_flags(frag
->node
->raw
));
212 ret
= jffs2_read_dnode(c
, f
, frag
->node
, buf
, fragofs
+ frag
->ofs
- frag
->node
->ofs
, readlen
);
213 jffs2_dbg(2, "node read done\n");
215 jffs2_dbg(1, "%s(): error %d\n",
217 memset(buf
, 0, readlen
);
222 frag
= frag_next(frag
);
223 jffs2_dbg(2, "node read was OK. Looping\n");