2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright (C) 2001-2003 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@redhat.com>
8 * For licensing information, see the file 'LICENCE' in this directory.
10 * $Id: read.c,v 1.36 2004/05/25 11:12:32 havasi Exp $
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 printk(KERN_WARNING
"Error reading node from 0x%08x: %d\n", ref_offset(fd
->raw
), ret
);
44 if (readlen
!= sizeof(*ri
)) {
45 jffs2_free_raw_inode(ri
);
46 printk(KERN_WARNING
"Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
47 ref_offset(fd
->raw
), sizeof(*ri
), readlen
);
50 crc
= crc32(0, ri
, sizeof(*ri
)-8);
52 #if 0 // mask by Victor Yu. 04-07-2007
53 D1(printk(KERN_DEBUG
"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
));
58 if (crc
!= je32_to_cpu(ri
->node_crc
)) {
59 #if 0 // mask by Victor Yu. 04-07-2007
60 printk(KERN_WARNING
"Node CRC %08x != calculated CRC %08x for node at %08x\n",
61 je32_to_cpu(ri
->node_crc
), crc
, ref_offset(fd
->raw
));
66 /* There was a bug where we wrote hole nodes out with csize/dsize
67 swapped. Deal with it */
68 if (ri
->compr
== JFFS2_COMPR_ZERO
&& !je32_to_cpu(ri
->dsize
) &&
69 je32_to_cpu(ri
->csize
)) {
70 ri
->dsize
= ri
->csize
;
71 ri
->csize
= cpu_to_je32(0);
74 D1(if(ofs
+ len
> je32_to_cpu(ri
->dsize
)) {
75 printk(KERN_WARNING
"jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n",
76 len
, ofs
, je32_to_cpu(ri
->dsize
));
82 if (ri
->compr
== JFFS2_COMPR_ZERO
) {
88 Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
89 Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
90 Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
91 Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
93 if (ri
->compr
== JFFS2_COMPR_NONE
&& len
== je32_to_cpu(ri
->dsize
)) {
96 readbuf
= kmalloc(je32_to_cpu(ri
->csize
), GFP_KERNEL
);
102 if (ri
->compr
!= JFFS2_COMPR_NONE
) {
103 if (len
< je32_to_cpu(ri
->dsize
)) {
104 decomprbuf
= kmalloc(je32_to_cpu(ri
->dsize
), GFP_KERNEL
);
113 decomprbuf
= readbuf
;
116 D2(printk(KERN_DEBUG
"Read %d bytes to %p\n", je32_to_cpu(ri
->csize
),
118 ret
= jffs2_flash_read(c
, (ref_offset(fd
->raw
)) + sizeof(*ri
),
119 je32_to_cpu(ri
->csize
), &readlen
, readbuf
);
121 if (!ret
&& readlen
!= je32_to_cpu(ri
->csize
))
126 crc
= crc32(0, readbuf
, je32_to_cpu(ri
->csize
));
127 if (crc
!= je32_to_cpu(ri
->data_crc
)) {
128 #if 0 // mask by Victor Yu. 04-07-2007
129 printk(KERN_WARNING
"Data CRC %08x != calculated CRC %08x for node at %08x\n",
130 je32_to_cpu(ri
->data_crc
), crc
, ref_offset(fd
->raw
));
135 #if 0 // mask by Victor Yu. 04-07-2007
136 D2(printk(KERN_DEBUG
"Data CRC matches calculated CRC %08x\n", crc
));
138 if (ri
->compr
!= JFFS2_COMPR_NONE
) {
139 D2(printk(KERN_DEBUG
"Decompress %d bytes from %p to %d bytes at %p\n",
140 je32_to_cpu(ri
->csize
), readbuf
, je32_to_cpu(ri
->dsize
), decomprbuf
));
141 ret
= jffs2_decompress(c
, f
, ri
->compr
| (ri
->usercompr
<< 8), readbuf
, decomprbuf
, je32_to_cpu(ri
->csize
), je32_to_cpu(ri
->dsize
));
143 printk(KERN_WARNING
"Error: jffs2_decompress returned %d\n", ret
);
148 if (len
< je32_to_cpu(ri
->dsize
)) {
149 memcpy(buf
, decomprbuf
+ofs
, len
);
152 if(decomprbuf
!= buf
&& decomprbuf
!= readbuf
)
158 jffs2_free_raw_inode(ri
);
163 int jffs2_read_inode_range(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
164 unsigned char *buf
, uint32_t offset
, uint32_t len
)
166 uint32_t end
= offset
+ len
;
167 struct jffs2_node_frag
*frag
;
170 D1(printk(KERN_DEBUG
"jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n",
171 f
->inocache
->ino
, offset
, offset
+len
));
173 frag
= jffs2_lookup_node_frag(&f
->fragtree
, offset
);
175 /* XXX FIXME: Where a single physical node actually shows up in two
176 frags, we read it twice. Don't do that. */
177 /* Now we're pointing at the first frag which overlaps our page */
178 while(offset
< end
) {
179 D2(printk(KERN_DEBUG
"jffs2_read_inode_range: offset %d, end %d\n", offset
, end
));
180 if (unlikely(!frag
|| frag
->ofs
> offset
)) {
181 uint32_t holesize
= end
- offset
;
183 D1(printk(KERN_NOTICE
"Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f
->inocache
->ino
, frag
->ofs
, offset
));
184 holesize
= min(holesize
, frag
->ofs
- offset
);
185 D1(jffs2_print_frag_list(f
));
187 D1(printk(KERN_DEBUG
"Filling non-frag hole from %d-%d\n", offset
, offset
+holesize
));
188 memset(buf
, 0, holesize
);
192 } else if (unlikely(!frag
->node
)) {
193 uint32_t holeend
= min(end
, frag
->ofs
+ frag
->size
);
194 D1(printk(KERN_DEBUG
"Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset
, holeend
, frag
->ofs
, frag
->ofs
+ frag
->size
));
195 memset(buf
, 0, holeend
- offset
);
196 buf
+= holeend
- offset
;
198 frag
= frag_next(frag
);
202 uint32_t fragofs
; /* offset within the frag to start reading */
204 fragofs
= offset
- frag
->ofs
;
205 readlen
= min(frag
->size
- fragofs
, end
- offset
);
206 D1(printk(KERN_DEBUG
"Reading %d-%d from node at 0x%08x (%d)\n",
207 frag
->ofs
+fragofs
, frag
->ofs
+fragofs
+readlen
,
208 ref_offset(frag
->node
->raw
), ref_flags(frag
->node
->raw
)));
209 ret
= jffs2_read_dnode(c
, f
, frag
->node
, buf
, fragofs
+ frag
->ofs
- frag
->node
->ofs
, readlen
);
210 D2(printk(KERN_DEBUG
"node read done\n"));
212 D1(printk(KERN_DEBUG
"jffs2_read_inode_range error %d\n",ret
));
213 memset(buf
, 0, readlen
);
218 frag
= frag_next(frag
);
219 D2(printk(KERN_DEBUG
"node read was OK. Looping\n"));
225 /* Core function to read symlink target. */
226 char *jffs2_getlink(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
)
234 printk(KERN_NOTICE
"No metadata for symlink inode #%u\n", f
->inocache
->ino
);
236 return ERR_PTR(-EINVAL
);
238 buf
= kmalloc(f
->metadata
->size
+1, GFP_USER
);
241 return ERR_PTR(-ENOMEM
);
243 buf
[f
->metadata
->size
]=0;
245 ret
= jffs2_read_dnode(c
, f
, f
->metadata
, buf
, 0, f
->metadata
->size
);