diff options
Diffstat (limited to 'fs/f2fs/inline.c')
-rw-r--r-- | fs/f2fs/inline.c | 482 |
1 files changed, 377 insertions, 105 deletions
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 88036fd75797..f2d3c581e776 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
@@ -15,35 +15,44 @@ | |||
15 | 15 | ||
16 | bool f2fs_may_inline(struct inode *inode) | 16 | bool f2fs_may_inline(struct inode *inode) |
17 | { | 17 | { |
18 | block_t nr_blocks; | ||
19 | loff_t i_size; | ||
20 | |||
21 | if (!test_opt(F2FS_I_SB(inode), INLINE_DATA)) | 18 | if (!test_opt(F2FS_I_SB(inode), INLINE_DATA)) |
22 | return false; | 19 | return false; |
23 | 20 | ||
24 | if (f2fs_is_atomic_file(inode)) | 21 | if (f2fs_is_atomic_file(inode)) |
25 | return false; | 22 | return false; |
26 | 23 | ||
27 | nr_blocks = F2FS_I(inode)->i_xattr_nid ? 3 : 2; | 24 | if (!S_ISREG(inode->i_mode)) |
28 | if (inode->i_blocks > nr_blocks) | ||
29 | return false; | 25 | return false; |
30 | 26 | ||
31 | i_size = i_size_read(inode); | 27 | if (i_size_read(inode) > MAX_INLINE_DATA) |
32 | if (i_size > MAX_INLINE_DATA) | ||
33 | return false; | 28 | return false; |
34 | 29 | ||
35 | return true; | 30 | return true; |
36 | } | 31 | } |
37 | 32 | ||
38 | int f2fs_read_inline_data(struct inode *inode, struct page *page) | 33 | void read_inline_data(struct page *page, struct page *ipage) |
39 | { | 34 | { |
40 | struct page *ipage; | ||
41 | void *src_addr, *dst_addr; | 35 | void *src_addr, *dst_addr; |
42 | 36 | ||
43 | if (page->index) { | 37 | if (PageUptodate(page)) |
44 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); | 38 | return; |
45 | goto out; | 39 | |
46 | } | 40 | f2fs_bug_on(F2FS_P_SB(page), page->index); |
41 | |||
42 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); | ||
43 | |||
44 | /* Copy the whole inline data block */ | ||
45 | src_addr = inline_data_addr(ipage); | ||
46 | dst_addr = kmap_atomic(page); | ||
47 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | ||
48 | flush_dcache_page(page); | ||
49 | kunmap_atomic(dst_addr); | ||
50 | SetPageUptodate(page); | ||
51 | } | ||
52 | |||
53 | int f2fs_read_inline_data(struct inode *inode, struct page *page) | ||
54 | { | ||
55 | struct page *ipage; | ||
47 | 56 | ||
48 | ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); | 57 | ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); |
49 | if (IS_ERR(ipage)) { | 58 | if (IS_ERR(ipage)) { |
@@ -51,112 +60,116 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) | |||
51 | return PTR_ERR(ipage); | 60 | return PTR_ERR(ipage); |
52 | } | 61 | } |
53 | 62 | ||
54 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); | 63 | if (!f2fs_has_inline_data(inode)) { |
64 | f2fs_put_page(ipage, 1); | ||
65 | return -EAGAIN; | ||
66 | } | ||
55 | 67 | ||
56 | /* Copy the whole inline data block */ | 68 | if (page->index) |
57 | src_addr = inline_data_addr(ipage); | 69 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); |
58 | dst_addr = kmap(page); | 70 | else |
59 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | 71 | read_inline_data(page, ipage); |
60 | kunmap(page); | ||
61 | f2fs_put_page(ipage, 1); | ||
62 | 72 | ||
63 | out: | ||
64 | SetPageUptodate(page); | 73 | SetPageUptodate(page); |
74 | f2fs_put_page(ipage, 1); | ||
65 | unlock_page(page); | 75 | unlock_page(page); |
66 | |||
67 | return 0; | 76 | return 0; |
68 | } | 77 | } |
69 | 78 | ||
70 | static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) | 79 | int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) |
71 | { | 80 | { |
72 | int err = 0; | ||
73 | struct page *ipage; | ||
74 | struct dnode_of_data dn; | ||
75 | void *src_addr, *dst_addr; | 81 | void *src_addr, *dst_addr; |
76 | block_t new_blk_addr; | 82 | block_t new_blk_addr; |
77 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
78 | struct f2fs_io_info fio = { | 83 | struct f2fs_io_info fio = { |
79 | .type = DATA, | 84 | .type = DATA, |
80 | .rw = WRITE_SYNC | REQ_PRIO, | 85 | .rw = WRITE_SYNC | REQ_PRIO, |
81 | }; | 86 | }; |
87 | int dirty, err; | ||
82 | 88 | ||
83 | f2fs_lock_op(sbi); | 89 | f2fs_bug_on(F2FS_I_SB(dn->inode), page->index); |
84 | ipage = get_node_page(sbi, inode->i_ino); | ||
85 | if (IS_ERR(ipage)) { | ||
86 | err = PTR_ERR(ipage); | ||
87 | goto out; | ||
88 | } | ||
89 | 90 | ||
90 | /* someone else converted inline_data already */ | 91 | if (!f2fs_exist_data(dn->inode)) |
91 | if (!f2fs_has_inline_data(inode)) | 92 | goto clear_out; |
92 | goto out; | ||
93 | 93 | ||
94 | /* | 94 | err = f2fs_reserve_block(dn, 0); |
95 | * i_addr[0] is not used for inline data, | ||
96 | * so reserving new block will not destroy inline data | ||
97 | */ | ||
98 | set_new_dnode(&dn, inode, ipage, NULL, 0); | ||
99 | err = f2fs_reserve_block(&dn, 0); | ||
100 | if (err) | 95 | if (err) |
101 | goto out; | 96 | return err; |
102 | 97 | ||
103 | f2fs_wait_on_page_writeback(page, DATA); | 98 | f2fs_wait_on_page_writeback(page, DATA); |
99 | |||
100 | if (PageUptodate(page)) | ||
101 | goto no_update; | ||
102 | |||
104 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); | 103 | zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE); |
105 | 104 | ||
106 | /* Copy the whole inline data block */ | 105 | /* Copy the whole inline data block */ |
107 | src_addr = inline_data_addr(ipage); | 106 | src_addr = inline_data_addr(dn->inode_page); |
108 | dst_addr = kmap(page); | 107 | dst_addr = kmap_atomic(page); |
109 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | 108 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); |
110 | kunmap(page); | 109 | flush_dcache_page(page); |
110 | kunmap_atomic(dst_addr); | ||
111 | SetPageUptodate(page); | 111 | SetPageUptodate(page); |
112 | no_update: | ||
113 | /* clear dirty state */ | ||
114 | dirty = clear_page_dirty_for_io(page); | ||
112 | 115 | ||
113 | /* write data page to try to make data consistent */ | 116 | /* write data page to try to make data consistent */ |
114 | set_page_writeback(page); | 117 | set_page_writeback(page); |
115 | write_data_page(page, &dn, &new_blk_addr, &fio); | 118 | |
116 | update_extent_cache(new_blk_addr, &dn); | 119 | write_data_page(page, dn, &new_blk_addr, &fio); |
120 | update_extent_cache(new_blk_addr, dn); | ||
117 | f2fs_wait_on_page_writeback(page, DATA); | 121 | f2fs_wait_on_page_writeback(page, DATA); |
122 | if (dirty) | ||
123 | inode_dec_dirty_pages(dn->inode); | ||
118 | 124 | ||
119 | /* clear inline data and flag after data writeback */ | 125 | /* this converted inline_data should be recovered. */ |
120 | zero_user_segment(ipage, INLINE_DATA_OFFSET, | 126 | set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE); |
121 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | ||
122 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
123 | stat_dec_inline_inode(inode); | ||
124 | 127 | ||
125 | sync_inode_page(&dn); | 128 | /* clear inline data and flag after data writeback */ |
126 | f2fs_put_dnode(&dn); | 129 | truncate_inline_data(dn->inode_page, 0); |
127 | out: | 130 | clear_out: |
128 | f2fs_unlock_op(sbi); | 131 | stat_dec_inline_inode(dn->inode); |
129 | return err; | 132 | f2fs_clear_inline_inode(dn->inode); |
133 | sync_inode_page(dn); | ||
134 | f2fs_put_dnode(dn); | ||
135 | return 0; | ||
130 | } | 136 | } |
131 | 137 | ||
132 | int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size, | 138 | int f2fs_convert_inline_inode(struct inode *inode) |
133 | struct page *page) | ||
134 | { | 139 | { |
135 | struct page *new_page = page; | 140 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
136 | int err; | 141 | struct dnode_of_data dn; |
142 | struct page *ipage, *page; | ||
143 | int err = 0; | ||
137 | 144 | ||
138 | if (!f2fs_has_inline_data(inode)) | 145 | page = grab_cache_page(inode->i_mapping, 0); |
139 | return 0; | 146 | if (!page) |
140 | else if (to_size <= MAX_INLINE_DATA) | 147 | return -ENOMEM; |
141 | return 0; | 148 | |
149 | f2fs_lock_op(sbi); | ||
142 | 150 | ||
143 | if (!page || page->index != 0) { | 151 | ipage = get_node_page(sbi, inode->i_ino); |
144 | new_page = grab_cache_page(inode->i_mapping, 0); | 152 | if (IS_ERR(ipage)) { |
145 | if (!new_page) | 153 | err = PTR_ERR(ipage); |
146 | return -ENOMEM; | 154 | goto out; |
147 | } | 155 | } |
148 | 156 | ||
149 | err = __f2fs_convert_inline_data(inode, new_page); | 157 | set_new_dnode(&dn, inode, ipage, ipage, 0); |
150 | if (!page || page->index != 0) | 158 | |
151 | f2fs_put_page(new_page, 1); | 159 | if (f2fs_has_inline_data(inode)) |
160 | err = f2fs_convert_inline_page(&dn, page); | ||
161 | |||
162 | f2fs_put_dnode(&dn); | ||
163 | out: | ||
164 | f2fs_unlock_op(sbi); | ||
165 | |||
166 | f2fs_put_page(page, 1); | ||
152 | return err; | 167 | return err; |
153 | } | 168 | } |
154 | 169 | ||
155 | int f2fs_write_inline_data(struct inode *inode, | 170 | int f2fs_write_inline_data(struct inode *inode, struct page *page) |
156 | struct page *page, unsigned size) | ||
157 | { | 171 | { |
158 | void *src_addr, *dst_addr; | 172 | void *src_addr, *dst_addr; |
159 | struct page *ipage; | ||
160 | struct dnode_of_data dn; | 173 | struct dnode_of_data dn; |
161 | int err; | 174 | int err; |
162 | 175 | ||
@@ -164,47 +177,39 @@ int f2fs_write_inline_data(struct inode *inode, | |||
164 | err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); | 177 | err = get_dnode_of_data(&dn, 0, LOOKUP_NODE); |
165 | if (err) | 178 | if (err) |
166 | return err; | 179 | return err; |
167 | ipage = dn.inode_page; | ||
168 | 180 | ||
169 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
170 | zero_user_segment(ipage, INLINE_DATA_OFFSET, | ||
171 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | ||
172 | src_addr = kmap(page); | ||
173 | dst_addr = inline_data_addr(ipage); | ||
174 | memcpy(dst_addr, src_addr, size); | ||
175 | kunmap(page); | ||
176 | |||
177 | /* Release the first data block if it is allocated */ | ||
178 | if (!f2fs_has_inline_data(inode)) { | 181 | if (!f2fs_has_inline_data(inode)) { |
179 | truncate_data_blocks_range(&dn, 1); | 182 | f2fs_put_dnode(&dn); |
180 | set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | 183 | return -EAGAIN; |
181 | stat_inc_inline_inode(inode); | ||
182 | } | 184 | } |
183 | 185 | ||
186 | f2fs_bug_on(F2FS_I_SB(inode), page->index); | ||
187 | |||
188 | f2fs_wait_on_page_writeback(dn.inode_page, NODE); | ||
189 | src_addr = kmap_atomic(page); | ||
190 | dst_addr = inline_data_addr(dn.inode_page); | ||
191 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | ||
192 | kunmap_atomic(src_addr); | ||
193 | |||
184 | set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); | 194 | set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); |
195 | set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); | ||
196 | |||
185 | sync_inode_page(&dn); | 197 | sync_inode_page(&dn); |
186 | f2fs_put_dnode(&dn); | 198 | f2fs_put_dnode(&dn); |
187 | |||
188 | return 0; | 199 | return 0; |
189 | } | 200 | } |
190 | 201 | ||
191 | void truncate_inline_data(struct inode *inode, u64 from) | 202 | void truncate_inline_data(struct page *ipage, u64 from) |
192 | { | 203 | { |
193 | struct page *ipage; | 204 | void *addr; |
194 | 205 | ||
195 | if (from >= MAX_INLINE_DATA) | 206 | if (from >= MAX_INLINE_DATA) |
196 | return; | 207 | return; |
197 | 208 | ||
198 | ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); | ||
199 | if (IS_ERR(ipage)) | ||
200 | return; | ||
201 | |||
202 | f2fs_wait_on_page_writeback(ipage, NODE); | 209 | f2fs_wait_on_page_writeback(ipage, NODE); |
203 | 210 | ||
204 | zero_user_segment(ipage, INLINE_DATA_OFFSET + from, | 211 | addr = inline_data_addr(ipage); |
205 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | 212 | memset(addr + from, 0, MAX_INLINE_DATA - from); |
206 | set_page_dirty(ipage); | ||
207 | f2fs_put_page(ipage, 1); | ||
208 | } | 213 | } |
209 | 214 | ||
210 | bool recover_inline_data(struct inode *inode, struct page *npage) | 215 | bool recover_inline_data(struct inode *inode, struct page *npage) |
@@ -236,6 +241,10 @@ process_inline: | |||
236 | src_addr = inline_data_addr(npage); | 241 | src_addr = inline_data_addr(npage); |
237 | dst_addr = inline_data_addr(ipage); | 242 | dst_addr = inline_data_addr(ipage); |
238 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); | 243 | memcpy(dst_addr, src_addr, MAX_INLINE_DATA); |
244 | |||
245 | set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
246 | set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); | ||
247 | |||
239 | update_inode(inode, ipage); | 248 | update_inode(inode, ipage); |
240 | f2fs_put_page(ipage, 1); | 249 | f2fs_put_page(ipage, 1); |
241 | return true; | 250 | return true; |
@@ -244,16 +253,279 @@ process_inline: | |||
244 | if (f2fs_has_inline_data(inode)) { | 253 | if (f2fs_has_inline_data(inode)) { |
245 | ipage = get_node_page(sbi, inode->i_ino); | 254 | ipage = get_node_page(sbi, inode->i_ino); |
246 | f2fs_bug_on(sbi, IS_ERR(ipage)); | 255 | f2fs_bug_on(sbi, IS_ERR(ipage)); |
247 | f2fs_wait_on_page_writeback(ipage, NODE); | 256 | truncate_inline_data(ipage, 0); |
248 | zero_user_segment(ipage, INLINE_DATA_OFFSET, | 257 | f2fs_clear_inline_inode(inode); |
249 | INLINE_DATA_OFFSET + MAX_INLINE_DATA); | ||
250 | clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
251 | update_inode(inode, ipage); | 258 | update_inode(inode, ipage); |
252 | f2fs_put_page(ipage, 1); | 259 | f2fs_put_page(ipage, 1); |
253 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { | 260 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { |
254 | truncate_blocks(inode, 0, false); | 261 | truncate_blocks(inode, 0, false); |
255 | set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); | ||
256 | goto process_inline; | 262 | goto process_inline; |
257 | } | 263 | } |
258 | return false; | 264 | return false; |
259 | } | 265 | } |
266 | |||
267 | struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, | ||
268 | struct qstr *name, struct page **res_page) | ||
269 | { | ||
270 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); | ||
271 | struct f2fs_inline_dentry *inline_dentry; | ||
272 | struct f2fs_dir_entry *de; | ||
273 | struct f2fs_dentry_ptr d; | ||
274 | struct page *ipage; | ||
275 | |||
276 | ipage = get_node_page(sbi, dir->i_ino); | ||
277 | if (IS_ERR(ipage)) | ||
278 | return NULL; | ||
279 | |||
280 | inline_dentry = inline_data_addr(ipage); | ||
281 | |||
282 | make_dentry_ptr(&d, (void *)inline_dentry, 2); | ||
283 | de = find_target_dentry(name, NULL, &d); | ||
284 | |||
285 | unlock_page(ipage); | ||
286 | if (de) | ||
287 | *res_page = ipage; | ||
288 | else | ||
289 | f2fs_put_page(ipage, 0); | ||
290 | |||
291 | /* | ||
292 | * For the most part, it should be a bug when name_len is zero. | ||
293 | * We stop here for figuring out where the bugs has occurred. | ||
294 | */ | ||
295 | f2fs_bug_on(sbi, d.max < 0); | ||
296 | return de; | ||
297 | } | ||
298 | |||
299 | struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir, | ||
300 | struct page **p) | ||
301 | { | ||
302 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | ||
303 | struct page *ipage; | ||
304 | struct f2fs_dir_entry *de; | ||
305 | struct f2fs_inline_dentry *dentry_blk; | ||
306 | |||
307 | ipage = get_node_page(sbi, dir->i_ino); | ||
308 | if (IS_ERR(ipage)) | ||
309 | return NULL; | ||
310 | |||
311 | dentry_blk = inline_data_addr(ipage); | ||
312 | de = &dentry_blk->dentry[1]; | ||
313 | *p = ipage; | ||
314 | unlock_page(ipage); | ||
315 | return de; | ||
316 | } | ||
317 | |||
318 | int make_empty_inline_dir(struct inode *inode, struct inode *parent, | ||
319 | struct page *ipage) | ||
320 | { | ||
321 | struct f2fs_inline_dentry *dentry_blk; | ||
322 | struct f2fs_dentry_ptr d; | ||
323 | |||
324 | dentry_blk = inline_data_addr(ipage); | ||
325 | |||
326 | make_dentry_ptr(&d, (void *)dentry_blk, 2); | ||
327 | do_make_empty_dir(inode, parent, &d); | ||
328 | |||
329 | set_page_dirty(ipage); | ||
330 | |||
331 | /* update i_size to MAX_INLINE_DATA */ | ||
332 | if (i_size_read(inode) < MAX_INLINE_DATA) { | ||
333 | i_size_write(inode, MAX_INLINE_DATA); | ||
334 | set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); | ||
335 | } | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, | ||
340 | struct f2fs_inline_dentry *inline_dentry) | ||
341 | { | ||
342 | struct page *page; | ||
343 | struct dnode_of_data dn; | ||
344 | struct f2fs_dentry_block *dentry_blk; | ||
345 | int err; | ||
346 | |||
347 | page = grab_cache_page(dir->i_mapping, 0); | ||
348 | if (!page) | ||
349 | return -ENOMEM; | ||
350 | |||
351 | set_new_dnode(&dn, dir, ipage, NULL, 0); | ||
352 | err = f2fs_reserve_block(&dn, 0); | ||
353 | if (err) | ||
354 | goto out; | ||
355 | |||
356 | f2fs_wait_on_page_writeback(page, DATA); | ||
357 | zero_user_segment(page, 0, PAGE_CACHE_SIZE); | ||
358 | |||
359 | dentry_blk = kmap_atomic(page); | ||
360 | |||
361 | /* copy data from inline dentry block to new dentry block */ | ||
362 | memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, | ||
363 | INLINE_DENTRY_BITMAP_SIZE); | ||
364 | memcpy(dentry_blk->dentry, inline_dentry->dentry, | ||
365 | sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY); | ||
366 | memcpy(dentry_blk->filename, inline_dentry->filename, | ||
367 | NR_INLINE_DENTRY * F2FS_SLOT_LEN); | ||
368 | |||
369 | kunmap_atomic(dentry_blk); | ||
370 | SetPageUptodate(page); | ||
371 | set_page_dirty(page); | ||
372 | |||
373 | /* clear inline dir and flag after data writeback */ | ||
374 | truncate_inline_data(ipage, 0); | ||
375 | |||
376 | stat_dec_inline_dir(dir); | ||
377 | clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); | ||
378 | |||
379 | if (i_size_read(dir) < PAGE_CACHE_SIZE) { | ||
380 | i_size_write(dir, PAGE_CACHE_SIZE); | ||
381 | set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); | ||
382 | } | ||
383 | |||
384 | sync_inode_page(&dn); | ||
385 | out: | ||
386 | f2fs_put_page(page, 1); | ||
387 | return err; | ||
388 | } | ||
389 | |||
390 | int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, | ||
391 | struct inode *inode) | ||
392 | { | ||
393 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | ||
394 | struct page *ipage; | ||
395 | unsigned int bit_pos; | ||
396 | f2fs_hash_t name_hash; | ||
397 | struct f2fs_dir_entry *de; | ||
398 | size_t namelen = name->len; | ||
399 | struct f2fs_inline_dentry *dentry_blk = NULL; | ||
400 | int slots = GET_DENTRY_SLOTS(namelen); | ||
401 | struct page *page; | ||
402 | int err = 0; | ||
403 | int i; | ||
404 | |||
405 | name_hash = f2fs_dentry_hash(name); | ||
406 | |||
407 | ipage = get_node_page(sbi, dir->i_ino); | ||
408 | if (IS_ERR(ipage)) | ||
409 | return PTR_ERR(ipage); | ||
410 | |||
411 | dentry_blk = inline_data_addr(ipage); | ||
412 | bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, | ||
413 | slots, NR_INLINE_DENTRY); | ||
414 | if (bit_pos >= NR_INLINE_DENTRY) { | ||
415 | err = f2fs_convert_inline_dir(dir, ipage, dentry_blk); | ||
416 | if (!err) | ||
417 | err = -EAGAIN; | ||
418 | goto out; | ||
419 | } | ||
420 | |||
421 | down_write(&F2FS_I(inode)->i_sem); | ||
422 | page = init_inode_metadata(inode, dir, name, ipage); | ||
423 | if (IS_ERR(page)) { | ||
424 | err = PTR_ERR(page); | ||
425 | goto fail; | ||
426 | } | ||
427 | |||
428 | f2fs_wait_on_page_writeback(ipage, NODE); | ||
429 | de = &dentry_blk->dentry[bit_pos]; | ||
430 | de->hash_code = name_hash; | ||
431 | de->name_len = cpu_to_le16(namelen); | ||
432 | memcpy(dentry_blk->filename[bit_pos], name->name, name->len); | ||
433 | de->ino = cpu_to_le32(inode->i_ino); | ||
434 | set_de_type(de, inode); | ||
435 | for (i = 0; i < slots; i++) | ||
436 | test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); | ||
437 | set_page_dirty(ipage); | ||
438 | |||
439 | /* we don't need to mark_inode_dirty now */ | ||
440 | F2FS_I(inode)->i_pino = dir->i_ino; | ||
441 | update_inode(inode, page); | ||
442 | f2fs_put_page(page, 1); | ||
443 | |||
444 | update_parent_metadata(dir, inode, 0); | ||
445 | fail: | ||
446 | up_write(&F2FS_I(inode)->i_sem); | ||
447 | |||
448 | if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { | ||
449 | update_inode(dir, ipage); | ||
450 | clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); | ||
451 | } | ||
452 | out: | ||
453 | f2fs_put_page(ipage, 1); | ||
454 | return err; | ||
455 | } | ||
456 | |||
457 | void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, | ||
458 | struct inode *dir, struct inode *inode) | ||
459 | { | ||
460 | struct f2fs_inline_dentry *inline_dentry; | ||
461 | int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); | ||
462 | unsigned int bit_pos; | ||
463 | int i; | ||
464 | |||
465 | lock_page(page); | ||
466 | f2fs_wait_on_page_writeback(page, NODE); | ||
467 | |||
468 | inline_dentry = inline_data_addr(page); | ||
469 | bit_pos = dentry - inline_dentry->dentry; | ||
470 | for (i = 0; i < slots; i++) | ||
471 | test_and_clear_bit_le(bit_pos + i, | ||
472 | &inline_dentry->dentry_bitmap); | ||
473 | |||
474 | set_page_dirty(page); | ||
475 | |||
476 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | ||
477 | |||
478 | if (inode) | ||
479 | f2fs_drop_nlink(dir, inode, page); | ||
480 | |||
481 | f2fs_put_page(page, 1); | ||
482 | } | ||
483 | |||
484 | bool f2fs_empty_inline_dir(struct inode *dir) | ||
485 | { | ||
486 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | ||
487 | struct page *ipage; | ||
488 | unsigned int bit_pos = 2; | ||
489 | struct f2fs_inline_dentry *dentry_blk; | ||
490 | |||
491 | ipage = get_node_page(sbi, dir->i_ino); | ||
492 | if (IS_ERR(ipage)) | ||
493 | return false; | ||
494 | |||
495 | dentry_blk = inline_data_addr(ipage); | ||
496 | bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, | ||
497 | NR_INLINE_DENTRY, | ||
498 | bit_pos); | ||
499 | |||
500 | f2fs_put_page(ipage, 1); | ||
501 | |||
502 | if (bit_pos < NR_INLINE_DENTRY) | ||
503 | return false; | ||
504 | |||
505 | return true; | ||
506 | } | ||
507 | |||
508 | int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) | ||
509 | { | ||
510 | struct inode *inode = file_inode(file); | ||
511 | struct f2fs_inline_dentry *inline_dentry = NULL; | ||
512 | struct page *ipage = NULL; | ||
513 | struct f2fs_dentry_ptr d; | ||
514 | |||
515 | if (ctx->pos == NR_INLINE_DENTRY) | ||
516 | return 0; | ||
517 | |||
518 | ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); | ||
519 | if (IS_ERR(ipage)) | ||
520 | return PTR_ERR(ipage); | ||
521 | |||
522 | inline_dentry = inline_data_addr(ipage); | ||
523 | |||
524 | make_dentry_ptr(&d, (void *)inline_dentry, 2); | ||
525 | |||
526 | if (!f2fs_fill_dentries(ctx, &d, 0)) | ||
527 | ctx->pos = NR_INLINE_DENTRY; | ||
528 | |||
529 | f2fs_put_page(ipage, 1); | ||
530 | return 0; | ||
531 | } | ||