aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-05-13 18:57:40 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-05-23 16:44:10 -0400
commit5700b1af93388544843a453e3c68f8f928bd1e88 (patch)
tree6c0ea7141990b88b8147e7e35d1f7ed8ebb0baa5 /drivers/scsi/libiscsi.c
parent184b57c630c86d35b7f92d4b6545fdf07647c5d5 (diff)
[SCSI] libiscsi: handle param allocation failures
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>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c108
1 files changed, 33 insertions, 75 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 11bc3e1fbd5a..b4aaf2e5fe7a 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2656,6 +2656,23 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
2656} 2656}
2657EXPORT_SYMBOL_GPL(iscsi_conn_bind); 2657EXPORT_SYMBOL_GPL(iscsi_conn_bind);
2658 2658
2659static int iscsi_switch_str_param(char **param, char *new_val_buf)
2660{
2661 char *new_val;
2662
2663 if (*param) {
2664 if (!strcmp(*param, new_val_buf))
2665 return 0;
2666 }
2667
2668 new_val = kstrdup(new_val_buf, GFP_NOIO);
2669 if (!new_val)
2670 return -ENOMEM;
2671
2672 kfree(*param);
2673 *param = new_val;
2674 return 0;
2675}
2659 2676
2660int iscsi_set_param(struct iscsi_cls_conn *cls_conn, 2677int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
2661 enum iscsi_param param, char *buf, int buflen) 2678 enum iscsi_param param, char *buf, int buflen)
@@ -2728,38 +2745,15 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
2728 sscanf(buf, "%u", &conn->exp_statsn); 2745 sscanf(buf, "%u", &conn->exp_statsn);
2729 break; 2746 break;
2730 case ISCSI_PARAM_USERNAME: 2747 case ISCSI_PARAM_USERNAME:
2731 kfree(session->username); 2748 return iscsi_switch_str_param(&session->username, buf);
2732 session->username = kstrdup(buf, GFP_KERNEL);
2733 if (!session->username)
2734 return -ENOMEM;
2735 break;
2736 case ISCSI_PARAM_USERNAME_IN: 2749 case ISCSI_PARAM_USERNAME_IN:
2737 kfree(session->username_in); 2750 return iscsi_switch_str_param(&session->username_in, buf);
2738 session->username_in = kstrdup(buf, GFP_KERNEL);
2739 if (!session->username_in)
2740 return -ENOMEM;
2741 break;
2742 case ISCSI_PARAM_PASSWORD: 2751 case ISCSI_PARAM_PASSWORD:
2743 kfree(session->password); 2752 return iscsi_switch_str_param(&session->password, buf);
2744 session->password = kstrdup(buf, GFP_KERNEL);
2745 if (!session->password)
2746 return -ENOMEM;
2747 break;
2748 case ISCSI_PARAM_PASSWORD_IN: 2753 case ISCSI_PARAM_PASSWORD_IN:
2749 kfree(session->password_in); 2754 return iscsi_switch_str_param(&session->password_in, buf);
2750 session->password_in = kstrdup(buf, GFP_KERNEL);
2751 if (!session->password_in)
2752 return -ENOMEM;
2753 break;
2754 case ISCSI_PARAM_TARGET_NAME: 2755 case ISCSI_PARAM_TARGET_NAME:
2755 /* this should not change between logins */ 2756 return iscsi_switch_str_param(&session->targetname, buf);
2756 if (session->targetname)
2757 break;
2758
2759 session->targetname = kstrdup(buf, GFP_KERNEL);
2760 if (!session->targetname)
2761 return -ENOMEM;
2762 break;
2763 case ISCSI_PARAM_TPGT: 2757 case ISCSI_PARAM_TPGT:
2764 sscanf(buf, "%d", &session->tpgt); 2758 sscanf(buf, "%d", &session->tpgt);
2765 break; 2759 break;
@@ -2767,25 +2761,11 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
2767 sscanf(buf, "%d", &conn->persistent_port); 2761 sscanf(buf, "%d", &conn->persistent_port);
2768 break; 2762 break;
2769 case ISCSI_PARAM_PERSISTENT_ADDRESS: 2763 case ISCSI_PARAM_PERSISTENT_ADDRESS:
2770 /* 2764 return iscsi_switch_str_param(&conn->persistent_address, buf);
2771 * this is the address returned in discovery so it should
2772 * not change between logins.
2773 */
2774 if (conn->persistent_address)
2775 break;
2776
2777 conn->persistent_address = kstrdup(buf, GFP_KERNEL);
2778 if (!conn->persistent_address)
2779 return -ENOMEM;
2780 break;
2781 case ISCSI_PARAM_IFACE_NAME: 2765 case ISCSI_PARAM_IFACE_NAME:
2782 if (!session->ifacename) 2766 return iscsi_switch_str_param(&session->ifacename, buf);
2783 session->ifacename = kstrdup(buf, GFP_KERNEL);
2784 break;
2785 case ISCSI_PARAM_INITIATOR_NAME: 2767 case ISCSI_PARAM_INITIATOR_NAME:
2786 if (!session->initiatorname) 2768 return iscsi_switch_str_param(&session->initiatorname, buf);
2787 session->initiatorname = kstrdup(buf, GFP_KERNEL);
2788 break;
2789 default: 2769 default:
2790 return -ENOSYS; 2770 return -ENOSYS;
2791 } 2771 }
@@ -2856,10 +2836,7 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
2856 len = sprintf(buf, "%s\n", session->ifacename); 2836 len = sprintf(buf, "%s\n", session->ifacename);
2857 break; 2837 break;
2858 case ISCSI_PARAM_INITIATOR_NAME: 2838 case ISCSI_PARAM_INITIATOR_NAME:
2859 if (!session->initiatorname) 2839 len = sprintf(buf, "%s\n", session->initiatorname);
2860 len = sprintf(buf, "%s\n", "unknown");
2861 else
2862 len = sprintf(buf, "%s\n", session->initiatorname);
2863 break; 2840 break;
2864 default: 2841 default:
2865 return -ENOSYS; 2842 return -ENOSYS;
@@ -2925,29 +2902,16 @@ int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
2925 2902
2926 switch (param) { 2903 switch (param) {
2927 case ISCSI_HOST_PARAM_NETDEV_NAME: 2904 case ISCSI_HOST_PARAM_NETDEV_NAME:
2928 if (!ihost->netdev) 2905 len = sprintf(buf, "%s\n", ihost->netdev);
2929 len = sprintf(buf, "%s\n", "default");
2930 else
2931 len = sprintf(buf, "%s\n", ihost->netdev);
2932 break; 2906 break;
2933 case ISCSI_HOST_PARAM_HWADDRESS: 2907 case ISCSI_HOST_PARAM_HWADDRESS:
2934 if (!ihost->hwaddress) 2908 len = sprintf(buf, "%s\n", ihost->hwaddress);
2935 len = sprintf(buf, "%s\n", "default");
2936 else
2937 len = sprintf(buf, "%s\n", ihost->hwaddress);
2938 break; 2909 break;
2939 case ISCSI_HOST_PARAM_INITIATOR_NAME: 2910 case ISCSI_HOST_PARAM_INITIATOR_NAME:
2940 if (!ihost->initiatorname) 2911 len = sprintf(buf, "%s\n", ihost->initiatorname);
2941 len = sprintf(buf, "%s\n", "unknown");
2942 else
2943 len = sprintf(buf, "%s\n", ihost->initiatorname);
2944 break; 2912 break;
2945 case ISCSI_HOST_PARAM_IPADDRESS: 2913 case ISCSI_HOST_PARAM_IPADDRESS:
2946 if (!strlen(ihost->local_address)) 2914 len = sprintf(buf, "%s\n", ihost->local_address);
2947 len = sprintf(buf, "%s\n", "unknown");
2948 else
2949 len = sprintf(buf, "%s\n",
2950 ihost->local_address);
2951 break; 2915 break;
2952 default: 2916 default:
2953 return -ENOSYS; 2917 return -ENOSYS;
@@ -2964,17 +2928,11 @@ int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param,
2964 2928
2965 switch (param) { 2929 switch (param) {
2966 case ISCSI_HOST_PARAM_NETDEV_NAME: 2930 case ISCSI_HOST_PARAM_NETDEV_NAME:
2967 if (!ihost->netdev) 2931 return iscsi_switch_str_param(&ihost->netdev, buf);
2968 ihost->netdev = kstrdup(buf, GFP_KERNEL);
2969 break;
2970 case ISCSI_HOST_PARAM_HWADDRESS: 2932 case ISCSI_HOST_PARAM_HWADDRESS:
2971 if (!ihost->hwaddress) 2933 return iscsi_switch_str_param(&ihost->hwaddress, buf);
2972 ihost->hwaddress = kstrdup(buf, GFP_KERNEL);
2973 break;
2974 case ISCSI_HOST_PARAM_INITIATOR_NAME: 2934 case ISCSI_HOST_PARAM_INITIATOR_NAME:
2975 if (!ihost->initiatorname) 2935 return iscsi_switch_str_param(&ihost->initiatorname, buf);
2976 ihost->initiatorname = kstrdup(buf, GFP_KERNEL);
2977 break;
2978 default: 2936 default:
2979 return -ENOSYS; 2937 return -ENOSYS;
2980 } 2938 }