Commit 048f7c3e authored by Corey Minyard's avatar Corey Minyard

ipmi: Properly release srcu locks on error conditions

When SRCU was added for handling hotplug, some error conditions
were not handled properly.
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent 58aae18e
...@@ -1291,18 +1291,19 @@ int ipmi_set_my_address(struct ipmi_user *user, ...@@ -1291,18 +1291,19 @@ int ipmi_set_my_address(struct ipmi_user *user,
unsigned int channel, unsigned int channel,
unsigned char address) unsigned char address)
{ {
int index; int index, rv = 0;
user = acquire_ipmi_user(user, &index); user = acquire_ipmi_user(user, &index);
if (!user) if (!user)
return -ENODEV; return -ENODEV;
if (channel >= IPMI_MAX_CHANNELS) if (channel >= IPMI_MAX_CHANNELS)
return -EINVAL; rv = -EINVAL;
user->intf->addrinfo[channel].address = address; else
user->intf->addrinfo[channel].address = address;
release_ipmi_user(user, index); release_ipmi_user(user, index);
return 0; return rv;
} }
EXPORT_SYMBOL(ipmi_set_my_address); EXPORT_SYMBOL(ipmi_set_my_address);
...@@ -1310,18 +1311,19 @@ int ipmi_get_my_address(struct ipmi_user *user, ...@@ -1310,18 +1311,19 @@ int ipmi_get_my_address(struct ipmi_user *user,
unsigned int channel, unsigned int channel,
unsigned char *address) unsigned char *address)
{ {
int index; int index, rv = 0;
user = acquire_ipmi_user(user, &index); user = acquire_ipmi_user(user, &index);
if (!user) if (!user)
return -ENODEV; return -ENODEV;
if (channel >= IPMI_MAX_CHANNELS) if (channel >= IPMI_MAX_CHANNELS)
return -EINVAL; rv = -EINVAL;
*address = user->intf->addrinfo[channel].address; else
*address = user->intf->addrinfo[channel].address;
release_ipmi_user(user, index); release_ipmi_user(user, index);
return 0; return rv;
} }
EXPORT_SYMBOL(ipmi_get_my_address); EXPORT_SYMBOL(ipmi_get_my_address);
...@@ -1329,15 +1331,16 @@ int ipmi_set_my_LUN(struct ipmi_user *user, ...@@ -1329,15 +1331,16 @@ int ipmi_set_my_LUN(struct ipmi_user *user,
unsigned int channel, unsigned int channel,
unsigned char LUN) unsigned char LUN)
{ {
int index; int index, rv = 0;
user = acquire_ipmi_user(user, &index); user = acquire_ipmi_user(user, &index);
if (!user) if (!user)
return -ENODEV; return -ENODEV;
if (channel >= IPMI_MAX_CHANNELS) if (channel >= IPMI_MAX_CHANNELS)
return -EINVAL; rv = -EINVAL;
user->intf->addrinfo[channel].lun = LUN & 0x3; else
user->intf->addrinfo[channel].lun = LUN & 0x3;
release_ipmi_user(user, index); release_ipmi_user(user, index);
return 0; return 0;
...@@ -1348,18 +1351,19 @@ int ipmi_get_my_LUN(struct ipmi_user *user, ...@@ -1348,18 +1351,19 @@ int ipmi_get_my_LUN(struct ipmi_user *user,
unsigned int channel, unsigned int channel,
unsigned char *address) unsigned char *address)
{ {
int index; int index, rv = 0;
user = acquire_ipmi_user(user, &index); user = acquire_ipmi_user(user, &index);
if (!user) if (!user)
return -ENODEV; return -ENODEV;
if (channel >= IPMI_MAX_CHANNELS) if (channel >= IPMI_MAX_CHANNELS)
return -EINVAL; rv = -EINVAL;
*address = user->intf->addrinfo[channel].lun; else
*address = user->intf->addrinfo[channel].lun;
release_ipmi_user(user, index); release_ipmi_user(user, index);
return 0; return rv;
} }
EXPORT_SYMBOL(ipmi_get_my_LUN); EXPORT_SYMBOL(ipmi_get_my_LUN);
...@@ -1540,8 +1544,10 @@ int ipmi_register_for_cmd(struct ipmi_user *user, ...@@ -1540,8 +1544,10 @@ int ipmi_register_for_cmd(struct ipmi_user *user,
return -ENODEV; return -ENODEV;
rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
if (!rcvr) if (!rcvr) {
return -ENOMEM; rv = -ENOMEM;
goto out_release;
}
rcvr->cmd = cmd; rcvr->cmd = cmd;
rcvr->netfn = netfn; rcvr->netfn = netfn;
rcvr->chans = chans; rcvr->chans = chans;
...@@ -1559,10 +1565,11 @@ int ipmi_register_for_cmd(struct ipmi_user *user, ...@@ -1559,10 +1565,11 @@ int ipmi_register_for_cmd(struct ipmi_user *user,
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
out_unlock: out_unlock:
mutex_unlock(&intf->cmd_rcvrs_mutex); mutex_unlock(&intf->cmd_rcvrs_mutex);
if (rv) if (rv)
kfree(rcvr); kfree(rcvr);
out_release:
release_ipmi_user(user, index); release_ipmi_user(user, index);
return rv; return rv;
......
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