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

Subversion Repositories openrisc

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

Go to most recent revision | 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: scan.c,v 1.121 2005/07/20 15:32:28 dedekind Exp $
11
 *
12
 */
13
#include <linux/kernel.h>
14
#include <linux/sched.h>
15
#include <linux/slab.h>
16
#include <linux/mtd/mtd.h>
17
#include <linux/pagemap.h>
18
#include <linux/crc32.h>
19
#include <linux/compiler.h>
20
#include "nodelist.h"
21
 
22
#define DEFAULT_EMPTY_SCAN_SIZE 1024
23
 
24
#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25
                c->free_size -= _x; c->dirty_size += _x; \
26
                jeb->free_size -= _x ; jeb->dirty_size += _x; \
27
                }while(0)
28
#define USED_SPACE(x) do { typeof(x) _x = (x); \
29
                c->free_size -= _x; c->used_size += _x; \
30
                jeb->free_size -= _x ; jeb->used_size += _x; \
31
                }while(0)
32
#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
33
                c->free_size -= _x; c->unchecked_size += _x; \
34
                jeb->free_size -= _x ; jeb->unchecked_size += _x; \
35
                }while(0)
36
 
37
#define noisy_printk(noise, args...) do { \
38
        if (*(noise)) { \
39
                printk(KERN_NOTICE args); \
40
                 (*(noise))--; \
41
                 if (!(*(noise))) { \
42
                         printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \
43
                 } \
44
        } \
45
} while(0)
46
 
47
static uint32_t pseudo_random;
48
 
49
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
50
                                  unsigned char *buf, uint32_t buf_size);
51
 
52
/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
53
 * Returning an error will abort the mount - bad checksums etc. should just mark the space
54
 * as dirty.
55
 */
56
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
57
                                 struct jffs2_raw_inode *ri, uint32_t ofs);
58
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
59
                                 struct jffs2_raw_dirent *rd, uint32_t ofs);
60
 
61
#define BLK_STATE_ALLFF         0
62
#define BLK_STATE_CLEAN         1
63
#define BLK_STATE_PARTDIRTY     2
64
#define BLK_STATE_CLEANMARKER   3
65
#define BLK_STATE_ALLDIRTY      4
66
#define BLK_STATE_BADBLOCK      5
67
 
68
static inline int min_free(struct jffs2_sb_info *c)
69
{
70
        uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
71
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
72
        if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
73
                return c->wbuf_pagesize;
74
#endif
75
        return min;
76
 
77
}
78
 
79
static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
80
        if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
81
                return sector_size;
82
        else
83
                return DEFAULT_EMPTY_SCAN_SIZE;
84
}
85
 
86
int jffs2_scan_medium(struct jffs2_sb_info *c)
87
{
88
        int i, ret;
89
        uint32_t empty_blocks = 0, bad_blocks = 0;
90
        unsigned char *flashbuf = NULL;
91
        uint32_t buf_size = 0;
92
#ifndef __ECOS
93
        size_t pointlen;
94
 
95
        if (c->mtd->point) {
96
                ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
97
                if (!ret && pointlen < c->mtd->size) {
98
                        /* Don't muck about if it won't let us point to the whole flash */
99
                        D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
100
                        c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
101
                        flashbuf = NULL;
102
                }
103
                if (ret)
104
                        D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
105
        }
106
#endif
107
        if (!flashbuf) {
108
                /* For NAND it's quicker to read a whole eraseblock at a time,
109
                   apparently */
110
                if (jffs2_cleanmarker_oob(c))
111
                        buf_size = c->sector_size;
112
                else
113
                        buf_size = PAGE_SIZE;
114
 
115
                /* Respect kmalloc limitations */
116
                if (buf_size > 128*1024)
117
                        buf_size = 128*1024;
118
 
119
                D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size));
120
                flashbuf = kmalloc(buf_size, GFP_KERNEL);
121
                if (!flashbuf)
122
                        return -ENOMEM;
123
        }
124
 
125
        for (i=0; i<c->nr_blocks; i++) {
126
                struct jffs2_eraseblock *jeb = &c->blocks[i];
127
 
128
                ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size);
129
 
130
                if (ret < 0)
131
                        goto out;
132
 
133
                jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
134
 
135
                /* Now decide which list to put it on */
