/*
 * 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) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2015, 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 <obd_support.h>
#include <obd.h>
#include <lprocfs_status.h>
#include <uapi/linux/lustre/lustre_idl.h>
#include <lustre_net.h>
#include <obd_class.h>
#include "ptlrpc_internal.h"

static struct ll_rpc_opcode {
	__u32       opcode;
	const char *opname;
} ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
	{ OST_REPLY,	"ost_reply" },
	{ OST_GETATTR,      "ost_getattr" },
	{ OST_SETATTR,      "ost_setattr" },
	{ OST_READ,	 "ost_read" },
	{ OST_WRITE,	"ost_write" },
	{ OST_CREATE,       "ost_create" },
	{ OST_DESTROY,      "ost_destroy" },
	{ OST_GET_INFO,     "ost_get_info" },
	{ OST_CONNECT,      "ost_connect" },
	{ OST_DISCONNECT,   "ost_disconnect" },
	{ OST_PUNCH,	"ost_punch" },
	{ OST_OPEN,	 "ost_open" },
	{ OST_CLOSE,	"ost_close" },
	{ OST_STATFS,       "ost_statfs" },
	{ 14,		NULL },    /* formerly OST_SAN_READ */
	{ 15,		NULL },    /* formerly OST_SAN_WRITE */
	{ OST_SYNC,	 "ost_sync" },
	{ OST_SET_INFO,     "ost_set_info" },
	{ OST_QUOTACHECK,   "ost_quotacheck" },
	{ OST_QUOTACTL,     "ost_quotactl" },
	{ OST_QUOTA_ADJUST_QUNIT, "ost_quota_adjust_qunit" },
	{ MDS_GETATTR,      "mds_getattr" },
	{ MDS_GETATTR_NAME, "mds_getattr_lock" },
	{ MDS_CLOSE,	"mds_close" },
	{ MDS_REINT,	"mds_reint" },
	{ MDS_READPAGE,     "mds_readpage" },
	{ MDS_CONNECT,      "mds_connect" },
	{ MDS_DISCONNECT,   "mds_disconnect" },
	{ MDS_GETSTATUS,    "mds_getstatus" },
	{ MDS_STATFS,       "mds_statfs" },
	{ MDS_PIN,	  "mds_pin" },
	{ MDS_UNPIN,	"mds_unpin" },
	{ MDS_SYNC,	 "mds_sync" },
	{ MDS_DONE_WRITING, "mds_done_writing" },
	{ MDS_SET_INFO,     "mds_set_info" },
	{ MDS_QUOTACHECK,   "mds_quotacheck" },
	{ MDS_QUOTACTL,     "mds_quotactl" },
	{ MDS_GETXATTR,     "mds_getxattr" },
	{ MDS_SETXATTR,     "mds_setxattr" },
	{ MDS_WRITEPAGE,    "mds_writepage" },
	{ MDS_IS_SUBDIR,    "mds_is_subdir" },
	{ MDS_GET_INFO,     "mds_get_info" },
	{ MDS_HSM_STATE_GET, "mds_hsm_state_get" },
	{ MDS_HSM_STATE_SET, "mds_hsm_state_set" },
	{ MDS_HSM_ACTION,   "mds_hsm_action" },
	{ MDS_HSM_PROGRESS, "mds_hsm_progress" },
	{ MDS_HSM_REQUEST,  "mds_hsm_request" },
	{ MDS_HSM_CT_REGISTER, "mds_hsm_ct_register" },
	{ MDS_HSM_CT_UNREGISTER, "mds_hsm_ct_unregister" },
	{ MDS_SWAP_LAYOUTS,	"mds_swap_layouts" },
	{ LDLM_ENQUEUE,     "ldlm_enqueue" },
	{ LDLM_CONVERT,     "ldlm_convert" },
	{ LDLM_CANCEL,      "ldlm_cancel" },
	{ LDLM_BL_CALLBACK, "ldlm_bl_callback" },
	{ LDLM_CP_CALLBACK, "ldlm_cp_callback" },
	{ LDLM_GL_CALLBACK, "ldlm_gl_callback" },
	{ LDLM_SET_INFO,    "ldlm_set_info" },
	{ MGS_CONNECT,      "mgs_connect" },
	{ MGS_DISCONNECT,   "mgs_disconnect" },
	{ MGS_EXCEPTION,    "mgs_exception" },
	{ MGS_TARGET_REG,   "mgs_target_reg" },
	{ MGS_TARGET_DEL,   "mgs_target_del" },
	{ MGS_SET_INFO,     "mgs_set_info" },
	{ MGS_CONFIG_READ,  "mgs_config_read" },
	{ OBD_PING,	 "obd_ping" },
	{ OBD_LOG_CANCEL,	"llog_cancel" },
	{ OBD_QC_CALLBACK,  "obd_quota_callback" },
	{ OBD_IDX_READ,	    "dt_index_read" },
	{ LLOG_ORIGIN_HANDLE_CREATE,	 "llog_origin_handle_open" },
	{ LLOG_ORIGIN_HANDLE_NEXT_BLOCK, "llog_origin_handle_next_block" },
	{ LLOG_ORIGIN_HANDLE_READ_HEADER, "llog_origin_handle_read_header" },
	{ LLOG_ORIGIN_HANDLE_WRITE_REC,  "llog_origin_handle_write_rec" },
	{ LLOG_ORIGIN_HANDLE_CLOSE,      "llog_origin_handle_close" },
	{ LLOG_ORIGIN_CONNECT,	   "llog_origin_connect" },
	{ LLOG_CATINFO,		  "llog_catinfo" },
	{ LLOG_ORIGIN_HANDLE_PREV_BLOCK, "llog_origin_handle_prev_block" },
	{ LLOG_ORIGIN_HANDLE_DESTROY,    "llog_origin_handle_destroy" },
	{ QUOTA_DQACQ,      "quota_acquire" },
	{ QUOTA_DQREL,      "quota_release" },
	{ SEQ_QUERY,	"seq_query" },
	{ SEC_CTX_INIT,     "sec_ctx_init" },
	{ SEC_CTX_INIT_CONT, "sec_ctx_init_cont" },
	{ SEC_CTX_FINI,     "sec_ctx_fini" },
	{ FLD_QUERY,	"fld_query" },
	{ FLD_READ,	"fld_read" },
};

