aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/proc_sysctl.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index a7708b7c957..47b474b572c 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -525,20 +525,32 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
525 525
526static int proc_sys_open(struct inode *inode, struct file *filp) 526static int proc_sys_open(struct inode *inode, struct file *filp)
527{ 527{
528 struct ctl_table_header *head = grab_header(inode);
528 struct ctl_table *table = PROC_I(inode)->sysctl_entry; 529 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
529 530
531 /* sysctl was unregistered */
532 if (IS_ERR(head))
533 return PTR_ERR(head);
534
530 if (table->poll) 535 if (table->poll)
531 filp->private_data = proc_sys_poll_event(table->poll); 536 filp->private_data = proc_sys_poll_event(table->poll);
532 537
538 sysctl_head_finish(head);
539
533 return 0; 540 return 0;
534} 541}
535 542
536static unsigned int proc_sys_poll(struct file *filp, poll_table *wait) 543static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
537{ 544{
538 struct inode *inode = filp->f_path.dentry->d_inode; 545 struct inode *inode = filp->f_path.dentry->d_inode;
546 struct ctl_table_header *head = grab_header(inode);
539 struct ctl_table *table = PROC_I(inode)->sysctl_entry; 547 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
540 unsigned long event = (unsigned long)filp->private_data;
541 unsigned int ret = DEFAULT_POLLMASK; 548 unsigned int ret = DEFAULT_POLLMASK;
549 unsigned long event;
550
551 /* sysctl was unregistered */
552 if (IS_ERR(head))
553 return POLLERR | POLLHUP;
542 554
543 if (!table->proc_handler) 555 if (!table->proc_handler)
544 goto out; 556 goto out;
@@ -546,6 +558,7 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
546 if (!table->poll) 558 if (!table->poll)
547 goto out; 559 goto out;
548 560
561 event = (unsigned long)filp->private_data;
549 poll_wait(filp, &table->poll->wait, wait); 562 poll_wait(filp, &table->poll->wait, wait);
550 563
551 if (event != atomic_read(&table->poll->event)) { 564 if (event != atomic_read(&table->poll->event)) {
@@ -554,6 +567,8 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
554 } 567 }
555 568
556out: 569out:
570 sysctl_head_finish(head);
571
557 return ret; 572 return ret;
558} 573}
559 574