diff options
author | Alex Elder <elder@inktank.com> | 2013-05-06 08:40:30 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2013-05-08 08:45:30 -0400 |
commit | 00a653e216a8427547774ab3f2cc92709c3e28c9 (patch) | |
tree | 0fcefd1576f7906ef3643b4f92f808b9a05af7af /drivers/block/rbd.c | |
parent | e627db085e0dab7744b68f3c927be6ed6df2f7f9 (diff) |
rbd: update capacity in rbd_dev_refresh()
When a mapped image changes size, we change the capacity recorded
for the Linux disk associated with it, in rbd_update_mapping_size().
That function is called in two places--the format 1 and format 2
refresh routines.
There is no need to set the capacity while holding the header
semaphore. Instead, do it in the common rbd_dev_refresh(), using
the logic that's already there to initiate disk revalidation.
Add handling in the request function, just in case a request
that exceeds the capacity of the device comes in (perhaps one
that was started before a refresh shrunk the device).
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r-- | drivers/block/rbd.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 5d5e3f0b5fb4..9c094c67d778 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -2874,6 +2874,13 @@ static void rbd_request_fn(struct request_queue *q) | |||
2874 | goto end_request; /* Shouldn't happen */ | 2874 | goto end_request; /* Shouldn't happen */ |
2875 | } | 2875 | } |
2876 | 2876 | ||
2877 | result = -EIO; | ||
2878 | if (offset + length > rbd_dev->mapping.size) { | ||
2879 | rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)\n", | ||
2880 | offset, length, rbd_dev->mapping.size); | ||
2881 | goto end_request; | ||
2882 | } | ||
2883 | |||
2877 | result = -ENOMEM; | 2884 | result = -ENOMEM; |
2878 | img_request = rbd_img_request_create(rbd_dev, offset, length, | 2885 | img_request = rbd_img_request_create(rbd_dev, offset, length, |
2879 | write_request, false); | 2886 | write_request, false); |
@@ -3116,14 +3123,8 @@ static void rbd_update_mapping_size(struct rbd_device *rbd_dev) | |||
3116 | if (rbd_dev->spec->snap_id != CEPH_NOSNAP) | 3123 | if (rbd_dev->spec->snap_id != CEPH_NOSNAP) |
3117 | return; | 3124 | return; |
3118 | 3125 | ||
3119 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) { | 3126 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) |
3120 | sector_t size; | ||
3121 | |||
3122 | rbd_dev->mapping.size = rbd_dev->header.image_size; | 3127 | rbd_dev->mapping.size = rbd_dev->header.image_size; |
3123 | size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; | ||
3124 | dout("setting size to %llu sectors", (unsigned long long)size); | ||
3125 | set_capacity(rbd_dev->disk, size); | ||
3126 | } | ||
3127 | } | 3128 | } |
3128 | 3129 | ||
3129 | /* | 3130 | /* |
@@ -3200,8 +3201,14 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev) | |||
3200 | 3201 | ||
3201 | rbd_exists_validate(rbd_dev); | 3202 | rbd_exists_validate(rbd_dev); |
3202 | mutex_unlock(&ctl_mutex); | 3203 | mutex_unlock(&ctl_mutex); |
3203 | if (mapping_size != rbd_dev->mapping.size) | 3204 | if (mapping_size != rbd_dev->mapping.size) { |
3205 | sector_t size; | ||
3206 | |||
3207 | size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; | ||
3208 | dout("setting size to %llu sectors", (unsigned long long)size); | ||
3209 | set_capacity(rbd_dev->disk, size); | ||
3204 | revalidate_disk(rbd_dev->disk); | 3210 | revalidate_disk(rbd_dev->disk); |
3211 | } | ||
3205 | 3212 | ||
3206 | return ret; | 3213 | return ret; |
3207 | } | 3214 | } |