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.

Revert "dm: fix a race condition in retrieve_deps"

This reverts commit f6007dce0cd35d634d9be91ef3515a6385dcee16.

Commit f6007dce0cd3 ("dm: fix a race condition in retrieve_deps") was
added to fix a race between retrieving the list of dm table devices and
multipath_message() modifying the list of table devices. But Commit
a48f6b82c5c4 ("dm mpath: don't call dm_get_device in multipath_message")
removed the call to dm_get_device() from multipath_message(). After that
commit, the only calls to dm_get_device() and dm_put_device() are in
target constructors and destructors, so the race with retrieve_deps() is
no longer possible.

Suggested-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

authored by

Benjamin Marzinski and committed by
Mikulas Patocka
4550a71b 787bd63e

+9 -31
-1
drivers/md/dm-core.h
··· 215 215 216 216 /* a list of devices used by this table */ 217 217 struct list_head devices; 218 - struct rw_semaphore devices_lock; 219 218 220 219 /* events get handed up using this callback */ 221 220 void (*event_fn)(void *data);
+1 -6
drivers/md/dm-ioctl.c
··· 1648 1648 struct dm_dev_internal *dd; 1649 1649 struct dm_target_deps *deps; 1650 1650 1651 - down_read(&table->devices_lock); 1652 - 1653 1651 deps = get_result_buffer(param, param_size, &len); 1654 1652 1655 1653 /* ··· 1662 1664 needed = struct_size(deps, dev, count); 1663 1665 if (len < needed) { 1664 1666 param->flags |= DM_BUFFER_FULL_FLAG; 1665 - goto out; 1667 + return; 1666 1668 } 1667 1669 1668 1670 /* ··· 1674 1676 deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev); 1675 1677 1676 1678 param->data_size = param->data_start + needed; 1677 - 1678 - out: 1679 - up_read(&table->devices_lock); 1680 1679 } 1681 1680 1682 1681 static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size)
+8 -24
drivers/md/dm-table.c
··· 139 139 return -ENOMEM; 140 140 141 141 INIT_LIST_HEAD(&t->devices); 142 - init_rwsem(&t->devices_lock); 143 142 144 143 if (!num_targets) 145 144 num_targets = KEYS_PER_NODE; ··· 379 380 if (dev == disk_devt(t->md->disk)) 380 381 return -EINVAL; 381 382 382 - down_write(&t->devices_lock); 383 - 384 383 dd = find_device(&t->devices, dev); 385 384 if (!dd) { 386 385 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 387 - if (!dd) { 388 - r = -ENOMEM; 389 - goto unlock_ret_r; 390 - } 386 + if (!dd) 387 + return -ENOMEM; 391 388 392 389 r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev); 393 390 if (r) { 394 391 kfree(dd); 395 - goto unlock_ret_r; 392 + return r; 396 393 } 397 394 398 395 refcount_set(&dd->count, 1); ··· 398 403 } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { 399 404 r = upgrade_mode(dd, mode, t->md); 400 405 if (r) 401 - goto unlock_ret_r; 406 + return r; 402 407 } 403 408 refcount_inc(&dd->count); 404 409 out: 405 - up_write(&t->devices_lock); 406 410 *result = dd->dm_dev; 407 411 return 0; 408 - 409 - unlock_ret_r: 410 - up_write(&t->devices_lock); 411 - return r; 412 412 } 413 413 EXPORT_SYMBOL(dm_get_device); 414 414 ··· 454 464 void dm_put_device(struct dm_target *ti, struct dm_dev *d) 455 465 { 456 466 int found = 0; 457 - struct dm_table *t = ti->table; 458 - struct list_head *devices = &t->devices; 467 + struct list_head *devices = &ti->table->devices; 459 468 struct dm_dev_internal *dd; 460 - 461 - down_write(&t->devices_lock); 462 469 463 470 list_for_each_entry(dd, devices, list) { 464 471 if (dd->dm_dev == d) { ··· 465 478 } 466 479 if (!found) { 467 480 DMERR("%s: device %s not in table devices list", 468 - dm_device_name(t->md), d->name); 469 - goto unlock_ret; 481 + dm_device_name(ti->table->md), d->name); 482 + return; 470 483 } 471 484 if (refcount_dec_and_test(&dd->count)) { 472 - dm_put_table_device(t->md, d); 485 + dm_put_table_device(ti->table->md, d); 473 486 list_del(&dd->list); 474 487 kfree(dd); 475 488 } 476 - 477 - unlock_ret: 478 - up_write(&t->devices_lock); 479 489 } 480 490 EXPORT_SYMBOL(dm_put_device); 481 491