diff options
author | Alex Elder <elder@inktank.com> | 2012-07-03 17:01:19 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-10-01 15:30:53 -0400 |
commit | cd892126c617b3837b6088bf6c097ad2def4de83 (patch) | |
tree | 769239813e121ed6191ca8d3db3dd8d23ec76f4d /drivers/block/rbd.c | |
parent | 34b131849feb359f183907b467e9aa4d652b1baa (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.c | 36 |
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 | ||
2105 | static 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 | ||