linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/11] f2fs: introduce macros for proc entries
@ 2016-05-03 18:21 Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 02/11] f2fs: add proc entry to show valid block bitmap Jaegeuk Kim
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This adds macros to be used multiple proc entries.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/super.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 19a85cf..b006de6 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -745,19 +745,22 @@ static int segment_info_seq_show(struct seq_file *seq, void *offset)
 	return 0;
 }
 
-static int segment_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, segment_info_seq_show, PDE_DATA(inode));
-}
-
-static const struct file_operations f2fs_seq_segment_info_fops = {
-	.owner = THIS_MODULE,
-	.open = segment_info_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
+#define F2FS_PROC_FILE_DEF(_name)					\
+static int _name##_open_fs(struct inode *inode, struct file *file)	\
+{									\
+	return single_open(file, _name##_seq_show, PDE_DATA(inode));	\
+}									\
+									\
+static const struct file_operations f2fs_seq_##_name##_fops = {		\
+	.owner = THIS_MODULE,						\
+	.open = _name##_open_fs,					\
+	.read = seq_read,						\
+	.llseek = seq_lseek,						\
+	.release = single_release,					\
 };
 
+F2FS_PROC_FILE_DEF(segment_info);
+
 static void default_options(struct f2fs_sb_info *sbi)
 {
 	/* init some FS parameters */
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/11] f2fs: add proc entry to show valid block bitmap
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 03/11] f2fs: introduce f2fs_kmalloc to wrap kmalloc Jaegeuk Kim
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds a new proc entry to show segment information in more detail.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/super.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b006de6..90d4b86 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -539,6 +539,7 @@ static void f2fs_put_super(struct super_block *sb)
 
 	if (sbi->s_proc) {
 		remove_proc_entry("segment_info", sbi->s_proc);
+		remove_proc_entry("segment_bits", sbi->s_proc);
 		remove_proc_entry(sb->s_id, f2fs_proc_root);
 	}
 	kobject_del(&sbi->s_kobj);
@@ -745,6 +746,30 @@ static int segment_info_seq_show(struct seq_file *seq, void *offset)
 	return 0;
 }
 
+static int segment_bits_seq_show(struct seq_file *seq, void *offset)
+{
+	struct super_block *sb = seq->private;
+	struct f2fs_sb_info *sbi = F2FS_SB(sb);
+	unsigned int total_segs =
+			le32_to_cpu(sbi->raw_super->segment_count_main);
+	int i, j;
+
+	seq_puts(seq, "format: segment_type|valid_blocks|bitmaps\n"
+		"segment_type(0:HD, 1:WD, 2:CD, 3:HN, 4:WN, 5:CN)\n");
+
+	for (i = 0; i < total_segs; i++) {
+		struct seg_entry *se = get_seg_entry(sbi, i);
+
+		seq_printf(seq, "%-10d", i);
+		seq_printf(seq, "%d|%-3u|", se->type,
+					get_valid_blocks(sbi, i, 1));
+		for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++)
+			seq_printf(seq, "%x ", se->cur_valid_map[j]);
+		seq_putc(seq, '\n');
+	}
+	return 0;
+}
+
 #define F2FS_PROC_FILE_DEF(_name)					\
 static int _name##_open_fs(struct inode *inode, struct file *file)	\
 {									\
@@ -760,6 +785,7 @@ static const struct file_operations f2fs_seq_##_name##_fops = {		\
 };
 
 F2FS_PROC_FILE_DEF(segment_info);
+F2FS_PROC_FILE_DEF(segment_bits);
 
 static void default_options(struct f2fs_sb_info *sbi)
 {
@@ -1541,9 +1567,12 @@ try_onemore:
 	if (f2fs_proc_root)
 		sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
 
-	if (sbi->s_proc)
+	if (sbi->s_proc) {
 		proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
 				 &f2fs_seq_segment_info_fops, sb);
+		proc_create_data("segment_bits", S_IRUGO, sbi->s_proc,
+				 &f2fs_seq_segment_bits_fops, sb);
+	}
 
 	sbi->s_kobj.kset = f2fs_kset;
 	init_completion(&sbi->s_kobj_unregister);
@@ -1619,6 +1648,7 @@ free_kobj:
 free_proc:
 	if (sbi->s_proc) {
 		remove_proc_entry("segment_info", sbi->s_proc);
+		remove_proc_entry("segment_bits", sbi->s_proc);
 		remove_proc_entry(sb->s_id, f2fs_proc_root);
 	}
 	f2fs_destroy_stats(sbi);
-- 
2.6.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/11] f2fs: introduce f2fs_kmalloc to wrap kmalloc
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 02/11] f2fs: add proc entry to show valid block bitmap Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 04/11] f2fs: use f2fs_grab_cache_page instead of grab_cache_page Jaegeuk Kim
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds f2fs_kmalloc.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/acl.c    | 4 ++--
 fs/f2fs/dir.c    | 2 +-
 fs/f2fs/f2fs.h   | 5 +++++
 fs/f2fs/gc.c     | 2 +-
 fs/f2fs/inline.c | 2 +-
 5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index c8f25f7..d757d79 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -115,7 +115,7 @@ static void *f2fs_acl_to_disk(const struct posix_acl *acl, size_t *size)
 	struct f2fs_acl_entry *entry;
 	int i;
 
-	f2fs_acl = kmalloc(sizeof(struct f2fs_acl_header) + acl->a_count *
+	f2fs_acl = f2fs_kmalloc(sizeof(struct f2fs_acl_header) + acl->a_count *
 			sizeof(struct f2fs_acl_entry), GFP_NOFS);
 	if (!f2fs_acl)
 		return ERR_PTR(-ENOMEM);
@@ -175,7 +175,7 @@ static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type,
 
 	retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage);
 	if (retval > 0) {
-		value = kmalloc(retval, GFP_F2FS_ZERO);
+		value = f2fs_kmalloc(retval, GFP_F2FS_ZERO);
 		if (!value)
 			return ERR_PTR(-ENOMEM);
 		retval = f2fs_getxattr(inode, name_index, "", value,
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index dbfc1d1..6bd0595 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -805,7 +805,7 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
 			int save_len = fstr->len;
 			int ret;
 
-			de_name.name = kmalloc(de_name.len, GFP_NOFS);
+			de_name.name = f2fs_kmalloc(de_name.len, GFP_NOFS);
 			if (!de_name.name)
 				return false;
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 38aa75c..364d5fd 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1643,6 +1643,11 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
 	return S_ISREG(inode->i_mode);
 }
 
+static inline void *f2fs_kmalloc(size_t size, gfp_t flags)
+{
+	return kmalloc(size, flags);
+}
+
 static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
 {
 	void *ret;
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 19e9faf..38d56f6 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -96,7 +96,7 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
 	dev_t dev = sbi->sb->s_bdev->bd_dev;
 	int err = 0;
 
-	gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
+	gc_th = f2fs_kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
 	if (!gc_th) {
 		err = -ENOMEM;
 		goto out;
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index e61084c..33830b2 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -465,7 +465,7 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
 	struct f2fs_inline_dentry *backup_dentry;
 	int err;
 
-	backup_dentry = kmalloc(sizeof(struct f2fs_inline_dentry),
+	backup_dentry = f2fs_kmalloc(sizeof(struct f2fs_inline_dentry),
 							GFP_F2FS_ZERO);
 	if (!backup_dentry)
 		return -ENOMEM;
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/11] f2fs: use f2fs_grab_cache_page instead of grab_cache_page
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 02/11] f2fs: add proc entry to show valid block bitmap Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 03/11] f2fs: introduce f2fs_kmalloc to wrap kmalloc Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 05/11] f2fs: add mount option to select fault injection ratio Jaegeuk Kim
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch converts grab_cache_page to f2fs_grab_cache_page.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c | 7 ++++---
 fs/f2fs/inline.c     | 4 ++--
 fs/f2fs/node.c       | 8 ++++----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index dc7bc72..ac87cd9 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -34,7 +34,7 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
 	struct address_space *mapping = META_MAPPING(sbi);
 	struct page *page = NULL;
 repeat:
-	page = grab_cache_page(mapping, index);
+	page = f2fs_grab_cache_page(mapping, index, false);
 	if (!page) {
 		cond_resched();
 		goto repeat;
@@ -64,7 +64,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
 	if (unlikely(!is_meta))
 		fio.rw &= ~REQ_META;
 repeat:
-	page = grab_cache_page(mapping, index);
+	page = f2fs_grab_cache_page(mapping, index, false);
 	if (!page) {
 		cond_resched();
 		goto repeat;
@@ -186,7 +186,8 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
 			BUG();
 		}
 
-		page = grab_cache_page(META_MAPPING(sbi), fio.new_blkaddr);
+		page = f2fs_grab_cache_page(META_MAPPING(sbi),
+						fio.new_blkaddr, false);
 		if (!page)
 			continue;
 		if (PageUptodate(page)) {
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 33830b2..8a51955 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -161,7 +161,7 @@ int f2fs_convert_inline_inode(struct inode *inode)
 	if (!f2fs_has_inline_data(inode))
 		return 0;
 
-	page = grab_cache_page(inode->i_mapping, 0);
+	page = f2fs_grab_cache_page(inode->i_mapping, 0, false);
 	if (!page)
 		return -ENOMEM;
 
@@ -358,7 +358,7 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
 	struct f2fs_dentry_block *dentry_blk;
 	int err;
 
-	page = grab_cache_page(dir->i_mapping, 0);
+	page = f2fs_grab_cache_page(dir->i_mapping, 0, false);
 	if (!page) {
 		f2fs_put_page(ipage, 1);
 		return -ENOMEM;
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index f80cfb6..af010f5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -995,7 +995,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
 	if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
 		return ERR_PTR(-EPERM);
 
-	page = grab_cache_page(NODE_MAPPING(sbi), dn->nid);
+	page = f2fs_grab_cache_page(NODE_MAPPING(sbi), dn->nid, false);
 	if (!page)
 		return ERR_PTR(-ENOMEM);
 
@@ -1087,7 +1087,7 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
 	if (apage)
 		return;
 
-	apage = grab_cache_page(NODE_MAPPING(sbi), nid);
+	apage = f2fs_grab_cache_page(NODE_MAPPING(sbi), nid, false);
 	if (!apage)
 		return;
 
@@ -1128,7 +1128,7 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
 		return ERR_PTR(-ENOENT);
 	f2fs_bug_on(sbi, check_nid_range(sbi, nid));
 repeat:
-	page = grab_cache_page(NODE_MAPPING(sbi), nid);
+	page = f2fs_grab_cache_page(NODE_MAPPING(sbi), nid, false);
 	if (!page)
 		return ERR_PTR(-ENOMEM);
 
@@ -2012,7 +2012,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
 	if (unlikely(old_ni.blk_addr != NULL_ADDR))
 		return -EINVAL;
 
-	ipage = grab_cache_page(NODE_MAPPING(sbi), ino);
+	ipage = f2fs_grab_cache_page(NODE_MAPPING(sbi), ino, false);
 	if (!ipage)
 		return -ENOMEM;
 
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/11] f2fs: add mount option to select fault injection ratio
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (2 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 04/11] f2fs: use f2fs_grab_cache_page instead of grab_cache_page Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-09 12:00   ` [f2fs-dev] " Chao Yu
  2016-05-03 18:21 ` [PATCH 06/11] f2fs: inject kmalloc failure Jaegeuk Kim
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds a mount option to select fault ratio.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/Kconfig |  8 ++++++++
 fs/f2fs/f2fs.h  |  1 +
 fs/f2fs/super.c | 16 ++++++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index 1f8982a..378c221 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -94,3 +94,11 @@ config F2FS_IO_TRACE
 	  information and block IO patterns in the filesystem level.
 
 	  If unsure, say N.
+
+config F2FS_FAULT_INJECTION
+	bool "F2FS fault injection facility"
+	depends on F2FS_FS
+	help
+	  Test F2FS to inject faults such as ENOMEM, ENOSPC, and so on.
+
+	  If unsure, say N.
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 364d5fd..0684d3e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -56,6 +56,7 @@
 #define F2FS_MOUNT_EXTENT_CACHE		0x00002000
 #define F2FS_MOUNT_FORCE_FG_GC		0x00004000
 #define F2FS_MOUNT_DATA_FLUSH		0x00008000
+#define F2FS_MOUNT_FAULT_INJECTION	0x00010000
 
 #define clear_opt(sbi, option)	(sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)	(sbi->mount_opt.opt |= F2FS_MOUNT_##option)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 90d4b86..b27febd 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -39,6 +39,10 @@ static struct proc_dir_entry *f2fs_proc_root;
 static struct kmem_cache *f2fs_inode_cachep;
 static struct kset *f2fs_kset;
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+u32 f2fs_fault_rate = 0;
+#endif
+
 /* f2fs-wide shrinker description */
 static struct shrinker f2fs_shrinker_info = {
 	.scan_objects = f2fs_shrink_scan,
@@ -68,6 +72,7 @@ enum {
 	Opt_noextent_cache,
 	Opt_noinline_data,
 	Opt_data_flush,
+	Opt_fault_injection,
 	Opt_err,
 };
 
@@ -93,6 +98,7 @@ static match_table_t f2fs_tokens = {
 	{Opt_noextent_cache, "noextent_cache"},
 	{Opt_noinline_data, "noinline_data"},
 	{Opt_data_flush, "data_flush"},
+	{Opt_fault_injection, "fault_injection=%u"},
 	{Opt_err, NULL},
 };
 
@@ -433,6 +439,16 @@ static int parse_options(struct super_block *sb, char *options)
 		case Opt_data_flush:
 			set_opt(sbi, DATA_FLUSH);
 			break;
+		case Opt_fault_injection:
+			if (args->from && match_int(args, &arg))
+				return -EINVAL;
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+			f2fs_fault_rate = arg;
+#else
+			f2fs_msg(sb, KERN_INFO,
+				"FAULT_INJECTION was not selected");
+#endif
+			break;
 		default:
 			f2fs_msg(sb, KERN_ERR,
 				"Unrecognized mount option \"%s\" or missing value",
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/11] f2fs: inject kmalloc failure
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (3 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 05/11] f2fs: add mount option to select fault injection ratio Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 07/11] f2fs: inject page allocation failures Jaegeuk Kim
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch injects kmalloc failure given a fault injection rate.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/f2fs.h  | 29 +++++++++++++++++++++++++++++
 fs/f2fs/super.c |  6 ++++++
 2 files changed, 35 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 0684d3e..60098df 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -37,6 +37,31 @@
 	} while (0)
 #endif
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+enum {
+	FAULT_KMALLOC,
+	FAULT_MAX,
+};
+
+extern u32 f2fs_fault_rate;
+extern atomic_t f2fs_ops;
+extern char *fault_name[FAULT_MAX];
+
+static inline bool time_to_inject(int type)
+{
+	atomic_inc(&f2fs_ops);
+	if (f2fs_fault_rate && (atomic_read(&f2fs_ops) >= f2fs_fault_rate)) {
+		atomic_set(&f2fs_ops, 0);
+		printk("%sF2FS-fs : inject %s in %pF\n",
+				KERN_INFO,
+				fault_name[type],
+				__builtin_return_address(0));
+		return true;
+	}
+	return false;
+}
+#endif
+
 /*
  * For mount options
  */
@@ -1646,6 +1671,10 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
 
 static inline void *f2fs_kmalloc(size_t size, gfp_t flags)
 {
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	if (time_to_inject(FAULT_KMALLOC))
+		return NULL;
+#endif
 	return kmalloc(size, flags);
 }
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b27febd..76f4d2c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -41,6 +41,11 @@ static struct kset *f2fs_kset;
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 u32 f2fs_fault_rate = 0;
+atomic_t f2fs_ops;
+
+char *fault_name[FAULT_MAX] = {
+	[FAULT_KMALLOC]		= "kmalloc",
+};
 #endif
 
 /* f2fs-wide shrinker description */
@@ -444,6 +449,7 @@ static int parse_options(struct super_block *sb, char *options)
 				return -EINVAL;
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 			f2fs_fault_rate = arg;
+			atomic_set(&f2fs_ops, 0);
 #else
 			f2fs_msg(sb, KERN_INFO,
 				"FAULT_INJECTION was not selected");
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/11] f2fs: inject page allocation failures
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (4 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 06/11] f2fs: inject kmalloc failure Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 08/11] f2fs: inject ENOSPC failures Jaegeuk Kim
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds page allocation failures.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/f2fs.h  | 9 +++++++++
 fs/f2fs/super.c | 1 +
 2 files changed, 10 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 60098df..02c2c96 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -40,6 +40,7 @@
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 enum {
 	FAULT_KMALLOC,
+	FAULT_PAGE_ALLOC,
 	FAULT_MAX,
 };
 
