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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [jffs2/] [scan.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: scan.c,v 1.1.1.1 2004-04-15 01:11:08 phoenix Exp $
35
 *
36
 */
37
#include <linux/kernel.h>
38
#include <linux/slab.h>
39
#include <linux/jffs2.h>
40
#include <linux/mtd/mtd.h>
41
#include <linux/pagemap.h>
42
#include "nodelist.h"
43
#include <linux/crc32.h>
44
 
45
 
46
#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
47
                c->free_size -= _x; c->dirty_size += _x; \
48
                jeb->free_size -= _x ; jeb->dirty_size += _x; \
49
                }while(0)
50
#define USED_SPACE(x) do { typeof(x) _x = (x); \
51
                c->free_size -= _x; c->used_size += _x; \
52
                jeb->free_size -= _x ; jeb->used_size += _x; \
53
                }while(0)
54
 
55
#define noisy_printk(noise, args...) do { \
56
        if (*(noise)) { \
57
                printk(KERN_NOTICE args); \
58
                 (*(noise))--; \
59
                 if (!(*(noise))) { \
60
                         printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \
61
                 } \
62
        } \
63
} while(0)
64
 
65
static uint32_t pseudo_random;
66
static void jffs2_rotate_lists(struct jffs2_sb_info *c);
67
 
68
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
69
 
70
/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
71
 * Returning an error will abort the mount - bad checksums etc. should just mark the space
72
 * as dirty.
73
 */
74
static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs, int *noise);
75
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
76
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
77
 
78
 
79
int jffs2_scan_medium(struct jffs2_sb_info *c)
80
{
81
        int i, ret;
82
        __u32 empty_blocks = 0;
83
 
84
        if (!c->blocks) {
85
                printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
86
                return -EINVAL;
87
        }
88
        for (i=0; i<c->nr_blocks; i++) {
89
                struct jffs2_eraseblock *jeb = &c->blocks[i];
90
 
91
                ret = jffs2_scan_eraseblock(c, jeb);
92
                if (ret < 0)
93
                        return ret;
94
 
95
                ACCT_PARANOIA_CHECK(jeb);
96
 
97
                /* Now decide which list to put it on */
98
                if (ret == 1) {
99
                        /*
100
                         * Empty block.   Since we can't be sure it
101
                         * was entirely erased, we just queue it for erase
102
                         * again.  It will be marked as such when the erase
103
                         * is complete.  Meanwhile we still count it as empty
104
                         * for later checks.
105
                         */
106
                        list_add(&jeb->list, &c->erase_pending_list);
107
                        empty_blocks++;
108
                        c->nr_erasing_blocks++;
109
                } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
110
                        /* Only a CLEANMARKER node is valid */
111
                        if (!jeb->dirty_size) {
112
                                /* It's actually free */
113
                                list_add(&jeb->list, &c->free_list);
114
                                c->nr_free_blocks++;
115
                        } else {
116
                                /* Dirt */
117
                                D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset));
118
                                list_add(&jeb->list, &c->erase_pending_list);
119
                                c->nr_erasing_blocks++;
120
                        }
121
                } else if (jeb->used_size > c->sector_size - (2*sizeof(struct jffs2_raw_inode))) {
122
                        /* Full (or almost full) of clean data. Clean list */
123
                        list_add(&jeb->list, &c->clean_list);
124
                } else if (jeb->used_size) {
125
                        /* Some data, but not full. Dirty list. */
126
                        /* Except that we want to remember the block with most free space,
127
                           and stick it in the 'nextblock' position to start writing to it.
128
                           Later when we do snapshots, this must be the most recent block,
129
                           not the one with most free space.
130
                        */
131
                        if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) &&
132
                                (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
133
                                /* Better candidate for the next writes to go to */
134
                                if (c->nextblock)
135
                                        list_add(&c->nextblock->list, &c->dirty_list);
136
                                c->nextblock = jeb;
137
                        } else {
138
                                list_add(&jeb->list, &c->dirty_list);
139
                        }
140
                } else {
141
                        /* Nothing valid - not even a clean marker. Needs erasing. */
142
                        /* For now we just put it on the erasing list. We'll start the erases later */
143
                        printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
144
                        list_add(&jeb->list, &c->erase_pending_list);
145
                        c->nr_erasing_blocks++;
146
                }
147
        }
148
        /* Rotate the lists by some number to ensure wear levelling */
149
        jffs2_rotate_lists(c);
150
 
151
        if (c->nr_erasing_blocks) {
152
                if (!c->used_size && empty_blocks != c->nr_blocks) {
153
                        printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
154
                        return -EIO;
155
                }
156
                jffs2_erase_pending_trigger(c);
157
        }
158
        return 0;
159
}
160
 
161
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
162
        struct jffs2_unknown_node node;
163
        __u32 ofs, prevofs;
164
        __u32 hdr_crc, nodetype;
165
        int err;
166
        int noise = 0;
167
 
168
        ofs = jeb->offset;
169
        prevofs = jeb->offset - 1;
170
 
171
        D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
172
 
173
        err = jffs2_scan_empty(c, jeb, &ofs, &noise);
174
        if (err) return err;
175
        if (ofs == jeb->offset + c->sector_size) {
176
                D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
177
                return 1;       /* special return code */
178
        }
179
 
180
        noise = 10;
181
 
182
        while(ofs < jeb->offset + c->sector_size) {
183
                ssize_t retlen;
184
                ACCT_PARANOIA_CHECK(jeb);
185
 
186
                if (ofs & 3) {
187
                        printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
188
                        ofs = (ofs+3)&~3;
189
                        continue;
190
                }
191
                if (ofs == prevofs) {
192
                        printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);
193
                        DIRTY_SPACE(4);
194
                        ofs += 4;
195
                        continue;
196
                }
197
                prevofs = ofs;
198
 
199
                if (jeb->offset + c->sector_size < ofs + sizeof(node)) {
200
                        D1(printk(KERN_DEBUG "Fewer than %d bytes left to end of block. Not reading\n", sizeof(struct jffs2_unknown_node)));
201
                        DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
202
                        break;
203
                }
204
 
205
                err = c->mtd->read(c->mtd, ofs, sizeof(node), &retlen, (char *)&node);
206
 
207
                if (err) {
208
                        D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", sizeof(node), ofs, err));
209
                        return err;
210
                }
211
                if (retlen < sizeof(node)) {
212
                        D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%x bytes\n", ofs, retlen));
213
                        DIRTY_SPACE(retlen);
214
                        ofs += retlen;
215
                        continue;
216
                }
217
 
218
                if (node.magic == JFFS2_EMPTY_BITMASK && node.nodetype == JFFS2_EMPTY_BITMASK) {
219
                        D1(printk(KERN_DEBUG "Found empty flash at 0x%x\n", ofs));
220
                        err = jffs2_scan_empty(c, jeb, &ofs, &noise);
221
                        if (err) return err;
222
                        continue;
223
                }
224
 
225
                if (ofs == jeb->offset && node.magic == KSAMTIB_CIGAM_2SFFJ) {
226
                        printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
227
                        DIRTY_SPACE(4);
228
                        ofs += 4;
229
                        continue;
230
                }
231
                if (node.magic == JFFS2_DIRTY_BITMASK) {
232
                        D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs));
233
                        DIRTY_SPACE(4);
234
                        ofs += 4;
235
                        continue;
236
                }
237
                if (node.magic == JFFS2_OLD_MAGIC_BITMASK) {
238
                        printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
239
                        printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
240
                        DIRTY_SPACE(4);
241
                        ofs += 4;
242
                        continue;
243
                }
244
                if (node.magic != JFFS2_MAGIC_BITMASK) {
245
                        /* OK. We're out of possibilities. Whinge and move on */
246
                        noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, node.magic);
247
                        DIRTY_SPACE(4);
248
                        ofs += 4;
249
                        continue;
250
                }
251
                /* We seem to have a node of sorts. Check the CRC */
252
                nodetype = node.nodetype;
253
                node.nodetype |= JFFS2_NODE_ACCURATE;
254
                hdr_crc = crc32(0, &node, sizeof(node)-4);
255
                node.nodetype = nodetype;
256
                if (hdr_crc != node.hdr_crc) {
257
                        noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
258
                                     ofs, node.magic, node.nodetype, node.totlen, node.hdr_crc, hdr_crc);
259
                        DIRTY_SPACE(4);
260
                        ofs += 4;
261
                        continue;
262
                }
263
 
