diff options
-rw-r--r-- | drivers/md/bcache/journal.c | 20 | ||||
-rw-r--r-- | drivers/md/bcache/journal.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 1 |
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: |