/*
 * 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.gnu.org/licenses/gpl-2.0.html
 *
 * 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/seq_file.h>
#include <linux/statfs.h>
#include "../include/lprocfs_status.h"
#include "../include/obd_class.h"
#include "lmv_internal.h"

static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
			   char *buf)
{
	struct obd_device *dev = container_of(kobj, struct obd_device,
					      obd_kobj);
	struct lmv_desc *desc;

	desc = &dev->u.lmv.desc;
	return sprintf(buf, "%u\n", desc->ld_tgt_count);
}
LUSTRE_RO_ATTR(numobd);

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

static enum placement_policy 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(enum placement_policy placement)
{
	LASSERT(placement < PLACEMENT_MAX_POLICY);
	return placement_name[placement];
}

static ssize_t placement_show(struct kobject *kobj, struct attribute *attr,
			      char *buf)
{
	struct obd_device *dev = container_of(kobj, struct obd_device,
					      obd_kobj);
	struct lmv_obd *lmv;

	lmv = &dev->u.lmv;
	return sprintf(buf, "%s\n", placement_policy2name(lmv->lmv_placement));
}

#define MAX_POLICY_STRING_SIZE 64

static ssize_t placement_store(struct kobject *kobj, struct attribute *attr,
			       const char *buffer,
			       size_t count)
{
	struct obd_device *dev = container_of(kobj, struct obd_device,
					      obd_kobj);
	char dummy[MAX_POLICY_STRING_SIZE + 1];
	enum placement_policy policy;
	struct lmv_obd *lmv = &dev->u.lmv;

	memcpy(dummy, buffer, MAX_POLICY_STRING_SIZE);

	if (count > MAX_POLICY_STRING_SIZE)
		count = MAX_POLICY_STRING_SIZE;

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

	policy = placement_name2policy(dummy, count);
	if (policy != PLACEMENT_INVAL_POLICY) {
		spin_lock(&lmv->lmv_lock);
		lmv->lmv_placement = policy;
		spin_unlock(&lmv->lmv_lock);
	} else {
		return -EINVAL;
	}
	return count;
}
LUSTRE_RW_ATTR(placement);

static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
			      char *buf)
{
	struct obd_device *dev = container_of(kobj, struct obd_device,
					      obd_kobj);
	struct lmv_desc *desc;

	desc = &dev->u.lmv.desc;
	return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
}
LUSTRE_RO_ATTR(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);
	lmv = &dev->u.lmv;
	seq_printf(m, "%s\n", lmv->desc.ld_uuid.uuid);
	return 0;
}

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)
		return 0;
	seq_printf(p, "%u: %s %sACTIVE\n",
		   tgt->ltd_idx, tgt->ltd_uuid.uuid,
		   tgt->ltd_active ? "" : "IN");
	return 0;
}

static const 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 = inode->i_private;

	return 0;
}

static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
	{ "desc_uuid",	  &lmv_desc_uuid_fops,    NULL, 0 },
	{ NULL }
};

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

static struct attribute *lmv_attrs[] = {
	&lustre_attr_activeobd.attr,
	&lustre_attr_numobd.attr,
	&lustre_attr_placement.attr,
	NULL,
};

static struct attribute_group lmv_attr_group = {
	.attrs = lmv_attrs,
};

void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
{
	lvars->sysfs_vars     = &lmv_attr_group;
	lvars->obd_vars       = lprocfs_lmv_obd_vars;
}
