diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0040-target-Fix-compatible-reservation-handling-CRH-1-wit.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0040-target-Fix-compatible-reservation-handling-CRH-1-wit.patch | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0040-target-Fix-compatible-reservation-handling-CRH-1-wit.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0040-target-Fix-compatible-reservation-handling-CRH-1-wit.patch new file mode 100644 index 00000000..1673697d --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.12/0040-target-Fix-compatible-reservation-handling-CRH-1-wit.patch | |||
@@ -0,0 +1,152 @@ | |||
1 | From 16add6db674e266a62219145284435960e47435e Mon Sep 17 00:00:00 2001 | ||
2 | From: Nicholas Bellinger <nab@linux-iscsi.org> | ||
3 | Date: Tue, 13 Mar 2012 21:29:06 -0700 | ||
4 | Subject: [PATCH 40/42] target: Fix compatible reservation handling (CRH=1) | ||
5 | with legacy RESERVE/RELEASE | ||
6 | |||
7 | commit 087a03b3ea1c8d6e2d5743a8d1c6d571058caa04 upstream. | ||
8 | |||
9 | This patch addresses a bug with target_check_scsi2_reservation_conflict() | ||
10 | return checking in target_scsi2_reservation_[reserve,release]() that was | ||
11 | preventing CRH=1 operation from silently succeeding in the two special | ||
12 | cases defined by SPC-3, and not failing with reservation conflict status | ||
13 | when dealing with legacy RESERVE/RELEASE + active SPC-3 PR logic. | ||
14 | |||
15 | Also explictly set cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT during | ||
16 | the early non reservation holder failure from pr_ops->t10_seq_non_holder() | ||
17 | check in transport_generic_cmd_sequencer() for fabrics that already expect | ||
18 | it to be set. | ||
19 | |||
20 | This bug was originally introduced in mainline commit: | ||
21 | |||
22 | commit eacac00ce5bfde8086cd0615fb53c986f7f970fe | ||
23 | Author: Christoph Hellwig <hch@infradead.org> | ||
24 | Date: Thu Nov 3 17:50:40 2011 -0400 | ||
25 | |||
26 | target: split core_scsi2_emulate_crh | ||
27 | |||
28 | Reported-by: Martin Svec <martin.svec@zoner.cz> | ||
29 | Cc: Martin Svec <martin.svec@zoner.cz> | ||
30 | Cc: Christoph Hellwig <hch@lst.de> | ||
31 | Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> | ||
32 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
33 | --- | ||
34 | drivers/target/target_core_pr.c | 34 +++++++++++++++++++++----------- | ||
35 | drivers/target/target_core_transport.c | 1 + | ||
36 | 2 files changed, 23 insertions(+), 12 deletions(-) | ||
37 | |||
38 | diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c | ||
39 | index 778c1a6..6cf6ff4 100644 | ||
40 | --- a/drivers/target/target_core_pr.c | ||
41 | +++ b/drivers/target/target_core_pr.c | ||
42 | @@ -120,7 +120,7 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, | ||
43 | struct se_node_acl *, struct se_session *); | ||
44 | static void core_scsi3_put_pr_reg(struct t10_pr_registration *); | ||
45 | |||
46 | -static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | ||
47 | +static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | ||
48 | { | ||
49 | struct se_session *se_sess = cmd->se_sess; | ||
50 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | ||
51 | @@ -130,7 +130,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | ||
52 | int conflict = 0; | ||
53 | |||
54 | if (!crh) | ||
55 | - return false; | ||
56 | + return -EINVAL; | ||
57 | |||
58 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | ||
59 | se_sess); | ||
60 | @@ -158,16 +158,14 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | ||
61 | */ | ||
62 | if (pr_reg->pr_res_holder) { | ||
63 | core_scsi3_put_pr_reg(pr_reg); | ||
64 | - *ret = 0; | ||
65 | - return false; | ||
66 | + return 1; | ||
67 | } | ||
68 | if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || | ||
69 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || | ||
70 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | ||
71 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { | ||
72 | core_scsi3_put_pr_reg(pr_reg); | ||
73 | - *ret = 0; | ||
74 | - return true; | ||
75 | + return 1; | ||
76 | } | ||
77 | core_scsi3_put_pr_reg(pr_reg); | ||
78 | conflict = 1; | ||
79 | @@ -192,10 +190,10 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | ||
80 | " while active SPC-3 registrations exist," | ||
81 | " returning RESERVATION_CONFLICT\n"); | ||
82 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
83 | - return true; | ||
84 | + return -EBUSY; | ||
85 | } | ||
86 | |||
87 | - return false; | ||
88 | + return 0; | ||
89 | } | ||
90 | |||
91 | int target_scsi2_reservation_release(struct se_task *task) | ||
92 | @@ -204,12 +202,18 @@ int target_scsi2_reservation_release(struct se_task *task) | ||
93 | struct se_device *dev = cmd->se_dev; | ||
94 | struct se_session *sess = cmd->se_sess; | ||
95 | struct se_portal_group *tpg = sess->se_tpg; | ||
96 | - int ret = 0; | ||
97 | + int ret = 0, rc; | ||
98 | |||
99 | if (!sess || !tpg) | ||
100 | goto out; | ||
101 | - if (target_check_scsi2_reservation_conflict(cmd, &ret)) | ||
102 | + rc = target_check_scsi2_reservation_conflict(cmd); | ||
103 | + if (rc == 1) | ||
104 | + goto out; | ||
105 | + else if (rc < 0) { | ||
106 | + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
107 | + ret = -EINVAL; | ||
108 | goto out; | ||
109 | + } | ||
110 | |||
111 | ret = 0; | ||
112 | spin_lock(&dev->dev_reservation_lock); | ||
113 | @@ -246,7 +250,7 @@ int target_scsi2_reservation_reserve(struct se_task *task) | ||
114 | struct se_device *dev = cmd->se_dev; | ||
115 | struct se_session *sess = cmd->se_sess; | ||
116 | struct se_portal_group *tpg = sess->se_tpg; | ||
117 | - int ret = 0; | ||
118 | + int ret = 0, rc; | ||
119 | |||
120 | if ((cmd->t_task_cdb[1] & 0x01) && | ||
121 | (cmd->t_task_cdb[1] & 0x02)) { | ||
122 | @@ -262,8 +266,14 @@ int target_scsi2_reservation_reserve(struct se_task *task) | ||
123 | */ | ||
124 | if (!sess || !tpg) | ||
125 | goto out; | ||
126 | - if (target_check_scsi2_reservation_conflict(cmd, &ret)) | ||
127 | + rc = target_check_scsi2_reservation_conflict(cmd); | ||
128 | + if (rc == 1) | ||
129 | goto out; | ||
130 | + else if (rc < 0) { | ||
131 | + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
132 | + ret = -EINVAL; | ||
133 | + goto out; | ||
134 | + } | ||
135 | |||
136 | ret = 0; | ||
137 | spin_lock(&dev->dev_reservation_lock); | ||
138 | diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c | ||
139 | index e4ddb93..cdb774b 100644 | ||
140 | --- a/drivers/target/target_core_transport.c | ||
141 | +++ b/drivers/target/target_core_transport.c | ||
142 | @@ -2507,6 +2507,7 @@ static int transport_generic_cmd_sequencer( | ||
143 | cmd, cdb, pr_reg_type) != 0) { | ||
144 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
145 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
146 | + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
147 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
148 | return -EBUSY; | ||
149 | } | ||
150 | -- | ||
151 | 1.7.9.4 | ||
152 | |||