From: Jaegeuk Kim <jaegeuk@kernel.org>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Subject: [PATCH 09/11] f2fs: revisit error handling flows
Date: Tue, 3 May 2016 11:21:46 -0700 [thread overview]
Message-ID: <1462299708-67906-9-git-send-email-jaegeuk@kernel.org> (raw)
In-Reply-To: <1462299708-67906-1-git-send-email-jaegeuk@kernel.org>
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
next prev parent reply other threads:[~2016-05-03 18:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Jaegeuk Kim [this message]
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 ` [f2fs-dev] " Hou Pengyang
2016-05-05 2:59 ` Jaegeuk Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1462299708-67906-9-git-send-email-jaegeuk@kernel.org \
--to=jaegeuk@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).