summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-08-26 23:31:43 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-08-26 23:31:43 -0800
commit17b8d5efc11585f3eb87238237df78f61fefc4fe (patch)
treed05c95ed2d824907b66597e635b47a08023749bb
parent31860830f9aea7b523cb3456050c6349e8bb41cf (diff)
bcache: delete an incorrect assertion
believe this was also made obsolete by the journal pipelining changes, but not quite sure wtf I was thinking when I wrote that. Also refactor a bit.
-rw-r--r--drivers/md/bcache/btree_io.c2
-rw-r--r--drivers/md/bcache/journal.c76
-rw-r--r--drivers/md/bcache/journal.h2
3 files changed, 42 insertions, 38 deletions
diff --git a/drivers/md/bcache/btree_io.c b/drivers/md/bcache/btree_io.c
index 57c820456b4f..a12b5684b63a 100644
--- a/drivers/md/bcache/btree_io.c
+++ b/drivers/md/bcache/btree_io.c
@@ -358,7 +358,7 @@ void bch_btree_node_read_done(struct cache_set *c, struct btree *b,
goto err;
err = "insufficient memory";
- ret = bch_journal_seq_blacklisted(c, le64_to_cpu(i->journal_seq), b);
+ ret = bch_journal_seq_should_ignore(c, le64_to_cpu(i->journal_seq), b);
if (ret < 0)
goto err;
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index fc76867d2201..50f3e781ed6e 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -176,13 +176,13 @@ static void journal_seq_blacklist_flush(struct journal *j,
closure_init_stack(&cl);
while (1) {
- mutex_lock(&c->journal.blacklist_lock);
+ mutex_lock(&j->blacklist_lock);
if (list_empty(&bl->nodes))
break;
b = list_first_entry(&bl->nodes, struct btree,
journal_seq_blacklisted);
- mutex_unlock(&c->journal.blacklist_lock);
+ mutex_unlock(&j->blacklist_lock);
/*
* b might be changing underneath us, but it won't be _freed_
@@ -202,11 +202,11 @@ static void journal_seq_blacklist_flush(struct journal *j,
closure_sync(&cl);
}
- journal_pin_drop(&c->journal, &bl->pin);
+ journal_pin_drop(j, &bl->pin);
list_del(&bl->list);
kfree(bl);
- mutex_unlock(&c->journal.blacklist_lock);
+ mutex_unlock(&j->blacklist_lock);
}
static struct journal_seq_blacklist *
@@ -237,61 +237,65 @@ bch_journal_seq_blacklisted_new(struct cache_set *c, u64 seq)
bl->seq = seq;
INIT_LIST_HEAD(&bl->nodes);
-
- BUG_ON(!list_empty(&j->seq_blacklist) &&
- list_last_entry(&j->seq_blacklist,
- struct journal_seq_blacklist,
- list)->seq >= bl->seq);
-
list_add_tail(&bl->list, &j->seq_blacklist);
return bl;
}
-static int __bch_journal_seq_blacklisted(struct cache_set *c, u64 seq,
- struct btree *b)
+/*
+ * Returns true if @seq is newer than the most recent journal entry that got
+ * written, and data corresponding to @seq should be ignored - also marks @seq
+ * as blacklisted so that on future restarts the corresponding data will still
+ * be ignored:
+ */
+int bch_journal_seq_should_ignore(struct cache_set *c, u64 seq, struct btree *b)
{
struct journal *j = &c->journal;
- struct journal_seq_blacklist *bl = journal_seq_blacklist_find(j, seq);
+ struct journal_seq_blacklist *bl;
+ int ret = 0;
+
+ /*
+ * After initial GC has finished, we've scanned the entire btree and
+ * found all the blacklisted sequence numbers - we won't be creating any
+ * new ones after startup:
+ */
+ if (test_bit(CACHE_SET_INITIAL_GC_DONE, &c->flags) &&
+ list_empty_careful(&j->seq_blacklist))
+ return 0;
+ mutex_lock(&j->blacklist_lock);
+
+ bl = journal_seq_blacklist_find(j, seq);
if (bl)
goto found;
/*
- * After startup, all the blacklisted sequence numbers will already be
- * in the list, we don't create new ones
+ * Don't look at j->seq after journal has started, since we aren't
+ * holding appropriate lock:
*/
+ if (test_bit(CACHE_SET_INITIAL_GC_DONE, &c->flags))
+ goto out;
if (seq <= j->seq)
- return 0;
+ goto out;
cache_set_inconsistent_on(seq > j->seq + 2, c,
"bset journal seq too far in the future: %llu > %llu",
seq, j->seq);
+ /*
+ * When we start the journal, bch_journal_start() will skip over @seq:
+ */
bl = bch_journal_seq_blacklisted_new(c, seq);
- if (!bl)
- return -ENOMEM;
+ if (!bl) {
+ ret = -ENOMEM;
+ goto out;
+ }
found:
- pr_debug("found %s blacklisted seq %llu",
- seq <= j->seq ? "old" : "new", seq);
-
if (list_empty(&b->journal_seq_blacklisted))
list_add(&b->journal_seq_blacklisted, &bl->nodes);
-
- return 1;
-}
-
-int bch_journal_seq_blacklisted(struct cache_set *c, u64 seq, struct btree *b)
-{
- int ret;
-
- if (test_bit(CACHE_SET_INITIAL_GC_DONE, &c->flags))
- return 0;
-
- mutex_lock(&c->journal.blacklist_lock);
- ret = __bch_journal_seq_blacklisted(c, seq, b);
- mutex_unlock(&c->journal.blacklist_lock);
-
+ ret = 1;
+out:
+ mutex_unlock(&j->blacklist_lock);
return ret;
}
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index 7fc789a9382a..0813e8d7d12b 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -193,7 +193,7 @@ struct keylist;
struct bkey_i *bch_journal_find_btree_root(struct cache_set *, struct jset *,
enum btree_id, unsigned *);
-int bch_journal_seq_blacklisted(struct cache_set *, u64, struct btree *);
+int bch_journal_seq_should_ignore(struct cache_set *, u64, struct btree *);
void bch_journal_add_keys(struct journal *, struct journal_res *,
enum btree_id, const struct bkey_i *);