summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-02-20 02:34:51 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-07-26 00:16:50 -0800
commitf7b8614c2979c15539479261a18a98590cdd8b9b (patch)
tree4f19f071c6932c5da20bfd01dfbc749925be10db
parent5d32d3c64bd7a7d767037bbb8191e62ad5c62f6e (diff)
bcache: kill BCH_WRITE_CHECK_ENOSPC
-rw-r--r--drivers/md/bcache/alloc.c27
-rw-r--r--drivers/md/bcache/alloc.h5
-rw-r--r--drivers/md/bcache/btree_update.c17
-rw-r--r--drivers/md/bcache/btree_update.h1
-rw-r--r--drivers/md/bcache/buckets.c22
-rw-r--r--drivers/md/bcache/buckets.h2
-rw-r--r--drivers/md/bcache/fs-io.c30
-rw-r--r--drivers/md/bcache/io.c4
-rw-r--r--drivers/md/bcache/io.h11
-rw-r--r--drivers/md/bcache/io_types.h2
-rw-r--r--drivers/md/bcache/migrate.c7
-rw-r--r--drivers/md/bcache/move.c3
-rw-r--r--drivers/md/bcache/move.h1
13 files changed, 65 insertions, 67 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 59d3574465df..6e732325df65 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -971,8 +971,7 @@ static enum bucket_alloc_ret __bch_bucket_alloc_set(struct cache_set *c,
enum alloc_reserve reserve,
unsigned nr_replicas,
struct cache_group *devs,
- long *caches_used,
- bool check_enospc)
+ long *caches_used)
{
enum bucket_alloc_ret ret;
@@ -1037,19 +1036,11 @@ static enum bucket_alloc_ret __bch_bucket_alloc_set(struct cache_set *c,
.offset = bucket_to_sector(ca, r),
.dev = ca->sb.nr_this_dev,
};
-
- if (check_enospc && cache_set_full(c)) {
- ret = CACHE_SET_FULL;
- goto err_nocheck;
- }
}
rcu_read_unlock();
return ALLOC_SUCCESS;
err:
- if (check_enospc && cache_set_full(c))
- ret = CACHE_SET_FULL;
-err_nocheck:
rcu_read_unlock();
return ret;
}
@@ -1058,15 +1049,14 @@ static int bch_bucket_alloc_set(struct cache_set *c, struct open_bucket *ob,
enum alloc_reserve reserve,
unsigned nr_replicas,
struct cache_group *devs, long *caches_used,
- bool check_enospc, struct closure *cl)
+ struct closure *cl)
{
struct closure_waitlist *waitlist = NULL;
bool waiting = false;
while (1) {
switch (__bch_bucket_alloc_set(c, ob, reserve, nr_replicas,
- devs, caches_used,
- check_enospc)) {
+ devs, caches_used)) {
case ALLOC_SUCCESS:
if (waitlist)
closure_wake_up(waitlist);
@@ -1271,7 +1261,6 @@ static int open_bucket_add_buckets(struct cache_set *c,
struct open_bucket *ob,
struct bkey_i_extent *e,
unsigned nr_replicas,
- bool check_enospc,
struct closure *cl)
{
const struct bch_extent_ptr *ptr;
@@ -1317,8 +1306,7 @@ static int open_bucket_add_buckets(struct cache_set *c,
}
return bch_bucket_alloc_set(c, ob, wp->reserve, nr_replicas,
- wp->group, caches_used,
- check_enospc, cl);
+ wp->group, caches_used, cl);
}
/*
@@ -1328,7 +1316,6 @@ struct open_bucket *bch_alloc_sectors_start(struct cache_set *c,
struct write_point *wp,
struct bkey_i_extent *e,
unsigned nr_replicas,
- bool check_enospc,
struct closure *cl)
{
struct open_bucket *ob;
@@ -1382,8 +1369,7 @@ retry:
ob = new_ob;
}
- ret = open_bucket_add_buckets(c, wp, ob, e, nr_replicas,
- check_enospc, cl);
+ ret = open_bucket_add_buckets(c, wp, ob, e, nr_replicas, cl);
if (ret) {
mutex_unlock(&ob->lock);
return ERR_PTR(ret);
@@ -1476,12 +1462,11 @@ struct open_bucket *bch_alloc_sectors(struct cache_set *c,
struct write_point *wp,
struct bkey_i_extent *e,
unsigned nr_replicas,
- bool check_enospc,
struct closure *cl)
{
struct open_bucket *ob;
- ob = bch_alloc_sectors_start(c, wp, e, nr_replicas, check_enospc, cl);
+ ob = bch_alloc_sectors_start(c, wp, e, nr_replicas, cl);
if (IS_ERR_OR_NULL(ob))
return ob;
diff --git a/drivers/md/bcache/alloc.h b/drivers/md/bcache/alloc.h
index 4a7afd213958..eb1bd5e3b6a3 100644
--- a/drivers/md/bcache/alloc.h
+++ b/drivers/md/bcache/alloc.h
@@ -19,14 +19,13 @@ void bch_open_bucket_put(struct cache_set *, struct open_bucket *);
struct open_bucket *bch_alloc_sectors_start(struct cache_set *,
struct write_point *,
struct bkey_i_extent *,
- unsigned, bool,
- struct closure *);
+ unsigned, struct closure *);
void bch_alloc_sectors_done(struct cache_set *, struct write_point *,
struct bkey_i_extent *, unsigned,
struct open_bucket *, unsigned);
struct open_bucket *bch_alloc_sectors(struct cache_set *, struct write_point *,
- struct bkey_i_extent *, unsigned, bool,
+ struct bkey_i_extent *, unsigned,
struct closure *);
static inline void bch_wake_allocator(struct cache *ca)
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index aea66cc8e68c..d3322ce47297 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -229,7 +229,6 @@ void btree_open_bucket_put(struct cache_set *c, struct btree *b)
}
static struct btree *__bch_btree_node_alloc(struct cache_set *c,
- bool check_enospc,
struct closure *cl)
{
BKEY_PADDED(k) tmp;
@@ -255,8 +254,7 @@ retry:
ob = bch_alloc_sectors(c, &c->btree_write_point,
bkey_i_to_extent(&tmp.k),
- c->opts.metadata_replicas,
- check_enospc, cl);
+ c->opts.metadata_replicas, cl);
if (IS_ERR(ob))
return ERR_CAST(ob);
@@ -447,6 +445,8 @@ static struct btree *__btree_root_alloc(struct cache_set *c, unsigned level,
void bch_btree_reserve_put(struct cache_set *c, struct btree_reserve *reserve)
{
+ atomic64_sub_bug(reserve->sectors_reserved, &c->sectors_reserved);
+
mutex_lock(&c->btree_reserve_cache_lock);
while (reserve->nr) {
@@ -484,8 +484,16 @@ static struct btree_reserve *__bch_btree_reserve_get(struct cache_set *c,
{
struct btree_reserve *reserve;
struct btree *b;
+ unsigned sectors_reserved = 0;
int ret;
+ if (check_enospc) {
+ sectors_reserved = nr_nodes * c->sb.btree_node_size;
+
+ if (bch_reserve_sectors(c, sectors_reserved))
+ return ERR_PTR(-ENOSPC);
+ }
+
BUG_ON(nr_nodes > BTREE_RESERVE_MAX);
/*
@@ -498,10 +506,11 @@ static struct btree_reserve *__bch_btree_reserve_get(struct cache_set *c,
reserve = mempool_alloc(&c->btree_reserve_pool, GFP_NOIO);
+ reserve->sectors_reserved = sectors_reserved;
reserve->nr = 0;
while (reserve->nr < nr_nodes) {
- b = __bch_btree_node_alloc(c, check_enospc, cl);
+ b = __bch_btree_node_alloc(c, cl);
if (IS_ERR(b)) {
ret = PTR_ERR(b);
goto err_free;
diff --git a/drivers/md/bcache/btree_update.h b/drivers/md/bcache/btree_update.h
index b3debb9d4784..e4ccd1ddb7e7 100644
--- a/drivers/md/bcache/btree_update.h
+++ b/drivers/md/bcache/btree_update.h
@@ -10,6 +10,7 @@ struct bkey_format;
struct btree;
struct btree_reserve {
+ unsigned sectors_reserved;
unsigned nr;
struct btree *b[];
};
diff --git a/drivers/md/bcache/buckets.c b/drivers/md/bcache/buckets.c
index 7f9fb8092e44..a78d883ee656 100644
--- a/drivers/md/bcache/buckets.c
+++ b/drivers/md/bcache/buckets.c
@@ -436,3 +436,25 @@ void bch_unmark_open_bucket(struct cache *ca, struct bucket *g)
new.owned_by_allocator = 0;
}));
}
+
+#define SECTORS_CACHE 1024
+
+int bch_reserve_sectors(struct cache_set *c, unsigned sectors)
+{
+ u64 sectors_to_get = SECTORS_CACHE + sectors;
+
+ if (likely(atomic64_sub_return(sectors,
+ &c->sectors_reserved_cache) >= 0))
+ return 0;
+
+ atomic64_add(sectors_to_get, &c->sectors_reserved);
+
+ if (likely(!cache_set_full(c))) {
+ atomic64_add(sectors_to_get, &c->sectors_reserved_cache);
+ return 0;
+ }
+
+ atomic64_sub_bug(sectors_to_get, &c->sectors_reserved);
+ atomic64_add(sectors, &c->sectors_reserved_cache);
+ return -ENOSPC;
+}
diff --git a/drivers/md/bcache/buckets.h b/drivers/md/bcache/buckets.h
index ac3f1b59d957..0c68ad57a23b 100644
--- a/drivers/md/bcache/buckets.h
+++ b/drivers/md/bcache/buckets.h
@@ -244,4 +244,6 @@ void bch_unmark_open_bucket(struct cache *, struct bucket *);
int bch_mark_pointers(struct cache_set *, struct bkey_s_c_extent,
int, bool, bool, bool, struct gc_pos);
+int bch_reserve_sectors(struct cache_set *, unsigned);
+
#endif /* _BUCKETS_H */
diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c
index 7efe53c563a8..173d5c9f4c65 100644
--- a/drivers/md/bcache/fs-io.c
+++ b/drivers/md/bcache/fs-io.c
@@ -360,7 +360,7 @@ union { struct {
*
* BCH_PAGE_UNALLOCATED: page is not fully written on disk, or is
* compressed - before writing we have to reserve space with
- * reserve_sectors()
+ * bch_reserve_sectors()
*
* BCH_PAGE_RESERVED: page has space reserved on disk (reservation will
* be consumed when the page is written).
@@ -411,28 +411,6 @@ union { struct {
_old; \
})
-#define SECTORS_CACHE 1024
-
-static int reserve_sectors(struct cache_set *c, unsigned sectors)
-{
- u64 sectors_to_get = SECTORS_CACHE + sectors;
-
- if (likely(atomic64_sub_return(sectors,
- &c->sectors_reserved_cache) >= 0))
- return 0;
-
- atomic64_add(sectors_to_get, &c->sectors_reserved);
-
- if (likely(!cache_set_full(c))) {
- atomic64_add(sectors_to_get, &c->sectors_reserved_cache);
- return 0;
- }
-
- atomic64_sub_bug(sectors_to_get, &c->sectors_reserved);
- atomic64_add(sectors, &c->sectors_reserved_cache);
- return -ENOSPC;
-}
-
static inline struct bch_page_state *page_state(struct page *page)
{
struct bch_page_state *s = (void *) &page->private;
@@ -466,7 +444,7 @@ static int bch_get_page_reservation(struct cache_set *c, struct page *page)
if (s->alloc_state != BCH_PAGE_UNALLOCATED)
return 0;
- ret = reserve_sectors(c, PAGE_SECTORS);
+ ret = bch_reserve_sectors(c, PAGE_SECTORS);
if (ret)
return ret;
@@ -1491,7 +1469,7 @@ static int bch_direct_IO_write(struct cache_set *c, struct kiocb *req,
* Have to then guard against racing with truncate (deleting data that
* we would have been overwriting)
*/
- ret = reserve_sectors(c, dio->nr_sectors);
+ ret = bch_reserve_sectors(c, dio->nr_sectors);
if (ret)
goto err_put_sectors_dirty;
@@ -2325,7 +2303,7 @@ static long bch_fallocate(struct inode *inode, int mode,
sectors = reservation.k.size;
- ret = reserve_sectors(c, sectors);
+ ret = bch_reserve_sectors(c, sectors);
if (ret)
goto err_put_sectors_dirty;
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 19bd1b44f66d..aac4eaa33f08 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -1012,7 +1012,6 @@ static void __bch_write(struct closure *cl)
b = bch_alloc_sectors_start(op->c, op->wp,
bkey_i_to_extent(k),
op->nr_replicas,
- op->check_enospc,
op->nowait ? NULL : cl);
BUG_ON(!b);
@@ -1226,7 +1225,6 @@ void bch_write_op_init(struct bch_write_op *op, struct cache_set *c,
op->written = 0;
op->error = 0;
op->flags = 0;
- op->check_enospc = (flags & BCH_WRITE_CHECK_ENOSPC) != 0;
op->nowait = (flags & BCH_WRITE_ALLOC_NOWAIT) != 0;
op->discard = (flags & BCH_WRITE_DISCARD) != 0;
op->cached = (flags & BCH_WRITE_CACHED) != 0;
@@ -1351,7 +1349,6 @@ void __cache_promote(struct cache_set *c, struct bbio *orig_bio,
bch_write_op_init(&op->iop, c, &op->bio, &c->promote_write_point,
new, old,
- BCH_WRITE_CHECK_ENOSPC|
BCH_WRITE_ALLOC_NOWAIT|write_flags);
op->iop.nr_replicas = 1;
@@ -1729,7 +1726,6 @@ void bch_read_extent_iter(struct cache_set *c, struct bio *orig,
&promote_op->bio,
&c->promote_write_point,
k, NULL, NULL,
- BCH_WRITE_CHECK_ENOSPC|
BCH_WRITE_ALLOC_NOWAIT);
if (!read_full) {
diff --git a/drivers/md/bcache/io.h b/drivers/md/bcache/io.h
index 490742660193..d165fc468f78 100644
--- a/drivers/md/bcache/io.h
+++ b/drivers/md/bcache/io.h
@@ -17,12 +17,11 @@
container_of((_bio), struct bch_write_bio, bio.bio)
enum bch_write_flags {
- BCH_WRITE_CHECK_ENOSPC = (1 << 0),
- BCH_WRITE_ALLOC_NOWAIT = (1 << 1),
- BCH_WRITE_DISCARD = (1 << 2),
- BCH_WRITE_CACHED = (1 << 3),
- BCH_WRITE_FLUSH = (1 << 4),
- BCH_WRITE_DISCARD_ON_ERROR = (1 << 5),
+ BCH_WRITE_ALLOC_NOWAIT = (1 << 0),
+ BCH_WRITE_DISCARD = (1 << 1),
+ BCH_WRITE_CACHED = (1 << 2),
+ BCH_WRITE_FLUSH = (1 << 3),
+ BCH_WRITE_DISCARD_ON_ERROR = (1 << 4),
};
void bch_write_op_init(struct bch_write_op *, struct cache_set *,
diff --git a/drivers/md/bcache/io_types.h b/drivers/md/bcache/io_types.h
index 88d35b8d3590..3946f2b7ba22 100644
--- a/drivers/md/bcache/io_types.h
+++ b/drivers/md/bcache/io_types.h
@@ -82,8 +82,6 @@ struct bch_write_op {
u16 flags;
struct {
- /* Return -ENOSPC if cache set is full? */
- unsigned check_enospc:1;
/* Return -ENOSPC if no buckets immediately available? */
unsigned nowait:1;
/* Discard key range? */
diff --git a/drivers/md/bcache/migrate.c b/drivers/md/bcache/migrate.c
index 685e96389e28..18c97ba8ec7a 100644
--- a/drivers/md/bcache/migrate.c
+++ b/drivers/md/bcache/migrate.c
@@ -39,10 +39,15 @@ static int issue_migration_move(struct cache *ca,
struct cache_set *c = ca->set;
struct moving_io *io;
+ if (bch_reserve_sectors(c, k.k->size))
+ return -ENOSPC;
+
io = moving_io_alloc(k);
if (io == NULL)
return -ENOMEM;
+ io->has_reservation = true;
+
/* This also copies k into the write op's replace_key and insert_key */
bch_replace_init(&io->replace, k);
@@ -50,7 +55,7 @@ static int issue_migration_move(struct cache *ca,
bch_write_op_init(&io->op, c, &io->bio,
&c->migration_write_point,
k, &io->replace.hook, NULL,
- BCH_WRITE_CHECK_ENOSPC);
+ 0);
io->op.nr_replicas = 1;
io->op.io_wq = q->wq;
diff --git a/drivers/md/bcache/move.c b/drivers/md/bcache/move.c
index 5c3750fc5c23..003865c596a3 100644
--- a/drivers/md/bcache/move.c
+++ b/drivers/md/bcache/move.c
@@ -112,6 +112,9 @@ struct moving_io *moving_io_alloc(struct bkey_s_c k)
void moving_io_free(struct moving_io *io)
{
+ if (io->has_reservation)
+ atomic64_sub_bug(io->key.k.size, &io->op.c->sectors_reserved);
+
bch_bio_free_pages(&io->bio.bio.bio);
kfree(io);
}
diff --git a/drivers/md/bcache/move.h b/drivers/md/bcache/move.h
index a265578b69cd..6d5a96b06b07 100644
--- a/drivers/md/bcache/move.h
+++ b/drivers/md/bcache/move.h
@@ -91,6 +91,7 @@ struct moving_io {
unsigned read_issued:1;
unsigned read_completed:1;
unsigned write_issued:1;
+ unsigned has_reservation:1;
/* Must be last since it is variable size */
struct bch_write_bio bio;
};