@@ -1296,6 +1297,14 @@ static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
 static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
 						pgoff_t index, bool for_write)
 {
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	struct page *page = find_lock_page(mapping, index);
+	if (page)
+		return page;
+
+	if (time_to_inject(FAULT_PAGE_ALLOC))
+		return NULL;
+#endif
 	if (!for_write)
 		return grab_cache_page(mapping, index);
 	return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 76f4d2c..1715794 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -45,6 +45,7 @@ atomic_t f2fs_ops;
 
 char *fault_name[FAULT_MAX] = {
 	[FAULT_KMALLOC]		= "kmalloc",
+	[FAULT_PAGE_ALLOC]	= "page alloc",
 };
 #endif
 
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/11] f2fs: inject ENOSPC failures
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (5 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 07/11] f2fs: inject page allocation failures Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 09/11] f2fs: revisit error handling flows Jaegeuk Kim
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch injects ENOSPC failures.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c |  7 +++++++
 fs/f2fs/dir.c        |  4 ++++
 fs/f2fs/f2fs.h       | 10 ++++++++++
 fs/f2fs/node.c       |  4 ++++
 fs/f2fs/super.c      |  4 ++++
 5 files changed, 29 insertions(+)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index ac87cd9..9169dab 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -474,6 +474,13 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi)
 	int err = 0;
 
 	spin_lock(&im->ino_lock);
+
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	if (time_to_inject(FAULT_ORPHAN)) {
+		spin_unlock(&im->ino_lock);
+		return -ENOSPC;
+	}
+#endif
 	if (unlikely(im->ino_num >= sbi->max_orphans))
 		err = -ENOSPC;
 	else
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 6bd0595..50f42be 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -537,6 +537,10 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
 	}
 
 start:
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	if (time_to_inject(FAULT_DIR_DEPTH))
+		return -ENOSPC;
+#endif
 	if (unlikely(current_depth == MAX_DIR_HASH_DEPTH))
 		return -ENOSPC;
 
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 02c2c96..659fdea 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -41,6 +41,10 @@
 enum {
 	FAULT_KMALLOC,
 	FAULT_PAGE_ALLOC,
+	FAULT_ALLOC_NID,
+	FAULT_ORPHAN,
+	FAULT_BLOCK,
+	FAULT_DIR_DEPTH,
 	FAULT_MAX,
 };
 
