Commit 10c69bb7 authored by Prarit Bhargava's avatar Prarit Bhargava Committed by Greg Kroah-Hartman

staging: unisys: visorchannel cleanup visorchannel_create_guts()

The error handling in this function was broken and while looking at that
I noticed that the whole function was in need of cleanup.  This patch
fixes the error handling, specifically

                if (!p) {
                        visorchannel_destroy(p);
                        channel = NULL;
                }

and does a lot of cleanup.  I also verified that the called functions
returned correct errors, and that led to a change in
visor_memregion_resize(), visorchannel_destroy() and
visor_memregion_destroy().
Signed-off-by: default avatarPrarit Bhargava <prarit@redhat.com>
Signed-off-by: default avatarBenjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2ee0deec
...@@ -55,60 +55,52 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes, ...@@ -55,60 +55,52 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes,
struct visorchannel *parent, ulong off, uuid_le guid, struct visorchannel *parent, ulong off, uuid_le guid,
BOOL needs_lock) BOOL needs_lock)
{ {
struct visorchannel *p = NULL; struct visorchannel *channel;
void *rc = NULL; int err;
size_t size = sizeof(struct channel_header);
struct memregion *memregion;
p = kmalloc(sizeof(*p), GFP_KERNEL|__GFP_NORETRY); channel = kmalloc(sizeof(*channel), GFP_KERNEL|__GFP_NORETRY);
if (!p) { if (!channel)
rc = NULL;
goto cleanup; goto cleanup;
}
p->memregion = NULL; channel->memregion = NULL;
p->needs_lock = needs_lock; channel->needs_lock = needs_lock;
spin_lock_init(&p->insert_lock); spin_lock_init(&channel->insert_lock);
spin_lock_init(&p->remove_lock); spin_lock_init(&channel->remove_lock);
/* prepare chan_hdr (abstraction to read/write channel memory) */ /* prepare chan_hdr (abstraction to read/write channel memory) */
if (!parent) if (!parent)
p->memregion = memregion = visor_memregion_create(physaddr, size);
visor_memregion_create(physaddr,
sizeof(struct channel_header));
else else
p->memregion = memregion = visor_memregion_create_overlapped(parent->memregion,
visor_memregion_create_overlapped(parent->memregion, off, size);
off, sizeof(struct channel_header)); if (!memregion)
if (!p->memregion) {
rc = NULL;
goto cleanup; goto cleanup;
} channel->memregion = memregion;
if (visor_memregion_read(p->memregion, 0, &p->chan_hdr,
sizeof(struct channel_header)) < 0) { err = visor_memregion_read(channel->memregion, 0, &channel->chan_hdr,
rc = NULL; sizeof(struct channel_header));
if (err)
goto cleanup; goto cleanup;
}
/* we had better be a CLIENT of this channel */
if (channel_bytes == 0) if (channel_bytes == 0)
/* we had better be a CLIENT of this channel */ channel_bytes = (ulong)channel->chan_hdr.size;
channel_bytes = (ulong)p->chan_hdr.size;
if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
/* we had better be a CLIENT of this channel */ guid = channel->chan_hdr.chtype;
guid = p->chan_hdr.chtype;
if (visor_memregion_resize(p->memregion, channel_bytes) < 0) { err = visor_memregion_resize(channel->memregion, channel_bytes);
rc = NULL; if (err)
goto cleanup; goto cleanup;
}
p->size = channel_bytes;
p->guid = guid;
rc = p; channel->size = channel_bytes;
cleanup: channel->guid = guid;
return channel;
if (!rc) { cleanup:
if (!p) { visorchannel_destroy(channel);
visorchannel_destroy(p); return NULL;
p = NULL;
}
}
return rc;
} }
struct visorchannel * struct visorchannel *
...@@ -153,10 +145,7 @@ visorchannel_destroy(struct visorchannel *channel) ...@@ -153,10 +145,7 @@ visorchannel_destroy(struct visorchannel *channel)
{ {
if (!channel) if (!channel)
return; return;
if (channel->memregion) { visor_memregion_destroy(channel->memregion);
visor_memregion_destroy(channel->memregion);
channel->memregion = NULL;
}
kfree(channel); kfree(channel);
} }
EXPORT_SYMBOL_GPL(visorchannel_destroy); EXPORT_SYMBOL_GPL(visorchannel_destroy);
......
...@@ -156,7 +156,7 @@ visor_memregion_resize(struct memregion *memregion, ulong newsize) ...@@ -156,7 +156,7 @@ visor_memregion_resize(struct memregion *memregion, ulong newsize)
unmapit(memregion); unmapit(memregion);
memregion->nbytes = newsize; memregion->nbytes = newsize;
if (!mapit(memregion)) if (!mapit(memregion))
return -1; return -EIO;
} }
return 0; return 0;
} }
...@@ -197,7 +197,7 @@ EXPORT_SYMBOL_GPL(visor_memregion_write); ...@@ -197,7 +197,7 @@ EXPORT_SYMBOL_GPL(visor_memregion_write);
void void
visor_memregion_destroy(struct memregion *memregion) visor_memregion_destroy(struct memregion *memregion)
{ {
if (memregion == NULL) if (!memregion)
return; return;
if (!memregion->overlapped) if (!memregion->overlapped)
unmapit(memregion); unmapit(memregion);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment