Commit eef0dc0b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2025-04-24' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent Overstreet:

 - Case insensitive directories now work

 - Ciemap now correctly reports on unwritten pagecache data

 - bcachefs tools 1.25.1 was incorrectly picking unaligned bucket sizes;
   fix journal and write path bugs this uncovered

And assorted smaller fixes...

* tag 'bcachefs-2025-04-24' of git://evilpiepirate.org/bcachefs: (24 commits)
  bcachefs: Rework fiemap transaction restart handling
  bcachefs: add fiemap delalloc extent detection
  bcachefs: refactor fiemap processing into extent helper and struct
  bcachefs: track current fiemap offset in start variable
  bcachefs: drop duplicate fiemap sync flag
  bcachefs: Fix btree_iter_peek_prev() at end of inode
  bcachefs: Make btree_iter_peek_prev() assert more precise
  bcachefs: Unit test fixes
  bcachefs: Print mount opts earlier
  bcachefs: unlink: casefold d_invalidate
  bcachefs: Fix casefold lookups
  bcachefs: Casefold is now a regular opts.h option
  bcachefs: Implement fileattr_(get|set)
  bcachefs: Allocator now copes with unaligned buckets
  bcachefs: Start copygc, rebalance threads earlier
  bcachefs: Refactor bch2_run_recovery_passes()
  bcachefs: bch2_copygc_wakeup()
  bcachefs: Fix ref leak in write_super()
  bcachefs: Change __journal_entry_close() assert to ERO
  bcachefs: Ensure journal space is block size aligned
  ...
parents 02ddfb98 d1b0f9aa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1425,6 +1425,8 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
	open_bucket_for_each(c, &wp->ptrs, ob, i)
		wp->sectors_free = min(wp->sectors_free, ob->sectors_free);

	wp->sectors_free = rounddown(wp->sectors_free, block_sectors(c));

	BUG_ON(!wp->sectors_free || wp->sectors_free == UINT_MAX);

	return 0;
