summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Lan <jlan@engr.sgi.com>2005-01-04 05:25:25 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:25:25 -0800
commit9ca7d6f6cdc862fdebc72c4c15249cbb729a2f0f (patch)
treefbc08e019693a73b1192aa2b2ae925980f2c3781
parent6c0993a01c43e614a7865da5c6f10894bff9e9b9 (diff)
[PATCH] enhanced I/O accounting data patch
This patch is to offer common accounting data collection method at I/O for various accounting packages including BSD accounting, ELSA, CSA and any other acct packages that use a common layer of data collection. Patch is made to fs/read_write.c to collect per process data on character read/written in bytes and number of read/write syscalls made. New struct fields are added to task_struct to store the data. These data are collected on per process basis. Signed-off-by: Jay Lan <jlan@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/read_write.c23
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/fork.c15
3 files changed, 35 insertions, 5 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index 5103b450ca71..93f0374678ad 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -216,8 +216,11 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
ret = file->f_op->read(file, buf, count, pos);
else
ret = do_sync_read(file, buf, count, pos);
- if (ret > 0)
+ if (ret > 0) {
dnotify_parent(file->f_dentry, DN_ACCESS);
+ current->rchar += ret;
+ }
+ current->syscr++;
}
}
@@ -260,8 +263,11 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
ret = file->f_op->write(file, buf, count, pos);
else
ret = do_sync_write(file, buf, count, pos);
- if (ret > 0)
+ if (ret > 0) {
dnotify_parent(file->f_dentry, DN_MODIFY);
+ current->wchar += ret;
+ }
+ current->syscw++;
}
}
@@ -540,6 +546,9 @@ sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
fput_light(file, fput_needed);
}
+ if (ret > 0)
+ current->rchar += ret;
+ current->syscr++;
return ret;
}
@@ -558,6 +567,9 @@ sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
fput_light(file, fput_needed);
}
+ if (ret > 0)
+ current->wchar += ret;
+ current->syscw++;
return ret;
}
@@ -636,6 +648,13 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
+ if (retval > 0) {
+ current->rchar += retval;
+ current->wchar += retval;
+ }
+ current->syscr++;
+ current->syscw++;
+
if (*ppos > max)
retval = -EOVERFLOW;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 38b1322be072..558d5733a0aa 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -660,6 +660,8 @@ struct task_struct {
* to a stack based synchronous wait) if its doing sync IO.
*/
wait_queue_t *io_wait;
+/* i/o counters(bytes read/written, #syscalls */
+ u64 rchar, wchar, syscr, syscw;
#ifdef CONFIG_NUMA
struct mempolicy *mempolicy;
short il_next; /* could be shared with used_math */
diff --git a/kernel/fork.c b/kernel/fork.c
index 84252e055db4..0e8f874efe67 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -865,12 +865,21 @@ static task_t *copy_process(unsigned long clone_flags,
clear_tsk_thread_flag(p, TIF_SIGPENDING);
init_sigpending(&p->pending);
- p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
- p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
+ p->it_real_value = 0;
+ p->it_real_incr = 0;
+ p->it_virt_value = 0;
+ p->it_virt_incr = 0;
+ p->it_prof_value = 0;
+ p->it_prof_incr = 0;
init_timer(&p->real_timer);
p->real_timer.data = (unsigned long) p;
- p->utime = p->stime = 0;
+ p->utime = 0;
+ p->stime = 0;
+ p->rchar = 0; /* I/O counter: bytes read */
+ p->wchar = 0; /* I/O counter: bytes written */
+ p->syscr = 0; /* I/O counter: read syscalls */
+ p->syscw = 0; /* I/O counter: write syscalls */
p->lock_depth = -1; /* -1 = no lock */
do_posix_clock_monotonic_gettime(&p->start_time);
p->security = NULL;