aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/ipc_sysctl.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 7f4235bed51b..d12ff5cd2a0b 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -35,6 +35,24 @@ static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
35 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); 35 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
36} 36}
37 37
38static int proc_ipc_callback_dointvec(ctl_table *table, int write,
39 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
40{
41 size_t lenp_bef = *lenp;
42 int rc;
43
44 rc = proc_ipc_dointvec(table, write, filp, buffer, lenp, ppos);
45
46 if (write && !rc && lenp_bef == *lenp)
47 /*
48 * Tunable has successfully been changed from userland:
49 * disable its automatic recomputing.
50 */
51 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
52
53 return rc;
54}
55
38static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, 56static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
39 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 57 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
40{ 58{
@@ -49,6 +67,7 @@ static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
49#else 67#else
50#define proc_ipc_doulongvec_minmax NULL 68#define proc_ipc_doulongvec_minmax NULL
51#define proc_ipc_dointvec NULL 69#define proc_ipc_dointvec NULL
70#define proc_ipc_callback_dointvec NULL
52#endif 71#endif
53 72
54#ifdef CONFIG_SYSCTL_SYSCALL 73#ifdef CONFIG_SYSCTL_SYSCALL
@@ -90,8 +109,28 @@ static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
90 } 109 }
91 return 1; 110 return 1;
92} 111}
112
113static int sysctl_ipc_registered_data(ctl_table *table, int __user *name,
114 int nlen, void __user *oldval, size_t __user *oldlenp,
115 void __user *newval, size_t newlen)
116{
117 int rc;
118
119 rc = sysctl_ipc_data(table, name, nlen, oldval, oldlenp, newval,
120 newlen);
121
122 if (newval && newlen && rc > 0)
123 /*
124 * Tunable has successfully been changed from userland:
125 * disable its automatic recomputing.
126 */
127 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
128
129 return rc;
130}
93#else 131#else
94#define sysctl_ipc_data NULL 132#define sysctl_ipc_data NULL
133#define sysctl_ipc_registered_data NULL
95#endif 134#endif
96 135
97static struct ctl_table ipc_kern_table[] = { 136static struct ctl_table ipc_kern_table[] = {
@@ -137,8 +176,8 @@ static struct ctl_table ipc_kern_table[] = {
137 .data = &init_ipc_ns.msg_ctlmni, 176 .data = &init_ipc_ns.msg_ctlmni,
138 .maxlen = sizeof (init_ipc_ns.msg_ctlmni), 177 .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
139 .mode = 0644, 178 .mode = 0644,
140 .proc_handler = proc_ipc_dointvec, 179 .proc_handler = proc_ipc_callback_dointvec,
141 .strategy = sysctl_ipc_data, 180 .strategy = sysctl_ipc_registered_data,
142 }, 181 },
143 { 182 {
144 .ctl_name = KERN_MSGMNB, 183 .ctl_name = KERN_MSGMNB,