diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/rbd.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 3b284d53a566..061c62496fea 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -2128,6 +2128,47 @@ static char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which, | |||
2128 | } | 2128 | } |
2129 | 2129 | ||
2130 | /* | 2130 | /* |
2131 | * Get the size and object order for an image snapshot, or if | ||
2132 | * snap_id is CEPH_NOSNAP, gets this information for the base | ||
2133 | * image. | ||
2134 | */ | ||
2135 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, | ||
2136 | u8 *order, u64 *snap_size) | ||
2137 | { | ||
2138 | __le64 snapid = cpu_to_le64(snap_id); | ||
2139 | int ret; | ||
2140 | struct { | ||
2141 | u8 order; | ||
2142 | __le64 size; | ||
2143 | } __attribute__ ((packed)) size_buf = { 0 }; | ||
2144 | |||
2145 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | ||
2146 | "rbd", "get_size", | ||
2147 | (char *) &snapid, sizeof (snapid), | ||
2148 | (char *) &size_buf, sizeof (size_buf), | ||
2149 | CEPH_OSD_FLAG_READ, NULL); | ||
2150 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | ||
2151 | if (ret < 0) | ||
2152 | return ret; | ||
2153 | |||
2154 | *order = size_buf.order; | ||
2155 | *snap_size = le64_to_cpu(size_buf.size); | ||
2156 | |||
2157 | dout(" snap_id 0x%016llx order = %u, snap_size = %llu\n", | ||
2158 | (unsigned long long) snap_id, (unsigned int) *order, | ||
2159 | (unsigned long long) *snap_size); | ||
2160 | |||
2161 | return 0; | ||
2162 | } | ||
2163 | |||
2164 | static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) | ||
2165 | { | ||
2166 | return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, | ||
2167 | &rbd_dev->header.obj_order, | ||
2168 | &rbd_dev->header.image_size); | ||
2169 | } | ||
2170 | |||
2171 | /* | ||
2131 | * Scan the rbd device's current snapshot list and compare it to the | 2172 | * Scan the rbd device's current snapshot list and compare it to the |
2132 | * newly-received snapshot context. Remove any existing snapshots | 2173 | * newly-received snapshot context. Remove any existing snapshots |
2133 | * not present in the new snapshot context. Add a new snapshot for | 2174 | * not present in the new snapshot context. Add a new snapshot for |
@@ -2636,6 +2677,7 @@ out_err: | |||
2636 | static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) | 2677 | static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) |
2637 | { | 2678 | { |
2638 | size_t size; | 2679 | size_t size; |
2680 | int ret; | ||
2639 | 2681 | ||
2640 | /* | 2682 | /* |
2641 | * Image id was filled in by the caller. Record the header | 2683 | * Image id was filled in by the caller. Record the header |
@@ -2647,12 +2689,23 @@ static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) | |||
2647 | return -ENOMEM; | 2689 | return -ENOMEM; |
2648 | sprintf(rbd_dev->header_name, "%s%s", | 2690 | sprintf(rbd_dev->header_name, "%s%s", |
2649 | RBD_HEADER_PREFIX, rbd_dev->image_id); | 2691 | RBD_HEADER_PREFIX, rbd_dev->image_id); |
2692 | |||
2693 | /* Get the size and object order for the image */ | ||
2694 | |||
2695 | ret = rbd_dev_v2_image_size(rbd_dev); | ||
2696 | if (ret < 0) | ||
2697 | goto out_err; | ||
2650 | rbd_dev->image_format = 2; | 2698 | rbd_dev->image_format = 2; |
2651 | 2699 | ||
2652 | dout("discovered version 2 image, header name is %s\n", | 2700 | dout("discovered version 2 image, header name is %s\n", |
2653 | rbd_dev->header_name); | 2701 | rbd_dev->header_name); |
2654 | 2702 | ||
2655 | return -ENOTSUPP; | 2703 | return -ENOTSUPP; |
2704 | out_err: | ||
2705 | kfree(rbd_dev->header_name); | ||
2706 | rbd_dev->header_name = NULL; | ||
2707 | |||
2708 | return ret; | ||
2656 | } | 2709 | } |
2657 | 2710 | ||
2658 | /* | 2711 | /* |