264
                if (ofs + node.totlen > jeb->offset + c->sector_size) {
265
                        /* Eep. Node goes over the end of the erase block. */
266
                        printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
267
                               ofs, node.totlen);
268
                        printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
269
                        DIRTY_SPACE(4);
270
                        ofs += 4;
271
                        continue;
272
                }
273
 
274
                switch(node.nodetype | JFFS2_NODE_ACCURATE) {
275
                case JFFS2_NODETYPE_INODE:
276
                        err = jffs2_scan_inode_node(c, jeb, &ofs);
277
                        if (err) return err;
278
                        break;
279
 
280
                case JFFS2_NODETYPE_DIRENT:
281
                        err = jffs2_scan_dirent_node(c, jeb, &ofs);
282
                        if (err) return err;
283
                        break;
284
 
285
                case JFFS2_NODETYPE_CLEANMARKER:
286
                        if (node.totlen != sizeof(struct jffs2_unknown_node)) {
287
                                printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
288
                                       ofs, node.totlen, sizeof(struct jffs2_unknown_node));
289
                                DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
290
                        } else if (jeb->first_node) {
291
                                printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
292
                                DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
293
                                ofs += PAD(sizeof(struct jffs2_unknown_node));
294
                                continue;
295
                        } else {
296
                                struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
297
                                if (!marker_ref) {
298
                                        printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");
299
                                        return -ENOMEM;
300
                                }
301
                                marker_ref->next_in_ino = NULL;
302
                                marker_ref->next_phys = NULL;
303
                                marker_ref->flash_offset = ofs;
304
                                marker_ref->totlen = sizeof(struct jffs2_unknown_node);
305
                                jeb->first_node = jeb->last_node = marker_ref;
306
 
307
                                USED_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
308
                        }
309
                        ofs += PAD(sizeof(struct jffs2_unknown_node));
310
                        break;
311
 
312
                default:
313
                        switch (node.nodetype & JFFS2_COMPAT_MASK) {
314
                        case JFFS2_FEATURE_ROCOMPAT:
315
                                printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
316
                                c->flags |= JFFS2_SB_FLAG_RO;
317
                                if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
318
                                        return -EROFS;
319
                                DIRTY_SPACE(PAD(node.totlen));
320
                                ofs += PAD(node.totlen);
321
                                continue;
322
 
323
                        case JFFS2_FEATURE_INCOMPAT:
324
                                printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
325
                                return -EINVAL;
326
 
327
                        case JFFS2_FEATURE_RWCOMPAT_DELETE:
328
                                printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
329
                                DIRTY_SPACE(PAD(node.totlen));
330
                                ofs += PAD(node.totlen);
331
                                break;
332
 
333
                        case JFFS2_FEATURE_RWCOMPAT_COPY:
334
                                printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
335
                                USED_SPACE(PAD(node.totlen));
336
                                ofs += PAD(node.totlen);
337
                                break;
338
                        }
339
                }
340
        }
341
        D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, used 0x%08x\n", jeb->offset,
342
                  jeb->free_size, jeb->dirty_size, jeb->used_size));
343
        return 0;
344
}
345
 
346
/* We're pointing at the first empty word on the flash. Scan and account for the whole dirty region */
347
static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *startofs, int *noise)
348
{
349
        __u32 *buf;
350
        __u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
351
        __u32 curofs = *startofs;
352
 
353
        buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
354
        if (!buf) {
355
                printk(KERN_WARNING "Scan buffer allocation failed\n");
356
                return -ENOMEM;
357
        }
358
        while(scanlen) {
359
                ssize_t retlen;
360
                int ret, i;
361
 
362
                ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
363
                if(ret) {
364
                        D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
365
                        kfree(buf);
366
                        return ret;
367
                }
368
                if (retlen < 4) {
369
                        D1(printk(KERN_WARNING "Eep. too few bytes read in scan_empty()\n"));
370
                        kfree(buf);
371
                        return -EIO;
372
                }
373
                for (i=0; i<(retlen / 4); i++) {
374
                        if (buf[i] != 0xffffffff) {
375
                                curofs += i*4;
376
 
377
                                noisy_printk(noise, "jffs2_scan_empty(): Empty block at 0x%08x ends at 0x%08x (with 0x%08x)! Marking dirty\n", *startofs, curofs, buf[i]);
378
                                DIRTY_SPACE(curofs - (*startofs));
379
                                *startofs = curofs;
380
                                kfree(buf);
381
                                return 0;
382
                        }
383
                }
384
                scanlen -= retlen&~3;
385
                curofs += retlen&~3;
386
        }
387
 
388
        D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs));