static struct ll_eopcode {
	__u32       opcode;
	const char *opname;
} ll_eopcode_table[EXTRA_LAST_OPC] = {
	{ LDLM_GLIMPSE_ENQUEUE, "ldlm_glimpse_enqueue" },
	{ LDLM_PLAIN_ENQUEUE,   "ldlm_plain_enqueue" },
	{ LDLM_EXTENT_ENQUEUE,  "ldlm_extent_enqueue" },
	{ LDLM_FLOCK_ENQUEUE,   "ldlm_flock_enqueue" },
	{ LDLM_IBITS_ENQUEUE,   "ldlm_ibits_enqueue" },
	{ MDS_REINT_SETATTR,    "mds_reint_setattr" },
	{ MDS_REINT_CREATE,     "mds_reint_create" },
	{ MDS_REINT_LINK,       "mds_reint_link" },
	{ MDS_REINT_UNLINK,     "mds_reint_unlink" },
	{ MDS_REINT_RENAME,     "mds_reint_rename" },
	{ MDS_REINT_OPEN,       "mds_reint_open" },
	{ MDS_REINT_SETXATTR,   "mds_reint_setxattr" },
	{ BRW_READ_BYTES,       "read_bytes" },
	{ BRW_WRITE_BYTES,      "write_bytes" },
};

const char *ll_opcode2str(__u32 opcode)
{
	/* When one of the assertions below fail, chances are that:
	 *     1) A new opcode was added in include/lustre/lustre_idl.h,
	 *	but is missing from the table above.
	 * or  2) The opcode space was renumbered or rearranged,
	 *	and the opcode_offset() function in
	 *	ptlrpc_internal.h needs to be modified.
	 */
	__u32 offset = opcode_offset(opcode);

	LASSERTF(offset < LUSTRE_MAX_OPCODES,
		 "offset %u >= LUSTRE_MAX_OPCODES %u\n",
		 offset, LUSTRE_MAX_OPCODES);
	LASSERTF(ll_rpc_opcode_table[offset].opcode == opcode,
		 "ll_rpc_opcode_table[%u].opcode %u != opcode %u\n",
		 offset, ll_rpc_opcode_table[offset].opcode, opcode);
	return ll_rpc_opcode_table[offset].opname;
}

static const char *ll_eopcode2str(__u32 opcode)
{
	LASSERT(ll_eopcode_table[opcode].opcode == opcode);
	return ll_eopcode_table[opcode].opname;
}

static void
ptlrpc_ldebugfs_register(struct dentry *root, char *dir,
			 char *name,
			 struct dentry **debugfs_root_ret,
			 struct lprocfs_stats **stats_ret)
{
	struct dentry *svc_debugfs_entry;
	struct lprocfs_stats *svc_stats;
	int i, rc;
	unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX |
					  LPROCFS_CNTR_STDDEV;

	LASSERT(!*debugfs_root_ret);
	LASSERT(!*stats_ret);

	svc_stats = lprocfs_alloc_stats(EXTRA_MAX_OPCODES + LUSTRE_MAX_OPCODES,
					0);
	if (!svc_stats)
		return;

	if (dir) {
		svc_debugfs_entry = ldebugfs_register(dir, root, NULL, NULL);
		if (IS_ERR(svc_debugfs_entry)) {
			lprocfs_free_stats(&svc_stats);
			return;
		}
	} else {
		svc_debugfs_entry = root;
	}

	lprocfs_counter_init(svc_stats, PTLRPC_REQWAIT_CNTR,
			     svc_counter_config, "req_waittime", "usec");
	lprocfs_counter_init(svc_stats, PTLRPC_REQQDEPTH_CNTR,
			     svc_counter_config, "req_qdepth", "reqs");
	lprocfs_counter_init(svc_stats, PTLRPC_REQACTIVE_CNTR,
			     svc_counter_config, "req_active", "reqs");
	lprocfs_counter_init(svc_stats, PTLRPC_TIMEOUT,
			     svc_counter_config, "req_timeout", "sec");
	lprocfs_counter_init(svc_stats, PTLRPC_REQBUF_AVAIL_CNTR,
			     svc_counter_config, "reqbuf_avail", "bufs");
	for (i = 0; i < EXTRA_LAST_OPC; i++) {
		char *units;

		switch (i) {
		case BRW_WRITE_BYTES:
		case BRW_READ_BYTES:
			units = "bytes";
			break;
		default:
			units = "reqs";
			break;
		}
		lprocfs_counter_init(svc_stats, PTLRPC_LAST_CNTR + i,
				     svc_counter_config,
				     ll_eopcode2str(i), units);
	}
	for (i = 0; i < LUSTRE_MAX_OPCODES; i++) {
		__u32 opcode = ll_rpc_opcode_table[i].opcode;

		lprocfs_counter_init(svc_stats,
				     EXTRA_MAX_OPCODES + i, svc_counter_config,
				     ll_opcode2str(opcode), "usec");
	}

