diff options
Diffstat (limited to 'fs/f2fs/inode.c')
-rw-r--r-- | fs/f2fs/inode.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 4131e3cfd1cf..9fe110ef8cc4 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -67,12 +67,38 @@ static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) | |||
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
70 | static int __recover_inline_status(struct inode *inode, struct page *ipage) | ||
71 | { | ||
72 | void *inline_data = inline_data_addr(ipage); | ||
73 | struct f2fs_inode *ri; | ||
74 | void *zbuf; | ||
75 | |||
76 | zbuf = kzalloc(MAX_INLINE_DATA, GFP_NOFS); | ||
77 | if (!zbuf) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | if (!memcmp(zbuf, inline_data, MAX_INLINE_DATA)) { | ||
81 | kfree(zbuf); | ||
82 | return 0; | ||
83 | } | ||
84 | kfree(zbuf); | ||
85 | |||
86 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
87 | set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); | ||
88 | |||
89 | ri = F2FS_INODE(ipage); | ||
90 | set_raw_inline(F2FS_I(inode), ri); | ||
91 | set_page_dirty(ipage); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
70 | static int do_read_inode(struct inode *inode) | 95 | static int do_read_inode(struct inode *inode) |
71 | { | 96 | { |
72 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 97 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
73 | struct f2fs_inode_info *fi = F2FS_I(inode); | 98 | struct f2fs_inode_info *fi = F2FS_I(inode); |
74 | struct page *node_page; | 99 | struct page *node_page; |
75 | struct f2fs_inode *ri; | 100 | struct f2fs_inode *ri; |
101 | int err = 0; | ||
76 | 102 | ||
77 | /* Check if ino is within scope */ | 103 | /* Check if ino is within scope */ |
78 | if (check_nid_range(sbi, inode->i_ino)) { | 104 | if (check_nid_range(sbi, inode->i_ino)) { |
@@ -114,11 +140,15 @@ static int do_read_inode(struct inode *inode) | |||
114 | get_extent_info(&fi->ext, ri->i_ext); | 140 | get_extent_info(&fi->ext, ri->i_ext); |
115 | get_inline_info(fi, ri); | 141 | get_inline_info(fi, ri); |
116 | 142 | ||
143 | /* check data exist */ | ||
144 | if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) | ||
145 | err = __recover_inline_status(inode, node_page); | ||
146 | |||
117 | /* get rdev by using inline_info */ | 147 | /* get rdev by using inline_info */ |
118 | __get_inode_rdev(inode, ri); | 148 | __get_inode_rdev(inode, ri); |
119 | 149 | ||
120 | f2fs_put_page(node_page, 1); | 150 | f2fs_put_page(node_page, 1); |
121 | return 0; | 151 | return err; |
122 | } | 152 | } |
123 | 153 | ||
124 | struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) | 154 | struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) |
@@ -329,6 +359,7 @@ void handle_failed_inode(struct inode *inode) | |||
329 | 359 | ||
330 | remove_inode_page(inode); | 360 | remove_inode_page(inode); |
331 | 361 | ||
362 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
332 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); | 363 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); |
333 | alloc_nid_failed(sbi, inode->i_ino); | 364 | alloc_nid_failed(sbi, inode->i_ino); |
334 | f2fs_unlock_op(sbi); | 365 | f2fs_unlock_op(sbi); |