|
|
958e1b |
From 9e46b4be497106cff27fd67c5c3cc79023e21762 Mon Sep 17 00:00:00 2001
|
|
|
240766 |
From: Fam Zheng <famz@redhat.com>
|
|
|
240766 |
Date: Fri, 4 Apr 2014 05:55:57 +0200
|
|
|
240766 |
Subject: [PATCH 02/12] iscsi: correctly propagate errors in iscsi_open
|
|
|
240766 |
|
|
|
240766 |
RH-Author: Fam Zheng <famz@redhat.com>
|
|
|
240766 |
Message-id: <1396590962-25815-3-git-send-email-famz@redhat.com>
|
|
|
240766 |
Patchwork-id: 58339
|
|
|
240766 |
O-Subject: [RHEL-7 0day qemu-kvm PATCH 2/7] iscsi: correctly propagate errors in iscsi_open
|
|
|
958e1b |
Bugzilla: 1083413
|
|
|
240766 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
240766 |
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
|
|
240766 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
240766 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
240766 |
|
|
|
240766 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
240766 |
|
|
|
240766 |
Before:
|
|
|
240766 |
$ ./qemu-io-old
|
|
|
240766 |
qemu-io-old> open -r -o file.driver=iscsi,file.filename=foo
|
|
|
240766 |
Failed to parse URL : foo
|
|
|
240766 |
qemu-io-old: can't open device (null): Could not open 'foo': Invalid argument
|
|
|
240766 |
|
|
|
240766 |
After:
|
|
|
240766 |
$ ./qemu-io
|
|
|
240766 |
qemu-io> open -r -o file.driver=iscsi,file.filename=foo
|
|
|
240766 |
qemu-io: can't open device (null): Failed to parse URL : foo
|
|
|
240766 |
|
|
|
240766 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
240766 |
Reviewed-by: Fam Zheng <famz@redhat.com>
|
|
|
240766 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
240766 |
(cherry picked from commit f2917853f715b0ef55df29eb2ffea29dc69ce814)
|
|
|
240766 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
240766 |
|
|
|
240766 |
Conflicts:
|
|
|
240766 |
block/iscsi.c
|
|
|
240766 |
Because 84d18f065fb041a1c0d78d20320d740ae0673c8a (Use
|
|
|
240766 |
error_is_set() only when necessary) is not backpored, which
|
|
|
240766 |
converted "if (error_is_set(&local_err))" to "if (local_err)".
|
|
|
240766 |
|
|
|
240766 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
240766 |
---
|
|
|
240766 |
block/iscsi.c | 105 ++++++++++++++++++++++++++++++----------------------------
|
|
|
240766 |
1 file changed, 54 insertions(+), 51 deletions(-)
|
|
|
240766 |
|
|
|
240766 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
240766 |
---
|
|
|
240766 |
block/iscsi.c | 105 +++++++++++++++++++++++++++++---------------------------
|
|
|
240766 |
1 files changed, 54 insertions(+), 51 deletions(-)
|
|
|
240766 |
|
|
|
240766 |
diff --git a/block/iscsi.c b/block/iscsi.c
|
|
|
240766 |
index 082956c..537d2cb 100644
|
|
|
240766 |
--- a/block/iscsi.c
|
|
|
240766 |
+++ b/block/iscsi.c
|
|
|
240766 |
@@ -1036,7 +1036,8 @@ retry:
|
|
|
240766 |
|
|
|
240766 |
#endif /* SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED */
|
|
|
240766 |
|
|
|
240766 |
-static int parse_chap(struct iscsi_context *iscsi, const char *target)
|
|
|
240766 |
+static void parse_chap(struct iscsi_context *iscsi, const char *target,
|
|
|
240766 |
+ Error **errp)
|
|
|
240766 |
{
|
|
|
240766 |
QemuOptsList *list;
|
|
|
240766 |
QemuOpts *opts;
|
|
|
240766 |
@@ -1045,37 +1046,35 @@ static int parse_chap(struct iscsi_context *iscsi, const char *target)
|
|
|
240766 |
|
|
|
240766 |
list = qemu_find_opts("iscsi");
|
|
|
240766 |
if (!list) {
|
|
|
240766 |
- return 0;
|
|
|
240766 |
+ return;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
opts = qemu_opts_find(list, target);
|
|
|
240766 |
if (opts == NULL) {
|
|
|
240766 |
opts = QTAILQ_FIRST(&list->head);
|
|
|
240766 |
if (!opts) {
|
|
|
240766 |
- return 0;
|
|
|
240766 |
+ return;
|
|
|
240766 |
}
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
user = qemu_opt_get(opts, "user");
|
|
|
240766 |
if (!user) {
|
|
|
240766 |
- return 0;
|
|
|
240766 |
+ return;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
password = qemu_opt_get(opts, "password");
|
|
|
240766 |
if (!password) {
|
|
|
240766 |
- error_report("CHAP username specified but no password was given");
|
|
|
240766 |
- return -1;
|
|
|
240766 |
+ error_setg(errp, "CHAP username specified but no password was given");
|
|
|
240766 |
+ return;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
|
|
|
240766 |
- error_report("Failed to set initiator username and password");
|
|
|
240766 |
- return -1;
|
|
|
240766 |
+ error_setg(errp, "Failed to set initiator username and password");
|
|
|
240766 |
}
|
|
|
240766 |
-
|
|
|
240766 |
- return 0;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
-static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
|
|
|
240766 |
+static void parse_header_digest(struct iscsi_context *iscsi, const char *target,
|
|
|
240766 |
+ Error **errp)
|
|
|
240766 |
{
|
|
|
240766 |
QemuOptsList *list;
|
|
|
240766 |
QemuOpts *opts;
|
|
|
240766 |
@@ -1108,7 +1107,7 @@ static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
|
|
|
240766 |
} else if (!strcmp(digest, "NONE-CRC32C")) {
|
|
|
240766 |
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
|
|
|
240766 |
} else {
|
|
|
240766 |
- error_report("Invalid header-digest setting : %s", digest);
|
|
|
240766 |
+ error_setg(errp, "Invalid header-digest setting : %s", digest);
|
|
|
240766 |
}
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
@@ -1166,12 +1165,11 @@ static void iscsi_nop_timed_event(void *opaque)
|
|
|
240766 |
}
|
|
|
240766 |
#endif
|
|
|
240766 |
|
|
|
240766 |
-static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
|
|
|
240766 |
+static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
|
|
|
240766 |
{
|
|
|
240766 |
struct scsi_task *task = NULL;
|
|
|
240766 |
struct scsi_readcapacity10 *rc10 = NULL;
|
|
|
240766 |
struct scsi_readcapacity16 *rc16 = NULL;
|
|
|
240766 |
- int ret = 0;
|
|
|
240766 |
int retries = ISCSI_CMD_RETRIES;
|
|
|
240766 |
|
|
|
240766 |
do {
|
|
|
240766 |
@@ -1186,8 +1184,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
|
|
|
240766 |
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
|
|
|
240766 |
rc16 = scsi_datain_unmarshall(task);
|
|
|
240766 |
if (rc16 == NULL) {
|
|
|
240766 |
- error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
|
|
|
240766 |
- ret = -EINVAL;
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to unmarshall readcapacity16 data.");
|
|
|
240766 |
} else {
|
|
|
240766 |
iscsilun->block_size = rc16->block_length;
|
|
|
240766 |
iscsilun->num_blocks = rc16->returned_lba + 1;
|
|
|
240766 |
@@ -1201,8 +1198,7 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
|
|
|
240766 |
if (task != NULL && task->status == SCSI_STATUS_GOOD) {
|
|
|
240766 |
rc10 = scsi_datain_unmarshall(task);
|
|
|
240766 |
if (rc10 == NULL) {
|
|
|
240766 |
- error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
|
|
|
240766 |
- ret = -EINVAL;
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to unmarshall readcapacity10 data.");
|
|
|
240766 |
} else {
|
|
|
240766 |
iscsilun->block_size = rc10->block_size;
|
|
|
240766 |
if (rc10->lba == 0) {
|
|
|
240766 |
@@ -1215,20 +1211,18 @@ static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
|
|
|
240766 |
}
|
|
|
240766 |
break;
|
|
|
240766 |
default:
|
|
|
240766 |
- return 0;
|
|
|
240766 |
+ return;
|
|
|
240766 |
}
|
|
|
240766 |
} while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
|
|
|
240766 |
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION
|
|
|
240766 |
&& retries-- > 0);
|
|
|
240766 |
|
|
|
240766 |
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
|
|
240766 |
- error_report("iSCSI: failed to send readcapacity10 command.");
|
|
|
240766 |
- ret = -EINVAL;
|
|
|
240766 |
+ error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
|
|
|
240766 |
}
|
|
|
240766 |
if (task) {
|
|
|
240766 |
scsi_free_scsi_task(task);
|
|
|
240766 |
}
|
|
|
240766 |
- return ret;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
/* TODO Convert to fine grained options */
|
|
|
240766 |
@@ -1246,7 +1240,7 @@ static QemuOptsList runtime_opts = {
|
|
|
240766 |
};
|
|
|
240766 |
|
|
|
240766 |
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
|
|
|
240766 |
- int evpd, int pc)
|
|
|
240766 |
+ int evpd, int pc, Error **errp)
|
|
|
240766 |
{
|
|
|
240766 |
int full_size;
|
|
|
240766 |
struct scsi_task *task = NULL;
|
|
|
240766 |
@@ -1268,8 +1262,8 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
|
|
|
240766 |
return task;
|
|
|
240766 |
|
|
|
240766 |
fail:
|
|
|
240766 |
- error_report("iSCSI: Inquiry command failed : %s",
|
|
|
240766 |
- iscsi_get_error(iscsi));
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Inquiry command failed : %s",
|
|
|
240766 |
+ iscsi_get_error(iscsi));
|
|
|
240766 |
if (task) {
|
|
|
240766 |
scsi_free_scsi_task(task);
|
|
|
240766 |
return NULL;
|
|
|
240766 |
@@ -1296,27 +1290,25 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
int ret;
|
|
|
240766 |
|
|
|
240766 |
if ((BDRV_SECTOR_SIZE % 512) != 0) {
|
|
|
240766 |
- error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
|
|
|
240766 |
- "BDRV_SECTOR_SIZE(%lld) is not a multiple "
|
|
|
240766 |
- "of 512", BDRV_SECTOR_SIZE);
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
|
|
|
240766 |
+ "BDRV_SECTOR_SIZE(%lld) is not a multiple "
|
|
|
240766 |
+ "of 512", BDRV_SECTOR_SIZE);
|
|
|
240766 |
return -EINVAL;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
opts = qemu_opts_create_nofail(&runtime_opts);
|
|
|
240766 |
qemu_opts_absorb_qdict(opts, options, &local_err);
|
|
|
240766 |
- if (error_is_set(&local_err)) {
|
|
|
240766 |
- qerror_report_err(local_err);
|
|
|
240766 |
- error_free(local_err);
|
|
|
240766 |
+ if (local_err) {
|
|
|
240766 |
+ error_propagate(errp, local_err);
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
filename = qemu_opt_get(opts, "filename");
|
|
|
240766 |
|
|
|
240766 |
-
|
|
|
240766 |
iscsi_url = iscsi_parse_full_url(iscsi, filename);
|
|
|
240766 |
if (iscsi_url == NULL) {
|
|
|
240766 |
- error_report("Failed to parse URL : %s", filename);
|
|
|
240766 |
+ error_setg(errp, "Failed to parse URL : %s", filename);
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1327,13 +1319,13 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
|
|
|
240766 |
iscsi = iscsi_create_context(initiator_name);
|
|
|
240766 |
if (iscsi == NULL) {
|
|
|
240766 |
- error_report("iSCSI: Failed to create iSCSI context.");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to create iSCSI context.");
|
|
|
240766 |
ret = -ENOMEM;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
|
|
|
240766 |
- error_report("iSCSI: Failed to set target name.");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to set target name.");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1342,21 +1334,22 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
|
|
|
240766 |
iscsi_url->passwd);
|
|
|
240766 |
if (ret != 0) {
|
|
|
240766 |
- error_report("Failed to set initiator username and password");
|
|
|
240766 |
+ error_setg(errp, "Failed to set initiator username and password");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
/* check if we got CHAP username/password via the options */
|
|
|
240766 |
- if (parse_chap(iscsi, iscsi_url->target) != 0) {
|
|
|
240766 |
- error_report("iSCSI: Failed to set CHAP user/password");
|
|
|
240766 |
+ parse_chap(iscsi, iscsi_url->target, &local_err);
|
|
|
240766 |
+ if (local_err != NULL) {
|
|
|
240766 |
+ error_propagate(errp, local_err);
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
|
|
|
240766 |
- error_report("iSCSI: Failed to set session type to normal.");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to set session type to normal.");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1364,10 +1357,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
|
|
|
240766 |
|
|
|
240766 |
/* check if we got HEADER_DIGEST via the options */
|
|
|
240766 |
- parse_header_digest(iscsi, iscsi_url->target);
|
|
|
240766 |
+ parse_header_digest(iscsi, iscsi_url->target, &local_err);
|
|
|
240766 |
+ if (local_err != NULL) {
|
|
|
240766 |
+ error_propagate(errp, local_err);
|
|
|
240766 |
+ ret = -EINVAL;
|
|
|
240766 |
+ goto out;
|
|
|
240766 |
+ }
|
|
|
240766 |
|
|
|
240766 |
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
|
|
|
240766 |
- error_report("iSCSI: Failed to connect to LUN : %s",
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
|
|
|
240766 |
iscsi_get_error(iscsi));
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
@@ -1379,14 +1377,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
|
|
|
240766 |
|
|
|
240766 |
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
|
|
240766 |
- error_report("iSCSI: failed to send inquiry command.");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: failed to send inquiry command.");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
inq = scsi_datain_unmarshall(task);
|
|
|
240766 |
if (inq == NULL) {
|
|
|
240766 |
- error_report("iSCSI: Failed to unmarshall inquiry data.");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: Failed to unmarshall inquiry data.");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1394,7 +1392,9 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
iscsilun->type = inq->periperal_device_type;
|
|
|
240766 |
iscsilun->has_write_same = true;
|
|
|
240766 |
|
|
|
240766 |
- if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
|
|
|
240766 |
+ iscsi_readcapacity_sync(iscsilun, &local_err);
|
|
|
240766 |
+ if (local_err != NULL) {
|
|
|
240766 |
+ error_propagate(errp, local_err);
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
|
|
|
240766 |
@@ -1411,14 +1411,15 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
if (iscsilun->lbpme) {
|
|
|
240766 |
struct scsi_inquiry_logical_block_provisioning *inq_lbp;
|
|
|
240766 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
|
|
240766 |
- SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING);
|
|
|
240766 |
+ SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
|
|
|
240766 |
+ errp);
|
|
|
240766 |
if (task == NULL) {
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
inq_lbp = scsi_datain_unmarshall(task);
|
|
|
240766 |
if (inq_lbp == NULL) {
|
|
|
240766 |
- error_report("iSCSI: failed to unmarshall inquiry datain blob");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1431,14 +1432,14 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
240766 |
if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
|
|
|
240766 |
struct scsi_inquiry_block_limits *inq_bl;
|
|
|
240766 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
|
|
240766 |
- SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS);
|
|
|
240766 |
+ SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp);
|
|
|
240766 |
if (task == NULL) {
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
inq_bl = scsi_datain_unmarshall(task);
|
|
|
240766 |
if (inq_bl == NULL) {
|
|
|
240766 |
- error_report("iSCSI: failed to unmarshall inquiry datain blob");
|
|
|
240766 |
+ error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
|
|
|
240766 |
ret = -EINVAL;
|
|
|
240766 |
goto out;
|
|
|
240766 |
}
|
|
|
240766 |
@@ -1529,14 +1530,16 @@ static int iscsi_reopen_prepare(BDRVReopenState *state,
|
|
|
240766 |
static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
|
|
|
240766 |
{
|
|
|
240766 |
IscsiLun *iscsilun = bs->opaque;
|
|
|
240766 |
- int ret = 0;
|
|
|
240766 |
+ Error *local_err = NULL;
|
|
|
240766 |
|
|
|
240766 |
if (iscsilun->type != TYPE_DISK) {
|
|
|
240766 |
return -ENOTSUP;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
- if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
|
|
|
240766 |
- return ret;
|
|
|
240766 |
+ iscsi_readcapacity_sync(iscsilun, &local_err);
|
|
|
240766 |
+ if (local_err != NULL) {
|
|
|
240766 |
+ error_free(local_err);
|
|
|
240766 |
+ return -EIO;
|
|
|
240766 |
}
|
|
|
240766 |
|
|
|
240766 |
if (offset > iscsi_getlength(bs)) {
|
|
|
240766 |
--
|
|
|
240766 |
1.7.1
|
|
|
240766 |
|