Commit 8f602276 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull bcachefs fixes from Kent Overstreet:
 "A lot of little fixes, bigger ones include:

   - bcachefs's __wait_on_freeing_inode() was broken in rc1 due to vfs
     changes, now fixed along with another lost wakeup

   - fragmentation LRU fixes; fsck now repairs successfully (this is the
     data structure copygc uses); along with some nice simplification.

   - Rework logged op error handling, so that if logged op replay errors
     (due to another filesystem error) we delete the logged op instead
     of going into an infinite loop)

   - Various small filesystem connectivitity repair fixes"

* tag 'bcachefs-2024-10-05' of git://evilpiepirate.org/bcachefs:
  bcachefs: Rework logged op error handling
  bcachefs: Add warn param to subvol_get_snapshot, peek_inode
  bcachefs: Kill snapshot arg to fsck_write_inode()
  bcachefs: Check for unlinked, non-empty dirs in check_inode()
  bcachefs: Check for unlinked inodes with dirents
  bcachefs: Check for directories with no backpointers
  bcachefs: Kill alloc_v4.fragmentation_lru
  bcachefs: minor lru fsck fixes
  bcachefs: Mark more errors AUTOFIX
  bcachefs: Make sure we print error that causes fsck to bail out
  bcachefs: bkey errors are only AUTOFIX during read
  bcachefs: Create lost+found in correct snapshot
  bcachefs: Fix reattach_inode()
  bcachefs: Add missing wakeup to bch2_inode_hash_remove()
  bcachefs: Fix trans_commit disk accounting revert
  bcachefs: Fix bch2_inode_is_open() check
  bcachefs: Fix return type of dirent_points_to_inode_nowarn()
  bcachefs: Fix bad shift in bch2_read_flag_list()
parents fc20a3e5 0f25eb4b
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -332,7 +332,6 @@ void bch2_alloc_v4_swab(struct bkey_s k)
	a->io_time[1]		= swab64(a->io_time[1]);
	a->stripe		= swab32(a->stripe);
	a->nr_external_backpointers = swab32(a->nr_external_backpointers);
	a->fragmentation_lru	= swab64(a->fragmentation_lru);
	a->stripe_sectors	= swab32(a->stripe_sectors);

	bps = alloc_v4_backpointers(a);
@@ -347,6 +346,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
{
	struct bch_alloc_v4 _a;
	const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
	struct bch_dev *ca = c ? bch2_dev_bucket_tryget_noerror(c, k.k->p) : NULL;

	prt_newline(out);
	printbuf_indent_add(out, 2);
@@ -364,9 +364,13 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
	prt_printf(out, "stripe_redundancy %u\n",	a->stripe_redundancy);
	prt_printf(out, "io_time[READ]     %llu\n",	a->io_time[READ]);
	prt_printf(out, "io_time[WRITE]    %llu\n",	a->io_time[WRITE]);
	prt_printf(out, "fragmentation     %llu\n",	a->fragmentation_lru);

	if (ca)
		prt_printf(out, "fragmentation     %llu\n",	alloc_lru_idx_fragmentation(*a, ca));
	prt_printf(out, "bp_start          %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a));
	printbuf_indent_sub(out, 2);

	bch2_dev_put(ca);
}

void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
@@ -882,12 +886,13 @@ int bch2_trigger_alloc(struct btree_trans *trans,
				goto err;
		}

		new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca);
		if (old_a->fragmentation_lru != new_a->fragmentation_lru) {
		old_lru = alloc_lru_idx_fragmentation(*old_a, ca);
		new_lru = alloc_lru_idx_fragmentation(*new_a, ca);
		if (old_lru != new_lru) {
			ret = bch2_lru_change(trans,
					BCH_LRU_FRAGMENTATION_START,
					bucket_to_u64(new.k->p),
					old_a->fragmentation_lru, new_a->fragmentation_lru);
					old_lru, new_lru);
			if (ret)
				goto err;
		}
