.. | .. |
---|
8 | 8 | |
---|
9 | 9 | #include <linux/fs.h> |
---|
10 | 10 | #include <linux/f2fs_fs.h> |
---|
| 11 | +#include <linux/fiemap.h> |
---|
11 | 12 | |
---|
12 | 13 | #include "f2fs.h" |
---|
13 | 14 | #include "node.h" |
---|
| 15 | +#include <trace/events/f2fs.h> |
---|
14 | 16 | #include <trace/events/android_fs.h> |
---|
15 | 17 | |
---|
16 | | -bool f2fs_may_inline_data(struct inode *inode) |
---|
| 18 | +static bool support_inline_data(struct inode *inode) |
---|
17 | 19 | { |
---|
18 | 20 | if (f2fs_is_atomic_file(inode)) |
---|
19 | 21 | return false; |
---|
20 | | - |
---|
21 | 22 | if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) |
---|
22 | 23 | return false; |
---|
23 | | - |
---|
24 | 24 | if (i_size_read(inode) > MAX_INLINE_DATA(inode)) |
---|
25 | 25 | return false; |
---|
| 26 | + return true; |
---|
| 27 | +} |
---|
26 | 28 | |
---|
27 | | - if (f2fs_post_read_required(inode)) |
---|
| 29 | +bool f2fs_may_inline_data(struct inode *inode) |
---|
| 30 | +{ |
---|
| 31 | + if (!support_inline_data(inode)) |
---|
28 | 32 | return false; |
---|
29 | 33 | |
---|
30 | | - return true; |
---|
| 34 | + return !f2fs_post_read_required(inode); |
---|
| 35 | +} |
---|
| 36 | + |
---|
| 37 | +bool f2fs_sanity_check_inline_data(struct inode *inode) |
---|
| 38 | +{ |
---|
| 39 | + if (!f2fs_has_inline_data(inode)) |
---|
| 40 | + return false; |
---|
| 41 | + |
---|
| 42 | + if (!support_inline_data(inode)) |
---|
| 43 | + return true; |
---|
| 44 | + |
---|
| 45 | + /* |
---|
| 46 | + * used by sanity_check_inode(), when disk layout fields has not |
---|
| 47 | + * been synchronized to inmem fields. |
---|
| 48 | + */ |
---|
| 49 | + return (S_ISREG(inode->i_mode) && |
---|
| 50 | + (file_is_encrypt(inode) || file_is_verity(inode) || |
---|
| 51 | + (F2FS_I(inode)->i_flags & F2FS_COMPR_FL))); |
---|
31 | 52 | } |
---|
32 | 53 | |
---|
33 | 54 | bool f2fs_may_inline_dentry(struct inode *inode) |
---|
.. | .. |
---|
44 | 65 | void f2fs_do_read_inline_data(struct page *page, struct page *ipage) |
---|
45 | 66 | { |
---|
46 | 67 | struct inode *inode = page->mapping->host; |
---|
47 | | - void *src_addr, *dst_addr; |
---|
48 | 68 | |
---|
49 | 69 | if (PageUptodate(page)) |
---|
50 | 70 | return; |
---|
.. | .. |
---|
54 | 74 | zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE); |
---|
55 | 75 | |
---|
56 | 76 | /* Copy the whole inline data block */ |
---|
57 | | - src_addr = inline_data_addr(inode, ipage); |
---|
58 | | - dst_addr = kmap_atomic(page); |
---|
59 | | - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); |
---|
60 | | - flush_dcache_page(page); |
---|
61 | | - kunmap_atomic(dst_addr); |
---|
| 77 | + memcpy_to_page(page, 0, inline_data_addr(inode, ipage), |
---|
| 78 | + MAX_INLINE_DATA(inode)); |
---|
62 | 79 | if (!PageUptodate(page)) |
---|
63 | 80 | SetPageUptodate(page); |
---|
64 | 81 | } |
---|
.. | .. |
---|
147 | 164 | if (err) |
---|
148 | 165 | return err; |
---|
149 | 166 | |
---|
150 | | - err = f2fs_get_node_info(fio.sbi, dn->nid, &ni); |
---|
| 167 | + err = f2fs_get_node_info(fio.sbi, dn->nid, &ni, false); |
---|
151 | 168 | if (err) { |
---|
152 | 169 | f2fs_truncate_data_blocks_range(dn, 1); |
---|
153 | 170 | f2fs_put_dnode(dn); |
---|
.. | .. |
---|
189 | 206 | |
---|
190 | 207 | /* clear inline data and flag after data writeback */ |
---|
191 | 208 | f2fs_truncate_inline_inode(dn->inode, dn->inode_page, 0); |
---|
192 | | - clear_inline_node(dn->inode_page); |
---|
| 209 | + clear_page_private_inline(dn->inode_page); |
---|
193 | 210 | clear_out: |
---|
194 | 211 | stat_dec_inline_inode(dn->inode); |
---|
195 | 212 | clear_inode_flag(dn->inode, FI_INLINE_DATA); |
---|
.. | .. |
---|
204 | 221 | struct page *ipage, *page; |
---|
205 | 222 | int err = 0; |
---|
206 | 223 | |
---|
207 | | - if (!f2fs_has_inline_data(inode)) |
---|
| 224 | + if (!f2fs_has_inline_data(inode) || |
---|
| 225 | + f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) |
---|
208 | 226 | return 0; |
---|
209 | 227 | |
---|
210 | 228 | err = dquot_initialize(inode); |
---|
.. | .. |
---|
242 | 260 | |
---|
243 | 261 | int f2fs_write_inline_data(struct inode *inode, struct page *page) |
---|
244 | 262 | { |
---|
245 | | - void *src_addr, *dst_addr; |
---|
246 | 263 | struct dnode_of_data dn; |
---|
247 | 264 | int err; |
---|
248 | 265 | |
---|
.. | .. |
---|
259 | 276 | f2fs_bug_on(F2FS_I_SB(inode), page->index); |
---|
260 | 277 | |
---|
261 | 278 | f2fs_wait_on_page_writeback(dn.inode_page, NODE, true, true); |
---|
262 | | - src_addr = kmap_atomic(page); |
---|
263 | | - dst_addr = inline_data_addr(inode, dn.inode_page); |
---|
264 | | - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); |
---|
265 | | - kunmap_atomic(src_addr); |
---|
| 279 | + memcpy_from_page(inline_data_addr(inode, dn.inode_page), |
---|
| 280 | + page, 0, MAX_INLINE_DATA(inode)); |
---|
266 | 281 | set_page_dirty(dn.inode_page); |
---|
267 | 282 | |
---|
268 | | - f2fs_clear_radix_tree_dirty_tag(page); |
---|
| 283 | + f2fs_clear_page_cache_dirty_tag(page); |
---|
269 | 284 | |
---|
270 | 285 | set_inode_flag(inode, FI_APPEND_WRITE); |
---|
271 | 286 | set_inode_flag(inode, FI_DATA_EXIST); |
---|
272 | 287 | |
---|
273 | | - clear_inline_node(dn.inode_page); |
---|
| 288 | + clear_page_private_inline(dn.inode_page); |
---|
274 | 289 | f2fs_put_dnode(&dn); |
---|
275 | 290 | return 0; |
---|
276 | 291 | } |
---|
.. | .. |
---|
287 | 302 | * [prev.] [next] of inline_data flag |
---|
288 | 303 | * o o -> recover inline_data |
---|
289 | 304 | * o x -> remove inline_data, and then recover data blocks |
---|
290 | | - * x o -> remove inline_data, and then recover inline_data |
---|
| 305 | + * x o -> remove data blocks, and then recover inline_data |
---|
291 | 306 | * x x -> recover data blocks |
---|
292 | 307 | */ |
---|
293 | 308 | if (IS_INODE(npage)) |
---|
.. | .. |
---|
319 | 334 | if (IS_ERR(ipage)) |
---|
320 | 335 | return PTR_ERR(ipage); |
---|
321 | 336 | f2fs_truncate_inline_inode(inode, ipage, 0); |
---|
| 337 | + stat_dec_inline_inode(inode); |
---|
322 | 338 | clear_inode_flag(inode, FI_INLINE_DATA); |
---|
323 | 339 | f2fs_put_page(ipage, 1); |
---|
324 | 340 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { |
---|
.. | .. |
---|
327 | 343 | ret = f2fs_truncate_blocks(inode, 0, false); |
---|
328 | 344 | if (ret) |
---|
329 | 345 | return ret; |
---|
| 346 | + stat_inc_inline_inode(inode); |
---|
330 | 347 | goto process_inline; |
---|
331 | 348 | } |
---|
332 | 349 | return 0; |
---|
.. | .. |
---|
353 | 370 | make_dentry_ptr_inline(dir, &d, inline_dentry); |
---|
354 | 371 | de = f2fs_find_target_dentry(&d, fname, NULL); |
---|
355 | 372 | unlock_page(ipage); |
---|
| 373 | + if (IS_ERR(de)) { |
---|
| 374 | + *res_page = ERR_CAST(de); |
---|
| 375 | + de = NULL; |
---|
| 376 | + } |
---|
356 | 377 | if (de) |
---|
357 | 378 | *res_page = ipage; |
---|
358 | 379 | else |
---|
.. | .. |
---|
417 | 438 | |
---|
418 | 439 | dentry_blk = page_address(page); |
---|
419 | 440 | |
---|
| 441 | + /* |
---|
| 442 | + * Start by zeroing the full block, to ensure that all unused space is |
---|
| 443 | + * zeroed and no uninitialized memory is leaked to disk. |
---|
| 444 | + */ |
---|
| 445 | + memset(dentry_blk, 0, F2FS_BLKSIZE); |
---|
| 446 | + |
---|
420 | 447 | make_dentry_ptr_inline(dir, &src, inline_dentry); |
---|
421 | 448 | make_dentry_ptr_block(dir, &dst, dentry_blk); |
---|
422 | 449 | |
---|
423 | 450 | /* copy data from inline dentry block to new dentry block */ |
---|
424 | 451 | memcpy(dst.bitmap, src.bitmap, src.nr_bitmap); |
---|
425 | | - memset(dst.bitmap + src.nr_bitmap, 0, dst.nr_bitmap - src.nr_bitmap); |
---|
426 | | - /* |
---|
427 | | - * we do not need to zero out remainder part of dentry and filename |
---|
428 | | - * field, since we have used bitmap for marking the usage status of |
---|
429 | | - * them, besides, we can also ignore copying/zeroing reserved space |
---|
430 | | - * of dentry block, because them haven't been used so far. |
---|
431 | | - */ |
---|
432 | 452 | memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max); |
---|
433 | 453 | memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN); |
---|
434 | 454 | |
---|
.. | .. |
---|
545 | 565 | !f2fs_has_inline_xattr(dir)) |
---|
546 | 566 | F2FS_I(dir)->i_inline_xattr_size = 0; |
---|
547 | 567 | |
---|
548 | | - kvfree(backup_dentry); |
---|
| 568 | + kfree(backup_dentry); |
---|
549 | 569 | return 0; |
---|
550 | 570 | recover: |
---|
551 | 571 | lock_page(ipage); |
---|
.. | .. |
---|
556 | 576 | set_page_dirty(ipage); |
---|
557 | 577 | f2fs_put_page(ipage, 1); |
---|
558 | 578 | |
---|
559 | | - kvfree(backup_dentry); |
---|
| 579 | + kfree(backup_dentry); |
---|
560 | 580 | return err; |
---|
561 | 581 | } |
---|
562 | 582 | |
---|
.. | .. |
---|
638 | 658 | } |
---|
639 | 659 | |
---|
640 | 660 | if (inode) { |
---|
641 | | - down_write(&F2FS_I(inode)->i_sem); |
---|
| 661 | + f2fs_down_write(&F2FS_I(inode)->i_sem); |
---|
642 | 662 | page = f2fs_init_inode_metadata(inode, dir, fname, ipage); |
---|
643 | 663 | if (IS_ERR(page)) { |
---|
644 | 664 | err = PTR_ERR(page); |
---|
.. | .. |
---|
667 | 687 | f2fs_update_parent_metadata(dir, inode, 0); |
---|
668 | 688 | fail: |
---|
669 | 689 | if (inode) |
---|
670 | | - up_write(&F2FS_I(inode)->i_sem); |
---|
| 690 | + f2fs_up_write(&F2FS_I(inode)->i_sem); |
---|
671 | 691 | out: |
---|
672 | 692 | f2fs_put_page(ipage, 1); |
---|
673 | 693 | return err; |
---|
.. | .. |
---|
795 | 815 | ilen = start + len; |
---|
796 | 816 | ilen -= start; |
---|
797 | 817 | |
---|
798 | | - err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); |
---|
| 818 | + err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false); |
---|
799 | 819 | if (err) |
---|
800 | 820 | goto out; |
---|
801 | 821 | |
---|
.. | .. |
---|
803 | 823 | byteaddr += (char *)inline_data_addr(inode, ipage) - |
---|
804 | 824 | (char *)F2FS_INODE(ipage); |
---|
805 | 825 | err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags); |
---|
| 826 | + trace_f2fs_fiemap(inode, start, byteaddr, ilen, flags, err); |
---|
806 | 827 | out: |
---|
807 | 828 | f2fs_put_page(ipage, 1); |
---|
808 | 829 | return err; |
---|