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); 103e52c222SKent Overstreet const char *bch2_inode_v2_invalid(const struct bch_fs *, struct bkey_s_c); 11319f9ac3SKent Overstreet void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 121c6fdbd8SKent Overstreet 1326609b61SKent Overstreet #define bch2_bkey_ops_inode (struct bkey_ops) { \ 141c6fdbd8SKent Overstreet .key_invalid = bch2_inode_invalid, \ 151c6fdbd8SKent Overstreet .val_to_text = bch2_inode_to_text, \ 16*880e2275SKent Overstreet .trans_trigger = bch2_trans_mark_inode, \ 17*880e2275SKent Overstreet .atomic_trigger = bch2_mark_inode, \ 181c6fdbd8SKent Overstreet } 191c6fdbd8SKent Overstreet 203e52c222SKent Overstreet #define bch2_bkey_ops_inode_v2 (struct bkey_ops) { \ 213e52c222SKent Overstreet .key_invalid = bch2_inode_v2_invalid, \ 223e52c222SKent Overstreet .val_to_text = bch2_inode_to_text, \ 23*880e2275SKent Overstreet .trans_trigger = bch2_trans_mark_inode, \ 24*880e2275SKent Overstreet .atomic_trigger = bch2_mark_inode, \ 253e52c222SKent Overstreet } 263e52c222SKent Overstreet 273e52c222SKent Overstreet static inline bool bkey_is_inode(const struct bkey *k) 283e52c222SKent Overstreet { 293e52c222SKent Overstreet return k->type == KEY_TYPE_inode || 303e52c222SKent Overstreet k->type == KEY_TYPE_inode_v2; 313e52c222SKent Overstreet } 323e52c222SKent Overstreet 3326609b61SKent Overstreet const char *bch2_inode_generation_invalid(const struct bch_fs *, 3426609b61SKent Overstreet struct bkey_s_c); 3526609b61SKent Overstreet void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, 3626609b61SKent Overstreet struct bkey_s_c); 3726609b61SKent Overstreet 3826609b61SKent 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, \ 4126609b61SKent 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 691c6fdbd8SKent Overstreet } __attribute__((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 1011c6fdbd8SKent Overstreet static inline struct bch_io_opts bch2_inode_opts_get(struct bch_inode_unpacked *inode) 1021c6fdbd8SKent Overstreet { 1031c6fdbd8SKent Overstreet struct bch_io_opts ret = { 0 }; 1041c6fdbd8SKent Overstreet 105a3e70fb2SKent Overstreet #define x(_name, _bits) \ 1061c6fdbd8SKent Overstreet if (inode->bi_##_name) \ 1071c6fdbd8SKent Overstreet opt_set(ret, _name, inode->bi_##_name - 1); 1081c6fdbd8SKent Overstreet BCH_INODE_OPTS() 109a3e70fb2SKent Overstreet #undef x 1101c6fdbd8SKent Overstreet return ret; 1111c6fdbd8SKent Overstreet } 1121c6fdbd8SKent Overstreet 1134d269918SKent Overstreet static inline void bch2_inode_opt_set(struct bch_inode_unpacked *inode, 1144d269918SKent Overstreet enum inode_opt_id id, u64 v) 1151c6fdbd8SKent Overstreet { 1161c6fdbd8SKent Overstreet switch (id) { 117a3e70fb2SKent Overstreet #define x(_name, ...) \ 1184d269918SKent Overstreet case Inode_opt_##_name: \ 1191c6fdbd8SKent Overstreet inode->bi_##_name = v; \ 1201c6fdbd8SKent Overstreet break; 1211c6fdbd8SKent Overstreet BCH_INODE_OPTS() 122a3e70fb2SKent Overstreet #undef x 1231c6fdbd8SKent Overstreet default: 1241c6fdbd8SKent Overstreet BUG(); 1251c6fdbd8SKent Overstreet } 1261c6fdbd8SKent Overstreet } 1271c6fdbd8SKent Overstreet 1284d269918SKent Overstreet static inline u64 bch2_inode_opt_get(struct bch_inode_unpacked *inode, 1294d269918SKent Overstreet enum inode_opt_id id) 1301c6fdbd8SKent Overstreet { 1314d269918SKent Overstreet switch (id) { 1324d269918SKent Overstreet #define x(_name, ...) \ 1334d269918SKent Overstreet case Inode_opt_##_name: \ 1344d269918SKent Overstreet return inode->bi_##_name; 1354d269918SKent Overstreet BCH_INODE_OPTS() 1364d269918SKent Overstreet #undef x 1374d269918SKent Overstreet default: 1384d269918SKent Overstreet BUG(); 1391c6fdbd8SKent Overstreet } 1401c6fdbd8SKent Overstreet } 1411c6fdbd8SKent Overstreet 1429a3df993SKent Overstreet static inline struct bch_io_opts 1439a3df993SKent Overstreet io_opts(struct bch_fs *c, struct bch_inode_unpacked *inode) 1449a3df993SKent Overstreet { 1459a3df993SKent Overstreet struct bch_io_opts opts = bch2_opts_to_inode_opts(c->opts); 1469a3df993SKent Overstreet 1479a3df993SKent Overstreet bch2_io_opts_apply(&opts, bch2_inode_opts_get(inode)); 1489a3df993SKent Overstreet return opts; 1499a3df993SKent Overstreet } 1509a3df993SKent Overstreet 15196385742SKent Overstreet static inline u8 mode_to_type(umode_t mode) 15296385742SKent Overstreet { 15396385742SKent Overstreet return (mode >> 12) & 15; 15496385742SKent Overstreet } 15596385742SKent Overstreet 156285b181aSKent Overstreet static inline u8 inode_d_type(struct bch_inode_unpacked *inode) 157285b181aSKent Overstreet { 158285b181aSKent Overstreet return inode->bi_subvol ? DT_SUBVOL : mode_to_type(inode->bi_mode); 159285b181aSKent Overstreet } 160285b181aSKent Overstreet 161b43a0f60SKent Overstreet /* i_nlink: */ 162b43a0f60SKent Overstreet 163b43a0f60SKent Overstreet static inline unsigned nlink_bias(umode_t mode) 164b43a0f60SKent Overstreet { 165b43a0f60SKent Overstreet return S_ISDIR(mode) ? 2 : 1; 166b43a0f60SKent Overstreet } 167b43a0f60SKent Overstreet 168b43a0f60SKent Overstreet static inline void bch2_inode_nlink_inc(struct bch_inode_unpacked *bi) 169b43a0f60SKent Overstreet { 170b43a0f60SKent Overstreet if (bi->bi_flags & BCH_INODE_UNLINKED) 171b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 172b43a0f60SKent Overstreet else 173b43a0f60SKent Overstreet bi->bi_nlink++; 174b43a0f60SKent Overstreet } 175b43a0f60SKent Overstreet 176b43a0f60SKent Overstreet static inline void bch2_inode_nlink_dec(struct bch_inode_unpacked *bi) 177b43a0f60SKent Overstreet { 178b43a0f60SKent Overstreet BUG_ON(bi->bi_flags & BCH_INODE_UNLINKED); 179b43a0f60SKent Overstreet if (bi->bi_nlink) 180b43a0f60SKent Overstreet bi->bi_nlink--; 181b43a0f60SKent Overstreet else 182b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 183b43a0f60SKent Overstreet } 184b43a0f60SKent Overstreet 185b43a0f60SKent Overstreet static inline unsigned bch2_inode_nlink_get(struct bch_inode_unpacked *bi) 186b43a0f60SKent Overstreet { 187b43a0f60SKent Overstreet return bi->bi_flags & BCH_INODE_UNLINKED 188b43a0f60SKent Overstreet ? 0 189b43a0f60SKent Overstreet : bi->bi_nlink + nlink_bias(bi->bi_mode); 190b43a0f60SKent Overstreet } 191b43a0f60SKent Overstreet 192b43a0f60SKent Overstreet static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi, 193b43a0f60SKent Overstreet unsigned nlink) 194b43a0f60SKent Overstreet { 195b43a0f60SKent Overstreet if (nlink) { 196b43a0f60SKent Overstreet bi->bi_nlink = nlink - nlink_bias(bi->bi_mode); 197b43a0f60SKent Overstreet bi->bi_flags &= ~BCH_INODE_UNLINKED; 198b43a0f60SKent Overstreet } else { 199b43a0f60SKent Overstreet bi->bi_nlink = 0; 200b43a0f60SKent Overstreet bi->bi_flags |= BCH_INODE_UNLINKED; 201b43a0f60SKent Overstreet } 202b43a0f60SKent Overstreet } 203b43a0f60SKent Overstreet 2041c6fdbd8SKent Overstreet #endif /* _BCACHEFS_INODE_H */ 205