diff options
author | Ilias Tsitsimpis <iliastsi@arrikto.com> | 2015-03-26 11:12:42 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-03-26 17:49:51 -0400 |
commit | e673dc920b805f08429e122321f8355cb97c2120 (patch) | |
tree | 872ce8724896451273bc0ae2eb23c66eb9a146b7 /drivers/target | |
parent | 073900bdb4e34109a647c7cb871856a771634460 (diff) |
target: Better handling of AllRegistrants reservations
Fix AllRegistrants reservations in register_and_move() function where
the code didn't handle all of the registered devices as reservation
holders, resulting in the wrong warning message being displayed.
At the same time, introduce a helper function named
'is_reservation_holder()' that properly checks if a device is a
reservation holder, taking into account the reservation type. This
function cleans up the code and improves readability.
Signed-off-by: Ilias Tsitsimpis <iliastsi@arrikto.com>
Signed-off-by: Vangelis Koukis <vkoukis@arrikto.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_pr.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 2de6fb8cee8d..7436fdaaad12 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -78,6 +78,22 @@ enum preempt_type { | |||
78 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, | 78 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, |
79 | struct t10_pr_registration *, int, int); | 79 | struct t10_pr_registration *, int, int); |
80 | 80 | ||
81 | static int is_reservation_holder( | ||
82 | struct t10_pr_registration *pr_res_holder, | ||
83 | struct t10_pr_registration *pr_reg) | ||
84 | { | ||
85 | int pr_res_type; | ||
86 | |||
87 | if (pr_res_holder) { | ||
88 | pr_res_type = pr_res_holder->pr_res_type; | ||
89 | |||
90 | return pr_res_holder == pr_reg || | ||
91 | pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG || | ||
92 | pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG; | ||
93 | } | ||
94 | return 0; | ||
95 | } | ||
96 | |||
81 | static sense_reason_t | 97 | static sense_reason_t |
82 | target_scsi2_reservation_check(struct se_cmd *cmd) | 98 | target_scsi2_reservation_check(struct se_cmd *cmd) |
83 | { | 99 | { |
@@ -2287,7 +2303,6 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) | |||
2287 | spin_lock(&dev->dev_reservation_lock); | 2303 | spin_lock(&dev->dev_reservation_lock); |
2288 | pr_res_holder = dev->dev_pr_res_holder; | 2304 | pr_res_holder = dev->dev_pr_res_holder; |
2289 | if (pr_res_holder) { | 2305 | if (pr_res_holder) { |
2290 | int pr_res_type = pr_res_holder->pr_res_type; | ||
2291 | /* | 2306 | /* |
2292 | * From spc4r17 Section 5.7.9: Reserving: | 2307 | * From spc4r17 Section 5.7.9: Reserving: |
2293 | * | 2308 | * |
@@ -2298,9 +2313,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) | |||
2298 | * the logical unit, then the command shall be completed with | 2313 | * the logical unit, then the command shall be completed with |
2299 | * RESERVATION CONFLICT status. | 2314 | * RESERVATION CONFLICT status. |
2300 | */ | 2315 | */ |
2301 | if ((pr_res_holder != pr_reg) && | 2316 | if (!is_reservation_holder(pr_res_holder, pr_reg)) { |
2302 | (pr_res_type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) && | ||
2303 | (pr_res_type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { | ||
2304 | struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; | 2317 | struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; |
2305 | pr_err("SPC-3 PR: Attempted RESERVE from" | 2318 | pr_err("SPC-3 PR: Attempted RESERVE from" |
2306 | " [%s]: %s while reservation already held by" | 2319 | " [%s]: %s while reservation already held by" |
@@ -2477,7 +2490,6 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, | |||
2477 | struct se_lun *se_lun = cmd->se_lun; | 2490 | struct se_lun *se_lun = cmd->se_lun; |
2478 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; | 2491 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder; |
2479 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2492 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2480 | int all_reg = 0; | ||
2481 | sense_reason_t ret = 0; | 2493 | sense_reason_t ret = 0; |
2482 | 2494 | ||
2483 | if (!se_sess || !se_lun) { | 2495 | if (!se_sess || !se_lun) { |
@@ -2514,13 +2526,9 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, | |||
2514 | spin_unlock(&dev->dev_reservation_lock); | 2526 | spin_unlock(&dev->dev_reservation_lock); |
2515 | goto out_put_pr_reg; | 2527 | goto out_put_pr_reg; |
2516 | } | 2528 | } |
2517 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | ||
2518 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) | ||
2519 | all_reg = 1; | ||
2520 | 2529 | ||
2521 | if ((all_reg == 0) && (pr_res_holder != pr_reg)) { | 2530 | if (!is_reservation_holder(pr_res_holder, pr_reg)) { |
2522 | /* | 2531 | /* |
2523 | * Non 'All Registrants' PR Type cases.. | ||
2524 | * Release request from a registered I_T nexus that is not a | 2532 | * Release request from a registered I_T nexus that is not a |
2525 | * persistent reservation holder. return GOOD status. | 2533 | * persistent reservation holder. return GOOD status. |
2526 | */ | 2534 | */ |
@@ -3375,7 +3383,7 @@ after_iport_check: | |||
3375 | * From spc4r17 section 5.7.8 Table 50 -- | 3383 | * From spc4r17 section 5.7.8 Table 50 -- |
3376 | * Register behaviors for a REGISTER AND MOVE service action | 3384 | * Register behaviors for a REGISTER AND MOVE service action |
3377 | */ | 3385 | */ |
3378 | if (pr_res_holder != pr_reg) { | 3386 | if (!is_reservation_holder(pr_res_holder, pr_reg)) { |
3379 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" | 3387 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" |
3380 | " Nexus is not reservation holder\n"); | 3388 | " Nexus is not reservation holder\n"); |
3381 | spin_unlock(&dev->dev_reservation_lock); | 3389 | spin_unlock(&dev->dev_reservation_lock); |