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: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2ee0deec49
commit
10c69bb7d9
@ -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;
|
||||||
|
channel->guid = guid;
|
||||||
|
return channel;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
visorchannel_destroy(channel);
|
||||||
if (!rc) {
|
return NULL;
|
||||||
if (!p) {
|
|
||||||
visorchannel_destroy(p);
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct visorchannel *
|
struct visorchannel *
|
||||||
@ -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)
|
|||||||
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);
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user