]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2015 14:31:40 +0000 (15:31 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2015 14:31:40 +0000 (15:31 +0100)
added patches:
target-add-missing-write_same-end-of-device-sanity-check.patch
target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch
target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch
target-fix-r_holder-bit-usage-for-allregistrants.patch

queue-3.19/series
queue-3.19/target-add-missing-write_same-end-of-device-sanity-check.patch [new file with mode: 0644]
queue-3.19/target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch [new file with mode: 0644]
queue-3.19/target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch [new file with mode: 0644]
queue-3.19/target-fix-r_holder-bit-usage-for-allregistrants.patch [new file with mode: 0644]

index e2e7e6d0477fe01ee495a3d5edeb67e89bf62015..1ceeb73b82da3f51a496e9f395df9933c24b36aa 100644 (file)
@@ -52,3 +52,7 @@ drm-i915-drop-vblank-wait-from-intel_dp_link_down.patch
 drm-i915-prevent-use-after-free-in-invalidate_range_start-callback.patch
 drm-i915-correct-the-iosf-dev_fn-field-for-iosf-transfers.patch
 drm-i915-clamp-efficient-frequency-to-valid-range.patch
+target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch
+target-add-missing-write_same-end-of-device-sanity-check.patch
+target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch
+target-fix-r_holder-bit-usage-for-allregistrants.patch
diff --git a/queue-3.19/target-add-missing-write_same-end-of-device-sanity-check.patch b/queue-3.19/target-add-missing-write_same-end-of-device-sanity-check.patch
new file mode 100644 (file)
index 0000000..41b3628
--- /dev/null
@@ -0,0 +1,53 @@
+From 8e575c50a171f2579e367a7f778f86477dfdaf49 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 13 Feb 2015 22:09:47 +0000
+Subject: target: Add missing WRITE_SAME end-of-device sanity check
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 8e575c50a171f2579e367a7f778f86477dfdaf49 upstream.
+
+This patch adds a check to sbc_setup_write_same() to verify
+the incoming WRITE_SAME LBA + number of blocks does not exceed
+past the end-of-device.
+
+Also check for potential LBA wrap-around as well.
+
+Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Cc: Martin Petersen <martin.petersen@oracle.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_sbc.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/target/target_core_sbc.c
++++ b/drivers/target/target_core_sbc.c
+@@ -251,6 +251,8 @@ static inline unsigned long long transpo
+ static sense_reason_t
+ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *ops)
+ {
++      struct se_device *dev = cmd->se_dev;
++      sector_t end_lba = dev->transport->get_blocks(dev) + 1;
+       unsigned int sectors = sbc_get_write_same_sectors(cmd);
+       if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
+@@ -264,6 +266,16 @@ sbc_setup_write_same(struct se_cmd *cmd,
+                       sectors, cmd->se_dev->dev_attrib.max_write_same_len);
+               return TCM_INVALID_CDB_FIELD;
+       }
++      /*
++       * Sanity check for LBA wrap and request past end of device.
++       */
++      if (((cmd->t_task_lba + sectors) < cmd->t_task_lba) ||
++          ((cmd->t_task_lba + sectors) > end_lba)) {
++              pr_err("WRITE_SAME exceeds last lba %llu (lba %llu, sectors %u)\n",
++                     (unsigned long long)end_lba, cmd->t_task_lba, sectors);
++              return TCM_ADDRESS_OUT_OF_RANGE;
++      }
++
+       /* We always have ANC_SUP == 0 so setting ANCHOR is always an error */
+       if (flags[0] & 0x10) {
+               pr_warn("WRITE SAME with ANCHOR not supported\n");
diff --git a/queue-3.19/target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch b/queue-3.19/target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch
new file mode 100644 (file)
index 0000000..89afb9b
--- /dev/null
@@ -0,0 +1,34 @@
+From aa179935edea9a64dec4b757090c8106a3907ffa Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 13 Feb 2015 22:27:40 +0000
+Subject: target: Check for LBA + sectors wrap-around in sbc_parse_cdb
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit aa179935edea9a64dec4b757090c8106a3907ffa upstream.
+
+This patch adds a check to sbc_parse_cdb() in order to detect when
+an LBA + sector vs. end-of-device calculation wraps when the LBA is
+sufficently large enough (eg: 0xFFFFFFFFFFFFFFFF).
+
+Cc: Martin Petersen <martin.petersen@oracle.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_sbc.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/target/target_core_sbc.c
++++ b/drivers/target/target_core_sbc.c
+@@ -967,7 +967,8 @@ sbc_parse_cdb(struct se_cmd *cmd, struct
+               unsigned long long end_lba;
+ check_lba:
+               end_lba = dev->transport->get_blocks(dev) + 1;
+-              if (cmd->t_task_lba + sectors > end_lba) {
++              if (((cmd->t_task_lba + sectors) < cmd->t_task_lba) ||
++                  ((cmd->t_task_lba + sectors) > end_lba)) {
+                       pr_err("cmd exceeds last lba %llu "
+                               "(lba %llu, sectors %u)\n",
+                               end_lba, cmd->t_task_lba, sectors);
diff --git a/queue-3.19/target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch b/queue-3.19/target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch
new file mode 100644 (file)
index 0000000..0ac6ff4
--- /dev/null
@@ -0,0 +1,109 @@
+From f161d4b44d7cc1dc66b53365215227db356378b1 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Wed, 11 Feb 2015 18:34:40 -0800
+Subject: target: Fix PR_APTPL_BUF_LEN buffer size limitation
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit f161d4b44d7cc1dc66b53365215227db356378b1 upstream.
+
+This patch addresses the original PR_APTPL_BUF_LEN = 8k limitiation
+for write-out of PR APTPL metadata that Martin has recently been
+running into.
+
+It changes core_scsi3_update_and_write_aptpl() to use vzalloc'ed
+memory instead of kzalloc, and increases the default hardcoded
+length to 256k.
+
+It also adds logic in core_scsi3_update_and_write_aptpl() to double
+the original length upon core_scsi3_update_aptpl_buf() failure, and
+retries until the vzalloc'ed buffer is large enough to accommodate
+the outgoing APTPL metadata.
+
+Reported-by: Martin Svec <martin.svec@zoner.cz>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_pr.c   |   25 +++++++++++++------------
+ include/target/target_core_base.h |    2 +-
+ 2 files changed, 14 insertions(+), 13 deletions(-)
+
+--- a/drivers/target/target_core_pr.c
++++ b/drivers/target/target_core_pr.c
+@@ -1874,8 +1874,8 @@ static int core_scsi3_update_aptpl_buf(
+               }
+               if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
+-                      pr_err("Unable to update renaming"
+-                              " APTPL metadata\n");
++                      pr_err("Unable to update renaming APTPL metadata,"
++                             " reallocating larger buffer\n");
+                       ret = -EMSGSIZE;
+                       goto out;
+               }
+@@ -1892,8 +1892,8 @@ static int core_scsi3_update_aptpl_buf(
+                       lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
+               if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
+-                      pr_err("Unable to update renaming"
+-                              " APTPL metadata\n");
++                      pr_err("Unable to update renaming APTPL metadata,"
++                             " reallocating larger buffer\n");
+                       ret = -EMSGSIZE;
+                       goto out;
+               }
+@@ -1956,7 +1956,7 @@ static int __core_scsi3_write_aptpl_to_f
+ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl)
+ {
+       unsigned char *buf;
+-      int rc;
++      int rc, len = PR_APTPL_BUF_LEN;
+       if (!aptpl) {
+               char *null_buf = "No Registrations or Reservations\n";
+@@ -1970,25 +1970,26 @@ static sense_reason_t core_scsi3_update_
+               return 0;
+       }
+-
+-      buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL);
++retry:
++      buf = vzalloc(len);
+       if (!buf)
+               return TCM_OUT_OF_RESOURCES;
+-      rc = core_scsi3_update_aptpl_buf(dev, buf, PR_APTPL_BUF_LEN);
++      rc = core_scsi3_update_aptpl_buf(dev, buf, len);
+       if (rc < 0) {
+-              kfree(buf);
+-              return TCM_OUT_OF_RESOURCES;
++              vfree(buf);
++              len *= 2;
++              goto retry;
+       }
+       rc = __core_scsi3_write_aptpl_to_file(dev, buf);
+       if (rc != 0) {
+               pr_err("SPC-3 PR: Could not update APTPL\n");
+-              kfree(buf);
++              vfree(buf);
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       }
+       dev->t10_pr.pr_aptpl_active = 1;
+-      kfree(buf);
++      vfree(buf);
+       pr_debug("SPC-3 PR: Set APTPL Bit Activated\n");
+       return 0;
+ }
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -407,7 +407,7 @@ struct t10_reservation {
+       /* Activate Persistence across Target Power Loss enabled
+        * for SCSI device */
+       int pr_aptpl_active;
+-#define PR_APTPL_BUF_LEN                      8192
++#define PR_APTPL_BUF_LEN                      262144
+       u32 pr_generation;
+       spinlock_t registration_lock;
+       spinlock_t aptpl_reg_lock;
diff --git a/queue-3.19/target-fix-r_holder-bit-usage-for-allregistrants.patch b/queue-3.19/target-fix-r_holder-bit-usage-for-allregistrants.patch
new file mode 100644 (file)
index 0000000..c72bcf0
--- /dev/null
@@ -0,0 +1,80 @@
+From d16ca7c5198fd668db10d2c7b048ed3359c12c54 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Sun, 14 Dec 2014 01:47:19 -0800
+Subject: target: Fix R_HOLDER bit usage for AllRegistrants
+
+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>
+
+diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
+index f91b6a1b846e..c4a8da5415c5 100644
+--- a/drivers/target/target_core_pr.c
++++ b/drivers/target/target_core_pr.c
+@@ -3834,7 +3834,8 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
+       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"
+@@ -3851,6 +3852,19 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
+       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) {
+@@ -3898,14 +3912,20 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
+                * 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 */
+               /*