136
                switch(ret) {
137
                case BLK_STATE_ALLFF:
138
                        /*
139
                         * Empty block.   Since we can't be sure it
140
                         * was entirely erased, we just queue it for erase
141
                         * again.  It will be marked as such when the erase
142
                         * is complete.  Meanwhile we still count it as empty
143
                         * for later checks.
144
                         */
145
                        empty_blocks++;
146
                        list_add(&jeb->list, &c->erase_pending_list);
147
                        c->nr_erasing_blocks++;
148
                        break;
149
 
150
                case BLK_STATE_CLEANMARKER:
151
                        /* Only a CLEANMARKER node is valid */
152
                        if (!jeb->dirty_size) {
153
                                /* It's actually free */
154
                                list_add(&jeb->list, &c->free_list);
155
                                c->nr_free_blocks++;
156
                        } else {
157
                                /* Dirt */
158
                                D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset));
159
                                list_add(&jeb->list, &c->erase_pending_list);
160
                                c->nr_erasing_blocks++;
161
                        }
162
                        break;
163
 
164
                case BLK_STATE_CLEAN:
165
                        /* Full (or almost full) of clean data. Clean list */
166
                        list_add(&jeb->list, &c->clean_list);
167
                        break;
168
 
169
                case BLK_STATE_PARTDIRTY:
170
                        /* Some data, but not full. Dirty list. */
171
                        /* We want to remember the block with most free space
172
                           and stick it in the 'nextblock' position to start writing to it. */
173
                        if (jeb->free_size > min_free(c) &&
174
                            (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
175
                                /* Better candidate for the next writes to go to */
176
                                if (c->nextblock) {
177
                                        c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
178
                                        c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
179
                                        c->free_size -= c->nextblock->free_size;
180
                                        c->wasted_size -= c->nextblock->wasted_size;
181
                                        c->nextblock->free_size = c->nextblock->wasted_size = 0;
182
                                        if (VERYDIRTY(c, c->nextblock->dirty_size)) {
183
                                                list_add(&c->nextblock->list, &c->very_dirty_list);
184
                                        } else {
185
                                                list_add(&c->nextblock->list, &c->dirty_list);
186
                                        }
187
                                }
188
                                c->nextblock = jeb;
189
                        } else {
190
                                jeb->dirty_size += jeb->free_size + jeb->wasted_size;
191
                                c->dirty_size += jeb->free_size + jeb->wasted_size;
192
                                c->free_size -= jeb->free_size;
193
                                c->wasted_size -= jeb->wasted_size;
194
                                jeb->free_size = jeb->wasted_size = 0;
195
                                if (VERYDIRTY(c, jeb->dirty_size)) {
196
                                        list_add(&jeb->list, &c->very_dirty_list);
197
                                } else {
198
                                        list_add(&jeb->list, &c->dirty_list);
199
                                }
200
                        }
201
                        break;
202
 
203
                case BLK_STATE_ALLDIRTY:
204
                        /* Nothing valid - not even a clean marker. Needs erasing. */
205
                        /* For now we just put it on the erasing list. We'll start the erases later */
206
                        D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
207
                        list_add(&jeb->list, &c->erase_pending_list);
208
                        c->nr_erasing_blocks++;
209
                        break;
210
 
211
                case BLK_STATE_BADBLOCK:
212
                        D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
213
                        list_add(&jeb->list, &c->bad_list);
214
                        c->bad_size += c->sector_size;
215
                        c->free_size -= c->sector_size;
216
                        bad_blocks++;
217
                        break;
218
                default:
219
                        printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
220
                        BUG();
221
                }
222
        }
223
 
224
        /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
225
        if (c->nextblock && (c->nextblock->dirty_size)) {
226
                c->nextblock->wasted_size += c->nextblock->dirty_size;
227
                c->wasted_size += c->nextblock->dirty_size;
228
                c->dirty_size -= c->nextblock->dirty_size;
229
                c->nextblock->dirty_size = 0;
230
        }
231
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
232
        if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
233
                /* If we're going to start writing into a block which already
234
                   contains data, and the end of the data isn't page-aligned,
235
                   skip a little and align it. */
236
 
237
                uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1);
238
 
239
                D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
240
                          skip));
241
                c->nextblock->wasted_size += skip;