389
        kfree(buf);
390
        *startofs = curofs;
391
        return 0;
392
}
393
 
394
static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino)
395
{
396
        struct jffs2_inode_cache *ic;
397
 
398
        ic = jffs2_get_ino_cache(c, ino);
399
        if (ic)
400
                return ic;
401
 
402
        ic = jffs2_alloc_inode_cache();
403
        if (!ic) {
404
                printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");
405
                return NULL;
406
        }
407
        memset(ic, 0, sizeof(*ic));
408
        ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL);
409
        if (!ic->scan) {
410
                printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n");
411
                jffs2_free_inode_cache(ic);
412
                return NULL;
413
        }
414
        memset(ic->scan, 0, sizeof(*ic->scan));
415
        ic->ino = ino;
416
        ic->nodes = (void *)ic;
417
        jffs2_add_ino_cache(c, ic);
418
        if (ino == 1)
419
                ic->nlink=1;
420
        return ic;
421
}
422
 
423
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
424
{
425
        struct jffs2_raw_node_ref *raw;
426
        struct jffs2_full_dnode *fn;
427
        struct jffs2_tmp_dnode_info *tn, **tn_list;
428
        struct jffs2_inode_cache *ic;
429
        struct jffs2_raw_inode ri;
430
        __u32 crc;
431
        __u16 oldnodetype;
432
        int ret;
433
        ssize_t retlen;
434
 
435
        D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs));
436
 
437
        ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri);
438
        if (ret) {
439
                printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret);
440
                return ret;
441
        }
442
        if (retlen != sizeof(ri)) {
443
                printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
444
                       retlen, *ofs, sizeof(ri));
445
                return -EIO;
446
        }
447
 
448
        /* We sort of assume that the node was accurate when it was
449
           first written to the medium :) */
450
        oldnodetype = ri.nodetype;
451
        ri.nodetype |= JFFS2_NODE_ACCURATE;
452
        crc = crc32(0, &ri, sizeof(ri)-8);
453
        ri.nodetype = oldnodetype;
454
 
455
        if(crc != ri.node_crc) {
456
                printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
457
                       *ofs, ri.node_crc, crc);
458
                /* FIXME: Why do we believe totlen? */
459
                DIRTY_SPACE(4);
460
                *ofs += 4;
461
                return 0;
462
        }
463
        /* There was a bug where we wrote hole nodes out with csize/dsize
464
           swapped. Deal with it */
465
        if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
466
                ri.dsize = ri.csize;
467
                ri.csize = 0;
468
        }
469
 
470
        if (ri.csize) {
471
                /* Check data CRC too */
472
                unsigned char *dbuf;
473
                __u32 crc;
474
 
475
                dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
476
                if (!dbuf) {
477
                        printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n");
478
                        return -ENOMEM;
479
                }
480
                ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf);
481
                if (ret) {
482
                        printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret);
483
                        kfree(dbuf);
484
                        return ret;
485
                }
486
                if (retlen != ri.csize) {
487
                        printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
488
                               retlen, *ofs+ sizeof(ri), ri.csize);
489
                        kfree(dbuf);
490
                        return -EIO;
491
                }
492
                crc = crc32(0, dbuf, ri.csize);
493
                kfree(dbuf);
494
                if (crc != ri.data_crc) {
495
                        printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
496
                               *ofs, ri.data_crc, crc);
497
                        DIRTY_SPACE(PAD(ri.totlen));
498
                        *ofs += PAD(ri.totlen);
499
                        return 0;
500
                }
501
        }
502
 
503
        /* Wheee. It worked */
504
        raw = jffs2_alloc_raw_node_ref();
505
        if (!raw) {
506
                printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
507
                return -ENOMEM;
508
        }
509
        tn = jffs2_alloc_tmp_dnode_info();
510
        if (!tn) {
511
                jffs2_free_raw_node_ref(raw);
512
                return -ENOMEM;
513
        }