	rc = ldebugfs_register_stats(svc_debugfs_entry, name, svc_stats);
	if (rc < 0) {
		if (dir)
			ldebugfs_remove(&svc_debugfs_entry);
		lprocfs_free_stats(&svc_stats);
	} else {
		if (dir)
			*debugfs_root_ret = svc_debugfs_entry;
		*stats_ret = svc_stats;
	}
}

static int
ptlrpc_lprocfs_req_history_len_seq_show(struct seq_file *m, void *v)
{
	struct ptlrpc_service *svc = m->private;
	struct ptlrpc_service_part *svcpt;
	int total = 0;
	int i;

	ptlrpc_service_for_each_part(svcpt, i, svc)
		total += svcpt->scp_hist_nrqbds;

	seq_printf(m, "%d\n", total);
	return 0;
}

LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_req_history_len);

static int
ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n)
{
	struct ptlrpc_service *svc = m->private;
	struct ptlrpc_service_part *svcpt;
	int total = 0;
	int i;

	ptlrpc_service_for_each_part(svcpt, i, svc)
		total += svc->srv_hist_nrqbds_cpt_max;

	seq_printf(m, "%d\n", total);
	return 0;
}

static ssize_t
ptlrpc_lprocfs_req_history_max_seq_write(struct file *file,
					 const char __user *buffer,
					 size_t count, loff_t *off)
{
	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
	int bufpages;
	int val;
	int rc;

	rc = lprocfs_write_helper(buffer, count, &val);
	if (rc < 0)
		return rc;

	if (val < 0)
		return -ERANGE;

	/* This sanity check is more of an insanity check; we can still
	 * hose a kernel by allowing the request history to grow too
	 * far.
	 */
	bufpages = (svc->srv_buf_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
	if (val > totalram_pages / (2 * bufpages))
		return -ERANGE;

	spin_lock(&svc->srv_lock);

	if (val == 0)
		svc->srv_hist_nrqbds_cpt_max = 0;
	else
		svc->srv_hist_nrqbds_cpt_max = max(1, (val / svc->srv_ncpts));

	spin_unlock(&svc->srv_lock);

	return count;
}

LPROC_SEQ_FOPS(ptlrpc_lprocfs_req_history_max);

static ssize_t threads_min_show(struct kobject *kobj, struct attribute *attr,
				char *buf)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);

	return sprintf(buf, "%d\n", svc->srv_nthrs_cpt_init * svc->srv_ncpts);
}

static ssize_t threads_min_store(struct kobject *kobj, struct attribute *attr,
				 const char *buffer, size_t count)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);
	unsigned long val;
	int rc = kstrtoul(buffer, 10, &val);

	if (rc < 0)
		return rc;

	if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
		return -ERANGE;

	spin_lock(&svc->srv_lock);
	if (val > svc->srv_nthrs_cpt_limit * svc->srv_ncpts) {
		spin_unlock(&svc->srv_lock);
		return -ERANGE;
	}

	svc->srv_nthrs_cpt_init = val / svc->srv_ncpts;

	spin_unlock(&svc->srv_lock);

	return count;
}
LUSTRE_RW_ATTR(threads_min);

static ssize_t threads_started_show(struct kobject *kobj,
				    struct attribute *attr,
				    char *buf)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);
	struct ptlrpc_service_part *svcpt;
	int total = 0;
	int i;

	ptlrpc_service_for_each_part(svcpt, i, svc)
		total += svcpt->scp_nthrs_running;

	return sprintf(buf, "%d\n", total);
}
LUSTRE_RO_ATTR(threads_started);

static ssize_t threads_max_show(struct kobject *kobj, struct attribute *attr,
				char *buf)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);

	return sprintf(buf, "%d\n", svc->srv_nthrs_cpt_limit * svc->srv_ncpts);
}

static ssize_t threads_max_store(struct kobject *kobj, struct attribute *attr,
				 const char *buffer, size_t count)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);
	unsigned long val;
	int rc = kstrtoul(buffer, 10, &val);

	if (rc < 0)
		return rc;

	if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
		return -ERANGE;

	spin_lock(&svc->srv_lock);
	if (val < svc->srv_nthrs_cpt_init * svc->srv_ncpts) {
		spin_unlock(&svc->srv_lock);
		return -ERANGE;
	}

	svc->srv_nthrs_cpt_limit = val / svc->srv_ncpts;

	spin_unlock(&svc->srv_lock);

	return count;
}
LUSTRE_RW_ATTR(threads_max);

/**
 * \addtogoup nrs
 * @{
 */

/**
 * Translates \e ptlrpc_nrs_pol_state values to human-readable strings.
 *
 * \param[in] state The policy state
 */
static const char *nrs_state2str(enum ptlrpc_nrs_pol_state state)
{
	switch (state) {
	default:
		LBUG();
	case NRS_POL_STATE_INVALID:
		return "invalid";
	case NRS_POL_STATE_STOPPED:
		return "stopped";
	case NRS_POL_STATE_STOPPING:
		return "stopping";
	case NRS_POL_STATE_STARTING:
		return "starting";
	case NRS_POL_STATE_STARTED:
		return "started";
	}
}

/**
 * Obtains status information for \a policy.
 *
 * Information is copied in \a info.
 *
 * \param[in] policy The policy
 * \param[out] info  Holds returned status information
 */
static void nrs_policy_get_info_locked(struct ptlrpc_nrs_policy *policy,
				       struct ptlrpc_nrs_pol_info *info)
{
	assert_spin_locked(&policy->pol_nrs->nrs_lock);

	memcpy(info->pi_name, policy->pol_desc->pd_name, NRS_POL_NAME_MAX);

