diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-10-14 02:26:14 +0200 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-11-04 01:07:32 +0100 |
commit | 4e6ebf6d493591403237400e94e6fc17b7cb1c62 (patch) | |
tree | e30734430c725f81f60f079c8cb7bee8d729d0ad /fs/f2fs/dir.c | |
parent | f2fs: reuse room_for_filename for inline dentry operation (diff) | |
download | linux-4e6ebf6d493591403237400e94e6fc17b7cb1c62.tar.xz linux-4e6ebf6d493591403237400e94e6fc17b7cb1c62.zip |
f2fs: reuse find_in_block code for find_in_inline_dir
This patch removes redundant copied code in find_in_inline_dir.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/dir.c')
-rw-r--r-- | fs/f2fs/dir.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 164c6c911bf8..0b97b1921504 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level, return bidx; } -bool early_match_name(size_t namelen, f2fs_hash_t namehash, +static bool early_match_name(size_t namelen, f2fs_hash_t namehash, struct f2fs_dir_entry *de) { if (le16_to_cpu(de->name_len) != namelen) @@ -90,49 +90,69 @@ bool early_match_name(size_t namelen, f2fs_hash_t namehash, } static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, - struct qstr *name, int *max_slots, - f2fs_hash_t namehash, struct page **res_page) + struct qstr *name, int *max_slots, + struct page **res_page) +{ + struct f2fs_dentry_block *dentry_blk; + struct f2fs_dir_entry *de; + + *max_slots = NR_DENTRY_IN_BLOCK; + + dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page); + de = find_target_dentry(name, max_slots, &dentry_blk->dentry_bitmap, + dentry_blk->dentry, + dentry_blk->filename); + if (de) + *res_page = dentry_page; + else + kunmap(dentry_page); + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs has occurred. + */ + f2fs_bug_on(F2FS_P_SB(dentry_page), *max_slots < 0); + return de; +} + +struct f2fs_dir_entry *find_target_dentry(struct qstr *name, int *max_slots, + const void *bitmap, struct f2fs_dir_entry *dentry, + __u8 (*filenames)[F2FS_SLOT_LEN]) { struct f2fs_dir_entry *de; unsigned long bit_pos = 0; - struct f2fs_dentry_block *dentry_blk = kmap(dentry_page); - const void *dentry_bits = &dentry_blk->dentry_bitmap; + f2fs_hash_t namehash = f2fs_dentry_hash(name); + int max_bits = *max_slots; int max_len = 0; - while (bit_pos < NR_DENTRY_IN_BLOCK) { - if (!test_bit_le(bit_pos, dentry_bits)) { + *max_slots = 0; + while (bit_pos < max_bits) { + if (!test_bit_le(bit_pos, bitmap)) { if (bit_pos == 0) max_len = 1; - else if (!test_bit_le(bit_pos - 1, dentry_bits)) + else if (!test_bit_le(bit_pos - 1, bitmap)) max_len++; bit_pos++; continue; } - de = &dentry_blk->dentry[bit_pos]; - if (early_match_name(name->len, namehash, de)) { - if (!memcmp(dentry_blk->filename[bit_pos], - name->name, - name->len)) { - *res_page = dentry_page; - goto found; - } - } - if (max_len > *max_slots) { + de = &dentry[bit_pos]; + if (early_match_name(name->len, namehash, de) && + !memcmp(filenames[bit_pos], name->name, name->len)) + goto found; + + if (*max_slots >= 0 && max_len > *max_slots) { *max_slots = max_len; max_len = 0; } - /* - * For the most part, it should be a bug when name_len is zero. - * We stop here for figuring out where the bugs has occurred. - */ - f2fs_bug_on(F2FS_P_SB(dentry_page), !de->name_len); + /* remain bug on condition */ + if (unlikely(!de->name_len)) + *max_slots = -1; bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); } de = NULL; - kunmap(dentry_page); found: if (max_len > *max_slots) *max_slots = max_len; @@ -149,7 +169,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, struct page *dentry_page; struct f2fs_dir_entry *de = NULL; bool room = false; - int max_slots = 0; + int max_slots; f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH); @@ -168,8 +188,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, continue; } - de = find_in_block(dentry_page, name, &max_slots, - namehash, res_page); + de = find_in_block(dentry_page, name, &max_slots, res_page); if (de) break; |