@@ -1629,18 +1634,22 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
	if (ret)
		return ret;

	struct bch_dev *ca = bch2_dev_tryget_noerror(c, alloc_k.k->p.inode);
	if (!ca)
		return 0;

	a = bch2_alloc_to_v4(alloc_k, &a_convert);

	if (a->fragmentation_lru) {
	u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca);
	if (lru_idx) {
		ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START,
					 a->fragmentation_lru,
					 alloc_k, last_flushed);
					 lru_idx, alloc_k, last_flushed);
		if (ret)
			return ret;
			goto err;
	}

	if (a->data_type != BCH_DATA_cached)
		return 0;
		goto err;

	if (fsck_err_on(!a->io_time[READ],
			trans, alloc_key_cached_but_read_time_zero,
@@ -1669,6 +1678,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
		goto err;
err:
fsck_err:
	bch2_dev_put(ca);
	printbuf_exit(&buf);
	return ret;
}
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ struct bch_alloc_v4 {
	__u32			stripe;
	__u32			nr_external_backpointers;
	/* end of fields in original version of alloc_v4 */
	__u64			fragmentation_lru;
	__u64			_fragmentation_lru; /* obsolete */
	__u32			stripe_sectors;
	__u32			pad;
} __packed __aligned(8);
+0 −3
Original line number Diff line number Diff line
@@ -828,8 +828,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
			return ret;
	}

	gc.fragmentation_lru = alloc_lru_idx_fragmentation(gc, ca);

	if (fsck_err_on(new.data_type != gc.data_type,
			trans, alloc_key_data_type_wrong,
			"bucket %llu:%llu gen %u has wrong data_type"
@@ -857,7 +855,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
	copy_bucket_field(alloc_key_cached_sectors_wrong,	cached_sectors);
	copy_bucket_field(alloc_key_stripe_wrong,		stripe);
	copy_bucket_field(alloc_key_stripe_redundancy_wrong,	stripe_redundancy);
	copy_bucket_field(alloc_key_fragmentation_lru_wrong,	fragmentation_lru);
#undef copy_bucket_field

	if (!bch2_alloc_v4_cmp(*old, new))
+2 −1
Original line number Diff line number Diff line
@@ -832,7 +832,8 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
	for (struct jset_entry *entry2 = trans->journal_entries;
	     entry2 != entry;
	     entry2 = vstruct_next(entry2))
		if (jset_entry_is_key(entry2) && entry2->start->k.type == KEY_TYPE_accounting) {
		if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys &&
		    entry2->start->k.type == KEY_TYPE_accounting) {
			struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start);

			bch2_accounting_neg(a);
+18 −5
Original line number Diff line number Diff line
@@ -393,6 +393,14 @@ int __bch2_fsck_err(struct bch_fs *c,
	     !(flags & FSCK_CAN_IGNORE)))
		ret = -BCH_ERR_fsck_errors_not_fixed;

	bool exiting =
		test_bit(BCH_FS_fsck_running, &c->flags) &&
		(ret != -BCH_ERR_fsck_fix &&
		 ret != -BCH_ERR_fsck_ignore);

	if (exiting)
		print = true;

	if (print) {
		if (bch2_fs_stdio_redirect(c))
			bch2_print(c, "%s\n", out->buf);
@@ -400,9 +408,7 @@ int __bch2_fsck_err(struct bch_fs *c,
			bch2_print_string_as_lines(KERN_ERR, out->buf);
	}

	if (test_bit(BCH_FS_fsck_running, &c->flags) &&
	    (ret != -BCH_ERR_fsck_fix &&
	     ret != -BCH_ERR_fsck_ignore))
	if (exiting)
		bch_err(c, "Unable to continue, halting");
	else if (suppressing)
		bch_err(c, "Ratelimiting new instances of previous error");
@@ -430,10 +436,17 @@ int __bch2_fsck_err(struct bch_fs *c,

int __bch2_bkey_fsck_err(struct bch_fs *c,
			 struct bkey_s_c k,
			 enum bch_fsck_flags flags,
			 enum bch_validate_flags validate_flags,
			 enum bch_sb_error_id err,
			 const char *fmt, ...)
{
	if (validate_flags & BCH_VALIDATE_silent)
		return -BCH_ERR_fsck_delete_bkey;

	unsigned fsck_flags = 0;
	if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)))
		fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX;

	struct printbuf buf = PRINTBUF;
	va_list args;

@@ -445,7 +458,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c,
	va_end(args);
	prt_str(&buf, ": delete?");

	int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf);
	int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf);
	printbuf_exit(&buf);
	return ret;
}
Loading