1
0
Fork 0

f2fs: use vmalloc to handle -ENOMEM error

This patch introduces f2fs_kvmalloc to avoid -ENOMEM during mount.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
hifive-unleashed-5.1
Jaegeuk Kim 2015-09-22 13:50:47 -07:00
parent ab126cfc30
commit 39307a8e24
2 changed files with 37 additions and 16 deletions

View File

@ -19,6 +19,7 @@
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/vmalloc.h>
#include <linux/bio.h> #include <linux/bio.h>
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
@ -1586,6 +1587,26 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
return S_ISREG(mode); return S_ISREG(mode);
} }
static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
{
void *ret;
ret = kmalloc(size, flags | __GFP_NOWARN);
if (!ret)
ret = __vmalloc(size, flags, PAGE_KERNEL);
return ret;
}
static inline void *f2fs_kvzalloc(size_t size, gfp_t flags)
{
void *ret;
ret = kzalloc(size, flags | __GFP_NOWARN);
if (!ret)
ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
return ret;
}
#define get_inode_mode(i) \ #define get_inode_mode(i) \
((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
(F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))

View File

@ -14,7 +14,6 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/prefetch.h> #include <linux/prefetch.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/swap.h> #include <linux/swap.h>
#include "f2fs.h" #include "f2fs.h"
@ -1955,12 +1954,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
SM_I(sbi)->sit_info = sit_i; SM_I(sbi)->sit_info = sit_i;
sit_i->sentries = vzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry)); sit_i->sentries = f2fs_kvzalloc(MAIN_SEGS(sbi) *
sizeof(struct seg_entry), GFP_KERNEL);
if (!sit_i->sentries) if (!sit_i->sentries)
return -ENOMEM; return -ENOMEM;
bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
sit_i->dirty_sentries_bitmap = kzalloc(bitmap_size, GFP_KERNEL); sit_i->dirty_sentries_bitmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
if (!sit_i->dirty_sentries_bitmap) if (!sit_i->dirty_sentries_bitmap)
return -ENOMEM; return -ENOMEM;
@ -1982,8 +1982,8 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
return -ENOMEM; return -ENOMEM;
if (sbi->segs_per_sec > 1) { if (sbi->segs_per_sec > 1) {
sit_i->sec_entries = vzalloc(MAIN_SECS(sbi) * sit_i->sec_entries = f2fs_kvzalloc(MAIN_SECS(sbi) *
sizeof(struct sec_entry)); sizeof(struct sec_entry), GFP_KERNEL);
if (!sit_i->sec_entries) if (!sit_i->sec_entries)
return -ENOMEM; return -ENOMEM;
} }
@ -2028,12 +2028,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi)
SM_I(sbi)->free_info = free_i; SM_I(sbi)->free_info = free_i;
bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
free_i->free_segmap = kmalloc(bitmap_size, GFP_KERNEL); free_i->free_segmap = f2fs_kvmalloc(bitmap_size, GFP_KERNEL);
if (!free_i->free_segmap) if (!free_i->free_segmap)
return -ENOMEM; return -ENOMEM;
sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
free_i->free_secmap = kmalloc(sec_bitmap_size, GFP_KERNEL); free_i->free_secmap = f2fs_kvmalloc(sec_bitmap_size, GFP_KERNEL);
if (!free_i->free_secmap) if (!free_i->free_secmap)
return -ENOMEM; return -ENOMEM;
@ -2174,7 +2174,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
dirty_i->victim_secmap = kzalloc(bitmap_size, GFP_KERNEL); dirty_i->victim_secmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
if (!dirty_i->victim_secmap) if (!dirty_i->victim_secmap)
return -ENOMEM; return -ENOMEM;
return 0; return 0;
@ -2196,7 +2196,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi)
bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
for (i = 0; i < NR_DIRTY_TYPE; i++) { for (i = 0; i < NR_DIRTY_TYPE; i++) {
dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL); dirty_i->dirty_segmap[i] = f2fs_kvzalloc(bitmap_size, GFP_KERNEL);
if (!dirty_i->dirty_segmap[i]) if (!dirty_i->dirty_segmap[i])
return -ENOMEM; return -ENOMEM;
} }
@ -2301,7 +2301,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
mutex_lock(&dirty_i->seglist_lock); mutex_lock(&dirty_i->seglist_lock);
kfree(dirty_i->dirty_segmap[dirty_type]); kvfree(dirty_i->dirty_segmap[dirty_type]);
dirty_i->nr_dirty[dirty_type] = 0; dirty_i->nr_dirty[dirty_type] = 0;
mutex_unlock(&dirty_i->seglist_lock); mutex_unlock(&dirty_i->seglist_lock);
} }
@ -2309,7 +2309,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
static void destroy_victim_secmap(struct f2fs_sb_info *sbi) static void destroy_victim_secmap(struct f2fs_sb_info *sbi)
{ {
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
kfree(dirty_i->victim_secmap); kvfree(dirty_i->victim_secmap);
} }
static void destroy_dirty_segmap(struct f2fs_sb_info *sbi) static void destroy_dirty_segmap(struct f2fs_sb_info *sbi)
@ -2348,8 +2348,8 @@ static void destroy_free_segmap(struct f2fs_sb_info *sbi)
if (!free_i) if (!free_i)
return; return;
SM_I(sbi)->free_info = NULL; SM_I(sbi)->free_info = NULL;
kfree(free_i->free_segmap); kvfree(free_i->free_segmap);
kfree(free_i->free_secmap); kvfree(free_i->free_secmap);
kfree(free_i); kfree(free_i);
} }
@ -2370,9 +2370,9 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi)
} }
kfree(sit_i->tmp_map); kfree(sit_i->tmp_map);
vfree(sit_i->sentries); kvfree(sit_i->sentries);
vfree(sit_i->sec_entries); kvfree(sit_i->sec_entries);
kfree(sit_i->dirty_sentries_bitmap); kvfree(sit_i->dirty_sentries_bitmap);
SM_I(sbi)->sit_info = NULL; SM_I(sbi)->sit_info = NULL;
kfree(sit_i->sit_bitmap); kfree(sit_i->sit_bitmap);