diff options
author | Chao Yu <chao2.yu@samsung.com> | 2014-09-24 06:17:04 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-11-03 19:07:31 -0500 |
commit | dbeacf02ebfed8161ac0b9379892262593c9a734 (patch) | |
tree | 5d4dcd8a7ea6bd0fe38d7402246f2e83dac6715d /fs/f2fs | |
parent | 5efd3c6f1be9cfbc621c9445cedd159998ed3ea6 (diff) |
f2fs: export dir operations for inline dir
This patch exports some dir operations for inline dir, additionally introduces
f2fs_drop_nlink from f2fs_delete_entry for reusing by inline dir function.
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/dir.c | 71 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 10 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 4 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 2 |
4 files changed, 50 insertions, 37 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index b54f87149c09..99e944e1dd01 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -37,7 +37,7 @@ static unsigned int bucket_blocks(unsigned int level) | |||
37 | return 4; | 37 | return 4; |
38 | } | 38 | } |
39 | 39 | ||
40 | static unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { | 40 | unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { |
41 | [F2FS_FT_UNKNOWN] = DT_UNKNOWN, | 41 | [F2FS_FT_UNKNOWN] = DT_UNKNOWN, |
42 | [F2FS_FT_REG_FILE] = DT_REG, | 42 | [F2FS_FT_REG_FILE] = DT_REG, |
43 | [F2FS_FT_DIR] = DT_DIR, | 43 | [F2FS_FT_DIR] = DT_DIR, |
@@ -59,7 +59,7 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { | |||
59 | [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, | 59 | [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) | 62 | void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) |
63 | { | 63 | { |
64 | umode_t mode = inode->i_mode; | 64 | umode_t mode = inode->i_mode; |
65 | de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; | 65 | de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; |
@@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level, | |||
77 | return bidx; | 77 | return bidx; |
78 | } | 78 | } |
79 | 79 | ||
80 | static bool early_match_name(size_t namelen, f2fs_hash_t namehash, | 80 | bool early_match_name(size_t namelen, f2fs_hash_t namehash, |
81 | struct f2fs_dir_entry *de) | 81 | struct f2fs_dir_entry *de) |
82 | { | 82 | { |
83 | if (le16_to_cpu(de->name_len) != namelen) | 83 | if (le16_to_cpu(de->name_len) != namelen) |
@@ -307,7 +307,6 @@ static int make_empty_dir(struct inode *inode, | |||
307 | if (IS_ERR(dentry_page)) | 307 | if (IS_ERR(dentry_page)) |
308 | return PTR_ERR(dentry_page); | 308 | return PTR_ERR(dentry_page); |
309 | 309 | ||
310 | |||
311 | dentry_blk = kmap_atomic(dentry_page); | 310 | dentry_blk = kmap_atomic(dentry_page); |
312 | 311 | ||
313 | de = &dentry_blk->dentry[0]; | 312 | de = &dentry_blk->dentry[0]; |
@@ -333,7 +332,7 @@ static int make_empty_dir(struct inode *inode, | |||
333 | return 0; | 332 | return 0; |
334 | } | 333 | } |
335 | 334 | ||
336 | static struct page *init_inode_metadata(struct inode *inode, | 335 | struct page *init_inode_metadata(struct inode *inode, |
337 | struct inode *dir, const struct qstr *name) | 336 | struct inode *dir, const struct qstr *name) |
338 | { | 337 | { |
339 | struct page *page; | 338 | struct page *page; |
@@ -395,7 +394,7 @@ error: | |||
395 | return ERR_PTR(err); | 394 | return ERR_PTR(err); |
396 | } | 395 | } |
397 | 396 | ||
398 | static void update_parent_metadata(struct inode *dir, struct inode *inode, | 397 | void update_parent_metadata(struct inode *dir, struct inode *inode, |
399 | unsigned int current_depth) | 398 | unsigned int current_depth) |
400 | { | 399 | { |
401 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { | 400 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { |
@@ -560,16 +559,44 @@ fail: | |||
560 | return err; | 559 | return err; |
561 | } | 560 | } |
562 | 561 | ||
562 | void f2fs_drop_nlink(struct inode *dir, struct inode *inode, struct page *page) | ||
563 | { | ||
564 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | ||
565 | |||
566 | down_write(&F2FS_I(inode)->i_sem); | ||
567 | |||
568 | if (S_ISDIR(inode->i_mode)) { | ||
569 | drop_nlink(dir); | ||
570 | if (page) | ||
571 | update_inode(dir, page); | ||
572 | else | ||
573 | update_inode_page(dir); | ||
574 | } | ||
575 | inode->i_ctime = CURRENT_TIME; | ||
576 | |||
577 | drop_nlink(inode); | ||
578 | if (S_ISDIR(inode->i_mode)) { | ||
579 | drop_nlink(inode); | ||
580 | i_size_write(inode, 0); | ||
581 | } | ||
582 | up_write(&F2FS_I(inode)->i_sem); | ||
583 | update_inode_page(inode); | ||
584 | |||
585 | if (inode->i_nlink == 0) | ||
586 | add_orphan_inode(sbi, inode->i_ino); | ||
587 | else | ||
588 | release_orphan_inode(sbi); | ||
589 | } | ||
590 | |||
563 | /* | 591 | /* |
564 | * It only removes the dentry from the dentry page, corresponding name | 592 | * It only removes the dentry from the dentry page, corresponding name |
565 | * entry in name page does not need to be touched during deletion. | 593 | * entry in name page does not need to be touched during deletion. |
566 | */ | 594 | */ |
567 | void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | 595 | void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, |
568 | struct inode *inode) | 596 | struct inode *dir, struct inode *inode) |
569 | { | 597 | { |
570 | struct f2fs_dentry_block *dentry_blk; | 598 | struct f2fs_dentry_block *dentry_blk; |
571 | unsigned int bit_pos; | 599 | unsigned int bit_pos; |
572 | struct inode *dir = page->mapping->host; | ||
573 | int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); | 600 | int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); |
574 | int i; | 601 | int i; |
575 | 602 | ||
@@ -590,29 +617,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
590 | 617 | ||
591 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 618 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
592 | 619 | ||
593 | if (inode) { | 620 | if (inode) |
594 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | 621 | f2fs_drop_nlink(dir, inode, NULL); |
595 | |||
596 | down_write(&F2FS_I(inode)->i_sem); | ||
597 | |||
598 | if (S_ISDIR(inode->i_mode)) { | ||
599 | drop_nlink(dir); | ||
600 | update_inode_page(dir); | ||
601 | } | ||
602 | inode->i_ctime = CURRENT_TIME; | ||
603 | drop_nlink(inode); | ||
604 | if (S_ISDIR(inode->i_mode)) { | ||
605 | drop_nlink(inode); | ||
606 | i_size_write(inode, 0); | ||
607 | } | ||
608 | up_write(&F2FS_I(inode)->i_sem); | ||
609 | update_inode_page(inode); | ||
610 | |||
611 | if (inode->i_nlink == 0) | ||
612 | add_orphan_inode(sbi, inode->i_ino); | ||
613 | else | ||
614 | release_orphan_inode(sbi); | ||
615 | } | ||
616 | 622 | ||
617 | if (bit_pos == NR_DENTRY_IN_BLOCK) { | 623 | if (bit_pos == NR_DENTRY_IN_BLOCK) { |
618 | truncate_hole(dir, page->index, page->index + 1); | 624 | truncate_hole(dir, page->index, page->index + 1); |
@@ -628,7 +634,7 @@ bool f2fs_empty_dir(struct inode *dir) | |||
628 | unsigned long bidx; | 634 | unsigned long bidx; |
629 | struct page *dentry_page; | 635 | struct page *dentry_page; |
630 | unsigned int bit_pos; | 636 | unsigned int bit_pos; |
631 | struct f2fs_dentry_block *dentry_blk; | 637 | struct f2fs_dentry_block *dentry_blk; |
632 | unsigned long nblock = dir_blocks(dir); | 638 | unsigned long nblock = dir_blocks(dir); |
633 | 639 | ||
634 | for (bidx = 0; bidx < nblock; bidx++) { | 640 | for (bidx = 0; bidx < nblock; bidx++) { |
@@ -640,7 +646,6 @@ bool f2fs_empty_dir(struct inode *dir) | |||
640 | return false; | 646 | return false; |
641 | } | 647 | } |
642 | 648 | ||
643 | |||
644 | dentry_blk = kmap_atomic(dentry_page); | 649 | dentry_blk = kmap_atomic(dentry_page); |
645 | if (bidx == 0) | 650 | if (bidx == 0) |
646 | bit_pos = 2; | 651 | bit_pos = 2; |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4fa0df5f54ea..97d90ed1d67b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1242,6 +1242,13 @@ struct dentry *f2fs_get_parent(struct dentry *child); | |||
1242 | /* | 1242 | /* |
1243 | * dir.c | 1243 | * dir.c |
1244 | */ | 1244 | */ |
1245 | extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; | ||
1246 | bool early_match_name(size_t, f2fs_hash_t, struct f2fs_dir_entry *); | ||
1247 | void set_de_type(struct f2fs_dir_entry *, struct inode *); | ||
1248 | struct page *init_inode_metadata(struct inode *, struct inode *, | ||
1249 | const struct qstr *); | ||
1250 | void update_parent_metadata(struct inode *, struct inode *, unsigned int); | ||
1251 | void f2fs_drop_nlink(struct inode *, struct inode *, struct page *); | ||
1245 | struct f2fs_dir_entry *f2fs_find_entry(struct inode *, struct qstr *, | 1252 | struct f2fs_dir_entry *f2fs_find_entry(struct inode *, struct qstr *, |
1246 | struct page **); | 1253 | struct page **); |
1247 | struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **); | 1254 | struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **); |
@@ -1250,7 +1257,8 @@ void f2fs_set_link(struct inode *, struct f2fs_dir_entry *, | |||
1250 | struct page *, struct inode *); | 1257 | struct page *, struct inode *); |
1251 | int update_dent_inode(struct inode *, const struct qstr *); | 1258 | int update_dent_inode(struct inode *, const struct qstr *); |
1252 | int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *); | 1259 | int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *); |
1253 | void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *); | 1260 | void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *, |
1261 | struct inode *); | ||
1254 | int f2fs_do_tmpfile(struct inode *, struct inode *); | 1262 | int f2fs_do_tmpfile(struct inode *, struct inode *); |
1255 | int f2fs_make_empty(struct inode *, struct inode *); | 1263 | int f2fs_make_empty(struct inode *, struct inode *); |
1256 | bool f2fs_empty_dir(struct inode *); | 1264 | bool f2fs_empty_dir(struct inode *); |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 0d2526e5aa11..6e67f2b6fce1 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -223,7 +223,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) | |||
223 | f2fs_put_page(page, 0); | 223 | f2fs_put_page(page, 0); |
224 | goto fail; | 224 | goto fail; |
225 | } | 225 | } |
226 | f2fs_delete_entry(de, page, inode); | 226 | f2fs_delete_entry(de, page, dir, inode); |
227 | f2fs_unlock_op(sbi); | 227 | f2fs_unlock_op(sbi); |
228 | 228 | ||
229 | /* In order to evict this inode, we set it dirty */ | 229 | /* In order to evict this inode, we set it dirty */ |
@@ -435,7 +435,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
435 | old_inode->i_ctime = CURRENT_TIME; | 435 | old_inode->i_ctime = CURRENT_TIME; |
436 | mark_inode_dirty(old_inode); | 436 | mark_inode_dirty(old_inode); |
437 | 437 | ||
438 | f2fs_delete_entry(old_entry, old_page, NULL); | 438 | f2fs_delete_entry(old_entry, old_page, old_dir, NULL); |
439 | 439 | ||
440 | if (old_dir_entry) { | 440 | if (old_dir_entry) { |
441 | if (old_dir != new_dir) { | 441 | if (old_dir != new_dir) { |
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index ebd013225788..843da53ed7d5 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -111,7 +111,7 @@ retry: | |||
111 | iput(einode); | 111 | iput(einode); |
112 | goto out_unmap_put; | 112 | goto out_unmap_put; |
113 | } | 113 | } |
114 | f2fs_delete_entry(de, page, einode); | 114 | f2fs_delete_entry(de, page, dir, einode); |
115 | iput(einode); | 115 | iput(einode); |
116 | goto retry; | 116 | goto retry; |
117 | } | 117 | } |