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 580f120eacSKent Overstreet void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *); 590f120eacSKent Overstreet 6067e0dd8fSKent Overstreet int bch2_inode_peek(struct btree_trans *, struct btree_iter *, 61*6fed42bbSKent Overstreet struct bch_inode_unpacked *, subvol_inum, 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 7467e0dd8fSKent Overstreet int bch2_inode_create(struct btree_trans *, struct btree_iter *, 75bff796aeSKent Overstreet struct bch_inode_unpacked *, u32, u64); 761c6fdbd8SKent Overstreet 77*6fed42bbSKent Overstreet int bch2_inode_rm(struct bch_fs *, subvol_inum, bool); 781c6fdbd8SKent Overstreet 79*6fed42bbSKent Overstreet int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum, 80*6fed42bbSKent Overstreet struct bch_inode_unpacked *); 811c6fdbd8SKent Overstreet 821c6fdbd8SKent Overstreet static inline struct bch_io_opts bch2_inode_opts_get(struct bch_inode_unpacked *inode) 831c6fdbd8SKent Overstreet { 841c6fdbd8SKent Overstreet struct bch_io_opts ret = { 0 }; 851c6fdbd8SKent Overstreet 86a3e70fb2SKent Overstreet #define x(_name, _bits) \ 871c6fdbd8SKent Overstreet if (inode->bi_##_name) \ 881c6fdbd8SKent Overstreet opt_set(ret, _name, inode->bi_##_name - 1); 891c6fdbd8SKent Overstreet BCH_INODE_OPTS() 90a3e70fb2SKent Overstreet #undef x 911c6fdbd8SKent Overstreet return ret; 921c6fdbd8SKent Overstreet } 931c6fdbd8SKent Overstreet 944d269918SKent Overstreet static inline void bch2_inode_opt_set(struct bch_inode_unpacked *inode, 954d269918SKent Overstreet enum inode_opt_id id, u64 v) 961c6fdbd8SKent Overstreet { 971c6fdbd8SKent Overstreet switch (id) { 98a3e70fb2SKent Overstreet #define x(_name, ...) \ 994d269918SKent Overstreet case Inode_opt_##_name: \ 1001c6fdbd8SKent Overstreet inode->bi_##_name = v; \ 1011c6fdbd8SKent Overstreet break; 1021c6fdbd8SKent Overstreet BCH_INODE_OPTS() 103a3e70fb2SKent Overstreet #undef x 1041c6fdbd8SKent Overstreet default: 1051c6fdbd8SKent Overstreet BUG(); 1061c6fdbd8SKent Overstreet } 1071c6fdbd8SKent Overstreet } 1081c6fdbd8SKent Overstreet 1094d269918SKent Overstreet static inline u64 bch2_inode_opt_get(struct bch_inode_unpacked *inode, 1104d269918SKent Overstreet enum inode_opt_id id) 1111c6fdbd8SKent Overstreet { 1124d269918SKent Overstreet switch (id) { 1134d269918SKent Overstreet #define x(_name, ...) \ 1144d269918SKent Overstreet case Inode_opt_##_name: \ 1154d269918SKent Overstreet return inode->bi_##_name; 1164d269918SKent Overstreet BCH_INODE_OPTS() 1174d269918SKent Overstreet #undef x 1184d269918SKent Overstreet default: 1194d269918SKent Overstreet BUG(); 1201c6fdbd8SKent Overstreet } 1211c6fdbd8SKent Overstreet } 1221c6fdbd8SKent Overstreet 1239a3df993SKent Overstreet static inline struct bch_io_opts 1249a3df993SKent Overstreet io_opts(struct bch_fs *c, struct bch_inode_unpacked *inode) 1259a3df993SKent Overstreet { 1269a3df993SKent Overstreet struct bch_io_opts opts = bch2_opts_to_inode_opts(c->opts); 1279a3df993SKent Overstreet 1289a3df993SKent Overstreet bch2_io_opts_apply(&opts, bch2_inode_opts_get(inode)); 1299a3df993SKent Overstreet return opts; 1309a3df993SKent Overstreet } 1319a3df993SKent Overstreet 13296385742SKent Overstreet static inline u8 mode_to_type(umode_t mode) 13396385742SKent Overstreet { 13496385742SKent Overstreet return (mode >> 12) & 15; 13596385742SKent Overstreet } 13696385742SKent Overstreet 137b43a0f60SKent Overstreet /* i_nlink: */ 138b43a0f60SKent Overstreet 139b43a0f60SKent Overstreet static inline unsigned nlink_bias(umode_t mode) 140b43a0f60SKent Overstreet { 141b43a0f60SKent Overstreet return S_ISDIR(mode) ? 2 : 1; 142b43a0f60SKent Overstreet } 143b43a0f60SKent Overstreet 144b43a0f60SKent Overstreet static inline void bch2_inode_nlink_inc(struct bch_inode_unpacked *bi) 145b43a0f60SKent Overstreet { 146b43a0f60SKent Overstreet if (bi->bi_flags & BCH_INODE_UNLINKED) 147b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 148b43a0f60SKent Overstreet else 149b43a0f60SKent Overstreet bi->bi_nlink++; 150b43a0f60SKent Overstreet } 151b43a0f60SKent Overstreet 152b43a0f60SKent Overstreet static inline void bch2_inode_nlink_dec(struct bch_inode_unpacked *bi) 153b43a0f60SKent Overstreet { 154b43a0f60SKent Overstreet BUG_ON(bi->bi_flags & BCH_INODE_UNLINKED); 155b43a0f60SKent Overstreet if (bi->bi_nlink) 156b43a0f60SKent Overstreet bi->bi_nlink--; 157b43a0f60SKent Overstreet else 158b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 159b43a0f60SKent Overstreet } 160b43a0f60SKent Overstreet 161b43a0f60SKent Overstreet static inline unsigned bch2_inode_nlink_get(struct bch_inode_unpacked *bi) 162b43a0f60SKent Overstreet { 163b43a0f60SKent Overstreet return bi->bi_flags & BCH_INODE_UNLINKED 164b43a0f60SKent Overstreet ? 0 165b43a0f60SKent Overstreet : bi->bi_nlink + nlink_bias(bi->bi_mode); 166b43a0f60SKent Overstreet } 167b43a0f60SKent Overstreet 168b43a0f60SKent Overstreet static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi, 169b43a0f60SKent Overstreet unsigned nlink) 170b43a0f60SKent Overstreet { 171b43a0f60SKent Overstreet if (nlink) { 172b43a0f60SKent Overstreet bi->bi_nlink = nlink - nlink_bias(bi->bi_mode); 173b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 174b43a0f60SKent Overstreet } else { 175b43a0f60SKent Overstreet bi->bi_nlink = 0; 176b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 177b43a0f60SKent Overstreet } 178b43a0f60SKent Overstreet } 179b43a0f60SKent Overstreet 1801c6fdbd8SKent Overstreet #endif /* _BCACHEFS_INODE_H */ 181