/* Global fscache object list maintainer and viewer
 *
 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#define FSCACHE_DEBUG_LEVEL COOKIE
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/key.h>
#include <keys/user-type.h>
#include "internal.h"

static struct rb_root fscache_object_list;
static DEFINE_RWLOCK(fscache_object_list_lock);

struct fscache_objlist_data {
	unsigned long	config;		/* display configuration */
#define FSCACHE_OBJLIST_CONFIG_KEY	0x00000001	/* show object keys */
#define FSCACHE_OBJLIST_CONFIG_AUX	0x00000002	/* show object auxdata */
#define FSCACHE_OBJLIST_CONFIG_COOKIE	0x00000004	/* show objects with cookies */
#define FSCACHE_OBJLIST_CONFIG_NOCOOKIE	0x00000008	/* show objects without cookies */
#define FSCACHE_OBJLIST_CONFIG_BUSY	0x00000010	/* show busy objects */
#define FSCACHE_OBJLIST_CONFIG_IDLE	0x00000020	/* show idle objects */
#define FSCACHE_OBJLIST_CONFIG_PENDWR	0x00000040	/* show objects with pending writes */
#define FSCACHE_OBJLIST_CONFIG_NOPENDWR	0x00000080	/* show objects without pending writes */
#define FSCACHE_OBJLIST_CONFIG_READS	0x00000100	/* show objects with active reads */
#define FSCACHE_OBJLIST_CONFIG_NOREADS	0x00000200	/* show objects without active reads */
#define FSCACHE_OBJLIST_CONFIG_EVENTS	0x00000400	/* show objects with events */
#define FSCACHE_OBJLIST_CONFIG_NOEVENTS	0x00000800	/* show objects without no events */
#define FSCACHE_OBJLIST_CONFIG_WORK	0x00001000	/* show objects with slow work */
#define FSCACHE_OBJLIST_CONFIG_NOWORK	0x00002000	/* show objects without slow work */

	u8		buf[512];	/* key and aux data buffer */
};

/*
 * Add an object to the object list
 * - we use the address of the fscache_object structure as the key into the
 *   tree
 */
void fscache_objlist_add(struct fscache_object *obj)
{
	struct fscache_object *xobj;
	struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL;

	write_lock(&fscache_object_list_lock);

	while (*p) {
		parent = *p;
		xobj = rb_entry(parent, struct fscache_object, objlist_link);

		if (obj < xobj)
			p = &(*p)->rb_left;
		else if (obj > xobj)
			p = &(*p)->rb_right;
		else
			BUG();
	}

	rb_link_node(&obj->objlist_link, parent, p);
	rb_insert_color(&obj->objlist_link, &fscache_object_list);

	write_unlock(&fscache_object_list_lock);
}

/**
 * fscache_object_destroy - Note that a cache object is about to be destroyed
 * @object: The object to be destroyed
 *
 * Note the imminent destruction and deallocation of a cache object record.
 */
void fscache_object_destroy(struct fscache_object *obj)
{
	write_lock(&fscache_object_list_lock);

	BUG_ON(RB_EMPTY_ROOT(&fscache_object_list));
	rb_erase(&obj->objlist_link, &fscache_object_list);

	write_unlock(&fscache_object_list_lock);
}
EXPORT_SYMBOL(fscache_object_destroy);

/*
 * find the object in the tree on or after the specified index
 */
static struct fscache_object *fscache_objlist_lookup(loff_t *_pos)
{
	struct fscache_object *pobj, *obj, *minobj = NULL;
	struct rb_node *p;
	unsigned long pos;

	if (*_pos >= (unsigned long) ERR_PTR(-ENOENT))
		return NULL;
	pos = *_pos;

	/* banners (can't represent line 0 by pos 0 as that would involve
	 * returning a NULL pointer) */
	if (pos == 0)
		return (struct fscache_object *) ++(*_pos);
	if (pos < 3)
		return (struct fscache_object *)pos;

