diff options
| -rw-r--r-- | drivers/md/bcache/bset.c | 12 | ||||
| -rw-r--r-- | drivers/md/bcache/bset.h | 2 | ||||
| -rw-r--r-- | drivers/md/bcache/btree.c | 6 | ||||
| -rw-r--r-- | drivers/md/bcache/request.c | 22 |
4 files changed, 26 insertions, 16 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index e6882659afb9..f91347a55c41 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
| @@ -14,21 +14,13 @@ | |||
| 14 | 14 | ||
| 15 | /* Keylists */ | 15 | /* Keylists */ |
| 16 | 16 | ||
| 17 | int bch_keylist_realloc(struct keylist *l, int nptrs, struct cache_set *c) | 17 | int __bch_keylist_realloc(struct keylist *l, unsigned u64s) |
| 18 | { | 18 | { |
| 19 | size_t oldsize = bch_keylist_nkeys(l); | 19 | size_t oldsize = bch_keylist_nkeys(l); |
| 20 | size_t newsize = oldsize + 2 + nptrs; | 20 | size_t newsize = oldsize + u64s; |
| 21 | uint64_t *old_keys = l->keys_p == l->inline_keys ? NULL : l->keys_p; | 21 | uint64_t *old_keys = l->keys_p == l->inline_keys ? NULL : l->keys_p; |
| 22 | uint64_t *new_keys; | 22 | uint64_t *new_keys; |
| 23 | 23 | ||
| 24 | /* The journalling code doesn't handle the case where the keys to insert | ||
| 25 | * is bigger than an empty write: If we just return -ENOMEM here, | ||
| 26 | * bio_insert() and bio_invalidate() will insert the keys created so far | ||
| 27 | * and finish the rest when the keylist is empty. | ||
| 28 | */ | ||
| 29 | if (newsize * sizeof(uint64_t) > block_bytes(c) - sizeof(struct jset)) | ||
| 30 | return -ENOMEM; | ||
| 31 | |||
| 32 | newsize = roundup_pow_of_two(newsize); | 24 | newsize = roundup_pow_of_two(newsize); |
| 33 | 25 | ||
| 34 | if (newsize <= KEYLIST_INLINE || | 26 | if (newsize <= KEYLIST_INLINE || |
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h index ba02f055bc64..303d31a3b9e6 100644 --- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h | |||
| @@ -259,7 +259,7 @@ static inline size_t bch_keylist_bytes(struct keylist *l) | |||
| 259 | 259 | ||
| 260 | struct bkey *bch_keylist_pop(struct keylist *); | 260 | struct bkey *bch_keylist_pop(struct keylist *); |
| 261 | void bch_keylist_pop_front(struct keylist *); | 261 | void bch_keylist_pop_front(struct keylist *); |
| 262 | int bch_keylist_realloc(struct keylist *, int, struct cache_set *); | 262 | int __bch_keylist_realloc(struct keylist *, unsigned); |
| 263 | 263 | ||
| 264 | void bch_bkey_copy_single_ptr(struct bkey *, const struct bkey *, | 264 | void bch_bkey_copy_single_ptr(struct bkey *, const struct bkey *, |
| 265 | unsigned); | 265 | unsigned); |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index f035ae3b1289..f0a6399fdd3c 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
| @@ -1356,8 +1356,8 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, | |||
| 1356 | 1356 | ||
| 1357 | n2->keys -= keys; | 1357 | n2->keys -= keys; |
| 1358 | 1358 | ||
| 1359 | if (bch_keylist_realloc(keylist, | 1359 | if (__bch_keylist_realloc(keylist, |
| 1360 | KEY_PTRS(&new_nodes[i]->key), b->c)) | 1360 | bkey_u64s(&new_nodes[i]->key))) |
| 1361 | goto out_nocoalesce; | 1361 | goto out_nocoalesce; |
| 1362 | 1362 | ||
| 1363 | bch_btree_node_write(new_nodes[i], &cl); | 1363 | bch_btree_node_write(new_nodes[i], &cl); |
| @@ -1365,7 +1365,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, | |||
| 1365 | } | 1365 | } |
| 1366 | 1366 | ||
| 1367 | for (i = 0; i < nodes; i++) { | 1367 | for (i = 0; i < nodes; i++) { |
| 1368 | if (bch_keylist_realloc(keylist, KEY_PTRS(&r[i].b->key), b->c)) | 1368 | if (__bch_keylist_realloc(keylist, bkey_u64s(&r[i].b->key))) |
| 1369 | goto out_nocoalesce; | 1369 | goto out_nocoalesce; |
| 1370 | 1370 | ||
| 1371 | make_btree_freeing_key(r[i].b, keylist->top); | 1371 | make_btree_freeing_key(r[i].b, keylist->top); |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index cce02f19e6c7..fcdb59f9ca91 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
| @@ -255,6 +255,24 @@ static void bch_data_insert_keys(struct closure *cl) | |||
| 255 | closure_return(cl); | 255 | closure_return(cl); |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | static int bch_keylist_realloc(struct keylist *l, unsigned u64s, | ||
| 259 | struct cache_set *c) | ||
| 260 | { | ||
| 261 | size_t oldsize = bch_keylist_nkeys(l); | ||
| 262 | size_t newsize = oldsize + u64s; | ||
| 263 | |||
| 264 | /* | ||
| 265 | * The journalling code doesn't handle the case where the keys to insert | ||
| 266 | * is bigger than an empty write: If we just return -ENOMEM here, | ||
| 267 | * bio_insert() and bio_invalidate() will insert the keys created so far | ||
| 268 | * and finish the rest when the keylist is empty. | ||
| 269 | */ | ||
| 270 | if (newsize * sizeof(uint64_t) > block_bytes(c) - sizeof(struct jset)) | ||
| 271 | return -ENOMEM; | ||
| 272 | |||
| 273 | return __bch_keylist_realloc(l, u64s); | ||
| 274 | } | ||
| 275 | |||
| 258 | static void bch_data_invalidate(struct closure *cl) | 276 | static void bch_data_invalidate(struct closure *cl) |
| 259 | { | 277 | { |
| 260 | struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | 278 | struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
| @@ -267,7 +285,7 @@ static void bch_data_invalidate(struct closure *cl) | |||
| 267 | unsigned sectors = min(bio_sectors(bio), | 285 | unsigned sectors = min(bio_sectors(bio), |
| 268 | 1U << (KEY_SIZE_BITS - 1)); | 286 | 1U << (KEY_SIZE_BITS - 1)); |
| 269 | 287 | ||
| 270 | if (bch_keylist_realloc(&op->insert_keys, 0, op->c)) | 288 | if (bch_keylist_realloc(&op->insert_keys, 2, op->c)) |
| 271 | goto out; | 289 | goto out; |
| 272 | 290 | ||
| 273 | bio->bi_iter.bi_sector += sectors; | 291 | bio->bi_iter.bi_sector += sectors; |
| @@ -357,7 +375,7 @@ static void bch_data_insert_start(struct closure *cl) | |||
| 357 | 375 | ||
| 358 | /* 1 for the device pointer and 1 for the chksum */ | 376 | /* 1 for the device pointer and 1 for the chksum */ |
| 359 | if (bch_keylist_realloc(&op->insert_keys, | 377 | if (bch_keylist_realloc(&op->insert_keys, |
| 360 | 1 + (op->csum ? 1 : 0), | 378 | 3 + (op->csum ? 1 : 0), |
| 361 | op->c)) | 379 | op->c)) |
| 362 | continue_at(cl, bch_data_insert_keys, bcache_wq); | 380 | continue_at(cl, bch_data_insert_keys, bcache_wq); |
| 363 | 381 | ||
