#include <linux/resource.h>
 #include <linux/timer.h>
 #include <linux/hrtimer.h>
+#include <linux/task_io_accounting.h>
 
 #include <asm/processor.h>
 
        wait_queue_t *io_wait;
 /* i/o counters(bytes read/written, #syscalls */
        u64 rchar, wchar, syscr, syscw;
+       struct task_io_accounting ioac;
 #if defined(CONFIG_TASK_XACCT)
        u64 acct_rss_mem1;      /* accumulated rss usage */
        u64 acct_vm_mem1;       /* accumulated virtual memory usage */
 
--- /dev/null
+/*
+ * task_io_accounting: a structure which is used for recording a single task's
+ * IO statistics.
+ *
+ * Don't include this header file directly - it is designed to be dragged in via
+ * sched.h.
+ *
+ * Blame akpm@osdl.org for all this.
+ */
+
+#ifdef CONFIG_TASK_IO_ACCOUNTING
+struct task_io_accounting {
+       /*
+        * The number of bytes which this task has caused to be read from
+        * storage.
+        */
+       u64 read_bytes;
+
+       /*
+        * The number of bytes which this task has caused, or shall cause to be
+        * written to disk.
+        */
+       u64 write_bytes;
+
+       /*
+        * A task can cause "negative" IO too.  If this task truncates some
+        * dirty pagecache, some IO which another task has been accounted for
+        * (in its write_bytes) will not be happening.  We _could_ just
+        * subtract that from the truncating task's write_bytes, but there is
+        * information loss in doing that.
+        */
+       u64 cancelled_write_bytes;
+};
+#else
+struct task_io_accounting {
+};
+#endif
 
--- /dev/null
+/*
+ * Task I/O accounting operations
+ */
+#ifndef __TASK_IO_ACCOUNTING_OPS_INCLUDED
+#define __TASK_IO_ACCOUNTING_OPS_INCLUDED
+
+#ifdef CONFIG_TASK_IO_ACCOUNTING
+static inline void task_io_account_read(size_t bytes)
+{
+       current->ioac.read_bytes += bytes;
+}
+
+static inline void task_io_account_write(size_t bytes)
+{
+       current->ioac.write_bytes += bytes;
+}
+
+static inline void task_io_account_cancelled_write(size_t bytes)
+{
+       current->ioac.cancelled_write_bytes += bytes;
+}
+
+static inline void task_io_accounting_init(struct task_struct *tsk)
+{
+       memset(&tsk->ioac, 0, sizeof(tsk->ioac));
+}
+
+#else
+
+static inline void task_io_account_read(size_t bytes)
+{
+}
+
+static inline void task_io_account_write(size_t bytes)
+{
+}
+
+static inline void task_io_account_cancelled_write(size_t bytes)
+{
+}
+
+static inline void task_io_accounting_init(struct task_struct *tsk)
+{
+}
+
+#endif         /* CONFIG_TASK_IO_ACCOUNTING */
+#endif         /* __TASK_IO_ACCOUNTING_OPS_INCLUDED */
 
 
          Say N if unsure.
 
+config TASK_IO_ACCOUNTING
+       bool "Enable per-task storage I/O accounting (EXPERIMENTAL)"
+       depends on TASK_XACCT
+       help
+         Collect information on the number of bytes of storage I/O which this
+         task has caused.
+
+         Say N if unsure.
+
 config SYSCTL
        bool
 
 
 #include <linux/syscalls.h>
 #include <linux/jiffies.h>
 #include <linux/futex.h>
+#include <linux/task_io_accounting_ops.h>
 #include <linux/rcupdate.h>
 #include <linux/ptrace.h>
 #include <linux/mount.h>
        p->wchar = 0;           /* I/O counter: bytes written */
        p->syscr = 0;           /* I/O counter: read syscalls */
        p->syscw = 0;           /* I/O counter: write syscalls */
+       task_io_accounting_init(p);
        acct_clear_integrals(p);
 
        p->it_virt_expires = cputime_zero;