	pobj = (struct fscache_object *)pos;
	p = fscache_object_list.rb_node;
	while (p) {
		obj = rb_entry(p, struct fscache_object, objlist_link);
		if (pobj < obj) {
			if (!minobj || minobj > obj)
				minobj = obj;
			p = p->rb_left;
		} else if (pobj > obj) {
			p = p->rb_right;
		} else {
			minobj = obj;
			break;
		}
		obj = NULL;
	}

	if (!minobj)
		*_pos = (unsigned long) ERR_PTR(-ENOENT);
	else if (minobj != obj)
		*_pos = (unsigned long) minobj;
	return minobj;
}

/*
 * set up the iterator to start reading from the first line
 */
static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos)
	__acquires(&fscache_object_list_lock)
{
	read_lock(&fscache_object_list_lock);
	return fscache_objlist_lookup(_pos);
}

/*
 * move to the next line
 */
static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos)
{
	(*_pos)++;
	return fscache_objlist_lookup(_pos);
}

/*
 * clean up after reading
 */
static void fscache_objlist_stop(struct seq_file *m, void *v)
	__releases(&fscache_object_list_lock)
{
	read_unlock(&fscache_object_list_lock);
}

/*
 * display an object
 */
static int fscache_objlist_show(struct seq_file *m, void *v)
{
	struct fscache_objlist_data *data = m->private;
	struct fscache_object *obj = v;
	unsigned long config = data->config;
	uint16_t keylen, auxlen;
	char _type[3], *type;
	bool no_cookie;
	u8 *buf = data->buf, *p;

	if ((unsigned long) v == 1) {
		seq_puts(m, "OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS"
			 " EM EV F S"
			 " | NETFS_COOKIE_DEF TY FL NETFS_DATA");
		if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
			      FSCACHE_OBJLIST_CONFIG_AUX))
			seq_puts(m, "       ");
		if (config & FSCACHE_OBJLIST_CONFIG_KEY)
			seq_puts(m, "OBJECT_KEY");
		if ((config & (FSCACHE_OBJLIST_CONFIG_KEY |
			       FSCACHE_OBJLIST_CONFIG_AUX)) ==
		    (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX))
			seq_puts(m, ", ");
		if (config & FSCACHE_OBJLIST_CONFIG_AUX)
			seq_puts(m, "AUX_DATA");
		seq_puts(m, "\n");
		return 0;
	}

	if ((unsigned long) v == 2) {
		seq_puts(m, "======== ======== ==== ===== === === === == ====="
			 " == == = ="
			 " | ================ == == ================");
		if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
			      FSCACHE_OBJLIST_CONFIG_AUX))
			seq_puts(m, " ================");
		seq_puts(m, "\n");
		return 0;
	}

	/* filter out any unwanted objects */
#define FILTER(criterion, _yes, _no)					\
	do {								\
		unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes;	\
		unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no;	\
		if (criterion) {					\
			if (!(config & yes))				\
				return 0;				\
		} else {						\
			if (!(config & no))				\
				return 0;				\
		}							\
	} while(0)

	if (~config) {
		FILTER(obj->cookie,
		       COOKIE, NOCOOKIE);
		FILTER(obj->state != FSCACHE_OBJECT_ACTIVE ||
		       obj->n_ops != 0 ||
		       obj->n_obj_ops != 0 ||
		       obj->flags ||
		       !list_empty(&obj->dependents),
		       BUSY, IDLE);
		FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags),
		       PENDWR, NOPENDWR);
		FILTER(atomic_read(&obj->n_reads),
		       READS, NOREADS);
		FILTER(obj->events & obj->event_mask,
		       EVENTS, NOEVENTS);
		FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW),
		       WORK, NOWORK);
	}

	seq_printf(m,
		   "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ",
		   obj->debug_id,
		   obj->parent ? obj->parent->debug_id : -1,
		   fscache_object_states_short[obj->state],
		   obj->n_children,
		   obj->n_ops,
		   obj->n_obj_ops,
		   obj->n_in_progress,
		   obj->n_exclusive,
		   atomic_read(&obj->n_reads),
		   obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK,
		   obj->events,
		   obj->flags,
		   obj->work.flags);

	no_cookie = true;
	keylen = auxlen = 0;
	if (obj->cookie) {
		spin_lock(&obj->lock);
		if (obj->cookie) {
			switch (obj->cookie->def->type) {
			case 0:
				type = "IX";
				break;
			case 1:
				type = "DT";
				break;
			default:
				sprintf(_type, "%02u",
					obj->cookie->def->type);
				type = _type;
				break;
			}

			seq_printf(m, "%-16s %s %2lx %16p",
				   obj->cookie->def->name,
				   type,
				   obj->cookie->flags,
				   obj->cookie->netfs_data);

			if (obj->cookie->def->get_key &&
			    config & FSCACHE_OBJLIST_CONFIG_KEY)
				keylen = obj->cookie->def->get_key(
					obj->cookie->netfs_data,
					buf, 400);

			if (obj->cookie->def->get_aux &&
			    config & FSCACHE_OBJLIST_CONFIG_AUX)
				auxlen = obj->cookie->def->get_aux(
					obj->cookie->netfs_data,
					buf + keylen, 512 - keylen);

			no_cookie = false;
		}
		spin_unlock(&obj->lock);

		if (!no_cookie && (keylen > 0 || auxlen > 0)) {
			seq_printf(m, " ");
			for (p = buf; keylen > 0; keylen--)
				seq_printf(m, "%02x", *p++);
			if (auxlen > 0) {
				if (config & FSCACHE_OBJLIST_CONFIG_KEY)
					seq_printf(m, ", ");
				for (; auxlen > 0; auxlen--)
					seq_printf(m, "%02x", *p++);
			}
		}
	}

	if (no_cookie)
		seq_printf(m, "<no_cookie>\n");
	else
		seq_printf(m, "\n");
	return 0;
}

static const struct seq_operations fscache_objlist_ops = {
	.start		= fscache_objlist_start,
	.stop		= fscache_objlist_stop,
	.next		= fscache_objlist_next,
	.show		= fscache_objlist_show,
};

/*
 * get the configuration for filtering the list
 */
static void fscache_objlist_config(struct fscache_objlist_data *data)
{
#ifdef CONFIG_KEYS
	struct user_key_payload *confkey;
	unsigned long config;
	struct key *key;
	const char *buf;
	int len;

	key = request_key(&key_type_user, "fscache:objlist", NULL);
	if (IS_ERR(key))
		goto no_config;

	config = 0;
	rcu_read_lock();

	confkey = key->payload.data;
	buf = confkey->data;

	for (len = confkey->datalen - 1; len >= 0; len--) {
		switch (buf[len]) {
		case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY;		break;
		case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX;		break;
		case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE;	break;
		case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE;	break;
		case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY;	break;
		case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE;	break;
		case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR;	break;
		case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR;	break;
		case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS;	break;
		case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS;	break;
		case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK;	break;
		case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK;	break;
		}
	}

	rcu_read_unlock();
	key_put(key);

	if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE)))
	    config   |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE;
	if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE)))
	    config   |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE;
	if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR)))
	    config   |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR;
	if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS)))
	    config   |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS;
	if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS)))
	    config   |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS;
	if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK)))
	    config   |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK;

	data->config = config;
	return;

no_config:
#endif
	data->config = ULONG_MAX;
}

/*
 * open "/proc/fs/fscache/objects" to provide a list of active objects
 * - can be configured by a user-defined key added to the caller's keyrings
 */
static int fscache_objlist_open(struct inode *inode, struct file *file)
{
	struct fscache_objlist_data *data;
	struct seq_file *m;
	int ret;

	ret = seq_open(file, &fscache_objlist_ops);
	if (ret < 0)
		return ret;

	m = file->private_data;

	/* buffer for key extraction */
	data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL);
	if (!data) {
		seq_release(inode, file);
		return -ENOMEM;
	}

	/* get the configuration key */
	fscache_objlist_config(data);

	m->private = data;
	return 0;
}

/*
 * clean up on close
 */
static int fscache_objlist_release(struct inode *inode, struct file *file)
{
	struct seq_file *m = file->private_data;

	kfree(m->private);
	m->private = NULL;
	return seq_release(inode, file);
}

const struct file_operations fscache_objlist_fops = {
	.owner		= THIS_MODULE,
	.open		= fscache_objlist_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= fscache_objlist_release,
};
