Commit c9e2f531 authored by Juergen Gross's avatar Juergen Gross Committed by David Vrabel
Browse files

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: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
parent f285aa8d
Loading
Loading
Loading
Loading
+41 −29
Original line number Diff line number Diff line
@@ -848,6 +848,24 @@ static int scsiback_map(struct vscsibk_info *info)
	return scsiback_init_sring(info, ring_ref, evtchn);
}

/*
  Check for a translation entry being present
*/
static struct v2p_entry *scsiback_chk_translation_entry(
	struct vscsibk_info *info, struct ids_tuple *v)
{
	struct list_head *head = &(info->v2p_entry_lists);
	struct v2p_entry *entry;

	list_for_each_entry(entry, head, l)
		if ((entry->v.chn == v->chn) &&
		    (entry->v.tgt == v->tgt) &&
		    (entry->v.lun == v->lun))
			return entry;

	return NULL;
}

/*
  Add a new translation entry
*/
@@ -855,9 +873,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
					  char *phy, struct ids_tuple *v)
{
	int err = 0;
	struct v2p_entry *entry;
	struct v2p_entry *new;
	struct list_head *head = &(info->v2p_entry_lists);
	unsigned long flags;
	char *lunp;
	unsigned long long unpacked_lun;
@@ -917,23 +933,18 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
	spin_lock_irqsave(&info->v2p_lock, flags);

	/* Check double assignment to identical virtual ID */
	list_for_each_entry(entry, head, l) {
		if ((entry->v.chn == v->chn) &&
		    (entry->v.tgt == v->tgt) &&
		    (entry->v.lun == v->lun)) {
	if (scsiback_chk_translation_entry(info, v)) {
		pr_warn("Virtual ID is already used. Assignment was not performed.\n");
		err = -EEXIST;
		goto out;
	}

	}

	/* Create a new translation entry and add to the list */
	kref_init(&new->kref);
	new->v = *v;
	new->tpg = tpg;
	new->lun = unpacked_lun;
	list_add_tail(&new->l, head);
	list_add_tail(&new->l, &info->v2p_entry_lists);

out:
	spin_unlock_irqrestore(&info->v2p_lock, flags);
@@ -956,39 +967,40 @@ static void __scsiback_del_translation_entry(struct v2p_entry *entry)
}

/*
  Delete the translation entry specfied
  Delete the translation entry specified
*/
static int scsiback_del_translation_entry(struct vscsibk_info *info,
					  struct ids_tuple *v)
{
	struct v2p_entry *entry;
	struct list_head *head = &(info->v2p_entry_lists);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&info->v2p_lock, flags);
	/* Find out the translation entry specified */
	list_for_each_entry(entry, head, l) {
		if ((entry->v.chn == v->chn) &&
		    (entry->v.tgt == v->tgt) &&
		    (entry->v.lun == v->lun)) {
			goto found;
		}
	}

	spin_unlock_irqrestore(&info->v2p_lock, flags);
	return 1;

found:
	/* Delete the translation entry specfied */
	entry = scsiback_chk_translation_entry(info, v);
	if (entry)
		__scsiback_del_translation_entry(entry);
	else
		ret = -ENOENT;

	spin_unlock_irqrestore(&info->v2p_lock, flags);
	return 0;
	return ret;
}

static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state,
				char *phy, struct ids_tuple *vir, int try)
{
	struct v2p_entry *entry;
	unsigned long flags;

	if (try) {
		spin_lock_irqsave(&info->v2p_lock, flags);
		entry = scsiback_chk_translation_entry(info, vir);
		spin_unlock_irqrestore(&info->v2p_lock, flags);
		if (entry)
			return;
	}
	if (!scsiback_add_translation_entry(info, phy, vir)) {
		if (xenbus_printf(XBT_NIL, info->dev->nodename, state,
				  "%d", XenbusStateInitialised)) {