Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dm: make "dmsetup remove_all" interruptible

The command "dmsetup remove_all" may take a long time (a minute for
removing 1000 devices), so make it interruptible with fatal signals.

For better readability, the bool arguments were changed to flags.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>

+25 -10
+25 -10
drivers/md/dm-ioctl.c
··· 64 64 static struct rb_root name_rb_tree = RB_ROOT; 65 65 static struct rb_root uuid_rb_tree = RB_ROOT; 66 66 67 - static void dm_hash_remove_all(bool keep_open_devices, bool mark_deferred, bool only_deferred); 67 + #define DM_REMOVE_KEEP_OPEN_DEVICES 1 68 + #define DM_REMOVE_MARK_DEFERRED 2 69 + #define DM_REMOVE_ONLY_DEFERRED 4 70 + #define DM_REMOVE_INTERRUPTIBLE 8 71 + static int dm_hash_remove_all(unsigned flags); 68 72 69 73 /* 70 74 * Guards access to both hash tables. ··· 82 78 83 79 static void dm_hash_exit(void) 84 80 { 85 - dm_hash_remove_all(false, false, false); 81 + dm_hash_remove_all(0); 86 82 } 87 83 88 84 /* ··· 337 333 return table; 338 334 } 339 335 340 - static void dm_hash_remove_all(bool keep_open_devices, bool mark_deferred, bool only_deferred) 336 + static int dm_hash_remove_all(unsigned flags) 341 337 { 342 338 int dev_skipped; 343 339 struct rb_node *n; ··· 351 347 down_write(&_hash_lock); 352 348 353 349 for (n = rb_first(&name_rb_tree); n; n = rb_next(n)) { 350 + if (flags & DM_REMOVE_INTERRUPTIBLE && fatal_signal_pending(current)) { 351 + up_write(&_hash_lock); 352 + return -EINTR; 353 + } 354 + 354 355 hc = container_of(n, struct hash_cell, name_node); 355 356 md = hc->md; 356 357 dm_get(md); 357 358 358 - if (keep_open_devices && 359 - dm_lock_for_deletion(md, mark_deferred, only_deferred)) { 359 + if (flags & DM_REMOVE_KEEP_OPEN_DEVICES && 360 + dm_lock_for_deletion(md, !!(flags & DM_REMOVE_MARK_DEFERRED), !!(flags & DM_REMOVE_ONLY_DEFERRED))) { 360 361 dm_put(md); 361 362 dev_skipped++; 362 363 continue; ··· 377 368 } 378 369 dm_ima_measure_on_device_remove(md, true); 379 370 dm_put(md); 380 - if (likely(keep_open_devices)) 371 + if (likely(flags & DM_REMOVE_KEEP_OPEN_DEVICES)) 381 372 dm_destroy(md); 382 373 else 383 374 dm_destroy_immediate(md); ··· 393 384 394 385 up_write(&_hash_lock); 395 386 396 - if (dev_skipped && !only_deferred) 387 + if (dev_skipped && !(flags & DM_REMOVE_ONLY_DEFERRED)) 397 388 DMWARN("remove_all left %d open device(s)", dev_skipped); 389 + 390 + return 0; 398 391 } 399 392 400 393 /* ··· 524 513 525 514 void dm_deferred_remove(void) 526 515 { 527 - dm_hash_remove_all(true, false, true); 516 + dm_hash_remove_all(DM_REMOVE_KEEP_OPEN_DEVICES | DM_REMOVE_ONLY_DEFERRED); 528 517 } 529 518 530 519 /* ··· 540 529 541 530 static int remove_all(struct file *filp, struct dm_ioctl *param, size_t param_size) 542 531 { 543 - dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false); 532 + int r; 533 + int flags = DM_REMOVE_KEEP_OPEN_DEVICES | DM_REMOVE_INTERRUPTIBLE; 534 + if (param->flags & DM_DEFERRED_REMOVE) 535 + flags |= DM_REMOVE_MARK_DEFERRED; 536 + r = dm_hash_remove_all(flags); 544 537 param->data_size = 0; 545 - return 0; 538 + return r; 546 539 } 547 540 548 541 /*