Skip to content

Commit 4550a71

Browse files
bmarzinsMikulas Patocka
authored andcommitted
Revert "dm: fix a race condition in retrieve_deps"
This reverts commit f6007dc. Commit f6007dc ("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 a48f6b8 ("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>
1 parent 787bd63 commit 4550a71

3 files changed

Lines changed: 9 additions & 31 deletions

File tree

drivers/md/dm-core.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ struct dm_table {
215215

216216
/* a list of devices used by this table */
217217
struct list_head devices;
218-
struct rw_semaphore devices_lock;
219218

220219
/* events get handed up using this callback */
221220
void (*event_fn)(void *data);

drivers/md/dm-ioctl.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,8 +1648,6 @@ static void retrieve_deps(struct dm_table *table,
16481648
struct dm_dev_internal *dd;
16491649
struct dm_target_deps *deps;
16501650

1651-
down_read(&table->devices_lock);
1652-
16531651
deps = get_result_buffer(param, param_size, &len);
16541652

16551653
/*
@@ -1664,7 +1662,7 @@ static void retrieve_deps(struct dm_table *table,
16641662
needed = struct_size(deps, dev, count);
16651663
if (len < needed) {
16661664
param->flags |= DM_BUFFER_FULL_FLAG;
1667-
goto out;
1665+
return;
16681666
}
16691667

16701668
/*
@@ -1676,9 +1674,6 @@ static void retrieve_deps(struct dm_table *table,
16761674
deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev);
16771675

16781676
param->data_size = param->data_start + needed;
1679-
1680-
out:
1681-
up_read(&table->devices_lock);
16821677
}
16831678

16841679
static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size)

drivers/md/dm-table.c

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ int dm_table_create(struct dm_table **result, blk_mode_t mode,
139139
return -ENOMEM;
140140

141141
INIT_LIST_HEAD(&t->devices);
142-
init_rwsem(&t->devices_lock);
143142

144143
if (!num_targets)
145144
num_targets = KEYS_PER_NODE;
@@ -380,20 +379,16 @@ int dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode,
380379
if (dev == disk_devt(t->md->disk))
381380
return -EINVAL;
382381

383-
down_write(&t->devices_lock);
384-
385382
dd = find_device(&t->devices, dev);
386383
if (!dd) {
387384
dd = kmalloc(sizeof(*dd), GFP_KERNEL);
388-
if (!dd) {
389-
r = -ENOMEM;
390-
goto unlock_ret_r;
391-
}
385+
if (!dd)
386+
return -ENOMEM;
392387

393388
r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev);
394389
if (r) {
395390
kfree(dd);
396-
goto unlock_ret_r;
391+
return r;
397392
}
398393

399394
refcount_set(&dd->count, 1);
@@ -403,17 +398,12 @@ int dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode,
403398
} else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) {
404399
r = upgrade_mode(dd, mode, t->md);
405400
if (r)
406-
goto unlock_ret_r;
401+
return r;
407402
}
408403
refcount_inc(&dd->count);
409404
out:
410-
up_write(&t->devices_lock);
411405
*result = dd->dm_dev;
412406
return 0;
413-
414-
unlock_ret_r:
415-
up_write(&t->devices_lock);
416-
return r;
417407
}
418408
EXPORT_SYMBOL(dm_get_device);
419409

@@ -464,12 +454,9 @@ static int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
464454
void dm_put_device(struct dm_target *ti, struct dm_dev *d)
465455
{
466456
int found = 0;
467-
struct dm_table *t = ti->table;
468-
struct list_head *devices = &t->devices;
457+
struct list_head *devices = &ti->table->devices;
469458
struct dm_dev_internal *dd;
470459

471-
down_write(&t->devices_lock);
472-
473460
list_for_each_entry(dd, devices, list) {
474461
if (dd->dm_dev == d) {
475462
found = 1;
@@ -478,17 +465,14 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d)
478465
}
479466
if (!found) {
480467
DMERR("%s: device %s not in table devices list",
481-
dm_device_name(t->md), d->name);
482-
goto unlock_ret;
468+
dm_device_name(ti->table->md), d->name);
469+
return;
483470
}
484471
if (refcount_dec_and_test(&dd->count)) {
485-
dm_put_table_device(t->md, d);
472+
dm_put_table_device(ti->table->md, d);
486473
list_del(&dd->list);
487474
kfree(dd);
488475
}
489-
490-
unlock_ret:
491-
up_write(&t->devices_lock);
492476
}
493477
EXPORT_SYMBOL(dm_put_device);
494478

0 commit comments

Comments
 (0)