aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-ioctl.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 79ee5ba217f2..6a6d475f8e80 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -249,40 +249,46 @@ static void __hash_remove(struct hash_cell *hc)
249 249
250static void dm_hash_remove_all(int keep_open_devices) 250static void dm_hash_remove_all(int keep_open_devices)
251{ 251{
252 int i, dev_skipped, dev_removed; 252 int i, dev_skipped;
253 struct hash_cell *hc; 253 struct hash_cell *hc;
254 struct list_head *tmp, *n; 254 struct mapped_device *md;
255
256retry:
257 dev_skipped = 0;
255 258
256 down_write(&_hash_lock); 259 down_write(&_hash_lock);
257 260
258retry:
259 dev_skipped = dev_removed = 0;
260 for (i = 0; i < NUM_BUCKETS; i++) { 261 for (i = 0; i < NUM_BUCKETS; i++) {
261 list_for_each_safe (tmp, n, _name_buckets + i) { 262 list_for_each_entry(hc, _name_buckets + i, name_list) {
262 hc = list_entry(tmp, struct hash_cell, name_list); 263 md = hc->md;
264 dm_get(md);
263 265
264 if (keep_open_devices && 266 if (keep_open_devices && dm_lock_for_deletion(md)) {
265 dm_lock_for_deletion(hc->md)) { 267 dm_put(md);
266 dev_skipped++; 268 dev_skipped++;
267 continue; 269 continue;
268 } 270 }
271
269 __hash_remove(hc); 272 __hash_remove(hc);
270 dev_removed = 1;
271 }
272 }
273 273
274 /* 274 up_write(&_hash_lock);
275 * Some mapped devices may be using other mapped devices, so if any
276 * still exist, repeat until we make no further progress.
277 */
278 if (dev_skipped) {
279 if (dev_removed)
280 goto retry;
281 275
282 DMWARN("remove_all left %d open device(s)", dev_skipped); 276 dm_put(md);
277
278 /*
279 * Some mapped devices may be using other mapped
280 * devices, so repeat until we make no further
281 * progress. If a new mapped device is created
282 * here it will also get removed.
283 */
284 goto retry;
285 }
283 } 286 }
284 287
285 up_write(&_hash_lock); 288 up_write(&_hash_lock);
289
290 if (dev_skipped)
291 DMWARN("remove_all left %d open device(s)", dev_skipped);
286} 292}
287 293
288static struct mapped_device *dm_hash_rename(struct dm_ioctl *param, 294static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,