diff options
| -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 | /* |