	info->pi_fallback    = !!(policy->pol_flags & PTLRPC_NRS_FL_FALLBACK);
	info->pi_state	     = policy->pol_state;
	/**
	 * XXX: These are accessed without holding
	 * ptlrpc_service_part::scp_req_lock.
	 */
	info->pi_req_queued  = policy->pol_req_queued;
	info->pi_req_started = policy->pol_req_started;
}

/**
 * Reads and prints policy status information for all policies of a PTLRPC
 * service.
 */
static int ptlrpc_lprocfs_nrs_seq_show(struct seq_file *m, void *n)
{
	struct ptlrpc_service *svc = m->private;
	struct ptlrpc_service_part *svcpt;
	struct ptlrpc_nrs *nrs;
	struct ptlrpc_nrs_policy *policy;
	struct ptlrpc_nrs_pol_info *infos;
	struct ptlrpc_nrs_pol_info tmp;
	unsigned int num_pols;
	unsigned int pol_idx = 0;
	bool hp = false;
	int i;
	int rc = 0;

	/**
	 * Serialize NRS core lprocfs operations with policy registration/
	 * unregistration.
	 */
	mutex_lock(&nrs_core.nrs_mutex);

	/**
	 * Use the first service partition's regular NRS head in order to obtain
	 * the number of policies registered with NRS heads of this service. All
	 * service partitions will have the same number of policies.
	 */
	nrs = nrs_svcpt2nrs(svc->srv_parts[0], false);

	spin_lock(&nrs->nrs_lock);
	num_pols = svc->srv_parts[0]->scp_nrs_reg.nrs_num_pols;
	spin_unlock(&nrs->nrs_lock);

	infos = kcalloc(num_pols, sizeof(*infos), GFP_NOFS);
	if (!infos) {
		rc = -ENOMEM;
		goto unlock;
	}
again:

	ptlrpc_service_for_each_part(svcpt, i, svc) {
		nrs = nrs_svcpt2nrs(svcpt, hp);
		spin_lock(&nrs->nrs_lock);

		pol_idx = 0;

		list_for_each_entry(policy, &nrs->nrs_policy_list, pol_list) {
			LASSERT(pol_idx < num_pols);

			nrs_policy_get_info_locked(policy, &tmp);
			/**
			 * Copy values when handling the first service
			 * partition.
			 */
			if (i == 0) {
				memcpy(infos[pol_idx].pi_name, tmp.pi_name,
				       NRS_POL_NAME_MAX);
				memcpy(&infos[pol_idx].pi_state, &tmp.pi_state,
				       sizeof(tmp.pi_state));
				infos[pol_idx].pi_fallback = tmp.pi_fallback;
				/**
				 * For the rest of the service partitions
				 * sanity-check the values we get.
				 */
			} else {
				LASSERT(strncmp(infos[pol_idx].pi_name,
						tmp.pi_name,
						NRS_POL_NAME_MAX) == 0);
				/**
				 * Not asserting ptlrpc_nrs_pol_info::pi_state,
				 * because it may be different between
				 * instances of the same policy in different
				 * service partitions.
				 */
				LASSERT(infos[pol_idx].pi_fallback ==
					tmp.pi_fallback);
			}

			infos[pol_idx].pi_req_queued += tmp.pi_req_queued;
			infos[pol_idx].pi_req_started += tmp.pi_req_started;

			pol_idx++;
		}
		spin_unlock(&nrs->nrs_lock);
	}

	/**
	 * Policy status information output is in YAML format.
	 * For example:
	 *
	 *	regular_requests:
	 *	  - name: fifo
	 *	    state: started
	 *	    fallback: yes
	 *	    queued: 0
	 *	    active: 0
	 *
	 *	  - name: crrn
	 *	    state: started
	 *	    fallback: no
	 *	    queued: 2015
	 *	    active: 384
	 *
	 *	high_priority_requests:
	 *	  - name: fifo
	 *	    state: started
	 *	    fallback: yes
	 *	    queued: 0
	 *	    active: 2
	 *
	 *	  - name: crrn
	 *	    state: stopped
	 *	    fallback: no
	 *	    queued: 0
	 *	    active: 0
	 */
	seq_printf(m, "%s\n",
		   !hp ?  "\nregular_requests:" : "high_priority_requests:");

	for (pol_idx = 0; pol_idx < num_pols; pol_idx++) {
		seq_printf(m,  "  - name: %s\n"
			       "    state: %s\n"
			       "    fallback: %s\n"
			       "    queued: %-20d\n"
			       "    active: %-20d\n\n",
			       infos[pol_idx].pi_name,
			       nrs_state2str(infos[pol_idx].pi_state),
			       infos[pol_idx].pi_fallback ? "yes" : "no",
			       (int)infos[pol_idx].pi_req_queued,
			       (int)infos[pol_idx].pi_req_started);
	}

	if (!hp && nrs_svc_has_hp(svc)) {
		memset(infos, 0, num_pols * sizeof(*infos));

		/**
		 * Redo the processing for the service's HP NRS heads' policies.
		 */
		hp = true;
		goto again;
	}

	kfree(infos);
unlock:
	mutex_unlock(&nrs_core.nrs_mutex);

	return rc;
}

/**
 * The longest valid command string is the maximum policy name size, plus the
 * length of the " reg" substring
 */
#define LPROCFS_NRS_WR_MAX_CMD	(NRS_POL_NAME_MAX + sizeof(" reg") - 1)

/**
 * Starts and stops a given policy on a PTLRPC service.
 *
 * Commands consist of the policy name, followed by an optional [reg|hp] token;
 * if the optional token is omitted, the operation is performed on both the
 * regular and high-priority (if the service has one) NRS head.
 */