242
                c->wasted_size += skip;
243
 
244
                c->nextblock->free_size -= skip;
245
                c->free_size -= skip;
246
        }
247
#endif
248
        if (c->nr_erasing_blocks) {
249
                if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
250
                        printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
251
                        printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
252
                        ret = -EIO;
253
                        goto out;
254
                }
255
                jffs2_erase_pending_trigger(c);
256
        }
257
        ret = 0;
258
 out:
259
        if (buf_size)
260
                kfree(flashbuf);
261
#ifndef __ECOS
262
        else
263
                c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
264
#endif
265
        return ret;
266
}
267
 
268
static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
269
                                uint32_t ofs, uint32_t len)
270
{
271
        int ret;
272
        size_t retlen;
273
 
274
        ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
275
        if (ret) {
276
                D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret));
277
                return ret;
278
        }
279
        if (retlen < len) {
280
                D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen));
281
                return -EIO;
282
        }
283
        D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs));
284
        D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
285
                  buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]));
286
        return 0;
287
}
288
 
289
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
290
                                  unsigned char *buf, uint32_t buf_size) {
291
        struct jffs2_unknown_node *node;
292
        struct jffs2_unknown_node crcnode;
293
        uint32_t ofs, prevofs;
294
        uint32_t hdr_crc, buf_ofs, buf_len;
295
        int err;
296
        int noise = 0;
297
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
298
        int cleanmarkerfound = 0;
299
#endif
300
 
301
        ofs = jeb->offset;
302
        prevofs = jeb->offset - 1;
303
 
304
        D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
305
 
306
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
307
        if (jffs2_cleanmarker_oob(c)) {
308
                int ret = jffs2_check_nand_cleanmarker(c, jeb);
309
                D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
310
                /* Even if it's not found, we still scan to see
311
                   if the block is empty. We use this information
312
                   to decide whether to erase it or not. */
313
                switch (ret) {
314
                case 0:          cleanmarkerfound = 1; break;
315
                case 1:         break;
316
                case 2:         return BLK_STATE_BADBLOCK;
317
                case 3:         return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
318
                default:        return ret;
319
                }
320
        }
321
#endif
322
        buf_ofs = jeb->offset;
323
 
324
        if (!buf_size) {
325
                buf_len = c->sector_size;
326
        } else {
327
                buf_len = EMPTY_SCAN_SIZE(c->sector_size);
328
                err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
329
                if (err)
330
                        return err;
331
        }
332
 
333
        /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
334
        ofs = 0;
335
 
336
        /* Scan only 4KiB of 0xFF before declaring it's empty */
337
        while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
338
                ofs += 4;
339
 
340
        if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
341
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
342
                if (jffs2_cleanmarker_oob(c)) {
343
                        /* scan oob, take care of cleanmarker */
344
                        int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
345
                        D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret));
346
                        switch (ret) {
347
                        case 0:          return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF;
348
                        case 1:         return BLK_STATE_ALLDIRTY;
349
                        default:        return ret;
350
                        }
351
                }
352
#endif
353
                D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
354
                if (c->cleanmarker_size == 0)
355
                        return BLK_STATE_CLEANMARKER;   /* don't bother with re-erase */
356
                else
357
                        return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
358
        }
359
        if (ofs) {
360
                D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
361
                          jeb->offset + ofs));
362
                DIRTY_SPACE(ofs);
363
        }
364
 
365
        /* Now ofs is a complete physical flash offset as it always was... */
366
        ofs += jeb->offset;
367
 
368
        noise = 10;
369
 
370
scan_more:
371
        while(ofs < jeb->offset + c->sector_size) {
372
 
373
                jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
374
 
375
                cond_resched();
376
 
377
                if (ofs & 3) {
378
                        printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
379
                        ofs = PAD(ofs);
380
                        continue;
381
                }
382
                if (ofs == prevofs) {
383
                        printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);
384
                        DIRTY_SPACE(4);
385
                        ofs += 4;
386
                        continue;
387
                }
388
                prevofs = ofs;
389
 
390
                if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
391
                        D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),
392
                                  jeb->offset, c->sector_size, ofs, sizeof(*node)));
393
                        DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
394
                        break;
395
                }
396
 
