#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/task_io_accounting_ops.h>
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/file.h>
return count;
}
-int maps_protect;
-EXPORT_SYMBOL(maps_protect);
-
static struct fs_struct *get_fs_struct(struct task_struct *task)
{
struct fs_struct *fs;
static int get_nr_threads(struct task_struct *tsk)
{
- /* Must be called with the rcu_read_lock held */
unsigned long flags;
int count = 0;
struct rlimit rlim[RLIM_NLIMITS];
- rcu_read_lock();
- if (!lock_task_sighand(task,&flags)) {
- rcu_read_unlock();
+ if (!lock_task_sighand(task, &flags))
return 0;
- }
memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
unlock_task_sighand(task, &flags);
- rcu_read_unlock();
/*
* print the file header
* /proc/pid/fd needs a special permission handler so that a process can still
* access /proc/self/fd after it has executed a setuid().
*/
-static int proc_fd_permission(struct inode *inode, int mask,
- struct nameidata *nd)
+static int proc_fd_permission(struct inode *inode, int mask)
{
int rv;
#ifdef CONFIG_TASK_IO_ACCOUNTING
static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
{
- u64 rchar, wchar, syscr, syscw;
- struct task_io_accounting ioac;
-
- rchar = task->rchar;
- wchar = task->wchar;
- syscr = task->syscr;
- syscw = task->syscw;
- memcpy(&ioac, &task->ioac, sizeof(ioac));
-
- if (whole) {
- unsigned long flags;
-
- if (lock_task_sighand(task, &flags)) {
- struct signal_struct *sig = task->signal;
- struct task_struct *t = task;
-
- rchar += sig->rchar;
- wchar += sig->wchar;
- syscr += sig->syscr;
- syscw += sig->syscw;
-
- ioac.read_bytes += sig->ioac.read_bytes;
- ioac.write_bytes += sig->ioac.write_bytes;
- ioac.cancelled_write_bytes +=
- sig->ioac.cancelled_write_bytes;
- while_each_thread(task, t) {
- rchar += t->rchar;
- wchar += t->wchar;
- syscr += t->syscr;
- syscw += t->syscw;
-
- ioac.read_bytes += t->ioac.read_bytes;
- ioac.write_bytes += t->ioac.write_bytes;
- ioac.cancelled_write_bytes +=
- t->ioac.cancelled_write_bytes;
- }
- unlock_task_sighand(task, &flags);
- }
+ struct task_io_accounting acct = task->ioac;
+ unsigned long flags;
+
+ if (whole && lock_task_sighand(task, &flags)) {
+ struct task_struct *t = task;
+
+ task_io_accounting_add(&acct, &task->signal->ioac);
+ while_each_thread(task, t)
+ task_io_accounting_add(&acct, &t->ioac);
+
+ unlock_task_sighand(task, &flags);
}
return sprintf(buffer,
"rchar: %llu\n"
"read_bytes: %llu\n"
"write_bytes: %llu\n"
"cancelled_write_bytes: %llu\n",
- rchar, wchar, syscr, syscw,
- ioac.read_bytes, ioac.write_bytes,
- ioac.cancelled_write_bytes);
+ (unsigned long long)acct.rchar,
+ (unsigned long long)acct.wchar,
+ (unsigned long long)acct.syscr,
+ (unsigned long long)acct.syscw,
+ (unsigned long long)acct.read_bytes,
+ (unsigned long long)acct.write_bytes,
+ (unsigned long long)acct.cancelled_write_bytes);
}
static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
}
#endif /* CONFIG_TASK_IO_ACCOUNTING */
+static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
+ struct pid *pid, struct task_struct *task)
+{
+ seq_printf(m, "%08x\n", task->personality);
+ return 0;
+}
+
/*
* Thread groups
*/
REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
ONE("status", S_IRUGO, pid_status),
+ ONE("personality", S_IRUSR, pid_personality),
INF("limits", S_IRUSR, pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, pid_sched),
REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
ONE("status", S_IRUGO, pid_status),
+ ONE("personality", S_IRUSR, pid_personality),
INF("limits", S_IRUSR, pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, pid_sched),
generic_fillattr(inode, stat);
if (p) {
- rcu_read_lock();
stat->nlink += get_nr_threads(p);
- rcu_read_unlock();
put_task_struct(p);
}