diff options
-rw-r--r-- | drivers/block/rbd.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 92a9ce0a9e85..c4606987e9d1 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -515,6 +515,7 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); | |||
515 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); | 515 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); |
516 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); | 516 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); |
517 | static int rbd_dev_header_info(struct rbd_device *rbd_dev); | 517 | static int rbd_dev_header_info(struct rbd_device *rbd_dev); |
518 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); | ||
518 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, | 519 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, |
519 | u64 snap_id); | 520 | u64 snap_id); |
520 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, | 521 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, |
@@ -3516,6 +3517,16 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev) | |||
3516 | if (ret) | 3517 | if (ret) |
3517 | return ret; | 3518 | return ret; |
3518 | 3519 | ||
3520 | /* | ||
3521 | * If there is a parent, see if it has disappeared due to the | ||
3522 | * mapped image getting flattened. | ||
3523 | */ | ||
3524 | if (rbd_dev->parent) { | ||
3525 | ret = rbd_dev_v2_parent_info(rbd_dev); | ||
3526 | if (ret) | ||
3527 | return ret; | ||
3528 | } | ||
3529 | |||
3519 | if (rbd_dev->spec->snap_id == CEPH_NOSNAP) { | 3530 | if (rbd_dev->spec->snap_id == CEPH_NOSNAP) { |
3520 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) | 3531 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) |
3521 | rbd_dev->mapping.size = rbd_dev->header.image_size; | 3532 | rbd_dev->mapping.size = rbd_dev->header.image_size; |
@@ -3526,9 +3537,8 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev) | |||
3526 | 3537 | ||
3527 | up_write(&rbd_dev->header_rwsem); | 3538 | up_write(&rbd_dev->header_rwsem); |
3528 | 3539 | ||
3529 | if (mapping_size != rbd_dev->mapping.size) { | 3540 | if (mapping_size != rbd_dev->mapping.size) |
3530 | rbd_dev_update_size(rbd_dev); | 3541 | rbd_dev_update_size(rbd_dev); |
3531 | } | ||
3532 | 3542 | ||
3533 | return 0; | 3543 | return 0; |
3534 | } | 3544 | } |
@@ -4479,33 +4489,6 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) | |||
4479 | return ret; | 4489 | return ret; |
4480 | } | 4490 | } |
4481 | 4491 | ||
4482 | /* | ||
4483 | * If the image supports layering, get the parent info. We | ||
4484 | * need to probe the first time regardless. Thereafter we | ||
4485 | * only need to if there's a parent, to see if it has | ||
4486 | * disappeared due to the mapped image getting flattened. | ||
4487 | */ | ||
4488 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING && | ||
4489 | (first_time || rbd_dev->parent_spec)) { | ||
4490 | bool warn; | ||
4491 | |||
4492 | ret = rbd_dev_v2_parent_info(rbd_dev); | ||
4493 | if (ret) | ||
4494 | return ret; | ||
4495 | |||
4496 | /* | ||
4497 | * Print a warning if this is the initial probe and | ||
4498 | * the image has a parent. Don't print it if the | ||
4499 | * image now being probed is itself a parent. We | ||
4500 | * can tell at this point because we won't know its | ||
4501 | * pool name yet (just its pool id). | ||
4502 | */ | ||
4503 | warn = rbd_dev->parent_spec && rbd_dev->spec->pool_name; | ||
4504 | if (first_time && warn) | ||
4505 | rbd_warn(rbd_dev, "WARNING: kernel layering " | ||
4506 | "is EXPERIMENTAL!"); | ||
4507 | } | ||
4508 | |||
4509 | ret = rbd_dev_v2_snap_context(rbd_dev); | 4492 | ret = rbd_dev_v2_snap_context(rbd_dev); |
4510 | dout("rbd_dev_v2_snap_context returned %d\n", ret); | 4493 | dout("rbd_dev_v2_snap_context returned %d\n", ret); |
4511 | 4494 | ||
@@ -5185,14 +5168,28 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping) | |||
5185 | if (ret) | 5168 | if (ret) |
5186 | goto err_out_probe; | 5169 | goto err_out_probe; |
5187 | 5170 | ||
5171 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { | ||
5172 | ret = rbd_dev_v2_parent_info(rbd_dev); | ||
5173 | if (ret) | ||
5174 | goto err_out_probe; | ||
5175 | |||
5176 | /* | ||
5177 | * Need to warn users if this image is the one being | ||
5178 | * mapped and has a parent. | ||
5179 | */ | ||
5180 | if (mapping && rbd_dev->parent_spec) | ||
5181 | rbd_warn(rbd_dev, | ||
5182 | "WARNING: kernel layering is EXPERIMENTAL!"); | ||
5183 | } | ||
5184 | |||
5188 | ret = rbd_dev_probe_parent(rbd_dev); | 5185 | ret = rbd_dev_probe_parent(rbd_dev); |
5189 | if (ret) | 5186 | if (ret) |
5190 | goto err_out_probe; | 5187 | goto err_out_probe; |
5191 | 5188 | ||
5192 | dout("discovered format %u image, header name is %s\n", | 5189 | dout("discovered format %u image, header name is %s\n", |
5193 | rbd_dev->image_format, rbd_dev->header_name); | 5190 | rbd_dev->image_format, rbd_dev->header_name); |
5194 | |||
5195 | return 0; | 5191 | return 0; |
5192 | |||
5196 | err_out_probe: | 5193 | err_out_probe: |
5197 | rbd_dev_unprobe(rbd_dev); | 5194 | rbd_dev_unprobe(rbd_dev); |
5198 | err_out_watch: | 5195 | err_out_watch: |
@@ -5205,9 +5202,6 @@ err_out_format: | |||
5205 | rbd_dev->image_format = 0; | 5202 | rbd_dev->image_format = 0; |
5206 | kfree(rbd_dev->spec->image_id); | 5203 | kfree(rbd_dev->spec->image_id); |
5207 | rbd_dev->spec->image_id = NULL; | 5204 | rbd_dev->spec->image_id = NULL; |
5208 | |||
5209 | dout("probe failed, returning %d\n", ret); | ||
5210 | |||
5211 | return ret; | 5205 | return ret; |
5212 | } | 5206 | } |
5213 | 5207 | ||