162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * fs/f2fs/dir.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2012 Samsung Electronics Co., Ltd. 662306a36Sopenharmony_ci * http://www.samsung.com/ 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <asm/unaligned.h> 962306a36Sopenharmony_ci#include <linux/fs.h> 1062306a36Sopenharmony_ci#include <linux/f2fs_fs.h> 1162306a36Sopenharmony_ci#include <linux/sched/signal.h> 1262306a36Sopenharmony_ci#include <linux/unicode.h> 1362306a36Sopenharmony_ci#include "f2fs.h" 1462306a36Sopenharmony_ci#include "node.h" 1562306a36Sopenharmony_ci#include "acl.h" 1662306a36Sopenharmony_ci#include "xattr.h" 1762306a36Sopenharmony_ci#include <trace/events/f2fs.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE) 2062306a36Sopenharmony_ciextern struct kmem_cache *f2fs_cf_name_slab; 2162306a36Sopenharmony_ci#endif 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic unsigned long dir_blocks(struct inode *inode) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci return ((unsigned long long) (i_size_read(inode) + PAGE_SIZE - 1)) 2662306a36Sopenharmony_ci >> PAGE_SHIFT; 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic unsigned int dir_buckets(unsigned int level, int dir_level) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci if (level + dir_level < MAX_DIR_HASH_DEPTH / 2) 3262306a36Sopenharmony_ci return BIT(level + dir_level); 3362306a36Sopenharmony_ci else 3462306a36Sopenharmony_ci return MAX_DIR_BUCKETS; 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic unsigned int bucket_blocks(unsigned int level) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci if (level < MAX_DIR_HASH_DEPTH / 2) 4062306a36Sopenharmony_ci return 2; 4162306a36Sopenharmony_ci else 4262306a36Sopenharmony_ci return 4; 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* If @dir is casefolded, initialize @fname->cf_name from @fname->usr_fname. */ 4662306a36Sopenharmony_ciint f2fs_init_casefolded_name(const struct inode *dir, 4762306a36Sopenharmony_ci struct f2fs_filename *fname) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE) 5062306a36Sopenharmony_ci struct super_block *sb = dir->i_sb; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (IS_CASEFOLDED(dir) && 5362306a36Sopenharmony_ci !is_dot_dotdot(fname->usr_fname->name, fname->usr_fname->len)) { 5462306a36Sopenharmony_ci fname->cf_name.name = f2fs_kmem_cache_alloc(f2fs_cf_name_slab, 5562306a36Sopenharmony_ci GFP_NOFS, false, F2FS_SB(sb)); 5662306a36Sopenharmony_ci if (!fname->cf_name.name) 5762306a36Sopenharmony_ci return -ENOMEM; 5862306a36Sopenharmony_ci fname->cf_name.len = utf8_casefold(sb->s_encoding, 5962306a36Sopenharmony_ci fname->usr_fname, 6062306a36Sopenharmony_ci fname->cf_name.name, 6162306a36Sopenharmony_ci F2FS_NAME_LEN); 6262306a36Sopenharmony_ci if ((int)fname->cf_name.len <= 0) { 6362306a36Sopenharmony_ci kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); 6462306a36Sopenharmony_ci fname->cf_name.name = NULL; 6562306a36Sopenharmony_ci if (sb_has_strict_encoding(sb)) 6662306a36Sopenharmony_ci return -EINVAL; 6762306a36Sopenharmony_ci /* fall back to treating name as opaque byte sequence */ 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci#endif 7162306a36Sopenharmony_ci return 0; 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic int __f2fs_setup_filename(const struct inode *dir, 7562306a36Sopenharmony_ci const struct fscrypt_name *crypt_name, 7662306a36Sopenharmony_ci struct f2fs_filename *fname) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci int err; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci memset(fname, 0, sizeof(*fname)); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci fname->usr_fname = crypt_name->usr_fname; 8362306a36Sopenharmony_ci fname->disk_name = crypt_name->disk_name; 8462306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION 8562306a36Sopenharmony_ci fname->crypto_buf = crypt_name->crypto_buf; 8662306a36Sopenharmony_ci#endif 8762306a36Sopenharmony_ci if (crypt_name->is_nokey_name) { 8862306a36Sopenharmony_ci /* hash was decoded from the no-key name */ 8962306a36Sopenharmony_ci fname->hash = cpu_to_le32(crypt_name->hash); 9062306a36Sopenharmony_ci } else { 9162306a36Sopenharmony_ci err = f2fs_init_casefolded_name(dir, fname); 9262306a36Sopenharmony_ci if (err) { 9362306a36Sopenharmony_ci f2fs_free_filename(fname); 9462306a36Sopenharmony_ci return err; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci f2fs_hash_filename(dir, fname); 9762306a36Sopenharmony_ci } 9862306a36Sopenharmony_ci return 0; 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* 10262306a36Sopenharmony_ci * Prepare to search for @iname in @dir. This is similar to 10362306a36Sopenharmony_ci * fscrypt_setup_filename(), but this also handles computing the casefolded name 10462306a36Sopenharmony_ci * and the f2fs dirhash if needed, then packing all the information about this 10562306a36Sopenharmony_ci * filename up into a 'struct f2fs_filename'. 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_ciint f2fs_setup_filename(struct inode *dir, const struct qstr *iname, 10862306a36Sopenharmony_ci int lookup, struct f2fs_filename *fname) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci struct fscrypt_name crypt_name; 11162306a36Sopenharmony_ci int err; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci err = fscrypt_setup_filename(dir, iname, lookup, &crypt_name); 11462306a36Sopenharmony_ci if (err) 11562306a36Sopenharmony_ci return err; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci return __f2fs_setup_filename(dir, &crypt_name, fname); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* 12162306a36Sopenharmony_ci * Prepare to look up @dentry in @dir. This is similar to 12262306a36Sopenharmony_ci * fscrypt_prepare_lookup(), but this also handles computing the casefolded name 12362306a36Sopenharmony_ci * and the f2fs dirhash if needed, then packing all the information about this 12462306a36Sopenharmony_ci * filename up into a 'struct f2fs_filename'. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ciint f2fs_prepare_lookup(struct inode *dir, struct dentry *dentry, 12762306a36Sopenharmony_ci struct f2fs_filename *fname) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci struct fscrypt_name crypt_name; 13062306a36Sopenharmony_ci int err; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci err = fscrypt_prepare_lookup(dir, dentry, &crypt_name); 13362306a36Sopenharmony_ci if (err) 13462306a36Sopenharmony_ci return err; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci return __f2fs_setup_filename(dir, &crypt_name, fname); 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_civoid f2fs_free_filename(struct f2fs_filename *fname) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION 14262306a36Sopenharmony_ci kfree(fname->crypto_buf.name); 14362306a36Sopenharmony_ci fname->crypto_buf.name = NULL; 14462306a36Sopenharmony_ci#endif 14562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE) 14662306a36Sopenharmony_ci if (fname->cf_name.name) { 14762306a36Sopenharmony_ci kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); 14862306a36Sopenharmony_ci fname->cf_name.name = NULL; 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci#endif 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic unsigned long dir_block_index(unsigned int level, 15462306a36Sopenharmony_ci int dir_level, unsigned int idx) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci unsigned long i; 15762306a36Sopenharmony_ci unsigned long bidx = 0; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci for (i = 0; i < level; i++) 16062306a36Sopenharmony_ci bidx += dir_buckets(i, dir_level) * bucket_blocks(i); 16162306a36Sopenharmony_ci bidx += idx * bucket_blocks(level); 16262306a36Sopenharmony_ci return bidx; 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic struct f2fs_dir_entry *find_in_block(struct inode *dir, 16662306a36Sopenharmony_ci struct page *dentry_page, 16762306a36Sopenharmony_ci const struct f2fs_filename *fname, 16862306a36Sopenharmony_ci int *max_slots) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk; 17162306a36Sopenharmony_ci struct f2fs_dentry_ptr d; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci make_dentry_ptr_block(dir, &d, dentry_blk); 17662306a36Sopenharmony_ci return f2fs_find_target_dentry(&d, fname, max_slots); 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE) 18062306a36Sopenharmony_ci/* 18162306a36Sopenharmony_ci * Test whether a case-insensitive directory entry matches the filename 18262306a36Sopenharmony_ci * being searched for. 18362306a36Sopenharmony_ci * 18462306a36Sopenharmony_ci * Returns 1 for a match, 0 for no match, and -errno on an error. 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_cistatic int f2fs_match_ci_name(const struct inode *dir, const struct qstr *name, 18762306a36Sopenharmony_ci const u8 *de_name, u32 de_name_len) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci const struct super_block *sb = dir->i_sb; 19062306a36Sopenharmony_ci const struct unicode_map *um = sb->s_encoding; 19162306a36Sopenharmony_ci struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len); 19262306a36Sopenharmony_ci struct qstr entry = QSTR_INIT(de_name, de_name_len); 19362306a36Sopenharmony_ci int res; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci if (IS_ENCRYPTED(dir)) { 19662306a36Sopenharmony_ci const struct fscrypt_str encrypted_name = 19762306a36Sopenharmony_ci FSTR_INIT((u8 *)de_name, de_name_len); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if (WARN_ON_ONCE(!fscrypt_has_encryption_key(dir))) 20062306a36Sopenharmony_ci return -EINVAL; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL); 20362306a36Sopenharmony_ci if (!decrypted_name.name) 20462306a36Sopenharmony_ci return -ENOMEM; 20562306a36Sopenharmony_ci res = fscrypt_fname_disk_to_usr(dir, 0, 0, &encrypted_name, 20662306a36Sopenharmony_ci &decrypted_name); 20762306a36Sopenharmony_ci if (res < 0) 20862306a36Sopenharmony_ci goto out; 20962306a36Sopenharmony_ci entry.name = decrypted_name.name; 21062306a36Sopenharmony_ci entry.len = decrypted_name.len; 21162306a36Sopenharmony_ci } 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci res = utf8_strncasecmp_folded(um, name, &entry); 21462306a36Sopenharmony_ci /* 21562306a36Sopenharmony_ci * In strict mode, ignore invalid names. In non-strict mode, 21662306a36Sopenharmony_ci * fall back to treating them as opaque byte sequences. 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ci if (res < 0 && !sb_has_strict_encoding(sb)) { 21962306a36Sopenharmony_ci res = name->len == entry.len && 22062306a36Sopenharmony_ci memcmp(name->name, entry.name, name->len) == 0; 22162306a36Sopenharmony_ci } else { 22262306a36Sopenharmony_ci /* utf8_strncasecmp_folded returns 0 on match */ 22362306a36Sopenharmony_ci res = (res == 0); 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ciout: 22662306a36Sopenharmony_ci kfree(decrypted_name.name); 22762306a36Sopenharmony_ci return res; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci#endif /* CONFIG_UNICODE */ 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic inline int f2fs_match_name(const struct inode *dir, 23262306a36Sopenharmony_ci const struct f2fs_filename *fname, 23362306a36Sopenharmony_ci const u8 *de_name, u32 de_name_len) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci struct fscrypt_name f; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNICODE) 23862306a36Sopenharmony_ci if (fname->cf_name.name) { 23962306a36Sopenharmony_ci struct qstr cf = FSTR_TO_QSTR(&fname->cf_name); 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci return f2fs_match_ci_name(dir, &cf, de_name, de_name_len); 24262306a36Sopenharmony_ci } 24362306a36Sopenharmony_ci#endif 24462306a36Sopenharmony_ci f.usr_fname = fname->usr_fname; 24562306a36Sopenharmony_ci f.disk_name = fname->disk_name; 24662306a36Sopenharmony_ci#ifdef CONFIG_FS_ENCRYPTION 24762306a36Sopenharmony_ci f.crypto_buf = fname->crypto_buf; 24862306a36Sopenharmony_ci#endif 24962306a36Sopenharmony_ci return fscrypt_match_name(&f, de_name, de_name_len); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, 25362306a36Sopenharmony_ci const struct f2fs_filename *fname, int *max_slots) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci struct f2fs_dir_entry *de; 25662306a36Sopenharmony_ci unsigned long bit_pos = 0; 25762306a36Sopenharmony_ci int max_len = 0; 25862306a36Sopenharmony_ci int res = 0; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci if (max_slots) 26162306a36Sopenharmony_ci *max_slots = 0; 26262306a36Sopenharmony_ci while (bit_pos < d->max) { 26362306a36Sopenharmony_ci if (!test_bit_le(bit_pos, d->bitmap)) { 26462306a36Sopenharmony_ci bit_pos++; 26562306a36Sopenharmony_ci max_len++; 26662306a36Sopenharmony_ci continue; 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci de = &d->dentry[bit_pos]; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (unlikely(!de->name_len)) { 27262306a36Sopenharmony_ci bit_pos++; 27362306a36Sopenharmony_ci continue; 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci if (de->hash_code == fname->hash) { 27762306a36Sopenharmony_ci res = f2fs_match_name(d->inode, fname, 27862306a36Sopenharmony_ci d->filename[bit_pos], 27962306a36Sopenharmony_ci le16_to_cpu(de->name_len)); 28062306a36Sopenharmony_ci if (res < 0) 28162306a36Sopenharmony_ci return ERR_PTR(res); 28262306a36Sopenharmony_ci if (res) 28362306a36Sopenharmony_ci goto found; 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci if (max_slots && max_len > *max_slots) 28762306a36Sopenharmony_ci *max_slots = max_len; 28862306a36Sopenharmony_ci max_len = 0; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci de = NULL; 29462306a36Sopenharmony_cifound: 29562306a36Sopenharmony_ci if (max_slots && max_len > *max_slots) 29662306a36Sopenharmony_ci *max_slots = max_len; 29762306a36Sopenharmony_ci return de; 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic struct f2fs_dir_entry *find_in_level(struct inode *dir, 30162306a36Sopenharmony_ci unsigned int level, 30262306a36Sopenharmony_ci const struct f2fs_filename *fname, 30362306a36Sopenharmony_ci struct page **res_page) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci int s = GET_DENTRY_SLOTS(fname->disk_name.len); 30662306a36Sopenharmony_ci unsigned int nbucket, nblock; 30762306a36Sopenharmony_ci unsigned int bidx, end_block; 30862306a36Sopenharmony_ci struct page *dentry_page; 30962306a36Sopenharmony_ci struct f2fs_dir_entry *de = NULL; 31062306a36Sopenharmony_ci pgoff_t next_pgofs; 31162306a36Sopenharmony_ci bool room = false; 31262306a36Sopenharmony_ci int max_slots; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); 31562306a36Sopenharmony_ci nblock = bucket_blocks(level); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, 31862306a36Sopenharmony_ci le32_to_cpu(fname->hash) % nbucket); 31962306a36Sopenharmony_ci end_block = bidx + nblock; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci while (bidx < end_block) { 32262306a36Sopenharmony_ci /* no need to allocate new dentry pages to all the indices */ 32362306a36Sopenharmony_ci dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs); 32462306a36Sopenharmony_ci if (IS_ERR(dentry_page)) { 32562306a36Sopenharmony_ci if (PTR_ERR(dentry_page) == -ENOENT) { 32662306a36Sopenharmony_ci room = true; 32762306a36Sopenharmony_ci bidx = next_pgofs; 32862306a36Sopenharmony_ci continue; 32962306a36Sopenharmony_ci } else { 33062306a36Sopenharmony_ci *res_page = dentry_page; 33162306a36Sopenharmony_ci break; 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci de = find_in_block(dir, dentry_page, fname, &max_slots); 33662306a36Sopenharmony_ci if (IS_ERR(de)) { 33762306a36Sopenharmony_ci *res_page = ERR_CAST(de); 33862306a36Sopenharmony_ci de = NULL; 33962306a36Sopenharmony_ci break; 34062306a36Sopenharmony_ci } else if (de) { 34162306a36Sopenharmony_ci *res_page = dentry_page; 34262306a36Sopenharmony_ci break; 34362306a36Sopenharmony_ci } 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci if (max_slots >= s) 34662306a36Sopenharmony_ci room = true; 34762306a36Sopenharmony_ci f2fs_put_page(dentry_page, 0); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci bidx++; 35062306a36Sopenharmony_ci } 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci if (!de && room && F2FS_I(dir)->chash != fname->hash) { 35362306a36Sopenharmony_ci F2FS_I(dir)->chash = fname->hash; 35462306a36Sopenharmony_ci F2FS_I(dir)->clevel = level; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci return de; 35862306a36Sopenharmony_ci} 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_cistruct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, 36162306a36Sopenharmony_ci const struct f2fs_filename *fname, 36262306a36Sopenharmony_ci struct page **res_page) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci unsigned long npages = dir_blocks(dir); 36562306a36Sopenharmony_ci struct f2fs_dir_entry *de = NULL; 36662306a36Sopenharmony_ci unsigned int max_depth; 36762306a36Sopenharmony_ci unsigned int level; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci *res_page = NULL; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci if (f2fs_has_inline_dentry(dir)) { 37262306a36Sopenharmony_ci de = f2fs_find_in_inline_dir(dir, fname, res_page); 37362306a36Sopenharmony_ci goto out; 37462306a36Sopenharmony_ci } 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci if (npages == 0) 37762306a36Sopenharmony_ci goto out; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci max_depth = F2FS_I(dir)->i_current_depth; 38062306a36Sopenharmony_ci if (unlikely(max_depth > MAX_DIR_HASH_DEPTH)) { 38162306a36Sopenharmony_ci f2fs_warn(F2FS_I_SB(dir), "Corrupted max_depth of %lu: %u", 38262306a36Sopenharmony_ci dir->i_ino, max_depth); 38362306a36Sopenharmony_ci max_depth = MAX_DIR_HASH_DEPTH; 38462306a36Sopenharmony_ci f2fs_i_depth_write(dir, max_depth); 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci for (level = 0; level < max_depth; level++) { 38862306a36Sopenharmony_ci de = find_in_level(dir, level, fname, res_page); 38962306a36Sopenharmony_ci if (de || IS_ERR(*res_page)) 39062306a36Sopenharmony_ci break; 39162306a36Sopenharmony_ci } 39262306a36Sopenharmony_ciout: 39362306a36Sopenharmony_ci /* This is to increase the speed of f2fs_create */ 39462306a36Sopenharmony_ci if (!de) 39562306a36Sopenharmony_ci F2FS_I(dir)->task = current; 39662306a36Sopenharmony_ci return de; 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci/* 40062306a36Sopenharmony_ci * Find an entry in the specified directory with the wanted name. 40162306a36Sopenharmony_ci * It returns the page where the entry was found (as a parameter - res_page), 40262306a36Sopenharmony_ci * and the entry itself. Page is returned mapped and unlocked. 40362306a36Sopenharmony_ci * Entry is guaranteed to be valid. 40462306a36Sopenharmony_ci */ 40562306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, 40662306a36Sopenharmony_ci const struct qstr *child, struct page **res_page) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci struct f2fs_dir_entry *de = NULL; 40962306a36Sopenharmony_ci struct f2fs_filename fname; 41062306a36Sopenharmony_ci int err; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci err = f2fs_setup_filename(dir, child, 1, &fname); 41362306a36Sopenharmony_ci if (err) { 41462306a36Sopenharmony_ci if (err == -ENOENT) 41562306a36Sopenharmony_ci *res_page = NULL; 41662306a36Sopenharmony_ci else 41762306a36Sopenharmony_ci *res_page = ERR_PTR(err); 41862306a36Sopenharmony_ci return NULL; 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci de = __f2fs_find_entry(dir, &fname, res_page); 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci f2fs_free_filename(&fname); 42462306a36Sopenharmony_ci return de; 42562306a36Sopenharmony_ci} 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_cistruct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci return f2fs_find_entry(dir, &dotdot_name, p); 43062306a36Sopenharmony_ci} 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ciino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr, 43362306a36Sopenharmony_ci struct page **page) 43462306a36Sopenharmony_ci{ 43562306a36Sopenharmony_ci ino_t res = 0; 43662306a36Sopenharmony_ci struct f2fs_dir_entry *de; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci de = f2fs_find_entry(dir, qstr, page); 43962306a36Sopenharmony_ci if (de) { 44062306a36Sopenharmony_ci res = le32_to_cpu(de->ino); 44162306a36Sopenharmony_ci f2fs_put_page(*page, 0); 44262306a36Sopenharmony_ci } 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci return res; 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_civoid f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, 44862306a36Sopenharmony_ci struct page *page, struct inode *inode) 44962306a36Sopenharmony_ci{ 45062306a36Sopenharmony_ci enum page_type type = f2fs_has_inline_dentry(dir) ? NODE : DATA; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci lock_page(page); 45362306a36Sopenharmony_ci f2fs_wait_on_page_writeback(page, type, true, true); 45462306a36Sopenharmony_ci de->ino = cpu_to_le32(inode->i_ino); 45562306a36Sopenharmony_ci de->file_type = fs_umode_to_ftype(inode->i_mode); 45662306a36Sopenharmony_ci set_page_dirty(page); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci dir->i_mtime = inode_set_ctime_current(dir); 45962306a36Sopenharmony_ci f2fs_mark_inode_dirty_sync(dir, false); 46062306a36Sopenharmony_ci f2fs_put_page(page, 1); 46162306a36Sopenharmony_ci} 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_cistatic void init_dent_inode(struct inode *dir, struct inode *inode, 46462306a36Sopenharmony_ci const struct f2fs_filename *fname, 46562306a36Sopenharmony_ci struct page *ipage) 46662306a36Sopenharmony_ci{ 46762306a36Sopenharmony_ci struct f2fs_inode *ri; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci if (!fname) /* tmpfile case? */ 47062306a36Sopenharmony_ci return; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci f2fs_wait_on_page_writeback(ipage, NODE, true, true); 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci /* copy name info. to this inode page */ 47562306a36Sopenharmony_ci ri = F2FS_INODE(ipage); 47662306a36Sopenharmony_ci ri->i_namelen = cpu_to_le32(fname->disk_name.len); 47762306a36Sopenharmony_ci memcpy(ri->i_name, fname->disk_name.name, fname->disk_name.len); 47862306a36Sopenharmony_ci if (IS_ENCRYPTED(dir)) { 47962306a36Sopenharmony_ci file_set_enc_name(inode); 48062306a36Sopenharmony_ci /* 48162306a36Sopenharmony_ci * Roll-forward recovery doesn't have encryption keys available, 48262306a36Sopenharmony_ci * so it can't compute the dirhash for encrypted+casefolded 48362306a36Sopenharmony_ci * filenames. Append it to i_name if possible. Else, disable 48462306a36Sopenharmony_ci * roll-forward recovery of the dentry (i.e., make fsync'ing the 48562306a36Sopenharmony_ci * file force a checkpoint) by setting LOST_PINO. 48662306a36Sopenharmony_ci */ 48762306a36Sopenharmony_ci if (IS_CASEFOLDED(dir)) { 48862306a36Sopenharmony_ci if (fname->disk_name.len + sizeof(f2fs_hash_t) <= 48962306a36Sopenharmony_ci F2FS_NAME_LEN) 49062306a36Sopenharmony_ci put_unaligned(fname->hash, (f2fs_hash_t *) 49162306a36Sopenharmony_ci &ri->i_name[fname->disk_name.len]); 49262306a36Sopenharmony_ci else 49362306a36Sopenharmony_ci file_lost_pino(inode); 49462306a36Sopenharmony_ci } 49562306a36Sopenharmony_ci } 49662306a36Sopenharmony_ci set_page_dirty(ipage); 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_civoid f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent, 50062306a36Sopenharmony_ci struct f2fs_dentry_ptr *d) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci struct fscrypt_str dot = FSTR_INIT(".", 1); 50362306a36Sopenharmony_ci struct fscrypt_str dotdot = FSTR_INIT("..", 2); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci /* update dirent of "." */ 50662306a36Sopenharmony_ci f2fs_update_dentry(inode->i_ino, inode->i_mode, d, &dot, 0, 0); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci /* update dirent of ".." */ 50962306a36Sopenharmony_ci f2fs_update_dentry(parent->i_ino, parent->i_mode, d, &dotdot, 0, 1); 51062306a36Sopenharmony_ci} 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_cistatic int make_empty_dir(struct inode *inode, 51362306a36Sopenharmony_ci struct inode *parent, struct page *page) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci struct page *dentry_page; 51662306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk; 51762306a36Sopenharmony_ci struct f2fs_dentry_ptr d; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci if (f2fs_has_inline_dentry(inode)) 52062306a36Sopenharmony_ci return f2fs_make_empty_inline_dir(inode, parent, page); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci dentry_page = f2fs_get_new_data_page(inode, page, 0, true); 52362306a36Sopenharmony_ci if (IS_ERR(dentry_page)) 52462306a36Sopenharmony_ci return PTR_ERR(dentry_page); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci dentry_blk = page_address(dentry_page); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci make_dentry_ptr_block(NULL, &d, dentry_blk); 52962306a36Sopenharmony_ci f2fs_do_make_empty_dir(inode, parent, &d); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci set_page_dirty(dentry_page); 53262306a36Sopenharmony_ci f2fs_put_page(dentry_page, 1); 53362306a36Sopenharmony_ci return 0; 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistruct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir, 53762306a36Sopenharmony_ci const struct f2fs_filename *fname, struct page *dpage) 53862306a36Sopenharmony_ci{ 53962306a36Sopenharmony_ci struct page *page; 54062306a36Sopenharmony_ci int err; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_NEW_INODE)) { 54362306a36Sopenharmony_ci page = f2fs_new_inode_page(inode); 54462306a36Sopenharmony_ci if (IS_ERR(page)) 54562306a36Sopenharmony_ci return page; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) { 54862306a36Sopenharmony_ci /* in order to handle error case */ 54962306a36Sopenharmony_ci get_page(page); 55062306a36Sopenharmony_ci err = make_empty_dir(inode, dir, page); 55162306a36Sopenharmony_ci if (err) { 55262306a36Sopenharmony_ci lock_page(page); 55362306a36Sopenharmony_ci goto put_error; 55462306a36Sopenharmony_ci } 55562306a36Sopenharmony_ci put_page(page); 55662306a36Sopenharmony_ci } 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci err = f2fs_init_acl(inode, dir, page, dpage); 55962306a36Sopenharmony_ci if (err) 56062306a36Sopenharmony_ci goto put_error; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci err = f2fs_init_security(inode, dir, 56362306a36Sopenharmony_ci fname ? fname->usr_fname : NULL, page); 56462306a36Sopenharmony_ci if (err) 56562306a36Sopenharmony_ci goto put_error; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci if (IS_ENCRYPTED(inode)) { 56862306a36Sopenharmony_ci err = fscrypt_set_context(inode, page); 56962306a36Sopenharmony_ci if (err) 57062306a36Sopenharmony_ci goto put_error; 57162306a36Sopenharmony_ci } 57262306a36Sopenharmony_ci } else { 57362306a36Sopenharmony_ci page = f2fs_get_node_page(F2FS_I_SB(dir), inode->i_ino); 57462306a36Sopenharmony_ci if (IS_ERR(page)) 57562306a36Sopenharmony_ci return page; 57662306a36Sopenharmony_ci } 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci init_dent_inode(dir, inode, fname, page); 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci /* 58162306a36Sopenharmony_ci * This file should be checkpointed during fsync. 58262306a36Sopenharmony_ci * We lost i_pino from now on. 58362306a36Sopenharmony_ci */ 58462306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_INC_LINK)) { 58562306a36Sopenharmony_ci if (!S_ISDIR(inode->i_mode)) 58662306a36Sopenharmony_ci file_lost_pino(inode); 58762306a36Sopenharmony_ci /* 58862306a36Sopenharmony_ci * If link the tmpfile to alias through linkat path, 58962306a36Sopenharmony_ci * we should remove this inode from orphan list. 59062306a36Sopenharmony_ci */ 59162306a36Sopenharmony_ci if (inode->i_nlink == 0) 59262306a36Sopenharmony_ci f2fs_remove_orphan_inode(F2FS_I_SB(dir), inode->i_ino); 59362306a36Sopenharmony_ci f2fs_i_links_write(inode, true); 59462306a36Sopenharmony_ci } 59562306a36Sopenharmony_ci return page; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ciput_error: 59862306a36Sopenharmony_ci clear_nlink(inode); 59962306a36Sopenharmony_ci f2fs_update_inode(inode, page); 60062306a36Sopenharmony_ci f2fs_put_page(page, 1); 60162306a36Sopenharmony_ci return ERR_PTR(err); 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_civoid f2fs_update_parent_metadata(struct inode *dir, struct inode *inode, 60562306a36Sopenharmony_ci unsigned int current_depth) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci if (inode && is_inode_flag_set(inode, FI_NEW_INODE)) { 60862306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 60962306a36Sopenharmony_ci f2fs_i_links_write(dir, true); 61062306a36Sopenharmony_ci clear_inode_flag(inode, FI_NEW_INODE); 61162306a36Sopenharmony_ci } 61262306a36Sopenharmony_ci dir->i_mtime = inode_set_ctime_current(dir); 61362306a36Sopenharmony_ci f2fs_mark_inode_dirty_sync(dir, false); 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci if (F2FS_I(dir)->i_current_depth != current_depth) 61662306a36Sopenharmony_ci f2fs_i_depth_write(dir, current_depth); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci if (inode && is_inode_flag_set(inode, FI_INC_LINK)) 61962306a36Sopenharmony_ci clear_inode_flag(inode, FI_INC_LINK); 62062306a36Sopenharmony_ci} 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ciint f2fs_room_for_filename(const void *bitmap, int slots, int max_slots) 62362306a36Sopenharmony_ci{ 62462306a36Sopenharmony_ci int bit_start = 0; 62562306a36Sopenharmony_ci int zero_start, zero_end; 62662306a36Sopenharmony_cinext: 62762306a36Sopenharmony_ci zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start); 62862306a36Sopenharmony_ci if (zero_start >= max_slots) 62962306a36Sopenharmony_ci return max_slots; 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci zero_end = find_next_bit_le(bitmap, max_slots, zero_start); 63262306a36Sopenharmony_ci if (zero_end - zero_start >= slots) 63362306a36Sopenharmony_ci return zero_start; 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci bit_start = zero_end + 1; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci if (zero_end + 1 >= max_slots) 63862306a36Sopenharmony_ci return max_slots; 63962306a36Sopenharmony_ci goto next; 64062306a36Sopenharmony_ci} 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_cibool f2fs_has_enough_room(struct inode *dir, struct page *ipage, 64362306a36Sopenharmony_ci const struct f2fs_filename *fname) 64462306a36Sopenharmony_ci{ 64562306a36Sopenharmony_ci struct f2fs_dentry_ptr d; 64662306a36Sopenharmony_ci unsigned int bit_pos; 64762306a36Sopenharmony_ci int slots = GET_DENTRY_SLOTS(fname->disk_name.len); 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci make_dentry_ptr_inline(dir, &d, inline_data_addr(dir, ipage)); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci bit_pos = f2fs_room_for_filename(d.bitmap, slots, d.max); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci return bit_pos < d.max; 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_civoid f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *d, 65762306a36Sopenharmony_ci const struct fscrypt_str *name, f2fs_hash_t name_hash, 65862306a36Sopenharmony_ci unsigned int bit_pos) 65962306a36Sopenharmony_ci{ 66062306a36Sopenharmony_ci struct f2fs_dir_entry *de; 66162306a36Sopenharmony_ci int slots = GET_DENTRY_SLOTS(name->len); 66262306a36Sopenharmony_ci int i; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci de = &d->dentry[bit_pos]; 66562306a36Sopenharmony_ci de->hash_code = name_hash; 66662306a36Sopenharmony_ci de->name_len = cpu_to_le16(name->len); 66762306a36Sopenharmony_ci memcpy(d->filename[bit_pos], name->name, name->len); 66862306a36Sopenharmony_ci de->ino = cpu_to_le32(ino); 66962306a36Sopenharmony_ci de->file_type = fs_umode_to_ftype(mode); 67062306a36Sopenharmony_ci for (i = 0; i < slots; i++) { 67162306a36Sopenharmony_ci __set_bit_le(bit_pos + i, (void *)d->bitmap); 67262306a36Sopenharmony_ci /* avoid wrong garbage data for readdir */ 67362306a36Sopenharmony_ci if (i) 67462306a36Sopenharmony_ci (de + i)->name_len = 0; 67562306a36Sopenharmony_ci } 67662306a36Sopenharmony_ci} 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ciint f2fs_add_regular_entry(struct inode *dir, const struct f2fs_filename *fname, 67962306a36Sopenharmony_ci struct inode *inode, nid_t ino, umode_t mode) 68062306a36Sopenharmony_ci{ 68162306a36Sopenharmony_ci unsigned int bit_pos; 68262306a36Sopenharmony_ci unsigned int level; 68362306a36Sopenharmony_ci unsigned int current_depth; 68462306a36Sopenharmony_ci unsigned long bidx, block; 68562306a36Sopenharmony_ci unsigned int nbucket, nblock; 68662306a36Sopenharmony_ci struct page *dentry_page = NULL; 68762306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk = NULL; 68862306a36Sopenharmony_ci struct f2fs_dentry_ptr d; 68962306a36Sopenharmony_ci struct page *page = NULL; 69062306a36Sopenharmony_ci int slots, err = 0; 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci level = 0; 69362306a36Sopenharmony_ci slots = GET_DENTRY_SLOTS(fname->disk_name.len); 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci current_depth = F2FS_I(dir)->i_current_depth; 69662306a36Sopenharmony_ci if (F2FS_I(dir)->chash == fname->hash) { 69762306a36Sopenharmony_ci level = F2FS_I(dir)->clevel; 69862306a36Sopenharmony_ci F2FS_I(dir)->chash = 0; 69962306a36Sopenharmony_ci } 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_cistart: 70262306a36Sopenharmony_ci if (time_to_inject(F2FS_I_SB(dir), FAULT_DIR_DEPTH)) 70362306a36Sopenharmony_ci return -ENOSPC; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci if (unlikely(current_depth == MAX_DIR_HASH_DEPTH)) 70662306a36Sopenharmony_ci return -ENOSPC; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci /* Increase the depth, if required */ 70962306a36Sopenharmony_ci if (level == current_depth) 71062306a36Sopenharmony_ci ++current_depth; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); 71362306a36Sopenharmony_ci nblock = bucket_blocks(level); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, 71662306a36Sopenharmony_ci (le32_to_cpu(fname->hash) % nbucket)); 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci for (block = bidx; block <= (bidx + nblock - 1); block++) { 71962306a36Sopenharmony_ci dentry_page = f2fs_get_new_data_page(dir, NULL, block, true); 72062306a36Sopenharmony_ci if (IS_ERR(dentry_page)) 72162306a36Sopenharmony_ci return PTR_ERR(dentry_page); 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci dentry_blk = page_address(dentry_page); 72462306a36Sopenharmony_ci bit_pos = f2fs_room_for_filename(&dentry_blk->dentry_bitmap, 72562306a36Sopenharmony_ci slots, NR_DENTRY_IN_BLOCK); 72662306a36Sopenharmony_ci if (bit_pos < NR_DENTRY_IN_BLOCK) 72762306a36Sopenharmony_ci goto add_dentry; 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci f2fs_put_page(dentry_page, 1); 73062306a36Sopenharmony_ci } 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci /* Move to next level to find the empty slot for new dentry */ 73362306a36Sopenharmony_ci ++level; 73462306a36Sopenharmony_ci goto start; 73562306a36Sopenharmony_ciadd_dentry: 73662306a36Sopenharmony_ci f2fs_wait_on_page_writeback(dentry_page, DATA, true, true); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci if (inode) { 73962306a36Sopenharmony_ci f2fs_down_write(&F2FS_I(inode)->i_sem); 74062306a36Sopenharmony_ci page = f2fs_init_inode_metadata(inode, dir, fname, NULL); 74162306a36Sopenharmony_ci if (IS_ERR(page)) { 74262306a36Sopenharmony_ci err = PTR_ERR(page); 74362306a36Sopenharmony_ci goto fail; 74462306a36Sopenharmony_ci } 74562306a36Sopenharmony_ci } 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci make_dentry_ptr_block(NULL, &d, dentry_blk); 74862306a36Sopenharmony_ci f2fs_update_dentry(ino, mode, &d, &fname->disk_name, fname->hash, 74962306a36Sopenharmony_ci bit_pos); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci set_page_dirty(dentry_page); 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci if (inode) { 75462306a36Sopenharmony_ci f2fs_i_pino_write(inode, dir->i_ino); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci /* synchronize inode page's data from inode cache */ 75762306a36Sopenharmony_ci if (is_inode_flag_set(inode, FI_NEW_INODE)) 75862306a36Sopenharmony_ci f2fs_update_inode(inode, page); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci f2fs_put_page(page, 1); 76162306a36Sopenharmony_ci } 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci f2fs_update_parent_metadata(dir, inode, current_depth); 76462306a36Sopenharmony_cifail: 76562306a36Sopenharmony_ci if (inode) 76662306a36Sopenharmony_ci f2fs_up_write(&F2FS_I(inode)->i_sem); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci f2fs_put_page(dentry_page, 1); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci return err; 77162306a36Sopenharmony_ci} 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ciint f2fs_add_dentry(struct inode *dir, const struct f2fs_filename *fname, 77462306a36Sopenharmony_ci struct inode *inode, nid_t ino, umode_t mode) 77562306a36Sopenharmony_ci{ 77662306a36Sopenharmony_ci int err = -EAGAIN; 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci if (f2fs_has_inline_dentry(dir)) { 77962306a36Sopenharmony_ci /* 78062306a36Sopenharmony_ci * Should get i_xattr_sem to keep the lock order: 78162306a36Sopenharmony_ci * i_xattr_sem -> inode_page lock used by f2fs_setxattr. 78262306a36Sopenharmony_ci */ 78362306a36Sopenharmony_ci f2fs_down_read(&F2FS_I(dir)->i_xattr_sem); 78462306a36Sopenharmony_ci err = f2fs_add_inline_entry(dir, fname, inode, ino, mode); 78562306a36Sopenharmony_ci f2fs_up_read(&F2FS_I(dir)->i_xattr_sem); 78662306a36Sopenharmony_ci } 78762306a36Sopenharmony_ci if (err == -EAGAIN) 78862306a36Sopenharmony_ci err = f2fs_add_regular_entry(dir, fname, inode, ino, mode); 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); 79162306a36Sopenharmony_ci return err; 79262306a36Sopenharmony_ci} 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_ci/* 79562306a36Sopenharmony_ci * Caller should grab and release a rwsem by calling f2fs_lock_op() and 79662306a36Sopenharmony_ci * f2fs_unlock_op(). 79762306a36Sopenharmony_ci */ 79862306a36Sopenharmony_ciint f2fs_do_add_link(struct inode *dir, const struct qstr *name, 79962306a36Sopenharmony_ci struct inode *inode, nid_t ino, umode_t mode) 80062306a36Sopenharmony_ci{ 80162306a36Sopenharmony_ci struct f2fs_filename fname; 80262306a36Sopenharmony_ci struct page *page = NULL; 80362306a36Sopenharmony_ci struct f2fs_dir_entry *de = NULL; 80462306a36Sopenharmony_ci int err; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci err = f2fs_setup_filename(dir, name, 0, &fname); 80762306a36Sopenharmony_ci if (err) 80862306a36Sopenharmony_ci return err; 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci /* 81162306a36Sopenharmony_ci * An immature stackable filesystem shows a race condition between lookup 81262306a36Sopenharmony_ci * and create. If we have same task when doing lookup and create, it's 81362306a36Sopenharmony_ci * definitely fine as expected by VFS normally. Otherwise, let's just 81462306a36Sopenharmony_ci * verify on-disk dentry one more time, which guarantees filesystem 81562306a36Sopenharmony_ci * consistency more. 81662306a36Sopenharmony_ci */ 81762306a36Sopenharmony_ci if (current != F2FS_I(dir)->task) { 81862306a36Sopenharmony_ci de = __f2fs_find_entry(dir, &fname, &page); 81962306a36Sopenharmony_ci F2FS_I(dir)->task = NULL; 82062306a36Sopenharmony_ci } 82162306a36Sopenharmony_ci if (de) { 82262306a36Sopenharmony_ci f2fs_put_page(page, 0); 82362306a36Sopenharmony_ci err = -EEXIST; 82462306a36Sopenharmony_ci } else if (IS_ERR(page)) { 82562306a36Sopenharmony_ci err = PTR_ERR(page); 82662306a36Sopenharmony_ci } else { 82762306a36Sopenharmony_ci err = f2fs_add_dentry(dir, &fname, inode, ino, mode); 82862306a36Sopenharmony_ci } 82962306a36Sopenharmony_ci f2fs_free_filename(&fname); 83062306a36Sopenharmony_ci return err; 83162306a36Sopenharmony_ci} 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ciint f2fs_do_tmpfile(struct inode *inode, struct inode *dir, 83462306a36Sopenharmony_ci struct f2fs_filename *fname) 83562306a36Sopenharmony_ci{ 83662306a36Sopenharmony_ci struct page *page; 83762306a36Sopenharmony_ci int err = 0; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci f2fs_down_write(&F2FS_I(inode)->i_sem); 84062306a36Sopenharmony_ci page = f2fs_init_inode_metadata(inode, dir, fname, NULL); 84162306a36Sopenharmony_ci if (IS_ERR(page)) { 84262306a36Sopenharmony_ci err = PTR_ERR(page); 84362306a36Sopenharmony_ci goto fail; 84462306a36Sopenharmony_ci } 84562306a36Sopenharmony_ci f2fs_put_page(page, 1); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci clear_inode_flag(inode, FI_NEW_INODE); 84862306a36Sopenharmony_ci f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); 84962306a36Sopenharmony_cifail: 85062306a36Sopenharmony_ci f2fs_up_write(&F2FS_I(inode)->i_sem); 85162306a36Sopenharmony_ci return err; 85262306a36Sopenharmony_ci} 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_civoid f2fs_drop_nlink(struct inode *dir, struct inode *inode) 85562306a36Sopenharmony_ci{ 85662306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(dir); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci f2fs_down_write(&F2FS_I(inode)->i_sem); 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) 86162306a36Sopenharmony_ci f2fs_i_links_write(dir, false); 86262306a36Sopenharmony_ci inode_set_ctime_current(inode); 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci f2fs_i_links_write(inode, false); 86562306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) { 86662306a36Sopenharmony_ci f2fs_i_links_write(inode, false); 86762306a36Sopenharmony_ci f2fs_i_size_write(inode, 0); 86862306a36Sopenharmony_ci } 86962306a36Sopenharmony_ci f2fs_up_write(&F2FS_I(inode)->i_sem); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci if (inode->i_nlink == 0) 87262306a36Sopenharmony_ci f2fs_add_orphan_inode(inode); 87362306a36Sopenharmony_ci else 87462306a36Sopenharmony_ci f2fs_release_orphan_inode(sbi); 87562306a36Sopenharmony_ci} 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci/* 87862306a36Sopenharmony_ci * It only removes the dentry from the dentry page, corresponding name 87962306a36Sopenharmony_ci * entry in name page does not need to be touched during deletion. 88062306a36Sopenharmony_ci */ 88162306a36Sopenharmony_civoid f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, 88262306a36Sopenharmony_ci struct inode *dir, struct inode *inode) 88362306a36Sopenharmony_ci{ 88462306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk; 88562306a36Sopenharmony_ci unsigned int bit_pos; 88662306a36Sopenharmony_ci int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); 88762306a36Sopenharmony_ci int i; 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci if (F2FS_OPTION(F2FS_I_SB(dir)).fsync_mode == FSYNC_MODE_STRICT) 89262306a36Sopenharmony_ci f2fs_add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO); 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci if (f2fs_has_inline_dentry(dir)) 89562306a36Sopenharmony_ci return f2fs_delete_inline_entry(dentry, page, dir, inode); 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_ci lock_page(page); 89862306a36Sopenharmony_ci f2fs_wait_on_page_writeback(page, DATA, true, true); 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci dentry_blk = page_address(page); 90162306a36Sopenharmony_ci bit_pos = dentry - dentry_blk->dentry; 90262306a36Sopenharmony_ci for (i = 0; i < slots; i++) 90362306a36Sopenharmony_ci __clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci /* Let's check and deallocate this dentry page */ 90662306a36Sopenharmony_ci bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 90762306a36Sopenharmony_ci NR_DENTRY_IN_BLOCK, 90862306a36Sopenharmony_ci 0); 90962306a36Sopenharmony_ci set_page_dirty(page); 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci if (bit_pos == NR_DENTRY_IN_BLOCK && 91262306a36Sopenharmony_ci !f2fs_truncate_hole(dir, page->index, page->index + 1)) { 91362306a36Sopenharmony_ci f2fs_clear_page_cache_dirty_tag(page); 91462306a36Sopenharmony_ci clear_page_dirty_for_io(page); 91562306a36Sopenharmony_ci ClearPageUptodate(page); 91662306a36Sopenharmony_ci clear_page_private_all(page); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci inode_dec_dirty_pages(dir); 91962306a36Sopenharmony_ci f2fs_remove_dirty_inode(dir); 92062306a36Sopenharmony_ci } 92162306a36Sopenharmony_ci f2fs_put_page(page, 1); 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci dir->i_mtime = inode_set_ctime_current(dir); 92462306a36Sopenharmony_ci f2fs_mark_inode_dirty_sync(dir, false); 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci if (inode) 92762306a36Sopenharmony_ci f2fs_drop_nlink(dir, inode); 92862306a36Sopenharmony_ci} 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_cibool f2fs_empty_dir(struct inode *dir) 93162306a36Sopenharmony_ci{ 93262306a36Sopenharmony_ci unsigned long bidx = 0; 93362306a36Sopenharmony_ci struct page *dentry_page; 93462306a36Sopenharmony_ci unsigned int bit_pos; 93562306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk; 93662306a36Sopenharmony_ci unsigned long nblock = dir_blocks(dir); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci if (f2fs_has_inline_dentry(dir)) 93962306a36Sopenharmony_ci return f2fs_empty_inline_dir(dir); 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci while (bidx < nblock) { 94262306a36Sopenharmony_ci pgoff_t next_pgofs; 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs); 94562306a36Sopenharmony_ci if (IS_ERR(dentry_page)) { 94662306a36Sopenharmony_ci if (PTR_ERR(dentry_page) == -ENOENT) { 94762306a36Sopenharmony_ci bidx = next_pgofs; 94862306a36Sopenharmony_ci continue; 94962306a36Sopenharmony_ci } else { 95062306a36Sopenharmony_ci return false; 95162306a36Sopenharmony_ci } 95262306a36Sopenharmony_ci } 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci dentry_blk = page_address(dentry_page); 95562306a36Sopenharmony_ci if (bidx == 0) 95662306a36Sopenharmony_ci bit_pos = 2; 95762306a36Sopenharmony_ci else 95862306a36Sopenharmony_ci bit_pos = 0; 95962306a36Sopenharmony_ci bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, 96062306a36Sopenharmony_ci NR_DENTRY_IN_BLOCK, 96162306a36Sopenharmony_ci bit_pos); 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci f2fs_put_page(dentry_page, 0); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci if (bit_pos < NR_DENTRY_IN_BLOCK) 96662306a36Sopenharmony_ci return false; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci bidx++; 96962306a36Sopenharmony_ci } 97062306a36Sopenharmony_ci return true; 97162306a36Sopenharmony_ci} 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ciint f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, 97462306a36Sopenharmony_ci unsigned int start_pos, struct fscrypt_str *fstr) 97562306a36Sopenharmony_ci{ 97662306a36Sopenharmony_ci unsigned char d_type = DT_UNKNOWN; 97762306a36Sopenharmony_ci unsigned int bit_pos; 97862306a36Sopenharmony_ci struct f2fs_dir_entry *de = NULL; 97962306a36Sopenharmony_ci struct fscrypt_str de_name = FSTR_INIT(NULL, 0); 98062306a36Sopenharmony_ci struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode); 98162306a36Sopenharmony_ci struct blk_plug plug; 98262306a36Sopenharmony_ci bool readdir_ra = sbi->readdir_ra; 98362306a36Sopenharmony_ci bool found_valid_dirent = false; 98462306a36Sopenharmony_ci int err = 0; 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci bit_pos = ((unsigned long)ctx->pos % d->max); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci if (readdir_ra) 98962306a36Sopenharmony_ci blk_start_plug(&plug); 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci while (bit_pos < d->max) { 99262306a36Sopenharmony_ci bit_pos = find_next_bit_le(d->bitmap, d->max, bit_pos); 99362306a36Sopenharmony_ci if (bit_pos >= d->max) 99462306a36Sopenharmony_ci break; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci de = &d->dentry[bit_pos]; 99762306a36Sopenharmony_ci if (de->name_len == 0) { 99862306a36Sopenharmony_ci if (found_valid_dirent || !bit_pos) { 99962306a36Sopenharmony_ci printk_ratelimited( 100062306a36Sopenharmony_ci "%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.", 100162306a36Sopenharmony_ci KERN_WARNING, sbi->sb->s_id, 100262306a36Sopenharmony_ci le32_to_cpu(de->ino)); 100362306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 100462306a36Sopenharmony_ci } 100562306a36Sopenharmony_ci bit_pos++; 100662306a36Sopenharmony_ci ctx->pos = start_pos + bit_pos; 100762306a36Sopenharmony_ci continue; 100862306a36Sopenharmony_ci } 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci d_type = fs_ftype_to_dtype(de->file_type); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci de_name.name = d->filename[bit_pos]; 101362306a36Sopenharmony_ci de_name.len = le16_to_cpu(de->name_len); 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci /* check memory boundary before moving forward */ 101662306a36Sopenharmony_ci bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); 101762306a36Sopenharmony_ci if (unlikely(bit_pos > d->max || 101862306a36Sopenharmony_ci le16_to_cpu(de->name_len) > F2FS_NAME_LEN)) { 101962306a36Sopenharmony_ci f2fs_warn(sbi, "%s: corrupted namelen=%d, run fsck to fix.", 102062306a36Sopenharmony_ci __func__, le16_to_cpu(de->name_len)); 102162306a36Sopenharmony_ci set_sbi_flag(sbi, SBI_NEED_FSCK); 102262306a36Sopenharmony_ci err = -EFSCORRUPTED; 102362306a36Sopenharmony_ci f2fs_handle_error(sbi, ERROR_CORRUPTED_DIRENT); 102462306a36Sopenharmony_ci goto out; 102562306a36Sopenharmony_ci } 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci if (IS_ENCRYPTED(d->inode)) { 102862306a36Sopenharmony_ci int save_len = fstr->len; 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci err = fscrypt_fname_disk_to_usr(d->inode, 103162306a36Sopenharmony_ci (u32)le32_to_cpu(de->hash_code), 103262306a36Sopenharmony_ci 0, &de_name, fstr); 103362306a36Sopenharmony_ci if (err) 103462306a36Sopenharmony_ci goto out; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci de_name = *fstr; 103762306a36Sopenharmony_ci fstr->len = save_len; 103862306a36Sopenharmony_ci } 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci if (!dir_emit(ctx, de_name.name, de_name.len, 104162306a36Sopenharmony_ci le32_to_cpu(de->ino), d_type)) { 104262306a36Sopenharmony_ci err = 1; 104362306a36Sopenharmony_ci goto out; 104462306a36Sopenharmony_ci } 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci if (readdir_ra) 104762306a36Sopenharmony_ci f2fs_ra_node_page(sbi, le32_to_cpu(de->ino)); 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci ctx->pos = start_pos + bit_pos; 105062306a36Sopenharmony_ci found_valid_dirent = true; 105162306a36Sopenharmony_ci } 105262306a36Sopenharmony_ciout: 105362306a36Sopenharmony_ci if (readdir_ra) 105462306a36Sopenharmony_ci blk_finish_plug(&plug); 105562306a36Sopenharmony_ci return err; 105662306a36Sopenharmony_ci} 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_cistatic int f2fs_readdir(struct file *file, struct dir_context *ctx) 105962306a36Sopenharmony_ci{ 106062306a36Sopenharmony_ci struct inode *inode = file_inode(file); 106162306a36Sopenharmony_ci unsigned long npages = dir_blocks(inode); 106262306a36Sopenharmony_ci struct f2fs_dentry_block *dentry_blk = NULL; 106362306a36Sopenharmony_ci struct page *dentry_page = NULL; 106462306a36Sopenharmony_ci struct file_ra_state *ra = &file->f_ra; 106562306a36Sopenharmony_ci loff_t start_pos = ctx->pos; 106662306a36Sopenharmony_ci unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); 106762306a36Sopenharmony_ci struct f2fs_dentry_ptr d; 106862306a36Sopenharmony_ci struct fscrypt_str fstr = FSTR_INIT(NULL, 0); 106962306a36Sopenharmony_ci int err = 0; 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci if (IS_ENCRYPTED(inode)) { 107262306a36Sopenharmony_ci err = fscrypt_prepare_readdir(inode); 107362306a36Sopenharmony_ci if (err) 107462306a36Sopenharmony_ci goto out; 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_ci err = fscrypt_fname_alloc_buffer(F2FS_NAME_LEN, &fstr); 107762306a36Sopenharmony_ci if (err < 0) 107862306a36Sopenharmony_ci goto out; 107962306a36Sopenharmony_ci } 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci if (f2fs_has_inline_dentry(inode)) { 108262306a36Sopenharmony_ci err = f2fs_read_inline_dir(file, ctx, &fstr); 108362306a36Sopenharmony_ci goto out_free; 108462306a36Sopenharmony_ci } 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci for (; n < npages; ctx->pos = n * NR_DENTRY_IN_BLOCK) { 108762306a36Sopenharmony_ci pgoff_t next_pgofs; 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ci /* allow readdir() to be interrupted */ 109062306a36Sopenharmony_ci if (fatal_signal_pending(current)) { 109162306a36Sopenharmony_ci err = -ERESTARTSYS; 109262306a36Sopenharmony_ci goto out_free; 109362306a36Sopenharmony_ci } 109462306a36Sopenharmony_ci cond_resched(); 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci /* readahead for multi pages of dir */ 109762306a36Sopenharmony_ci if (npages - n > 1 && !ra_has_index(ra, n)) 109862306a36Sopenharmony_ci page_cache_sync_readahead(inode->i_mapping, ra, file, n, 109962306a36Sopenharmony_ci min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_ci dentry_page = f2fs_find_data_page(inode, n, &next_pgofs); 110262306a36Sopenharmony_ci if (IS_ERR(dentry_page)) { 110362306a36Sopenharmony_ci err = PTR_ERR(dentry_page); 110462306a36Sopenharmony_ci if (err == -ENOENT) { 110562306a36Sopenharmony_ci err = 0; 110662306a36Sopenharmony_ci n = next_pgofs; 110762306a36Sopenharmony_ci continue; 110862306a36Sopenharmony_ci } else { 110962306a36Sopenharmony_ci goto out_free; 111062306a36Sopenharmony_ci } 111162306a36Sopenharmony_ci } 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci dentry_blk = page_address(dentry_page); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci make_dentry_ptr_block(inode, &d, dentry_blk); 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci err = f2fs_fill_dentries(ctx, &d, 111862306a36Sopenharmony_ci n * NR_DENTRY_IN_BLOCK, &fstr); 111962306a36Sopenharmony_ci if (err) { 112062306a36Sopenharmony_ci f2fs_put_page(dentry_page, 0); 112162306a36Sopenharmony_ci break; 112262306a36Sopenharmony_ci } 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci f2fs_put_page(dentry_page, 0); 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci n++; 112762306a36Sopenharmony_ci } 112862306a36Sopenharmony_ciout_free: 112962306a36Sopenharmony_ci fscrypt_fname_free_buffer(&fstr); 113062306a36Sopenharmony_ciout: 113162306a36Sopenharmony_ci trace_f2fs_readdir(inode, start_pos, ctx->pos, err); 113262306a36Sopenharmony_ci return err < 0 ? err : 0; 113362306a36Sopenharmony_ci} 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ciconst struct file_operations f2fs_dir_operations = { 113662306a36Sopenharmony_ci .llseek = generic_file_llseek, 113762306a36Sopenharmony_ci .read = generic_read_dir, 113862306a36Sopenharmony_ci .iterate_shared = f2fs_readdir, 113962306a36Sopenharmony_ci .fsync = f2fs_sync_file, 114062306a36Sopenharmony_ci .unlocked_ioctl = f2fs_ioctl, 114162306a36Sopenharmony_ci#ifdef CONFIG_COMPAT 114262306a36Sopenharmony_ci .compat_ioctl = f2fs_compat_ioctl, 114362306a36Sopenharmony_ci#endif 114462306a36Sopenharmony_ci}; 1145