aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2015-02-13 18:28:27 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2015-02-13 21:09:46 -0500
commitfde9f50f80fe89a9115b4bfa773017272597d85d (patch)
tree8b1a67b39f2e3b64aafd32b95ccd8fb4a96314f4
parentafd73f1b60fc5883ea4982f68e9522e77b28f1e5 (diff)
target: Add sanity checks for DPO/FUA bit usage
This patch adds a sbc_check_dpofua() function that performs sanity checks for DPO/FUA command bits. It introduces checks to fail when either bit is set, but the backend device is not advertising support for them. It also moves the existing cmd->se_cmd_flags |= SCF_FUA assignement into the new helper function. Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_sbc.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 87cbbe220151..856e800926b8 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -692,6 +692,29 @@ sbc_check_prot(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb,
692 return TCM_NO_SENSE; 692 return TCM_NO_SENSE;
693} 693}
694 694
695static int
696sbc_check_dpofua(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb)
697{
698 if (cdb[1] & 0x10) {
699 if (!dev->dev_attrib.emulate_dpo) {
700 pr_err("Got CDB: 0x%02x with DPO bit set, but device"
701 " does not advertise support for DPO\n", cdb[0]);
702 return -EINVAL;
703 }
704 }
705 if (cdb[1] & 0x8) {
706 if (!dev->dev_attrib.emulate_fua_write ||
707 !dev->dev_attrib.emulate_write_cache) {
708 pr_err("Got CDB: 0x%02x with FUA bit set, but device"
709 " does not advertise support for FUA write\n",
710 cdb[0]);
711 return -EINVAL;
712 }
713 cmd->se_cmd_flags |= SCF_FUA;
714 }
715 return 0;
716}
717
695sense_reason_t 718sense_reason_t
696sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) 719sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
697{ 720{
@@ -713,6 +736,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
713 sectors = transport_get_sectors_10(cdb); 736 sectors = transport_get_sectors_10(cdb);
714 cmd->t_task_lba = transport_lba_32(cdb); 737 cmd->t_task_lba = transport_lba_32(cdb);
715 738
739 if (sbc_check_dpofua(dev, cmd, cdb))
740 return TCM_INVALID_CDB_FIELD;
741
716 ret = sbc_check_prot(dev, cmd, cdb, sectors, false); 742 ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
717 if (ret) 743 if (ret)
718 return ret; 744 return ret;
@@ -725,6 +751,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
725 sectors = transport_get_sectors_12(cdb); 751 sectors = transport_get_sectors_12(cdb);
726 cmd->t_task_lba = transport_lba_32(cdb); 752 cmd->t_task_lba = transport_lba_32(cdb);
727 753
754 if (sbc_check_dpofua(dev, cmd, cdb))
755 return TCM_INVALID_CDB_FIELD;
756
728 ret = sbc_check_prot(dev, cmd, cdb, sectors, false); 757 ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
729 if (ret) 758 if (ret)
730 return ret; 759 return ret;
@@ -737,6 +766,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
737 sectors = transport_get_sectors_16(cdb); 766 sectors = transport_get_sectors_16(cdb);
738 cmd->t_task_lba = transport_lba_64(cdb); 767 cmd->t_task_lba = transport_lba_64(cdb);
739 768
769 if (sbc_check_dpofua(dev, cmd, cdb))
770 return TCM_INVALID_CDB_FIELD;
771
740 ret = sbc_check_prot(dev, cmd, cdb, sectors, false); 772 ret = sbc_check_prot(dev, cmd, cdb, sectors, false);
741 if (ret) 773 if (ret)
742 return ret; 774 return ret;
@@ -757,12 +789,13 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
757 sectors = transport_get_sectors_10(cdb); 789 sectors = transport_get_sectors_10(cdb);
758 cmd->t_task_lba = transport_lba_32(cdb); 790 cmd->t_task_lba = transport_lba_32(cdb);
759 791
792 if (sbc_check_dpofua(dev, cmd, cdb))
793 return TCM_INVALID_CDB_FIELD;
794
760 ret = sbc_check_prot(dev, cmd, cdb, sectors, true); 795 ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
761 if (ret) 796 if (ret)
762 return ret; 797 return ret;
763 798
764 if (cdb[1] & 0x8)
765 cmd->se_cmd_flags |= SCF_FUA;
766 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 799 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
767 cmd->execute_rw = ops->execute_rw; 800 cmd->execute_rw = ops->execute_rw;
768 cmd->execute_cmd = sbc_execute_rw; 801 cmd->execute_cmd = sbc_execute_rw;
@@ -771,12 +804,13 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
771 sectors = transport_get_sectors_12(cdb); 804 sectors = transport_get_sectors_12(cdb);
772 cmd->t_task_lba = transport_lba_32(cdb); 805 cmd->t_task_lba = transport_lba_32(cdb);
773 806
807 if (sbc_check_dpofua(dev, cmd, cdb))
808 return TCM_INVALID_CDB_FIELD;
809
774 ret = sbc_check_prot(dev, cmd, cdb, sectors, true); 810 ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
775 if (ret) 811 if (ret)
776 return ret; 812 return ret;
777 813
778 if (cdb[1] & 0x8)
779 cmd->se_cmd_flags |= SCF_FUA;
780 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 814 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
781 cmd->execute_rw = ops->execute_rw; 815 cmd->execute_rw = ops->execute_rw;
782 cmd->execute_cmd = sbc_execute_rw; 816 cmd->execute_cmd = sbc_execute_rw;
@@ -785,12 +819,13 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
785 sectors = transport_get_sectors_16(cdb); 819 sectors = transport_get_sectors_16(cdb);
786 cmd->t_task_lba = transport_lba_64(cdb); 820 cmd->t_task_lba = transport_lba_64(cdb);
787 821
822 if (sbc_check_dpofua(dev, cmd, cdb))
823 return TCM_INVALID_CDB_FIELD;
824
788 ret = sbc_check_prot(dev, cmd, cdb, sectors, true); 825 ret = sbc_check_prot(dev, cmd, cdb, sectors, true);
789 if (ret) 826 if (ret)
790 return ret; 827 return ret;
791 828
792 if (cdb[1] & 0x8)
793 cmd->se_cmd_flags |= SCF_FUA;
794 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 829 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
795 cmd->execute_rw = ops->execute_rw; 830 cmd->execute_rw = ops->execute_rw;
796 cmd->execute_cmd = sbc_execute_rw; 831 cmd->execute_cmd = sbc_execute_rw;
@@ -801,6 +836,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
801 return TCM_INVALID_CDB_FIELD; 836 return TCM_INVALID_CDB_FIELD;
802 sectors = transport_get_sectors_10(cdb); 837 sectors = transport_get_sectors_10(cdb);
803 838
839 if (sbc_check_dpofua(dev, cmd, cdb))
840 return TCM_INVALID_CDB_FIELD;
841
804 cmd->t_task_lba = transport_lba_32(cdb); 842 cmd->t_task_lba = transport_lba_32(cdb);
805 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; 843 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
806 844
@@ -810,8 +848,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
810 cmd->execute_rw = ops->execute_rw; 848 cmd->execute_rw = ops->execute_rw;
811 cmd->execute_cmd = sbc_execute_rw; 849 cmd->execute_cmd = sbc_execute_rw;
812 cmd->transport_complete_callback = &xdreadwrite_callback; 850 cmd->transport_complete_callback = &xdreadwrite_callback;
813 if (cdb[1] & 0x8)
814 cmd->se_cmd_flags |= SCF_FUA;
815 break; 851 break;
816 case VARIABLE_LENGTH_CMD: 852 case VARIABLE_LENGTH_CMD:
817 { 853 {
@@ -820,6 +856,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
820 case XDWRITEREAD_32: 856 case XDWRITEREAD_32:
821 sectors = transport_get_sectors_32(cdb); 857 sectors = transport_get_sectors_32(cdb);
822 858
859 if (sbc_check_dpofua(dev, cmd, cdb))
860 return TCM_INVALID_CDB_FIELD;
823 /* 861 /*
824 * Use WRITE_32 and READ_32 opcodes for the emulated 862 * Use WRITE_32 and READ_32 opcodes for the emulated
825 * XDWRITE_READ_32 logic. 863 * XDWRITE_READ_32 logic.
@@ -834,8 +872,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
834 cmd->execute_rw = ops->execute_rw; 872 cmd->execute_rw = ops->execute_rw;
835 cmd->execute_cmd = sbc_execute_rw; 873 cmd->execute_cmd = sbc_execute_rw;
836 cmd->transport_complete_callback = &xdreadwrite_callback; 874 cmd->transport_complete_callback = &xdreadwrite_callback;
837 if (cdb[1] & 0x8)
838 cmd->se_cmd_flags |= SCF_FUA;
839 break; 875 break;
840 case WRITE_SAME_32: 876 case WRITE_SAME_32:
841 sectors = transport_get_sectors_32(cdb); 877 sectors = transport_get_sectors_32(cdb);