static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file,
					    const char __user *buffer,
					    size_t count, loff_t *off)
{
	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
	enum ptlrpc_nrs_queue_type queue = PTLRPC_NRS_QUEUE_BOTH;
	char *cmd;
	char *cmd_copy = NULL;
	char *token;
	int rc = 0;

	if (count >= LPROCFS_NRS_WR_MAX_CMD)
		return -EINVAL;

	cmd = kzalloc(LPROCFS_NRS_WR_MAX_CMD, GFP_NOFS);
	if (!cmd)
		return -ENOMEM;
	/**
	 * strsep() modifies its argument, so keep a copy
	 */
	cmd_copy = cmd;

	if (copy_from_user(cmd, buffer, count)) {
		rc = -EFAULT;
		goto out;
	}

	cmd[count] = '\0';

	token = strsep(&cmd, " ");

	if (strlen(token) > NRS_POL_NAME_MAX - 1) {
		rc = -EINVAL;
		goto out;
	}

	/**
	 * No [reg|hp] token has been specified
	 */
	if (!cmd)
		goto default_queue;

	/**
	 * The second token is either NULL, or an optional [reg|hp] string
	 */
	if (strcmp(cmd, "reg") == 0) {
		queue = PTLRPC_NRS_QUEUE_REG;
	} else if (strcmp(cmd, "hp") == 0) {
		queue = PTLRPC_NRS_QUEUE_HP;
	} else {
		rc = -EINVAL;
		goto out;
	}

default_queue:

	if (queue == PTLRPC_NRS_QUEUE_HP && !nrs_svc_has_hp(svc)) {
		rc = -ENODEV;
		goto out;
	} else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc)) {
		queue = PTLRPC_NRS_QUEUE_REG;
	}

	/**
	 * Serialize NRS core lprocfs operations with policy registration/
	 * unregistration.
	 */
	mutex_lock(&nrs_core.nrs_mutex);

	rc = ptlrpc_nrs_policy_control(svc, queue, token, PTLRPC_NRS_CTL_START,
				       false, NULL);

	mutex_unlock(&nrs_core.nrs_mutex);
out:
	kfree(cmd_copy);

	return rc < 0 ? rc : count;
}

LPROC_SEQ_FOPS(ptlrpc_lprocfs_nrs);

/** @} nrs */

struct ptlrpc_srh_iterator {
	int			srhi_idx;
	__u64			srhi_seq;
	struct ptlrpc_request	*srhi_req;
};

static int
ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt,
				    struct ptlrpc_srh_iterator *srhi,
				    __u64 seq)
{
	struct list_head *e;
	struct ptlrpc_request *req;

	if (srhi->srhi_req && srhi->srhi_seq > svcpt->scp_hist_seq_culled &&
	    srhi->srhi_seq <= seq) {
		/* If srhi_req was set previously, hasn't been culled and
		 * we're searching for a seq on or after it (i.e. more
		 * recent), search from it onwards.
		 * Since the service history is LRU (i.e. culled reqs will
		 * be near the head), we shouldn't have to do long
		 * re-scans
		 */
		LASSERTF(srhi->srhi_seq == srhi->srhi_req->rq_history_seq,
			 "%s:%d: seek seq %llu, request seq %llu\n",
			 svcpt->scp_service->srv_name, svcpt->scp_cpt,
			 srhi->srhi_seq, srhi->srhi_req->rq_history_seq);
		LASSERTF(!list_empty(&svcpt->scp_hist_reqs),
			 "%s:%d: seek offset %llu, request seq %llu, last culled %llu\n",
			 svcpt->scp_service->srv_name, svcpt->scp_cpt,
			 seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled);
		e = &srhi->srhi_req->rq_history_list;
	} else {
		/* search from start */
		e = svcpt->scp_hist_reqs.next;
	}

	while (e != &svcpt->scp_hist_reqs) {
		req = list_entry(e, struct ptlrpc_request, rq_history_list);

		if (req->rq_history_seq >= seq) {
			srhi->srhi_seq = req->rq_history_seq;
			srhi->srhi_req = req;
			return 0;
		}
		e = e->next;
	}

	return -ENOENT;
}

/*
 * ptlrpc history sequence is used as "position" of seq_file, in some case,
 * seq_read() will increase "position" to indicate reading the next
 * element, however, low bits of history sequence are reserved for CPT id
 * (check the details from comments before ptlrpc_req_add_history), which
 * means seq_read() might change CPT id of history sequence and never
 * finish reading of requests on a CPT. To make it work, we have to shift
 * CPT id to high bits and timestamp to low bits, so seq_read() will only
 * increase timestamp which can correctly indicate the next position.
 */

/* convert seq_file pos to cpt */
#define PTLRPC_REQ_POS2CPT(svc, pos)			\
	((svc)->srv_cpt_bits == 0 ? 0 :			\
	 (__u64)(pos) >> (64 - (svc)->srv_cpt_bits))

/* make up seq_file pos from cpt */
#define PTLRPC_REQ_CPT2POS(svc, cpt)			\
	((svc)->srv_cpt_bits == 0 ? 0 :			\
	 (cpt) << (64 - (svc)->srv_cpt_bits))

/* convert sequence to position */
#define PTLRPC_REQ_SEQ2POS(svc, seq)			\
	((svc)->srv_cpt_bits == 0 ? (seq) :		\
	 ((seq) >> (svc)->srv_cpt_bits) |		\
	 ((seq) << (64 - (svc)->srv_cpt_bits)))

/* convert position to sequence */
#define PTLRPC_REQ_POS2SEQ(svc, pos)			\
	((svc)->srv_cpt_bits == 0 ? (pos) :		\
	 ((__u64)(pos) << (svc)->srv_cpt_bits) |	\
	 ((__u64)(pos) >> (64 - (svc)->srv_cpt_bits)))

static void *
ptlrpc_lprocfs_svc_req_history_start(struct seq_file *s, loff_t *pos)
{
	struct ptlrpc_service		*svc = s->private;
	struct ptlrpc_service_part	*svcpt;
	struct ptlrpc_srh_iterator	*srhi;
	unsigned int			cpt;
	int				rc;
	int				i;

	if (sizeof(loff_t) != sizeof(__u64)) { /* can't support */
		CWARN("Failed to read request history because size of loff_t %d can't match size of u64\n",
		      (int)sizeof(loff_t));
		return NULL;
	}

	srhi = kzalloc(sizeof(*srhi), GFP_NOFS);
	if (!srhi)
		return NULL;

	srhi->srhi_seq = 0;
	srhi->srhi_req = NULL;

	cpt = PTLRPC_REQ_POS2CPT(svc, *pos);

	ptlrpc_service_for_each_part(svcpt, i, svc) {
		if (i < cpt) /* skip */
			continue;
		if (i > cpt) /* make up the lowest position for this CPT */
			*pos = PTLRPC_REQ_CPT2POS(svc, i);

		spin_lock(&svcpt->scp_lock);
		rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi,
				PTLRPC_REQ_POS2SEQ(svc, *pos));
		spin_unlock(&svcpt->scp_lock);
		if (rc == 0) {
			*pos = PTLRPC_REQ_SEQ2POS(svc, srhi->srhi_seq);
			srhi->srhi_idx = i;
			return srhi;
		}
	}

	kfree(srhi);
	return NULL;
}

static void
ptlrpc_lprocfs_svc_req_history_stop(struct seq_file *s, void *iter)
{
	struct ptlrpc_srh_iterator *srhi = iter;

	kfree(srhi);
}

static void *
ptlrpc_lprocfs_svc_req_history_next(struct seq_file *s,
				    void *iter, loff_t *pos)
{
	struct ptlrpc_service *svc = s->private;
	struct ptlrpc_srh_iterator *srhi = iter;
	struct ptlrpc_service_part *svcpt;
	__u64 seq;
	int rc;
	int i;

	for (i = srhi->srhi_idx; i < svc->srv_ncpts; i++) {
		svcpt = svc->srv_parts[i];

		if (i > srhi->srhi_idx) { /* reset iterator for a new CPT */
			srhi->srhi_req = NULL;
			seq = 0;
			srhi->srhi_seq = 0;
		} else { /* the next sequence */
			seq = srhi->srhi_seq + (1 << svc->srv_cpt_bits);
		}

		spin_lock(&svcpt->scp_lock);
		rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, seq);
		spin_unlock(&svcpt->scp_lock);
		if (rc == 0) {
			*pos = PTLRPC_REQ_SEQ2POS(svc, srhi->srhi_seq);
			srhi->srhi_idx = i;
			return srhi;
		}
	}

	kfree(srhi);
	return NULL;
}

static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
{
	struct ptlrpc_service *svc = s->private;
	struct ptlrpc_srh_iterator *srhi = iter;
	struct ptlrpc_service_part *svcpt;
	struct ptlrpc_request *req;
	int rc;

	LASSERT(srhi->srhi_idx < svc->srv_ncpts);

	svcpt = svc->srv_parts[srhi->srhi_idx];

	spin_lock(&svcpt->scp_lock);

	rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, srhi->srhi_seq);

	if (rc == 0) {
		struct timespec64 arrival, sent, arrivaldiff;
		char nidstr[LNET_NIDSTR_SIZE];

		req = srhi->srhi_req;

		libcfs_nid2str_r(req->rq_self, nidstr, sizeof(nidstr));
		arrival.tv_sec = req->rq_arrival_time.tv_sec;
		arrival.tv_nsec = req->rq_arrival_time.tv_nsec;
		sent.tv_sec = req->rq_sent;
		sent.tv_nsec = 0;
		arrivaldiff = timespec64_sub(sent, arrival);

		/* Print common req fields.
		 * CAVEAT EMPTOR: we're racing with the service handler
		 * here.  The request could contain any old crap, so you
		 * must be just as careful as the service's request
		 * parser. Currently I only print stuff here I know is OK
		 * to look at coz it was set up in request_in_callback()!!!
		 */
		seq_printf(s, "%lld:%s:%s:x%llu:%d:%s:%lld.%06lld:%lld.%06llds(%+lld.0s) ",
			   req->rq_history_seq, nidstr,
			   libcfs_id2str(req->rq_peer), req->rq_xid,
			   req->rq_reqlen, ptlrpc_rqphase2str(req),
			   (s64)req->rq_arrival_time.tv_sec,
			   (s64)req->rq_arrival_time.tv_nsec / NSEC_PER_USEC,
			   (s64)arrivaldiff.tv_sec,
			   (s64)(arrivaldiff.tv_nsec / NSEC_PER_USEC),
			   (s64)(req->rq_sent - req->rq_deadline));
		if (!svc->srv_ops.so_req_printer)
			seq_putc(s, '\n');
		else
			svc->srv_ops.so_req_printer(s, srhi->srhi_req);
	}

	spin_unlock(&svcpt->scp_lock);
	return rc;
}

static int
ptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file)
{
	static const struct seq_operations sops = {
		.start = ptlrpc_lprocfs_svc_req_history_start,
		.stop  = ptlrpc_lprocfs_svc_req_history_stop,
		.next  = ptlrpc_lprocfs_svc_req_history_next,
		.show  = ptlrpc_lprocfs_svc_req_history_show,
	};
	struct seq_file *seqf;
	int rc;

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

	seqf = file->private_data;
	seqf->private = inode->i_private;
	return 0;
}

