Commit f4a584f4 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: bch2_disk_accounting_mod2()



We're hitting some issues with uninitialized struct padding, flagged by
kmsan.

They appear to be falso positives, otherwise bch2_accounting_validate()
would have flagged them as "junk at end". But for now, we'll need to
initialize disk_accounting_pos with memset().

This adds a new helper, bch2_disk_accounting_mod2(), that initializes a
disk_accounting_pos and does the accounting mod all at once - so overall
things actually get slightly more ergonomic.

BCH_DISK_ACCOUNTING_replicas keys are left for now; KMSAN isn't warning
about them and they're a bit special.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 5ae6f330
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -777,14 +777,12 @@ static inline int bch2_dev_data_type_accounting_mod(struct btree_trans *trans, s
						    s64 delta_sectors,
						    s64 delta_fragmented, unsigned flags)
{
	struct disk_accounting_pos acc = {
		.type = BCH_DISK_ACCOUNTING_dev_data_type,
		.dev_data_type.dev		= ca->dev_idx,
		.dev_data_type.data_type	= data_type,
	};
	s64 d[3] = { delta_buckets, delta_sectors, delta_fragmented };

	return bch2_disk_accounting_mod(trans, &acc, d, 3, flags & BTREE_TRIGGER_gc);
	return bch2_disk_accounting_mod2(trans, flags & BTREE_TRIGGER_gc,
					 d, dev_data_type,
					 .dev		= ca->dev_idx,
					 .data_type	= data_type);
}

