diff options
| -rw-r--r-- | fs/proc/proc_sysctl.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index a7708b7c957f..47b474b572c1 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 | ||
| 526 | static int proc_sys_open(struct inode *inode, struct file *filp) | 526 | static 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 | ||
| 536 | static unsigned int proc_sys_poll(struct file *filp, poll_table *wait) | 543 | static 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 | ||
| 556 | out: | 569 | out: |
| 570 | sysctl_head_finish(head); | ||
| 571 | |||
| 557 | return ret; | 572 | return ret; |
| 558 | } | 573 | } |
| 559 | 574 | ||
