diff options
Diffstat (limited to 'fs/f2fs/inline.c')
-rw-r--r-- | fs/f2fs/inline.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 383db1fabcf4..1bba5228c197 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
@@ -81,8 +81,10 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) | |||
81 | 81 | ||
82 | f2fs_lock_op(sbi); | 82 | f2fs_lock_op(sbi); |
83 | ipage = get_node_page(sbi, inode->i_ino); | 83 | ipage = get_node_page(sbi, inode->i_ino); |
84 | if (IS_ERR(ipage)) | 84 | if (IS_ERR(ipage)) { |
85 | return PTR_ERR(ipage); | 85 | err = PTR_ERR(ipage); |
86 | goto out; | ||
87 | } | ||
86 | 88 | ||
87 | /* | 89 | /* |
88 | * i_addr[0] is not used for inline data, | 90 | * i_addr[0] is not used for inline data, |
@@ -90,11 +92,10 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) | |||
90 | */ | 92 | */ |
91 | set_new_dnode(&dn, inode, ipage, NULL, 0); | 93 | set_new_dnode(&dn, inode, ipage, NULL, 0); |
92 | err = f2fs_reserve_block(&dn, 0); | 94 | err = f2fs_reserve_block(&dn, 0); |
93 | if (err) { | 95 | if (err) |
94 | f2fs_unlock_op(sbi); | 96 | goto out; |
95 | return err; | ||
96 | } | ||
97 | 97 | ||
98 | f2fs_wait_on_page_writeback(page, DATA); | ||
98 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); | 99 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); |
99 | 100 | ||
100 | /* Copy the whole inline data block */ | 101 | /* Copy the whole inline data block */ |
@@ -118,6 +119,7 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) | |||
118 | 119 | ||
119 | sync_inode_page(&dn); | 120 | sync_inode_page(&dn); |
120 | f2fs_put_dnode(&dn); | 121 | f2fs_put_dnode(&dn); |
122 | out: | ||
121 | f2fs_unlock_op(sbi); | 123 | f2fs_unlock_op(sbi); |
122 | return err; | 124 | return err; |
123 | } | 125 | } |
@@ -132,7 +134,7 @@ int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) | |||
132 | else if (to_size <= MAX_INLINE_DATA) | 134 | else if (to_size <= MAX_INLINE_DATA) |
133 | return 0; | 135 | return 0; |
134 | 136 | ||
135 | page = grab_cache_page_write_begin(inode->i_mapping, 0, AOP_FLAG_NOFS); | 137 | page = grab_cache_page(inode->i_mapping, 0); |
136 | if (!page) | 138 | if (!page) |
137 | return -ENOMEM; | 139 | return -ENOMEM; |
138 | 140 | ||
@@ -155,6 +157,7 @@ int f2fs_write_inline_data(struct inode *inode, | |||
155 | return err; | 157 | return err; |
156 | ipage = dn.inode_page; | 158 | ipage = dn.inode_page; |
157 | 159 | ||
160 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
158 | zero_user_segment(ipage, INLINE_DATA_OFFSET, | 161 | zero_user_segment(ipage, INLINE_DATA_OFFSET, |
159 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | 162 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); |
160 | src_addr = kmap(page); | 163 | src_addr = kmap(page); |
@@ -175,6 +178,26 @@ int f2fs_write_inline_data(struct inode *inode, | |||
175 | return 0; | 178 | return 0; |
176 | } | 179 | } |
177 | 180 | ||
181 | void truncate_inline_data(struct inode *inode, u64 from) | ||
182 | { | ||
183 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | ||
184 | struct page *ipage; | ||
185 | |||
186 | if (from >= MAX_INLINE_DATA) | ||
187 | return; | ||
188 | |||
189 | ipage = get_node_page(sbi, inode->i_ino); | ||
190 | if (IS_ERR(ipage)) | ||
191 | return; | ||
192 | |||
193 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
194 | |||
195 | zero_user_segment(ipage, INLINE_DATA_OFFSET + from, | ||
196 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | ||
197 | set_page_dirty(ipage); | ||
198 | f2fs_put_page(ipage, 1); | ||
199 | } | ||
200 | |||
178 | int recover_inline_data(struct inode *inode, struct page *npage) | 201 | int recover_inline_data(struct inode *inode, struct page *npage) |
179 | { | 202 | { |
180 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 203 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
@@ -199,6 +222,8 @@ process_inline: | |||
199 | ipage = get_node_page(sbi, inode->i_ino); | 222 | ipage = get_node_page(sbi, inode->i_ino); |
200 | f2fs_bug_on(IS_ERR(ipage)); | 223 | f2fs_bug_on(IS_ERR(ipage)); |
201 | 224 | ||
225 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
226 | |||
202 | src_addr = inline_data_addr(npage); | 227 | src_addr = inline_data_addr(npage); |
203 | dst_addr = inline_data_addr(ipage); | 228 | dst_addr = inline_data_addr(ipage); |
204 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | 229 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); |
@@ -210,6 +235,7 @@ process_inline: | |||
210 | if (f2fs_has_inline_data(inode)) { | 235 | if (f2fs_has_inline_data(inode)) { |
211 | ipage = get_node_page(sbi, inode->i_ino); | 236 | ipage = get_node_page(sbi, inode->i_ino); |
212 | f2fs_bug_on(IS_ERR(ipage)); | 237 | f2fs_bug_on(IS_ERR(ipage)); |
238 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
213 | zero_user_segment(ipage, INLINE_DATA_OFFSET, | 239 | zero_user_segment(ipage, INLINE_DATA_OFFSET, |
214 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | 240 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); |
215 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | 241 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); |