diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 160 | ||||
-rw-r--r-- | fs/proc/base.c | 132 | ||||
-rw-r--r-- | fs/proc/generic.c | 74 | ||||
-rw-r--r-- | fs/proc/inode.c | 61 | ||||
-rw-r--r-- | fs/proc/internal.h | 17 | ||||
-rw-r--r-- | fs/proc/kcore.c | 1 | ||||
-rw-r--r-- | fs/proc/nommu.c | 4 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 36 | ||||
-rw-r--r-- | fs/proc/proc_net.c | 7 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 6 | ||||
-rw-r--r-- | fs/proc/proc_tty.c | 5 | ||||
-rw-r--r-- | fs/proc/root.c | 1 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 22 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 13 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 1 |
15 files changed, 307 insertions, 233 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 6ba2746e4517..07d6c4853fe8 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -77,6 +77,7 @@ | |||
77 | #include <linux/cpuset.h> | 77 | #include <linux/cpuset.h> |
78 | #include <linux/rcupdate.h> | 78 | #include <linux/rcupdate.h> |
79 | #include <linux/delayacct.h> | 79 | #include <linux/delayacct.h> |
80 | #include <linux/seq_file.h> | ||
80 | #include <linux/pid_namespace.h> | 81 | #include <linux/pid_namespace.h> |
81 | 82 | ||
82 | #include <asm/pgtable.h> | 83 | #include <asm/pgtable.h> |
@@ -88,18 +89,21 @@ | |||
88 | do { memcpy(buffer, string, strlen(string)); \ | 89 | do { memcpy(buffer, string, strlen(string)); \ |
89 | buffer += strlen(string); } while (0) | 90 | buffer += strlen(string); } while (0) |
90 | 91 | ||
91 | static inline char *task_name(struct task_struct *p, char *buf) | 92 | static inline void task_name(struct seq_file *m, struct task_struct *p) |
92 | { | 93 | { |
93 | int i; | 94 | int i; |
95 | char *buf, *end; | ||
94 | char *name; | 96 | char *name; |
95 | char tcomm[sizeof(p->comm)]; | 97 | char tcomm[sizeof(p->comm)]; |
96 | 98 | ||
97 | get_task_comm(tcomm, p); | 99 | get_task_comm(tcomm, p); |
98 | 100 | ||
99 | ADDBUF(buf, "Name:\t"); | 101 | seq_printf(m, "Name:\t"); |
102 | end = m->buf + m->size; | ||
103 | buf = m->buf + m->count; | ||
100 | name = tcomm; | 104 | name = tcomm; |
101 | i = sizeof(tcomm); | 105 | i = sizeof(tcomm); |
102 | do { | 106 | while (i && (buf < end)) { |
103 | unsigned char c = *name; | 107 | unsigned char c = *name; |
104 | name++; | 108 | name++; |
105 | i--; | 109 | i--; |
@@ -107,20 +111,21 @@ static inline char *task_name(struct task_struct *p, char *buf) | |||
107 | if (!c) | 111 | if (!c) |
108 | break; | 112 | break; |
109 | if (c == '\\') { | 113 | if (c == '\\') { |
110 | buf[1] = c; | 114 | buf++; |
111 | buf += 2; | 115 | if (buf < end) |
116 | *buf++ = c; | ||
112 | continue; | 117 | continue; |
113 | } | 118 | } |
114 | if (c == '\n') { | 119 | if (c == '\n') { |
115 | buf[0] = '\\'; | 120 | *buf++ = '\\'; |
116 | buf[1] = 'n'; | 121 | if (buf < end) |
117 | buf += 2; | 122 | *buf++ = 'n'; |
118 | continue; | 123 | continue; |
119 | } | 124 | } |
120 | buf++; | 125 | buf++; |
121 | } while (i); | 126 | } |
122 | *buf = '\n'; | 127 | m->count = buf - m->buf; |
123 | return buf+1; | 128 | seq_printf(m, "\n"); |
124 | } | 129 | } |
125 | 130 | ||
126 | /* | 131 | /* |
@@ -151,21 +156,20 @@ static inline const char *get_task_state(struct task_struct *tsk) | |||
151 | return *p; | 156 | return *p; |
152 | } | 157 | } |
153 | 158 | ||
154 | static inline char *task_state(struct task_struct *p, char *buffer) | 159 | static inline void task_state(struct seq_file *m, struct pid_namespace *ns, |
160 | struct pid *pid, struct task_struct *p) | ||
155 | { | 161 | { |
156 | struct group_info *group_info; | 162 | struct group_info *group_info; |
157 | int g; | 163 | int g; |
158 | struct fdtable *fdt = NULL; | 164 | struct fdtable *fdt = NULL; |
159 | struct pid_namespace *ns; | ||
160 | pid_t ppid, tpid; | 165 | pid_t ppid, tpid; |
161 | 166 | ||
162 | ns = current->nsproxy->pid_ns; | ||
163 | rcu_read_lock(); | 167 | rcu_read_lock(); |
164 | ppid = pid_alive(p) ? | 168 | ppid = pid_alive(p) ? |
165 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; | 169 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; |
166 | tpid = pid_alive(p) && p->ptrace ? | 170 | tpid = pid_alive(p) && p->ptrace ? |
167 | task_pid_nr_ns(rcu_dereference(p->parent), ns) : 0; | 171 | task_pid_nr_ns(rcu_dereference(p->parent), ns) : 0; |
168 | buffer += sprintf(buffer, | 172 | seq_printf(m, |
169 | "State:\t%s\n" | 173 | "State:\t%s\n" |
170 | "Tgid:\t%d\n" | 174 | "Tgid:\t%d\n" |
171 | "Pid:\t%d\n" | 175 | "Pid:\t%d\n" |
@@ -175,7 +179,7 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
175 | "Gid:\t%d\t%d\t%d\t%d\n", | 179 | "Gid:\t%d\t%d\t%d\t%d\n", |
176 | get_task_state(p), | 180 | get_task_state(p), |
177 | task_tgid_nr_ns(p, ns), | 181 | task_tgid_nr_ns(p, ns), |
178 | task_pid_nr_ns(p, ns), | 182 | pid_nr_ns(pid, ns), |
179 | ppid, tpid, | 183 | ppid, tpid, |
180 | p->uid, p->euid, p->suid, p->fsuid, | 184 | p->uid, p->euid, p->suid, p->fsuid, |
181 | p->gid, p->egid, p->sgid, p->fsgid); | 185 | p->gid, p->egid, p->sgid, p->fsgid); |
@@ -183,7 +187,7 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
183 | task_lock(p); | 187 | task_lock(p); |
184 | if (p->files) | 188 | if (p->files) |
185 | fdt = files_fdtable(p->files); | 189 | fdt = files_fdtable(p->files); |
186 | buffer += sprintf(buffer, | 190 | seq_printf(m, |
187 | "FDSize:\t%d\n" | 191 | "FDSize:\t%d\n" |
188 | "Groups:\t", | 192 | "Groups:\t", |
189 | fdt ? fdt->max_fds : 0); | 193 | fdt ? fdt->max_fds : 0); |
@@ -194,20 +198,18 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
194 | task_unlock(p); | 198 | task_unlock(p); |
195 | 199 | ||
196 | for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) | 200 | for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) |
197 | buffer += sprintf(buffer, "%d ", GROUP_AT(group_info, g)); | 201 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); |
198 | put_group_info(group_info); | 202 | put_group_info(group_info); |
199 | 203 | ||
200 | buffer += sprintf(buffer, "\n"); | 204 | seq_printf(m, "\n"); |
201 | return buffer; | ||
202 | } | 205 | } |
203 | 206 | ||
204 | static char *render_sigset_t(const char *header, sigset_t *set, char *buffer) | 207 | static void render_sigset_t(struct seq_file *m, const char *header, |
208 | sigset_t *set) | ||
205 | { | 209 | { |
206 | int i, len; | 210 | int i; |
207 | 211 | ||
208 | len = strlen(header); | 212 | seq_printf(m, "%s", header); |
209 | memcpy(buffer, header, len); | ||
210 | buffer += len; | ||
211 | 213 | ||
212 | i = _NSIG; | 214 | i = _NSIG; |
213 | do { | 215 | do { |
@@ -218,12 +220,10 @@ static char *render_sigset_t(const char *header, sigset_t *set, char *buffer) | |||
218 | if (sigismember(set, i+2)) x |= 2; | 220 | if (sigismember(set, i+2)) x |= 2; |
219 | if (sigismember(set, i+3)) x |= 4; | 221 | if (sigismember(set, i+3)) x |= 4; |
220 | if (sigismember(set, i+4)) x |= 8; | 222 | if (sigismember(set, i+4)) x |= 8; |
221 | *buffer++ = (x < 10 ? '0' : 'a' - 10) + x; | 223 | seq_printf(m, "%x", x); |
222 | } while (i >= 4); | 224 | } while (i >= 4); |
223 | 225 | ||
224 | *buffer++ = '\n'; | 226 | seq_printf(m, "\n"); |
225 | *buffer = 0; | ||
226 | return buffer; | ||
227 | } | 227 | } |
228 | 228 | ||
229 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, | 229 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, |
@@ -241,7 +241,7 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, | |||
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
244 | static inline char *task_sig(struct task_struct *p, char *buffer) | 244 | static inline void task_sig(struct seq_file *m, struct task_struct *p) |
245 | { | 245 | { |
246 | unsigned long flags; | 246 | unsigned long flags; |
247 | sigset_t pending, shpending, blocked, ignored, caught; | 247 | sigset_t pending, shpending, blocked, ignored, caught; |
@@ -268,67 +268,66 @@ static inline char *task_sig(struct task_struct *p, char *buffer) | |||
268 | } | 268 | } |
269 | rcu_read_unlock(); | 269 | rcu_read_unlock(); |
270 | 270 | ||
271 | buffer += sprintf(buffer, "Threads:\t%d\n", num_threads); | 271 | seq_printf(m, "Threads:\t%d\n", num_threads); |
272 | buffer += sprintf(buffer, "SigQ:\t%lu/%lu\n", qsize, qlim); | 272 | seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim); |
273 | 273 | ||
274 | /* render them all */ | 274 | /* render them all */ |
275 | buffer = render_sigset_t("SigPnd:\t", &pending, buffer); | 275 | render_sigset_t(m, "SigPnd:\t", &pending); |
276 | buffer = render_sigset_t("ShdPnd:\t", &shpending, buffer); | 276 | render_sigset_t(m, "ShdPnd:\t", &shpending); |
277 | buffer = render_sigset_t("SigBlk:\t", &blocked, buffer); | 277 | render_sigset_t(m, "SigBlk:\t", &blocked); |
278 | buffer = render_sigset_t("SigIgn:\t", &ignored, buffer); | 278 | render_sigset_t(m, "SigIgn:\t", &ignored); |
279 | buffer = render_sigset_t("SigCgt:\t", &caught, buffer); | 279 | render_sigset_t(m, "SigCgt:\t", &caught); |
280 | |||
281 | return buffer; | ||
282 | } | 280 | } |
283 | 281 | ||
284 | static char *render_cap_t(const char *header, kernel_cap_t *a, char *buffer) | 282 | static void render_cap_t(struct seq_file *m, const char *header, |
283 | kernel_cap_t *a) | ||
285 | { | 284 | { |
286 | unsigned __capi; | 285 | unsigned __capi; |
287 | 286 | ||
288 | buffer += sprintf(buffer, "%s", header); | 287 | seq_printf(m, "%s", header); |
289 | CAP_FOR_EACH_U32(__capi) { | 288 | CAP_FOR_EACH_U32(__capi) { |
290 | buffer += sprintf(buffer, "%08x", | 289 | seq_printf(m, "%08x", |
291 | a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]); | 290 | a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]); |
292 | } | 291 | } |
293 | return buffer + sprintf(buffer, "\n"); | 292 | seq_printf(m, "\n"); |
294 | } | 293 | } |
295 | 294 | ||
296 | static inline char *task_cap(struct task_struct *p, char *buffer) | 295 | static inline void task_cap(struct seq_file *m, struct task_struct *p) |
297 | { | 296 | { |
298 | buffer = render_cap_t("CapInh:\t", &p->cap_inheritable, buffer); | 297 | render_cap_t(m, "CapInh:\t", &p->cap_inheritable); |
299 | buffer = render_cap_t("CapPrm:\t", &p->cap_permitted, buffer); | 298 | render_cap_t(m, "CapPrm:\t", &p->cap_permitted); |
300 | return render_cap_t("CapEff:\t", &p->cap_effective, buffer); | 299 | render_cap_t(m, "CapEff:\t", &p->cap_effective); |
301 | } | 300 | } |
302 | 301 | ||
303 | static inline char *task_context_switch_counts(struct task_struct *p, | 302 | static inline void task_context_switch_counts(struct seq_file *m, |
304 | char *buffer) | 303 | struct task_struct *p) |
305 | { | 304 | { |
306 | return buffer + sprintf(buffer, "voluntary_ctxt_switches:\t%lu\n" | 305 | seq_printf(m, "voluntary_ctxt_switches:\t%lu\n" |
307 | "nonvoluntary_ctxt_switches:\t%lu\n", | 306 | "nonvoluntary_ctxt_switches:\t%lu\n", |
308 | p->nvcsw, | 307 | p->nvcsw, |
309 | p->nivcsw); | 308 | p->nivcsw); |
310 | } | 309 | } |
311 | 310 | ||
312 | int proc_pid_status(struct task_struct *task, char *buffer) | 311 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
312 | struct pid *pid, struct task_struct *task) | ||
313 | { | 313 | { |
314 | char *orig = buffer; | ||
315 | struct mm_struct *mm = get_task_mm(task); | 314 | struct mm_struct *mm = get_task_mm(task); |
316 | 315 | ||
317 | buffer = task_name(task, buffer); | 316 | task_name(m, task); |
318 | buffer = task_state(task, buffer); | 317 | task_state(m, ns, pid, task); |
319 | 318 | ||
320 | if (mm) { | 319 | if (mm) { |
321 | buffer = task_mem(mm, buffer); | 320 | task_mem(m, mm); |
322 | mmput(mm); | 321 | mmput(mm); |
323 | } | 322 | } |
324 | buffer = task_sig(task, buffer); | 323 | task_sig(m, task); |
325 | buffer = task_cap(task, buffer); | 324 | task_cap(m, task); |
326 | buffer = cpuset_task_status_allowed(task, buffer); | 325 | cpuset_task_status_allowed(m, task); |
327 | #if defined(CONFIG_S390) | 326 | #if defined(CONFIG_S390) |
328 | buffer = task_show_regs(task, buffer); | 327 | task_show_regs(m, task); |
329 | #endif | 328 | #endif |
330 | buffer = task_context_switch_counts(task, buffer); | 329 | task_context_switch_counts(m, task); |
331 | return buffer - orig; | 330 | return 0; |
332 | } | 331 | } |
333 | 332 | ||
334 | /* | 333 | /* |
@@ -390,14 +389,14 @@ static cputime_t task_gtime(struct task_struct *p) | |||
390 | return p->gtime; | 389 | return p->gtime; |
391 | } | 390 | } |
392 | 391 | ||
393 | static int do_task_stat(struct task_struct *task, char *buffer, int whole) | 392 | static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, |
393 | struct pid *pid, struct task_struct *task, int whole) | ||
394 | { | 394 | { |
395 | unsigned long vsize, eip, esp, wchan = ~0UL; | 395 | unsigned long vsize, eip, esp, wchan = ~0UL; |
396 | long priority, nice; | 396 | long priority, nice; |
397 | int tty_pgrp = -1, tty_nr = 0; | 397 | int tty_pgrp = -1, tty_nr = 0; |
398 | sigset_t sigign, sigcatch; | 398 | sigset_t sigign, sigcatch; |
399 | char state; | 399 | char state; |
400 | int res; | ||
401 | pid_t ppid = 0, pgid = -1, sid = -1; | 400 | pid_t ppid = 0, pgid = -1, sid = -1; |
402 | int num_threads = 0; | 401 | int num_threads = 0; |
403 | struct mm_struct *mm; | 402 | struct mm_struct *mm; |
@@ -409,9 +408,6 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
409 | unsigned long rsslim = 0; | 408 | unsigned long rsslim = 0; |
410 | char tcomm[sizeof(task->comm)]; | 409 | char tcomm[sizeof(task->comm)]; |
411 | unsigned long flags; | 410 | unsigned long flags; |
412 | struct pid_namespace *ns; | ||
413 | |||
414 | ns = current->nsproxy->pid_ns; | ||
415 | 411 | ||
416 | state = *get_task_state(task); | 412 | state = *get_task_state(task); |
417 | vsize = eip = esp = 0; | 413 | vsize = eip = esp = 0; |
@@ -498,10 +494,10 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
498 | /* convert nsec -> ticks */ | 494 | /* convert nsec -> ticks */ |
499 | start_time = nsec_to_clock_t(start_time); | 495 | start_time = nsec_to_clock_t(start_time); |
500 | 496 | ||
501 | res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ | 497 | seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \ |
502 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ | 498 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ |
503 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", | 499 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", |
504 | task_pid_nr_ns(task, ns), | 500 | pid_nr_ns(pid, ns), |
505 | tcomm, | 501 | tcomm, |
506 | state, | 502 | state, |
507 | ppid, | 503 | ppid, |
@@ -550,20 +546,23 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
550 | cputime_to_clock_t(cgtime)); | 546 | cputime_to_clock_t(cgtime)); |
551 | if (mm) | 547 | if (mm) |
552 | mmput(mm); | 548 | mmput(mm); |
553 | return res; | 549 | return 0; |
554 | } | 550 | } |
555 | 551 | ||
556 | int proc_tid_stat(struct task_struct *task, char *buffer) | 552 | int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, |
553 | struct pid *pid, struct task_struct *task) | ||
557 | { | 554 | { |
558 | return do_task_stat(task, buffer, 0); | 555 | return do_task_stat(m, ns, pid, task, 0); |
559 | } | 556 | } |
560 | 557 | ||
561 | int proc_tgid_stat(struct task_struct *task, char *buffer) | 558 | int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, |
559 | struct pid *pid, struct task_struct *task) | ||
562 | { | 560 | { |
563 | return do_task_stat(task, buffer, 1); | 561 | return do_task_stat(m, ns, pid, task, 1); |
564 | } | 562 | } |
565 | 563 | ||
566 | int proc_pid_statm(struct task_struct *task, char *buffer) | 564 | int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, |
565 | struct pid *pid, struct task_struct *task) | ||
567 | { | 566 | { |
568 | int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0; | 567 | int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0; |
569 | struct mm_struct *mm = get_task_mm(task); | 568 | struct mm_struct *mm = get_task_mm(task); |
@@ -572,7 +571,8 @@ int proc_pid_statm(struct task_struct *task, char *buffer) | |||
572 | size = task_statm(mm, &shared, &text, &data, &resident); | 571 | size = task_statm(mm, &shared, &text, &data, &resident); |
573 | mmput(mm); | 572 | mmput(mm); |
574 | } | 573 | } |
574 | seq_printf(m, "%d %d %d %d %d %d %d\n", | ||
575 | size, resident, shared, text, lib, data, 0); | ||
575 | 576 | ||
576 | return sprintf(buffer, "%d %d %d %d %d %d %d\n", | 577 | return 0; |
577 | size, resident, shared, text, lib, data, 0); | ||
578 | } | 578 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index c59852b38787..88f8edf18258 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -121,6 +121,10 @@ struct pid_entry { | |||
121 | NOD(NAME, (S_IFREG|(MODE)), \ | 121 | NOD(NAME, (S_IFREG|(MODE)), \ |
122 | NULL, &proc_info_file_operations, \ | 122 | NULL, &proc_info_file_operations, \ |
123 | { .proc_read = &proc_##OTYPE } ) | 123 | { .proc_read = &proc_##OTYPE } ) |
124 | #define ONE(NAME, MODE, OTYPE) \ | ||
125 | NOD(NAME, (S_IFREG|(MODE)), \ | ||
126 | NULL, &proc_single_file_operations, \ | ||
127 | { .proc_show = &proc_##OTYPE } ) | ||
124 | 128 | ||
125 | int maps_protect; | 129 | int maps_protect; |
126 | EXPORT_SYMBOL(maps_protect); | 130 | EXPORT_SYMBOL(maps_protect); |
@@ -149,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk) | |||
149 | return count; | 153 | return count; |
150 | } | 154 | } |
151 | 155 | ||
152 | static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 156 | static int proc_cwd_link(struct inode *inode, struct path *path) |
153 | { | 157 | { |
154 | struct task_struct *task = get_proc_task(inode); | 158 | struct task_struct *task = get_proc_task(inode); |
155 | struct fs_struct *fs = NULL; | 159 | struct fs_struct *fs = NULL; |
@@ -161,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs | |||
161 | } | 165 | } |
162 | if (fs) { | 166 | if (fs) { |
163 | read_lock(&fs->lock); | 167 | read_lock(&fs->lock); |
164 | *mnt = mntget(fs->pwdmnt); | 168 | *path = fs->pwd; |
165 | *dentry = dget(fs->pwd); | 169 | path_get(&fs->pwd); |
166 | read_unlock(&fs->lock); | 170 | read_unlock(&fs->lock); |
167 | result = 0; | 171 | result = 0; |
168 | put_fs_struct(fs); | 172 | put_fs_struct(fs); |
@@ -170,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs | |||
170 | return result; | 174 | return result; |
171 | } | 175 | } |
172 | 176 | ||
173 | static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 177 | static int proc_root_link(struct inode *inode, struct path *path) |
174 | { | 178 | { |
175 | struct task_struct *task = get_proc_task(inode); | 179 | struct task_struct *task = get_proc_task(inode); |
176 | struct fs_struct *fs = NULL; | 180 | struct fs_struct *fs = NULL; |
@@ -182,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
182 | } | 186 | } |
183 | if (fs) { | 187 | if (fs) { |
184 | read_lock(&fs->lock); | 188 | read_lock(&fs->lock); |
185 | *mnt = mntget(fs->rootmnt); | 189 | *path = fs->root; |
186 | *dentry = dget(fs->root); | 190 | path_get(&fs->root); |
187 | read_unlock(&fs->lock); | 191 | read_unlock(&fs->lock); |
188 | result = 0; | 192 | result = 0; |
189 | put_fs_struct(fs); | 193 | put_fs_struct(fs); |
@@ -502,7 +506,7 @@ static const struct inode_operations proc_def_inode_operations = { | |||
502 | .setattr = proc_setattr, | 506 | .setattr = proc_setattr, |
503 | }; | 507 | }; |
504 | 508 | ||
505 | extern struct seq_operations mounts_op; | 509 | extern const struct seq_operations mounts_op; |
506 | struct proc_mounts { | 510 | struct proc_mounts { |
507 | struct seq_file m; | 511 | struct seq_file m; |
508 | int event; | 512 | int event; |
@@ -581,7 +585,7 @@ static const struct file_operations proc_mounts_operations = { | |||
581 | .poll = mounts_poll, | 585 | .poll = mounts_poll, |
582 | }; | 586 | }; |
583 | 587 | ||
584 | extern struct seq_operations mountstats_op; | 588 | extern const struct seq_operations mountstats_op; |
585 | static int mountstats_open(struct inode *inode, struct file *file) | 589 | static int mountstats_open(struct inode *inode, struct file *file) |
586 | { | 590 | { |
587 | int ret = seq_open(file, &mountstats_op); | 591 | int ret = seq_open(file, &mountstats_op); |
@@ -658,6 +662,45 @@ static const struct file_operations proc_info_file_operations = { | |||
658 | .read = proc_info_read, | 662 | .read = proc_info_read, |
659 | }; | 663 | }; |
660 | 664 | ||
665 | static int proc_single_show(struct seq_file *m, void *v) | ||
666 | { | ||
667 | struct inode *inode = m->private; | ||
668 | struct pid_namespace *ns; | ||
669 | struct pid *pid; | ||
670 | struct task_struct *task; | ||
671 | int ret; | ||
672 | |||
673 | ns = inode->i_sb->s_fs_info; | ||
674 | pid = proc_pid(inode); | ||
675 | task = get_pid_task(pid, PIDTYPE_PID); | ||
676 | if (!task) | ||
677 | return -ESRCH; | ||
678 | |||
679 | ret = PROC_I(inode)->op.proc_show(m, ns, pid, task); | ||
680 | |||
681 | put_task_struct(task); | ||
682 | return ret; | ||
683 | } | ||
684 | |||
685 | static int proc_single_open(struct inode *inode, struct file *filp) | ||
686 | { | ||
687 | int ret; | ||
688 | ret = single_open(filp, proc_single_show, NULL); | ||
689 | if (!ret) { | ||
690 | struct seq_file *m = filp->private_data; | ||
691 | |||
692 | m->private = inode; | ||
693 | } | ||
694 | return ret; | ||
695 | } | ||
696 | |||
697 | static const struct file_operations proc_single_file_operations = { | ||
698 | .open = proc_single_open, | ||
699 | .read = seq_read, | ||
700 | .llseek = seq_lseek, | ||
701 | .release = single_release, | ||
702 | }; | ||
703 | |||
661 | static int mem_open(struct inode* inode, struct file* file) | 704 | static int mem_open(struct inode* inode, struct file* file) |
662 | { | 705 | { |
663 | file->private_data = (void*)((long)current->self_exec_id); | 706 | file->private_data = (void*)((long)current->self_exec_id); |
@@ -1121,39 +1164,36 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1121 | int error = -EACCES; | 1164 | int error = -EACCES; |
1122 | 1165 | ||
1123 | /* We don't need a base pointer in the /proc filesystem */ | 1166 | /* We don't need a base pointer in the /proc filesystem */ |
1124 | path_release(nd); | 1167 | path_put(&nd->path); |
1125 | 1168 | ||
1126 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1169 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1127 | if (!proc_fd_access_allowed(inode)) | 1170 | if (!proc_fd_access_allowed(inode)) |
1128 | goto out; | 1171 | goto out; |
1129 | 1172 | ||
1130 | error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); | 1173 | error = PROC_I(inode)->op.proc_get_link(inode, &nd->path); |
1131 | nd->last_type = LAST_BIND; | 1174 | nd->last_type = LAST_BIND; |
1132 | out: | 1175 | out: |
1133 | return ERR_PTR(error); | 1176 | return ERR_PTR(error); |
1134 | } | 1177 | } |
1135 | 1178 | ||
1136 | static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, | 1179 | static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) |
1137 | char __user *buffer, int buflen) | ||
1138 | { | 1180 | { |
1139 | struct inode * inode; | ||
1140 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); | 1181 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); |
1141 | char *path; | 1182 | char *pathname; |
1142 | int len; | 1183 | int len; |
1143 | 1184 | ||
1144 | if (!tmp) | 1185 | if (!tmp) |
1145 | return -ENOMEM; | 1186 | return -ENOMEM; |
1146 | 1187 | ||
1147 | inode = dentry->d_inode; | 1188 | pathname = d_path(path, tmp, PAGE_SIZE); |
1148 | path = d_path(dentry, mnt, tmp, PAGE_SIZE); | 1189 | len = PTR_ERR(pathname); |
1149 | len = PTR_ERR(path); | 1190 | if (IS_ERR(pathname)) |
1150 | if (IS_ERR(path)) | ||
1151 | goto out; | 1191 | goto out; |
1152 | len = tmp + PAGE_SIZE - 1 - path; | 1192 | len = tmp + PAGE_SIZE - 1 - pathname; |
1153 | 1193 | ||
1154 | if (len > buflen) | 1194 | if (len > buflen) |
1155 | len = buflen; | 1195 | len = buflen; |
1156 | if (copy_to_user(buffer, path, len)) | 1196 | if (copy_to_user(buffer, pathname, len)) |
1157 | len = -EFAULT; | 1197 | len = -EFAULT; |
1158 | out: | 1198 | out: |
1159 | free_page((unsigned long)tmp); | 1199 | free_page((unsigned long)tmp); |
@@ -1164,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b | |||
1164 | { | 1204 | { |
1165 | int error = -EACCES; | 1205 | int error = -EACCES; |
1166 | struct inode *inode = dentry->d_inode; | 1206 | struct inode *inode = dentry->d_inode; |
1167 | struct dentry *de; | 1207 | struct path path; |
1168 | struct vfsmount *mnt = NULL; | ||
1169 | 1208 | ||
1170 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1209 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1171 | if (!proc_fd_access_allowed(inode)) | 1210 | if (!proc_fd_access_allowed(inode)) |
1172 | goto out; | 1211 | goto out; |
1173 | 1212 | ||
1174 | error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); | 1213 | error = PROC_I(inode)->op.proc_get_link(inode, &path); |
1175 | if (error) | 1214 | if (error) |
1176 | goto out; | 1215 | goto out; |
1177 | 1216 | ||
1178 | error = do_proc_readlink(de, mnt, buffer, buflen); | 1217 | error = do_proc_readlink(&path, buffer, buflen); |
1179 | dput(de); | 1218 | path_put(&path); |
1180 | mntput(mnt); | ||
1181 | out: | 1219 | out: |
1182 | return error; | 1220 | return error; |
1183 | } | 1221 | } |
@@ -1404,8 +1442,7 @@ out: | |||
1404 | 1442 | ||
1405 | #define PROC_FDINFO_MAX 64 | 1443 | #define PROC_FDINFO_MAX 64 |
1406 | 1444 | ||
1407 | static int proc_fd_info(struct inode *inode, struct dentry **dentry, | 1445 | static int proc_fd_info(struct inode *inode, struct path *path, char *info) |
1408 | struct vfsmount **mnt, char *info) | ||
1409 | { | 1446 | { |
1410 | struct task_struct *task = get_proc_task(inode); | 1447 | struct task_struct *task = get_proc_task(inode); |
1411 | struct files_struct *files = NULL; | 1448 | struct files_struct *files = NULL; |
@@ -1424,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1424 | spin_lock(&files->file_lock); | 1461 | spin_lock(&files->file_lock); |
1425 | file = fcheck_files(files, fd); | 1462 | file = fcheck_files(files, fd); |
1426 | if (file) { | 1463 | if (file) { |
1427 | if (mnt) | 1464 | if (path) { |
1428 | *mnt = mntget(file->f_path.mnt); | 1465 | *path = file->f_path; |
1429 | if (dentry) | 1466 | path_get(&file->f_path); |
1430 | *dentry = dget(file->f_path.dentry); | 1467 | } |
1431 | if (info) | 1468 | if (info) |
1432 | snprintf(info, PROC_FDINFO_MAX, | 1469 | snprintf(info, PROC_FDINFO_MAX, |
1433 | "pos:\t%lli\n" | 1470 | "pos:\t%lli\n" |
@@ -1444,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1444 | return -ENOENT; | 1481 | return -ENOENT; |
1445 | } | 1482 | } |
1446 | 1483 | ||
1447 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, | 1484 | static int proc_fd_link(struct inode *inode, struct path *path) |
1448 | struct vfsmount **mnt) | ||
1449 | { | 1485 | { |
1450 | return proc_fd_info(inode, dentry, mnt, NULL); | 1486 | return proc_fd_info(inode, path, NULL); |
1451 | } | 1487 | } |
1452 | 1488 | ||
1453 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1489 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) |
@@ -1641,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, | |||
1641 | size_t len, loff_t *ppos) | 1677 | size_t len, loff_t *ppos) |
1642 | { | 1678 | { |
1643 | char tmp[PROC_FDINFO_MAX]; | 1679 | char tmp[PROC_FDINFO_MAX]; |
1644 | int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); | 1680 | int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp); |
1645 | if (!err) | 1681 | if (!err) |
1646 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); | 1682 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); |
1647 | return err; | 1683 | return err; |
@@ -2058,15 +2094,23 @@ static const struct file_operations proc_coredump_filter_operations = { | |||
2058 | static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | 2094 | static int proc_self_readlink(struct dentry *dentry, char __user *buffer, |
2059 | int buflen) | 2095 | int buflen) |
2060 | { | 2096 | { |
2097 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2098 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2061 | char tmp[PROC_NUMBUF]; | 2099 | char tmp[PROC_NUMBUF]; |
2062 | sprintf(tmp, "%d", task_tgid_vnr(current)); | 2100 | if (!tgid) |
2101 | return -ENOENT; | ||
2102 | sprintf(tmp, "%d", tgid); | ||
2063 | return vfs_readlink(dentry,buffer,buflen,tmp); | 2103 | return vfs_readlink(dentry,buffer,buflen,tmp); |
2064 | } | 2104 | } |
2065 | 2105 | ||
2066 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 2106 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
2067 | { | 2107 | { |
2108 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2109 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2068 | char tmp[PROC_NUMBUF]; | 2110 | char tmp[PROC_NUMBUF]; |
2069 | sprintf(tmp, "%d", task_tgid_vnr(current)); | 2111 | if (!tgid) |
2112 | return ERR_PTR(-ENOENT); | ||
2113 | sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); | ||
2070 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 2114 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
2071 | } | 2115 | } |
2072 | 2116 | ||
@@ -2231,14 +2275,14 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2231 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2275 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), |
2232 | REG("environ", S_IRUSR, environ), | 2276 | REG("environ", S_IRUSR, environ), |
2233 | INF("auxv", S_IRUSR, pid_auxv), | 2277 | INF("auxv", S_IRUSR, pid_auxv), |
2234 | INF("status", S_IRUGO, pid_status), | 2278 | ONE("status", S_IRUGO, pid_status), |
2235 | INF("limits", S_IRUSR, pid_limits), | 2279 | INF("limits", S_IRUSR, pid_limits), |
2236 | #ifdef CONFIG_SCHED_DEBUG | 2280 | #ifdef CONFIG_SCHED_DEBUG |
2237 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2281 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2238 | #endif | 2282 | #endif |
2239 | INF("cmdline", S_IRUGO, pid_cmdline), | 2283 | INF("cmdline", S_IRUGO, pid_cmdline), |
2240 | INF("stat", S_IRUGO, tgid_stat), | 2284 | ONE("stat", S_IRUGO, tgid_stat), |
2241 | INF("statm", S_IRUGO, pid_statm), | 2285 | ONE("statm", S_IRUGO, pid_statm), |
2242 | REG("maps", S_IRUGO, maps), | 2286 | REG("maps", S_IRUGO, maps), |
2243 | #ifdef CONFIG_NUMA | 2287 | #ifdef CONFIG_NUMA |
2244 | REG("numa_maps", S_IRUGO, numa_maps), | 2288 | REG("numa_maps", S_IRUGO, numa_maps), |
@@ -2562,14 +2606,14 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2562 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2606 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), |
2563 | REG("environ", S_IRUSR, environ), | 2607 | REG("environ", S_IRUSR, environ), |
2564 | INF("auxv", S_IRUSR, pid_auxv), | 2608 | INF("auxv", S_IRUSR, pid_auxv), |
2565 | INF("status", S_IRUGO, pid_status), | 2609 | ONE("status", S_IRUGO, pid_status), |
2566 | INF("limits", S_IRUSR, pid_limits), | 2610 | INF("limits", S_IRUSR, pid_limits), |
2567 | #ifdef CONFIG_SCHED_DEBUG | 2611 | #ifdef CONFIG_SCHED_DEBUG |
2568 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2612 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2569 | #endif | 2613 | #endif |
2570 | INF("cmdline", S_IRUGO, pid_cmdline), | 2614 | INF("cmdline", S_IRUGO, pid_cmdline), |
2571 | INF("stat", S_IRUGO, tid_stat), | 2615 | ONE("stat", S_IRUGO, tid_stat), |
2572 | INF("statm", S_IRUGO, pid_statm), | 2616 | ONE("statm", S_IRUGO, pid_statm), |
2573 | REG("maps", S_IRUGO, maps), | 2617 | REG("maps", S_IRUGO, maps), |
2574 | #ifdef CONFIG_NUMA | 2618 | #ifdef CONFIG_NUMA |
2575 | REG("numa_maps", S_IRUGO, numa_maps), | 2619 | REG("numa_maps", S_IRUGO, numa_maps), |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 6a2fe5187b62..68971e66cd41 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -25,12 +25,6 @@ | |||
25 | 25 | ||
26 | #include "internal.h" | 26 | #include "internal.h" |
27 | 27 | ||
28 | static ssize_t proc_file_read(struct file *file, char __user *buf, | ||
29 | size_t nbytes, loff_t *ppos); | ||
30 | static ssize_t proc_file_write(struct file *file, const char __user *buffer, | ||
31 | size_t count, loff_t *ppos); | ||
32 | static loff_t proc_file_lseek(struct file *, loff_t, int); | ||
33 | |||
34 | DEFINE_SPINLOCK(proc_subdir_lock); | 28 | DEFINE_SPINLOCK(proc_subdir_lock); |
35 | 29 | ||
36 | static int proc_match(int len, const char *name, struct proc_dir_entry *de) | 30 | static int proc_match(int len, const char *name, struct proc_dir_entry *de) |
@@ -40,12 +34,6 @@ static int proc_match(int len, const char *name, struct proc_dir_entry *de) | |||
40 | return !memcmp(name, de->name, len); | 34 | return !memcmp(name, de->name, len); |
41 | } | 35 | } |
42 | 36 | ||
43 | static const struct file_operations proc_file_operations = { | ||
44 | .llseek = proc_file_lseek, | ||
45 | .read = proc_file_read, | ||
46 | .write = proc_file_write, | ||
47 | }; | ||
48 | |||
49 | /* buffer size is one page but our output routines use some slack for overruns */ | 37 | /* buffer size is one page but our output routines use some slack for overruns */ |
50 | #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) | 38 | #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) |
51 | 39 | ||
@@ -233,6 +221,12 @@ proc_file_lseek(struct file *file, loff_t offset, int orig) | |||
233 | return retval; | 221 | return retval; |
234 | } | 222 | } |
235 | 223 | ||
224 | static const struct file_operations proc_file_operations = { | ||
225 | .llseek = proc_file_lseek, | ||
226 | .read = proc_file_read, | ||
227 | .write = proc_file_write, | ||
228 | }; | ||
229 | |||
236 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | 230 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) |
237 | { | 231 | { |
238 | struct inode *inode = dentry->d_inode; | 232 | struct inode *inode = dentry->d_inode; |
@@ -406,12 +400,12 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam | |||
406 | spin_unlock(&proc_subdir_lock); | 400 | spin_unlock(&proc_subdir_lock); |
407 | error = -EINVAL; | 401 | error = -EINVAL; |
408 | inode = proc_get_inode(dir->i_sb, ino, de); | 402 | inode = proc_get_inode(dir->i_sb, ino, de); |
409 | spin_lock(&proc_subdir_lock); | 403 | goto out_unlock; |
410 | break; | ||
411 | } | 404 | } |
412 | } | 405 | } |
413 | } | 406 | } |
414 | spin_unlock(&proc_subdir_lock); | 407 | spin_unlock(&proc_subdir_lock); |
408 | out_unlock: | ||
415 | unlock_kernel(); | 409 | unlock_kernel(); |
416 | 410 | ||
417 | if (inode) { | 411 | if (inode) { |
@@ -527,6 +521,7 @@ static const struct inode_operations proc_dir_inode_operations = { | |||
527 | static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) | 521 | static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) |
528 | { | 522 | { |
529 | unsigned int i; | 523 | unsigned int i; |
524 | struct proc_dir_entry *tmp; | ||
530 | 525 | ||
531 | i = get_inode_number(); | 526 | i = get_inode_number(); |
532 | if (i == 0) | 527 | if (i == 0) |
@@ -550,6 +545,15 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp | |||
550 | } | 545 | } |
551 | 546 | ||
552 | spin_lock(&proc_subdir_lock); | 547 | spin_lock(&proc_subdir_lock); |
548 | |||
549 | for (tmp = dir->subdir; tmp; tmp = tmp->next) | ||
550 | if (strcmp(tmp->name, dp->name) == 0) { | ||
551 | printk(KERN_WARNING "proc_dir_entry '%s' already " | ||
552 | "registered\n", dp->name); | ||
553 | dump_stack(); | ||
554 | break; | ||
555 | } | ||
556 | |||
553 | dp->next = dir->subdir; | 557 | dp->next = dir->subdir; |
554 | dp->parent = dir; | 558 | dp->parent = dir; |
555 | dir->subdir = dp; | 559 | dir->subdir = dp; |
@@ -558,7 +562,7 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp | |||
558 | return 0; | 562 | return 0; |
559 | } | 563 | } |
560 | 564 | ||
561 | static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, | 565 | static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, |
562 | const char *name, | 566 | const char *name, |
563 | mode_t mode, | 567 | mode_t mode, |
564 | nlink_t nlink) | 568 | nlink_t nlink) |
@@ -601,7 +605,7 @@ struct proc_dir_entry *proc_symlink(const char *name, | |||
601 | { | 605 | { |
602 | struct proc_dir_entry *ent; | 606 | struct proc_dir_entry *ent; |
603 | 607 | ||
604 | ent = proc_create(&parent,name, | 608 | ent = __proc_create(&parent, name, |
605 | (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1); | 609 | (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1); |
606 | 610 | ||
607 | if (ent) { | 611 | if (ent) { |
@@ -626,7 +630,7 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode, | |||
626 | { | 630 | { |
627 | struct proc_dir_entry *ent; | 631 | struct proc_dir_entry *ent; |
628 | 632 | ||
629 | ent = proc_create(&parent, name, S_IFDIR | mode, 2); | 633 | ent = __proc_create(&parent, name, S_IFDIR | mode, 2); |
630 | if (ent) { | 634 | if (ent) { |
631 | if (proc_register(parent, ent) < 0) { | 635 | if (proc_register(parent, ent) < 0) { |
632 | kfree(ent); | 636 | kfree(ent); |
@@ -660,7 +664,7 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, | |||
660 | nlink = 1; | 664 | nlink = 1; |
661 | } | 665 | } |
662 | 666 | ||
663 | ent = proc_create(&parent,name,mode,nlink); | 667 | ent = __proc_create(&parent, name, mode, nlink); |
664 | if (ent) { | 668 | if (ent) { |
665 | if (proc_register(parent, ent) < 0) { | 669 | if (proc_register(parent, ent) < 0) { |
666 | kfree(ent); | 670 | kfree(ent); |
@@ -670,6 +674,38 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, | |||
670 | return ent; | 674 | return ent; |
671 | } | 675 | } |
672 | 676 | ||
677 | struct proc_dir_entry *proc_create(const char *name, mode_t mode, | ||
678 | struct proc_dir_entry *parent, | ||
679 | const struct file_operations *proc_fops) | ||
680 | { | ||
681 | struct proc_dir_entry *pde; | ||
682 | nlink_t nlink; | ||
683 | |||
684 | if (S_ISDIR(mode)) { | ||
685 | if ((mode & S_IALLUGO) == 0) | ||
686 | mode |= S_IRUGO | S_IXUGO; | ||
687 | nlink = 2; | ||
688 | } else { | ||
689 | if ((mode & S_IFMT) == 0) | ||
690 | mode |= S_IFREG; | ||
691 | if ((mode & S_IALLUGO) == 0) | ||
692 | mode |= S_IRUGO; | ||
693 | nlink = 1; | ||
694 | } | ||
695 | |||
696 | pde = __proc_create(&parent, name, mode, nlink); | ||
697 | if (!pde) | ||
698 | goto out; | ||
699 | pde->proc_fops = proc_fops; | ||
700 | if (proc_register(parent, pde) < 0) | ||
701 | goto out_free; | ||
702 | return pde; | ||
703 | out_free: | ||
704 | kfree(pde); | ||
705 | out: | ||
706 | return NULL; | ||
707 | } | ||
708 | |||
673 | void free_proc_entry(struct proc_dir_entry *de) | 709 | void free_proc_entry(struct proc_dir_entry *de) |
674 | { | 710 | { |
675 | unsigned int ino = de->low_ino; | 711 | unsigned int ino = de->low_ino; |
@@ -679,7 +715,7 @@ void free_proc_entry(struct proc_dir_entry *de) | |||
679 | 715 | ||
680 | release_inode_number(ino); | 716 | release_inode_number(ino); |
681 | 717 | ||
682 | if (S_ISLNK(de->mode) && de->data) | 718 | if (S_ISLNK(de->mode)) |
683 | kfree(de->data); | 719 | kfree(de->data); |
684 | kfree(de); | 720 | kfree(de); |
685 | } | 721 | } |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 1a551d92e1d8..82b3a1b5a70b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -73,11 +73,6 @@ static void proc_delete_inode(struct inode *inode) | |||
73 | 73 | ||
74 | struct vfsmount *proc_mnt; | 74 | struct vfsmount *proc_mnt; |
75 | 75 | ||
76 | static void proc_read_inode(struct inode * inode) | ||
77 | { | ||
78 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
79 | } | ||
80 | |||
81 | static struct kmem_cache * proc_inode_cachep; | 76 | static struct kmem_cache * proc_inode_cachep; |
82 | 77 | ||
83 | static struct inode *proc_alloc_inode(struct super_block *sb) | 78 | static struct inode *proc_alloc_inode(struct super_block *sb) |
@@ -128,7 +123,6 @@ static int proc_remount(struct super_block *sb, int *flags, char *data) | |||
128 | static const struct super_operations proc_sops = { | 123 | static const struct super_operations proc_sops = { |
129 | .alloc_inode = proc_alloc_inode, | 124 | .alloc_inode = proc_alloc_inode, |
130 | .destroy_inode = proc_destroy_inode, | 125 | .destroy_inode = proc_destroy_inode, |
131 | .read_inode = proc_read_inode, | ||
132 | .drop_inode = generic_delete_inode, | 126 | .drop_inode = generic_delete_inode, |
133 | .delete_inode = proc_delete_inode, | 127 | .delete_inode = proc_delete_inode, |
134 | .statfs = simple_statfs, | 128 | .statfs = simple_statfs, |
@@ -401,39 +395,41 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
401 | if (de != NULL && !try_module_get(de->owner)) | 395 | if (de != NULL && !try_module_get(de->owner)) |
402 | goto out_mod; | 396 | goto out_mod; |
403 | 397 | ||
404 | inode = iget(sb, ino); | 398 | inode = iget_locked(sb, ino); |
405 | if (!inode) | 399 | if (!inode) |
406 | goto out_ino; | 400 | goto out_ino; |
407 | 401 | if (inode->i_state & I_NEW) { | |
408 | PROC_I(inode)->fd = 0; | 402 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
409 | PROC_I(inode)->pde = de; | 403 | PROC_I(inode)->fd = 0; |
410 | if (de) { | 404 | PROC_I(inode)->pde = de; |
411 | if (de->mode) { | 405 | if (de) { |
412 | inode->i_mode = de->mode; | 406 | if (de->mode) { |
413 | inode->i_uid = de->uid; | 407 | inode->i_mode = de->mode; |
414 | inode->i_gid = de->gid; | 408 | inode->i_uid = de->uid; |
415 | } | 409 | inode->i_gid = de->gid; |
416 | if (de->size) | 410 | } |
417 | inode->i_size = de->size; | 411 | if (de->size) |
418 | if (de->nlink) | 412 | inode->i_size = de->size; |
419 | inode->i_nlink = de->nlink; | 413 | if (de->nlink) |
420 | if (de->proc_iops) | 414 | inode->i_nlink = de->nlink; |
421 | inode->i_op = de->proc_iops; | 415 | if (de->proc_iops) |
422 | if (de->proc_fops) { | 416 | inode->i_op = de->proc_iops; |
423 | if (S_ISREG(inode->i_mode)) { | 417 | if (de->proc_fops) { |
418 | if (S_ISREG(inode->i_mode)) { | ||
424 | #ifdef CONFIG_COMPAT | 419 | #ifdef CONFIG_COMPAT |
425 | if (!de->proc_fops->compat_ioctl) | 420 | if (!de->proc_fops->compat_ioctl) |
426 | inode->i_fop = | 421 | inode->i_fop = |
427 | &proc_reg_file_ops_no_compat; | 422 | &proc_reg_file_ops_no_compat; |
428 | else | 423 | else |
429 | #endif | 424 | #endif |
430 | inode->i_fop = &proc_reg_file_ops; | 425 | inode->i_fop = &proc_reg_file_ops; |
426 | } else { | ||
427 | inode->i_fop = de->proc_fops; | ||
428 | } | ||
431 | } | 429 | } |
432 | else | ||
433 | inode->i_fop = de->proc_fops; | ||
434 | } | 430 | } |
431 | unlock_new_inode(inode); | ||
435 | } | 432 | } |
436 | |||
437 | return inode; | 433 | return inode; |
438 | 434 | ||
439 | out_ino: | 435 | out_ino: |
@@ -471,4 +467,3 @@ out_no_root: | |||
471 | de_put(&proc_root); | 467 | de_put(&proc_root); |
472 | return -ENOMEM; | 468 | return -ENOMEM; |
473 | } | 469 | } |
474 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 7d57e8069924..1c81c8f1aeed 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -46,12 +46,17 @@ extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); | |||
46 | 46 | ||
47 | extern int maps_protect; | 47 | extern int maps_protect; |
48 | 48 | ||
49 | extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f); | 49 | extern void create_seq_entry(char *name, mode_t mode, |
50 | extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); | 50 | const struct file_operations *f); |
51 | extern int proc_tid_stat(struct task_struct *, char *); | 51 | extern int proc_exe_link(struct inode *, struct path *); |
52 | extern int proc_tgid_stat(struct task_struct *, char *); | 52 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, |
53 | extern int proc_pid_status(struct task_struct *, char *); | 53 | struct pid *pid, struct task_struct *task); |
54 | extern int proc_pid_statm(struct task_struct *, char *); | 54 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, |
55 | struct pid *pid, struct task_struct *task); | ||
56 | extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | ||
57 | struct pid *pid, struct task_struct *task); | ||
58 | extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, | ||
59 | struct pid *pid, struct task_struct *task); | ||
55 | extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); | 60 | extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); |
56 | 61 | ||
57 | extern const struct file_operations proc_maps_operations; | 62 | extern const struct file_operations proc_maps_operations; |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 7dd26e18cbfd..e78c81fcf547 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/user.h> | 14 | #include <linux/user.h> |
15 | #include <linux/a.out.h> | ||
16 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
17 | #include <linux/elf.h> | 16 | #include <linux/elf.h> |
18 | #include <linux/elfcore.h> | 17 | #include <linux/elfcore.h> |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index 22f789de3909..941e95114b5a 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
@@ -67,7 +67,7 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | |||
67 | if (len < 1) | 67 | if (len < 1) |
68 | len = 1; | 68 | len = 1; |
69 | seq_printf(m, "%*c", len, ' '); | 69 | seq_printf(m, "%*c", len, ' '); |
70 | seq_path(m, file->f_path.mnt, file->f_path.dentry, ""); | 70 | seq_path(m, &file->f_path, ""); |
71 | } | 71 | } |
72 | 72 | ||
73 | seq_putc(m, '\n'); | 73 | seq_putc(m, '\n'); |
@@ -116,7 +116,7 @@ static void *nommu_vma_list_next(struct seq_file *m, void *v, loff_t *pos) | |||
116 | return rb_next((struct rb_node *) v); | 116 | return rb_next((struct rb_node *) v); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct seq_operations proc_nommu_vma_list_seqop = { | 119 | static const struct seq_operations proc_nommu_vma_list_seqop = { |
120 | .start = nommu_vma_list_start, | 120 | .start = nommu_vma_list_start, |
121 | .next = nommu_vma_list_next, | 121 | .next = nommu_vma_list_next, |
122 | .stop = nommu_vma_list_stop, | 122 | .stop = nommu_vma_list_stop, |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 51288db37a0c..468805d40e2b 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/mmzone.h> | 30 | #include <linux/mmzone.h> |
31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
32 | #include <linux/interrupt.h> | ||
32 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
34 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
@@ -64,7 +65,6 @@ | |||
64 | */ | 65 | */ |
65 | extern int get_hardware_list(char *); | 66 | extern int get_hardware_list(char *); |
66 | extern int get_stram_list(char *); | 67 | extern int get_stram_list(char *); |
67 | extern int get_filesystem_list(char *); | ||
68 | extern int get_exec_domain_list(char *); | 68 | extern int get_exec_domain_list(char *); |
69 | extern int get_dma_list(char *); | 69 | extern int get_dma_list(char *); |
70 | 70 | ||
@@ -84,10 +84,15 @@ static int loadavg_read_proc(char *page, char **start, off_t off, | |||
84 | { | 84 | { |
85 | int a, b, c; | 85 | int a, b, c; |
86 | int len; | 86 | int len; |
87 | unsigned long seq; | ||
88 | |||
89 | do { | ||
90 | seq = read_seqbegin(&xtime_lock); | ||
91 | a = avenrun[0] + (FIXED_1/200); | ||
92 | b = avenrun[1] + (FIXED_1/200); | ||
93 | c = avenrun[2] + (FIXED_1/200); | ||
94 | } while (read_seqretry(&xtime_lock, seq)); | ||
87 | 95 | ||
88 | a = avenrun[0] + (FIXED_1/200); | ||
89 | b = avenrun[1] + (FIXED_1/200); | ||
90 | c = avenrun[2] + (FIXED_1/200); | ||
91 | len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", | 96 | len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", |
92 | LOAD_INT(a), LOAD_FRAC(a), | 97 | LOAD_INT(a), LOAD_FRAC(a), |
93 | LOAD_INT(b), LOAD_FRAC(b), | 98 | LOAD_INT(b), LOAD_FRAC(b), |
@@ -217,7 +222,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off, | |||
217 | #undef K | 222 | #undef K |
218 | } | 223 | } |
219 | 224 | ||
220 | extern struct seq_operations fragmentation_op; | 225 | extern const struct seq_operations fragmentation_op; |
221 | static int fragmentation_open(struct inode *inode, struct file *file) | 226 | static int fragmentation_open(struct inode *inode, struct file *file) |
222 | { | 227 | { |
223 | (void)inode; | 228 | (void)inode; |
@@ -231,7 +236,7 @@ static const struct file_operations fragmentation_file_operations = { | |||
231 | .release = seq_release, | 236 | .release = seq_release, |
232 | }; | 237 | }; |
233 | 238 | ||
234 | extern struct seq_operations pagetypeinfo_op; | 239 | extern const struct seq_operations pagetypeinfo_op; |
235 | static int pagetypeinfo_open(struct inode *inode, struct file *file) | 240 | static int pagetypeinfo_open(struct inode *inode, struct file *file) |
236 | { | 241 | { |
237 | return seq_open(file, &pagetypeinfo_op); | 242 | return seq_open(file, &pagetypeinfo_op); |
@@ -244,7 +249,7 @@ static const struct file_operations pagetypeinfo_file_ops = { | |||
244 | .release = seq_release, | 249 | .release = seq_release, |
245 | }; | 250 | }; |
246 | 251 | ||
247 | extern struct seq_operations zoneinfo_op; | 252 | extern const struct seq_operations zoneinfo_op; |
248 | static int zoneinfo_open(struct inode *inode, struct file *file) | 253 | static int zoneinfo_open(struct inode *inode, struct file *file) |
249 | { | 254 | { |
250 | return seq_open(file, &zoneinfo_op); | 255 | return seq_open(file, &zoneinfo_op); |
@@ -269,7 +274,7 @@ static int version_read_proc(char *page, char **start, off_t off, | |||
269 | return proc_calc_metrics(page, start, off, count, eof, len); | 274 | return proc_calc_metrics(page, start, off, count, eof, len); |
270 | } | 275 | } |
271 | 276 | ||
272 | extern struct seq_operations cpuinfo_op; | 277 | extern const struct seq_operations cpuinfo_op; |
273 | static int cpuinfo_open(struct inode *inode, struct file *file) | 278 | static int cpuinfo_open(struct inode *inode, struct file *file) |
274 | { | 279 | { |
275 | return seq_open(file, &cpuinfo_op); | 280 | return seq_open(file, &cpuinfo_op); |
@@ -322,7 +327,7 @@ static void devinfo_stop(struct seq_file *f, void *v) | |||
322 | /* Nothing to do */ | 327 | /* Nothing to do */ |
323 | } | 328 | } |
324 | 329 | ||
325 | static struct seq_operations devinfo_ops = { | 330 | static const struct seq_operations devinfo_ops = { |
326 | .start = devinfo_start, | 331 | .start = devinfo_start, |
327 | .next = devinfo_next, | 332 | .next = devinfo_next, |
328 | .stop = devinfo_stop, | 333 | .stop = devinfo_stop, |
@@ -341,7 +346,7 @@ static const struct file_operations proc_devinfo_operations = { | |||
341 | .release = seq_release, | 346 | .release = seq_release, |
342 | }; | 347 | }; |
343 | 348 | ||
344 | extern struct seq_operations vmstat_op; | 349 | extern const struct seq_operations vmstat_op; |
345 | static int vmstat_open(struct inode *inode, struct file *file) | 350 | static int vmstat_open(struct inode *inode, struct file *file) |
346 | { | 351 | { |
347 | return seq_open(file, &vmstat_op); | 352 | return seq_open(file, &vmstat_op); |
@@ -372,7 +377,7 @@ static int stram_read_proc(char *page, char **start, off_t off, | |||
372 | #endif | 377 | #endif |
373 | 378 | ||
374 | #ifdef CONFIG_BLOCK | 379 | #ifdef CONFIG_BLOCK |
375 | extern struct seq_operations partitions_op; | 380 | extern const struct seq_operations partitions_op; |
376 | static int partitions_open(struct inode *inode, struct file *file) | 381 | static int partitions_open(struct inode *inode, struct file *file) |
377 | { | 382 | { |
378 | return seq_open(file, &partitions_op); | 383 | return seq_open(file, &partitions_op); |
@@ -384,7 +389,7 @@ static const struct file_operations proc_partitions_operations = { | |||
384 | .release = seq_release, | 389 | .release = seq_release, |
385 | }; | 390 | }; |
386 | 391 | ||
387 | extern struct seq_operations diskstats_op; | 392 | extern const struct seq_operations diskstats_op; |
388 | static int diskstats_open(struct inode *inode, struct file *file) | 393 | static int diskstats_open(struct inode *inode, struct file *file) |
389 | { | 394 | { |
390 | return seq_open(file, &diskstats_op); | 395 | return seq_open(file, &diskstats_op); |
@@ -398,7 +403,7 @@ static const struct file_operations proc_diskstats_operations = { | |||
398 | #endif | 403 | #endif |
399 | 404 | ||
400 | #ifdef CONFIG_MODULES | 405 | #ifdef CONFIG_MODULES |
401 | extern struct seq_operations modules_op; | 406 | extern const struct seq_operations modules_op; |
402 | static int modules_open(struct inode *inode, struct file *file) | 407 | static int modules_open(struct inode *inode, struct file *file) |
403 | { | 408 | { |
404 | return seq_open(file, &modules_op); | 409 | return seq_open(file, &modules_op); |
@@ -425,7 +430,7 @@ static const struct file_operations proc_slabinfo_operations = { | |||
425 | }; | 430 | }; |
426 | 431 | ||
427 | #ifdef CONFIG_DEBUG_SLAB_LEAK | 432 | #ifdef CONFIG_DEBUG_SLAB_LEAK |
428 | extern struct seq_operations slabstats_op; | 433 | extern const struct seq_operations slabstats_op; |
429 | static int slabstats_open(struct inode *inode, struct file *file) | 434 | static int slabstats_open(struct inode *inode, struct file *file) |
430 | { | 435 | { |
431 | unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL); | 436 | unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL); |
@@ -599,8 +604,7 @@ static void int_seq_stop(struct seq_file *f, void *v) | |||
599 | } | 604 | } |
600 | 605 | ||
601 | 606 | ||
602 | extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */ | 607 | static const struct seq_operations int_seq_ops = { |
603 | static struct seq_operations int_seq_ops = { | ||
604 | .start = int_seq_start, | 608 | .start = int_seq_start, |
605 | .next = int_seq_next, | 609 | .next = int_seq_next, |
606 | .stop = int_seq_stop, | 610 | .stop = int_seq_stop, |
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 4823c9677fac..14e9b5aaf863 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c | |||
@@ -67,12 +67,7 @@ EXPORT_SYMBOL_GPL(seq_release_net); | |||
67 | struct proc_dir_entry *proc_net_fops_create(struct net *net, | 67 | struct proc_dir_entry *proc_net_fops_create(struct net *net, |
68 | const char *name, mode_t mode, const struct file_operations *fops) | 68 | const char *name, mode_t mode, const struct file_operations *fops) |
69 | { | 69 | { |
70 | struct proc_dir_entry *res; | 70 | return proc_create(name, mode, net->proc_net, fops); |
71 | |||
72 | res = create_proc_entry(name, mode, net->proc_net); | ||
73 | if (res) | ||
74 | res->proc_fops = fops; | ||
75 | return res; | ||
76 | } | 71 | } |
77 | EXPORT_SYMBOL_GPL(proc_net_fops_create); | 72 | EXPORT_SYMBOL_GPL(proc_net_fops_create); |
78 | 73 | ||
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 4e57fcf85982..614c34b6d1c2 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | static struct dentry_operations proc_sys_dentry_operations; | 10 | static struct dentry_operations proc_sys_dentry_operations; |
11 | static const struct file_operations proc_sys_file_operations; | 11 | static const struct file_operations proc_sys_file_operations; |
12 | static struct inode_operations proc_sys_inode_operations; | 12 | static const struct inode_operations proc_sys_inode_operations; |
13 | 13 | ||
14 | static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table) | 14 | static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table) |
15 | { | 15 | { |
@@ -407,7 +407,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * | |||
407 | if (!nd || !depth) | 407 | if (!nd || !depth) |
408 | goto out; | 408 | goto out; |
409 | 409 | ||
410 | dentry = nd->dentry; | 410 | dentry = nd->path.dentry; |
411 | table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); | 411 | table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); |
412 | 412 | ||
413 | /* If the entry does not exist deny permission */ | 413 | /* If the entry does not exist deny permission */ |
@@ -446,7 +446,7 @@ static const struct file_operations proc_sys_file_operations = { | |||
446 | .readdir = proc_sys_readdir, | 446 | .readdir = proc_sys_readdir, |
447 | }; | 447 | }; |
448 | 448 | ||
449 | static struct inode_operations proc_sys_inode_operations = { | 449 | static const struct inode_operations proc_sys_inode_operations = { |
450 | .lookup = proc_sys_lookup, | 450 | .lookup = proc_sys_lookup, |
451 | .permission = proc_sys_permission, | 451 | .permission = proc_sys_permission, |
452 | .setattr = proc_sys_setattr, | 452 | .setattr = proc_sys_setattr, |
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 22846225acfa..49816e00b51a 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -15,9 +15,6 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
17 | 17 | ||
18 | static int tty_ldiscs_read_proc(char *page, char **start, off_t off, | ||
19 | int count, int *eof, void *data); | ||
20 | |||
21 | /* | 18 | /* |
22 | * The /proc/tty directory inodes... | 19 | * The /proc/tty directory inodes... |
23 | */ | 20 | */ |
@@ -120,7 +117,7 @@ static void t_stop(struct seq_file *m, void *v) | |||
120 | mutex_unlock(&tty_mutex); | 117 | mutex_unlock(&tty_mutex); |
121 | } | 118 | } |
122 | 119 | ||
123 | static struct seq_operations tty_drivers_op = { | 120 | static const struct seq_operations tty_drivers_op = { |
124 | .start = t_start, | 121 | .start = t_start, |
125 | .next = t_next, | 122 | .next = t_next, |
126 | .stop = t_stop, | 123 | .stop = t_stop, |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 81f99e691f99..ef0fb57fc9ef 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -232,6 +232,7 @@ void pid_ns_release_proc(struct pid_namespace *ns) | |||
232 | EXPORT_SYMBOL(proc_symlink); | 232 | EXPORT_SYMBOL(proc_symlink); |
233 | EXPORT_SYMBOL(proc_mkdir); | 233 | EXPORT_SYMBOL(proc_mkdir); |
234 | EXPORT_SYMBOL(create_proc_entry); | 234 | EXPORT_SYMBOL(create_proc_entry); |
235 | EXPORT_SYMBOL(proc_create); | ||
235 | EXPORT_SYMBOL(remove_proc_entry); | 236 | EXPORT_SYMBOL(remove_proc_entry); |
236 | EXPORT_SYMBOL(proc_root); | 237 | EXPORT_SYMBOL(proc_root); |
237 | EXPORT_SYMBOL(proc_root_fs); | 238 | EXPORT_SYMBOL(proc_root_fs); |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 38338ed98cc6..49958cffbd8d 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -9,13 +9,14 @@ | |||
9 | #include <linux/mempolicy.h> | 9 | #include <linux/mempolicy.h> |
10 | #include <linux/swap.h> | 10 | #include <linux/swap.h> |
11 | #include <linux/swapops.h> | 11 | #include <linux/swapops.h> |
12 | #include <linux/seq_file.h> | ||
12 | 13 | ||
13 | #include <asm/elf.h> | 14 | #include <asm/elf.h> |
14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
15 | #include <asm/tlbflush.h> | 16 | #include <asm/tlbflush.h> |
16 | #include "internal.h" | 17 | #include "internal.h" |
17 | 18 | ||
18 | char *task_mem(struct mm_struct *mm, char *buffer) | 19 | void task_mem(struct seq_file *m, struct mm_struct *mm) |
19 | { | 20 | { |
20 | unsigned long data, text, lib; | 21 | unsigned long data, text, lib; |
21 | unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; | 22 | unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; |
@@ -37,7 +38,7 @@ char *task_mem(struct mm_struct *mm, char *buffer) | |||
37 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; | 38 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; |
38 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; | 39 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; |
39 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; | 40 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; |
40 | buffer += sprintf(buffer, | 41 | seq_printf(m, |
41 | "VmPeak:\t%8lu kB\n" | 42 | "VmPeak:\t%8lu kB\n" |
42 | "VmSize:\t%8lu kB\n" | 43 | "VmSize:\t%8lu kB\n" |
43 | "VmLck:\t%8lu kB\n" | 44 | "VmLck:\t%8lu kB\n" |
@@ -56,7 +57,6 @@ char *task_mem(struct mm_struct *mm, char *buffer) | |||
56 | data << (PAGE_SHIFT-10), | 57 | data << (PAGE_SHIFT-10), |
57 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, | 58 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
58 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); | 59 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); |
59 | return buffer; | ||
60 | } | 60 | } |
61 | 61 | ||
62 | unsigned long task_vsize(struct mm_struct *mm) | 62 | unsigned long task_vsize(struct mm_struct *mm) |
@@ -75,7 +75,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
75 | return mm->total_vm; | 75 | return mm->total_vm; |
76 | } | 76 | } |
77 | 77 | ||
78 | int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 78 | int proc_exe_link(struct inode *inode, struct path *path) |
79 | { | 79 | { |
80 | struct vm_area_struct * vma; | 80 | struct vm_area_struct * vma; |
81 | int result = -ENOENT; | 81 | int result = -ENOENT; |
@@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount * | |||
98 | } | 98 | } |
99 | 99 | ||
100 | if (vma) { | 100 | if (vma) { |
101 | *mnt = mntget(vma->vm_file->f_path.mnt); | 101 | *path = vma->vm_file->f_path; |
102 | *dentry = dget(vma->vm_file->f_path.dentry); | 102 | path_get(&vma->vm_file->f_path); |
103 | result = 0; | 103 | result = 0; |
104 | } | 104 | } |
105 | 105 | ||
@@ -216,7 +216,7 @@ static void m_stop(struct seq_file *m, void *v) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | static int do_maps_open(struct inode *inode, struct file *file, | 218 | static int do_maps_open(struct inode *inode, struct file *file, |
219 | struct seq_operations *ops) | 219 | const struct seq_operations *ops) |
220 | { | 220 | { |
221 | struct proc_maps_private *priv; | 221 | struct proc_maps_private *priv; |
222 | int ret = -ENOMEM; | 222 | int ret = -ENOMEM; |
@@ -271,7 +271,7 @@ static int show_map(struct seq_file *m, void *v) | |||
271 | */ | 271 | */ |
272 | if (file) { | 272 | if (file) { |
273 | pad_len_spaces(m, len); | 273 | pad_len_spaces(m, len); |
274 | seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n"); | 274 | seq_path(m, &file->f_path, "\n"); |
275 | } else { | 275 | } else { |
276 | const char *name = arch_vma_name(vma); | 276 | const char *name = arch_vma_name(vma); |
277 | if (!name) { | 277 | if (!name) { |
@@ -299,7 +299,7 @@ static int show_map(struct seq_file *m, void *v) | |||
299 | return 0; | 299 | return 0; |
300 | } | 300 | } |
301 | 301 | ||
302 | static struct seq_operations proc_pid_maps_op = { | 302 | static const struct seq_operations proc_pid_maps_op = { |
303 | .start = m_start, | 303 | .start = m_start, |
304 | .next = m_next, | 304 | .next = m_next, |
305 | .stop = m_stop, | 305 | .stop = m_stop, |
@@ -434,7 +434,7 @@ static int show_smap(struct seq_file *m, void *v) | |||
434 | return ret; | 434 | return ret; |
435 | } | 435 | } |
436 | 436 | ||
437 | static struct seq_operations proc_pid_smaps_op = { | 437 | static const struct seq_operations proc_pid_smaps_op = { |
438 | .start = m_start, | 438 | .start = m_start, |
439 | .next = m_next, | 439 | .next = m_next, |
440 | .stop = m_stop, | 440 | .stop = m_stop, |
@@ -734,7 +734,7 @@ static int show_numa_map_checked(struct seq_file *m, void *v) | |||
734 | return show_numa_map(m, v); | 734 | return show_numa_map(m, v); |
735 | } | 735 | } |
736 | 736 | ||
737 | static struct seq_operations proc_pid_numa_maps_op = { | 737 | static const struct seq_operations proc_pid_numa_maps_op = { |
738 | .start = m_start, | 738 | .start = m_start, |
739 | .next = m_next, | 739 | .next = m_next, |
740 | .stop = m_stop, | 740 | .stop = m_stop, |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 1932c2ca3457..8011528518bd 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * each process that owns it. Non-shared memory is counted | 12 | * each process that owns it. Non-shared memory is counted |
13 | * accurately. | 13 | * accurately. |
14 | */ | 14 | */ |
15 | char *task_mem(struct mm_struct *mm, char *buffer) | 15 | void task_mem(struct seq_file *m, struct mm_struct *mm) |
16 | { | 16 | { |
17 | struct vm_list_struct *vml; | 17 | struct vm_list_struct *vml; |
18 | unsigned long bytes = 0, sbytes = 0, slack = 0; | 18 | unsigned long bytes = 0, sbytes = 0, slack = 0; |
@@ -58,14 +58,13 @@ char *task_mem(struct mm_struct *mm, char *buffer) | |||
58 | 58 | ||
59 | bytes += kobjsize(current); /* includes kernel stack */ | 59 | bytes += kobjsize(current); /* includes kernel stack */ |
60 | 60 | ||
61 | buffer += sprintf(buffer, | 61 | seq_printf(m, |
62 | "Mem:\t%8lu bytes\n" | 62 | "Mem:\t%8lu bytes\n" |
63 | "Slack:\t%8lu bytes\n" | 63 | "Slack:\t%8lu bytes\n" |
64 | "Shared:\t%8lu bytes\n", | 64 | "Shared:\t%8lu bytes\n", |
65 | bytes, slack, sbytes); | 65 | bytes, slack, sbytes); |
66 | 66 | ||
67 | up_read(&mm->mmap_sem); | 67 | up_read(&mm->mmap_sem); |
68 | return buffer; | ||
69 | } | 68 | } |
70 | 69 | ||
71 | unsigned long task_vsize(struct mm_struct *mm) | 70 | unsigned long task_vsize(struct mm_struct *mm) |
@@ -104,7 +103,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
104 | return size; | 103 | return size; |
105 | } | 104 | } |
106 | 105 | ||
107 | int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 106 | int proc_exe_link(struct inode *inode, struct path *path) |
108 | { | 107 | { |
109 | struct vm_list_struct *vml; | 108 | struct vm_list_struct *vml; |
110 | struct vm_area_struct *vma; | 109 | struct vm_area_struct *vma; |
@@ -127,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount * | |||
127 | } | 126 | } |
128 | 127 | ||
129 | if (vma) { | 128 | if (vma) { |
130 | *mnt = mntget(vma->vm_file->f_path.mnt); | 129 | *path = vma->vm_file->f_path; |
131 | *dentry = dget(vma->vm_file->f_path.dentry); | 130 | path_get(&vma->vm_file->f_path); |
132 | result = 0; | 131 | result = 0; |
133 | } | 132 | } |
134 | 133 | ||
@@ -199,7 +198,7 @@ static void *m_next(struct seq_file *m, void *_vml, loff_t *pos) | |||
199 | return vml ? vml->next : NULL; | 198 | return vml ? vml->next : NULL; |
200 | } | 199 | } |
201 | 200 | ||
202 | static struct seq_operations proc_pid_maps_ops = { | 201 | static const struct seq_operations proc_pid_maps_ops = { |
203 | .start = m_start, | 202 | .start = m_start, |
204 | .next = m_next, | 203 | .next = m_next, |
205 | .stop = m_stop, | 204 | .stop = m_stop, |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 523e1098ae88..9ac0f5e064e0 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/proc_fs.h> | 11 | #include <linux/proc_fs.h> |
12 | #include <linux/user.h> | 12 | #include <linux/user.h> |
13 | #include <linux/a.out.h> | ||
14 | #include <linux/elf.h> | 13 | #include <linux/elf.h> |
15 | #include <linux/elfcore.h> | 14 | #include <linux/elfcore.h> |
16 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |