Skip to content

Commit 9627a7b

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: fix error path in do_recover_data()
- don't panic kernel if f2fs_get_node_page() fails in f2fs_recover_inline_data() or f2fs_recover_inline_xattr(); - return error number of f2fs_truncate_blocks() to f2fs_recover_inline_data()'s caller; Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 4fc781a commit 9627a7b

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

fs/f2fs/f2fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,7 +3302,7 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid);
33023302
void f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
33033303
void f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
33043304
int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
3305-
void f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
3305+
int f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
33063306
int f2fs_recover_xattr_data(struct inode *inode, struct page *page);
33073307
int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
33083308
int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
@@ -3769,7 +3769,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page);
37693769
int f2fs_convert_inline_inode(struct inode *inode);
37703770
int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry);
37713771
int f2fs_write_inline_data(struct inode *inode, struct page *page);
3772-
bool f2fs_recover_inline_data(struct inode *inode, struct page *npage);
3772+
int f2fs_recover_inline_data(struct inode *inode, struct page *npage);
37733773
struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
37743774
const struct f2fs_filename *fname,
37753775
struct page **res_page);

fs/f2fs/inline.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
254254
return 0;
255255
}
256256

257-
bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
257+
int f2fs_recover_inline_data(struct inode *inode, struct page *npage)
258258
{
259259
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
260260
struct f2fs_inode *ri = NULL;
@@ -276,7 +276,8 @@ bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
276276
ri && (ri->i_inline & F2FS_INLINE_DATA)) {
277277
process_inline:
278278
ipage = f2fs_get_node_page(sbi, inode->i_ino);
279-
f2fs_bug_on(sbi, IS_ERR(ipage));
279+
if (IS_ERR(ipage))
280+
return PTR_ERR(ipage);
280281

281282
f2fs_wait_on_page_writeback(ipage, NODE, true, true);
282283

@@ -289,21 +290,25 @@ bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
289290

290291
set_page_dirty(ipage);
291292
f2fs_put_page(ipage, 1);
292-
return true;
293+
return 1;
293294
}
294295

295296
if (f2fs_has_inline_data(inode)) {
296297
ipage = f2fs_get_node_page(sbi, inode->i_ino);
297-
f2fs_bug_on(sbi, IS_ERR(ipage));
298+
if (IS_ERR(ipage))
299+
return PTR_ERR(ipage);
298300
f2fs_truncate_inline_inode(inode, ipage, 0);
299301
clear_inode_flag(inode, FI_INLINE_DATA);
300302
f2fs_put_page(ipage, 1);
301303
} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
302-
if (f2fs_truncate_blocks(inode, 0, false))
303-
return false;
304+
int ret;
305+
306+
ret = f2fs_truncate_blocks(inode, 0, false);
307+
if (ret)
308+
return ret;
304309
goto process_inline;
305310
}
306-
return false;
311+
return 0;
307312
}
308313

309314
struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,

fs/f2fs/node.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2572,15 +2572,16 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink)
25722572
return nr - nr_shrink;
25732573
}
25742574

2575-
void f2fs_recover_inline_xattr(struct inode *inode, struct page *page)
2575+
int f2fs_recover_inline_xattr(struct inode *inode, struct page *page)
25762576
{
25772577
void *src_addr, *dst_addr;
25782578
size_t inline_size;
25792579
struct page *ipage;
25802580
struct f2fs_inode *ri;
25812581

25822582
ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
2583-
f2fs_bug_on(F2FS_I_SB(inode), IS_ERR(ipage));
2583+
if (IS_ERR(ipage))
2584+
return PTR_ERR(ipage);
25842585

25852586
ri = F2FS_INODE(page);
25862587
if (ri->i_inline & F2FS_INLINE_XATTR) {
@@ -2599,6 +2600,7 @@ void f2fs_recover_inline_xattr(struct inode *inode, struct page *page)
25992600
update_inode:
26002601
f2fs_update_inode(inode, ipage);
26012602
f2fs_put_page(ipage, 1);
2603+
return 0;
26022604
}
26032605

26042606
int f2fs_recover_xattr_data(struct inode *inode, struct page *page)

fs/f2fs/recovery.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,9 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
544544

545545
/* step 1: recover xattr */
546546
if (IS_INODE(page)) {
547-
f2fs_recover_inline_xattr(inode, page);
547+
err = f2fs_recover_inline_xattr(inode, page);
548+
if (err)
549+
goto out;
548550
} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
549551
err = f2fs_recover_xattr_data(inode, page);
550552
if (!err)
@@ -553,8 +555,12 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
553555
}
554556

555557
/* step 2: recover inline data */
556-
if (f2fs_recover_inline_data(inode, page))
558+
err = f2fs_recover_inline_data(inode, page);
559+
if (err) {
560+
if (err == 1)
561+
err = 0;
557562
goto out;
563+
}
558564

559565
/* step 3: recover data indices */
560566
start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);

0 commit comments

Comments
 (0)