diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/proc/proc_sysctl.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/proc/proc_sysctl.c')
-rw-r--r-- | fs/proc/proc_sysctl.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 5be436ea088e..d167de365a8d 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/sysctl.h> | 5 | #include <linux/sysctl.h> |
6 | #include <linux/proc_fs.h> | 6 | #include <linux/proc_fs.h> |
7 | #include <linux/security.h> | 7 | #include <linux/security.h> |
8 | #include <linux/namei.h> | ||
8 | #include "internal.h" | 9 | #include "internal.h" |
9 | 10 | ||
10 | static const struct dentry_operations proc_sys_dentry_operations; | 11 | static const struct dentry_operations proc_sys_dentry_operations; |
@@ -23,13 +24,14 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, | |||
23 | if (!inode) | 24 | if (!inode) |
24 | goto out; | 25 | goto out; |
25 | 26 | ||
27 | inode->i_ino = get_next_ino(); | ||
28 | |||
26 | sysctl_head_get(head); | 29 | sysctl_head_get(head); |
27 | ei = PROC_I(inode); | 30 | ei = PROC_I(inode); |
28 | ei->sysctl = head; | 31 | ei->sysctl = head; |
29 | ei->sysctl_entry = table; | 32 | ei->sysctl_entry = table; |
30 | 33 | ||
31 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 34 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
32 | inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ | ||
33 | inode->i_mode = table->mode; | 35 | inode->i_mode = table->mode; |
34 | if (!table->child) { | 36 | if (!table->child) { |
35 | inode->i_mode |= S_IFREG; | 37 | inode->i_mode |= S_IFREG; |
@@ -118,7 +120,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, | |||
118 | goto out; | 120 | goto out; |
119 | 121 | ||
120 | err = NULL; | 122 | err = NULL; |
121 | dentry->d_op = &proc_sys_dentry_operations; | 123 | d_set_d_op(dentry, &proc_sys_dentry_operations); |
122 | d_add(dentry, inode); | 124 | d_add(dentry, inode); |
123 | 125 | ||
124 | out: | 126 | out: |
@@ -199,7 +201,7 @@ static int proc_sys_fill_cache(struct file *filp, void *dirent, | |||
199 | dput(child); | 201 | dput(child); |
200 | return -ENOMEM; | 202 | return -ENOMEM; |
201 | } else { | 203 | } else { |
202 | child->d_op = &proc_sys_dentry_operations; | 204 | d_set_d_op(child, &proc_sys_dentry_operations); |
203 | d_add(child, inode); | 205 | d_add(child, inode); |
204 | } | 206 | } |
205 | } else { | 207 | } else { |
@@ -292,7 +294,7 @@ out: | |||
292 | return ret; | 294 | return ret; |
293 | } | 295 | } |
294 | 296 | ||
295 | static int proc_sys_permission(struct inode *inode, int mask) | 297 | static int proc_sys_permission(struct inode *inode, int mask,unsigned int flags) |
296 | { | 298 | { |
297 | /* | 299 | /* |
298 | * sysctl entries that are not writeable, | 300 | * sysctl entries that are not writeable, |
@@ -364,6 +366,7 @@ static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct | |||
364 | static const struct file_operations proc_sys_file_operations = { | 366 | static const struct file_operations proc_sys_file_operations = { |
365 | .read = proc_sys_read, | 367 | .read = proc_sys_read, |
366 | .write = proc_sys_write, | 368 | .write = proc_sys_write, |
369 | .llseek = default_llseek, | ||
367 | }; | 370 | }; |
368 | 371 | ||
369 | static const struct file_operations proc_sys_dir_file_operations = { | 372 | static const struct file_operations proc_sys_dir_file_operations = { |
@@ -386,23 +389,33 @@ static const struct inode_operations proc_sys_dir_operations = { | |||
386 | 389 | ||
387 | static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) | 390 | static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) |
388 | { | 391 | { |
392 | if (nd->flags & LOOKUP_RCU) | ||
393 | return -ECHILD; | ||
389 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; | 394 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; |
390 | } | 395 | } |
391 | 396 | ||
392 | static int proc_sys_delete(struct dentry *dentry) | 397 | static int proc_sys_delete(const struct dentry *dentry) |
393 | { | 398 | { |
394 | return !!PROC_I(dentry->d_inode)->sysctl->unregistering; | 399 | return !!PROC_I(dentry->d_inode)->sysctl->unregistering; |
395 | } | 400 | } |
396 | 401 | ||
397 | static int proc_sys_compare(struct dentry *dir, struct qstr *qstr, | 402 | static int proc_sys_compare(const struct dentry *parent, |
398 | struct qstr *name) | 403 | const struct inode *pinode, |
404 | const struct dentry *dentry, const struct inode *inode, | ||
405 | unsigned int len, const char *str, const struct qstr *name) | ||
399 | { | 406 | { |
400 | struct dentry *dentry = container_of(qstr, struct dentry, d_name); | 407 | struct ctl_table_header *head; |
401 | if (qstr->len != name->len) | 408 | /* Although proc doesn't have negative dentries, rcu-walk means |
409 | * that inode here can be NULL */ | ||
410 | /* AV: can it, indeed? */ | ||
411 | if (!inode) | ||
412 | return 1; | ||
413 | if (name->len != len) | ||
402 | return 1; | 414 | return 1; |
403 | if (memcmp(qstr->name, name->name, name->len)) | 415 | if (memcmp(name->name, str, len)) |
404 | return 1; | 416 | return 1; |
405 | return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl); | 417 | head = rcu_dereference(PROC_I(inode)->sysctl); |
418 | return !head || !sysctl_is_seen(head); | ||
406 | } | 419 | } |
407 | 420 | ||
408 | static const struct dentry_operations proc_sys_dentry_operations = { | 421 | static const struct dentry_operations proc_sys_dentry_operations = { |