11c6fdbd8SKent Overstreet /* SPDX-License-Identifier: GPL-2.0 */ 21c6fdbd8SKent Overstreet #ifndef _BCACHEFS_INODE_H 31c6fdbd8SKent Overstreet #define _BCACHEFS_INODE_H 41c6fdbd8SKent Overstreet 51c6fdbd8SKent Overstreet #include "opts.h" 61c6fdbd8SKent Overstreet 74d269918SKent Overstreet extern const char * const bch2_inode_opts[]; 84d269918SKent Overstreet 91c6fdbd8SKent Overstreet const char *bch2_inode_invalid(const struct bch_fs *, struct bkey_s_c); 10319f9ac3SKent Overstreet void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 111c6fdbd8SKent Overstreet 1226609b61SKent Overstreet #define bch2_bkey_ops_inode (struct bkey_ops) { \ 131c6fdbd8SKent Overstreet .key_invalid = bch2_inode_invalid, \ 141c6fdbd8SKent Overstreet .val_to_text = bch2_inode_to_text, \ 151c6fdbd8SKent Overstreet } 161c6fdbd8SKent Overstreet 1726609b61SKent Overstreet const char *bch2_inode_generation_invalid(const struct bch_fs *, 1826609b61SKent Overstreet struct bkey_s_c); 1926609b61SKent Overstreet void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, 2026609b61SKent Overstreet struct bkey_s_c); 2126609b61SKent Overstreet 2226609b61SKent Overstreet #define bch2_bkey_ops_inode_generation (struct bkey_ops) { \ 2326609b61SKent Overstreet .key_invalid = bch2_inode_generation_invalid, \ 2426609b61SKent Overstreet .val_to_text = bch2_inode_generation_to_text, \ 2526609b61SKent Overstreet } 2626609b61SKent Overstreet 27a3e72262SKent Overstreet #if 0 28a3e72262SKent Overstreet typedef struct { 29a3e72262SKent Overstreet u64 lo; 30a3e72262SKent Overstreet u32 hi; 31a3e72262SKent Overstreet } __packed __aligned(4) u96; 32a3e72262SKent Overstreet #endif 33a3e72262SKent Overstreet typedef u64 u96; 34a3e72262SKent Overstreet 351c6fdbd8SKent Overstreet struct bch_inode_unpacked { 361c6fdbd8SKent Overstreet u64 bi_inum; 371c6fdbd8SKent Overstreet __le64 bi_hash_seed; 381c6fdbd8SKent Overstreet u32 bi_flags; 391c6fdbd8SKent Overstreet u16 bi_mode; 401c6fdbd8SKent Overstreet 41a3e70fb2SKent Overstreet #define x(_name, _bits) u##_bits _name; 421c6fdbd8SKent Overstreet BCH_INODE_FIELDS() 43a3e70fb2SKent Overstreet #undef x 441c6fdbd8SKent Overstreet }; 451c6fdbd8SKent Overstreet 461c6fdbd8SKent Overstreet struct bkey_inode_buf { 471c6fdbd8SKent Overstreet struct bkey_i_inode inode; 481c6fdbd8SKent Overstreet 49a3e70fb2SKent Overstreet #define x(_name, _bits) + 8 + _bits / 8 501c6fdbd8SKent Overstreet u8 _pad[0 + BCH_INODE_FIELDS()]; 51a3e70fb2SKent Overstreet #undef x 521c6fdbd8SKent Overstreet } __attribute__((packed, aligned(8))); 531c6fdbd8SKent Overstreet 54a3e72262SKent Overstreet void bch2_inode_pack(struct bch_fs *, struct bkey_inode_buf *, 55a3e72262SKent Overstreet const struct bch_inode_unpacked *); 561c6fdbd8SKent Overstreet int bch2_inode_unpack(struct bkey_s_c_inode, struct bch_inode_unpacked *); 571c6fdbd8SKent Overstreet 58*0f120eacSKent Overstreet void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *); 59*0f120eacSKent Overstreet 6058677a1dSKent Overstreet struct btree_iter *bch2_inode_peek(struct btree_trans *, 6158677a1dSKent Overstreet struct bch_inode_unpacked *, u64, unsigned); 6258677a1dSKent Overstreet int bch2_inode_write(struct btree_trans *, struct btree_iter *, 6358677a1dSKent Overstreet struct bch_inode_unpacked *); 6458677a1dSKent Overstreet 6596385742SKent Overstreet void bch2_inode_init_early(struct bch_fs *, 6696385742SKent Overstreet struct bch_inode_unpacked *); 6796385742SKent Overstreet void bch2_inode_init_late(struct bch_inode_unpacked *, u64, 6896385742SKent Overstreet uid_t, gid_t, umode_t, dev_t, 6996385742SKent Overstreet struct bch_inode_unpacked *); 701c6fdbd8SKent Overstreet void bch2_inode_init(struct bch_fs *, struct bch_inode_unpacked *, 711c6fdbd8SKent Overstreet uid_t, gid_t, umode_t, dev_t, 721c6fdbd8SKent Overstreet struct bch_inode_unpacked *); 731c6fdbd8SKent Overstreet 74ab2a29ccSKent Overstreet struct btree_iter *bch2_inode_create(struct btree_trans *, 75bff796aeSKent Overstreet struct bch_inode_unpacked *, u32, u64); 761c6fdbd8SKent Overstreet 776584e84aSKent Overstreet int bch2_inode_rm(struct bch_fs *, u64, bool); 781c6fdbd8SKent Overstreet 796bd13057SKent Overstreet int bch2_inode_find_by_inum(struct bch_fs *, u64, struct bch_inode_unpacked *); 801c6fdbd8SKent Overstreet 811c6fdbd8SKent Overstreet static inline struct bch_io_opts bch2_inode_opts_get(struct bch_inode_unpacked *inode) 821c6fdbd8SKent Overstreet { 831c6fdbd8SKent Overstreet struct bch_io_opts ret = { 0 }; 841c6fdbd8SKent Overstreet 85a3e70fb2SKent Overstreet #define x(_name, _bits) \ 861c6fdbd8SKent Overstreet if (inode->bi_##_name) \ 871c6fdbd8SKent Overstreet opt_set(ret, _name, inode->bi_##_name - 1); 881c6fdbd8SKent Overstreet BCH_INODE_OPTS() 89a3e70fb2SKent Overstreet #undef x 901c6fdbd8SKent Overstreet return ret; 911c6fdbd8SKent Overstreet } 921c6fdbd8SKent Overstreet 934d269918SKent Overstreet static inline void bch2_inode_opt_set(struct bch_inode_unpacked *inode, 944d269918SKent Overstreet enum inode_opt_id id, u64 v) 951c6fdbd8SKent Overstreet { 961c6fdbd8SKent Overstreet switch (id) { 97a3e70fb2SKent Overstreet #define x(_name, ...) \ 984d269918SKent Overstreet case Inode_opt_##_name: \ 991c6fdbd8SKent Overstreet inode->bi_##_name = v; \ 1001c6fdbd8SKent Overstreet break; 1011c6fdbd8SKent Overstreet BCH_INODE_OPTS() 102a3e70fb2SKent Overstreet #undef x 1031c6fdbd8SKent Overstreet default: 1041c6fdbd8SKent Overstreet BUG(); 1051c6fdbd8SKent Overstreet } 1061c6fdbd8SKent Overstreet } 1071c6fdbd8SKent Overstreet 1084d269918SKent Overstreet static inline u64 bch2_inode_opt_get(struct bch_inode_unpacked *inode, 1094d269918SKent Overstreet enum inode_opt_id id) 1101c6fdbd8SKent Overstreet { 1114d269918SKent Overstreet switch (id) { 1124d269918SKent Overstreet #define x(_name, ...) \ 1134d269918SKent Overstreet case Inode_opt_##_name: \ 1144d269918SKent Overstreet return inode->bi_##_name; 1154d269918SKent Overstreet BCH_INODE_OPTS() 1164d269918SKent Overstreet #undef x 1174d269918SKent Overstreet default: 1184d269918SKent Overstreet BUG(); 1191c6fdbd8SKent Overstreet } 1201c6fdbd8SKent Overstreet } 1211c6fdbd8SKent Overstreet 1229a3df993SKent Overstreet static inline struct bch_io_opts 1239a3df993SKent Overstreet io_opts(struct bch_fs *c, struct bch_inode_unpacked *inode) 1249a3df993SKent Overstreet { 1259a3df993SKent Overstreet struct bch_io_opts opts = bch2_opts_to_inode_opts(c->opts); 1269a3df993SKent Overstreet 1279a3df993SKent Overstreet bch2_io_opts_apply(&opts, bch2_inode_opts_get(inode)); 1289a3df993SKent Overstreet return opts; 1299a3df993SKent Overstreet } 1309a3df993SKent Overstreet 13196385742SKent Overstreet static inline u8 mode_to_type(umode_t mode) 13296385742SKent Overstreet { 13396385742SKent Overstreet return (mode >> 12) & 15; 13496385742SKent Overstreet } 13596385742SKent Overstreet 136b43a0f60SKent Overstreet /* i_nlink: */ 137b43a0f60SKent Overstreet 138b43a0f60SKent Overstreet static inline unsigned nlink_bias(umode_t mode) 139b43a0f60SKent Overstreet { 140b43a0f60SKent Overstreet return S_ISDIR(mode) ? 2 : 1; 141b43a0f60SKent Overstreet } 142b43a0f60SKent Overstreet 143b43a0f60SKent Overstreet static inline void bch2_inode_nlink_inc(struct bch_inode_unpacked *bi) 144b43a0f60SKent Overstreet { 145b43a0f60SKent Overstreet if (bi->bi_flags & BCH_INODE_UNLINKED) 146b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 147b43a0f60SKent Overstreet else 148b43a0f60SKent Overstreet bi->bi_nlink++; 149b43a0f60SKent Overstreet } 150b43a0f60SKent Overstreet 151b43a0f60SKent Overstreet static inline void bch2_inode_nlink_dec(struct bch_inode_unpacked *bi) 152b43a0f60SKent Overstreet { 153b43a0f60SKent Overstreet BUG_ON(bi->bi_flags & BCH_INODE_UNLINKED); 154b43a0f60SKent Overstreet if (bi->bi_nlink) 155b43a0f60SKent Overstreet bi->bi_nlink--; 156b43a0f60SKent Overstreet else 157b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 158b43a0f60SKent Overstreet } 159b43a0f60SKent Overstreet 160b43a0f60SKent Overstreet static inline unsigned bch2_inode_nlink_get(struct bch_inode_unpacked *bi) 161b43a0f60SKent Overstreet { 162b43a0f60SKent Overstreet return bi->bi_flags & BCH_INODE_UNLINKED 163b43a0f60SKent Overstreet ? 0 164b43a0f60SKent Overstreet : bi->bi_nlink + nlink_bias(bi->bi_mode); 165b43a0f60SKent Overstreet } 166b43a0f60SKent Overstreet 167b43a0f60SKent Overstreet static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi, 168b43a0f60SKent Overstreet unsigned nlink) 169b43a0f60SKent Overstreet { 170b43a0f60SKent Overstreet if (nlink) { 171b43a0f60SKent Overstreet bi->bi_nlink = nlink - nlink_bias(bi->bi_mode); 172b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 173b43a0f60SKent Overstreet } else { 174b43a0f60SKent Overstreet bi->bi_nlink = 0; 175b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 176b43a0f60SKent Overstreet } 177b43a0f60SKent Overstreet } 178b43a0f60SKent Overstreet 1791c6fdbd8SKent Overstreet #endif /* _BCACHEFS_INODE_H */ 180