diff options
author | Ilya Dryomov <idryomov@redhat.com> | 2015-01-19 14:57:39 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-02-19 05:31:39 -0500 |
commit | cf32bd9c86b6917d8446c00ea0081dde6e716a82 (patch) | |
tree | 69bbd080903e8809f7a4374c3fb30ed70af988fc /drivers/block | |
parent | bf91c3150880ed6304f578cf00bd408d642fe6a0 (diff) |
rbd: do not treat standalone as flatten
If the clone is resized down to 0, it becomes standalone. If such
resize is carried over while an image is mapped we would detect this
and call rbd_dev_parent_put() which means "let go of all parent state,
including the spec(s) of parent images(s)". This leads to a mismatch
between "rbd info" and sysfs parent fields, so a fix is in order.
# rbd create --image-format 2 --size 1 foo
# rbd snap create foo@snap
# rbd snap protect foo@snap
# rbd clone foo@snap bar
# DEV=$(rbd map bar)
# rbd resize --allow-shrink --size 0 bar
# rbd resize --size 1 bar
# rbd info bar | grep parent
parent: rbd/foo@snap
Before:
# cat /sys/bus/rbd/devices/0/parent
(no parent image)
After:
# cat /sys/bus/rbd/devices/0/parent
pool_id 0
pool_name rbd
image_id 10056b8b4567
image_name foo
snap_id 2
snap_name snap
overlap 0
Signed-off-by: Ilya Dryomov <idryomov@redhat.com>
Reviewed-by: Josh Durgin <jdurgin@redhat.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/rbd.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index b85d52005a21..e818c2a6ffb1 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -4273,32 +4273,22 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | |||
4273 | } | 4273 | } |
4274 | 4274 | ||
4275 | /* | 4275 | /* |
4276 | * We always update the parent overlap. If it's zero we | 4276 | * We always update the parent overlap. If it's zero we issue |
4277 | * treat it specially. | 4277 | * a warning, as we will proceed as if there was no parent. |
4278 | */ | 4278 | */ |
4279 | rbd_dev->parent_overlap = overlap; | ||
4280 | if (!overlap) { | 4279 | if (!overlap) { |
4281 | |||
4282 | /* A null parent_spec indicates it's the initial probe */ | ||
4283 | |||
4284 | if (parent_spec) { | 4280 | if (parent_spec) { |
4285 | /* | 4281 | /* refresh, careful to warn just once */ |
4286 | * The overlap has become zero, so the clone | 4282 | if (rbd_dev->parent_overlap) |
4287 | * must have been resized down to 0 at some | 4283 | rbd_warn(rbd_dev, |
4288 | * point. Treat this the same as a flatten. | 4284 | "clone now standalone (overlap became 0)"); |
4289 | */ | ||
4290 | rbd_dev_parent_put(rbd_dev); | ||
4291 | pr_info("%s: clone image now standalone\n", | ||
4292 | rbd_dev->disk->disk_name); | ||
4293 | } else { | 4285 | } else { |
4294 | /* | 4286 | /* initial probe */ |
4295 | * For the initial probe, if we find the | 4287 | rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); |
4296 | * overlap is zero we just pretend there was | ||
4297 | * no parent image. | ||
4298 | */ | ||
4299 | rbd_warn(rbd_dev, "ignoring parent with overlap 0"); | ||
4300 | } | 4288 | } |
4301 | } | 4289 | } |
4290 | rbd_dev->parent_overlap = overlap; | ||
4291 | |||
4302 | out: | 4292 | out: |
4303 | ret = 0; | 4293 | ret = 0; |
4304 | out_err: | 4294 | out_err: |