Commit 791c8ab0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2023-11-17' of https://evilpiepirate.org/git/bcachefs

Pull bcachefs fixes from Kent Overstreet:
 "Lots of small fixes for minor nits and compiler warnings.

  Bigger items:

   - The six locks lost wakeup is finally fixed: six_read_trylock() was
     checking for the waiting bit before decrementing the number of
     readers - validated the fix with a torture test.

   - Fix for a memory reclaim issue: when needing to reallocate a key
     cache key, we now do our usual GFP_NOWAIT; unlock(); GFP_KERNEL
     dance.

   - Multiple deleted inodes btree fixes

   - Fix an issue in fsck, where i_nlink would be recalculated
     incorrectly for hardlinked files if a snapshot had ever been taken.

   - Kill journal pre-reservations: This is a bigger patch than I would
     normally send at this point, but it deletes code and it fixes some
     of our tests that would sporadically die with the journal getting
     stuck, and it's a performance improvement, too"

* tag 'bcachefs-2023-11-17' of https://evilpiepirate.org/git/bcachefs: (22 commits)
  bcachefs: Fix missing locking for dentry->d_parent access
  bcachefs: six locks: Fix lost wakeup
  bcachefs: Fix no_data_io mode checksum check
  bcachefs: Fix bch2_check_nlinks() for snapshots
  bcachefs: Don't decrease BTREE_ITER_MAX when LOCKDEP=y
  bcachefs: Disable debug log statements
  bcachefs: Fix missing transaction commit
  bcachefs: Fix error path in bch2_mount()
  bcachefs: Fix potential sleeping during mount
  bcachefs: Fix iterator leak in may_delete_deleted_inode()
  bcachefs: Kill journal pre-reservations
  bcachefs: Check for nonce offset inconsistency in data_update path
  bcachefs: Make sure to drop/retake btree locks before reclaim
  bcachefs: btree_trans->write_locked
  bcachefs: Run btree key cache shrinker less aggressively
  bcachefs: Split out btree_key_cache_types.h
  bcachefs: Guard against insufficient devices to create stripes
  bcachefs: Fix null ptr deref in bch2_backpointer_get_node()
  bcachefs: Fix multiple -Warray-bounds warnings
  bcachefs: Use DECLARE_FLEX_ARRAY() helper and fix multiple -Warray-bounds warnings
  ...
