summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/journal.c20
-rw-r--r--drivers/md/bcache/journal.h2
-rw-r--r--drivers/md/bcache/super.c1
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 765e529c222a..f1c9784e9b07 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -387,6 +387,11 @@ err:
return ret;
}
+void bch_journal_space_reserve(struct journal *j)
+{
+ j->do_reserve = true;
+}
+
/* Journalling */
#define journal_max_cmp(l, r) \
(fifo_idx(&c->journal.pin, btree_current_write(l)->journal) < \
@@ -507,6 +512,17 @@ static void do_journal_discard(struct cache *ca)
}
}
+static bool dev_has_journal_buckets_free(struct cache_set *c, struct cache *ca)
+{
+ struct journal *j = &c->journal;
+ struct journal_device *ja = &ca->journal;
+ unsigned nr_free = (ca->sb.njournal_buckets +
+ ja->discard_idx - ja->cur_idx) %
+ ca->sb.njournal_buckets;
+
+ return nr_free > 1 + j->do_reserve;
+}
+
static void journal_reclaim(struct cache_set *c)
{
struct bkey *k = &c->journal.key;
@@ -549,8 +565,8 @@ static void journal_reclaim(struct cache_set *c)
unsigned next = (ja->cur_idx + 1) % ca->sb.njournal_buckets;
/* No space available on this device */
- if (next == ja->discard_idx)
- continue;
+ if (!dev_has_journal_buckets_free(c, ca))
+ goto out;
ja->cur_idx = next;
k->ptr[n++] = MAKE_PTR(0,
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index b5788199188f..bfc2007cfff1 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -103,6 +103,7 @@ struct journal_write {
/* Embedded in struct cache_set */
struct journal {
spinlock_t lock;
+ bool do_reserve;
/* used when waiting because the journal was full */
struct closure_waitlist wait;
struct closure io;
@@ -176,5 +177,6 @@ int bch_journal_replay(struct cache_set *, struct list_head *);
void bch_journal_free(struct cache_set *);
int bch_journal_alloc(struct cache_set *);
+void bch_journal_space_reserve(struct journal *j);
#endif /* _BCACHE_JOURNAL_H */
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 7fe842176421..41120ee4ab72 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1943,6 +1943,7 @@ static int run_cache_set(struct cache_set *c)
flash_devs_run(c);
+ bch_journal_space_reserve(&c->journal);
set_bit(CACHE_SET_RUNNING, &c->flags);
return 0;
err: