diff options
author | Asai Thambi SP <asamymuthupa@micron.com> | 2016-02-25 00:18:10 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-03-03 11:08:43 -0500 |
commit | 51c6570eb922146470c2fe660c34585414679bd6 (patch) | |
tree | 1bb30615e06ad211bd7c4185e163332410b1a469 | |
parent | 59cf70e236c96594d9f1e065755d8fce9df5356b (diff) |
mtip32xx: Handle safe removal during IO
Flush inflight IOs using fsync_bdev() when the device is safely
removed. Also, block further IOs in device open function.
Signed-off-by: Selvan Mani <smani@micron.com>
Signed-off-by: Rajesh Kumar Sambandam <rsambandam@micron.com>
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 34 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 1 |
2 files changed, 33 insertions, 2 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 4c4d13aadf77..6268ea006354 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -3595,6 +3595,28 @@ static int mtip_block_getgeo(struct block_device *dev, | |||
3595 | return 0; | 3595 | return 0; |
3596 | } | 3596 | } |
3597 | 3597 | ||
3598 | static int mtip_block_open(struct block_device *dev, fmode_t mode) | ||
3599 | { | ||
3600 | struct driver_data *dd; | ||
3601 | |||
3602 | if (dev && dev->bd_disk) { | ||
3603 | dd = (struct driver_data *) dev->bd_disk->private_data; | ||
3604 | |||
3605 | if (dd) { | ||
3606 | if (test_bit(MTIP_DDF_REMOVAL_BIT, | ||
3607 | &dd->dd_flag)) { | ||
3608 | return -ENODEV; | ||
3609 | } | ||
3610 | return 0; | ||
3611 | } | ||
3612 | } | ||
3613 | return -ENODEV; | ||
3614 | } | ||
3615 | |||
3616 | void mtip_block_release(struct gendisk *disk, fmode_t mode) | ||
3617 | { | ||
3618 | } | ||
3619 | |||
3598 | /* | 3620 | /* |
3599 | * Block device operation function. | 3621 | * Block device operation function. |
3600 | * | 3622 | * |
@@ -3602,6 +3624,8 @@ static int mtip_block_getgeo(struct block_device *dev, | |||
3602 | * layer. | 3624 | * layer. |
3603 | */ | 3625 | */ |
3604 | static const struct block_device_operations mtip_block_ops = { | 3626 | static const struct block_device_operations mtip_block_ops = { |
3627 | .open = mtip_block_open, | ||
3628 | .release = mtip_block_release, | ||
3605 | .ioctl = mtip_block_ioctl, | 3629 | .ioctl = mtip_block_ioctl, |
3606 | #ifdef CONFIG_COMPAT | 3630 | #ifdef CONFIG_COMPAT |
3607 | .compat_ioctl = mtip_block_compat_ioctl, | 3631 | .compat_ioctl = mtip_block_compat_ioctl, |
@@ -4427,7 +4451,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4427 | struct driver_data *dd = pci_get_drvdata(pdev); | 4451 | struct driver_data *dd = pci_get_drvdata(pdev); |
4428 | unsigned long flags, to; | 4452 | unsigned long flags, to; |
4429 | 4453 | ||
4430 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); | 4454 | set_bit(MTIP_DDF_REMOVAL_BIT, &dd->dd_flag); |
4431 | 4455 | ||
4432 | spin_lock_irqsave(&dev_lock, flags); | 4456 | spin_lock_irqsave(&dev_lock, flags); |
4433 | list_del_init(&dd->online_list); | 4457 | list_del_init(&dd->online_list); |
@@ -4444,12 +4468,18 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4444 | } while (atomic_read(&dd->irq_workers_active) != 0 && | 4468 | } while (atomic_read(&dd->irq_workers_active) != 0 && |
4445 | time_before(jiffies, to)); | 4469 | time_before(jiffies, to)); |
4446 | 4470 | ||
4471 | fsync_bdev(dd->bdev); | ||
4472 | |||
4447 | if (atomic_read(&dd->irq_workers_active) != 0) { | 4473 | if (atomic_read(&dd->irq_workers_active) != 0) { |
4448 | dev_warn(&dd->pdev->dev, | 4474 | dev_warn(&dd->pdev->dev, |
4449 | "Completion workers still active!\n"); | 4475 | "Completion workers still active!\n"); |
4450 | } | 4476 | } |
4451 | 4477 | ||
4452 | blk_mq_stop_hw_queues(dd->queue); | 4478 | if (dd->sr) |
4479 | blk_mq_stop_hw_queues(dd->queue); | ||
4480 | |||
4481 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); | ||
4482 | |||
4453 | /* Clean up the block layer. */ | 4483 | /* Clean up the block layer. */ |
4454 | mtip_block_remove(dd); | 4484 | mtip_block_remove(dd); |
4455 | 4485 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 8635239c521f..50af742421e2 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -158,6 +158,7 @@ enum { | |||
158 | MTIP_DDF_RESUME_BIT = 6, | 158 | MTIP_DDF_RESUME_BIT = 6, |
159 | MTIP_DDF_INIT_DONE_BIT = 7, | 159 | MTIP_DDF_INIT_DONE_BIT = 7, |
160 | MTIP_DDF_REBUILD_FAILED_BIT = 8, | 160 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
161 | MTIP_DDF_REMOVAL_BIT = 9, | ||
161 | 162 | ||
162 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | | 163 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | |
163 | (1 << MTIP_DDF_SEC_LOCK_BIT) | | 164 | (1 << MTIP_DDF_SEC_LOCK_BIT) | |