summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-07-03 17:01:19 -0400
committerAlex Elder <elder@inktank.com>2012-10-01 15:30:53 -0400
commitcd892126c617b3837b6088bf6c097ad2def4de83 (patch)
tree769239813e121ed6191ca8d3db3dd8d23ec76f4d /drivers/block/rbd.c
parent34b131849feb359f183907b467e9aa4d652b1baa (diff)
rbd: encapsulate code that gets snapshot info
Create a function that encapsulates looking up the name, size and features related to a given snapshot, which is indicated by its index in an rbd device's snapshot context array of snapshot ids. This interface will be used to hide differences between the format 1 and format 2 images. At the moment this (looking up the name anyway) is slightly less efficient than what's done currently, but we may be able to optimize this a bit later on by cacheing the last lookup if it proves to be a problem. 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.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 463f8b264c6f..366a3a1f2aac 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2102,6 +2102,25 @@ err:
2102 return ERR_PTR(ret); 2102 return ERR_PTR(ret);
2103} 2103}
2104 2104
2105static char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which,
2106 u64 *snap_size, u64 *snap_features)
2107{
2108 char *snap_name;
2109
2110 rbd_assert(which < rbd_dev->header.snapc->num_snaps);
2111
2112 *snap_size = rbd_dev->header.snap_sizes[which];
2113 *snap_features = 0; /* No features for v1 */
2114
2115 /* Skip over names until we find the one we are looking for */
2116
2117 snap_name = rbd_dev->header.snap_names;
2118 while (which--)
2119 snap_name += strlen(snap_name) + 1;
2120
2121 return snap_name;
2122}
2123
2105/* 2124/*
2106 * Scan the rbd device's current snapshot list and compare it to the 2125 * Scan the rbd device's current snapshot list and compare it to the
2107 * newly-received snapshot context. Remove any existing snapshots 2126 * newly-received snapshot context. Remove any existing snapshots
@@ -2118,7 +2137,6 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2118{ 2137{
2119 struct ceph_snap_context *snapc = rbd_dev->header.snapc; 2138 struct ceph_snap_context *snapc = rbd_dev->header.snapc;
2120 const u32 snap_count = snapc->num_snaps; 2139 const u32 snap_count = snapc->num_snaps;
2121 char *snap_name = rbd_dev->header.snap_names;
2122 struct list_head *head = &rbd_dev->snaps; 2140 struct list_head *head = &rbd_dev->snaps;
2123 struct list_head *links = head->next; 2141 struct list_head *links = head->next;
2124 u32 index = 0; 2142 u32 index = 0;
@@ -2127,6 +2145,9 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2127 while (index < snap_count || links != head) { 2145 while (index < snap_count || links != head) {
2128 u64 snap_id; 2146 u64 snap_id;
2129 struct rbd_snap *snap; 2147 struct rbd_snap *snap;
2148 char *snap_name;
2149 u64 snap_size = 0;
2150 u64 snap_features = 0;
2130 2151
2131 snap_id = index < snap_count ? snapc->snaps[index] 2152 snap_id = index < snap_count ? snapc->snaps[index]
2132 : CEPH_NOSNAP; 2153 : CEPH_NOSNAP;
@@ -2153,16 +2174,20 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2153 continue; 2174 continue;
2154 } 2175 }
2155 2176
2177 snap_name = rbd_dev_v1_snap_info(rbd_dev, index,
2178 &snap_size, &snap_features);
2179 if (IS_ERR(snap_name))
2180 return PTR_ERR(snap_name);
2181
2156 dout("entry %u: snap_id = %llu\n", (unsigned int) snap_count, 2182 dout("entry %u: snap_id = %llu\n", (unsigned int) snap_count,
2157 (unsigned long long) snap_id); 2183 (unsigned long long) snap_id);
2158 if (!snap || (snap_id != CEPH_NOSNAP && snap->id < snap_id)) { 2184 if (!snap || (snap_id != CEPH_NOSNAP && snap->id < snap_id)) {
2159 struct rbd_image_header *header = &rbd_dev->header;
2160 struct rbd_snap *new_snap; 2185 struct rbd_snap *new_snap;
2161 2186
2162 /* We haven't seen this snapshot before */ 2187 /* We haven't seen this snapshot before */
2163 2188
2164 new_snap = __rbd_add_snap_dev(rbd_dev, snap_name, 2189 new_snap = __rbd_add_snap_dev(rbd_dev, snap_name,
2165 snap_id, header->snap_sizes[index], 0); 2190 snap_id, snap_size, snap_features);
2166 if (IS_ERR(new_snap)) { 2191 if (IS_ERR(new_snap)) {
2167 int err = PTR_ERR(new_snap); 2192 int err = PTR_ERR(new_snap);
2168 2193
@@ -2183,9 +2208,9 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2183 2208
2184 dout(" already present\n"); 2209 dout(" already present\n");
2185 2210
2186 rbd_assert(snap->size == 2211 rbd_assert(snap->size == snap_size);
2187 rbd_dev->header.snap_sizes[index]);
2188 rbd_assert(!strcmp(snap->name, snap_name)); 2212 rbd_assert(!strcmp(snap->name, snap_name));
2213 rbd_assert(snap->features == snap_features);
2189 2214
2190 /* Done with this list entry; advance */ 2215 /* Done with this list entry; advance */
2191 2216
@@ -2195,7 +2220,6 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
2195 /* Advance to the next entry in the snapshot context */ 2220 /* Advance to the next entry in the snapshot context */
2196 2221
2197 index++; 2222 index++;
2198 snap_name += strlen(snap_name) + 1;
2199 } 2223 }
2200 dout("%s: done\n", __func__); 2224 dout("%s: done\n", __func__);
2201 2225