aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2011-08-01 08:45:02 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-08-01 08:45:02 -0400
commit9933fc0ac1ac14b795819cd63d05ea92112f690a (patch)
treebff42e3494fd5401e6b171ddae8f52ecd1defd91 /fs/ext4
parent33853a0dde359ded0534204eb6857ad5166d515b (diff)
ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and ext4_kvfree()
Introduce new helper functions which try kmalloc, and then fall back to vmalloc if necessary, and use them for allocating and deallocating s_flex_groups. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/super.c54
2 files changed, 39 insertions, 18 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ba2009b49a55..db9feadf53a0 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1874,6 +1874,9 @@ extern int ext4_group_extend(struct super_block *sb,
1874 ext4_fsblk_t n_blocks_count); 1874 ext4_fsblk_t n_blocks_count);
1875 1875
1876/* super.c */ 1876/* super.c */
1877extern void *ext4_kvmalloc(size_t size, gfp_t flags);
1878extern void *ext4_kvzalloc(size_t size, gfp_t flags);
1879extern void ext4_kvfree(void *ptr);
1877extern void __ext4_error(struct super_block *, const char *, unsigned int, 1880extern void __ext4_error(struct super_block *, const char *, unsigned int,
1878 const char *, ...) 1881 const char *, ...)
1879 __attribute__ ((format (printf, 4, 5))); 1882 __attribute__ ((format (printf, 4, 5)));
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index cfe9f39c4ba2..658f5864e9cf 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -110,6 +110,35 @@ static struct file_system_type ext3_fs_type = {
110#define IS_EXT3_SB(sb) (0) 110#define IS_EXT3_SB(sb) (0)
111#endif 111#endif
112 112
113void *ext4_kvmalloc(size_t size, gfp_t flags)
114{
115 void *ret;
116
117 ret = kmalloc(size, flags);
118 if (!ret)
119 ret = __vmalloc(size, flags, PAGE_KERNEL);
120 return ret;
121}
122
123void *ext4_kvzalloc(size_t size, gfp_t flags)
124{
125 void *ret;
126
127 ret = kmalloc(size, flags);
128 if (!ret)
129 ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
130 return ret;
131}
132
133void ext4_kvfree(void *ptr)
134{
135 if (is_vmalloc_addr(ptr))
136 vfree(ptr);
137 else
138 kfree(ptr);
139
140}
141
113ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, 142ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
114 struct ext4_group_desc *bg) 143 struct ext4_group_desc *bg)
115{ 144{
@@ -791,10 +820,7 @@ static void ext4_put_super(struct super_block *sb)
791 for (i = 0; i < sbi->s_gdb_count; i++) 820 for (i = 0; i < sbi->s_gdb_count; i++)
792 brelse(sbi->s_group_desc[i]); 821 brelse(sbi->s_group_desc[i]);
793 kfree(sbi->s_group_desc); 822 kfree(sbi->s_group_desc);
794 if (is_vmalloc_addr(sbi->s_flex_groups)) 823 ext4_kvfree(sbi->s_flex_groups);
795 vfree(sbi->s_flex_groups);
796 else
797 kfree(sbi->s_flex_groups);
798 percpu_counter_destroy(&sbi->s_freeblocks_counter); 824 percpu_counter_destroy(&sbi->s_freeblocks_counter);
799 percpu_counter_destroy(&sbi->s_freeinodes_counter); 825 percpu_counter_destroy(&sbi->s_freeinodes_counter);
800 percpu_counter_destroy(&sbi->s_dirs_counter); 826 percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -1977,15 +2003,11 @@ static int ext4_fill_flex_info(struct super_block *sb)
1977 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << 2003 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
1978 EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; 2004 EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
1979 size = flex_group_count * sizeof(struct flex_groups); 2005 size = flex_group_count * sizeof(struct flex_groups);
1980 sbi->s_flex_groups = kzalloc(size, GFP_KERNEL); 2006 sbi->s_flex_groups = ext4_kvzalloc(size, GFP_KERNEL);
1981 if (sbi->s_flex_groups == NULL) { 2007 if (sbi->s_flex_groups == NULL) {
1982 sbi->s_flex_groups = vzalloc(size); 2008 ext4_msg(sb, KERN_ERR, "not enough memory for %u flex groups",
1983 if (sbi->s_flex_groups == NULL) { 2009 flex_group_count);
1984 ext4_msg(sb, KERN_ERR, 2010 goto failed;
1985 "not enough memory for %u flex groups",
1986 flex_group_count);
1987 goto failed;
1988 }
1989 } 2011 }
1990 2012
1991 for (i = 0; i < sbi->s_groups_count; i++) { 2013 for (i = 0; i < sbi->s_groups_count; i++) {
@@ -3750,12 +3772,8 @@ failed_mount_wq:
3750 } 3772 }
3751failed_mount3: 3773failed_mount3:
3752 del_timer(&sbi->s_err_report); 3774 del_timer(&sbi->s_err_report);
3753 if (sbi->s_flex_groups) { 3775 if (sbi->s_flex_groups)
3754 if (is_vmalloc_addr(sbi->s_flex_groups)) 3776 ext4_kvfree(sbi->s_flex_groups);
3755 vfree(sbi->s_flex_groups);
3756 else
3757 kfree(sbi->s_flex_groups);
3758 }
3759 percpu_counter_destroy(&sbi->s_freeblocks_counter); 3777 percpu_counter_destroy(&sbi->s_freeblocks_counter);
3760 percpu_counter_destroy(&sbi->s_freeinodes_counter); 3778 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3761 percpu_counter_destroy(&sbi->s_dirs_counter); 3779 percpu_counter_destroy(&sbi->s_dirs_counter);