diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-11 21:34:40 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-02-12 15:24:12 -0500 |
commit | f161d4b44d7cc1dc66b53365215227db356378b1 (patch) | |
tree | fc7a5791374458619b4cd7aa8de799927de84617 /drivers/target | |
parent | 3fd7b60f2c7418239d586e359e0c6d8503e10646 (diff) |
target: Fix PR_APTPL_BUF_LEN buffer size limitation
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>
Cc: stable@vger.kernel.org
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_pr.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d56f2aaba9af..67fb3bf240cd 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -1862,8 +1862,8 @@ static int core_scsi3_update_aptpl_buf( | |||
1862 | } | 1862 | } |
1863 | 1863 | ||
1864 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1864 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1865 | pr_err("Unable to update renaming" | 1865 | pr_err("Unable to update renaming APTPL metadata," |
1866 | " APTPL metadata\n"); | 1866 | " reallocating larger buffer\n"); |
1867 | ret = -EMSGSIZE; | 1867 | ret = -EMSGSIZE; |
1868 | goto out; | 1868 | goto out; |
1869 | } | 1869 | } |
@@ -1880,8 +1880,8 @@ static int core_scsi3_update_aptpl_buf( | |||
1880 | lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count); | 1880 | lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count); |
1881 | 1881 | ||
1882 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1882 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1883 | pr_err("Unable to update renaming" | 1883 | pr_err("Unable to update renaming APTPL metadata," |
1884 | " APTPL metadata\n"); | 1884 | " reallocating larger buffer\n"); |
1885 | ret = -EMSGSIZE; | 1885 | ret = -EMSGSIZE; |
1886 | goto out; | 1886 | goto out; |
1887 | } | 1887 | } |
@@ -1944,7 +1944,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
1944 | static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl) | 1944 | static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl) |
1945 | { | 1945 | { |
1946 | unsigned char *buf; | 1946 | unsigned char *buf; |
1947 | int rc; | 1947 | int rc, len = PR_APTPL_BUF_LEN; |
1948 | 1948 | ||
1949 | if (!aptpl) { | 1949 | if (!aptpl) { |
1950 | char *null_buf = "No Registrations or Reservations\n"; | 1950 | char *null_buf = "No Registrations or Reservations\n"; |
@@ -1958,25 +1958,26 @@ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, b | |||
1958 | 1958 | ||
1959 | return 0; | 1959 | return 0; |
1960 | } | 1960 | } |
1961 | 1961 | retry: | |
1962 | buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL); | 1962 | buf = vzalloc(len); |
1963 | if (!buf) | 1963 | if (!buf) |
1964 | return TCM_OUT_OF_RESOURCES; | 1964 | return TCM_OUT_OF_RESOURCES; |
1965 | 1965 | ||
1966 | rc = core_scsi3_update_aptpl_buf(dev, buf, PR_APTPL_BUF_LEN); | 1966 | rc = core_scsi3_update_aptpl_buf(dev, buf, len); |
1967 | if (rc < 0) { | 1967 | if (rc < 0) { |
1968 | kfree(buf); | 1968 | vfree(buf); |
1969 | return TCM_OUT_OF_RESOURCES; | 1969 | len *= 2; |
1970 | goto retry; | ||
1970 | } | 1971 | } |
1971 | 1972 | ||
1972 | rc = __core_scsi3_write_aptpl_to_file(dev, buf); | 1973 | rc = __core_scsi3_write_aptpl_to_file(dev, buf); |
1973 | if (rc != 0) { | 1974 | if (rc != 0) { |
1974 | pr_err("SPC-3 PR: Could not update APTPL\n"); | 1975 | pr_err("SPC-3 PR: Could not update APTPL\n"); |
1975 | kfree(buf); | 1976 | vfree(buf); |
1976 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1977 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1977 | } | 1978 | } |
1978 | dev->t10_pr.pr_aptpl_active = 1; | 1979 | dev->t10_pr.pr_aptpl_active = 1; |
1979 | kfree(buf); | 1980 | vfree(buf); |
1980 | pr_debug("SPC-3 PR: Set APTPL Bit Activated\n"); | 1981 | pr_debug("SPC-3 PR: Set APTPL Bit Activated\n"); |
1981 | return 0; | 1982 | return 0; |
1982 | } | 1983 | } |