514
        fn = jffs2_alloc_full_dnode();
515
        if (!fn) {
516
                jffs2_free_tmp_dnode_info(tn);
517
                jffs2_free_raw_node_ref(raw);
518
                return -ENOMEM;
519
        }
520
        ic = jffs2_scan_make_ino_cache(c, ri.ino);
521
        if (!ic) {
522
                jffs2_free_full_dnode(fn);
523
                jffs2_free_tmp_dnode_info(tn);
524
                jffs2_free_raw_node_ref(raw);
525
                return -ENOMEM;
526
        }
527
 
528
        /* Build the data structures and file them for later */
529
        raw->flash_offset = *ofs;
530
        raw->totlen = PAD(ri.totlen);
531
        raw->next_phys = NULL;
532
        raw->next_in_ino = ic->nodes;
533
        ic->nodes = raw;
534
        if (!jeb->first_node)
535
                jeb->first_node = raw;
536
        if (jeb->last_node)
537
                jeb->last_node->next_phys = raw;
538
        jeb->last_node = raw;
539
 
540
        D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
541
                  ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
542
 
543
        pseudo_random += ri.version;
544
 
545
        for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
546
                if ((*tn_list)->version < ri.version)
547
                        continue;
548
                if ((*tn_list)->version > ri.version)
549
                        break;
550
                /* Wheee. We've found another instance of the same version number.
551
                   We should obsolete one of them.
552
                */
553
                D1(printk(KERN_DEBUG "Duplicate version %d found in ino #%u. Previous one is at 0x%08x\n", ri.version, ic->ino, (*tn_list)->fn->raw->flash_offset &~3));
554
                if (!jeb->used_size) {
555
                        D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n",
556
                                  jeb->offset, raw->flash_offset & ~3));
557
                        ri.nodetype &= ~JFFS2_NODE_ACCURATE;
558
                        /* Perhaps we could also mark it as such on the medium. Maybe later */
559
                }
560
                break;
561
        }
562
 
563
        if (ri.nodetype & JFFS2_NODE_ACCURATE) {
564
                memset(fn,0,sizeof(*fn));
565
 
566
                fn->ofs = ri.offset;
567
                fn->size = ri.dsize;
568
                fn->frags = 0;
569
                fn->raw = raw;
570
 
571
                tn->next = NULL;
572
                tn->fn = fn;
573
                tn->version = ri.version;
574
 
575
                USED_SPACE(PAD(ri.totlen));
576
                jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes);
577
                /* Make sure the one we just added is the _last_ in the list
578
                   with this version number, so the older ones get obsoleted */
579
                while (tn->next && tn->next->version == tn->version) {
580
 
581
                        D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n",
582
                                  fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version));
583
 
584
                        if(tn->fn != fn)
585
                                BUG();
586
                        tn->fn = tn->next->fn;
587
                        tn->next->fn = fn;
588
                        tn = tn->next;
589
                }
590
        } else {
591
                jffs2_free_full_dnode(fn);
592
                jffs2_free_tmp_dnode_info(tn);
593
                raw->flash_offset |= 1;
594
                DIRTY_SPACE(PAD(ri.totlen));
595
        }
596
        *ofs += PAD(ri.totlen);
597
        return 0;
598
}
599
 
600
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
601
{
602
        struct jffs2_raw_node_ref *raw;
603
        struct jffs2_full_dirent *fd;
604
        struct jffs2_inode_cache *ic;
605
        struct jffs2_raw_dirent rd;
606
        __u16 oldnodetype;
607
        int ret;
608
        __u32 crc;
609
        ssize_t retlen;
610
 
611
        D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs));
612
 
613
        ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd);
614
        if (ret) {
615
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret);
616
                return ret;
617
        }
618
        if (retlen != sizeof(rd)) {
619
                printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
620
                       retlen, *ofs, sizeof(rd));
621
                return -EIO;
622
        }
623
 
624
        /* We sort of assume that the node was accurate when it was
625
           first written to the medium :) */
626
        oldnodetype = rd.nodetype;
627
        rd.nodetype |= JFFS2_NODE_ACCURATE;
628
        crc = crc32(0, &rd, sizeof(rd)-8);
629
        rd.nodetype = oldnodetype;
630
 
631
        if (crc != rd.node_crc) {
632
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
633
                       *ofs, rd.node_crc, crc);
