/* drivers/misc/uid_stat.c
 *
 * Copyright (C) 2008 - 2009 Google, Inc.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <asm/atomic.h>

#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/uid_stat.h>
#include <net/activity_stats.h>

static DEFINE_SPINLOCK(uid_lock);
static LIST_HEAD(uid_list);
static struct proc_dir_entry *parent;

struct uid_stat {
	struct list_head link;
	uid_t uid;
	atomic_t tcp_rcv;
	atomic_t tcp_snd;
};

static struct uid_stat *find_uid_stat(uid_t uid) {
	struct uid_stat *entry;

	list_for_each_entry(entry, &uid_list, link) {
		if (entry->uid == uid) {
			return entry;
		}
	}
	return NULL;
}

static int uid_stat_atomic_int_show(struct seq_file *m, void *v)
{
	unsigned int bytes;
	atomic_t *counter = m->private;

	bytes = (unsigned int) (atomic_read(counter) + INT_MIN);
	return seq_printf(m, "%u\n", bytes);
}

static int uid_stat_read_atomic_int_open(struct inode *inode, struct file *file)
{
	return single_open(file, uid_stat_atomic_int_show, PDE_DATA(inode));
}

static const struct file_operations uid_stat_read_atomic_int_fops = {
	.open		= uid_stat_read_atomic_int_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release        = single_release,
};

/* Create a new entry for tracking the specified uid. */
static struct uid_stat *create_stat(uid_t uid) {
	struct uid_stat *new_uid;
	/* Create the uid stat struct and append it to the list. */
	new_uid = kmalloc(sizeof(struct uid_stat), GFP_ATOMIC);
	if (!new_uid)
		return NULL;

	new_uid->uid = uid;
	/* Counters start at INT_MIN, so we can track 4GB of network traffic. */
	atomic_set(&new_uid->tcp_rcv, INT_MIN);
	atomic_set(&new_uid->tcp_snd, INT_MIN);

	list_add_tail(&new_uid->link, &uid_list);
	return new_uid;
}

static void create_stat_proc(struct uid_stat *new_uid)
{
	char uid_s[32];
	struct proc_dir_entry *entry;
	sprintf(uid_s, "%d", new_uid->uid);
	entry = proc_mkdir(uid_s, parent);

	/* Keep reference to uid_stat so we know what uid to read stats from. */
	proc_create_data("tcp_snd", S_IRUGO, entry,
			 &uid_stat_read_atomic_int_fops, &new_uid->tcp_snd);

	proc_create_data("tcp_rcv", S_IRUGO, entry,
			 &uid_stat_read_atomic_int_fops, &new_uid->tcp_rcv);
}

static struct uid_stat *find_or_create_uid_stat(uid_t uid)
{
	struct uid_stat *entry;
	unsigned long flags;
	spin_lock_irqsave(&uid_lock, flags);
	entry = find_uid_stat(uid);
	if (entry) {
		spin_unlock_irqrestore(&uid_lock, flags);
		return entry;
	}
	entry = create_stat(uid);
	spin_unlock_irqrestore(&uid_lock, flags);
	if (entry)
		create_stat_proc(entry);
	return entry;
}

int uid_stat_tcp_snd(uid_t uid, int size) {
	struct uid_stat *entry;
	activity_stats_update();
	entry = find_or_create_uid_stat(uid);
	if (!entry)
		return -1;
	atomic_add(size, &entry->tcp_snd);
	return 0;
}

int uid_stat_tcp_rcv(uid_t uid, int size) {
	struct uid_stat *entry;
	activity_stats_update();
	entry = find_or_create_uid_stat(uid);
	if (!entry)
		return -1;
	atomic_add(size, &entry->tcp_rcv);
	return 0;
}

static int __init uid_stat_init(void)
{
	parent = proc_mkdir("uid_stat", NULL);
	if (!parent) {
		pr_err("uid_stat: failed to create proc entry\n");
		return -1;
	}
	return 0;
}

__initcall(uid_stat_init);
