Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ilya Dryomov and committed by
Ilya Dryomov
cf32bd9c bf91c315

+10 -20
+10 -20
drivers/block/rbd.c
··· 4273 4273 } 4274 4274 4275 4275 /* 4276 - * We always update the parent overlap. If it's zero we 4277 - * treat it specially. 4276 + * We always update the parent overlap. If it's zero we issue 4277 + * a warning, as we will proceed as if there was no parent. 4278 4278 */ 4279 - rbd_dev->parent_overlap = overlap; 4280 4279 if (!overlap) { 4281 - 4282 - /* A null parent_spec indicates it's the initial probe */ 4283 - 4284 4280 if (parent_spec) { 4285 - /* 4286 - * The overlap has become zero, so the clone 4287 - * must have been resized down to 0 at some 4288 - * point. Treat this the same as a flatten. 4289 - */ 4290 - rbd_dev_parent_put(rbd_dev); 4291 - pr_info("%s: clone image now standalone\n", 4292 - rbd_dev->disk->disk_name); 4281 + /* refresh, careful to warn just once */ 4282 + if (rbd_dev->parent_overlap) 4283 + rbd_warn(rbd_dev, 4284 + "clone now standalone (overlap became 0)"); 4293 4285 } else { 4294 - /* 4295 - * For the initial probe, if we find the 4296 - * overlap is zero we just pretend there was 4297 - * no parent image. 4298 - */ 4299 - rbd_warn(rbd_dev, "ignoring parent with overlap 0"); 4286 + /* initial probe */ 4287 + rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); 4300 4288 } 4301 4289 } 4290 + rbd_dev->parent_overlap = overlap; 4291 + 4302 4292 out: 4303 4293 ret = 0; 4304 4294 out_err: