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