634
                /* FIXME: Why do we believe totlen? */
635
                DIRTY_SPACE(4);
636
                *ofs += 4;
637
                return 0;
638
        }
639
 
640
        pseudo_random += rd.version;
641
 
642
        fd = jffs2_alloc_full_dirent(rd.nsize+1);
643
        if (!fd) {
644
                return -ENOMEM;
645
}
646
        ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]);
647
        if (ret) {
648
                jffs2_free_full_dirent(fd);
649
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n",
650
                       *ofs + sizeof(rd), ret);
651
                return ret;
652
        }
653
        if (retlen != rd.nsize) {
654
                jffs2_free_full_dirent(fd);
655
                printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
656
                       retlen, *ofs + sizeof(rd), rd.nsize);
657
                return -EIO;
658
        }
659
        crc = crc32(0, fd->name, rd.nsize);
660
        if (crc != rd.name_crc) {
661
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
662
                       *ofs, rd.name_crc, crc);
663
                fd->name[rd.nsize]=0;
664
                D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
665
                jffs2_free_full_dirent(fd);
666
                /* FIXME: Why do we believe totlen? */
667
                DIRTY_SPACE(PAD(rd.totlen));
668
                *ofs += PAD(rd.totlen);
669
                return 0;
670
        }
671
        raw = jffs2_alloc_raw_node_ref();
672
        if (!raw) {
673
                jffs2_free_full_dirent(fd);
674
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
675
                return -ENOMEM;
676
        }
677
        ic = jffs2_scan_make_ino_cache(c, rd.pino);
678
        if (!ic) {
679
                jffs2_free_full_dirent(fd);
680
                jffs2_free_raw_node_ref(raw);
681
                return -ENOMEM;
682
        }
683
 
684
        raw->totlen = PAD(rd.totlen);
685
        raw->flash_offset = *ofs;
686
        raw->next_phys = NULL;
687
        raw->next_in_ino = ic->nodes;
688
        ic->nodes = raw;
689
        if (!jeb->first_node)
690
                jeb->first_node = raw;
691
        if (jeb->last_node)
692
                jeb->last_node->next_phys = raw;
693
        jeb->last_node = raw;
694
 
695
        if (rd.nodetype & JFFS2_NODE_ACCURATE) {
696
                fd->raw = raw;
697
                fd->next = NULL;
698
                fd->version = rd.version;
699
                fd->ino = rd.ino;
700
                fd->name[rd.nsize]=0;
701
                fd->nhash = full_name_hash(fd->name, rd.nsize);
702
                fd->type = rd.type;
703
 
704
                USED_SPACE(PAD(rd.totlen));
705
                jffs2_add_fd_to_list(c, fd, &ic->scan->dents);
706
        } else {
707
                raw->flash_offset |= 1;
708
                jffs2_free_full_dirent(fd);
709
 
710
                DIRTY_SPACE(PAD(rd.totlen));
711
        }
712
        *ofs += PAD(rd.totlen);
713
        return 0;
714
}
715
 
716
static int count_list(struct list_head *l)
717
{
718
        uint32_t count = 0;
719
        struct list_head *tmp;
720
 
721
        list_for_each(tmp, l) {
722
                count++;
723
        }
724
        return count;
725
}
726
 
727
/* Note: This breaks if list_empty(head). I don't care. You
728
   might, if you copy this code and use it elsewhere :) */
729
static void rotate_list(struct list_head *head, uint32_t count)
730
{
731
        struct list_head *n = head->next;
732
 
733
        list_del(head);
734
        while(count--)
735
                n = n->next;
736
        list_add(head, n);
737
}
738
 
739
static void jffs2_rotate_lists(struct jffs2_sb_info *c)
740
{
741
        uint32_t x;
742
 
743
        x = count_list(&c->clean_list);
744
        if (x)
745
                rotate_list((&c->clean_list), pseudo_random % x);
746
 
747
        x = count_list(&c->dirty_list);
748
        if (x)
749
                rotate_list((&c->dirty_list), pseudo_random % x);
750
 
751
        if (c->nr_erasing_blocks)
752
                rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
753
 
754
        if (c->nr_free_blocks) /* Not that it should ever be zero */
755
                rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
756
}

powered by: WebSVN 2.1.0

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