diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-02-20 02:34:51 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-07-26 00:16:50 -0800 |
commit | f7b8614c2979c15539479261a18a98590cdd8b9b (patch) | |
tree | 4f19f071c6932c5da20bfd01dfbc749925be10db | |
parent | 5d32d3c64bd7a7d767037bbb8191e62ad5c62f6e (diff) |
bcache: kill BCH_WRITE_CHECK_ENOSPC
-rw-r--r-- | drivers/md/bcache/alloc.c | 27 | ||||
-rw-r--r-- | drivers/md/bcache/alloc.h | 5 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 17 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/buckets.c | 22 | ||||
-rw-r--r-- | drivers/md/bcache/buckets.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/fs-io.c | 30 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 4 | ||||
-rw-r--r-- | drivers/md/bcache/io.h | 11 | ||||
-rw-r--r-- | drivers/md/bcache/io_types.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/migrate.c | 7 | ||||
-rw-r--r-- | drivers/md/bcache/move.c | 3 | ||||
-rw-r--r-- | drivers/md/bcache/move.h | 1 |
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; }; |