[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