inode.h 5.09 KB
Newer Older
1 2 3 4 5 6
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_INODE_H
#define _BCACHEFS_INODE_H

#include "opts.h"

7 8
extern const char * const bch2_inode_opts[];

9 10
int bch2_inode_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
int bch2_inode_v2_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
11
void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
12

13
#define bch2_bkey_ops_inode (struct bkey_ops) {		\
14 15
	.key_invalid	= bch2_inode_invalid,		\
	.val_to_text	= bch2_inode_to_text,		\
16 17
	.trans_trigger	= bch2_trans_mark_inode,	\
	.atomic_trigger	= bch2_mark_inode,		\
18 19
}

20 21 22
#define bch2_bkey_ops_inode_v2 (struct bkey_ops) {	\
	.key_invalid	= bch2_inode_v2_invalid,	\
	.val_to_text	= bch2_inode_to_text,		\
23 24
	.trans_trigger	= bch2_trans_mark_inode,	\
	.atomic_trigger	= bch2_mark_inode,		\
25 26 27 28 29 30 31 32
}

static inline bool bkey_is_inode(const struct bkey *k)
{
	return  k->type == KEY_TYPE_inode ||
		k->type == KEY_TYPE_inode_v2;
}

33 34
int bch2_inode_generation_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
35 36 37 38 39 40

#define bch2_bkey_ops_inode_generation (struct bkey_ops) {	\
	.key_invalid	= bch2_inode_generation_invalid,	\
	.val_to_text	= bch2_inode_generation_to_text,	\
}

Kent Overstreet's avatar
Kent Overstreet committed
41 42 43 44 45 46 47 48
#if 0
typedef struct {
	u64			lo;
	u32			hi;
} __packed __aligned(4) u96;
#endif
typedef u64 u96;

49 50
struct bch_inode_unpacked {
	u64			bi_inum;
51
	u64			bi_journal_seq;
52 53 54 55
	__le64			bi_hash_seed;
	u32			bi_flags;
	u16			bi_mode;

56
#define x(_name, _bits)	u##_bits _name;
57
	BCH_INODE_FIELDS()
58
#undef  x
59 60 61
};

struct bkey_inode_buf {
62
	struct bkey_i_inode_v2	inode;
63

64
#define x(_name, _bits)		+ 8 + _bits / 8
65
	u8		_pad[0 + BCH_INODE_FIELDS()];
66
#undef  x
67 68
} __attribute__((packed, aligned(8)));

Kent Overstreet's avatar
Kent Overstreet committed
69 70
void bch2_inode_pack(struct bch_fs *, struct bkey_inode_buf *,
		     const struct bch_inode_unpacked *);
71
int bch2_inode_unpack(struct bkey_s_c, struct bch_inode_unpacked *);
72

73 74
void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *);

Kent Overstreet's avatar
Kent Overstreet committed
75
int bch2_inode_peek(struct btree_trans *, struct btree_iter *,
76
		    struct bch_inode_unpacked *, subvol_inum, unsigned);
77 78 79
int bch2_inode_write(struct btree_trans *, struct btree_iter *,
		     struct bch_inode_unpacked *);

80 81 82 83 84
void bch2_inode_init_early(struct bch_fs *,
			   struct bch_inode_unpacked *);
void bch2_inode_init_late(struct bch_inode_unpacked *, u64,
			  uid_t, gid_t, umode_t, dev_t,
			  struct bch_inode_unpacked *);
85 86 87 88
void bch2_inode_init(struct bch_fs *, struct bch_inode_unpacked *,
		     uid_t, gid_t, umode_t, dev_t,
		     struct bch_inode_unpacked *);

Kent Overstreet's avatar
Kent Overstreet committed
89 90
int bch2_inode_create(struct btree_trans *, struct btree_iter *,
		      struct bch_inode_unpacked *, u32, u64);
91

92
int bch2_inode_rm(struct bch_fs *, subvol_inum);
93

94 95
int bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum,
				  struct bch_inode_unpacked *);
96 97
int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum,
			    struct bch_inode_unpacked *);
98 99 100 101 102

static inline struct bch_io_opts bch2_inode_opts_get(struct bch_inode_unpacked *inode)
{
	struct bch_io_opts ret = { 0 };

103
#define x(_name, _bits)					\
104 105 106
	if (inode->bi_##_name)						\
		opt_set(ret, _name, inode->bi_##_name - 1);
	BCH_INODE_OPTS()
107
#undef x
108 109 110
	return ret;
}

111 112
static inline void bch2_inode_opt_set(struct bch_inode_unpacked *inode,
				      enum inode_opt_id id, u64 v)
113 114
{
	switch (id) {
115 116
#define x(_name, ...)							\
	case Inode_opt_##_name:						\
117 118 119
		inode->bi_##_name = v;					\
		break;
	BCH_INODE_OPTS()
120
#undef x
121 122 123 124 125
	default:
		BUG();
	}
}

126 127
static inline u64 bch2_inode_opt_get(struct bch_inode_unpacked *inode,
				     enum inode_opt_id id)
128
{
129 130 131 132 133 134 135 136 137
	switch (id) {
#define x(_name, ...)							\
	case Inode_opt_##_name:						\
		return inode->bi_##_name;
	BCH_INODE_OPTS()
#undef x
	default:
		BUG();
	}
138 139
}

140 141 142 143 144 145 146 147 148
static inline struct bch_io_opts
io_opts(struct bch_fs *c, struct bch_inode_unpacked *inode)
{
	struct bch_io_opts opts = bch2_opts_to_inode_opts(c->opts);

	bch2_io_opts_apply(&opts, bch2_inode_opts_get(inode));
	return opts;
}

149 150 151 152 153
static inline u8 mode_to_type(umode_t mode)
{
	return (mode >> 12) & 15;
}

154 155 156 157 158
static inline u8 inode_d_type(struct bch_inode_unpacked *inode)
{
	return inode->bi_subvol ? DT_SUBVOL : mode_to_type(inode->bi_mode);
}

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/* i_nlink: */

static inline unsigned nlink_bias(umode_t mode)
{
	return S_ISDIR(mode) ? 2 : 1;
}

static inline void bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
{
	if (bi->bi_flags & BCH_INODE_UNLINKED)
		bi->bi_flags &= ~BCH_INODE_UNLINKED;
	else
		bi->bi_nlink++;
}

static inline void bch2_inode_nlink_dec(struct bch_inode_unpacked *bi)
{
	BUG_ON(bi->bi_flags & BCH_INODE_UNLINKED);
	if (bi->bi_nlink)
		bi->bi_nlink--;
	else
		bi->bi_flags |= BCH_INODE_UNLINKED;
}

static inline unsigned bch2_inode_nlink_get(struct bch_inode_unpacked *bi)
{
	return bi->bi_flags & BCH_INODE_UNLINKED
		  ? 0
		  : bi->bi_nlink + nlink_bias(bi->bi_mode);
}

static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi,
					unsigned nlink)
{
	if (nlink) {
		bi->bi_nlink = nlink - nlink_bias(bi->bi_mode);
		bi->bi_flags &= ~BCH_INODE_UNLINKED;
	} else {
		bi->bi_nlink = 0;
		bi->bi_flags |= BCH_INODE_UNLINKED;
	}
}

202
#endif /* _BCACHEFS_INODE_H */