OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [fs/] [jffs2/] [current/] [src/] [read.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*
2
 * JFFS2 -- Journalling Flash File System, Version 2.
3
 *
4
 * Copyright (C) 2001-2003 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
 * $Id: read.c,v 1.41 2005/07/22 10:32:08 dedekind Exp $
11
 *
12
 */
13
 
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>
20
#include "nodelist.h"
21
#include "compr.h"
22
 
23
int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
24
                     struct jffs2_full_dnode *fd, unsigned char *buf,
25
                     int ofs, int len)
26
{
27
        struct jffs2_raw_inode *ri;
28
        size_t readlen;
29
        uint32_t crc;
30
        unsigned char *decomprbuf = NULL;
31
        unsigned char *readbuf = NULL;
32
        int ret = 0;
33
 
34
        ri = jffs2_alloc_raw_inode();
35
        if (!ri)
36
                return -ENOMEM;
37
 
38
        ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri);
39
        if (ret) {
40
                jffs2_free_raw_inode(ri);
41
                printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret);
42
                return ret;
43
        }
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);
48
                return -EIO;
49
        }
50
        crc = crc32(0, ri, sizeof(*ri)-8);
51
 
52
        D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n",
53
                  ref_offset(fd->raw), je32_to_cpu(ri->node_crc),
54
                  crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize),
55
                  je32_to_cpu(ri->offset), buf));
56
        if (crc != je32_to_cpu(ri->node_crc)) {
57
                printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n",
58
                       je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw));
59
                ret = -EIO;
60
                goto out_ri;
61
        }
62
        /* There was a bug where we wrote hole nodes out with csize/dsize
63
           swapped. Deal with it */
64
        if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
65
            je32_to_cpu(ri->csize)) {
66
                ri->dsize = ri->csize;
67
                ri->csize = cpu_to_je32(0);
68
        }
69
 
70
        D1(if(ofs + len > je32_to_cpu(ri->dsize)) {
71
                printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n",
72
                       len, ofs, je32_to_cpu(ri->dsize));
73
                ret = -EINVAL;
74
                goto out_ri;
75
        });
76
 
77
 
78
        if (ri->compr == JFFS2_COMPR_ZERO) {
79
                memset(buf, 0, len);
80
                goto out_ri;
81
        }
82
 
83
        /* Cases:
84
           Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
85
           Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
86
           Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
87
           Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
88
        */
89
        if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
90
                readbuf = buf;
91
        } else {
92
                readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL);
93
                if (!readbuf) {
94
                        ret = -ENOMEM;
95
                        goto out_ri;
96
                }
97
        }
98
        if (ri->compr != JFFS2_COMPR_NONE) {
99
                if (len < je32_to_cpu(ri->dsize)) {
100
                        decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL);
101
                        if (!decomprbuf) {
102
                                ret = -ENOMEM;
103
                                goto out_readbuf;
104
                        }
105
                } else {
106
                        decomprbuf = buf;
107
                }
108
        } else {
109
                decomprbuf = readbuf;
110
        }
111
 
112
        D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize),
113
                  readbuf));
114
        ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri),
115
                               je32_to_cpu(ri->csize), &readlen, readbuf);
116
 
117
        if (!ret && readlen != je32_to_cpu(ri->csize))
118
                ret = -EIO;
119
        if (ret)
120
                goto out_decomprbuf;
121
 
122
        crc = crc32(0, readbuf, je32_to_cpu(ri->csize));
123
        if (crc != je32_to_cpu(ri->data_crc)) {
124
                printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n",
125
                       je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw));
126
                ret = -EIO;
127
                goto out_decomprbuf;
128
        }
129
        D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
130
        if (ri->compr != JFFS2_COMPR_NONE) {
131
                D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
132
                          je32_to_cpu(ri->csize), readbuf, 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
                        printk(KERN_WARNING "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
        D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n",
163
                  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
        while(offset < end) {
171
                D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
172
                if (unlikely(!frag || frag->ofs > offset)) {
173
                        uint32_t holesize = end - offset;
174
                        if (frag) {
175
                                D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
176
                                holesize = min(holesize, frag->ofs - offset);
177
                        }
178
                        D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
179
                        memset(buf, 0, holesize);
180
                        buf += holesize;
181
                        offset += holesize;
182
                        continue;
183
                } else if (unlikely(!frag->node)) {
184
                        uint32_t holeend = min(end, frag->ofs + frag->size);
185
                        D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
186
                        memset(buf, 0, holeend - offset);
187
                        buf += holeend - offset;
188
                        offset = holeend;
189
                        frag = frag_next(frag);
190
                        continue;
191
                } else {
192
                        uint32_t readlen;
193
                        uint32_t fragofs; /* offset within the frag to start reading */
194
 
195
                        fragofs = offset - frag->ofs;
196
                        readlen = min(frag->size - fragofs, end - offset);
197
                        D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
198
                                  frag->ofs+fragofs, frag->ofs+fragofs+readlen,
199
                                  ref_offset(frag->node->raw), ref_flags(frag->node->raw)));
200
                        ret = jffs2_read_dnode(c, f, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen);
201
                        D2(printk(KERN_DEBUG "node read done\n"));
202
                        if (ret) {
203
                                D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret));
204
                                memset(buf, 0, readlen);
205
                                return ret;
206
                        }
207
                        buf += readlen;
208
                        offset += readlen;
209
                        frag = frag_next(frag);
210
                        D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
211
                }
212
        }
213
        return 0;
214
}
215
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.