Skip to content

Commit 9eb7109

Browse files
bmarzinsMikulas Patocka
authored andcommitted
dm: don't change md if dm_table_set_restrictions() fails
__bind was changing the disk capacity, geometry and mempools of the mapped device before calling dm_table_set_restrictions() which could fail, forcing dm to drop the new table. Failing here would leave the device using the old table but with the wrong capacity and mempools. Move dm_table_set_restrictions() earlier in __bind(). Since it needs the capacity to be set, save the old version and restore it on failure. Fixes: bb37d77 ("dm: introduce zone append emulation") Reviewed-by: Damien Le Moal <[email protected]> Tested-by: Damien Le Moal <[email protected]> Signed-off-by: Benjamin Marzinski <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]>
1 parent 0af2f6b commit 9eb7109

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

drivers/md/dm.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2421,21 +2421,29 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
24212421
struct queue_limits *limits)
24222422
{
24232423
struct dm_table *old_map;
2424-
sector_t size;
2424+
sector_t size, old_size;
24252425
int ret;
24262426

24272427
lockdep_assert_held(&md->suspend_lock);
24282428

24292429
size = dm_table_get_size(t);
24302430

2431+
old_size = dm_get_size(md);
2432+
set_capacity(md->disk, size);
2433+
2434+
ret = dm_table_set_restrictions(t, md->queue, limits);
2435+
if (ret) {
2436+
set_capacity(md->disk, old_size);
2437+
old_map = ERR_PTR(ret);
2438+
goto out;
2439+
}
2440+
24312441
/*
24322442
* Wipe any geometry if the size of the table changed.
24332443
*/
2434-
if (size != dm_get_size(md))
2444+
if (size != old_size)
24352445
memset(&md->geometry, 0, sizeof(md->geometry));
24362446

2437-
set_capacity(md->disk, size);
2438-
24392447
dm_table_event_callback(t, event_callback, md);
24402448

24412449
if (dm_table_request_based(t)) {
@@ -2468,12 +2476,6 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
24682476
t->mempools = NULL;
24692477
}
24702478

2471-
ret = dm_table_set_restrictions(t, md->queue, limits);
2472-
if (ret) {
2473-
old_map = ERR_PTR(ret);
2474-
goto out;
2475-
}
2476-
24772479
old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
24782480
rcu_assign_pointer(md->map, (void *)t);
24792481
md->immutable_target_type = dm_table_get_immutable_target_type(t);

0 commit comments

Comments
 (0)