rbd: fix a bug in resizing a mapping
authorAlex Elder <elder@inktank.com>
Fri, 26 Apr 2013 20:44:35 +0000 (15:44 -0500)
committerSage Weil <sage@inktank.com>
Thu, 2 May 2013 04:19:45 +0000 (21:19 -0700)
When a snapshot context update occurs, rbd_update_mapping_size() is
called to set the capacity of the disk to record the updated
size of the image in case it has changed.

There's a bug though.  The mapping size is in units of *bytes*.  The
code that updates the mapping size field is assigning a value that
has been scaled down to *sectors*.

Fix that.  Also, check to see if the size has actually changed, and
don't bother updating things (specifically, calling set_capacity())
if it has not.

This resolves:
    http://tracker.ceph.com/issues/4833

Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
drivers/block/rbd.c

index 3bd12ead509199799aaa8e0124d53eb84828af8c..83265adab19c27121f347fec389260e102292a90 100644 (file)
@@ -3034,15 +3034,17 @@ static void rbd_remove_all_snaps(struct rbd_device *rbd_dev)
 
 static void rbd_update_mapping_size(struct rbd_device *rbd_dev)
 {
-       sector_t size;
-
        if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
                return;
 
-       size = (sector_t) rbd_dev->header.image_size / SECTOR_SIZE;
-       dout("setting size to %llu sectors", (unsigned long long) size);
-       rbd_dev->mapping.size = (u64) size;
-       set_capacity(rbd_dev->disk, size);
+       if (rbd_dev->mapping.size != rbd_dev->header.image_size) {
+               sector_t size;
+
+               rbd_dev->mapping.size = rbd_dev->header.image_size;
+               size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE;
+               dout("setting size to %llu sectors", (unsigned long long)size);
+               set_capacity(rbd_dev->disk, size);
+       }
 }
 
 /*