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

Merge tag 'bcachefs-2024-10-14' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent Overstreet:

 - New metadata version inode_has_child_snapshots

   This fixes bugs with handling of unlinked inodes + snapshots, in
   particular when an inode is reattached after taking a snapshot;
   deleted inodes now get correctly cleaned up across snapshots.

 - Disk accounting rewrite fixes
     - validation fixes for when a device has been removed
     - fix journal replay failing with "journal_reclaim_would_deadlock"

 - Some more small fixes for erasure coding + device removal

 - Assorted small syzbot fixes

* tag 'bcachefs-2024-10-14' of git://evilpiepirate.org/bcachefs: (27 commits)
  bcachefs: Fix sysfs warning in fstests generic/730,731
  bcachefs: Handle race between stripe reuse, invalidate_stripe_to_dev
  bcachefs: Fix kasan splat in new_stripe_alloc_buckets()
  bcachefs: Add missing validation for bch_stripe.csum_granularity_bits
  bcachefs: Fix missing bounds checks in bch2_alloc_read()
  bcachefs: fix uaf in bch2_dio_write_done()
  bcachefs: Improve check_snapshot_exists()
  bcachefs: Fix bkey_nocow_lock()
  bcachefs: Fix accounting replay flags
  bcachefs: Fix invalid shift in member_to_text()
  bcachefs: Fix bch2_have_enough_devs() for BCH_SB_MEMBER_INVALID
  bcachefs: __wait_for_freeing_inode: Switch to wait_bit_queue_entry
  bcachefs: Check if stuck in journal_res_get()
  closures: Add closure_wait_event_timeout()
  bcachefs: Fix state lock involved deadlock
  bcachefs: Fix NULL pointer dereference in bch2_opt_to_text
  bcachefs: Release transaction before wake up
  bcachefs: add check for btree id against max in try read node
  bcachefs: Disk accounting device validation fixes
  bcachefs: bch2_inode_or_descendents_is_open()
  ...
parents eca631b8 5e3b7232
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -639,6 +639,16 @@ int bch2_alloc_read(struct bch_fs *c)
				continue;
			}

			if (k.k->p.offset < ca->mi.first_bucket) {
				bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode, ca->mi.first_bucket));
				continue;
			}

			if (k.k->p.offset >= ca->mi.nbuckets) {
				bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode + 1, 0));
				continue;
			}

			struct bch_alloc_v4 a;
			*bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
			0;
+2 −1
Original line number Diff line number Diff line
@@ -678,7 +678,8 @@ struct bch_sb_field_ext {
	x(disk_accounting_v2,		BCH_VERSION(1,  9))		\
	x(disk_accounting_v3,		BCH_VERSION(1, 10))		\
	x(disk_accounting_inum,		BCH_VERSION(1, 11))		\
	x(rebalance_work_acct_fix,	BCH_VERSION(1, 12))
	x(rebalance_work_acct_fix,	BCH_VERSION(1, 12))		\
	x(inode_has_child_snapshots,	BCH_VERSION(1, 13))

enum bcachefs_metadata_version {
	bcachefs_metadata_version_min = 9,
+9 −6
Original line number Diff line number Diff line
@@ -1224,17 +1224,20 @@ int bch2_gc_gens(struct bch_fs *c)
	u64 b, start_time = local_clock();
	int ret;

	/*
	 * Ideally we would be using state_lock and not gc_gens_lock here, but that
	 * introduces a deadlock in the RO path - we currently take the state
	 * lock at the start of going RO, thus the gc thread may get stuck:
	 */
	if (!mutex_trylock(&c->gc_gens_lock))
		return 0;

	trace_and_count(c, gc_gens_start, c);

	down_read(&c->state_lock);
	/*
	 * We have to use trylock here. Otherwise, we would
	 * introduce a deadlock in the RO path - we take the
	 * state lock at the start of going RO.
	 */
	if (!down_read_trylock(&c->state_lock)) {
		mutex_unlock(&c->gc_gens_lock);
		return 0;
	}

	for_each_member_device(c, ca) {
		struct bucket_gens *gens = bucket_gens(ca);
+3 −2
Original line number Diff line number Diff line
@@ -1838,10 +1838,11 @@ static void btree_node_write_done(struct bch_fs *c, struct btree *b)
	struct btree_trans *trans = bch2_trans_get(c);

	btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
	__btree_node_write_done(c, b);
	six_unlock_read(&b->c.lock);

	/* we don't need transaction context anymore after we got the lock. */
	bch2_trans_put(trans);
	__btree_node_write_done(c, b);
	six_unlock_read(&b->c.lock);
}

static void btree_node_write_work(struct work_struct *work)
+3 −3
Original line number Diff line number Diff line
@@ -2381,9 +2381,9 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
		else
			iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k));

		if (unlikely(!(iter->flags & BTREE_ITER_is_extents)
			     ? bkey_gt(iter_pos, end)
			     : bkey_ge(iter_pos, end)))
		if (unlikely(iter->flags & BTREE_ITER_all_snapshots	? bpos_gt(iter_pos, end) :
			     iter->flags & BTREE_ITER_is_extents	? bkey_ge(iter_pos, end) :
									  bkey_gt(iter_pos, end)))
			goto end;

		break;
Loading