Skip to content

Commit 6ffeba9

Browse files
committed
Merge tag 'dm-4.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: "Two fixes for 4.4-rc1's DM ioctl changes that introduced the potential for infinite recursion on ioctl (with DM multipath). And four stable fixes: - A DM thin-provisioning fix to restore 'error_if_no_space' setting when a thin-pool is made writable again (after having been out of space). - A DM thin-provisioning fix to properly advertise discard support for thin volumes that are stacked on a thin-pool whose underlying data device doesn't support discards. - A DM ioctl fix to allow ctrl-c to break out of an ioctl retry loop when DM multipath is configured to 'queue_if_no_path'. - A DM crypt fix for a possible hang on dm-crypt device removal" * tag 'dm-4.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm thin: fix regression in advertised discard limits dm crypt: fix a possible hang due to race condition on exit dm mpath: fix infinite recursion in ioctl when no paths and !queue_if_no_path dm: do not reuse dm_blk_ioctl block_device input as local variable dm: fix ioctl retry termination with signal dm thin: restore requested 'error_if_no_space' setting on OODS to WRITE transition
2 parents 81b1a83 + 0fcb04d commit 6ffeba9

4 files changed

Lines changed: 36 additions & 29 deletions

File tree

drivers/md/dm-crypt.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ struct iv_tcw_private {
112112
* and encrypts / decrypts at the same time.
113113
*/
114114
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
115-
DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
115+
DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
116+
DM_CRYPT_EXIT_THREAD};
116117

117118
/*
118119
* The fields in here must be read only after initialization.
@@ -1203,20 +1204,18 @@ static int dmcrypt_write(void *data)
12031204
if (!RB_EMPTY_ROOT(&cc->write_tree))
12041205
goto pop_from_list;
12051206

1207+
if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) {
1208+
spin_unlock_irq(&cc->write_thread_wait.lock);
1209+
break;
1210+
}
1211+
12061212
__set_current_state(TASK_INTERRUPTIBLE);
12071213
__add_wait_queue(&cc->write_thread_wait, &wait);
12081214

12091215
spin_unlock_irq(&cc->write_thread_wait.lock);
12101216

1211-
if (unlikely(kthread_should_stop())) {
1212-
set_task_state(current, TASK_RUNNING);
1213-
remove_wait_queue(&cc->write_thread_wait, &wait);
1214-
break;
1215-
}
1216-
12171217
schedule();
12181218

1219-
set_task_state(current, TASK_RUNNING);
12201219
spin_lock_irq(&cc->write_thread_wait.lock);
12211220
__remove_wait_queue(&cc->write_thread_wait, &wait);
12221221
goto continue_locked;
@@ -1531,8 +1530,13 @@ static void crypt_dtr(struct dm_target *ti)
15311530
if (!cc)
15321531
return;
15331532

1534-
if (cc->write_thread)
1533+
if (cc->write_thread) {
1534+
spin_lock_irq(&cc->write_thread_wait.lock);
1535+
set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags);
1536+
wake_up_locked(&cc->write_thread_wait);
1537+
spin_unlock_irq(&cc->write_thread_wait.lock);
15351538
kthread_stop(cc->write_thread);
1539+
}
15361540

15371541
if (cc->io_queue)
15381542
destroy_workqueue(cc->io_queue);

drivers/md/dm-mpath.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,32 +1537,34 @@ static int multipath_prepare_ioctl(struct dm_target *ti,
15371537
struct block_device **bdev, fmode_t *mode)
15381538
{
15391539
struct multipath *m = ti->private;
1540-
struct pgpath *pgpath;
15411540
unsigned long flags;
15421541
int r;
15431542

1544-
r = 0;
1545-
15461543
spin_lock_irqsave(&m->lock, flags);
15471544

15481545
if (!m->current_pgpath)
15491546
__choose_pgpath(m, 0);
15501547

1551-
pgpath = m->current_pgpath;
1552-
1553-
if (pgpath) {
1554-
*bdev = pgpath->path.dev->bdev;
1555-
*mode = pgpath->path.dev->mode;
1548+
if (m->current_pgpath) {
1549+
if (!m->queue_io) {
1550+
*bdev = m->current_pgpath->path.dev->bdev;
1551+
*mode = m->current_pgpath->path.dev->mode;
1552+
r = 0;
1553+
} else {
1554+
/* pg_init has not started or completed */
1555+
r = -ENOTCONN;
1556+
}
1557+
} else {
1558+
/* No path is available */
1559+
if (m->queue_if_no_path)
1560+
r = -ENOTCONN;
1561+
else
1562+
r = -EIO;
15561563
}
15571564

1558-
if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
1559-
r = -ENOTCONN;
1560-
else if (!*bdev)
1561-
r = -EIO;
1562-
15631565
spin_unlock_irqrestore(&m->lock, flags);
15641566

1565-
if (r == -ENOTCONN && !fatal_signal_pending(current)) {
1567+
if (r == -ENOTCONN) {
15661568
spin_lock_irqsave(&m->lock, flags);
15671569
if (!m->current_pg) {
15681570
/* Path status changed, redo selection */

drivers/md/dm-thin.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
24322432
case PM_WRITE:
24332433
if (old_mode != new_mode)
24342434
notify_of_pool_mode_change(pool, "write");
2435+
pool->pf.error_if_no_space = pt->requested_pf.error_if_no_space;
24352436
dm_pool_metadata_read_write(pool->pmd);
24362437
pool->process_bio = process_bio;
24372438
pool->process_discard = process_discard_bio;
@@ -4249,10 +4250,9 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
42494250
{
42504251
struct thin_c *tc = ti->private;
42514252
struct pool *pool = tc->pool;
4252-
struct queue_limits *pool_limits = dm_get_queue_limits(pool->pool_md);
42534253

4254-
if (!pool_limits->discard_granularity)
4255-
return; /* pool's discard support is disabled */
4254+
if (!pool->pf.discard_enabled)
4255+
return;
42564256

42574257
limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
42584258
limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */

drivers/md/dm.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ static int dm_get_live_table_for_ioctl(struct mapped_device *md,
591591

592592
out:
593593
dm_put_live_table(md, *srcu_idx);
594-
if (r == -ENOTCONN) {
594+
if (r == -ENOTCONN && !fatal_signal_pending(current)) {
595595
msleep(10);
596596
goto retry;
597597
}
@@ -603,9 +603,10 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
603603
{
604604
struct mapped_device *md = bdev->bd_disk->private_data;
605605
struct dm_target *tgt;
606+
struct block_device *tgt_bdev = NULL;
606607
int srcu_idx, r;
607608

608-
r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
609+
r = dm_get_live_table_for_ioctl(md, &tgt, &tgt_bdev, &mode, &srcu_idx);
609610
if (r < 0)
610611
return r;
611612

@@ -620,7 +621,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
620621
goto out;
621622
}
622623

623-
r = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
624+
r = __blkdev_driver_ioctl(tgt_bdev, mode, cmd, arg);
624625
out:
625626
dm_put_live_table(md, srcu_idx);
626627
return r;

0 commit comments

Comments
 (0)