io_last->fsync -= task->ioac.syscfs;
}
-static void update_io_stats_locked(void)
+static void update_io_stats_all_locked(void)
{
struct uid_entry *uid_entry;
struct task_struct *task, *temp;
struct io_stats *io_bucket, *io_curr, *io_last;
+ struct user_namespace *user_ns = current_user_ns();
unsigned long bkt;
-
- BUG_ON(!rt_mutex_is_locked(&uid_lock));
+ uid_t uid;
hash_for_each(hash_table, bkt, uid_entry, hash)
memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
sizeof(struct io_stats));
- read_lock(&tasklist_lock);
+ rcu_read_lock();
do_each_thread(temp, task) {
- uid_entry = find_or_register_uid(from_kuid_munged(
- current_user_ns(), task_uid(task)));
+ uid = from_kuid_munged(user_ns, task_uid(task));
+ uid_entry = find_or_register_uid(uid);
if (!uid_entry)
continue;
add_uid_io_curr_stats(uid_entry, task);
} while_each_thread(temp, task);
- read_unlock(&tasklist_lock);
+ rcu_read_unlock();
hash_for_each(hash_table, bkt, uid_entry, hash) {
io_bucket = &uid_entry->io[uid_entry->state];
}
}
+static void update_io_stats_uid_locked(uid_t target_uid)
+{
+ struct uid_entry *uid_entry;
+ struct task_struct *task, *temp;
+ struct io_stats *io_bucket, *io_curr, *io_last;
+ struct user_namespace *user_ns = current_user_ns();
+
+ uid_entry = find_or_register_uid(target_uid);
+ if (!uid_entry)
+ return;
+
+ memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
+ sizeof(struct io_stats));
+
+ rcu_read_lock();
+ do_each_thread(temp, task) {
+ if (from_kuid_munged(user_ns, task_uid(task)) != target_uid)
+ continue;
+ add_uid_io_curr_stats(uid_entry, task);
+ } while_each_thread(temp, task);
+ rcu_read_unlock();
+
+ io_bucket = &uid_entry->io[uid_entry->state];
+ io_curr = &uid_entry->io[UID_STATE_TOTAL_CURR];
+ io_last = &uid_entry->io[UID_STATE_TOTAL_LAST];
+
+ io_bucket->read_bytes +=
+ io_curr->read_bytes - io_last->read_bytes;
+ io_bucket->write_bytes +=
+ io_curr->write_bytes - io_last->write_bytes;
+ io_bucket->rchar += io_curr->rchar - io_last->rchar;
+ io_bucket->wchar += io_curr->wchar - io_last->wchar;
+ io_bucket->fsync += io_curr->fsync - io_last->fsync;
+
+ io_last->read_bytes = io_curr->read_bytes;
+ io_last->write_bytes = io_curr->write_bytes;
+ io_last->rchar = io_curr->rchar;
+ io_last->wchar = io_curr->wchar;
+ io_last->fsync = io_curr->fsync;
+}
+
static int uid_io_show(struct seq_file *m, void *v)
{
struct uid_entry *uid_entry;
rt_mutex_lock(&uid_lock);
- update_io_stats_locked();
+ update_io_stats_all_locked();
hash_for_each(hash_table, bkt, uid_entry, hash) {
seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
return count;
}
- update_io_stats_locked();
+ update_io_stats_uid_locked(uid);
uid_entry->state = state;
uid_entry->utime += utime;
uid_entry->stime += stime;
- update_io_stats_locked();
+ update_io_stats_uid_locked(uid);
clean_uid_io_last_stats(uid_entry, task);
exit: