/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * 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 version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

#define DEBUG_SUBSYSTEM S_CLASS

#include <linux/version.h>
#include <linux/seq_file.h>
#include <asm/statfs.h>
#include <lprocfs_status.h>
#include <obd_class.h>

#ifndef LPROCFS
static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
#else
static int lmv_numobd_seq_show(struct seq_file *m, void *v)
{
	struct obd_device       *dev = (struct obd_device *)m->private;
	struct lmv_desc	 *desc;

	LASSERT(dev != NULL);
	desc = &dev->u.lmv.desc;
	return seq_printf(m, "%u\n", desc->ld_tgt_count);
}
LPROC_SEQ_FOPS_RO(lmv_numobd);

static const char *placement_name[] = {
	[PLACEMENT_CHAR_POLICY] = "CHAR",
	[PLACEMENT_NID_POLICY]  = "NID",
	[PLACEMENT_INVAL_POLICY]  = "INVAL"
};

static placement_policy_t placement_name2policy(char *name, int len)
{
	int		     i;

	for (i = 0; i < PLACEMENT_MAX_POLICY; i++) {
		if (!strncmp(placement_name[i], name, len))
			return i;
	}
	return PLACEMENT_INVAL_POLICY;
}

static const char *placement_policy2name(placement_policy_t placement)
{
	LASSERT(placement < PLACEMENT_MAX_POLICY);
	return placement_name[placement];
}

static int lmv_placement_seq_show(struct seq_file *m, void *v)
{
	struct obd_device       *dev = (struct obd_device *)m->private;
	struct lmv_obd	  *lmv;

	LASSERT(dev != NULL);
	lmv = &dev->u.lmv;
	return seq_printf(m, "%s\n", placement_policy2name(lmv->lmv_placement));
}

#define MAX_POLICY_STRING_SIZE 64

static ssize_t lmv_placement_seq_write(struct file *file, const char *buffer,
				   size_t count, loff_t *off)
{
	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
	char		     dummy[MAX_POLICY_STRING_SIZE + 1];
	int		      len = count;
	placement_policy_t       policy;
	struct lmv_obd	  *lmv;

	if (copy_from_user(dummy, buffer, MAX_POLICY_STRING_SIZE))
		return -EFAULT;

	LASSERT(dev != NULL);
	lmv = &dev->u.lmv;

	if (len > MAX_POLICY_STRING_SIZE)
		len = MAX_POLICY_STRING_SIZE;

	if (dummy[len - 1] == '\n')
		len--;
	dummy[len] = '\0';

	policy = placement_name2policy(dummy, len);
	if (policy != PLACEMENT_INVAL_POLICY) {
		spin_lock(&lmv->lmv_lock);
		lmv->lmv_placement = policy;
		spin_unlock(&lmv->lmv_lock);
	} else {
		CERROR("Invalid placement policy \"%s\"!\n", dummy);
		return -EINVAL;
	}
	return count;
}
LPROC_SEQ_FOPS(lmv_placement);

static int lmv_activeobd_seq_show(struct seq_file *m, void *v)
{
	struct obd_device       *dev = (struct obd_device *)m->private;
	struct lmv_desc	 *desc;

	LASSERT(dev != NULL);
	desc = &dev->u.lmv.desc;
	return seq_printf(m, "%u\n", desc->ld_active_tgt_count);
}
LPROC_SEQ_FOPS_RO(lmv_activeobd);

static int lmv_desc_uuid_seq_show(struct seq_file *m, void *v)
{
	struct obd_device *dev = (struct obd_device *)m->private;
	struct lmv_obd	  *lmv;

	LASSERT(dev != NULL);
	lmv = &dev->u.lmv;
	return seq_printf(m, "%s\n", lmv->desc.ld_uuid.uuid);
}
LPROC_SEQ_FOPS_RO(lmv_desc_uuid);

static void *lmv_tgt_seq_start(struct seq_file *p, loff_t *pos)
{
	struct obd_device       *dev = p->private;
	struct lmv_obd	  *lmv = &dev->u.lmv;
	return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
}

static void lmv_tgt_seq_stop(struct seq_file *p, void *v)
{
	return;
}

static void *lmv_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
{
	struct obd_device       *dev = p->private;
	struct lmv_obd	  *lmv = &dev->u.lmv;
	++*pos;
	return (*pos >= lmv->desc.ld_tgt_count) ? NULL : lmv->tgts[*pos];
}

static int lmv_tgt_seq_show(struct seq_file *p, void *v)
{
	struct lmv_tgt_desc     *tgt = v;

	if (tgt == NULL)
		return 0;
	return seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_idx,
			  tgt->ltd_uuid.uuid, tgt->ltd_active ? "" : "IN");
}

struct seq_operations lmv_tgt_sops = {
	.start		 = lmv_tgt_seq_start,
	.stop		  = lmv_tgt_seq_stop,
	.next		  = lmv_tgt_seq_next,
	.show		  = lmv_tgt_seq_show,
};

static int lmv_target_seq_open(struct inode *inode, struct file *file)
{
	struct seq_file	 *seq;
	int		     rc;

	rc = seq_open(file, &lmv_tgt_sops);
	if (rc)
		return rc;

	seq = file->private_data;
	seq->private = PDE_DATA(inode);

	return 0;
}

LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid);

struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
	{ "numobd",	  &lmv_numobd_fops,	  0, 0 },
	{ "placement",	  &lmv_placement_fops,    0, 0 },
	{ "activeobd",	  &lmv_activeobd_fops,    0, 0 },
	{ "uuid",	  &lmv_uuid_fops,	  0, 0 },
	{ "desc_uuid",	  &lmv_desc_uuid_fops,    0, 0 },
	{ 0 }
};

LPROC_SEQ_FOPS_RO_TYPE(lmv, numrefs);

static struct lprocfs_vars lprocfs_lmv_module_vars[] = {
	{ "num_refs",	   &lmv_numrefs_fops, 0, 0 },
	{ 0 }
};

struct file_operations lmv_proc_target_fops = {
	.owner		= THIS_MODULE,
	.open		 = lmv_target_seq_open,
	.read		 = seq_read,
	.llseek	       = seq_lseek,
	.release	      = seq_release,
};

#endif /* LPROCFS */
void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
{
	lvars->module_vars    = lprocfs_lmv_module_vars;
	lvars->obd_vars       = lprocfs_lmv_obd_vars;
}
