summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-12-21 13:54:24 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:41:31 -0900
commite869a3a639bcc2101212ab58a16af080c82c6bd8 (patch)
tree635a90fce05e1ac44feee5ed4d5d46ef43bfde04
parent4557025dd5aed1d910caaf5b85dac76668a803e6 (diff)
bcache: fixups for "short circuit bch_prio_write() and journal flush when possible"
-rw-r--r--drivers/md/bcache/alloc.c1
-rw-r--r--drivers/md/bcache/btree_cache.c3
-rw-r--r--drivers/md/bcache/buckets.c7
-rw-r--r--drivers/md/bcache/buckets_types.h6
4 files changed, 13 insertions, 4 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 0887ed3eccd1..45d5ab8c790e 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -777,6 +777,7 @@ static void bch_find_empty_buckets(struct cache_set *c, struct cache *ca)
if (is_available_bucket(m) &&
!m.cached_sectors &&
+ !m.had_metadata &&
(!m.wait_on_journal ||
((s16) last_seq_ondisk - (s16) m.journal_seq >= 0))) {
spin_lock(&ca->freelist_lock);
diff --git a/drivers/md/bcache/btree_cache.c b/drivers/md/bcache/btree_cache.c
index 07c37c1de1fe..099419067138 100644
--- a/drivers/md/bcache/btree_cache.c
+++ b/drivers/md/bcache/btree_cache.c
@@ -693,6 +693,9 @@ retry:
}
EBUG_ON(!b->written);
+ EBUG_ON(b->btree_id != iter->btree_id ||
+ BSET_BTREE_LEVEL(&b->data->keys) != level ||
+ bkey_cmp(b->data->max_key, k->k.p));
return b;
}
diff --git a/drivers/md/bcache/buckets.c b/drivers/md/bcache/buckets.c
index 90dfa03b0a7a..1e617dbc61d8 100644
--- a/drivers/md/bcache/buckets.c
+++ b/drivers/md/bcache/buckets.c
@@ -360,6 +360,7 @@ void bch_mark_metadata_bucket(struct cache *ca, struct bucket *g,
old = bucket_cmpxchg(g, new, ({
new.is_metadata = 1;
+ new.had_metadata = 1;
}));
BUG_ON(old.cached_sectors);
@@ -471,10 +472,6 @@ static void bch_mark_pointer(struct cache_set *c,
is_available_bucket(old) &&
test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags));
- BUG_ON((old.dirty_sectors ||
- old.cached_sectors) &&
- old.is_metadata != (type == S_META));
-
if (type != S_CACHED &&
new.dirty_sectors == GC_MAX_SECTORS_USED &&
disk_sectors < 0)
@@ -498,6 +495,8 @@ static void bch_mark_pointer(struct cache_set *c,
} else {
new.is_metadata = (type == S_META);
}
+
+ new.had_metadata |= new.is_metadata;
} while ((v = cmpxchg(&g->_mark.counter,
old.counter,
new.counter)) != old.counter);
diff --git a/drivers/md/bcache/buckets_types.h b/drivers/md/bcache/buckets_types.h
index 90bb09c6db35..6bbdcd26fba4 100644
--- a/drivers/md/bcache/buckets_types.h
+++ b/drivers/md/bcache/buckets_types.h
@@ -14,6 +14,12 @@ struct bucket_mark {
unsigned copygc:1;
unsigned wait_on_journal:1;
+ /*
+ * If this bucket ever had metadata in it, the allocator must
+ * increment its gen before we reuse it:
+ */
+ unsigned had_metadata:1;
+
unsigned owned_by_allocator:1;
unsigned is_metadata:1;