diff options
author | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
commit | 95ee46aa8698f2000647dfb362400fadbb5807cf (patch) | |
tree | e5a05c7297f997e191c73091934e42e3195c0e40 /fs/proc | |
parent | cfa806f059801dbe7e435745eb2e187c8bfe1e7f (diff) | |
parent | 92fa5bd9a946b6e7aab6764e7312e4e3d9bed295 (diff) |
Merge branch 'linus' into release
Conflicts:
drivers/acpi/debug.c
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Makefile | 2 | ||||
-rw-r--r-- | fs/proc/base.c | 144 | ||||
-rw-r--r-- | fs/proc/generic.c | 18 | ||||
-rw-r--r-- | fs/proc/inode.c | 23 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 15 |
5 files changed, 155 insertions, 47 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 11a7b5c68153..2758e2afc518 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the Linux proc filesystem routines. | 2 | # Makefile for the Linux proc filesystem routines. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_PROC_FS) += proc.o | 5 | obj-y += proc.o |
6 | 6 | ||
7 | proc-y := nommu.o task_nommu.o | 7 | proc-y := nommu.o task_nommu.o |
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
diff --git a/fs/proc/base.c b/fs/proc/base.c index acb7ef80ea4f..a1c43e7c8a7b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/namei.h> | 63 | #include <linux/namei.h> |
64 | #include <linux/mnt_namespace.h> | 64 | #include <linux/mnt_namespace.h> |
65 | #include <linux/mm.h> | 65 | #include <linux/mm.h> |
66 | #include <linux/swap.h> | ||
66 | #include <linux/rcupdate.h> | 67 | #include <linux/rcupdate.h> |
67 | #include <linux/kallsyms.h> | 68 | #include <linux/kallsyms.h> |
68 | #include <linux/stacktrace.h> | 69 | #include <linux/stacktrace.h> |
@@ -148,18 +149,13 @@ static unsigned int pid_entry_count_dirs(const struct pid_entry *entries, | |||
148 | return count; | 149 | return count; |
149 | } | 150 | } |
150 | 151 | ||
151 | static int get_fs_path(struct task_struct *task, struct path *path, bool root) | 152 | static int get_task_root(struct task_struct *task, struct path *root) |
152 | { | 153 | { |
153 | struct fs_struct *fs; | ||
154 | int result = -ENOENT; | 154 | int result = -ENOENT; |
155 | 155 | ||
156 | task_lock(task); | 156 | task_lock(task); |
157 | fs = task->fs; | 157 | if (task->fs) { |
158 | if (fs) { | 158 | get_fs_root(task->fs, root); |
159 | read_lock(&fs->lock); | ||
160 | *path = root ? fs->root : fs->pwd; | ||
161 | path_get(path); | ||
162 | read_unlock(&fs->lock); | ||
163 | result = 0; | 159 | result = 0; |
164 | } | 160 | } |
165 | task_unlock(task); | 161 | task_unlock(task); |
@@ -172,7 +168,12 @@ static int proc_cwd_link(struct inode *inode, struct path *path) | |||
172 | int result = -ENOENT; | 168 | int result = -ENOENT; |
173 | 169 | ||
174 | if (task) { | 170 | if (task) { |
175 | result = get_fs_path(task, path, 0); | 171 | task_lock(task); |
172 | if (task->fs) { | ||
173 | get_fs_pwd(task->fs, path); | ||
174 | result = 0; | ||
175 | } | ||
176 | task_unlock(task); | ||
176 | put_task_struct(task); | 177 | put_task_struct(task); |
177 | } | 178 | } |
178 | return result; | 179 | return result; |
@@ -184,7 +185,7 @@ static int proc_root_link(struct inode *inode, struct path *path) | |||
184 | int result = -ENOENT; | 185 | int result = -ENOENT; |
185 | 186 | ||
186 | if (task) { | 187 | if (task) { |
187 | result = get_fs_path(task, path, 1); | 188 | result = get_task_root(task, path); |
188 | put_task_struct(task); | 189 | put_task_struct(task); |
189 | } | 190 | } |
190 | return result; | 191 | return result; |
@@ -427,17 +428,14 @@ static const struct file_operations proc_lstats_operations = { | |||
427 | 428 | ||
428 | #endif | 429 | #endif |
429 | 430 | ||
430 | /* The badness from the OOM killer */ | ||
431 | unsigned long badness(struct task_struct *p, unsigned long uptime); | ||
432 | static int proc_oom_score(struct task_struct *task, char *buffer) | 431 | static int proc_oom_score(struct task_struct *task, char *buffer) |
433 | { | 432 | { |
434 | unsigned long points = 0; | 433 | unsigned long points = 0; |
435 | struct timespec uptime; | ||
436 | 434 | ||
437 | do_posix_clock_monotonic_gettime(&uptime); | ||
438 | read_lock(&tasklist_lock); | 435 | read_lock(&tasklist_lock); |
439 | if (pid_alive(task)) | 436 | if (pid_alive(task)) |
440 | points = badness(task, uptime.tv_sec); | 437 | points = oom_badness(task, NULL, NULL, |
438 | totalram_pages + total_swap_pages); | ||
441 | read_unlock(&tasklist_lock); | 439 | read_unlock(&tasklist_lock); |
442 | return sprintf(buffer, "%lu\n", points); | 440 | return sprintf(buffer, "%lu\n", points); |
443 | } | 441 | } |
@@ -561,9 +559,19 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr) | |||
561 | return -EPERM; | 559 | return -EPERM; |
562 | 560 | ||
563 | error = inode_change_ok(inode, attr); | 561 | error = inode_change_ok(inode, attr); |
564 | if (!error) | 562 | if (error) |
565 | error = inode_setattr(inode, attr); | 563 | return error; |
566 | return error; | 564 | |
565 | if ((attr->ia_valid & ATTR_SIZE) && | ||
566 | attr->ia_size != i_size_read(inode)) { | ||
567 | error = vmtruncate(inode, attr->ia_size); | ||
568 | if (error) | ||
569 | return error; | ||
570 | } | ||
571 | |||
572 | setattr_copy(inode, attr); | ||
573 | mark_inode_dirty(inode); | ||
574 | return 0; | ||
567 | } | 575 | } |
568 | 576 | ||
569 | static const struct inode_operations proc_def_inode_operations = { | 577 | static const struct inode_operations proc_def_inode_operations = { |
@@ -589,7 +597,7 @@ static int mounts_open_common(struct inode *inode, struct file *file, | |||
589 | get_mnt_ns(ns); | 597 | get_mnt_ns(ns); |
590 | } | 598 | } |
591 | rcu_read_unlock(); | 599 | rcu_read_unlock(); |
592 | if (ns && get_fs_path(task, &root, 1) == 0) | 600 | if (ns && get_task_root(task, &root) == 0) |
593 | ret = 0; | 601 | ret = 0; |
594 | put_task_struct(task); | 602 | put_task_struct(task); |
595 | } | 603 | } |
@@ -1039,8 +1047,24 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
1039 | return -EACCES; | 1047 | return -EACCES; |
1040 | } | 1048 | } |
1041 | 1049 | ||
1050 | /* | ||
1051 | * Warn that /proc/pid/oom_adj is deprecated, see | ||
1052 | * Documentation/feature-removal-schedule.txt. | ||
1053 | */ | ||
1054 | printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, " | ||
1055 | "please use /proc/%d/oom_score_adj instead.\n", | ||
1056 | current->comm, task_pid_nr(current), | ||
1057 | task_pid_nr(task), task_pid_nr(task)); | ||
1042 | task->signal->oom_adj = oom_adjust; | 1058 | task->signal->oom_adj = oom_adjust; |
1043 | 1059 | /* | |
1060 | * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum | ||
1061 | * value is always attainable. | ||
1062 | */ | ||
1063 | if (task->signal->oom_adj == OOM_ADJUST_MAX) | ||
1064 | task->signal->oom_score_adj = OOM_SCORE_ADJ_MAX; | ||
1065 | else | ||
1066 | task->signal->oom_score_adj = (oom_adjust * OOM_SCORE_ADJ_MAX) / | ||
1067 | -OOM_DISABLE; | ||
1044 | unlock_task_sighand(task, &flags); | 1068 | unlock_task_sighand(task, &flags); |
1045 | put_task_struct(task); | 1069 | put_task_struct(task); |
1046 | 1070 | ||
@@ -1053,6 +1077,82 @@ static const struct file_operations proc_oom_adjust_operations = { | |||
1053 | .llseek = generic_file_llseek, | 1077 | .llseek = generic_file_llseek, |
1054 | }; | 1078 | }; |
1055 | 1079 | ||
1080 | static ssize_t oom_score_adj_read(struct file *file, char __user *buf, | ||
1081 | size_t count, loff_t *ppos) | ||
1082 | { | ||
1083 | struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); | ||
1084 | char buffer[PROC_NUMBUF]; | ||
1085 | int oom_score_adj = OOM_SCORE_ADJ_MIN; | ||
1086 | unsigned long flags; | ||
1087 | size_t len; | ||
1088 | |||
1089 | if (!task) | ||
1090 | return -ESRCH; | ||
1091 | if (lock_task_sighand(task, &flags)) { | ||
1092 | oom_score_adj = task->signal->oom_score_adj; | ||
1093 | unlock_task_sighand(task, &flags); | ||
1094 | } | ||
1095 | put_task_struct(task); | ||
1096 | len = snprintf(buffer, sizeof(buffer), "%d\n", oom_score_adj); | ||
1097 | return simple_read_from_buffer(buf, count, ppos, buffer, len); | ||
1098 | } | ||
1099 | |||
1100 | static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | ||
1101 | size_t count, loff_t *ppos) | ||
1102 | { | ||
1103 | struct task_struct *task; | ||
1104 | char buffer[PROC_NUMBUF]; | ||
1105 | unsigned long flags; | ||
1106 | long oom_score_adj; | ||
1107 | int err; | ||
1108 | |||
1109 | memset(buffer, 0, sizeof(buffer)); | ||
1110 | if (count > sizeof(buffer) - 1) | ||
1111 | count = sizeof(buffer) - 1; | ||
1112 | if (copy_from_user(buffer, buf, count)) | ||
1113 | return -EFAULT; | ||
1114 | |||
1115 | err = strict_strtol(strstrip(buffer), 0, &oom_score_adj); | ||
1116 | if (err) | ||
1117 | return -EINVAL; | ||
1118 | if (oom_score_adj < OOM_SCORE_ADJ_MIN || | ||
1119 | oom_score_adj > OOM_SCORE_ADJ_MAX) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | task = get_proc_task(file->f_path.dentry->d_inode); | ||
1123 | if (!task) | ||
1124 | return -ESRCH; | ||
1125 | if (!lock_task_sighand(task, &flags)) { | ||
1126 | put_task_struct(task); | ||
1127 | return -ESRCH; | ||
1128 | } | ||
1129 | if (oom_score_adj < task->signal->oom_score_adj && | ||
1130 | !capable(CAP_SYS_RESOURCE)) { | ||
1131 | unlock_task_sighand(task, &flags); | ||
1132 | put_task_struct(task); | ||
1133 | return -EACCES; | ||
1134 | } | ||
1135 | |||
1136 | task->signal->oom_score_adj = oom_score_adj; | ||
1137 | /* | ||
1138 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is | ||
1139 | * always attainable. | ||
1140 | */ | ||
1141 | if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) | ||
1142 | task->signal->oom_adj = OOM_DISABLE; | ||
1143 | else | ||
1144 | task->signal->oom_adj = (oom_score_adj * OOM_ADJUST_MAX) / | ||
1145 | OOM_SCORE_ADJ_MAX; | ||
1146 | unlock_task_sighand(task, &flags); | ||
1147 | put_task_struct(task); | ||
1148 | return count; | ||
1149 | } | ||
1150 | |||
1151 | static const struct file_operations proc_oom_score_adj_operations = { | ||
1152 | .read = oom_score_adj_read, | ||
1153 | .write = oom_score_adj_write, | ||
1154 | }; | ||
1155 | |||
1056 | #ifdef CONFIG_AUDITSYSCALL | 1156 | #ifdef CONFIG_AUDITSYSCALL |
1057 | #define TMPBUFLEN 21 | 1157 | #define TMPBUFLEN 21 |
1058 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | 1158 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, |
@@ -1426,7 +1526,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) | |||
1426 | if (!tmp) | 1526 | if (!tmp) |
1427 | return -ENOMEM; | 1527 | return -ENOMEM; |
1428 | 1528 | ||
1429 | pathname = d_path(path, tmp, PAGE_SIZE); | 1529 | pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE); |
1430 | len = PTR_ERR(pathname); | 1530 | len = PTR_ERR(pathname); |
1431 | if (IS_ERR(pathname)) | 1531 | if (IS_ERR(pathname)) |
1432 | goto out; | 1532 | goto out; |
@@ -2625,6 +2725,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2625 | #endif | 2725 | #endif |
2626 | INF("oom_score", S_IRUGO, proc_oom_score), | 2726 | INF("oom_score", S_IRUGO, proc_oom_score), |
2627 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), | 2727 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), |
2728 | REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), | ||
2628 | #ifdef CONFIG_AUDITSYSCALL | 2729 | #ifdef CONFIG_AUDITSYSCALL |
2629 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), | 2730 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
2630 | REG("sessionid", S_IRUGO, proc_sessionid_operations), | 2731 | REG("sessionid", S_IRUGO, proc_sessionid_operations), |
@@ -2959,6 +3060,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2959 | #endif | 3060 | #endif |
2960 | INF("oom_score", S_IRUGO, proc_oom_score), | 3061 | INF("oom_score", S_IRUGO, proc_oom_score), |
2961 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), | 3062 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), |
3063 | REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), | ||
2962 | #ifdef CONFIG_AUDITSYSCALL | 3064 | #ifdef CONFIG_AUDITSYSCALL |
2963 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), | 3065 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
2964 | REG("sessionid", S_IRUSR, proc_sessionid_operations), | 3066 | REG("sessionid", S_IRUSR, proc_sessionid_operations), |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 2791907744ed..dd29f0337661 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/mm.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
17 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
@@ -258,17 +259,22 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | |||
258 | 259 | ||
259 | error = inode_change_ok(inode, iattr); | 260 | error = inode_change_ok(inode, iattr); |
260 | if (error) | 261 | if (error) |
261 | goto out; | 262 | return error; |
262 | 263 | ||
263 | error = inode_setattr(inode, iattr); | 264 | if ((iattr->ia_valid & ATTR_SIZE) && |
264 | if (error) | 265 | iattr->ia_size != i_size_read(inode)) { |
265 | goto out; | 266 | error = vmtruncate(inode, iattr->ia_size); |
267 | if (error) | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | setattr_copy(inode, iattr); | ||
272 | mark_inode_dirty(inode); | ||
266 | 273 | ||
267 | de->uid = inode->i_uid; | 274 | de->uid = inode->i_uid; |
268 | de->gid = inode->i_gid; | 275 | de->gid = inode->i_gid; |
269 | de->mode = inode->i_mode; | 276 | de->mode = inode->i_mode; |
270 | out: | 277 | return 0; |
271 | return error; | ||
272 | } | 278 | } |
273 | 279 | ||
274 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, | 280 | static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index aea8502e58a3..9c2b5f484879 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -25,11 +25,12 @@ | |||
25 | 25 | ||
26 | #include "internal.h" | 26 | #include "internal.h" |
27 | 27 | ||
28 | static void proc_delete_inode(struct inode *inode) | 28 | static void proc_evict_inode(struct inode *inode) |
29 | { | 29 | { |
30 | struct proc_dir_entry *de; | 30 | struct proc_dir_entry *de; |
31 | 31 | ||
32 | truncate_inode_pages(&inode->i_data, 0); | 32 | truncate_inode_pages(&inode->i_data, 0); |
33 | end_writeback(inode); | ||
33 | 34 | ||
34 | /* Stop tracking associated processes */ | 35 | /* Stop tracking associated processes */ |
35 | put_pid(PROC_I(inode)->pid); | 36 | put_pid(PROC_I(inode)->pid); |
@@ -40,7 +41,6 @@ static void proc_delete_inode(struct inode *inode) | |||
40 | pde_put(de); | 41 | pde_put(de); |
41 | if (PROC_I(inode)->sysctl) | 42 | if (PROC_I(inode)->sysctl) |
42 | sysctl_head_put(PROC_I(inode)->sysctl); | 43 | sysctl_head_put(PROC_I(inode)->sysctl); |
43 | clear_inode(inode); | ||
44 | } | 44 | } |
45 | 45 | ||
46 | struct vfsmount *proc_mnt; | 46 | struct vfsmount *proc_mnt; |
@@ -91,7 +91,7 @@ static const struct super_operations proc_sops = { | |||
91 | .alloc_inode = proc_alloc_inode, | 91 | .alloc_inode = proc_alloc_inode, |
92 | .destroy_inode = proc_destroy_inode, | 92 | .destroy_inode = proc_destroy_inode, |
93 | .drop_inode = generic_delete_inode, | 93 | .drop_inode = generic_delete_inode, |
94 | .delete_inode = proc_delete_inode, | 94 | .evict_inode = proc_evict_inode, |
95 | .statfs = simple_statfs, | 95 | .statfs = simple_statfs, |
96 | }; | 96 | }; |
97 | 97 | ||
@@ -214,8 +214,7 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne | |||
214 | { | 214 | { |
215 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | 215 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); |
216 | long rv = -ENOTTY; | 216 | long rv = -ENOTTY; |
217 | long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long); | 217 | long (*ioctl)(struct file *, unsigned int, unsigned long); |
218 | int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long); | ||
219 | 218 | ||
220 | spin_lock(&pde->pde_unload_lock); | 219 | spin_lock(&pde->pde_unload_lock); |
221 | if (!pde->proc_fops) { | 220 | if (!pde->proc_fops) { |
@@ -223,19 +222,11 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne | |||
223 | return rv; | 222 | return rv; |
224 | } | 223 | } |
225 | pde->pde_users++; | 224 | pde->pde_users++; |
226 | unlocked_ioctl = pde->proc_fops->unlocked_ioctl; | 225 | ioctl = pde->proc_fops->unlocked_ioctl; |
227 | ioctl = pde->proc_fops->ioctl; | ||
228 | spin_unlock(&pde->pde_unload_lock); | 226 | spin_unlock(&pde->pde_unload_lock); |
229 | 227 | ||
230 | if (unlocked_ioctl) { | 228 | if (ioctl) |
231 | rv = unlocked_ioctl(file, cmd, arg); | 229 | rv = ioctl(file, cmd, arg); |
232 | if (rv == -ENOIOCTLCMD) | ||
233 | rv = -EINVAL; | ||
234 | } else if (ioctl) { | ||
235 | WARN_ONCE(1, "Procfs ioctl handlers must use unlocked_ioctl, " | ||
236 | "%pf will be called without the Bkl held\n", ioctl); | ||
237 | rv = ioctl(file->f_path.dentry->d_inode, file, cmd, arg); | ||
238 | } | ||
239 | 230 | ||
240 | pde_users_dec(pde); | 231 | pde_users_dec(pde); |
241 | return rv; | 232 | return rv; |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 6ff9981f0a18..5be436ea088e 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -329,10 +329,19 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) | |||
329 | return -EPERM; | 329 | return -EPERM; |
330 | 330 | ||
331 | error = inode_change_ok(inode, attr); | 331 | error = inode_change_ok(inode, attr); |
332 | if (!error) | 332 | if (error) |
333 | error = inode_setattr(inode, attr); | 333 | return error; |
334 | |||
335 | if ((attr->ia_valid & ATTR_SIZE) && | ||
336 | attr->ia_size != i_size_read(inode)) { | ||
337 | error = vmtruncate(inode, attr->ia_size); | ||
338 | if (error) | ||
339 | return error; | ||
340 | } | ||
334 | 341 | ||
335 | return error; | 342 | setattr_copy(inode, attr); |
343 | mark_inode_dirty(inode); | ||
344 | return 0; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 347 | static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |