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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [jffs2/] [read.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * JFFS2 -- Journalling Flash File System, Version 2.
3
 *
4
 * Copyright (C) 2001 Red Hat, Inc.
5
 *
6
 * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
7
 *
8
 * The original JFFS, from which the design for JFFS2 was derived,
9
 * was designed and implemented by Axis Communications AB.
10
 *
11
 * The contents of this file are subject to the Red Hat eCos Public
12
 * License Version 1.1 (the "Licence"); you may not use this file
13
 * except in compliance with the Licence.  You may obtain a copy of
14
 * the Licence at http://www.redhat.com/
15
 *
16
 * Software distributed under the Licence is distributed on an "AS IS"
17
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
18
 * See the Licence for the specific language governing rights and
19
 * limitations under the Licence.
20
 *
21
 * The Original Code is JFFS2 - Journalling Flash File System, version 2
22
 *
23
 * Alternatively, the contents of this file may be used under the
24
 * terms of the GNU General Public License version 2 (the "GPL"), in
25
 * which case the provisions of the GPL are applicable instead of the
26
 * above.  If you wish to allow the use of your version of this file
27
 * only under the terms of the GPL and not to allow others to use your
28
 * version of this file under the RHEPL, indicate your decision by
29
 * deleting the provisions above and replace them with the notice and
30
 * other provisions required by the GPL.  If you do not delete the
31
 * provisions above, a recipient may use your version of this file
32
 * under either the RHEPL or the GPL.
33
 *
34
 * $Id: read.c,v 1.1.1.1 2004-04-15 01:11:07 phoenix Exp $
35
 *
36
 */
37
 
38
#include <linux/kernel.h>
39
#include <linux/slab.h>
40
#include <linux/jffs2.h>
41
#include <linux/mtd/mtd.h>
42
#include "nodelist.h"
43
#include <linux/crc32.h>
44
 
45
int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len)
46
{
47
        struct jffs2_raw_inode *ri;
48
        size_t readlen;
49
        __u32 crc;
50
        unsigned char *decomprbuf = NULL;
51
        unsigned char *readbuf = NULL;
52
        int ret = 0;
53
 
54
        ri = jffs2_alloc_raw_inode();
55
        if (!ri)
56
                return -ENOMEM;
57
 
58
        ret = c->mtd->read(c->mtd, fd->raw->flash_offset & ~3, sizeof(*ri), &readlen, (char *)ri);
59
        if (ret) {
60
                jffs2_free_raw_inode(ri);
61
                printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", fd->raw->flash_offset & ~3, ret);
62
                return ret;
63
        }
64
        if (readlen != sizeof(*ri)) {
65
                jffs2_free_raw_inode(ri);
66
                printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%x bytes, got 0x%x\n",
67
                       fd->raw->flash_offset & ~3, sizeof(*ri), readlen);
68
                return -EIO;
69
        }
70
        crc = crc32(0, ri, sizeof(*ri)-8);
71
 
72
        D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", fd->raw->flash_offset & ~3, ri->node_crc, crc, ri->dsize, ri->csize, ri->offset, buf));
73
        if (crc != ri->node_crc) {
74
                printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", ri->node_crc, crc, fd->raw->flash_offset & ~3);
75
                ret = -EIO;
76
                goto out_ri;
77
        }
78
        /* There was a bug where we wrote hole nodes out with csize/dsize
79
           swapped. Deal with it */
80
        if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) {
81
                ri->dsize = ri->csize;
82
                ri->csize = 0;
83
        }
84
 
85
        D1(if(ofs + len > ri->dsize) {
86
                printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", len, ofs, ri->dsize);
87
                ret = -EINVAL;
88
                goto out_ri;
89
        });
90
 
91
 
92
        if (ri->compr == JFFS2_COMPR_ZERO) {
93
                memset(buf, 0, len);
94
                goto out_ri;
95
        }
96
 
97
        /* Cases:
98
           Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
99
           Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
100
           Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
101
           Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
102
        */
103
        if (ri->compr == JFFS2_COMPR_NONE && len == ri->dsize) {
104
                readbuf = buf;
105
        } else {
106
                readbuf = kmalloc(ri->csize, GFP_KERNEL);
107
                if (!readbuf) {
108
                        ret = -ENOMEM;
109
                        goto out_ri;
110
                }
111
        }
112
        if (ri->compr != JFFS2_COMPR_NONE) {
113
                if (len < ri->dsize) {
114
                        decomprbuf = kmalloc(ri->dsize, GFP_KERNEL);
115
                        if (!decomprbuf) {
116
                                ret = -ENOMEM;
117
                                goto out_readbuf;
118
                        }
119
                } else {
120
                        decomprbuf = buf;
121
                }
122
        } else {
123
                decomprbuf = readbuf;
124
        }
125
 
126
        D2(printk(KERN_DEBUG "Read %d bytes to %p\n", ri->csize, readbuf));
127
        ret = c->mtd->read(c->mtd, (fd->raw->flash_offset &~3) + sizeof(*ri), ri->csize, &readlen, readbuf);
128
 
129
        if (!ret && readlen != ri->csize)
130
                ret = -EIO;
131
        if (ret)
132
                goto out_decomprbuf;
133
 
134
        crc = crc32(0, readbuf, ri->csize);
135
        if (crc != ri->data_crc) {
136
                printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", ri->data_crc, crc, fd->raw->flash_offset & ~3);
137
                ret = -EIO;
138
                goto out_decomprbuf;
139
        }
140
        D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
141
        if (ri->compr != JFFS2_COMPR_NONE) {
142
                D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf));
143
                ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize);
144
                if (ret) {
145
                        printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
146
                        goto out_decomprbuf;
147
                }
148
        }
149
 
150
        if (len < ri->dsize) {
151
                memcpy(buf, decomprbuf+ofs, len);
152
        }
153
 out_decomprbuf:
154
        if(decomprbuf != buf && decomprbuf != readbuf)
155
                kfree(decomprbuf);
156
 out_readbuf:
157
        if(readbuf != buf)
158
                kfree(readbuf);
159
 out_ri:
160
        jffs2_free_raw_inode(ri);
161
 
162
        return ret;
163
}

powered by: WebSVN 2.1.0

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