|
@@ -525,20 +525,32 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
|
|
|
|
|
|
static int proc_sys_open(struct inode *inode, struct file *filp)
|
|
|
{
|
|
|
+ struct ctl_table_header *head = grab_header(inode);
|
|
|
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
|
|
|
|
|
+ /* sysctl was unregistered */
|
|
|
+ if (IS_ERR(head))
|
|
|
+ return PTR_ERR(head);
|
|
|
+
|
|
|
if (table->poll)
|
|
|
filp->private_data = proc_sys_poll_event(table->poll);
|
|
|
|
|
|
+ sysctl_head_finish(head);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
|
|
{
|
|
|
struct inode *inode = filp->f_path.dentry->d_inode;
|
|
|
+ struct ctl_table_header *head = grab_header(inode);
|
|
|
struct ctl_table *table = PROC_I(inode)->sysctl_entry;
|
|
|
- unsigned long event = (unsigned long)filp->private_data;
|
|
|
unsigned int ret = DEFAULT_POLLMASK;
|
|
|
+ unsigned long event;
|
|
|
+
|
|
|
+ /* sysctl was unregistered */
|
|
|
+ if (IS_ERR(head))
|
|
|
+ return POLLERR | POLLHUP;
|
|
|
|
|
|
if (!table->proc_handler)
|
|
|
goto out;
|
|
@@ -546,6 +558,7 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
|
|
if (!table->poll)
|
|
|
goto out;
|
|
|
|
|
|
+ event = (unsigned long)filp->private_data;
|
|
|
poll_wait(filp, &table->poll->wait, wait);
|
|
|
|
|
|
if (event != atomic_read(&table->poll->event)) {
|
|
@@ -554,6 +567,8 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
+ sysctl_head_finish(head);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|