@@ -1087,6 +1091,12 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
 	block_t	valid_block_count;
 
 	spin_lock(&sbi->stat_lock);
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	if (time_to_inject(FAULT_BLOCK)) {
+		spin_unlock(&sbi->stat_lock);
+		return false;
+	}
+#endif
 	valid_block_count =
 		sbi->total_valid_block_count + (block_t)count;
 	if (unlikely(valid_block_count > sbi->user_block_count)) {
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index af010f5..78b98db 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1838,6 +1838,10 @@ bool alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
 	struct f2fs_nm_info *nm_i = NM_I(sbi);
 	struct free_nid *i = NULL;
 retry:
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+	if (time_to_inject(FAULT_ALLOC_NID))
+		return false;
+#endif
 	if (unlikely(sbi->total_valid_node_count + 1 > nm_i->available_nids))
 		return false;
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 1715794..55e8eb0 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -46,6 +46,10 @@ atomic_t f2fs_ops;
 char *fault_name[FAULT_MAX] = {
 	[FAULT_KMALLOC]		= "kmalloc",
 	[FAULT_PAGE_ALLOC]	= "page alloc",
+	[FAULT_ALLOC_NID]	= "alloc nid",
+	[FAULT_ORPHAN]		= "orphan",
+	[FAULT_BLOCK]		= "no more block",
+	[FAULT_DIR_DEPTH]	= "too big dir depth",
 };
 #endif
 
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/11] f2fs: revisit error handling flows
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (6 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 08/11] f2fs: inject ENOSPC failures Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 10/11] f2fs: fix leak of orphan inode objects Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case Jaegeuk Kim
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch fixes a couple of bugs regarding to orphan inodes when handling
errors.

This tries to
 - call alloc_nid_done with add_orphan_inode in handle_failed_inode
 - let truncate blocks in f2fs_evict_inode
 - not make a bad inode due to i_mode change

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/dir.c   | 20 ++++++++++++--------
 fs/f2fs/inode.c | 40 ++++++++++++++++------------------------
 2 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 50f42be..5373f33 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -391,9 +391,14 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 			return page;
 
 		if (S_ISDIR(inode->i_mode)) {
+			/* in order to handle error case */
+			get_page(page);
 			err = make_empty_dir(inode, dir, page);
-			if (err)
-				goto error;
+			if (err) {
+				lock_page(page);
+				goto put_error;
+			}
+			put_page(page);
 		}
 
 		err = f2fs_init_acl(inode, dir, page, dpage);
@@ -437,13 +442,12 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
 	return page;
 
 put_error:
-	f2fs_put_page(page, 1);
-error:
-	/* once the failed inode becomes a bad inode, i_mode is S_IFREG */
+	/* truncate empty dir pages */
 	truncate_inode_pages(&inode->i_data, 0);
-	truncate_blocks(inode, 0, false);
-	remove_dirty_inode(inode);
-	remove_inode_page(inode);
+
+	clear_nlink(inode);
+	update_inode(inode, page);
+	f2fs_put_page(page, 1);
 	return ERR_PTR(err);
 }
 
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index cb269c4..f4ac851 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -368,10 +368,7 @@ no_delete:
 	if (is_inode_flag_set(fi, FI_UPDATE_WRITE))
 		add_ino_entry(sbi, inode->i_ino, UPDATE_INO);
 	if (is_inode_flag_set(fi, FI_FREE_NID)) {
-		if (err && err != -ENOENT)
-			alloc_nid_done(sbi, inode->i_ino);
-		else
-			alloc_nid_failed(sbi, inode->i_ino);
+		alloc_nid_failed(sbi, inode->i_ino);
 		clear_inode_flag(fi, FI_FREE_NID);
 	}
 
@@ -397,37 +394,32 @@ out_clear:
 void handle_failed_inode(struct inode *inode)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-	int err = 0;
+	struct node_info ni;
 
-	clear_nlink(inode);
-	make_bad_inode(inode);
+	/* don't make bad inode, since it becomes a regular file. */
 	unlock_new_inode(inode);
 