397
                if (buf_ofs + buf_len < ofs + sizeof(*node)) {
398
                        buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
399
                        D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",
400
                                  sizeof(struct jffs2_unknown_node), buf_len, ofs));
401
                        err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
402
                        if (err)
403
                                return err;
404
                        buf_ofs = ofs;
405
                }
406
 
407
                node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];
408
 
409
                if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
410
                        uint32_t inbuf_ofs;
411
                        uint32_t empty_start;
412
 
413
                        empty_start = ofs;
414
                        ofs += 4;
415
 
416
                        D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));
417
                more_empty:
418
                        inbuf_ofs = ofs - buf_ofs;
419
                        while (inbuf_ofs < buf_len) {
420
                                if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {
421
                                        printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
422
                                               empty_start, ofs);
423
                                        DIRTY_SPACE(ofs-empty_start);
424
                                        goto scan_more;
425
                                }
426
 
427
                                inbuf_ofs+=4;
428
                                ofs += 4;
429
                        }
430
                        /* Ran off end. */
431
                        D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs));
432
 
433
                        /* If we're only checking the beginning of a block with a cleanmarker,
434
                           bail now */
435
                        if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
436
                            c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
437
                                D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
438
                                return BLK_STATE_CLEANMARKER;
439
                        }
440
 
441
                        /* See how much more there is to read in this eraseblock... */
442
                        buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
443
                        if (!buf_len) {
444
                                /* No more to read. Break out of main loop without marking
445
                                   this range of empty space as dirty (because it's not) */
446
                                D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
447
                                          empty_start));
448
                                break;
449
                        }
450
                        D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs));
451
                        err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
452
                        if (err)
453
                                return err;
454
                        buf_ofs = ofs;
455
                        goto more_empty;
456
                }
457
 
458
                if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
459
                        printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
460
                        DIRTY_SPACE(4);
461
                        ofs += 4;
462
                        continue;
463
                }
464
                if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
465
                        D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
466
                        DIRTY_SPACE(4);
467
                        ofs += 4;
468
                        continue;
469
                }
470
                if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {
471
                        printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
472
                        printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
473
                        DIRTY_SPACE(4);
474
                        ofs += 4;
475
                        continue;
476
                }
477
                if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
478
                        /* OK. We're out of possibilities. Whinge and move on */
479
                        noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
480
                                     JFFS2_MAGIC_BITMASK, ofs,
481
                                     je16_to_cpu(node->magic));
482
                        DIRTY_SPACE(4);
483
                        ofs += 4;
484
                        continue;
485
                }
486
                /* We seem to have a node of sorts. Check the CRC */
487
                crcnode.magic = node->magic;
488
                crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE);
489
                crcnode.totlen = node->totlen;
490
                hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4);
491
 
492
                if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
493
                        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",
494
                                     ofs, je16_to_cpu(node->magic),
495
                                     je16_to_cpu(node->nodetype),
496
                                     je32_to_cpu(node->totlen),
497
                                     je32_to_cpu(node->hdr_crc),
498
                                     hdr_crc);
499
                        DIRTY_SPACE(4);
500
                        ofs += 4;
501
                        continue;
502
                }
503
 
504
                if (ofs + je32_to_cpu(node->totlen) >
505
                    jeb->offset + c->sector_size) {
506
                        /* Eep. Node goes over the end of the erase block. */
507
                        printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
508
                               ofs, je32_to_cpu(node->totlen));
509
                        printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
510
                        DIRTY_SPACE(4);
511
                        ofs += 4;
512
                        continue;
513
                }
514
 
515
                if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {
516
                        /* Wheee. This is an obsoleted node */
517
                        D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));
518
                        DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
519
                        ofs += PAD(je32_to_cpu(node->totlen));
520
                        continue;
521
                }
522
 
523
                switch(je16_to_cpu(node->nodetype)) {
524
                case JFFS2_NODETYPE_INODE:
525
                        if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) {
526
                                buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
527
                                D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n",
528
                                          sizeof(struct jffs2_raw_inode), buf_len, ofs));
529
                                err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
530
                                if (err)
531
                                        return err;
532
                                buf_ofs = ofs;
533
                                node = (void *)buf;
534
                        }
535
                        err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs);
536
                        if (err) return err;
