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

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

Pull bcachefs fixes from Kent Overstreet:

 - fix ca->io_ref usage; analagous to previous patch doing that for main
   discard path

 - cond_resched() in __journal_keys_sort(), cutting down on "hung task"
   warnings when journal is big

 - rest of basic BCH_SB_MEMBER_INVALID support

 - and the critical one: don't delete open files in online fsck, this
   was causing the "dirent points to inode that doesn't point back"
   inconsistencies some users were seeing

* tag 'bcachefs-2024-09-09' of git://evilpiepirate.org/bcachefs:
  bcachefs: Don't delete open files in online fsck
  bcachefs: fix btree_key_cache sysfs knob
  bcachefs: More BCH_SB_MEMBER_INVALID support
  bcachefs: Simplify bch2_bkey_drop_ptrs()
  bcachefs: Add a cond_resched() to __journal_keys_sort()
  bcachefs: Fix ca->io_ref usage
parents fb92a1ff 16005147
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -1968,8 +1968,8 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
			break;
	}

	bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
	percpu_ref_put(&ca->io_ref);
	bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
}

static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket)
@@ -1979,18 +1979,18 @@ static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket)
	if (discard_in_flight_add(ca, bucket, false))
		return;

	if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard_fast))
		return;

	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard_fast))
		goto put_ioref;
	if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
		goto put_ref;

	if (queue_work(c->write_ref_wq, &ca->discard_fast_work))
		return;

	bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
put_ioref:
	percpu_ref_put(&ca->io_ref);
put_ref:
	bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
}

static int invalidate_one_bucket(struct btree_trans *trans,
@@ -2132,26 +2132,26 @@ static void bch2_do_invalidates_work(struct work_struct *work)
	bch2_trans_iter_exit(trans, &iter);
err:
	bch2_trans_put(trans);
	bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
	percpu_ref_put(&ca->io_ref);
	bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
}

void bch2_dev_do_invalidates(struct bch_dev *ca)
{
	struct bch_fs *c = ca->fs;

	if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate))
		return;

	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate))
		goto put_ioref;
	if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
		goto put_ref;

	if (queue_work(c->write_ref_wq, &ca->invalidate_work))
		return;

	bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
put_ioref:
	percpu_ref_put(&ca->io_ref);
put_ref:
	bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
}

void bch2_do_invalidates(struct bch_fs *c)
+2 −0
Original line number Diff line number Diff line
@@ -530,6 +530,8 @@ static void __journal_keys_sort(struct journal_keys *keys)
{
	sort(keys->data, keys->nr, sizeof(keys->data[0]), journal_sort_key_cmp, NULL);

	cond_resched();

	struct journal_key *dst = keys->data;

	darray_for_each(*keys, src) {
+8 −7
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ static int bch2_check_fix_ptr(struct btree_trans *trans,

	struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
	if (!ca) {
		if (fsck_err(trans, ptr_to_invalid_device,
		if (fsck_err_on(p.ptr.dev != BCH_SB_MEMBER_INVALID,
				trans, ptr_to_invalid_device,
				"pointer to missing device %u\n"
				"while marking %s",
				p.ptr.dev,
@@ -562,7 +563,7 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
	struct bch_fs *c = trans->c;
	struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
	if (unlikely(!ca)) {
		if (insert)
		if (insert && p.ptr.dev != BCH_SB_MEMBER_INVALID)
			ret = -EIO;
		goto err;
	}
+3 −1
Original line number Diff line number Diff line
@@ -97,7 +97,9 @@ static inline bool __bch2_ptr_matches_stripe(const struct bch_extent_ptr *stripe
					     const struct bch_extent_ptr *data_ptr,
					     unsigned sectors)
{
	return  data_ptr->dev    == stripe_ptr->dev &&
	return  (data_ptr->dev    == stripe_ptr->dev ||
		 data_ptr->dev    == BCH_SB_MEMBER_INVALID ||
		 stripe_ptr->dev  == BCH_SB_MEMBER_INVALID) &&
		data_ptr->gen    == stripe_ptr->gen &&
		data_ptr->offset >= stripe_ptr->offset &&
		data_ptr->offset  < stripe_ptr->offset + sectors;
+10 −16
Original line number Diff line number Diff line
@@ -781,14 +781,17 @@ static union bch_extent_entry *extent_entry_prev(struct bkey_ptrs ptrs,
/*
 * Returns pointer to the next entry after the one being dropped:
 */
union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s k,
						   struct bch_extent_ptr *ptr)
void bch2_bkey_drop_ptr_noerror(struct bkey_s k, struct bch_extent_ptr *ptr)
{
	struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
	union bch_extent_entry *entry = to_entry(ptr), *next;
	union bch_extent_entry *ret = entry;
	bool drop_crc = true;

	if (k.k->type == KEY_TYPE_stripe) {
		ptr->dev = BCH_SB_MEMBER_INVALID;
		return;
	}

	EBUG_ON(ptr < &ptrs.start->ptr ||
		ptr >= &ptrs.end->ptr);
	EBUG_ON(ptr->type != 1 << BCH_EXTENT_ENTRY_ptr);
@@ -811,20 +814,15 @@ union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s k,
			break;

		if ((extent_entry_is_crc(entry) && drop_crc) ||
		    extent_entry_is_stripe_ptr(entry)) {
			ret = (void *) ret - extent_entry_bytes(entry);
		    extent_entry_is_stripe_ptr(entry))
			extent_entry_drop(k, entry);
	}
}

	return ret;
}

union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s k,
					   struct bch_extent_ptr *ptr)
void bch2_bkey_drop_ptr(struct bkey_s k, struct bch_extent_ptr *ptr)
{
	bool have_dirty = bch2_bkey_dirty_devs(k.s_c).nr;
	union bch_extent_entry *ret =

	bch2_bkey_drop_ptr_noerror(k, ptr);

	/*
@@ -837,14 +835,10 @@ union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s k,
	    !bch2_bkey_dirty_devs(k.s_c).nr) {
		k.k->type = KEY_TYPE_error;
		set_bkey_val_u64s(k.k, 0);
		ret = NULL;
	} else if (!bch2_bkey_nr_ptrs(k.s_c)) {
		k.k->type = KEY_TYPE_deleted;
		set_bkey_val_u64s(k.k, 0);
		ret = NULL;
	}

	return ret;
}

void bch2_bkey_drop_device(struct bkey_s k, unsigned dev)
Loading