diff options
Diffstat (limited to 'fs/f2fs/inline.c')
-rw-r--r-- | fs/f2fs/inline.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 1484c00133cd..8140e4f0e538 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
@@ -21,7 +21,7 @@ bool f2fs_may_inline(struct inode *inode) | |||
21 | if (f2fs_is_atomic_file(inode)) | 21 | if (f2fs_is_atomic_file(inode)) |
22 | return false; | 22 | return false; |
23 | 23 | ||
24 | if (!S_ISREG(inode->i_mode)) | 24 | if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) |
25 | return false; | 25 | return false; |
26 | 26 | ||
27 | if (i_size_read(inode) > MAX_INLINE_DATA) | 27 | if (i_size_read(inode) > MAX_INLINE_DATA) |
@@ -50,10 +50,19 @@ void read_inline_data(struct page *page, struct page *ipage) | |||
50 | SetPageUptodate(page); | 50 | SetPageUptodate(page); |
51 | } | 51 | } |
52 | 52 | ||
53 | static void truncate_inline_data(struct page *ipage) | 53 | bool truncate_inline_inode(struct page *ipage, u64 from) |
54 | { | 54 | { |
55 | void *addr; | ||
56 | |||
57 | if (from >= MAX_INLINE_DATA) | ||
58 | return false; | ||
59 | |||
60 | addr = inline_data_addr(ipage); | ||
61 | |||
55 | f2fs_wait_on_page_writeback(ipage, NODE); | 62 | f2fs_wait_on_page_writeback(ipage, NODE); |
56 | memset(inline_data_addr(ipage), 0, MAX_INLINE_DATA); | 63 | memset(addr + from, 0, MAX_INLINE_DATA - from); |
64 | |||
65 | return true; | ||
57 | } | 66 | } |
58 | 67 | ||
59 | int f2fs_read_inline_data(struct inode *inode, struct page *page) | 68 | int f2fs_read_inline_data(struct inode *inode, struct page *page) |
@@ -122,7 +131,8 @@ no_update: | |||
122 | set_page_writeback(page); | 131 | set_page_writeback(page); |
123 | fio.blk_addr = dn->data_blkaddr; | 132 | fio.blk_addr = dn->data_blkaddr; |
124 | write_data_page(page, dn, &fio); | 133 | write_data_page(page, dn, &fio); |
125 | update_extent_cache(dn); | 134 | set_data_blkaddr(dn); |
135 | f2fs_update_extent_cache(dn); | ||
126 | f2fs_wait_on_page_writeback(page, DATA); | 136 | f2fs_wait_on_page_writeback(page, DATA); |
127 | if (dirty) | 137 | if (dirty) |
128 | inode_dec_dirty_pages(dn->inode); | 138 | inode_dec_dirty_pages(dn->inode); |
@@ -131,7 +141,7 @@ no_update: | |||
131 | set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE); | 141 | set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE); |
132 | 142 | ||
133 | /* clear inline data and flag after data writeback */ | 143 | /* clear inline data and flag after data writeback */ |
134 | truncate_inline_data(dn->inode_page); | 144 | truncate_inline_inode(dn->inode_page, 0); |
135 | clear_out: | 145 | clear_out: |
136 | stat_dec_inline_inode(dn->inode); | 146 | stat_dec_inline_inode(dn->inode); |
137 | f2fs_clear_inline_inode(dn->inode); | 147 | f2fs_clear_inline_inode(dn->inode); |
@@ -245,7 +255,7 @@ process_inline: | |||
245 | if (f2fs_has_inline_data(inode)) { | 255 | if (f2fs_has_inline_data(inode)) { |
246 | ipage = get_node_page(sbi, inode->i_ino); | 256 | ipage = get_node_page(sbi, inode->i_ino); |
247 | f2fs_bug_on(sbi, IS_ERR(ipage)); | 257 | f2fs_bug_on(sbi, IS_ERR(ipage)); |
248 | truncate_inline_data(ipage); | 258 | truncate_inline_inode(ipage, 0); |
249 | f2fs_clear_inline_inode(inode); | 259 | f2fs_clear_inline_inode(inode); |
250 | update_inode(inode, ipage); | 260 | update_inode(inode, ipage); |
251 | f2fs_put_page(ipage, 1); | 261 | f2fs_put_page(ipage, 1); |
@@ -363,7 +373,7 @@ static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, | |||
363 | set_page_dirty(page); | 373 | set_page_dirty(page); |
364 | 374 | ||
365 | /* clear inline dir and flag after data writeback */ | 375 | /* clear inline dir and flag after data writeback */ |
366 | truncate_inline_data(ipage); | 376 | truncate_inline_inode(ipage, 0); |
367 | 377 | ||
368 | stat_dec_inline_dir(dir); | 378 | stat_dec_inline_dir(dir); |
369 | clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); | 379 | clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); |
@@ -380,21 +390,18 @@ out: | |||
380 | } | 390 | } |
381 | 391 | ||
382 | int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, | 392 | int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, |
383 | struct inode *inode) | 393 | struct inode *inode, nid_t ino, umode_t mode) |
384 | { | 394 | { |
385 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | 395 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
386 | struct page *ipage; | 396 | struct page *ipage; |
387 | unsigned int bit_pos; | 397 | unsigned int bit_pos; |
388 | f2fs_hash_t name_hash; | 398 | f2fs_hash_t name_hash; |
389 | struct f2fs_dir_entry *de; | ||
390 | size_t namelen = name->len; | 399 | size_t namelen = name->len; |
391 | struct f2fs_inline_dentry *dentry_blk = NULL; | 400 | struct f2fs_inline_dentry *dentry_blk = NULL; |
401 | struct f2fs_dentry_ptr d; | ||
392 | int slots = GET_DENTRY_SLOTS(namelen); | 402 | int slots = GET_DENTRY_SLOTS(namelen); |
393 | struct page *page; | 403 | struct page *page = NULL; |
394 | int err = 0; | 404 | int err = 0; |
395 | int i; | ||
396 | |||
397 | name_hash = f2fs_dentry_hash(name); | ||
398 | 405 | ||
399 | ipage = get_node_page(sbi, dir->i_ino); | 406 | ipage = get_node_page(sbi, dir->i_ino); |
400 | if (IS_ERR(ipage)) | 407 | if (IS_ERR(ipage)) |
@@ -410,32 +417,34 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, | |||
410 | goto out; | 417 | goto out; |
411 | } | 418 | } |
412 | 419 | ||
413 | down_write(&F2FS_I(inode)->i_sem); | 420 | if (inode) { |
414 | page = init_inode_metadata(inode, dir, name, ipage); | 421 | down_write(&F2FS_I(inode)->i_sem); |
415 | if (IS_ERR(page)) { | 422 | page = init_inode_metadata(inode, dir, name, ipage); |
416 | err = PTR_ERR(page); | 423 | if (IS_ERR(page)) { |
417 | goto fail; | 424 | err = PTR_ERR(page); |
425 | goto fail; | ||
426 | } | ||
418 | } | 427 | } |
419 | 428 | ||
420 | f2fs_wait_on_page_writeback(ipage, NODE); | 429 | f2fs_wait_on_page_writeback(ipage, NODE); |
421 | de = &dentry_blk->dentry[bit_pos]; | 430 | |
422 | de->hash_code = name_hash; | 431 | name_hash = f2fs_dentry_hash(name); |
423 | de->name_len = cpu_to_le16(namelen); | 432 | make_dentry_ptr(&d, (void *)dentry_blk, 2); |
424 | memcpy(dentry_blk->filename[bit_pos], name->name, name->len); | 433 | f2fs_update_dentry(ino, mode, &d, name, name_hash, bit_pos); |
425 | de->ino = cpu_to_le32(inode->i_ino); | 434 | |
426 | set_de_type(de, inode); | ||
427 | for (i = 0; i < slots; i++) | ||
428 | test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); | ||
429 | set_page_dirty(ipage); | 435 | set_page_dirty(ipage); |
430 | 436 | ||
431 | /* we don't need to mark_inode_dirty now */ | 437 | /* we don't need to mark_inode_dirty now */ |
432 | F2FS_I(inode)->i_pino = dir->i_ino; | 438 | if (inode) { |
433 | update_inode(inode, page); | 439 | F2FS_I(inode)->i_pino = dir->i_ino; |
434 | f2fs_put_page(page, 1); | 440 | update_inode(inode, page); |
441 | f2fs_put_page(page, 1); | ||
442 | } | ||
435 | 443 | ||
436 | update_parent_metadata(dir, inode, 0); | 444 | update_parent_metadata(dir, inode, 0); |
437 | fail: | 445 | fail: |
438 | up_write(&F2FS_I(inode)->i_sem); | 446 | if (inode) |
447 | up_write(&F2FS_I(inode)->i_sem); | ||
439 | 448 | ||
440 | if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { | 449 | if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { |
441 | update_inode(dir, ipage); | 450 | update_inode(dir, ipage); |