-	i_size_write(inode, 0);
-	if (F2FS_HAS_BLOCKS(inode))
-		err = f2fs_truncate(inode, false);
-
-	if (!err)
-		err = remove_inode_page(inode);
-
 	/*
-	 * if we skip truncate_node in remove_inode_page bacause we failed
-	 * before, it's better to find another way to release resource of
-	 * this inode (e.g. valid block count, node block or nid). Here we
-	 * choose to add this inode to orphan list, so that we can call iput
-	 * for releasing in orphan recovery flow.
-	 *
 	 * Note: we should add inode to orphan list before f2fs_unlock_op()
 	 * so we can prevent losing this orphan when encoutering checkpoint
 	 * and following suddenly power-off.
 	 */
-	if (err && err != -ENOENT) {
-		err = acquire_orphan_inode(sbi);
-		if (!err)
+	get_node_info(sbi, inode->i_ino, &ni);
+
+	if (ni.blk_addr != NULL_ADDR) {
+		int err = acquire_orphan_inode(sbi);
+		if (err) {
+			set_sbi_flag(sbi, SBI_NEED_FSCK);
+			f2fs_msg(sbi->sb, KERN_WARNING,
+				"Too many orphan inodes, run fsck to fix.");
+		} else {
 			add_orphan_inode(sbi, inode->i_ino);
+		}
+		alloc_nid_done(sbi, inode->i_ino);
+	} else {
+		set_inode_flag(F2FS_I(inode), FI_FREE_NID);
 	}
 
-	set_inode_flag(F2FS_I(inode), FI_FREE_NID);
 	f2fs_unlock_op(sbi);
 
 	/* iput will drop the inode object */
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/11] f2fs: fix leak of orphan inode objects
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (7 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 09/11] f2fs: revisit error handling flows Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-03 18:21 ` [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case Jaegeuk Kim
  9 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

When unmounting filesystem, we should release all the ino entries.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/checkpoint.c | 6 +++---
 fs/f2fs/f2fs.h       | 2 +-
 fs/f2fs/super.c      | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 9169dab..6402e93 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -449,12 +449,12 @@ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
 	return e ? true : false;
 }
 
-void release_ino_entry(struct f2fs_sb_info *sbi)
+void release_ino_entry(struct f2fs_sb_info *sbi, bool all)
 {
 	struct ino_entry *e, *tmp;
 	int i;
 
-	for (i = APPEND_INO; i <= UPDATE_INO; i++) {
+	for (i = all ? ORPHAN_INO: APPEND_INO; i <= UPDATE_INO; i++) {
 		struct inode_management *im = &sbi->im[i];
 
 		spin_lock(&im->ino_lock);
@@ -1090,7 +1090,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 		invalidate_mapping_pages(META_MAPPING(sbi), discard_blk,
 								discard_blk);
 
-	release_ino_entry(sbi);
+	release_ino_entry(sbi, false);
 
 	if (unlikely(f2fs_cp_error(sbi)))
 		return -EIO;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 659fdea..6e6fd0b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1910,7 +1910,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t);
 long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
 void add_ino_entry(struct f2fs_sb_info *, nid_t, int type);
 void remove_ino_entry(struct f2fs_sb_info *, nid_t, int type);
-void release_ino_entry(struct f2fs_sb_info *);
+void release_ino_entry(struct f2fs_sb_info *, bool);
 bool exist_written_data(struct f2fs_sb_info *, nid_t, int);
 int acquire_orphan_inode(struct f2fs_sb_info *);
 void release_orphan_inode(struct f2fs_sb_info *);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 55e8eb0..6b5f0af 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -596,7 +596,7 @@ static void f2fs_put_super(struct super_block *sb)
 	 * normally superblock is clean, so we need to release this.
 	 * In addition, EIO will skip do checkpoint, we need this as well.
 	 */
-	release_ino_entry(sbi);
+	release_ino_entry(sbi, true);
 	release_discard_addrs(sbi);
 
 	f2fs_leave_shrinker(sbi);
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case
  2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
                   ` (8 preceding siblings ...)
  2016-05-03 18:21 ` [PATCH 10/11] f2fs: fix leak of orphan inode objects Jaegeuk Kim
@ 2016-05-03 18:21 ` Jaegeuk Kim
  2016-05-05  2:00   ` Hou Pengyang
  9 siblings, 1 reply; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-03 18:21 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch modifies to retry truncating node blocks in -ENOMEM case.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/inode.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index f4ac851..5cccd7a 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -344,7 +344,7 @@ void f2fs_evict_inode(struct inode *inode)
 	sb_start_intwrite(inode->i_sb);
 	set_inode_flag(fi, FI_NO_ALLOC);
 	i_size_write(inode, 0);
-
+retry:
 	if (F2FS_HAS_BLOCKS(inode))
 		err = f2fs_truncate(inode, true);
 
@@ -374,6 +374,11 @@ no_delete:
 
 	if (err && err != -ENOENT) {
 		if (!exist_written_data(sbi, inode->i_ino, ORPHAN_INO)) {
+			/* give more chances, if ENOMEM case */
+			if (err == -ENOMEM) {
+				err = 0;
+				goto retry;
+			}
 			/*
 			 * get here because we failed to release resource
 			 * of inode previously, reminder our user to run fsck
-- 
2.6.3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case
  2016-05-03 18:21 ` [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case Jaegeuk Kim
@ 2016-05-05  2:00   ` Hou Pengyang
  2016-05-05  2:59     ` [f2fs-dev] " Jaegeuk Kim
  0 siblings, 1 reply; 14+ messages in thread
From: Hou Pengyang @ 2016-05-05  2:00 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-fsdevel, linux-kernel, linux-f2fs-devel

On 2016/5/4 2:21, Jaegeuk Kim wrote:
> This patch modifies to retry truncating node blocks in -ENOMEM case.
>
Hi, Kim. in this patch, I think there is NO chance to retry for -ENOMEM.

This is because if exist_written_data returns false, we can confirm that
this inode has been released from orphan radix-tree:
f2fs_evict_inode
  ---> remove_inode_page
     ---> truncate_node
         ---> remove_orphan_inode
On this condition, err is 0, So it won't enter:
if (err && err != -ENOENT)
{
     ...
}
sequentially, there is no chance to truncate node blocks again.
I miss something else?

How about this patch?

--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -345,6 +345,7 @@ void f2fs_evict_inode(struct inode *inode)
         set_inode_flag(fi, FI_NO_ALLOC);
         i_size_write(inode, 0);

+retry:
         if (F2FS_HAS_BLOCKS(inode))
                 err = f2fs_truncate(inode, true);

@@ -354,6 +355,11 @@ void f2fs_evict_inode(struct inode *inode)
                 f2fs_unlock_op(sbi);
         }