parents 12ee72fe ba276ce5
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -313,17 +313,17 @@ struct btree *bch2_backpointer_get_node(struct btree_trans *trans,
				  bp.level - 1,
				  0);
	b = bch2_btree_iter_peek_node(iter);
	if (IS_ERR(b))
	if (IS_ERR_OR_NULL(b))
		goto err;

	BUG_ON(b->c.level != bp.level - 1);

	if (b && extent_matches_bp(c, bp.btree_id, bp.level,
	if (extent_matches_bp(c, bp.btree_id, bp.level,
			      bkey_i_to_s_c(&b->key),
			      bucket, bp))
		return b;

	if (b && btree_node_will_make_reachable(b)) {
	if (btree_node_will_make_reachable(b)) {
		b = ERR_PTR(-BCH_ERR_backpointer_to_overwritten_btree_node);
	} else {
		backpointer_not_found(trans, bp_pos, bp, bkey_i_to_s_c(&b->key));
+1 −1
Original line number Diff line number Diff line
@@ -617,7 +617,7 @@ struct journal_seq_blacklist_table {
		u64		start;
		u64		end;
		bool		dirty;
	}			entries[0];
	}			entries[];
};

struct journal_keys {
+0 −2
Original line number Diff line number Diff line
@@ -3087,8 +3087,6 @@ void bch2_trans_put(struct btree_trans *trans)
		srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx);
	}

	bch2_journal_preres_put(&c->journal, &trans->journal_preres);

	kfree(trans->extra_journal_entries.data);

	if (trans->fs_usage_deltas) {
+19 −18
Original line number Diff line number Diff line
@@ -89,10 +89,13 @@ static void bkey_cached_free(struct btree_key_cache *bc,
	ck->btree_trans_barrier_seq =
		start_poll_synchronize_srcu(&c->btree_trans_barrier);

	if (ck->c.lock.readers)
	if (ck->c.lock.readers) {
		list_move_tail(&ck->list, &bc->freed_pcpu);
	else
		bc->nr_freed_pcpu++;
	} else {
		list_move_tail(&ck->list, &bc->freed_nonpcpu);
		bc->nr_freed_nonpcpu++;
	}
	atomic_long_inc(&bc->nr_freed);

	kfree(ck->k);
@@ -109,6 +112,8 @@ static void __bkey_cached_move_to_freelist_ordered(struct btree_key_cache *bc,
{
	struct bkey_cached *pos;

	bc->nr_freed_nonpcpu++;

	list_for_each_entry_reverse(pos, &bc->freed_nonpcpu, list) {
		if (ULONG_CMP_GE(ck->btree_trans_barrier_seq,
				 pos->btree_trans_barrier_seq)) {
@@ -158,6 +163,7 @@ static void bkey_cached_move_to_freelist(struct btree_key_cache *bc,
#else
		mutex_lock(&bc->lock);
		list_move_tail(&ck->list, &bc->freed_nonpcpu);
		bc->nr_freed_nonpcpu++;
		mutex_unlock(&bc->lock);
#endif
	} else {
@@ -217,6 +223,7 @@ bkey_cached_alloc(struct btree_trans *trans, struct btree_path *path,
			       f->nr < ARRAY_SIZE(f->objs) / 2) {
				ck = list_last_entry(&bc->freed_nonpcpu, struct bkey_cached, list);
				list_del_init(&ck->list);
				bc->nr_freed_nonpcpu--;
				f->objs[f->nr++] = ck;
			}

@@ -229,6 +236,7 @@ bkey_cached_alloc(struct btree_trans *trans, struct btree_path *path,
		if (!list_empty(&bc->freed_nonpcpu)) {
			ck = list_last_entry(&bc->freed_nonpcpu, struct bkey_cached, list);
			list_del_init(&ck->list);
			bc->nr_freed_nonpcpu--;
		}
		mutex_unlock(&bc->lock);
#endif
@@ -664,7 +672,6 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
		goto out;

	bch2_journal_pin_drop(j, &ck->journal);
	bch2_journal_preres_put(j, &ck->res);

	BUG_ON(!btree_node_locked(c_iter.path, 0));

@@ -762,18 +769,6 @@ bool bch2_btree_insert_key_cached(struct btree_trans *trans,

	BUG_ON(insert->k.u64s > ck->u64s);

	if (likely(!(flags & BTREE_INSERT_JOURNAL_REPLAY))) {
		int difference;

		BUG_ON(jset_u64s(insert->k.u64s) > trans->journal_preres.u64s);

		difference = jset_u64s(insert->k.u64s) - ck->res.u64s;
		if (difference > 0) {
			trans->journal_preres.u64s	-= difference;
			ck->res.u64s			+= difference;
		}
	}

	bkey_copy(ck->k, insert);
	ck->valid = true;

@@ -850,6 +845,8 @@ static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink,
	 * Newest freed entries are at the end of the list - once we hit one
	 * that's too new to be freed, we can bail out:
	 */
	scanned += bc->nr_freed_nonpcpu;

	list_for_each_entry_safe(ck, t, &bc->freed_nonpcpu, list) {
		if (!poll_state_synchronize_srcu(&c->btree_trans_barrier,
						 ck->btree_trans_barrier_seq))
@@ -859,13 +856,15 @@ static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink,
		six_lock_exit(&ck->c.lock);
		kmem_cache_free(bch2_key_cache, ck);
		atomic_long_dec(&bc->nr_freed);
		scanned++;
		freed++;
		bc->nr_freed_nonpcpu--;
	}

	if (scanned >= nr)
		goto out;

	scanned += bc->nr_freed_pcpu;

	list_for_each_entry_safe(ck, t, &bc->freed_pcpu, list) {
		if (!poll_state_synchronize_srcu(&c->btree_trans_barrier,
						 ck->btree_trans_barrier_seq))
@@ -875,8 +874,8 @@ static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink,
		six_lock_exit(&ck->c.lock);
		kmem_cache_free(bch2_key_cache, ck);
		atomic_long_dec(&bc->nr_freed);
		scanned++;
		freed++;
		bc->nr_freed_pcpu--;
	}

	if (scanned >= nr)
@@ -982,6 +981,9 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
	}
#endif

	BUG_ON(list_count_nodes(&bc->freed_pcpu) != bc->nr_freed_pcpu);
	BUG_ON(list_count_nodes(&bc->freed_nonpcpu) != bc->nr_freed_nonpcpu);

	list_splice(&bc->freed_pcpu,	&items);
	list_splice(&bc->freed_nonpcpu,	&items);

@@ -991,7 +993,6 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
		cond_resched();

		bch2_journal_pin_drop(&c->journal, &ck->journal);
		bch2_journal_preres_put(&c->journal, &ck->res);

		list_del(&ck->list);
		kfree(ck->k);
+34 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_BTREE_KEY_CACHE_TYPES_H
#define _BCACHEFS_BTREE_KEY_CACHE_TYPES_H

struct btree_key_cache_freelist {
	struct bkey_cached	*objs[16];
	unsigned		nr;
};

struct btree_key_cache {
	struct mutex		lock;
	struct rhashtable	table;
	bool			table_init_done;

	struct list_head	freed_pcpu;
	size_t			nr_freed_pcpu;
	struct list_head	freed_nonpcpu;
	size_t			nr_freed_nonpcpu;

	struct shrinker		*shrink;
	unsigned		shrink_iter;
	struct btree_key_cache_freelist __percpu *pcpu_freed;

	atomic_long_t		nr_freed;
	atomic_long_t		nr_keys;
	atomic_long_t		nr_dirty;
};

struct bkey_cached_key {
	u32			btree_id;
	struct bpos		pos;
} __packed __aligned(4);

#endif /* _BCACHEFS_BTREE_KEY_CACHE_TYPES_H */
Loading