11c6fdbd8SKent Overstreet /* SPDX-License-Identifier: GPL-2.0 */ 21c6fdbd8SKent Overstreet #ifndef _BCACHEFS_INODE_H 31c6fdbd8SKent Overstreet #define _BCACHEFS_INODE_H 41c6fdbd8SKent Overstreet 577671e8fSKent Overstreet #include "bkey.h" 61c6fdbd8SKent Overstreet #include "opts.h" 71c6fdbd8SKent Overstreet 84d269918SKent Overstreet extern const char * const bch2_inode_opts[]; 94d269918SKent Overstreet 10275c8426SKent Overstreet int bch2_inode_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *); 11275c8426SKent Overstreet int bch2_inode_v2_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *); 12319f9ac3SKent Overstreet void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 131c6fdbd8SKent Overstreet 14a1019576SKent Overstreet #define bch2_bkey_ops_inode ((struct bkey_ops) { \ 151c6fdbd8SKent Overstreet .key_invalid = bch2_inode_invalid, \ 161c6fdbd8SKent Overstreet .val_to_text = bch2_inode_to_text, \ 17880e2275SKent Overstreet .trans_trigger = bch2_trans_mark_inode, \ 18880e2275SKent Overstreet .atomic_trigger = bch2_mark_inode, \ 19a1019576SKent Overstreet }) 201c6fdbd8SKent Overstreet 21a1019576SKent Overstreet #define bch2_bkey_ops_inode_v2 ((struct bkey_ops) { \ 223e52c222SKent Overstreet .key_invalid = bch2_inode_v2_invalid, \ 233e52c222SKent Overstreet .val_to_text = bch2_inode_to_text, \ 24880e2275SKent Overstreet .trans_trigger = bch2_trans_mark_inode, \ 25880e2275SKent Overstreet .atomic_trigger = bch2_mark_inode, \ 26a1019576SKent Overstreet }) 273e52c222SKent Overstreet 283e52c222SKent Overstreet static inline bool bkey_is_inode(const struct bkey *k) 293e52c222SKent Overstreet { 303e52c222SKent Overstreet return k->type == KEY_TYPE_inode || 313e52c222SKent Overstreet k->type == KEY_TYPE_inode_v2; 323e52c222SKent Overstreet } 333e52c222SKent Overstreet 34275c8426SKent Overstreet int bch2_inode_generation_invalid(const struct bch_fs *, struct bkey_s_c, 35275c8426SKent Overstreet int, struct printbuf *); 36f0ac7df2SKent Overstreet void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 3726609b61SKent Overstreet 38a1019576SKent Overstreet #define bch2_bkey_ops_inode_generation ((struct bkey_ops) { \ 3926609b61SKent Overstreet .key_invalid = bch2_inode_generation_invalid, \ 4026609b61SKent Overstreet .val_to_text = bch2_inode_generation_to_text, \ 41a1019576SKent Overstreet }) 4226609b61SKent Overstreet 43a3e72262SKent Overstreet #if 0 44a3e72262SKent Overstreet typedef struct { 45a3e72262SKent Overstreet u64 lo; 46a3e72262SKent Overstreet u32 hi; 47a3e72262SKent Overstreet } __packed __aligned(4) u96; 48a3e72262SKent Overstreet #endif 49a3e72262SKent Overstreet typedef u64 u96; 50a3e72262SKent Overstreet 511c6fdbd8SKent Overstreet struct bch_inode_unpacked { 521c6fdbd8SKent Overstreet u64 bi_inum; 533e52c222SKent Overstreet u64 bi_journal_seq; 541c6fdbd8SKent Overstreet __le64 bi_hash_seed; 551c6fdbd8SKent Overstreet u32 bi_flags; 561c6fdbd8SKent Overstreet u16 bi_mode; 571c6fdbd8SKent Overstreet 58a3e70fb2SKent Overstreet #define x(_name, _bits) u##_bits _name; 591c6fdbd8SKent Overstreet BCH_INODE_FIELDS() 60a3e70fb2SKent Overstreet #undef x 611c6fdbd8SKent Overstreet }; 621c6fdbd8SKent Overstreet 631c6fdbd8SKent Overstreet struct bkey_inode_buf { 643e52c222SKent Overstreet struct bkey_i_inode_v2 inode; 651c6fdbd8SKent Overstreet 66a3e70fb2SKent Overstreet #define x(_name, _bits) + 8 + _bits / 8 671c6fdbd8SKent Overstreet u8 _pad[0 + BCH_INODE_FIELDS()]; 68a3e70fb2SKent Overstreet #undef x 69fd0c7679SKent Overstreet } __packed __aligned(8); 701c6fdbd8SKent Overstreet 71a3e72262SKent Overstreet void bch2_inode_pack(struct bch_fs *, struct bkey_inode_buf *, 72a3e72262SKent Overstreet const struct bch_inode_unpacked *); 733e52c222SKent Overstreet int bch2_inode_unpack(struct bkey_s_c, struct bch_inode_unpacked *); 741c6fdbd8SKent Overstreet 750f120eacSKent Overstreet void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *); 760f120eacSKent Overstreet 7767e0dd8fSKent Overstreet int bch2_inode_peek(struct btree_trans *, struct btree_iter *, 786fed42bbSKent Overstreet struct bch_inode_unpacked *, subvol_inum, unsigned); 7958677a1dSKent Overstreet int bch2_inode_write(struct btree_trans *, struct btree_iter *, 8058677a1dSKent Overstreet struct bch_inode_unpacked *); 8158677a1dSKent Overstreet 8296385742SKent Overstreet void bch2_inode_init_early(struct bch_fs *, 8396385742SKent Overstreet struct bch_inode_unpacked *); 8496385742SKent Overstreet void bch2_inode_init_late(struct bch_inode_unpacked *, u64, 8596385742SKent Overstreet uid_t, gid_t, umode_t, dev_t, 8696385742SKent Overstreet struct bch_inode_unpacked *); 871c6fdbd8SKent Overstreet void bch2_inode_init(struct bch_fs *, struct bch_inode_unpacked *, 881c6fdbd8SKent Overstreet uid_t, gid_t, umode_t, dev_t, 891c6fdbd8SKent Overstreet struct bch_inode_unpacked *); 901c6fdbd8SKent Overstreet 9167e0dd8fSKent Overstreet int bch2_inode_create(struct btree_trans *, struct btree_iter *, 92bff796aeSKent Overstreet struct bch_inode_unpacked *, u32, u64); 931c6fdbd8SKent Overstreet 947c8f6f98SKent Overstreet int bch2_inode_rm(struct bch_fs *, subvol_inum); 951c6fdbd8SKent Overstreet 9632b26e8cSKent Overstreet int bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum, 9732b26e8cSKent Overstreet struct bch_inode_unpacked *); 986fed42bbSKent Overstreet int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum, 996fed42bbSKent Overstreet struct bch_inode_unpacked *); 1001c6fdbd8SKent Overstreet 101*01ad6737SKent Overstreet #define inode_opt_get(_c, _inode, _name) \ 102*01ad6737SKent Overstreet ((_inode)->bi_##_name ? (_inode)->bi_##_name - 1 : (_c)->opts._name) 1031c6fdbd8SKent Overstreet 1044d269918SKent Overstreet static inline void bch2_inode_opt_set(struct bch_inode_unpacked *inode, 1054d269918SKent Overstreet enum inode_opt_id id, u64 v) 1061c6fdbd8SKent Overstreet { 1071c6fdbd8SKent Overstreet switch (id) { 108a3e70fb2SKent Overstreet #define x(_name, ...) \ 1094d269918SKent Overstreet case Inode_opt_##_name: \ 1101c6fdbd8SKent Overstreet inode->bi_##_name = v; \ 1111c6fdbd8SKent Overstreet break; 1121c6fdbd8SKent Overstreet BCH_INODE_OPTS() 113a3e70fb2SKent Overstreet #undef x 1141c6fdbd8SKent Overstreet default: 1151c6fdbd8SKent Overstreet BUG(); 1161c6fdbd8SKent Overstreet } 1171c6fdbd8SKent Overstreet } 1181c6fdbd8SKent Overstreet 1194d269918SKent Overstreet static inline u64 bch2_inode_opt_get(struct bch_inode_unpacked *inode, 1204d269918SKent Overstreet enum inode_opt_id id) 1211c6fdbd8SKent Overstreet { 1224d269918SKent Overstreet switch (id) { 1234d269918SKent Overstreet #define x(_name, ...) \ 1244d269918SKent Overstreet case Inode_opt_##_name: \ 1254d269918SKent Overstreet return inode->bi_##_name; 1264d269918SKent Overstreet BCH_INODE_OPTS() 1274d269918SKent Overstreet #undef x 1284d269918SKent Overstreet default: 1294d269918SKent Overstreet BUG(); 1301c6fdbd8SKent Overstreet } 1311c6fdbd8SKent Overstreet } 1321c6fdbd8SKent Overstreet 13396385742SKent Overstreet static inline u8 mode_to_type(umode_t mode) 13496385742SKent Overstreet { 13596385742SKent Overstreet return (mode >> 12) & 15; 13696385742SKent Overstreet } 13796385742SKent Overstreet 138285b181aSKent Overstreet static inline u8 inode_d_type(struct bch_inode_unpacked *inode) 139285b181aSKent Overstreet { 140285b181aSKent Overstreet return inode->bi_subvol ? DT_SUBVOL : mode_to_type(inode->bi_mode); 141285b181aSKent Overstreet } 142285b181aSKent Overstreet 143b43a0f60SKent Overstreet /* i_nlink: */ 144b43a0f60SKent Overstreet 145b43a0f60SKent Overstreet static inline unsigned nlink_bias(umode_t mode) 146b43a0f60SKent Overstreet { 147b43a0f60SKent Overstreet return S_ISDIR(mode) ? 2 : 1; 148b43a0f60SKent Overstreet } 149b43a0f60SKent Overstreet 150b43a0f60SKent Overstreet static inline unsigned bch2_inode_nlink_get(struct bch_inode_unpacked *bi) 151b43a0f60SKent Overstreet { 152b43a0f60SKent Overstreet return bi->bi_flags & BCH_INODE_UNLINKED 153b43a0f60SKent Overstreet ? 0 154b43a0f60SKent Overstreet : bi->bi_nlink + nlink_bias(bi->bi_mode); 155b43a0f60SKent Overstreet } 156b43a0f60SKent Overstreet 157b43a0f60SKent Overstreet static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi, 158b43a0f60SKent Overstreet unsigned nlink) 159b43a0f60SKent Overstreet { 160b43a0f60SKent Overstreet if (nlink) { 161b43a0f60SKent Overstreet bi->bi_nlink = nlink - nlink_bias(bi->bi_mode); 162b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 163b43a0f60SKent Overstreet } else { 164b43a0f60SKent Overstreet bi->bi_nlink = 0; 165b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 166b43a0f60SKent Overstreet } 167b43a0f60SKent Overstreet } 168b43a0f60SKent Overstreet 169962ad1a7SKent Overstreet int bch2_inode_nlink_inc(struct bch_inode_unpacked *); 170962ad1a7SKent Overstreet void bch2_inode_nlink_dec(struct btree_trans *, struct bch_inode_unpacked *); 171962ad1a7SKent Overstreet 172abb936fbSKent Overstreet struct bch_opts bch2_inode_opts_to_opts(struct bch_inode_unpacked *); 173*01ad6737SKent Overstreet void bch2_inode_opts_get(struct bch_io_opts *, struct bch_fs *, 174*01ad6737SKent Overstreet struct bch_inode_unpacked *); 175abb936fbSKent Overstreet 1761c6fdbd8SKent Overstreet #endif /* _BCACHEFS_INODE_H */ 177