+       if (err == -ENOMEM) {
+               err = 0;
+               goto retry;
+       }
+
         sb_end_intwrite(inode->i_sb);
  no_delete:
         stat_dec_inline_xattr(inode);
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
>   fs/f2fs/inode.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index f4ac851..5cccd7a 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -344,7 +344,7 @@ void f2fs_evict_inode(struct inode *inode)
>   	sb_start_intwrite(inode->i_sb);
>   	set_inode_flag(fi, FI_NO_ALLOC);
>   	i_size_write(inode, 0);
> -
> +retry:
>   	if (F2FS_HAS_BLOCKS(inode))
>   		err = f2fs_truncate(inode, true);
>
> @@ -374,6 +374,11 @@ no_delete:
>
>   	if (err && err != -ENOENT) {
>   		if (!exist_written_data(sbi, inode->i_ino, ORPHAN_INO)) {
> +			/* give more chances, if ENOMEM case */
> +			if (err == -ENOMEM) {
> +				err = 0;
> +				goto retry;
> +			}
>   			/*
>   			 * get here because we failed to release resource
>   			 * of inode previously, reminder our user to run fsck
>



------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [f2fs-dev] [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case
  2016-05-05  2:00   ` Hou Pengyang
@ 2016-05-05  2:59     ` Jaegeuk Kim
  0 siblings, 0 replies; 14+ messages in thread
From: Jaegeuk Kim @ 2016-05-05  2:59 UTC (permalink / raw)
  To: Hou Pengyang
  Cc: linux-kernel, linux-fsdevel, linux-f2fs-devel,
	wangbintian 00221568

Hi,

On Thu, May 05, 2016 at 10:00:15AM +0800, Hou Pengyang wrote:
> On 2016/5/4 2:21, Jaegeuk Kim wrote:
> >This patch modifies to retry truncating node blocks in -ENOMEM case.
> >
> Hi, Kim. in this patch, I think there is NO chance to retry for -ENOMEM.
> 
> This is because if exist_written_data returns false, we can confirm that
> this inode has been released from orphan radix-tree:
> f2fs_evict_inode
>  ---> remove_inode_page
>     ---> truncate_node
>         ---> remove_orphan_inode
> On this condition, err is 0, So it won't enter:
> if (err && err != -ENOENT)
> {
>     ...
> }
> sequentially, there is no chance to truncate node blocks again.
> I miss something else?

When I initially tested fault injection, I could hit that before.
But, now I can't hit this again. :(
It seems it was gone while I updated the error flow before.
Agreed with you, and let me take your change.

BTW, I even suspect whether this leaking condition happens or not.
If f2fs_evict_inode deals with inode deletion, that inode should be an orphan
one. So, we don't need to consider that condition actually.

So, I wrote this patch as well.
I started stress tests again. :)

Thanks,

>From 8c1e4e5ca23410b8f55bbc75d64f75416d486739 Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <jaegeuk@kernel.org>
Date: Wed, 4 May 2016 19:48:53 -0700
Subject: [PATCH] f2fs: don't worry about inode leak in evict_inode

Even if an inode failed to release its blocks, it should be kept in an orphan
inode list, so it will be released later.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/inode.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index baf3a2a..689d691 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -377,20 +377,8 @@ no_delete:
 		alloc_nid_failed(sbi, inode->i_ino);
 		clear_inode_flag(fi, FI_FREE_NID);
 	}
-
-	if (err && err != -ENOENT) {
-		if (!exist_written_data(sbi, inode->i_ino, ORPHAN_INO)) {
-			/*
-			 * get here because we failed to release resource
-			 * of inode previously, reminder our user to run fsck
-			 * for fixing.
-			 */
-			set_sbi_flag(sbi, SBI_NEED_FSCK);
-			f2fs_msg(sbi->sb, KERN_WARNING,
-				"inode (ino:%lu) resource leak, run fsck "
-				"to fix this issue!", inode->i_ino);
-		}
-	}
+	f2fs_bug_on(sbi, err &&
+		!exist_written_data(sbi, inode->i_ino, ORPHAN_INO));
 out_clear:
 	fscrypt_put_encryption_info(inode, NULL);
 	clear_inode(inode);