/* See also lprocfs_rd_timeouts */
static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n)
{
	struct ptlrpc_service *svc = m->private;
	struct ptlrpc_service_part *svcpt;
	struct dhms ts;
	time64_t worstt;
	unsigned int cur;
	unsigned int worst;
	int i;

	if (AT_OFF) {
		seq_printf(m, "adaptive timeouts off, using obd_timeout %u\n",
			   obd_timeout);
		return 0;
	}

	ptlrpc_service_for_each_part(svcpt, i, svc) {
		cur	= at_get(&svcpt->scp_at_estimate);
		worst	= svcpt->scp_at_estimate.at_worst_ever;
		worstt	= svcpt->scp_at_estimate.at_worst_time;
		s2dhms(&ts, ktime_get_real_seconds() - worstt);

		seq_printf(m, "%10s : cur %3u  worst %3u (at %lld, "
			   DHMS_FMT " ago) ", "service",
			   cur, worst, (s64)worstt, DHMS_VARS(&ts));

		lprocfs_at_hist_helper(m, &svcpt->scp_at_estimate);
	}

	return 0;
}

LPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_timeouts);

static ssize_t high_priority_ratio_show(struct kobject *kobj,
					struct attribute *attr,
					char *buf)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);
	return sprintf(buf, "%d\n", svc->srv_hpreq_ratio);
}

static ssize_t high_priority_ratio_store(struct kobject *kobj,
					 struct attribute *attr,
					 const char *buffer,
					 size_t count)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);
	int rc;
	int val;

	rc = kstrtoint(buffer, 10, &val);
	if (rc < 0)
		return rc;

	if (val < 0)
		return -ERANGE;

	spin_lock(&svc->srv_lock);
	svc->srv_hpreq_ratio = val;
	spin_unlock(&svc->srv_lock);

	return count;
}
LUSTRE_RW_ATTR(high_priority_ratio);

static struct attribute *ptlrpc_svc_attrs[] = {
	&lustre_attr_threads_min.attr,
	&lustre_attr_threads_started.attr,
	&lustre_attr_threads_max.attr,
	&lustre_attr_high_priority_ratio.attr,
	NULL,
};

static void ptlrpc_sysfs_svc_release(struct kobject *kobj)
{
	struct ptlrpc_service *svc = container_of(kobj, struct ptlrpc_service,
						  srv_kobj);

	complete(&svc->srv_kobj_unregister);
}

static struct kobj_type ptlrpc_svc_ktype = {
	.default_attrs	= ptlrpc_svc_attrs,
	.sysfs_ops	= &lustre_sysfs_ops,
	.release	= ptlrpc_sysfs_svc_release,
};

void ptlrpc_sysfs_unregister_service(struct ptlrpc_service *svc)
{
	/* Let's see if we had a chance at initialization first */
	if (svc->srv_kobj.kset) {
		kobject_put(&svc->srv_kobj);
		wait_for_completion(&svc->srv_kobj_unregister);
	}
}

int ptlrpc_sysfs_register_service(struct kset *parent,
				  struct ptlrpc_service *svc)
{
	int rc;

	svc->srv_kobj.kset = parent;
	init_completion(&svc->srv_kobj_unregister);
	rc = kobject_init_and_add(&svc->srv_kobj, &ptlrpc_svc_ktype, NULL,
				  "%s", svc->srv_name);

	return rc;
}

void ptlrpc_ldebugfs_register_service(struct dentry *entry,
				      struct ptlrpc_service *svc)
{
	struct lprocfs_vars lproc_vars[] = {
		{.name       = "req_buffer_history_len",
		 .fops	     = &ptlrpc_lprocfs_req_history_len_fops,
		 .data       = svc},
		{.name       = "req_buffer_history_max",
		 .fops	     = &ptlrpc_lprocfs_req_history_max_fops,
		 .data       = svc},
		{.name       = "timeouts",
		 .fops	     = &ptlrpc_lprocfs_timeouts_fops,
		 .data       = svc},
		{.name       = "nrs_policies",
		 .fops	     = &ptlrpc_lprocfs_nrs_fops,
		 .data	     = svc},
		{NULL}
	};
	static const struct file_operations req_history_fops = {
		.owner       = THIS_MODULE,
		.open	= ptlrpc_lprocfs_svc_req_history_open,
		.read	= seq_read,
		.llseek      = seq_lseek,
		.release     = lprocfs_seq_release,
	};

	int rc;

	ptlrpc_ldebugfs_register(entry, svc->srv_name,
				 "stats", &svc->srv_debugfs_entry,
				 &svc->srv_stats);

	if (IS_ERR_OR_NULL(svc->srv_debugfs_entry))
		return;

	ldebugfs_add_vars(svc->srv_debugfs_entry, lproc_vars, NULL);

	rc = ldebugfs_seq_create(svc->srv_debugfs_entry, "req_history",
				 0400, &req_history_fops, svc);
	if (rc)
		CWARN("Error adding the req_history file\n");
}

void ptlrpc_lprocfs_register_obd(struct obd_device *obddev)
{
	ptlrpc_ldebugfs_register(obddev->obd_debugfs_entry, NULL, "stats",
				 &obddev->obd_svc_debugfs_entry,
				 &obddev->obd_svc_stats);
}
EXPORT_SYMBOL(ptlrpc_lprocfs_register_obd);

