Commit 81322f8e authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

[PATCH] Fix procfs warnings when removing ipmi_si module

Presently we get procfs warnings from ipmi_si.ko due to its failing to
remove all of a /proc directory's contents prior to removing that
directory.

This patch tracks all proc entries for an IPMI interface and unregisters
them all upon removal.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent be5979d3
...@@ -123,6 +123,12 @@ struct ipmi_channel ...@@ -123,6 +123,12 @@ struct ipmi_channel
unsigned char protocol; unsigned char protocol;
}; };
struct ipmi_proc_entry
{
char *name;
struct ipmi_proc_entry *next;
};
#define IPMI_IPMB_NUM_SEQ 64 #define IPMI_IPMB_NUM_SEQ 64
#define IPMI_MAX_CHANNELS 8 #define IPMI_MAX_CHANNELS 8
struct ipmi_smi struct ipmi_smi
...@@ -149,6 +155,11 @@ struct ipmi_smi ...@@ -149,6 +155,11 @@ struct ipmi_smi
struct ipmi_smi_handlers *handlers; struct ipmi_smi_handlers *handlers;
void *send_info; void *send_info;
/* A list of proc entries for this interface. This does not
need a lock, only one thread creates it and only one thread
destroys it. */
struct ipmi_proc_entry *proc_entries;
/* A table of sequence numbers for this interface. We use the /* A table of sequence numbers for this interface. We use the
sequence numbers for IPMB messages that go out of the sequence numbers for IPMB messages that go out of the
interface to match them up with their responses. A routine interface to match them up with their responses. A routine
...@@ -1515,18 +1526,36 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, ...@@ -1515,18 +1526,36 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc, write_proc_t *write_proc, read_proc_t *read_proc, write_proc_t *write_proc,
void *data, struct module *owner) void *data, struct module *owner)
{ {
struct proc_dir_entry *file; struct proc_dir_entry *file;
int rv = 0; int rv = 0;
struct ipmi_proc_entry *entry;
/* Create a list element. */
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->name = kmalloc(strlen(name)+1, GFP_KERNEL);
if (!entry->name) {
kfree(entry);
return -ENOMEM;
}
strcpy(entry->name, name);
file = create_proc_entry(name, 0, smi->proc_dir); file = create_proc_entry(name, 0, smi->proc_dir);
if (!file) if (!file) {
kfree(entry->name);
kfree(entry);
rv = -ENOMEM; rv = -ENOMEM;
else { } else {
file->nlink = 1; file->nlink = 1;
file->data = data; file->data = data;
file->read_proc = read_proc; file->read_proc = read_proc;
file->write_proc = write_proc; file->write_proc = write_proc;
file->owner = owner; file->owner = owner;
/* Stick it on the list. */
entry->next = smi->proc_entries;
smi->proc_entries = entry;
} }
return rv; return rv;
...@@ -1562,6 +1591,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num) ...@@ -1562,6 +1591,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
return rv; return rv;
} }
static void remove_proc_entries(ipmi_smi_t smi)
{
struct ipmi_proc_entry *entry;
while (smi->proc_entries) {
entry = smi->proc_entries;
smi->proc_entries = entry->next;
remove_proc_entry(entry->name, smi->proc_dir);
kfree(entry->name);
kfree(entry);
}
remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
}
static int static int
send_channel_info_cmd(ipmi_smi_t intf, int chan) send_channel_info_cmd(ipmi_smi_t intf, int chan)
{ {
...@@ -1749,8 +1793,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, ...@@ -1749,8 +1793,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
if (rv) { if (rv) {
if (new_intf->proc_dir) if (new_intf->proc_dir)
remove_proc_entry(new_intf->proc_dir_name, remove_proc_entries(new_intf);
proc_ipmi_root);
kfree(new_intf); kfree(new_intf);
} }
...@@ -1806,8 +1849,7 @@ int ipmi_unregister_smi(ipmi_smi_t intf) ...@@ -1806,8 +1849,7 @@ int ipmi_unregister_smi(ipmi_smi_t intf)
{ {
for (i=0; i<MAX_IPMI_INTERFACES; i++) { for (i=0; i<MAX_IPMI_INTERFACES; i++) {
if (ipmi_interfaces[i] == intf) { if (ipmi_interfaces[i] == intf) {
remove_proc_entry(intf->proc_dir_name, remove_proc_entries(intf);
proc_ipmi_root);
spin_lock_irqsave(&interfaces_lock, flags); spin_lock_irqsave(&interfaces_lock, flags);
ipmi_interfaces[i] = NULL; ipmi_interfaces[i] = NULL;
clean_up_interface_data(intf); clean_up_interface_data(intf);
......
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