Commit 482deed9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2025-07-03' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent Overstreet:
 "The 'opts.casefold_disabled' patch is non critical, but would be a
  6.15 backport; it's to address the casefolding + overlayfs
  incompatibility that was discovvered late.

  It's late because I was hoping that this would be addressed on the
  overlayfs side (and will be in 6.17), but user reports keep coming in
  on this one (lots of people are using docker these days)"

* tag 'bcachefs-2025-07-03' of git://evilpiepirate.org/bcachefs:
  bcachefs: opts.casefold_disabled
  bcachefs: Work around deadlock to btree node rewrites in journal replay
  bcachefs: Fix incorrect transaction restart handling
  bcachefs: fix btree_trans_peek_prev_journal()
  bcachefs: mark invalid_btree_id autofix
parents 2eb7f03a 94426e42
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -863,9 +863,7 @@ struct bch_fs {
	DARRAY(enum bcachefs_metadata_version)
				incompat_versions_requested;

#ifdef CONFIG_UNICODE
	struct unicode_map	*cf_encoding;
#endif

	struct bch_sb_handle	disk_sb;

@@ -1285,4 +1283,13 @@ static inline bool bch2_discard_opt_enabled(struct bch_fs *c, struct bch_dev *ca
		: ca->mi.discard;
}

static inline bool bch2_fs_casefold_enabled(struct bch_fs *c)
{
#ifdef CONFIG_UNICODE
	return !c->opts.casefold_disabled;
#else
	return false;
#endif
}

#endif /* _BCACHEFS_H */
+35 −8
Original line number Diff line number Diff line
@@ -1337,6 +1337,32 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,

	btree_node_reset_sib_u64s(b);

	/*
	 * XXX:
	 *
	 * We deadlock if too many btree updates require node rewrites while
	 * we're still in journal replay.
	 *
	 * This is because btree node rewrites generate more updates for the
	 * interior updates (alloc, backpointers), and if those updates touch
	 * new nodes and generate more rewrites - well, you see the problem.
	 *
	 * The biggest cause is that we don't use the btree write buffer (for
	 * the backpointer updates - this needs some real thought on locking in
	 * order to fix.
	 *
	 * The problem with this workaround (not doing the rewrite for degraded
	 * nodes in journal replay) is that those degraded nodes persist, and we
	 * don't want that (this is a real bug when a btree node write completes
	 * with fewer replicas than we wanted and leaves a degraded node due to
	 * device _removal_, i.e. the device went away mid write).
	 *
	 * It's less of a bug here, but still a problem because we don't yet
	 * have a way of tracking degraded data - we another index (all
	 * extents/btree nodes, by replicas entry) in order to fix properly
	 * (re-replicate degraded data at the earliest possible time).
	 */
	if (c->recovery.passes_complete & BIT_ULL(BCH_RECOVERY_PASS_journal_replay)) {
		scoped_guard(rcu)
			bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
				struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev);
@@ -1346,6 +1372,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
					set_btree_node_need_rewrite_degraded(b);
				}
			}
	}

	if (!ptr_written) {
		set_btree_node_need_rewrite(b);
+1 −1
Original line number Diff line number Diff line
@@ -2189,7 +2189,7 @@ void btree_trans_peek_prev_journal(struct btree_trans *trans,
	struct btree_path *path = btree_iter_path(trans, iter);
	struct bkey_i *next_journal =
		bch2_btree_journal_peek_prev(trans, iter, search_key,
				k->k ? k->k->p : path_l(path)->b->key.k.p);
				k->k ? k->k->p : path_l(path)->b->data->min_key);

	if (next_journal) {
		iter->k = next_journal->k;
+9 −10
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
{
	*out_cf = (struct qstr) QSTR_INIT(NULL, 0);

#ifdef CONFIG_UNICODE
	if (!bch2_fs_casefold_enabled(trans->c))
		return -EOPNOTSUPP;

	unsigned char *buf = bch2_trans_kmalloc(trans, BCH_NAME_MAX + 1);
	int ret = PTR_ERR_OR_ZERO(buf);
	if (ret)
@@ -30,9 +32,6 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,

	*out_cf = (struct qstr) QSTR_INIT(buf, ret);
	return 0;
#else
	return -EOPNOTSUPP;
#endif
}

static unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d)
@@ -231,7 +230,8 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
	prt_printf(out, " type %s", bch2_d_type_str(d.v->d_type));
}

int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
int bch2_dirent_init_name(struct bch_fs *c,
			  struct bkey_i_dirent *dirent,
			  const struct bch_hash_info *hash_info,
			  const struct qstr *name,
			  const struct qstr *cf_name)
@@ -251,7 +251,9 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
		       offsetof(struct bch_dirent, d_name) -
		       name->len);
	} else {
#ifdef CONFIG_UNICODE
		if (!bch2_fs_casefold_enabled(c))
			return -EOPNOTSUPP;

		memcpy(&dirent->v.d_cf_name_block.d_names[0], name->name, name->len);

		char *cf_out = &dirent->v.d_cf_name_block.d_names[name->len];
@@ -277,9 +279,6 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
		dirent->v.d_cf_name_block.d_cf_name_len = cpu_to_le16(cf_len);

		EBUG_ON(bch2_dirent_get_casefold_name(dirent_i_to_s_c(dirent)).len != cf_len);
#else
	return -EOPNOTSUPP;
#endif
	}

	unsigned u64s = dirent_val_u64s(name->len, cf_len);
@@ -313,7 +312,7 @@ struct bkey_i_dirent *bch2_dirent_create_key(struct btree_trans *trans,
	dirent->v.d_type = type;
	dirent->v.d_unused = 0;

	int ret = bch2_dirent_init_name(dirent, hash_info, name, cf_name);
	int ret = bch2_dirent_init_name(trans->c, dirent, hash_info, name, cf_name);
	if (ret)
		return ERR_PTR(ret);

+2 −1
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ static inline void dirent_copy_target(struct bkey_i_dirent *dst,
	dst->v.d_type = src.v->d_type;
}

int bch2_dirent_init_name(struct bkey_i_dirent *,
int bch2_dirent_init_name(struct bch_fs *,
			  struct bkey_i_dirent *,
			  const struct bch_hash_info *,
			  const struct qstr *,
			  const struct qstr *);
Loading