Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39307a8e authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: use vmalloc to handle -ENOMEM error



This patch introduces f2fs_kvmalloc to avoid -ENOMEM during mount.

Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent ab126cfc
Loading
Loading
Loading
Loading
+21 −0
Original line number Original line Diff line number Diff line
@@ -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))
+16 −16
Original line number Original line Diff line number Diff line
@@ -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);