Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtip32xx: Abort I/O during secure erase operation

Currently I/Os are being queued when secure erase operation starts, and issue
them after the operation completes. As all data will be gone when the operation
completes, any queued I/O doesn't make sense. Hence, abort I/O (return -ENODATA)
as soon as the driver receives.

Signed-off-by: Selvan Mani <smani@micron.com>
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Asai Thambi SP and committed by
Jens Axboe
686d8e0b ee04bed6

+28 -4
+28 -4
drivers/block/mtip32xx/mtip32xx.c
··· 994 994 return false; 995 995 996 996 if (fis->command == ATA_CMD_SEC_ERASE_PREP) { 997 - set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); 998 997 port->ic_pause_timer = jiffies; 999 998 return true; 1000 999 } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && ··· 1008 1009 clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); 1009 1010 /* Com reset after secure erase or lowlevel format */ 1010 1011 mtip_restart_port(port); 1012 + clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); 1011 1013 return false; 1012 1014 } 1013 1015 ··· 1108 1108 int_cmd = mtip_get_int_command(dd); 1109 1109 1110 1110 set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); 1111 - port->ic_pause_timer = 0; 1112 1111 1113 - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); 1112 + if (fis->command == ATA_CMD_SEC_ERASE_PREP) 1113 + set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); 1114 + 1114 1115 clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); 1115 1116 1116 1117 if (atomic == GFP_KERNEL) { ··· 1248 1247 exec_ic_exit: 1249 1248 /* Clear the allocated and active bits for the internal command. */ 1250 1249 mtip_put_int_command(dd, int_cmd); 1250 + clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); 1251 1251 if (rv >= 0 && mtip_pause_ncq(port, fis)) { 1252 1252 /* NCQ paused */ 1253 1253 return rv; 1254 1254 } 1255 - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); 1256 1255 wake_up_interruptible(&port->svc_wait); 1257 1256 1258 1257 return rv; ··· 3685 3684 .owner = THIS_MODULE 3686 3685 }; 3687 3686 3687 + static inline bool is_se_active(struct driver_data *dd) 3688 + { 3689 + if (unlikely(test_bit(MTIP_PF_SE_ACTIVE_BIT, &dd->port->flags))) { 3690 + if (dd->port->ic_pause_timer) { 3691 + unsigned long to = dd->port->ic_pause_timer + 3692 + msecs_to_jiffies(1000); 3693 + if (time_after(jiffies, to)) { 3694 + clear_bit(MTIP_PF_SE_ACTIVE_BIT, 3695 + &dd->port->flags); 3696 + clear_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag); 3697 + dd->port->ic_pause_timer = 0; 3698 + wake_up_interruptible(&dd->port->svc_wait); 3699 + return false; 3700 + } 3701 + } 3702 + return true; 3703 + } 3704 + return false; 3705 + } 3706 + 3688 3707 /* 3689 3708 * Block layer make request function. 3690 3709 * ··· 3721 3700 struct driver_data *dd = hctx->queue->queuedata; 3722 3701 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); 3723 3702 unsigned int nents; 3703 + 3704 + if (is_se_active(dd)) 3705 + return -ENODATA; 3724 3706 3725 3707 if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { 3726 3708 if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,