537
                        ofs += PAD(je32_to_cpu(node->totlen));
538
                        break;
539
 
540
                case JFFS2_NODETYPE_DIRENT:
541
                        if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
542
                                buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
543
                                D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n",
544
                                          je32_to_cpu(node->totlen), buf_len, ofs));
545
                                err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
546
                                if (err)
547
                                        return err;
548
                                buf_ofs = ofs;
549
                                node = (void *)buf;
550
                        }
551
                        err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs);
552
                        if (err) return err;
553
                        ofs += PAD(je32_to_cpu(node->totlen));
554
                        break;
555
 
556
                case JFFS2_NODETYPE_CLEANMARKER:
557
                        D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
558
                        if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
559
                                printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
560
                                       ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
561
                                DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
562
                                ofs += PAD(sizeof(struct jffs2_unknown_node));
563
                        } else if (jeb->first_node) {
564
                                printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
565
                                DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
566
                                ofs += PAD(sizeof(struct jffs2_unknown_node));
567
                        } else {
568
                                struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
569
                                if (!marker_ref) {
570
                                        printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");
571
                                        return -ENOMEM;
572
                                }
573
                                marker_ref->next_in_ino = NULL;
574
                                marker_ref->next_phys = NULL;
575
                                marker_ref->flash_offset = ofs | REF_NORMAL;
576
                                marker_ref->__totlen = c->cleanmarker_size;
577
                                jeb->first_node = jeb->last_node = marker_ref;
578
 
579
                                USED_SPACE(PAD(c->cleanmarker_size));
580
                                ofs += PAD(c->cleanmarker_size);
581
                        }
582
                        break;
583
 
584
                case JFFS2_NODETYPE_PADDING:
585
                        DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
586
                        ofs += PAD(je32_to_cpu(node->totlen));
587
                        break;
588
 
589
                default:
590
                        switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {
591
                        case JFFS2_FEATURE_ROCOMPAT:
592
                                printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
593
                                c->flags |= JFFS2_SB_FLAG_RO;
594
                                if (!(jffs2_is_readonly(c)))
595
                                        return -EROFS;
596
                                DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
597
                                ofs += PAD(je32_to_cpu(node->totlen));
598
                                break;
599
 
600
                        case JFFS2_FEATURE_INCOMPAT:
601
                                printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
602
                                return -EINVAL;
603
 
604
                        case JFFS2_FEATURE_RWCOMPAT_DELETE:
605
                                D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
606
                                DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
607
                                ofs += PAD(je32_to_cpu(node->totlen));
608
                                break;
609
 
610
                        case JFFS2_FEATURE_RWCOMPAT_COPY:
611
                                D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
612
                                USED_SPACE(PAD(je32_to_cpu(node->totlen)));
613
                                ofs += PAD(je32_to_cpu(node->totlen));
614
                                break;
615
                        }
616
                }
617
        }
618
 
619
 
620
        D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
621
                  jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
622
 
623
        /* mark_node_obsolete can add to wasted !! */
624
        if (jeb->wasted_size) {
625
                jeb->dirty_size += jeb->wasted_size;
626
                c->dirty_size += jeb->wasted_size;
627
                c->wasted_size -= jeb->wasted_size;
628
                jeb->wasted_size = 0;
629
        }
630
 
631
        if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
632
                && (!jeb->first_node || !jeb->first_node->next_phys) )
633
                return BLK_STATE_CLEANMARKER;
634
 
635
        /* move blocks with max 4 byte dirty space to cleanlist */
636
        else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
637
                c->dirty_size -= jeb->dirty_size;
638
                c->wasted_size += jeb->dirty_size;
639
                jeb->wasted_size += jeb->dirty_size;
640
                jeb->dirty_size = 0;
641
                return BLK_STATE_CLEAN;
642
        } else if (jeb->used_size || jeb->unchecked_size)
643
                return BLK_STATE_PARTDIRTY;
644
        else
645
                return BLK_STATE_ALLDIRTY;
646
}
647
 
