f2fs: add inline_data recovery routine
This patch adds a inline_data recovery routine with the following policy. [prev.] [next] of inline_data flag o o -> recover inline_data o x -> remove inline_data, and then recover data blocks x o -> remove inline_data, and then recover inline_data x x -> recover data blocks Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
This commit is contained in:
@@ -169,3 +169,51 @@ int f2fs_write_inline_data(struct inode *inode,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int recover_inline_data(struct inode *inode, struct page *npage)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
|
||||
struct f2fs_inode *ri = NULL;
|
||||
void *src_addr, *dst_addr;
|
||||
struct page *ipage;
|
||||
|
||||
/*
|
||||
* The inline_data recovery policy is as follows.
|
||||
* [prev.] [next] of inline_data flag
|
||||
* o o -> recover inline_data
|
||||
* o x -> remove inline_data, and then recover data blocks
|
||||
* x o -> remove inline_data, and then recover inline_data
|
||||
* x x -> recover data blocks
|
||||
*/
|
||||
if (IS_INODE(npage))
|
||||
ri = F2FS_INODE(npage);
|
||||
|
||||
if (f2fs_has_inline_data(inode) &&
|
||||
ri && ri->i_inline & F2FS_INLINE_DATA) {
|
||||
process_inline:
|
||||
ipage = get_node_page(sbi, inode->i_ino);
|
||||
f2fs_bug_on(IS_ERR(ipage));
|
||||
|
||||
src_addr = inline_data_addr(npage);
|
||||
dst_addr = inline_data_addr(ipage);
|
||||
memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
|
||||
update_inode(inode, ipage);
|
||||
f2fs_put_page(ipage, 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (f2fs_has_inline_data(inode)) {
|
||||
ipage = get_node_page(sbi, inode->i_ino);
|
||||
f2fs_bug_on(IS_ERR(ipage));
|
||||
zero_user_segment(ipage, INLINE_DATA_OFFSET,
|
||||
INLINE_DATA_OFFSET + MAX_INLINE_DATA);
|
||||
clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
|
||||
update_inode(inode, ipage);
|
||||
f2fs_put_page(ipage, 1);
|
||||
} else if (ri && ri->i_inline & F2FS_INLINE_DATA) {
|
||||
truncate_blocks(inode, 0);
|
||||
set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
|
||||
goto process_inline;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user