diff options
Diffstat (limited to 'fs/f2fs/inode.c')
-rw-r--r-- | fs/f2fs/inode.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 0deead4505e7..196cc7843aaf 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,19 @@ 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 | |
152 | stat_inc_inline_inode(inode); | ||
153 | stat_inc_inline_dir(inode); | ||
154 | |||
155 | return err; | ||
122 | } | 156 | } |
123 | 157 | ||
124 | struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) | 158 | struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) |
@@ -156,7 +190,7 @@ make_now: | |||
156 | inode->i_op = &f2fs_dir_inode_operations; | 190 | inode->i_op = &f2fs_dir_inode_operations; |
157 | inode->i_fop = &f2fs_dir_operations; | 191 | inode->i_fop = &f2fs_dir_operations; |
158 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | 192 | inode->i_mapping->a_ops = &f2fs_dblock_aops; |
159 | mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); | 193 | mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); |
160 | } else if (S_ISLNK(inode->i_mode)) { | 194 | } else if (S_ISLNK(inode->i_mode)) { |
161 | inode->i_op = &f2fs_symlink_inode_operations; | 195 | inode->i_op = &f2fs_symlink_inode_operations; |
162 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | 196 | inode->i_mapping->a_ops = &f2fs_dblock_aops; |
@@ -295,11 +329,12 @@ void f2fs_evict_inode(struct inode *inode) | |||
295 | 329 | ||
296 | f2fs_lock_op(sbi); | 330 | f2fs_lock_op(sbi); |
297 | remove_inode_page(inode); | 331 | remove_inode_page(inode); |
298 | stat_dec_inline_inode(inode); | ||
299 | f2fs_unlock_op(sbi); | 332 | f2fs_unlock_op(sbi); |
300 | 333 | ||
301 | sb_end_intwrite(inode->i_sb); | 334 | sb_end_intwrite(inode->i_sb); |
302 | no_delete: | 335 | no_delete: |
336 | stat_dec_inline_dir(inode); | ||
337 | stat_dec_inline_inode(inode); | ||
303 | invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); | 338 | invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); |
304 | if (xnid) | 339 | if (xnid) |
305 | invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); | 340 | invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); |
@@ -325,8 +360,9 @@ void handle_failed_inode(struct inode *inode) | |||
325 | f2fs_truncate(inode); | 360 | f2fs_truncate(inode); |
326 | 361 | ||
327 | remove_inode_page(inode); | 362 | remove_inode_page(inode); |
328 | stat_dec_inline_inode(inode); | ||
329 | 363 | ||
364 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
365 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); | ||
330 | alloc_nid_failed(sbi, inode->i_ino); | 366 | alloc_nid_failed(sbi, inode->i_ino); |
331 | f2fs_unlock_op(sbi); | 367 | f2fs_unlock_op(sbi); |
332 | 368 | ||