648
static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
649
{
650
        struct jffs2_inode_cache *ic;
651
 
652
        ic = jffs2_get_ino_cache(c, ino);
653
        if (ic)
654
                return ic;
655
 
656
        if (ino > c->highest_ino)
657
                c->highest_ino = ino;
658
 
659
        ic = jffs2_alloc_inode_cache();
660
        if (!ic) {
661
                printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");
662
                return NULL;
663
        }
664
        memset(ic, 0, sizeof(*ic));
665
 
666
        ic->ino = ino;
667
        ic->nodes = (void *)ic;
668
        jffs2_add_ino_cache(c, ic);
669
        if (ino == 1)
670
                ic->nlink = 1;
671
        return ic;
672
}
673
 
674
static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
675
                                 struct jffs2_raw_inode *ri, uint32_t ofs)
676
{
677
        struct jffs2_raw_node_ref *raw;
678
        struct jffs2_inode_cache *ic;
679
        uint32_t ino = je32_to_cpu(ri->ino);
680
 
681
        D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
682
 
683
        /* We do very little here now. Just check the ino# to which we should attribute
684
           this node; we can do all the CRC checking etc. later. There's a tradeoff here --
685
           we used to scan the flash once only, reading everything we want from it into
686
           memory, then building all our in-core data structures and freeing the extra
687
           information. Now we allow the first part of the mount to complete a lot quicker,
688
           but we have to go _back_ to the flash in order to finish the CRC checking, etc.
689
           Which means that the _full_ amount of time to get to proper write mode with GC
690
           operational may actually be _longer_ than before. Sucks to be me. */
691
 
692
        raw = jffs2_alloc_raw_node_ref();
693
        if (!raw) {
694
                printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
695
                return -ENOMEM;
696
        }
697
 
698
        ic = jffs2_get_ino_cache(c, ino);
699
        if (!ic) {
700
                /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the
701
                   first node we found for this inode. Do a CRC check to protect against the former
702
                   case */
703
                uint32_t crc = crc32(0, ri, sizeof(*ri)-8);
704
 
705
                if (crc != je32_to_cpu(ri->node_crc)) {
706
                        printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
707
                               ofs, je32_to_cpu(ri->node_crc), crc);
708
                        /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
709
                        DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen)));
710
                        jffs2_free_raw_node_ref(raw);
711
                        return 0;
712
                }
713
                ic = jffs2_scan_make_ino_cache(c, ino);
714
                if (!ic) {
715
                        jffs2_free_raw_node_ref(raw);
716
                        return -ENOMEM;
717
                }
718
        }
719
 
720
        /* Wheee. It worked */
721
 
722
        raw->flash_offset = ofs | REF_UNCHECKED;
723
        raw->__totlen = PAD(je32_to_cpu(ri->totlen));
724
        raw->next_phys = NULL;
725
        raw->next_in_ino = ic->nodes;
726
 
727
        ic->nodes = raw;
728
        if (!jeb->first_node)
729
                jeb->first_node = raw;
730
        if (jeb->last_node)
731
                jeb->last_node->next_phys = raw;
732
        jeb->last_node = raw;
733
 
734
        D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
735
                  je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
736
                  je32_to_cpu(ri->offset),
737
                  je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
738
 
739
        pseudo_random += je32_to_cpu(ri->version);
740
 
741
        UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
742
        return 0;
743
}
744
 
745
static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
746
                                  struct jffs2_raw_dirent *rd, uint32_t ofs)
747
{
748
        struct jffs2_raw_node_ref *raw;
749
        struct jffs2_full_dirent *fd;
750
        struct jffs2_inode_cache *ic;
751
        uint32_t crc;
752
 
753
        D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs));
754
 
755
        /* We don't get here unless the node is still valid, so we don't have to
756
           mask in the ACCURATE bit any more. */
757
        crc = crc32(0, rd, sizeof(*rd)-8);
758
 
759
        if (crc != je32_to_cpu(rd->node_crc)) {
760
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
761
                       ofs, je32_to_cpu(rd->node_crc), crc);
762
                /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
763
                DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
764
                return 0;
765
        }
766
 
767
        pseudo_random += je32_to_cpu(rd->version);
768
 
769
        fd = jffs2_alloc_full_dirent(rd->nsize+1);
770
        if (!fd) {
771
                return -ENOMEM;
772
        }
773
        memcpy(&fd->name, rd->name, rd->nsize);
774
        fd->name[rd->nsize] = 0;
775
 
776
        crc = crc32(0, fd->name, rd->nsize);
