aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@dreamhost.com>2012-02-02 09:13:29 -0500
committerAlex Elder <elder@dreamhost.com>2012-03-22 11:47:47 -0400
commit499afd5b8e742792fda6bd7730c738ad83aecf6b (patch)
treea3cac0fa73a3251e80d8c6eb2e0eb9addbcc5e22 /drivers/block/rbd.c
parente124a82f3c4efc2cc2bae68a2bf30020fb8c4fc2 (diff)
rbd: tie rbd_dev_list changes to rbd_id operations
The only time entries are added to or removed from the global rbd_dev_list is exactly when a "put" or "get" operation is being performed on a rbd_dev's id. So just move the list management code into get/put routines. Signed-off-by: Alex Elder <elder@dreamhost.com> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index e259feedc7d0..e7727e8337fc 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2154,26 +2154,36 @@ static int rbd_init_watch_dev(struct rbd_device *rbd_dev)
2154static atomic64_t rbd_id_max = ATOMIC64_INIT(0); 2154static atomic64_t rbd_id_max = ATOMIC64_INIT(0);
2155 2155
2156/* 2156/*
2157 * Get a unique rbd identifier. The minimum rbd id is 1. 2157 * Get a unique rbd identifier for the given new rbd_dev, and add
2158 * the rbd_dev to the global list. The minimum rbd id is 1.
2158 */ 2159 */
2159static int rbd_id_get(void) 2160static void rbd_id_get(struct rbd_device *rbd_dev)
2160{ 2161{
2161 return atomic64_inc_return(&rbd_id_max); 2162 rbd_dev->id = atomic64_inc_return(&rbd_id_max);
2163
2164 spin_lock(&rbd_dev_list_lock);
2165 list_add_tail(&rbd_dev->node, &rbd_dev_list);
2166 spin_unlock(&rbd_dev_list_lock);
2162} 2167}
2163 2168
2164/* 2169/*
2165 * Record that an rbd identifier is no longer in use. 2170 * Remove an rbd_dev from the global list, and record that its
2171 * identifier is no longer in use.
2166 */ 2172 */
2167static void rbd_id_put(int rbd_id) 2173static void rbd_id_put(struct rbd_device *rbd_dev)
2168{ 2174{
2169 BUG_ON(rbd_id < 1); 2175 BUG_ON(rbd_dev->id < 1);
2176
2177 spin_lock(&rbd_dev_list_lock);
2178 list_del_init(&rbd_dev->node);
2179 spin_unlock(&rbd_dev_list_lock);
2170 2180
2171 /* 2181 /*
2172 * New id's are always one more than the current maximum. 2182 * New id's are always one more than the current maximum.
2173 * If the id being "put" *is* that maximum, decrement the 2183 * If the id being "put" *is* that maximum, decrement the
2174 * maximum so the next one requested just reuses this one. 2184 * maximum so the next one requested just reuses this one.
2175 */ 2185 */
2176 atomic64_cmpxchg(&rbd_id_max, rbd_id, rbd_id - 1); 2186 atomic64_cmpxchg(&rbd_id_max, rbd_dev->id, rbd_dev->id - 1);
2177} 2187}
2178 2188
2179static ssize_t rbd_add(struct bus_type *bus, 2189static ssize_t rbd_add(struct bus_type *bus,
@@ -2211,12 +2221,7 @@ static ssize_t rbd_add(struct bus_type *bus,
2211 init_rwsem(&rbd_dev->header.snap_rwsem); 2221 init_rwsem(&rbd_dev->header.snap_rwsem);
2212 2222
2213 /* generate unique id: one more than highest used so far */ 2223 /* generate unique id: one more than highest used so far */
2214 rbd_dev->id = rbd_id_get(); 2224 rbd_id_get(rbd_dev);
2215
2216 /* add to global list */
2217 spin_lock(&rbd_dev_list_lock);
2218 list_add_tail(&rbd_dev->node, &rbd_dev_list);
2219 spin_unlock(&rbd_dev_list_lock);
2220 2225
2221 /* parse add command */ 2226 /* parse add command */
2222 if (sscanf(buf, "%" __stringify(RBD_MAX_OPT_LEN) "s " 2227 if (sscanf(buf, "%" __stringify(RBD_MAX_OPT_LEN) "s "
@@ -2279,10 +2284,7 @@ static ssize_t rbd_add(struct bus_type *bus,
2279 return count; 2284 return count;
2280 2285
2281err_out_bus: 2286err_out_bus:
2282 spin_lock(&rbd_dev_list_lock); 2287 rbd_id_put(rbd_dev);
2283 list_del_init(&rbd_dev->node);
2284 spin_unlock(&rbd_dev_list_lock);
2285 rbd_id_put(target_id);
2286 2288
2287 /* this will also clean up rest of rbd_dev stuff */ 2289 /* this will also clean up rest of rbd_dev stuff */
2288 2290
@@ -2296,10 +2298,7 @@ err_out_blkdev:
2296err_out_client: 2298err_out_client:
2297 rbd_put_client(rbd_dev); 2299 rbd_put_client(rbd_dev);
2298err_out_slot: 2300err_out_slot:
2299 spin_lock(&rbd_dev_list_lock); 2301 rbd_id_put(rbd_dev);
2300 list_del_init(&rbd_dev->node);
2301 spin_unlock(&rbd_dev_list_lock);
2302 rbd_id_put(target_id);
2303 2302
2304 kfree(rbd_dev); 2303 kfree(rbd_dev);
2305err_out_opt: 2304err_out_opt:
@@ -2380,11 +2379,7 @@ static ssize_t rbd_remove(struct bus_type *bus,
2380 goto done; 2379 goto done;
2381 } 2380 }
2382 2381
2383 spin_lock(&rbd_dev_list_lock); 2382 rbd_id_put(rbd_dev);
2384 list_del_init(&rbd_dev->node);
2385 spin_unlock(&rbd_dev_list_lock);
2386
2387 rbd_id_put(target_id);
2388 2383
2389 __rbd_remove_all_snaps(rbd_dev); 2384 __rbd_remove_all_snaps(rbd_dev);
2390 rbd_bus_del_dev(rbd_dev); 2385 rbd_bus_del_dev(rbd_dev);