[dm-devel] [PATCH] dm btree: add ref counting ops for the leaves of top level btrees

Luis Henriques luis.henriques at canonical.com
Mon Aug 31 10:57:29 UTC 2015


On Wed, Aug 19, 2015 at 02:45:43PM -0400, Mike Snitzer wrote:
> This stable@ backport drops the dm-btree-remove.c:remove_one() hunk
> from the original commit because it isn't relevant for stable.
>

Thanks, I guess this is applicable to the 3.16 kernel as well, so I'll
use a similar backport.

Cheers,
--
Luís

> Upstream linux.git commit b0dc3c8bc157c60b1d470163882be8c13e1950af
> Author: Joe Thornber <ejt at redhat.com>
> Date:   Wed Aug 12 15:12:09 2015 +0100
> 
>     dm btree: add ref counting ops for the leaves of top level btrees
> 
>     When using nested btrees, the top leaves of the top levels contain
>     block addresses for the root of the next tree down.  If we shadow a
>     shared leaf node the leaf values (sub tree roots) should be incremented
>     accordingly.
> 
>     This is only an issue if there is metadata sharing in the top levels.
>     Which only occurs if metadata snapshots are being used (as is possible
>     with dm-thinp).  And could result in a block from the thinp metadata
>     snap being reused early, thus corrupting the thinp metadata snap.
> 
>     Signed-off-by: Joe Thornber <ejt at redhat.com>
>     Signed-off-by: Mike Snitzer <snitzer at redhat.com>
>     Cc: stable at vger.kernel.org
> ---
>  drivers/md/persistent-data/dm-btree-internal.h |  6 +++++
>  drivers/md/persistent-data/dm-btree-remove.c   | 12 +++------
>  drivers/md/persistent-data/dm-btree-spine.c    | 37 ++++++++++++++++++++++++++
>  drivers/md/persistent-data/dm-btree.c          |  7 +----
>  4 files changed, 47 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h
> index bf2b80d..8731b6e 100644
> --- a/drivers/md/persistent-data/dm-btree-internal.h
> +++ b/drivers/md/persistent-data/dm-btree-internal.h
> @@ -138,4 +138,10 @@ int lower_bound(struct btree_node *n, uint64_t key);
>  
>  extern struct dm_block_validator btree_node_validator;
>  
> +/*
> + * Value type for upper levels of multi-level btrees.
> + */
> +extern void init_le64_type(struct dm_transaction_manager *tm,
> +			   struct dm_btree_value_type *vt);
> +
>  #endif	/* DM_BTREE_INTERNAL_H */
> diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
> index b88757c..ff96197 100644
> --- a/drivers/md/persistent-data/dm-btree-remove.c
> +++ b/drivers/md/persistent-data/dm-btree-remove.c
> @@ -544,14 +544,6 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
>  	return r;
>  }
>  
> -static struct dm_btree_value_type le64_type = {
> -	.context = NULL,
> -	.size = sizeof(__le64),
> -	.inc = NULL,
> -	.dec = NULL,
> -	.equal = NULL
> -};
> -
>  int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
>  		    uint64_t *keys, dm_block_t *new_root)
>  {
> @@ -559,12 +551,14 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
>  	int index = 0, r = 0;
>  	struct shadow_spine spine;
>  	struct btree_node *n;
> +	struct dm_btree_value_type le64_vt;
>  
> +	init_le64_type(info->tm, &le64_vt);
>  	init_shadow_spine(&spine, info);
>  	for (level = 0; level < info->levels; level++) {
>  		r = remove_raw(&spine, info,
>  			       (level == last_level ?
> -				&info->value_type : &le64_type),
> +				&info->value_type : &le64_vt),
>  			       root, keys[level], (unsigned *)&index);
>  		if (r < 0)
>  			break;
> diff --git a/drivers/md/persistent-data/dm-btree-spine.c b/drivers/md/persistent-data/dm-btree-spine.c
> index 1b5e13e..0dee514 100644
> --- a/drivers/md/persistent-data/dm-btree-spine.c
> +++ b/drivers/md/persistent-data/dm-btree-spine.c
> @@ -249,3 +249,40 @@ int shadow_root(struct shadow_spine *s)
>  {
>  	return s->root;
>  }
> +
> +static void le64_inc(void *context, const void *value_le)
> +{
> +	struct dm_transaction_manager *tm = context;
> +	__le64 v_le;
> +
> +	memcpy(&v_le, value_le, sizeof(v_le));
> +	dm_tm_inc(tm, le64_to_cpu(v_le));
> +}
> +
> +static void le64_dec(void *context, const void *value_le)
> +{
> +	struct dm_transaction_manager *tm = context;
> +	__le64 v_le;
> +
> +	memcpy(&v_le, value_le, sizeof(v_le));
> +	dm_tm_dec(tm, le64_to_cpu(v_le));
> +}
> +
> +static int le64_equal(void *context, const void *value1_le, const void *value2_le)
> +{
> +	__le64 v1_le, v2_le;
> +
> +	memcpy(&v1_le, value1_le, sizeof(v1_le));
> +	memcpy(&v2_le, value2_le, sizeof(v2_le));
> +	return v1_le == v2_le;
> +}
> +
> +void init_le64_type(struct dm_transaction_manager *tm,
> +		    struct dm_btree_value_type *vt)
> +{
> +	vt->context = tm;
> +	vt->size = sizeof(__le64);
> +	vt->inc = le64_inc;
> +	vt->dec = le64_dec;
> +	vt->equal = le64_equal;
> +}
> diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
> index 200ac12..41e1ab2 100644
> --- a/drivers/md/persistent-data/dm-btree.c
> +++ b/drivers/md/persistent-data/dm-btree.c
> @@ -667,12 +667,7 @@ static int insert(struct dm_btree_info *info, dm_block_t root,
>  	struct btree_node *n;
>  	struct dm_btree_value_type le64_type;
>  
> -	le64_type.context = NULL;
> -	le64_type.size = sizeof(__le64);
> -	le64_type.inc = NULL;
> -	le64_type.dec = NULL;
> -	le64_type.equal = NULL;
> -
> +	init_le64_type(info->tm, &le64_type);
>  	init_shadow_spine(&spine, info);
>  
>  	for (level = 0; level < (info->levels - 1); level++) {
> -- 
> 2.3.2 (Apple Git-55)
> 
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




More information about the dm-devel mailing list