777
        if (crc != je32_to_cpu(rd->name_crc)) {
778
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
779
                       ofs, je32_to_cpu(rd->name_crc), crc);
780
                D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
781
                jffs2_free_full_dirent(fd);
782
                /* FIXME: Why do we believe totlen? */
783
                /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
784
                DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
785
                return 0;
786
        }
787
        raw = jffs2_alloc_raw_node_ref();
788
        if (!raw) {
789
                jffs2_free_full_dirent(fd);
790
                printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
791
                return -ENOMEM;
792
        }
793
        ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino));
794
        if (!ic) {
795
                jffs2_free_full_dirent(fd);
796
                jffs2_free_raw_node_ref(raw);
797
                return -ENOMEM;
798
        }
799
 
800
        raw->__totlen = PAD(je32_to_cpu(rd->totlen));
801
        raw->flash_offset = ofs | REF_PRISTINE;
802
        raw->next_phys = NULL;
803
        raw->next_in_ino = ic->nodes;
804
        ic->nodes = raw;
805
        if (!jeb->first_node)
806
                jeb->first_node = raw;
807
        if (jeb->last_node)
808
                jeb->last_node->next_phys = raw;
809
        jeb->last_node = raw;
810
 
811
        fd->raw = raw;
812
        fd->next = NULL;
813
        fd->version = je32_to_cpu(rd->version);
814
        fd->ino = je32_to_cpu(rd->ino);
815
        fd->nhash = full_name_hash(fd->name, rd->nsize);
816
        fd->type = rd->type;
817
        USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
818
        jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
819
 
820
        return 0;
821
}
822
 
823
static int count_list(struct list_head *l)
824
{
825
        uint32_t count = 0;
826
        struct list_head *tmp;
827
 
828
        list_for_each(tmp, l) {
829
                count++;
830
        }
831
        return count;
832
}
833
 
834
/* Note: This breaks if list_empty(head). I don't care. You
835
   might, if you copy this code and use it elsewhere :) */
836
static void rotate_list(struct list_head *head, uint32_t count)
837
{
838
        struct list_head *n = head->next;
839
 
840
        list_del(head);
841
        while(count--) {
842
                n = n->next;
843
        }
844
        list_add(head, n);
845
}
846
 
847
void jffs2_rotate_lists(struct jffs2_sb_info *c)
848
{
849
        uint32_t x;
850
        uint32_t rotateby;
851
 
852
        x = count_list(&c->clean_list);
853
        if (x) {
854
                rotateby = pseudo_random % x;
855
                D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
856
 
857
                rotate_list((&c->clean_list), rotateby);
858
 
859
                D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
860
                          list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
861
        } else {
862
                D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
863
        }
864
 
865
        x = count_list(&c->very_dirty_list);
866
        if (x) {
867
                rotateby = pseudo_random % x;
868
                D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
869
 
870
                rotate_list((&c->very_dirty_list), rotateby);
871
 
872
                D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
873
                          list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
874
        } else {
875
                D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
876
        }
877
 
878
        x = count_list(&c->dirty_list);
879
        if (x) {
880
                rotateby = pseudo_random % x;
881
                D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
882
 
883
                rotate_list((&c->dirty_list), rotateby);
884
 
885
                D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
886
                          list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
887
        } else {
888
                D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
889
        }
890
 
891
        x = count_list(&c->erasable_list);
892
        if (x) {
893
                rotateby = pseudo_random % x;
894
                D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
895
 
896
                rotate_list((&c->erasable_list), rotateby);
897
 
898
                D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
899
                          list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
900
        } else {
901
                D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
902
        }
903
 
904
        if (c->nr_erasing_blocks) {
905
                rotateby = pseudo_random % c->nr_erasing_blocks;
906
                D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
907
 
908
                rotate_list((&c->erase_pending_list), rotateby);
909
 
910
                D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
911
                          list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
912
        } else {
913
                D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
914
        }
915
 
916
        if (c->nr_free_blocks) {
917
                rotateby = pseudo_random % c->nr_free_blocks;
918
                D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
919
 
920
                rotate_list((&c->free_list), rotateby);
921
 
922
                D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
923
                          list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
924
        } else {
925
                D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
926
        }
927
}

powered by: WebSVN 2.1.0

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