lkml.org 
[lkml]   [2015]   [Mar]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.10 53/55] target: Fix R_HOLDER bit usage for AllRegistrants
    Date
    3.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Nicholas Bellinger <nab@linux-iscsi.org>

    commit d16ca7c5198fd668db10d2c7b048ed3359c12c54 upstream.

    This patch fixes the usage of R_HOLDER bit for an All Registrants
    reservation in READ_FULL_STATUS, where only the registration who
    issued RESERVE was being reported as having an active reservation.

    It changes core_scsi3_pri_read_full_status() to check ahead of the
    list walk of active registrations to see if All Registrants is active,
    and if so set R_HOLDER bit and scope/type fields for all active
    registrations.

    Reported-by: Ilias Tsitsimpis <i.tsitsimpis@gmail.com>
    Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
    Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/target/target_core_pr.c | 26 +++++++++++++++++++++++---
    1 file changed, 23 insertions(+), 3 deletions(-)

    --- a/drivers/target/target_core_pr.c
    +++ b/drivers/target/target_core_pr.c
    @@ -4012,7 +4012,8 @@ core_scsi3_pri_read_full_status(struct s
    unsigned char *buf;
    u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
    u32 off = 8; /* off into first Full Status descriptor */
    - int format_code = 0;
    + int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
    + bool all_reg = false;

    if (cmd->data_length < 8) {
    pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
    @@ -4029,6 +4030,19 @@ core_scsi3_pri_read_full_status(struct s
    buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
    buf[3] = (dev->t10_pr.pr_generation & 0xff);

    + spin_lock(&dev->dev_reservation_lock);
    + if (dev->dev_pr_res_holder) {
    + struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder;
    +
    + if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG ||
    + pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) {
    + all_reg = true;
    + pr_res_type = pr_holder->pr_res_type;
    + pr_res_scope = pr_holder->pr_res_scope;
    + }
    + }
    + spin_unlock(&dev->dev_reservation_lock);
    +
    spin_lock(&pr_tmpl->registration_lock);
    list_for_each_entry_safe(pr_reg, pr_reg_tmp,
    &pr_tmpl->registration_list, pr_reg_list) {
    @@ -4078,14 +4092,20 @@ core_scsi3_pri_read_full_status(struct s
    * reservation holder for PR_HOLDER bit.
    *
    * Also, if this registration is the reservation
    - * holder, fill in SCOPE and TYPE in the next byte.
    + * holder or there is an All Registrants reservation
    + * active, fill in SCOPE and TYPE in the next byte.
    */
    if (pr_reg->pr_res_holder) {
    buf[off++] |= 0x01;
    buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
    (pr_reg->pr_res_type & 0x0f);
    - } else
    + } else if (all_reg) {
    + buf[off++] |= 0x01;
    + buf[off++] = (pr_res_scope & 0xf0) |
    + (pr_res_type & 0x0f);
    + } else {
    off += 2;
    + }

    off += 4; /* Skip over reserved area */
    /*



    \
     
     \ /
      Last update: 2015-03-24 17:01    [W:4.170 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site