diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 11:13:34 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 11:13:34 -0400 |
commit | 9641b784ff82cf0a48a6c70ef9867f5fd728de67 (patch) | |
tree | 40d7bbc06ee5e54560ea7e7dabe75ac01a72e00c /fs/jffs2/summary.c | |
parent | 6c8b44abc86a3e23dd1a22c0ee187f06bd7c7f5d (diff) |
[JFFS2] Optimise reading of eraseblock summary nodes
This improves the time to mount 512MiB of NAND flash on my OLPC prototype
by about 4%. We used to read the last page of the eraseblock twice -- once
to find the offset of the summary node, and again to actually _read_ the
summary node. Now we read the last page only once, and read more only if
we need to.
We also don't allocate a new buffer just for the summary code -- we use
the buffer which was already allocated for the scan. Better still, if the
'buffer' for the scan is actually just a pointer directly into NOR flash,
we use that too, avoiding the memcpy() which we used to do.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r-- | fs/jffs2/summary.c | 36 |
1 files changed, 6 insertions, 30 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 48293c197f13..82a3706c54d8 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -318,7 +318,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
318 | raw = jffs2_alloc_raw_node_ref(); | 318 | raw = jffs2_alloc_raw_node_ref(); |
319 | if (!raw) { | 319 | if (!raw) { |
320 | JFFS2_NOTICE("allocation of node reference failed\n"); | 320 | JFFS2_NOTICE("allocation of node reference failed\n"); |
321 | kfree(summary); | ||
322 | return -ENOMEM; | 321 | return -ENOMEM; |
323 | } | 322 | } |
324 | 323 | ||
@@ -326,7 +325,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
326 | if (!ic) { | 325 | if (!ic) { |
327 | JFFS2_NOTICE("scan_make_ino_cache failed\n"); | 326 | JFFS2_NOTICE("scan_make_ino_cache failed\n"); |
328 | jffs2_free_raw_node_ref(raw); | 327 | jffs2_free_raw_node_ref(raw); |
329 | kfree(summary); | ||
330 | return -ENOMEM; | 328 | return -ENOMEM; |
331 | } | 329 | } |
332 | 330 | ||
@@ -358,10 +356,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
358 | jeb->offset + je32_to_cpu(spd->offset)); | 356 | jeb->offset + je32_to_cpu(spd->offset)); |
359 | 357 | ||
360 | fd = jffs2_alloc_full_dirent(spd->nsize+1); | 358 | fd = jffs2_alloc_full_dirent(spd->nsize+1); |
361 | if (!fd) { | 359 | if (!fd) |
362 | kfree(summary); | ||
363 | return -ENOMEM; | 360 | return -ENOMEM; |
364 | } | ||
365 | 361 | ||
366 | memcpy(&fd->name, spd->name, spd->nsize); | 362 | memcpy(&fd->name, spd->name, spd->nsize); |
367 | fd->name[spd->nsize] = 0; | 363 | fd->name[spd->nsize] = 0; |
@@ -370,7 +366,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
370 | if (!raw) { | 366 | if (!raw) { |
371 | jffs2_free_full_dirent(fd); | 367 | jffs2_free_full_dirent(fd); |
372 | JFFS2_NOTICE("allocation of node reference failed\n"); | 368 | JFFS2_NOTICE("allocation of node reference failed\n"); |
373 | kfree(summary); | ||
374 | return -ENOMEM; | 369 | return -ENOMEM; |
375 | } | 370 | } |
376 | 371 | ||
@@ -378,7 +373,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
378 | if (!ic) { | 373 | if (!ic) { |
379 | jffs2_free_full_dirent(fd); | 374 | jffs2_free_full_dirent(fd); |
380 | jffs2_free_raw_node_ref(raw); | 375 | jffs2_free_raw_node_ref(raw); |
381 | kfree(summary); | ||
382 | return -ENOMEM; | 376 | return -ENOMEM; |
383 | } | 377 | } |
384 | 378 | ||
@@ -411,45 +405,28 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
411 | 405 | ||
412 | default : { | 406 | default : { |
413 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); | 407 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); |
414 | kfree(summary); | ||
415 | return -EIO; | 408 | return -EIO; |
416 | } | 409 | } |
417 | } | 410 | } |
418 | } | 411 | } |
419 | 412 | ||
420 | kfree(summary); | ||
421 | return 0; | 413 | return 0; |
422 | } | 414 | } |
423 | 415 | ||
424 | /* Process the summary node - called from jffs2_scan_eraseblock() */ | 416 | /* Process the summary node - called from jffs2_scan_eraseblock() */ |
425 | |||
426 | int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 417 | int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
427 | uint32_t ofs, uint32_t *pseudo_random) | 418 | struct jffs2_raw_summary *summary, uint32_t sumsize, |
419 | uint32_t *pseudo_random) | ||
428 | { | 420 | { |
429 | struct jffs2_unknown_node crcnode; | 421 | struct jffs2_unknown_node crcnode; |
430 | struct jffs2_raw_node_ref *cache_ref; | 422 | struct jffs2_raw_node_ref *cache_ref; |
431 | struct jffs2_raw_summary *summary; | 423 | int ret, ofs; |
432 | int ret, sumsize; | ||
433 | uint32_t crc; | 424 | uint32_t crc; |
434 | 425 | ||
435 | sumsize = c->sector_size - ofs; | 426 | ofs = jeb->offset + c->sector_size - sumsize; |
436 | ofs += jeb->offset; | ||
437 | 427 | ||
438 | dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", | 428 | dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", |
439 | jeb->offset, ofs, sumsize); | 429 | jeb->offset, ofs, sumsize); |
440 | |||
441 | summary = kmalloc(sumsize, GFP_KERNEL); | ||
442 | |||
443 | if (!summary) { | ||
444 | return -ENOMEM; | ||
445 | } | ||
446 | |||
447 | ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize); | ||
448 | |||
449 | if (ret) { | ||
450 | kfree(summary); | ||
451 | return ret; | ||
452 | } | ||
453 | 430 | ||
454 | /* OK, now check for node validity and CRC */ | 431 | /* OK, now check for node validity and CRC */ |
455 | crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); | 432 | crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); |
@@ -499,7 +476,6 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb | |||
499 | 476 | ||
500 | if (!marker_ref) { | 477 | if (!marker_ref) { |
501 | JFFS2_NOTICE("Failed to allocate node ref for clean marker\n"); | 478 | JFFS2_NOTICE("Failed to allocate node ref for clean marker\n"); |
502 | kfree(summary); | ||
503 | return -ENOMEM; | 479 | return -ENOMEM; |
504 | } | 480 | } |
505 | 481 | ||