aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/inline.c')
-rw-r--r--fs/f2fs/inline.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 5beeccef9ae1..3e8ecdf3742b 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -68,7 +68,7 @@ out:
68 68
69static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) 69static int __f2fs_convert_inline_data(struct inode *inode, struct page *page)
70{ 70{
71 int err; 71 int err = 0;
72 struct page *ipage; 72 struct page *ipage;
73 struct dnode_of_data dn; 73 struct dnode_of_data dn;
74 void *src_addr, *dst_addr; 74 void *src_addr, *dst_addr;
@@ -86,6 +86,10 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page)
86 goto out; 86 goto out;
87 } 87 }
88 88
89 /* someone else converted inline_data already */
90 if (!f2fs_has_inline_data(inode))
91 goto out;
92
89 /* 93 /*
90 * i_addr[0] is not used for inline data, 94 * i_addr[0] is not used for inline data,
91 * so reserving new block will not destroy inline data 95 * so reserving new block will not destroy inline data
@@ -124,9 +128,10 @@ out:
124 return err; 128 return err;
125} 129}
126 130
127int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) 131int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size,
132 struct page *page)
128{ 133{
129 struct page *page; 134 struct page *new_page = page;
130 int err; 135 int err;
131 136
132 if (!f2fs_has_inline_data(inode)) 137 if (!f2fs_has_inline_data(inode))
@@ -134,17 +139,20 @@ int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size)
134 else if (to_size <= MAX_INLINE_DATA) 139 else if (to_size <= MAX_INLINE_DATA)
135 return 0; 140 return 0;
136 141
137 page = grab_cache_page(inode->i_mapping, 0); 142 if (!page || page->index != 0) {
138 if (!page) 143 new_page = grab_cache_page(inode->i_mapping, 0);
139 return -ENOMEM; 144 if (!new_page)
145 return -ENOMEM;
146 }
140 147
141 err = __f2fs_convert_inline_data(inode, page); 148 err = __f2fs_convert_inline_data(inode, new_page);
142 f2fs_put_page(page, 1); 149 if (!page || page->index != 0)
150 f2fs_put_page(new_page, 1);
143 return err; 151 return err;
144} 152}
145 153
146int f2fs_write_inline_data(struct inode *inode, 154int f2fs_write_inline_data(struct inode *inode,
147 struct page *page, unsigned size) 155 struct page *page, unsigned size)
148{ 156{
149 void *src_addr, *dst_addr; 157 void *src_addr, *dst_addr;
150 struct page *ipage; 158 struct page *ipage;
@@ -199,7 +207,7 @@ void truncate_inline_data(struct inode *inode, u64 from)
199 f2fs_put_page(ipage, 1); 207 f2fs_put_page(ipage, 1);
200} 208}
201 209
202int recover_inline_data(struct inode *inode, struct page *npage) 210bool recover_inline_data(struct inode *inode, struct page *npage)
203{ 211{
204 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 212 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
205 struct f2fs_inode *ri = NULL; 213 struct f2fs_inode *ri = NULL;
@@ -218,7 +226,7 @@ int recover_inline_data(struct inode *inode, struct page *npage)
218 ri = F2FS_INODE(npage); 226 ri = F2FS_INODE(npage);
219 227
220 if (f2fs_has_inline_data(inode) && 228 if (f2fs_has_inline_data(inode) &&
221 ri && ri->i_inline & F2FS_INLINE_DATA) { 229 ri && (ri->i_inline & F2FS_INLINE_DATA)) {
222process_inline: 230process_inline:
223 ipage = get_node_page(sbi, inode->i_ino); 231 ipage = get_node_page(sbi, inode->i_ino);
224 f2fs_bug_on(IS_ERR(ipage)); 232 f2fs_bug_on(IS_ERR(ipage));
@@ -230,7 +238,7 @@ process_inline:
230 memcpy(dst_addr, src_addr, MAX_INLINE_DATA); 238 memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
231 update_inode(inode, ipage); 239 update_inode(inode, ipage);
232 f2fs_put_page(ipage, 1); 240 f2fs_put_page(ipage, 1);
233 return -1; 241 return true;
234 } 242 }
235 243
236 if (f2fs_has_inline_data(inode)) { 244 if (f2fs_has_inline_data(inode)) {
@@ -242,10 +250,10 @@ process_inline:
242 clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 250 clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
243 update_inode(inode, ipage); 251 update_inode(inode, ipage);
244 f2fs_put_page(ipage, 1); 252 f2fs_put_page(ipage, 1);
245 } else if (ri && ri->i_inline & F2FS_INLINE_DATA) { 253 } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
246 truncate_blocks(inode, 0); 254 truncate_blocks(inode, 0, false);
247 set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); 255 set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
248 goto process_inline; 256 goto process_inline;
249 } 257 }
250 return 0; 258 return false;
251} 259}