void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount)
{
	struct lprocfs_stats *svc_stats;
	__u32 op = lustre_msg_get_opc(req->rq_reqmsg);
	int opc = opcode_offset(op);

	svc_stats = req->rq_import->imp_obd->obd_svc_stats;
	if (!svc_stats || opc <= 0)
		return;
	LASSERT(opc < LUSTRE_MAX_OPCODES);
	if (!(op == LDLM_ENQUEUE || op == MDS_REINT))
		lprocfs_counter_add(svc_stats, opc + EXTRA_MAX_OPCODES, amount);
}

void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes)
{
	struct lprocfs_stats *svc_stats;
	int idx;

	if (!req->rq_import)
		return;
	svc_stats = req->rq_import->imp_obd->obd_svc_stats;
	if (!svc_stats)
		return;
	idx = lustre_msg_get_opc(req->rq_reqmsg);
	switch (idx) {
	case OST_READ:
		idx = BRW_READ_BYTES + PTLRPC_LAST_CNTR;
		break;
	case OST_WRITE:
		idx = BRW_WRITE_BYTES + PTLRPC_LAST_CNTR;
		break;
	default:
		LASSERTF(0, "unsupported opcode %u\n", idx);
		break;
	}

	lprocfs_counter_add(svc_stats, idx, bytes);
}
EXPORT_SYMBOL(ptlrpc_lprocfs_brw);

void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc)
{
	if (!IS_ERR_OR_NULL(svc->srv_debugfs_entry))
		ldebugfs_remove(&svc->srv_debugfs_entry);

	if (svc->srv_stats)
		lprocfs_free_stats(&svc->srv_stats);
}

void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd)
{
	if (!IS_ERR_OR_NULL(obd->obd_svc_debugfs_entry))
		ldebugfs_remove(&obd->obd_svc_debugfs_entry);

	if (obd->obd_svc_stats)
		lprocfs_free_stats(&obd->obd_svc_stats);
}
EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);

#undef BUFLEN

int lprocfs_wr_ping(struct file *file, const char __user *buffer,
		    size_t count, loff_t *off)
{
	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
	struct ptlrpc_request *req;
	int rc;

	rc = lprocfs_climp_check(obd);
	if (rc)
		return rc;

	req = ptlrpc_prep_ping(obd->u.cli.cl_import);
	up_read(&obd->u.cli.cl_sem);
	if (!req)
		return -ENOMEM;

	req->rq_send_state = LUSTRE_IMP_FULL;

	rc = ptlrpc_queue_wait(req);

	ptlrpc_req_finished(req);
	if (rc >= 0)
		return count;
	return rc;
}
EXPORT_SYMBOL(lprocfs_wr_ping);

/* Write the connection UUID to this file to attempt to connect to that node.
 * The connection UUID is a node's primary NID. For example,
 * "echo connection=192.168.0.1@tcp0::instance > .../import".
 */
int lprocfs_wr_import(struct file *file, const char __user *buffer,
		      size_t count, loff_t *off)
{
	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
	struct obd_import *imp = obd->u.cli.cl_import;
	char *kbuf = NULL;
	char *uuid;
	char *ptr;
	int do_reconn = 1;
	const char prefix[] = "connection=";
	const int prefix_len = sizeof(prefix) - 1;

	if (count > PAGE_SIZE - 1 || count <= prefix_len)
		return -EINVAL;

	kbuf = kzalloc(count + 1, GFP_NOFS);
	if (!kbuf)
		return -ENOMEM;

	if (copy_from_user(kbuf, buffer, count)) {
		count = -EFAULT;
		goto out;
	}

	kbuf[count] = 0;

	/* only support connection=uuid::instance now */
	if (strncmp(prefix, kbuf, prefix_len) != 0) {
		count = -EINVAL;
		goto out;
	}

	uuid = kbuf + prefix_len;
	ptr = strstr(uuid, "::");
	if (ptr) {
		__u32 inst;
		char *endptr;

		*ptr = 0;
		do_reconn = 0;
		ptr += strlen("::");
		inst = simple_strtoul(ptr, &endptr, 10);
		if (*endptr) {
			CERROR("config: wrong instance # %s\n", ptr);
		} else if (inst != imp->imp_connect_data.ocd_instance) {
			CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n",
			       imp->imp_obd->obd_name,
			       imp->imp_connect_data.ocd_instance, inst);
			do_reconn = 1;
		} else {
			CDEBUG(D_INFO, "IR: %s has already been connecting to new target(%u)\n",
			       imp->imp_obd->obd_name, inst);
		}
	}

	if (do_reconn)
		ptlrpc_recover_import(imp, uuid, 1);

out:
	kfree(kbuf);
	return count;
}
EXPORT_SYMBOL(lprocfs_wr_import);

int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
{
	struct obd_device *obd = m->private;
	struct obd_import *imp = obd->u.cli.cl_import;
	int rc;

	rc = lprocfs_climp_check(obd);
	if (rc)
		return rc;

	seq_printf(m, "%d\n", !imp->imp_no_pinger_recover);
	up_read(&obd->u.cli.cl_sem);

	return 0;
}
EXPORT_SYMBOL(lprocfs_rd_pinger_recov);

int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
			    size_t count, loff_t *off)
{
	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
	struct client_obd *cli = &obd->u.cli;
	struct obd_import *imp = cli->cl_import;
	int rc, val;

	rc = lprocfs_write_helper(buffer, count, &val);
	if (rc < 0)
		return rc;

	if (val != 0 && val != 1)
		return -ERANGE;

	rc = lprocfs_climp_check(obd);
	if (rc)
		return rc;

	spin_lock(&imp->imp_lock);
	imp->imp_no_pinger_recover = !val;
	spin_unlock(&imp->imp_lock);
	up_read(&obd->u.cli.cl_sem);

	return count;
}
EXPORT_SYMBOL(lprocfs_wr_pinger_recov);
