aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2008-07-27 01:31:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-27 12:45:34 -0400
commitbfbcf034798b2ca45338cee5049b5694b7ddc865 (patch)
tree51ca2687c318033b7a41533ecdfd2801a7241327 /kernel/sysctl.c
parent8be1a6d6c77ab4532e4476fdb8177030ef48b52c (diff)
lost sysctl fix
try_attach() should walk into the matching subdirectory, not the first one... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Tested-by: Valdis.Kletnieks@vt.edu Tested-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 911d846f0503..fe4713347275 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1680,43 +1680,45 @@ static __init int sysctl_init(void)
1680 1680
1681core_initcall(sysctl_init); 1681core_initcall(sysctl_init);
1682 1682
1683static int is_branch_in(struct ctl_table *branch, struct ctl_table *table) 1683static struct ctl_table *is_branch_in(struct ctl_table *branch,
1684 struct ctl_table *table)
1684{ 1685{
1685 struct ctl_table *p; 1686 struct ctl_table *p;
1686 const char *s = branch->procname; 1687 const char *s = branch->procname;
1687 1688
1688 /* branch should have named subdirectory as its first element */ 1689 /* branch should have named subdirectory as its first element */
1689 if (!s || !branch->child) 1690 if (!s || !branch->child)
1690 return 0; 1691 return NULL;
1691 1692
1692 /* ... and nothing else */ 1693 /* ... and nothing else */
1693 if (branch[1].procname || branch[1].ctl_name) 1694 if (branch[1].procname || branch[1].ctl_name)
1694 return 0; 1695 return NULL;
1695 1696
1696 /* table should contain subdirectory with the same name */ 1697 /* table should contain subdirectory with the same name */
1697 for (p = table; p->procname || p->ctl_name; p++) { 1698 for (p = table; p->procname || p->ctl_name; p++) {
1698 if (!p->child) 1699 if (!p->child)
1699 continue; 1700 continue;
1700 if (p->procname && strcmp(p->procname, s) == 0) 1701 if (p->procname && strcmp(p->procname, s) == 0)
1701 return 1; 1702 return p;
1702 } 1703 }
1703 return 0; 1704 return NULL;
1704} 1705}
1705 1706
1706/* see if attaching q to p would be an improvement */ 1707/* see if attaching q to p would be an improvement */
1707static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) 1708static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1708{ 1709{
1709 struct ctl_table *to = p->ctl_table, *by = q->ctl_table; 1710 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
1711 struct ctl_table *next;
1710 int is_better = 0; 1712 int is_better = 0;
1711 int not_in_parent = !p->attached_by; 1713 int not_in_parent = !p->attached_by;
1712 1714
1713 while (is_branch_in(by, to)) { 1715 while ((next = is_branch_in(by, to)) != NULL) {
1714 if (by == q->attached_by) 1716 if (by == q->attached_by)
1715 is_better = 1; 1717 is_better = 1;
1716 if (to == p->attached_by) 1718 if (to == p->attached_by)
1717 not_in_parent = 1; 1719 not_in_parent = 1;
1718 by = by->child; 1720 by = by->child;
1719 to = to->child; 1721 to = next->child;
1720 } 1722 }
1721 1723
1722 if (is_better && not_in_parent) { 1724 if (is_better && not_in_parent) {