-- 
2.6.3

> 
> How about this patch?
> 
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -345,6 +345,7 @@ void f2fs_evict_inode(struct inode *inode)
>         set_inode_flag(fi, FI_NO_ALLOC);
>         i_size_write(inode, 0);
> 
> +retry:
>         if (F2FS_HAS_BLOCKS(inode))
>                 err = f2fs_truncate(inode, true);
> 
> @@ -354,6 +355,11 @@ void f2fs_evict_inode(struct inode *inode)
>                 f2fs_unlock_op(sbi);
>         }
> 
> +       if (err == -ENOMEM) {
> +               err = 0;
> +               goto retry;
> +       }
> +
>         sb_end_intwrite(inode->i_sb);
>  no_delete:
>         stat_dec_inline_xattr(inode);
> >Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> >---
> >  fs/f2fs/inode.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> >diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> >index f4ac851..5cccd7a 100644
> >--- a/fs/f2fs/inode.c
> >+++ b/fs/f2fs/inode.c
> >@@ -344,7 +344,7 @@ void f2fs_evict_inode(struct inode *inode)
> >  	sb_start_intwrite(inode->i_sb);
> >  	set_inode_flag(fi, FI_NO_ALLOC);
> >  	i_size_write(inode, 0);
> >-
> >+retry:
> >  	if (F2FS_HAS_BLOCKS(inode))
> >  		err = f2fs_truncate(inode, true);
> >
> >@@ -374,6 +374,11 @@ no_delete:
> >
> >  	if (err && err != -ENOENT) {
> >  		if (!exist_written_data(sbi, inode->i_ino, ORPHAN_INO)) {
> >+			/* give more chances, if ENOMEM case */
> >+			if (err == -ENOMEM) {
> >+				err = 0;
> >+				goto retry;
> >+			}
> >  			/*
> >  			 * get here because we failed to release resource
> >  			 * of inode previously, reminder our user to run fsck
> >
> 

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [f2fs-dev] [PATCH 05/11] f2fs: add mount option to select fault injection ratio
  2016-05-03 18:21 ` [PATCH 05/11] f2fs: add mount option to select fault injection ratio Jaegeuk Kim
@ 2016-05-09 12:00   ` Chao Yu
  0 siblings, 0 replies; 14+ messages in thread
From: Chao Yu @ 2016-05-09 12:00 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Jaegeuk,

On 2016/5/4 2:21, Jaegeuk Kim wrote:
> This patch adds a mount option to select fault ratio.

It's better to add description in documentation for this new mount option.

Anyway, this patchset looks good to me, please add:

Acked-by: Chao Yu <yuchao0@huawei.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-05-09 12:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-03 18:21 [PATCH 01/11] f2fs: introduce macros for proc entries Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 02/11] f2fs: add proc entry to show valid block bitmap Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 03/11] f2fs: introduce f2fs_kmalloc to wrap kmalloc Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 04/11] f2fs: use f2fs_grab_cache_page instead of grab_cache_page Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 05/11] f2fs: add mount option to select fault injection ratio Jaegeuk Kim
2016-05-09 12:00   ` [f2fs-dev] " Chao Yu
2016-05-03 18:21 ` [PATCH 06/11] f2fs: inject kmalloc failure Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 07/11] f2fs: inject page allocation failures Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 08/11] f2fs: inject ENOSPC failures Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 09/11] f2fs: revisit error handling flows Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 10/11] f2fs: fix leak of orphan inode objects Jaegeuk Kim
2016-05-03 18:21 ` [PATCH 11/11] f2fs: retry to truncate blocks in -ENOMEM case Jaegeuk Kim
2016-05-05  2:00   ` Hou Pengyang
2016-05-05  2:59     ` [f2fs-dev] " Jaegeuk Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).