Patch "dm space map metadata: fix ref counting bug when bootstrapping a new space map" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
dm space map metadata: fix ref counting bug when bootstrapping a new space map
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
dm-space-map-metadata-fix-ref-counting-bug-when-bootstrapping-a-new-space-map.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
50dd842ad83b43bed71790efb31cfb2f6c05c9c1Mon Sep 17 00:00:00 2001
From: Joe Thornber <[email protected]>
Date: Wed, 9 Dec 2015 16:38:12 +0000
Subject: dm space map metadata: fix ref counting bug when bootstrapping a new space map
From: Joe Thornber <[email protected]>
commit 50dd842ad83b43bed71790efb31cfb2f6c05c9c1 upstream.
When applying block operations (BOPs) do not remove them from the uncommitted BOP ring-buffer until after they've been applied -- in case we recurse.
Also, perform BOP_INC operation, in dm_sm_metadata_create() and sm_metadata_extend(), in terms of the uncommitted BOP ring-buffer rather than using direct calls to sm_ll_inc().
--- drivers/md/persistent-data/dm-space-map-metadata.c | 32 ++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-)
drivers/md/persistent-data/dm-space-map-metadata.c +22 -10
@@ -136,7 +136,7 @@ static int brb_push(struct bop_ring_buffreturn 0 ; } -static int brb_pop (struct bop_ring_buffer *brb,struct block_op *result) +static int brb_peek (struct bop_ring_buffer *brb,struct block_op *result) {struct block_op *bop;
@@ -147,6 +147,17 @@ static int brb_pop(struct bop_ring_buffe result->type = bop->type; result->block = bop->block; +return 0 ; +} + +static int brb_pop (struct bop_ring_buffer *brb) +{ +struct block_op *bop; + +if (brb_empty (brb)) +return -ENODATA ; + + bop = brb->bops + brb->begin; brb->begin =brb_next (brb, brb->begin);return 0 ;
@@ -211,7 +222,7 @@ static int apply_bops(struct sm_metadatawhile (!brb_empty (&smm->uncommitted)) {struct block_op bop; - r =brb_pop (&smm->uncommitted, &bop); + r =brb_peek (&smm->uncommitted, &bop);if (r) {DMERR ("bug in bop ring buffer" );break ;
@@ -220,6 +231,8 @@ static int apply_bops(struct sm_metadata r =commit_bop (smm, &bop);if (r)break ; + +brb_pop (&smm->uncommitted); }return r;
@@ -681,7 +694,6 @@ static struct dm_space_map bootstrap_opsstatic int sm_metadata_extend (struct dm_space_map *sm,dm_block_t extra_blocks) {int r, i; -enum allocation_event ev; struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);dm_block_t old_len = smm->ll.nr_blocks;
@@ -703,11 +715,12 @@ static int sm_metadata_extend(struct dm_* allocate any new blocks. */ do { - for (i = old_len; !r && i < smm->begin; i++) { - r = sm_ll_inc(&smm->ll, i, &ev); - if (r) - goto out; - } + for (i = old_len; !r && i < smm->begin; i++) + r = add_bop(smm, BOP_INC, i); + + if (r) + goto out; + old_len = smm->begin; r = apply_bops(smm);
@@ -752,7 +765,6 @@ int dm_sm_metadata_create(struct dm_spac {int r;dm_block_t i; -enum allocation_event ev; struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); smm->begin = superblock +1 ;
@@ -780,7 +792,7 @@ int dm_sm_metadata_create(struct dm_spac* allocated blocks that they were built from. */ for (i = superblock; !r && i < smm->begin; i++) - r =sm_ll_inc (&smm->ll, i, &ev); + r =add_bop (smm,BOP_INC , i);if (r)return r;
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/dm-thin-restore-requested-error_if_no_space-setting-on-oods-to-write-transition.patch queue-3.14/dm-space-map-metadata-fix-ref-counting-bug-when-bootstrapping-a-new-space-map.patch queue-3.14/dm-btree-fix-bufio-buffer-leaks-in-dm_btree_del-error-path.patch queue-3.14/dm-thin-metadata-fix-bug-when-taking-a-metadata-snapshot.patch