aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/scan.c
diff options
context:
space:
mode:
authorFerenc Havasi <havasi@inf.u-szeged.hu>2005-09-07 04:35:26 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:29:48 -0500
commite631ddba588783edd521c5a89f7b2902772fb691 (patch)
treee25f322ee498b344f058ce4a40060baa22a5f105 /fs/jffs2/scan.c
parent15017876751e4c2d786ba95920618359fe2b4f0a (diff)
[JFFS2] Add erase block summary support (mount time improvement)
The goal of summary is to speed up the mount time. Erase block summary (EBS) stores summary information at the end of every (closed) erase block. It is no longer necessary to scan all nodes separetly (and read all pages of them) just read this "small" summary, where every information is stored which is needed at mount time. This summary information is stored in a JFFS2_FEATURE_RWCOMPAT_DELETE. During the mount process if there is no summary info the orignal scan process will be executed. EBS works with NAND and NOR flashes, too. There is a user space tool called sumtool to generate this summary information for a JFFS2 image. Signed-off-by: Ferenc Havasi <havasi@inf.u-szeged.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r--fs/jffs2/scan.c198
1 files changed, 133 insertions, 65 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index fcd6314cf179..4e60ba8da197 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: scan.c,v 1.121 2005/07/20 15:32:28 dedekind Exp $ 10 * $Id: scan.c,v 1.122 2005/09/07 08:34:54 havasi Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -18,22 +18,11 @@
18#include <linux/crc32.h> 18#include <linux/crc32.h>
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21#include "summary.h"
22#include "debug.h"
21 23
22#define DEFAULT_EMPTY_SCAN_SIZE 1024 24#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 25
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 { \ 26#define noisy_printk(noise, args...) do { \
38 if (*(noise)) { \ 27 if (*(noise)) { \
39 printk(KERN_NOTICE args); \ 28 printk(KERN_NOTICE args); \
@@ -47,23 +36,16 @@
47static uint32_t pseudo_random; 36static uint32_t pseudo_random;
48 37
49static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 38static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
50 unsigned char *buf, uint32_t buf_size); 39 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s);
51 40
52/* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 41/* 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 42 * Returning an error will abort the mount - bad checksums etc. should just mark the space
54 * as dirty. 43 * as dirty.
55 */ 44 */
56static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 45static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
57 struct jffs2_raw_inode *ri, uint32_t ofs); 46 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s);
58static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 47static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
59 struct jffs2_raw_dirent *rd, uint32_t ofs); 48 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s);
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 49
68static inline int min_free(struct jffs2_sb_info *c) 50static inline int min_free(struct jffs2_sb_info *c)
69{ 51{
@@ -89,6 +71,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
89 uint32_t empty_blocks = 0, bad_blocks = 0; 71 uint32_t empty_blocks = 0, bad_blocks = 0;
90 unsigned char *flashbuf = NULL; 72 unsigned char *flashbuf = NULL;
91 uint32_t buf_size = 0; 73 uint32_t buf_size = 0;
74 struct jffs2_summary *s = NULL; /* summary info collected by the scan process */
92#ifndef __ECOS 75#ifndef __ECOS
93 size_t pointlen; 76 size_t pointlen;
94 77
@@ -122,10 +105,23 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
122 return -ENOMEM; 105 return -ENOMEM;
123 } 106 }
124 107
108 if (jffs2_sum_active()) {
109 s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
110 if (!s) {
111 JFFS2_WARNING("Can't allocate memory for summary\n");
112 return -ENOMEM;
113 }
114 memset(s, 0, sizeof(struct jffs2_summary));
115 }
116
125 for (i=0; i<c->nr_blocks; i++) { 117 for (i=0; i<c->nr_blocks; i++) {
126 struct jffs2_eraseblock *jeb = &c->blocks[i]; 118 struct jffs2_eraseblock *jeb = &c->blocks[i];
127 119
128 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size); 120 /* reset summary info for next eraseblock scan */
121 jffs2_sum_reset_collected(s);
122
123 ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
124 buf_size, s);
129 125
130 if (ret < 0) 126 if (ret < 0)
131 goto out; 127 goto out;
@@ -162,18 +158,18 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
162 break; 158 break;
163 159
164 case BLK_STATE_CLEAN: 160 case BLK_STATE_CLEAN:
165 /* Full (or almost full) of clean data. Clean list */ 161 /* Full (or almost full) of clean data. Clean list */
166 list_add(&jeb->list, &c->clean_list); 162 list_add(&jeb->list, &c->clean_list);
167 break; 163 break;
168 164
169 case BLK_STATE_PARTDIRTY: 165 case BLK_STATE_PARTDIRTY:
170 /* Some data, but not full. Dirty list. */ 166 /* Some data, but not full. Dirty list. */
171 /* We want to remember the block with most free space 167 /* We want to remember the block with most free space
172 and stick it in the 'nextblock' position to start writing to it. */ 168 and stick it in the 'nextblock' position to start writing to it. */
173 if (jeb->free_size > min_free(c) && 169 if (jeb->free_size > min_free(c) &&
174 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { 170 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
175 /* Better candidate for the next writes to go to */ 171 /* Better candidate for the next writes to go to */
176 if (c->nextblock) { 172 if (c->nextblock) {
177 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 173 c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
178 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; 174 c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
179 c->free_size -= c->nextblock->free_size; 175 c->free_size -= c->nextblock->free_size;
@@ -184,9 +180,14 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
184 } else { 180 } else {
185 list_add(&c->nextblock->list, &c->dirty_list); 181 list_add(&c->nextblock->list, &c->dirty_list);
186 } 182 }
183 /* deleting summary information of the old nextblock */
184 jffs2_sum_reset_collected(c->summary);
187 } 185 }
188 c->nextblock = jeb; 186 /* update collected summary infromation for the current nextblock */
189 } else { 187 jffs2_sum_move_collected(c, s);
188 D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));
189 c->nextblock = jeb;
190 } else {
190 jeb->dirty_size += jeb->free_size + jeb->wasted_size; 191 jeb->dirty_size += jeb->free_size + jeb->wasted_size;
191 c->dirty_size += jeb->free_size + jeb->wasted_size; 192 c->dirty_size += jeb->free_size + jeb->wasted_size;
192 c->free_size -= jeb->free_size; 193 c->free_size -= jeb->free_size;
@@ -197,30 +198,33 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
197 } else { 198 } else {
198 list_add(&jeb->list, &c->dirty_list); 199 list_add(&jeb->list, &c->dirty_list);
199 } 200 }
200 } 201 }
201 break; 202 break;
202 203
203 case BLK_STATE_ALLDIRTY: 204 case BLK_STATE_ALLDIRTY:
204 /* Nothing valid - not even a clean marker. Needs erasing. */ 205 /* 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 /* 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 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 list_add(&jeb->list, &c->erase_pending_list);
208 c->nr_erasing_blocks++; 209 c->nr_erasing_blocks++;
209 break; 210 break;
210 211
211 case BLK_STATE_BADBLOCK: 212 case BLK_STATE_BADBLOCK:
212 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); 213 D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
213 list_add(&jeb->list, &c->bad_list); 214 list_add(&jeb->list, &c->bad_list);
214 c->bad_size += c->sector_size; 215 c->bad_size += c->sector_size;
215 c->free_size -= c->sector_size; 216 c->free_size -= c->sector_size;
216 bad_blocks++; 217 bad_blocks++;
217 break; 218 break;
218 default: 219 default:
219 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); 220 printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
220 BUG(); 221 BUG();
221 } 222 }
222 } 223 }
223 224
225 if (jffs2_sum_active() && s)
226 kfree(s);
227
224 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ 228 /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
225 if (c->nextblock && (c->nextblock->dirty_size)) { 229 if (c->nextblock && (c->nextblock->dirty_size)) {
226 c->nextblock->wasted_size += c->nextblock->dirty_size; 230 c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -265,7 +269,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
265 return ret; 269 return ret;
266} 270}
267 271
268static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, 272int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
269 uint32_t ofs, uint32_t len) 273 uint32_t ofs, uint32_t len)
270{ 274{
271 int ret; 275 int ret;
@@ -286,14 +290,36 @@ static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
286 return 0; 290 return 0;
287} 291}
288 292
293int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
294{
295 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
296 && (!jeb->first_node || !jeb->first_node->next_phys) )
297 return BLK_STATE_CLEANMARKER;
298
299 /* move blocks with max 4 byte dirty space to cleanlist */
300 else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
301 c->dirty_size -= jeb->dirty_size;
302 c->wasted_size += jeb->dirty_size;
303 jeb->wasted_size += jeb->dirty_size;
304 jeb->dirty_size = 0;
305 return BLK_STATE_CLEAN;
306 } else if (jeb->used_size || jeb->unchecked_size)
307 return BLK_STATE_PARTDIRTY;
308 else
309 return BLK_STATE_ALLDIRTY;
310}
311
289static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 312static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
290 unsigned char *buf, uint32_t buf_size) { 313 unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
291 struct jffs2_unknown_node *node; 314 struct jffs2_unknown_node *node;
292 struct jffs2_unknown_node crcnode; 315 struct jffs2_unknown_node crcnode;
316 struct jffs2_sum_marker *sm;
293 uint32_t ofs, prevofs; 317 uint32_t ofs, prevofs;
294 uint32_t hdr_crc, buf_ofs, buf_len; 318 uint32_t hdr_crc, buf_ofs, buf_len;
295 int err; 319 int err;
296 int noise = 0; 320 int noise = 0;
321
322
297#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 323#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
298 int cleanmarkerfound = 0; 324 int cleanmarkerfound = 0;
299#endif 325#endif
@@ -319,10 +345,46 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
319 } 345 }
320 } 346 }
321#endif 347#endif
348
349 if (jffs2_sum_active()) {
350 sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL);
351 if (!sm) {
352 return -ENOMEM;
353 }
354
355 err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
356 sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
357 if (err) {
358 kfree(sm);
359 return err;
360 }
361
362 if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) {
363 err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random);
364 if (err) {
365 kfree(sm);
366 return err;
367 }
368 }
369
370 kfree(sm);
371
372 ofs = jeb->offset;
373 prevofs = jeb->offset - 1;
374 }
375
322 buf_ofs = jeb->offset; 376 buf_ofs = jeb->offset;
323 377
324 if (!buf_size) { 378 if (!buf_size) {
325 buf_len = c->sector_size; 379 buf_len = c->sector_size;
380
381 if (jffs2_sum_active()) {
382 /* must reread because of summary test */
383 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
384 if (err)
385 return err;
386 }
387
326 } else { 388 } else {
327 buf_len = EMPTY_SCAN_SIZE(c->sector_size); 389 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 390 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
@@ -367,6 +429,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
367 429
368 noise = 10; 430 noise = 10;
369 431
432 JFFS2_DBG_SUMMARY("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
433
370scan_more: 434scan_more:
371 while(ofs < jeb->offset + c->sector_size) { 435 while(ofs < jeb->offset + c->sector_size) {
372 436
@@ -532,7 +596,7 @@ scan_more:
532 buf_ofs = ofs; 596 buf_ofs = ofs;
533 node = (void *)buf; 597 node = (void *)buf;
534 } 598 }
535 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); 599 err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s);
536 if (err) return err; 600 if (err) return err;
537 ofs += PAD(je32_to_cpu(node->totlen)); 601 ofs += PAD(je32_to_cpu(node->totlen));
538 break; 602 break;
@@ -548,7 +612,7 @@ scan_more:
548 buf_ofs = ofs; 612 buf_ofs = ofs;
549 node = (void *)buf; 613 node = (void *)buf;
550 } 614 }
551 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); 615 err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s);
552 if (err) return err; 616 if (err) return err;
553 ofs += PAD(je32_to_cpu(node->totlen)); 617 ofs += PAD(je32_to_cpu(node->totlen));
554 break; 618 break;
@@ -582,6 +646,8 @@ scan_more:
582 break; 646 break;
583 647
584 case JFFS2_NODETYPE_PADDING: 648 case JFFS2_NODETYPE_PADDING:
649 if (jffs2_sum_active())
650 jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));
585 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); 651 DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
586 ofs += PAD(je32_to_cpu(node->totlen)); 652 ofs += PAD(je32_to_cpu(node->totlen));
587 break; 653 break;
@@ -616,6 +682,13 @@ scan_more:
616 } 682 }
617 } 683 }
618 684
685 if (jffs2_sum_active()) {
686 if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) {
687 JFFS2_DBG_SUMMARY("There is not enough space for "
688 "summary information, disabling for this jeb!\n");
689 jffs2_sum_disable_collecting(s);
690 }
691 }
619 692
620 D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, 693 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)); 694 jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
@@ -628,24 +701,10 @@ scan_more:
628 jeb->wasted_size = 0; 701 jeb->wasted_size = 0;
629 } 702 }
630 703
631 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 704 return jffs2_scan_classify_jeb(c, jeb);
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} 705}
647 706
648static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) 707struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
649{ 708{
650 struct jffs2_inode_cache *ic; 709 struct jffs2_inode_cache *ic;
651 710
@@ -672,7 +731,7 @@ static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info
672} 731}
673 732
674static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 733static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
675 struct jffs2_raw_inode *ri, uint32_t ofs) 734 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
676{ 735{
677 struct jffs2_raw_node_ref *raw; 736 struct jffs2_raw_node_ref *raw;
678 struct jffs2_inode_cache *ic; 737 struct jffs2_inode_cache *ic;
@@ -739,11 +798,16 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
739 pseudo_random += je32_to_cpu(ri->version); 798 pseudo_random += je32_to_cpu(ri->version);
740 799
741 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen))); 800 UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
801
802 if (jffs2_sum_active()) {
803 jffs2_sum_add_inode_mem(s, ri, ofs - jeb->offset);
804 }
805
742 return 0; 806 return 0;
743} 807}
744 808
745static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 809static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
746 struct jffs2_raw_dirent *rd, uint32_t ofs) 810 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
747{ 811{
748 struct jffs2_raw_node_ref *raw; 812 struct jffs2_raw_node_ref *raw;
749 struct jffs2_full_dirent *fd; 813 struct jffs2_full_dirent *fd;
@@ -817,6 +881,10 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
817 USED_SPACE(PAD(je32_to_cpu(rd->totlen))); 881 USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
818 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 882 jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
819 883
884 if (jffs2_sum_active()) {
885 jffs2_sum_add_dirent_mem(s, rd, ofs - jeb->offset);
886 }
887
820 return 0; 888 return 0;
821} 889}
822 890