1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BCACHEFS_DIRENT_H 3 #define _BCACHEFS_DIRENT_H 4 5 #include "str_hash.h" 6 7 extern const struct bch_hash_desc bch2_dirent_hash_desc; 8 9 int bch2_dirent_validate(struct bch_fs *, struct bkey_s_c, 10 struct bkey_validate_context); 11 void bch2_dirent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 12 13 #define bch2_bkey_ops_dirent ((struct bkey_ops) { \ 14 .key_validate = bch2_dirent_validate, \ 15 .val_to_text = bch2_dirent_to_text, \ 16 .min_val_size = 16, \ 17 }) 18 19 struct qstr; 20 struct file; 21 struct dir_context; 22 struct bch_fs; 23 struct bch_hash_info; 24 struct bch_inode_info; 25 26 #ifdef CONFIG_UNICODE 27 int bch2_casefold(struct btree_trans *, const struct bch_hash_info *, 28 const struct qstr *, struct qstr *); 29 #else 30 static inline int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info, 31 const struct qstr *str, struct qstr *out_cf) 32 { 33 return -EOPNOTSUPP; 34 } 35 #endif 36 37 static inline int bch2_maybe_casefold(struct btree_trans *trans, 38 const struct bch_hash_info *info, 39 const struct qstr *str, struct qstr *out_cf) 40 { 41 if (likely(!info->cf_encoding)) { 42 *out_cf = *str; 43 return 0; 44 } else { 45 return bch2_casefold(trans, info, str, out_cf); 46 } 47 } 48 49 struct qstr bch2_dirent_get_name(struct bkey_s_c_dirent); 50 51 static inline unsigned dirent_val_u64s(unsigned len, unsigned cf_len) 52 { 53 unsigned bytes = cf_len 54 ? offsetof(struct bch_dirent, d_cf_name_block.d_names) + len + cf_len 55 : offsetof(struct bch_dirent, d_name) + len; 56 57 return DIV_ROUND_UP(bytes, sizeof(u64)); 58 } 59 60 int bch2_dirent_read_target(struct btree_trans *, subvol_inum, 61 struct bkey_s_c_dirent, subvol_inum *); 62 63 static inline void dirent_copy_target(struct bkey_i_dirent *dst, 64 struct bkey_s_c_dirent src) 65 { 66 dst->v.d_inum = src.v->d_inum; 67 dst->v.d_type = src.v->d_type; 68 } 69 70 int bch2_dirent_init_name(struct bch_fs *, 71 struct bkey_i_dirent *, 72 const struct bch_hash_info *, 73 const struct qstr *, 74 const struct qstr *); 75 struct bkey_i_dirent *bch2_dirent_create_key(struct btree_trans *, 76 const struct bch_hash_info *, subvol_inum, u8, 77 const struct qstr *, const struct qstr *, u64); 78 79 int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32, 80 const struct bch_hash_info *, u8, 81 const struct qstr *, u64, u64 *, 82 enum btree_iter_update_trigger_flags); 83 int bch2_dirent_create(struct btree_trans *, subvol_inum, 84 const struct bch_hash_info *, u8, 85 const struct qstr *, u64, u64 *, 86 enum btree_iter_update_trigger_flags); 87 88 static inline unsigned vfs_d_type(unsigned type) 89 { 90 return type == DT_SUBVOL ? DT_DIR : type; 91 } 92 93 enum bch_rename_mode { 94 BCH_RENAME, 95 BCH_RENAME_OVERWRITE, 96 BCH_RENAME_EXCHANGE, 97 }; 98 99 int bch2_dirent_rename(struct btree_trans *, 100 subvol_inum, struct bch_hash_info *, 101 subvol_inum, struct bch_hash_info *, 102 const struct qstr *, subvol_inum *, u64 *, 103 const struct qstr *, subvol_inum *, u64 *, 104 enum bch_rename_mode); 105 106 int bch2_dirent_lookup_trans(struct btree_trans *, struct btree_iter *, 107 subvol_inum, const struct bch_hash_info *, 108 const struct qstr *, subvol_inum *, unsigned); 109 u64 bch2_dirent_lookup(struct bch_fs *, subvol_inum, 110 const struct bch_hash_info *, 111 const struct qstr *, subvol_inum *); 112 113 int bch2_empty_dir_snapshot(struct btree_trans *, u64, u32, u32); 114 int bch2_empty_dir_trans(struct btree_trans *, subvol_inum); 115 int bch2_readdir(struct bch_fs *, subvol_inum, struct bch_hash_info *, struct dir_context *); 116 117 int bch2_fsck_remove_dirent(struct btree_trans *, struct bpos); 118 119 #endif /* _BCACHEFS_DIRENT_H */ 120