aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c53
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 */
2135static 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
2164static 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:
2636static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) 2677static 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;
2704out_err:
2705 kfree(rbd_dev->header_name);
2706 rbd_dev->header_name = NULL;
2707
2708 return ret;
2656} 2709}
2657 2710
2658/* 2711/*