Commit 65e5a0e18e5fb5bc6cfabd8ef4b9fc1c8569ba62
Committed by
David Woodhouse
1 parent
b46daf7eb1
jffs2: Dynamically choose inocache hash size
When JFFS2 is used for large volumes, the mount times are quite long. Increasing the hash size provides a significant speed boost on the OLPC XO-1 laptop. Add logic that dynamically selects a hash size based on the size of the medium. A 64mb medium will result in a hash size of 128, and a 512mb medium will result in a hash size of 1024. Signed-off-by: Daniel Drake <dsd@laptop.org> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Showing 5 changed files with 29 additions and 7 deletions Side-by-side Diff
fs/jffs2/build.c
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | static inline struct jffs2_inode_cache * |
24 | 24 | first_inode_chain(int *i, struct jffs2_sb_info *c) |
25 | 25 | { |
26 | - for (; *i < INOCACHE_HASHSIZE; (*i)++) { | |
26 | + for (; *i < c->inocache_hashsize; (*i)++) { | |
27 | 27 | if (c->inocache_list[*i]) |
28 | 28 | return c->inocache_list[*i]; |
29 | 29 | } |
fs/jffs2/fs.c
... | ... | @@ -478,7 +478,26 @@ |
478 | 478 | return inode; |
479 | 479 | } |
480 | 480 | |
481 | +static int calculate_inocache_hashsize(uint32_t flash_size) | |
482 | +{ | |
483 | + /* | |
484 | + * Pick a inocache hash size based on the size of the medium. | |
485 | + * Count how many megabytes we're dealing with, apply a hashsize twice | |
486 | + * that size, but rounding down to the usual big powers of 2. And keep | |
487 | + * to sensible bounds. | |
488 | + */ | |
481 | 489 | |
490 | + int size_mb = flash_size / 1024 / 1024; | |
491 | + int hashsize = (size_mb * 2) & ~0x3f; | |
492 | + | |
493 | + if (hashsize < INOCACHE_HASHSIZE_MIN) | |
494 | + return INOCACHE_HASHSIZE_MIN; | |
495 | + if (hashsize > INOCACHE_HASHSIZE_MAX) | |
496 | + return INOCACHE_HASHSIZE_MAX; | |
497 | + | |
498 | + return hashsize; | |
499 | +} | |
500 | + | |
482 | 501 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) |
483 | 502 | { |
484 | 503 | struct jffs2_sb_info *c; |
... | ... | @@ -524,7 +543,8 @@ |
524 | 543 | if (ret) |
525 | 544 | return ret; |
526 | 545 | |
527 | - c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); | |
546 | + c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); | |
547 | + c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); | |
528 | 548 | if (!c->inocache_list) { |
529 | 549 | ret = -ENOMEM; |
530 | 550 | goto out_wbuf; |
fs/jffs2/jffs2_fs_sb.h
fs/jffs2/nodelist.c
... | ... | @@ -420,7 +420,7 @@ |
420 | 420 | { |
421 | 421 | struct jffs2_inode_cache *ret; |
422 | 422 | |
423 | - ret = c->inocache_list[ino % INOCACHE_HASHSIZE]; | |
423 | + ret = c->inocache_list[ino % c->inocache_hashsize]; | |
424 | 424 | while (ret && ret->ino < ino) { |
425 | 425 | ret = ret->next; |
426 | 426 | } |
... | ... | @@ -441,7 +441,7 @@ |
441 | 441 | |
442 | 442 | dbg_inocache("add %p (ino #%u)\n", new, new->ino); |
443 | 443 | |
444 | - prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; | |
444 | + prev = &c->inocache_list[new->ino % c->inocache_hashsize]; | |
445 | 445 | |
446 | 446 | while ((*prev) && (*prev)->ino < new->ino) { |
447 | 447 | prev = &(*prev)->next; |
... | ... | @@ -462,7 +462,7 @@ |
462 | 462 | dbg_inocache("del %p (ino #%u)\n", old, old->ino); |
463 | 463 | spin_lock(&c->inocache_lock); |
464 | 464 | |
465 | - prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; | |
465 | + prev = &c->inocache_list[old->ino % c->inocache_hashsize]; | |
466 | 466 | |
467 | 467 | while ((*prev) && (*prev)->ino < old->ino) { |
468 | 468 | prev = &(*prev)->next; |
... | ... | @@ -487,7 +487,7 @@ |
487 | 487 | int i; |
488 | 488 | struct jffs2_inode_cache *this, *next; |
489 | 489 | |
490 | - for (i=0; i<INOCACHE_HASHSIZE; i++) { | |
490 | + for (i=0; i < c->inocache_hashsize; i++) { | |
491 | 491 | this = c->inocache_list[i]; |
492 | 492 | while (this) { |
493 | 493 | next = this->next; |
fs/jffs2/nodelist.h
... | ... | @@ -199,7 +199,8 @@ |
199 | 199 | #define RAWNODE_CLASS_XATTR_DATUM 1 |
200 | 200 | #define RAWNODE_CLASS_XATTR_REF 2 |
201 | 201 | |
202 | -#define INOCACHE_HASHSIZE 128 | |
202 | +#define INOCACHE_HASHSIZE_MIN 128 | |
203 | +#define INOCACHE_HASHSIZE_MAX 1024 | |
203 | 204 | |
204 | 205 | #define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size) |
205 | 206 |