diff options
| -rw-r--r-- | drivers/md/dm-crypt.c | 22 | ||||
| -rw-r--r-- | drivers/md/dm-mpath.c | 30 | ||||
| -rw-r--r-- | drivers/md/dm-thin.c | 6 | ||||
| -rw-r--r-- | drivers/md/dm.c | 7 |
4 files changed, 36 insertions, 29 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 917d47e290ae..3147c8d09ea8 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -112,7 +112,8 @@ struct iv_tcw_private { | |||
| 112 | * and encrypts / decrypts at the same time. | 112 | * and encrypts / decrypts at the same time. |
| 113 | */ | 113 | */ |
| 114 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, | 114 | 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}; | ||
| 116 | 117 | ||
| 117 | /* | 118 | /* |
| 118 | * The fields in here must be read only after initialization. | 119 | * The fields in here must be read only after initialization. |
| @@ -1203,20 +1204,18 @@ continue_locked: | |||
| 1203 | if (!RB_EMPTY_ROOT(&cc->write_tree)) | 1204 | if (!RB_EMPTY_ROOT(&cc->write_tree)) |
| 1204 | goto pop_from_list; | 1205 | goto pop_from_list; |
| 1205 | 1206 | ||
| 1207 | if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) { | ||
| 1208 | spin_unlock_irq(&cc->write_thread_wait.lock); | ||
| 1209 | break; | ||
| 1210 | } | ||
| 1211 | |||
| 1206 | __set_current_state(TASK_INTERRUPTIBLE); | 1212 | __set_current_state(TASK_INTERRUPTIBLE); |
| 1207 | __add_wait_queue(&cc->write_thread_wait, &wait); | 1213 | __add_wait_queue(&cc->write_thread_wait, &wait); |
| 1208 | 1214 | ||
| 1209 | spin_unlock_irq(&cc->write_thread_wait.lock); | 1215 | spin_unlock_irq(&cc->write_thread_wait.lock); |
| 1210 | 1216 | ||
| 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 | |||
| 1217 | schedule(); | 1217 | schedule(); |
| 1218 | 1218 | ||
| 1219 | set_task_state(current, TASK_RUNNING); | ||
| 1220 | spin_lock_irq(&cc->write_thread_wait.lock); | 1219 | spin_lock_irq(&cc->write_thread_wait.lock); |
| 1221 | __remove_wait_queue(&cc->write_thread_wait, &wait); | 1220 | __remove_wait_queue(&cc->write_thread_wait, &wait); |
| 1222 | goto continue_locked; | 1221 | goto continue_locked; |
| @@ -1531,8 +1530,13 @@ static void crypt_dtr(struct dm_target *ti) | |||
| 1531 | if (!cc) | 1530 | if (!cc) |
| 1532 | return; | 1531 | return; |
| 1533 | 1532 | ||
| 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); | ||
| 1535 | kthread_stop(cc->write_thread); | 1538 | kthread_stop(cc->write_thread); |
| 1539 | } | ||
| 1536 | 1540 | ||
| 1537 | if (cc->io_queue) | 1541 | if (cc->io_queue) |
| 1538 | destroy_workqueue(cc->io_queue); | 1542 | destroy_workqueue(cc->io_queue); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index aaa6caa46a9f..cfa29f574c2a 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -1537,32 +1537,34 @@ static int multipath_prepare_ioctl(struct dm_target *ti, | |||
| 1537 | struct block_device **bdev, fmode_t *mode) | 1537 | struct block_device **bdev, fmode_t *mode) |
| 1538 | { | 1538 | { |
| 1539 | struct multipath *m = ti->private; | 1539 | struct multipath *m = ti->private; |
| 1540 | struct pgpath *pgpath; | ||
| 1541 | unsigned long flags; | 1540 | unsigned long flags; |
| 1542 | int r; | 1541 | int r; |
| 1543 | 1542 | ||
| 1544 | r = 0; | ||
| 1545 | |||
| 1546 | spin_lock_irqsave(&m->lock, flags); | 1543 | spin_lock_irqsave(&m->lock, flags); |
| 1547 | 1544 | ||
| 1548 | if (!m->current_pgpath) | 1545 | if (!m->current_pgpath) |
| 1549 | __choose_pgpath(m, 0); | 1546 | __choose_pgpath(m, 0); |
| 1550 | 1547 | ||
| 1551 | pgpath = m->current_pgpath; | 1548 | if (m->current_pgpath) { |
| 1552 | 1549 | if (!m->queue_io) { | |
| 1553 | if (pgpath) { | 1550 | *bdev = m->current_pgpath->path.dev->bdev; |
| 1554 | *bdev = pgpath->path.dev->bdev; | 1551 | *mode = m->current_pgpath->path.dev->mode; |
| 1555 | *mode = 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; | ||
| 1556 | } | 1563 | } |
| 1557 | 1564 | ||
| 1558 | if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path)) | ||
| 1559 | r = -ENOTCONN; | ||
| 1560 | else if (!*bdev) | ||
| 1561 | r = -EIO; | ||
| 1562 | |||
| 1563 | spin_unlock_irqrestore(&m->lock, flags); | 1565 | spin_unlock_irqrestore(&m->lock, flags); |
| 1564 | 1566 | ||
| 1565 | if (r == -ENOTCONN && !fatal_signal_pending(current)) { | 1567 | if (r == -ENOTCONN) { |
| 1566 | spin_lock_irqsave(&m->lock, flags); | 1568 | spin_lock_irqsave(&m->lock, flags); |
| 1567 | if (!m->current_pg) { | 1569 | if (!m->current_pg) { |
| 1568 | /* Path status changed, redo selection */ | 1570 | /* Path status changed, redo selection */ |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 3897b90bd462..63903a5a5d9e 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -2432,6 +2432,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | |||
| 2432 | case PM_WRITE: | 2432 | case PM_WRITE: |
| 2433 | if (old_mode != new_mode) | 2433 | if (old_mode != new_mode) |
| 2434 | notify_of_pool_mode_change(pool, "write"); | 2434 | notify_of_pool_mode_change(pool, "write"); |
| 2435 | pool->pf.error_if_no_space = pt->requested_pf.error_if_no_space; | ||
| 2435 | dm_pool_metadata_read_write(pool->pmd); | 2436 | dm_pool_metadata_read_write(pool->pmd); |
| 2436 | pool->process_bio = process_bio; | 2437 | pool->process_bio = process_bio; |
| 2437 | pool->process_discard = process_discard_bio; | 2438 | pool->process_discard = process_discard_bio; |
| @@ -4249,10 +4250,9 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
| 4249 | { | 4250 | { |
| 4250 | struct thin_c *tc = ti->private; | 4251 | struct thin_c *tc = ti->private; |
| 4251 | struct pool *pool = tc->pool; | 4252 | struct pool *pool = tc->pool; |
| 4252 | struct queue_limits *pool_limits = dm_get_queue_limits(pool->pool_md); | ||
| 4253 | 4253 | ||
| 4254 | if (!pool_limits->discard_granularity) | 4254 | if (!pool->pf.discard_enabled) |
| 4255 | return; /* pool's discard support is disabled */ | 4255 | return; |
| 4256 | 4256 | ||
| 4257 | limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT; | 4257 | limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT; |
| 4258 | limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */ | 4258 | limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */ |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6e15f3565892..5df40480228b 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -591,7 +591,7 @@ retry: | |||
| 591 | 591 | ||
| 592 | out: | 592 | out: |
| 593 | dm_put_live_table(md, *srcu_idx); | 593 | dm_put_live_table(md, *srcu_idx); |
| 594 | if (r == -ENOTCONN) { | 594 | if (r == -ENOTCONN && !fatal_signal_pending(current)) { |
| 595 | msleep(10); | 595 | msleep(10); |
| 596 | goto retry; | 596 | goto retry; |
| 597 | } | 597 | } |
| @@ -603,9 +603,10 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 603 | { | 603 | { |
| 604 | struct mapped_device *md = bdev->bd_disk->private_data; | 604 | struct mapped_device *md = bdev->bd_disk->private_data; |
| 605 | struct dm_target *tgt; | 605 | struct dm_target *tgt; |
| 606 | struct block_device *tgt_bdev = NULL; | ||
| 606 | int srcu_idx, r; | 607 | int srcu_idx, r; |
| 607 | 608 | ||
| 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); |
| 609 | if (r < 0) | 610 | if (r < 0) |
| 610 | return r; | 611 | return r; |
| 611 | 612 | ||
| @@ -620,7 +621,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 620 | goto out; | 621 | goto out; |
| 621 | } | 622 | } |
| 622 | 623 | ||
| 623 | r = __blkdev_driver_ioctl(bdev, mode, cmd, arg); | 624 | r = __blkdev_driver_ioctl(tgt_bdev, mode, cmd, arg); |
| 624 | out: | 625 | out: |
| 625 | dm_put_live_table(md, srcu_idx); | 626 | dm_put_live_table(md, srcu_idx); |
| 626 | return r; | 627 | return r; |