int bch2_alloc_key_to_dev_counters(struct btree_trans *trans, struct bch_dev *ca,
+23 −43
Original line number Diff line number Diff line
@@ -724,9 +724,7 @@ static int __trigger_extent(struct btree_trans *trans,
		.replicas.nr_required	= 1,
	};

	struct disk_accounting_pos acct_compression_key = {
		.type			= BCH_DISK_ACCOUNTING_compression,
	};
	unsigned cur_compression_type = 0;
	u64 compression_acct[3] = { 1, 0, 0 };

	bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
@@ -760,13 +758,13 @@ static int __trigger_extent(struct btree_trans *trans,
			acc_replicas_key.replicas.nr_required = 0;
		}

		if (acct_compression_key.compression.type &&
		    acct_compression_key.compression.type != p.crc.compression_type) {
		if (cur_compression_type &&
		    cur_compression_type != p.crc.compression_type) {
			if (flags & BTREE_TRIGGER_overwrite)
				bch2_u64s_neg(compression_acct, ARRAY_SIZE(compression_acct));

			ret = bch2_disk_accounting_mod(trans, &acct_compression_key, compression_acct,
						       ARRAY_SIZE(compression_acct), gc);
			ret = bch2_disk_accounting_mod2(trans, gc, compression_acct,
							compression, cur_compression_type);
			if (ret)
				return ret;

@@ -775,7 +773,7 @@ static int __trigger_extent(struct btree_trans *trans,
			compression_acct[2] = 0;
		}

		acct_compression_key.compression.type = p.crc.compression_type;
		cur_compression_type = p.crc.compression_type;
		if (p.crc.compression_type) {
			compression_acct[1] += p.crc.uncompressed_size;
			compression_acct[2] += p.crc.compressed_size;
@@ -789,45 +787,34 @@ static int __trigger_extent(struct btree_trans *trans,
	}

	if (acc_replicas_key.replicas.nr_devs && !level && k.k->p.snapshot) {
		struct disk_accounting_pos acc_snapshot_key = {
			.type			= BCH_DISK_ACCOUNTING_snapshot,
			.snapshot.id		= k.k->p.snapshot,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_snapshot_key, replicas_sectors, 1, gc);
		ret = bch2_disk_accounting_mod2_nr(trans, gc, replicas_sectors, 1, snapshot, k.k->p.snapshot);
		if (ret)
			return ret;
	}

	if (acct_compression_key.compression.type) {
	if (cur_compression_type) {
		if (flags & BTREE_TRIGGER_overwrite)
			bch2_u64s_neg(compression_acct, ARRAY_SIZE(compression_acct));

		ret = bch2_disk_accounting_mod(trans, &acct_compression_key, compression_acct,
					       ARRAY_SIZE(compression_acct), gc);
		ret = bch2_disk_accounting_mod2(trans, gc, compression_acct,
						compression, cur_compression_type);
		if (ret)
			return ret;
	}

	if (level) {
		struct disk_accounting_pos acc_btree_key = {
			.type		= BCH_DISK_ACCOUNTING_btree,
			.btree.id	= btree_id,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_btree_key, replicas_sectors, 1, gc);
		ret = bch2_disk_accounting_mod2_nr(trans, gc, replicas_sectors, 1, btree, btree_id);
		if (ret)
			return ret;
	} else {
		bool insert = !(flags & BTREE_TRIGGER_overwrite);
		struct disk_accounting_pos acc_inum_key = {
			.type		= BCH_DISK_ACCOUNTING_inum,
			.inum.inum	= k.k->p.inode,
		};

		s64 v[3] = {
			insert ? 1 : -1,
			insert ? k.k->size : -((s64) k.k->size),
			*replicas_sectors,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_inum_key, v, ARRAY_SIZE(v), gc);
		ret = bch2_disk_accounting_mod2(trans, gc, v, inum, k.k->p.inode);
		if (ret)
			return ret;
	}
@@ -876,15 +863,15 @@ int bch2_trigger_extent(struct btree_trans *trans,
		}

		int need_rebalance_delta = 0;
		s64 need_rebalance_sectors_delta = 0;
		s64 need_rebalance_sectors_delta[1] = { 0 };

		s64 s = bch2_bkey_sectors_need_rebalance(c, old);
		need_rebalance_delta -= s != 0;
		need_rebalance_sectors_delta -= s;
		need_rebalance_sectors_delta[0] -= s;

		s = bch2_bkey_sectors_need_rebalance(c, new.s_c);
		need_rebalance_delta += s != 0;
		need_rebalance_sectors_delta += s;
		need_rebalance_sectors_delta[0] += s;

		if ((flags & BTREE_TRIGGER_transactional) && need_rebalance_delta) {
			int ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_rebalance_work,
@@ -893,12 +880,9 @@ int bch2_trigger_extent(struct btree_trans *trans,
				return ret;
		}

		if (need_rebalance_sectors_delta) {
			struct disk_accounting_pos acc = {
				.type		= BCH_DISK_ACCOUNTING_rebalance_work,
			};
			int ret = bch2_disk_accounting_mod(trans, &acc, &need_rebalance_sectors_delta, 1,
							   flags & BTREE_TRIGGER_gc);
		if (need_rebalance_sectors_delta[0]) {
			int ret = bch2_disk_accounting_mod2(trans, flags & BTREE_TRIGGER_gc,
							    need_rebalance_sectors_delta, rebalance_work);
			if (ret)
				return ret;
		}
@@ -914,17 +898,13 @@ static int __trigger_reservation(struct btree_trans *trans,
			enum btree_iter_update_trigger_flags flags)
{
	if (flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc)) {
		s64 sectors = k.k->size;
		s64 sectors[1] = { k.k->size };

		if (flags & BTREE_TRIGGER_overwrite)
			sectors = -sectors;

		struct disk_accounting_pos acc = {
			.type = BCH_DISK_ACCOUNTING_persistent_reserved,
			.persistent_reserved.nr_replicas = bkey_s_c_to_reservation(k).v->nr_replicas,
		};
			sectors[0] = -sectors[0];

		return bch2_disk_accounting_mod(trans, &acc, &sectors, 1, flags & BTREE_TRIGGER_gc);
		return bch2_disk_accounting_mod2(trans, flags & BTREE_TRIGGER_gc, sectors,
				persistent_reserved, bkey_s_c_to_reservation(k).v->nr_replicas);
	}

	return 0;
+18 −0
Original line number Diff line number Diff line
@@ -85,6 +85,24 @@ static inline struct bpos disk_accounting_pos_to_bpos(struct disk_accounting_pos

int bch2_disk_accounting_mod(struct btree_trans *, struct disk_accounting_pos *,
			     s64 *, unsigned, bool);

#define disk_accounting_key_init(_k, _type, ...)			\
do {									\
	memset(&(_k), 0, sizeof(_k));					\
	(_k).type	= BCH_DISK_ACCOUNTING_##_type;			\
	(_k)._type	= (struct bch_acct_##_type) { __VA_ARGS__ };	\
} while (0)

#define bch2_disk_accounting_mod2_nr(_trans, _gc, _v, _nr, ...)		\
({									\
	struct disk_accounting_pos pos;					\
	disk_accounting_key_init(pos, __VA_ARGS__);			\
	bch2_disk_accounting_mod(trans, &pos, _v, _nr, _gc);		\
})

#define bch2_disk_accounting_mod2(_trans, _gc, _v, ...)			\
	bch2_disk_accounting_mod2_nr(_trans, _gc, _v, ARRAY_SIZE(_v), __VA_ARGS__)

int bch2_mod_dev_cached_sectors(struct btree_trans *, unsigned, s64, bool);

int bch2_accounting_validate(struct bch_fs *, struct bkey_s_c,
+6 −6
Original line number Diff line number Diff line
@@ -113,14 +113,14 @@ enum disk_accounting_type {
	BCH_DISK_ACCOUNTING_TYPE_NR,
};

struct bch_nr_inodes {
struct bch_acct_nr_inodes {
};

struct bch_persistent_reserved {
struct bch_acct_persistent_reserved {
	__u8			nr_replicas;
};

struct bch_dev_data_type {
struct bch_acct_dev_data_type {
	__u8			dev;
	__u8			data_type;
};
@@ -149,10 +149,10 @@ struct disk_accounting_pos {
	struct {
		__u8				type;
		union {
		struct bch_nr_inodes		nr_inodes;
		struct bch_persistent_reserved	persistent_reserved;
		struct bch_acct_nr_inodes		nr_inodes;
		struct bch_acct_persistent_reserved	persistent_reserved;
		struct bch_replicas_entry_v1	replicas;
		struct bch_dev_data_type	dev_data_type;
		struct bch_acct_dev_data_type	dev_data_type;
		struct bch_acct_compression	compression;
		struct bch_acct_snapshot	snapshot;
		struct bch_acct_btree		btree;
+3 −4
Original line number Diff line number Diff line
@@ -731,10 +731,9 @@ int bch2_trigger_inode(struct btree_trans *trans,
		bkey_s_to_inode_v3(new).v->bi_journal_seq = cpu_to_le64(trans->journal_res.seq);
	}

	s64 nr = bkey_is_inode(new.k) - bkey_is_inode(old.k);
	if ((flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc)) && nr) {
		struct disk_accounting_pos acc = { .type = BCH_DISK_ACCOUNTING_nr_inodes };
		int ret = bch2_disk_accounting_mod(trans, &acc, &nr, 1, flags & BTREE_TRIGGER_gc);
	s64 nr[1] = { bkey_is_inode(new.k) - bkey_is_inode(old.k) };
	if ((flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc)) && nr[0]) {
		int ret = bch2_disk_accounting_mod2(trans, flags & BTREE_TRIGGER_gc, nr, nr_inodes);
		if (ret)
			return ret;
	}
Loading