aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2016-02-08 09:30:19 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2016-02-08 11:51:36 -0500
commitc9e2f531be000af652927ee0af3a0f24f8e9e046 (patch)
tree8bcf8cefe2dd2c80cfbf9d6a9c627aef2c63cc8c
parentf285aa8db7cc4432c1a03f8b55ff34fe96317c11 (diff)
xen/scsiback: avoid warnings when adding multiple LUNs to a domain
When adding more than one LUN to a frontend a warning for a failed assignment is issued in dom0 for each already existing LUN. Avoid this warning by checking for a LUN already existing when existence is allowed (scsiback_do_add_lun() called with try == 1). As the LUN existence check is needed now for a third time, factor it out into a function. This in turn leads to a more or less complete rewrite of scsiback_del_translation_entry() which will now return a proper error code in case of failure. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
-rw-r--r--drivers/xen/xen-scsiback.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 51387d75c7bf..c46ee189466f 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -849,15 +849,31 @@ static int scsiback_map(struct vscsibk_info *info)
849} 849}
850 850
851/* 851/*
852 Check for a translation entry being present
853*/
854static struct v2p_entry *scsiback_chk_translation_entry(
855 struct vscsibk_info *info, struct ids_tuple *v)
856{
857 struct list_head *head = &(info->v2p_entry_lists);
858 struct v2p_entry *entry;
859
860 list_for_each_entry(entry, head, l)
861 if ((entry->v.chn == v->chn) &&
862 (entry->v.tgt == v->tgt) &&
863 (entry->v.lun == v->lun))
864 return entry;
865
866 return NULL;
867}
868
869/*
852 Add a new translation entry 870 Add a new translation entry
853*/ 871*/
854static int scsiback_add_translation_entry(struct vscsibk_info *info, 872static int scsiback_add_translation_entry(struct vscsibk_info *info,
855 char *phy, struct ids_tuple *v) 873 char *phy, struct ids_tuple *v)
856{ 874{
857 int err = 0; 875 int err = 0;
858 struct v2p_entry *entry;
859 struct v2p_entry *new; 876 struct v2p_entry *new;
860 struct list_head *head = &(info->v2p_entry_lists);
861 unsigned long flags; 877 unsigned long flags;
862 char *lunp; 878 char *lunp;
863 unsigned long long unpacked_lun; 879 unsigned long long unpacked_lun;
@@ -917,15 +933,10 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
917 spin_lock_irqsave(&info->v2p_lock, flags); 933 spin_lock_irqsave(&info->v2p_lock, flags);
918 934
919 /* Check double assignment to identical virtual ID */ 935 /* Check double assignment to identical virtual ID */
920 list_for_each_entry(entry, head, l) { 936 if (scsiback_chk_translation_entry(info, v)) {
921 if ((entry->v.chn == v->chn) && 937 pr_warn("Virtual ID is already used. Assignment was not performed.\n");
922 (entry->v.tgt == v->tgt) && 938 err = -EEXIST;
923 (entry->v.lun == v->lun)) { 939 goto out;
924 pr_warn("Virtual ID is already used. Assignment was not performed.\n");
925 err = -EEXIST;
926 goto out;
927 }
928
929 } 940 }
930 941
931 /* Create a new translation entry and add to the list */ 942 /* Create a new translation entry and add to the list */
@@ -933,7 +944,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
933 new->v = *v; 944 new->v = *v;
934 new->tpg = tpg; 945 new->tpg = tpg;
935 new->lun = unpacked_lun; 946 new->lun = unpacked_lun;
936 list_add_tail(&new->l, head); 947 list_add_tail(&new->l, &info->v2p_entry_lists);
937 948
938out: 949out:
939 spin_unlock_irqrestore(&info->v2p_lock, flags); 950 spin_unlock_irqrestore(&info->v2p_lock, flags);
@@ -956,39 +967,40 @@ static void __scsiback_del_translation_entry(struct v2p_entry *entry)
956} 967}
957 968
958/* 969/*
959 Delete the translation entry specfied 970 Delete the translation entry specified
960*/ 971*/
961static int scsiback_del_translation_entry(struct vscsibk_info *info, 972static int scsiback_del_translation_entry(struct vscsibk_info *info,
962 struct ids_tuple *v) 973 struct ids_tuple *v)
963{ 974{
964 struct v2p_entry *entry; 975 struct v2p_entry *entry;
965 struct list_head *head = &(info->v2p_entry_lists);
966 unsigned long flags; 976 unsigned long flags;
977 int ret = 0;
967 978
968 spin_lock_irqsave(&info->v2p_lock, flags); 979 spin_lock_irqsave(&info->v2p_lock, flags);
969 /* Find out the translation entry specified */ 980 /* Find out the translation entry specified */
970 list_for_each_entry(entry, head, l) { 981 entry = scsiback_chk_translation_entry(info, v);
971 if ((entry->v.chn == v->chn) && 982 if (entry)
972 (entry->v.tgt == v->tgt) && 983 __scsiback_del_translation_entry(entry);
973 (entry->v.lun == v->lun)) { 984 else
974 goto found; 985 ret = -ENOENT;
975 }
976 }
977
978 spin_unlock_irqrestore(&info->v2p_lock, flags);
979 return 1;
980
981found:
982 /* Delete the translation entry specfied */
983 __scsiback_del_translation_entry(entry);
984 986
985 spin_unlock_irqrestore(&info->v2p_lock, flags); 987 spin_unlock_irqrestore(&info->v2p_lock, flags);
986 return 0; 988 return ret;
987} 989}
988 990
989static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state, 991static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,
990 char *phy, struct ids_tuple *vir, int try) 992 char *phy, struct ids_tuple *vir, int try)
991{ 993{
994 struct v2p_entry *entry;
995 unsigned long flags;
996
997 if (try) {
998 spin_lock_irqsave(&info->v2p_lock, flags);
999 entry = scsiback_chk_translation_entry(info, vir);
1000 spin_unlock_irqrestore(&info->v2p_lock, flags);
1001 if (entry)
1002 return;
1003 }
992 if (!scsiback_add_translation_entry(info, phy, vir)) { 1004 if (!scsiback_add_translation_entry(info, phy, vir)) {
993 if (xenbus_printf(XBT_NIL, info->dev->nodename, state, 1005 if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
994 "%d", XenbusStateInitialised)) { 1006 "%d", XenbusStateInitialised)) {