diff options
Diffstat (limited to 'fs/jffs2/fs.c')
-rw-r--r-- | fs/jffs2/fs.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index d9beb06e6fca..e896e67767eb 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -474,6 +474,25 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i | |||
474 | return inode; | 474 | return inode; |
475 | } | 475 | } |
476 | 476 | ||
477 | static int calculate_inocache_hashsize(uint32_t flash_size) | ||
478 | { | ||
479 | /* | ||
480 | * Pick a inocache hash size based on the size of the medium. | ||
481 | * Count how many megabytes we're dealing with, apply a hashsize twice | ||
482 | * that size, but rounding down to the usual big powers of 2. And keep | ||
483 | * to sensible bounds. | ||
484 | */ | ||
485 | |||
486 | int size_mb = flash_size / 1024 / 1024; | ||
487 | int hashsize = (size_mb * 2) & ~0x3f; | ||
488 | |||
489 | if (hashsize < INOCACHE_HASHSIZE_MIN) | ||
490 | return INOCACHE_HASHSIZE_MIN; | ||
491 | if (hashsize > INOCACHE_HASHSIZE_MAX) | ||
492 | return INOCACHE_HASHSIZE_MAX; | ||
493 | |||
494 | return hashsize; | ||
495 | } | ||
477 | 496 | ||
478 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | 497 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) |
479 | { | 498 | { |
@@ -520,7 +539,8 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
520 | if (ret) | 539 | if (ret) |
521 | return ret; | 540 | return ret; |
522 | 541 | ||
523 | c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); | 542 | c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); |
543 | c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); | ||
524 | if (!c->inocache_list) { | 544 | if (!c->inocache_list) { |
525 | ret = -ENOMEM; | 545 | ret = -ENOMEM; |
526 | goto out_wbuf; | 546 | goto out_wbuf; |