static struct f2fs_dir_entry *find_in_level(struct inode *dir, unsigned int level, const char *name, size_t namelen, f2fs_hash_t namehash, struct page **res_page) { int s = GET_DENTRY_SLOTS(namelen); unsigned int nbucket, nblock; unsigned int bidx, end_block; struct page *dentry_page; struct f2fs_dir_entry *de = NULL; struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); bool room = false; int max_slots = 0; f2fs_bug_on(level > MAX_DIR_HASH_DEPTH); nbucket = dir_buckets(level); nblock = bucket_blocks(level); bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket); end_block = bidx + nblock; for (; bidx < end_block; bidx++) { bool nocase = false; /* no need to allocate new dentry pages to all the indices */ dentry_page = find_data_page(dir, bidx, true); if (IS_ERR(dentry_page)) { room = true; continue; } if (test_opt(sbi, ANDROID_EMU) && (sbi->android_emu_flags & F2FS_ANDROID_EMU_NOCASE) && F2FS_I(dir)->i_advise & FADVISE_ANDROID_EMU) nocase = true; de = find_in_block(dentry_page, name, namelen, &max_slots, namehash, res_page, nocase); if (de) break; if (max_slots >= s) room = true; f2fs_put_page(dentry_page, 0); } if (!de && room && F2FS_I(dir)->chash != namehash) { F2FS_I(dir)->chash = namehash; F2FS_I(dir)->clevel = level; } return de; }
static struct f2fs_dir_entry *find_in_level(struct inode *dir, unsigned int level, struct qstr *name, f2fs_hash_t namehash, struct page **res_page, unsigned int flags) { int s = GET_DENTRY_SLOTS(name->len); unsigned int nbucket, nblock; unsigned int bidx, end_block; struct page *dentry_page; struct f2fs_dir_entry *de = NULL; bool room = false; int max_slots; f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH); nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); nblock = bucket_blocks(level); bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, le32_to_cpu(namehash) % nbucket); end_block = bidx + nblock; for (; bidx < end_block; bidx++) { /* no need to allocate new dentry pages to all the indices */ dentry_page = find_data_page(dir, bidx, true); if (IS_ERR(dentry_page)) { room = true; continue; } de = find_in_block(dentry_page, name, &max_slots, res_page, flags); if (de) break; if (max_slots >= s) room = true; f2fs_put_page(dentry_page, 0); } if (!de && room && F2FS_I(dir)->chash != namehash) { F2FS_I(dir)->chash = namehash; F2FS_I(dir)->clevel = level; } return de; }