xref: /linux/fs/bcachefs/inode.h (revision 880e2275f9f1461c87cd113a8da291861cc01400)
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