+3 −1
Original line number Diff line number Diff line
@@ -110,7 +110,9 @@ static inline void bch2_alloc_sectors_done_inlined(struct bch_fs *c, struct writ
	unsigned i;

	open_bucket_for_each(c, &wp->ptrs, ob, i)
		ob_push(c, !ob->sectors_free ? &ptrs : &keep, ob);
		ob_push(c, ob->sectors_free < block_sectors(c)
			? &ptrs
			: &keep, ob);
	wp->ptrs = keep;

	mutex_unlock(&wp->lock);
+43 −38
Original line number Diff line number Diff line
@@ -366,6 +366,10 @@ static inline void bkey_init(struct bkey *k)
#define __BKEY_PADDED(key, pad)					\
	struct bkey_i key; __u64 key ## _pad[pad]

enum bch_bkey_type_flags {
	BKEY_TYPE_strict_btree_checks	= BIT(0),
};

/*
 * - DELETED keys are used internally to mark keys that should be ignored but
 *   override keys in composition order.  Their version number is ignored.
@@ -384,45 +388,45 @@ static inline void bkey_init(struct bkey *k)
 * - WHITEOUT: for hash table btrees
 */
#define BCH_BKEY_TYPES()						\
	x(deleted,		0)			\
	x(whiteout,		1)			\
	x(error,		2)			\
	x(cookie,		3)			\
	x(hash_whiteout,	4)			\
	x(btree_ptr,		5)			\
	x(extent,		6)			\
	x(reservation,		7)			\
	x(inode,		8)			\
	x(inode_generation,	9)			\
	x(dirent,		10)			\
	x(xattr,		11)			\
	x(alloc,		12)			\
	x(quota,		13)			\
	x(stripe,		14)			\
	x(reflink_p,		15)			\
	x(reflink_v,		16)			\
	x(inline_data,		17)			\
	x(btree_ptr_v2,		18)			\
	x(indirect_inline_data,	19)			\
	x(alloc_v2,		20)			\
	x(subvolume,		21)			\
	x(snapshot,		22)			\
	x(inode_v2,		23)			\
	x(alloc_v3,		24)			\
	x(set,			25)			\
	x(lru,			26)			\
	x(alloc_v4,		27)			\
	x(backpointer,		28)			\
	x(inode_v3,		29)			\
	x(bucket_gens,		30)			\
	x(snapshot_tree,	31)			\
	x(logged_op_truncate,	32)			\
	x(logged_op_finsert,	33)			\
	x(accounting,		34)			\
	x(inode_alloc_cursor,	35)
	x(deleted,		0,	0)				\
	x(whiteout,		1,	0)				\
	x(error,		2,	0)				\
	x(cookie,		3,	0)				\
	x(hash_whiteout,	4,	BKEY_TYPE_strict_btree_checks)	\
	x(btree_ptr,		5,	BKEY_TYPE_strict_btree_checks)	\
	x(extent,		6,	BKEY_TYPE_strict_btree_checks)	\
	x(reservation,		7,	BKEY_TYPE_strict_btree_checks)	\
	x(inode,		8,	BKEY_TYPE_strict_btree_checks)	\
	x(inode_generation,	9,	BKEY_TYPE_strict_btree_checks)	\
	x(dirent,		10,	BKEY_TYPE_strict_btree_checks)	\
	x(xattr,		11,	BKEY_TYPE_strict_btree_checks)	\
	x(alloc,		12,	BKEY_TYPE_strict_btree_checks)	\
	x(quota,		13,	BKEY_TYPE_strict_btree_checks)	\
	x(stripe,		14,	BKEY_TYPE_strict_btree_checks)	\
	x(reflink_p,		15,	BKEY_TYPE_strict_btree_checks)	\
	x(reflink_v,		16,	BKEY_TYPE_strict_btree_checks)	\
	x(inline_data,		17,	BKEY_TYPE_strict_btree_checks)	\
	x(btree_ptr_v2,		18,	BKEY_TYPE_strict_btree_checks)	\
	x(indirect_inline_data,	19,	BKEY_TYPE_strict_btree_checks)	\
	x(alloc_v2,		20,	BKEY_TYPE_strict_btree_checks)	\
	x(subvolume,		21,	BKEY_TYPE_strict_btree_checks)	\
	x(snapshot,		22,	BKEY_TYPE_strict_btree_checks)	\
	x(inode_v2,		23,	BKEY_TYPE_strict_btree_checks)	\
	x(alloc_v3,		24,	BKEY_TYPE_strict_btree_checks)	\
	x(set,			25,	0)				\
	x(lru,			26,	BKEY_TYPE_strict_btree_checks)	\
	x(alloc_v4,		27,	BKEY_TYPE_strict_btree_checks)	\
	x(backpointer,		28,	BKEY_TYPE_strict_btree_checks)	\
	x(inode_v3,		29,	BKEY_TYPE_strict_btree_checks)	\
	x(bucket_gens,		30,	BKEY_TYPE_strict_btree_checks)	\
	x(snapshot_tree,	31,	BKEY_TYPE_strict_btree_checks)	\
	x(logged_op_truncate,	32,	BKEY_TYPE_strict_btree_checks)	\
	x(logged_op_finsert,	33,	BKEY_TYPE_strict_btree_checks)	\
	x(accounting,		34,	BKEY_TYPE_strict_btree_checks)	\
	x(inode_alloc_cursor,	35,	BKEY_TYPE_strict_btree_checks)

enum bch_bkey_type {
#define x(name, nr) KEY_TYPE_##name	= nr,
#define x(name, nr, ...) KEY_TYPE_##name	= nr,
	BCH_BKEY_TYPES()
#undef x
	KEY_TYPE_MAX,
@@ -863,6 +867,7 @@ LE64_BITMASK(BCH_SB_VERSION_INCOMPAT_ALLOWED,
LE64_BITMASK(BCH_SB_SHARD_INUMS_NBITS,	struct bch_sb, flags[6],  0,  4);
LE64_BITMASK(BCH_SB_WRITE_ERROR_TIMEOUT,struct bch_sb, flags[6],  4, 14);
LE64_BITMASK(BCH_SB_CSUM_ERR_RETRY_NR,	struct bch_sb, flags[6], 14, 20);
LE64_BITMASK(BCH_SB_CASEFOLD,		struct bch_sb, flags[6], 22, 23);

static inline __u64 BCH_SB_COMPRESSION_TYPE(const struct bch_sb *sb)
{
+20 −4
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include "xattr.h"

const char * const bch2_bkey_types[] = {
#define x(name, nr) #name,
#define x(name, nr, ...) #name,
	BCH_BKEY_TYPES()
#undef x
	NULL
@@ -115,7 +115,7 @@ static bool key_type_set_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_
})

const struct bkey_ops bch2_bkey_ops[] = {
#define x(name, nr) [KEY_TYPE_##name]	= bch2_bkey_ops_##name,
#define x(name, nr, ...) [KEY_TYPE_##name]	= bch2_bkey_ops_##name,
	BCH_BKEY_TYPES()
#undef x
};
@@ -155,6 +155,12 @@ static u64 bch2_key_types_allowed[] = {
#undef x
};

static const enum bch_bkey_type_flags bch2_bkey_type_flags[] = {
#define x(name, nr, flags)	[KEY_TYPE_##name] = flags,
	BCH_BKEY_TYPES()
#undef x
};

const char *bch2_btree_node_type_str(enum btree_node_type type)
{
	return type == BKEY_TYPE_btree ? "internal btree node" : bch2_btree_id_str(type - 1);
@@ -177,8 +183,18 @@ int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
	if (type >= BKEY_TYPE_NR)
		return 0;

	bkey_fsck_err_on(k.k->type < KEY_TYPE_MAX &&
			 (type == BKEY_TYPE_btree || (from.flags & BCH_VALIDATE_commit)) &&
	enum bch_bkey_type_flags bkey_flags = k.k->type < KEY_TYPE_MAX
		? bch2_bkey_type_flags[k.k->type]
		: 0;

	bool strict_key_type_allowed =
		(from.flags & BCH_VALIDATE_commit) ||
		type == BKEY_TYPE_btree ||
		(from.btree < BTREE_ID_NR &&
		 (bkey_flags & BKEY_TYPE_strict_btree_checks));

	bkey_fsck_err_on(strict_key_type_allowed &&
			 k.k->type < KEY_TYPE_MAX &&
			 !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)),
			 c, bkey_invalid_type_for_btree,
			 "invalid key type for btree %s (%s)",
+5 −2
Original line number Diff line number Diff line
@@ -2577,7 +2577,10 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_trans *trans, struct
					      struct bpos end)
{
	if ((iter->flags & (BTREE_ITER_is_extents|BTREE_ITER_filter_snapshots)) &&
	   !bkey_eq(iter->pos, POS_MAX)) {
	   !bkey_eq(iter->pos, POS_MAX) &&
	   !((iter->flags & BTREE_ITER_is_extents) &&
	     iter->pos.offset == U64_MAX)) {

		/*
		 * bkey_start_pos(), for extents, is not monotonically
		 * increasing until after filtering for snapshots:
@@ -2602,7 +2605,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_trans *trans, struct

	bch2_trans_verify_not_unlocked_or_in_restart(trans);
	bch2_btree_iter_verify_entry_exit(iter);
	EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bpos_eq(end, POS_MIN));
	EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && iter->pos.inode != end.inode);

	int ret = trans_maybe_inject_restart(trans, _RET_IP_);
	if (unlikely(ret)) {
Loading