diff options
| author | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-05-02 12:34:48 -0700 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-04-13 12:33:26 +0200 |
| commit | 68de7b37bd3c47b52fb4a7b4dc08a1832e234528 (patch) | |
| tree | 5e60ee7223b6e8809620b29aeef3717a3a02f01f /fs/f2fs/dir.c | |
| parent | b6cb1ce74b0a141b49ba3f30752ceb0533835082 (diff) | |
f2fs: revisit error handling flows
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>
Diffstat (limited to 'fs/f2fs/dir.c')
| -rw-r--r-- | fs/f2fs/dir.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 972e19ac9..64596576b 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -393,9 +393,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); @@ -439,13 +444,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); } |
