[PATCH 3/4] disk-protect: Add a REQ_TYPE_LINUX_BLOCK request handler to libata

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Defines a generic handler to be used as the lb_request_fn() callback for
libata managed hosts. Support for REQ_LB_OP_FREEZE and REQ_LB_OP_THAW is
included as well.

Signed-off-by: Elias Oltmanns <eo@xxxxxxxxxxxxxx>
---

 drivers/ata/ahci.c        |    1 +
 drivers/ata/ata_piix.c    |    1 +
 drivers/ata/libata-scsi.c |   53 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/blkdev.h    |    2 ++
 include/linux/libata.h    |    1 +
 5 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 54f38c2..324c4fa 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -273,6 +273,7 @@ static struct scsi_host_template ahci_sht = {
 	.name			= DRV_NAME,
 	.ioctl			= ata_scsi_ioctl,
 	.queuecommand		= ata_scsi_queuecmd,
+	.lb_request_fn		= ata_scsi_lb_request_fn,
 	.change_queue_depth	= ata_scsi_change_queue_depth,
 	.can_queue		= AHCI_MAX_CMDS - 1,
 	.this_id		= ATA_SHT_THIS_ID,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index b406b39..c2b7ad7 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -283,6 +283,7 @@ static struct scsi_host_template piix_sht = {
 	.name			= DRV_NAME,
 	.ioctl			= ata_scsi_ioctl,
 	.queuecommand		= ata_scsi_queuecmd,
+	.lb_request_fn		= ata_scsi_lb_request_fn,
 	.can_queue		= ATA_DEF_QUEUE,
 	.this_id		= ATA_SHT_THIS_ID,
 	.sg_tablesize		= LIBATA_MAX_PRD,
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d0fd762..df25aa4 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3123,6 +3123,59 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
 	}
 }
 
+/**
+ *	ata_scsi_lb_request_fn - process block request for libata-managed device
+ *	@req: REQ_TYPE_LINUX_BLOCK request to be processed
+ *
+ *	This function is the default handler for REQ_TYPE_LINUX_BLOCK
+ *	requests in libata.
+ *
+ *	LOCKING:
+ *	Releases queue lock, and obtains host lock.
+ *
+ *	RETURNS:
+ *	SUCCESS if opcode is known to us, FAILED otherwise.
+ */
+
+int ata_scsi_lb_request_fn(struct request *req)
+{
+	struct request_queue *q = req->q;
+	struct scsi_device *sdev = q->queuedata;
+	struct Scsi_Host *shost = sdev->host;
+	struct ata_port *ap = ata_shost_to_port(shost);
+	struct ata_device *dev;
+	int rc = SUCCESS;
+
+	spin_unlock(q->queue_lock);
+	spin_lock(ap->lock);
+
+	dev = ata_scsi_find_dev(ap, sdev);
+	if (unlikely(!dev)) {
+		req->errors = -ENXIO;
+		goto out;
+	}
+
+	switch (req->cmd[0]) {
+	case REQ_LB_OP_FREEZE:
+		ata_scsi_protect_dev(dev);
+		break;
+
+	case REQ_LB_OP_THAW:
+		ata_scsi_unprotect_dev(dev);
+		break;
+
+	default:
+		rc = FAILED;
+		goto out;
+	}
+
+out:
+	spin_unlock(ap->lock);
+	spin_lock(q->queue_lock);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ata_scsi_lb_request_fn);
+
 int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
 {
 	int i, rc;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5955b57..1854a69 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -164,6 +164,8 @@ enum {
 	 */
 	REQ_LB_OP_EJECT	= 0x40,		/* eject request */
 	REQ_LB_OP_FLUSH = 0x41,		/* flush device */
+	REQ_LB_OP_FREEZE = 0x42,	/* freeze queue (protect device) */
+	REQ_LB_OP_THAW	= 0x3,		/* thaw queue */
 };
 
 /*
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 2db23c3..4e97964 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -809,6 +809,7 @@ extern void ata_host_init(struct ata_host *, struct device *,
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+extern int ata_scsi_lb_request_fn(struct request *req);
 extern void ata_sas_port_destroy(struct ata_port *);
 extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
 					   struct ata_port_info *, struct Scsi_Host *);


--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux