Skip to content

Commit

Permalink
[SCSI] libiscsi: handle param allocation failures
Browse files Browse the repository at this point in the history
If we could not allocate the initiator name or some other id like
the hwaddress or netdev, then userspace could deal with the failure
by just running in a dregraded mode.

Now we want to be able to switch values for the params and we
want some feedback, so this patch will check if a string like
the initiatorname could not be allocated and return an error.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed May 23, 2009
1 parent 184b57c commit 5700b1a
Showing 1 changed file with 33 additions and 75 deletions.
108 changes: 33 additions & 75 deletions drivers/scsi/libiscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2656,6 +2656,23 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
}
EXPORT_SYMBOL_GPL(iscsi_conn_bind);

static int iscsi_switch_str_param(char **param, char *new_val_buf)
{
char *new_val;

if (*param) {
if (!strcmp(*param, new_val_buf))
return 0;
}

new_val = kstrdup(new_val_buf, GFP_NOIO);
if (!new_val)
return -ENOMEM;

kfree(*param);
*param = new_val;
return 0;
}

int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen)
Expand Down Expand Up @@ -2728,64 +2745,27 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
sscanf(buf, "%u", &conn->exp_statsn);
break;
case ISCSI_PARAM_USERNAME:
kfree(session->username);
session->username = kstrdup(buf, GFP_KERNEL);
if (!session->username)
return -ENOMEM;
break;
return iscsi_switch_str_param(&session->username, buf);
case ISCSI_PARAM_USERNAME_IN:
kfree(session->username_in);
session->username_in = kstrdup(buf, GFP_KERNEL);
if (!session->username_in)
return -ENOMEM;
break;
return iscsi_switch_str_param(&session->username_in, buf);
case ISCSI_PARAM_PASSWORD:
kfree(session->password);
session->password = kstrdup(buf, GFP_KERNEL);
if (!session->password)
return -ENOMEM;
break;
return iscsi_switch_str_param(&session->password, buf);
case ISCSI_PARAM_PASSWORD_IN:
kfree(session->password_in);
session->password_in = kstrdup(buf, GFP_KERNEL);
if (!session->password_in)
return -ENOMEM;
break;
return iscsi_switch_str_param(&session->password_in, buf);
case ISCSI_PARAM_TARGET_NAME:
/* this should not change between logins */
if (session->targetname)
break;

session->targetname = kstrdup(buf, GFP_KERNEL);
if (!session->targetname)
return -ENOMEM;
break;
return iscsi_switch_str_param(&session->targetname, buf);
case ISCSI_PARAM_TPGT:
sscanf(buf, "%d", &session->tpgt);
break;
case ISCSI_PARAM_PERSISTENT_PORT:
sscanf(buf, "%d", &conn->persistent_port);
break;
case ISCSI_PARAM_PERSISTENT_ADDRESS:
/*
* this is the address returned in discovery so it should
* not change between logins.
*/
if (conn->persistent_address)
break;

conn->persistent_address = kstrdup(buf, GFP_KERNEL);
if (!conn->persistent_address)
return -ENOMEM;
break;
return iscsi_switch_str_param(&conn->persistent_address, buf);
case ISCSI_PARAM_IFACE_NAME:
if (!session->ifacename)
session->ifacename = kstrdup(buf, GFP_KERNEL);
break;
return iscsi_switch_str_param(&session->ifacename, buf);
case ISCSI_PARAM_INITIATOR_NAME:
if (!session->initiatorname)
session->initiatorname = kstrdup(buf, GFP_KERNEL);
break;
return iscsi_switch_str_param(&session->initiatorname, buf);
default:
return -ENOSYS;
}
Expand Down Expand Up @@ -2856,10 +2836,7 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
len = sprintf(buf, "%s\n", session->ifacename);
break;
case ISCSI_PARAM_INITIATOR_NAME:
if (!session->initiatorname)
len = sprintf(buf, "%s\n", "unknown");
else
len = sprintf(buf, "%s\n", session->initiatorname);
len = sprintf(buf, "%s\n", session->initiatorname);
break;
default:
return -ENOSYS;
Expand Down Expand Up @@ -2925,29 +2902,16 @@ int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,

switch (param) {
case ISCSI_HOST_PARAM_NETDEV_NAME:
if (!ihost->netdev)
len = sprintf(buf, "%s\n", "default");
else
len = sprintf(buf, "%s\n", ihost->netdev);
len = sprintf(buf, "%s\n", ihost->netdev);
break;
case ISCSI_HOST_PARAM_HWADDRESS:
if (!ihost->hwaddress)
len = sprintf(buf, "%s\n", "default");
else
len = sprintf(buf, "%s\n", ihost->hwaddress);
len = sprintf(buf, "%s\n", ihost->hwaddress);
break;
case ISCSI_HOST_PARAM_INITIATOR_NAME:
if (!ihost->initiatorname)
len = sprintf(buf, "%s\n", "unknown");
else
len = sprintf(buf, "%s\n", ihost->initiatorname);
len = sprintf(buf, "%s\n", ihost->initiatorname);
break;
case ISCSI_HOST_PARAM_IPADDRESS:
if (!strlen(ihost->local_address))
len = sprintf(buf, "%s\n", "unknown");
else
len = sprintf(buf, "%s\n",
ihost->local_address);
len = sprintf(buf, "%s\n", ihost->local_address);
break;
default:
return -ENOSYS;
Expand All @@ -2964,17 +2928,11 @@ int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,

switch (param) {
case ISCSI_HOST_PARAM_NETDEV_NAME:
if (!ihost->netdev)
ihost->netdev = kstrdup(buf, GFP_KERNEL);
break;
return iscsi_switch_str_param(&ihost->netdev, buf);
case ISCSI_HOST_PARAM_HWADDRESS:
if (!ihost->hwaddress)
ihost->hwaddress = kstrdup(buf, GFP_KERNEL);
break;
return iscsi_switch_str_param(&ihost->hwaddress, buf);
case ISCSI_HOST_PARAM_INITIATOR_NAME:
if (!ihost->initiatorname)
ihost->initiatorname = kstrdup(buf, GFP_KERNEL);
break;
return iscsi_switch_str_param(&ihost->initiatorname, buf);
default:
return -ENOSYS;
}
Expand Down

0 comments on commit 5700b1a

Please sign in to comment.