* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define DEBUG_SUBSYSTEM S_CLASS
-
#include <obd_class.h>
#include <lprocfs_status.h>
#include <lustre/lustre_idl.h>
}
EXPORT_SYMBOL(lprocfs_add_symlink);
-#ifdef HAVE_ONLY_PROCFS_SEQ
static const struct file_operations lprocfs_generic_fops = { };
-#else
-
-ssize_t
-lprocfs_fops_read(struct file *f, char __user *buf, size_t size, loff_t *ppos)
-{
- struct inode *inode = f->f_dentry->d_inode;
- struct proc_dir_entry *dp = PDE(inode);
- char *page, *start = NULL;
- int rc, eof = 1, count;
-
- if (*ppos >= PAGE_CACHE_SIZE)
- return 0;
-
- page = (char *)__get_free_page(GFP_KERNEL);
- if (page == NULL)
- return -ENOMEM;
-
- rc = LPROCFS_ENTRY_CHECK(inode);
- if (rc < 0)
- goto out;
-
- OBD_FAIL_TIMEOUT(OBD_FAIL_LPROC_REMOVE, 10);
- if (dp->read_proc != NULL)
- rc = dp->read_proc(page, &start, *ppos, PAGE_CACHE_SIZE,
- &eof, dp->data);
- else
- rc = 0;
-
- if (rc <= 0)
- goto out;
-
- /* for lustre proc read, the read count must be less than PAGE_SIZE */
- LASSERT(eof == 1);
-
- if (start == NULL) {
- rc -= *ppos;
- if (rc < 0)
- rc = 0;
- if (rc == 0)
- goto out;
- start = page + *ppos;
- } else if (start < page) {
- start = page;
- }
-
- count = (rc < size) ? rc : size;
- if (copy_to_user(buf, start, count)) {
- rc = -EFAULT;
- goto out;
- }
- *ppos += count;
-
-out:
- free_page((unsigned long)page);
- return rc;
-}
-
-ssize_t
-lprocfs_fops_write(struct file *f, const char __user *buf, size_t size,
- loff_t *ppos)
-{
- struct inode *inode = f->f_dentry->d_inode;
- struct proc_dir_entry *dp = PDE(inode);
- int rc;
-
- rc = LPROCFS_ENTRY_CHECK(inode);
- if (rc < 0)
- return rc;
-
- if (dp->write_proc != NULL)
- rc = dp->write_proc(f, buf, size, dp->data);
- else
- rc = -EIO;
-
- return rc;
-}
-
-static struct file_operations lprocfs_generic_fops = {
- .owner = THIS_MODULE,
- .read = lprocfs_fops_read,
- .write = lprocfs_fops_write,
-};
-
-/* for b=10866, global variable */
-DECLARE_RWSEM(_lprocfs_lock);
-EXPORT_SYMBOL(_lprocfs_lock);
-
-static struct proc_dir_entry *__lprocfs_srch(struct proc_dir_entry *head,
- const char *name)
-{
- struct proc_dir_entry *temp;
-
- if (head == NULL)
- return NULL;
-
- temp = head->subdir;
- while (temp != NULL) {
- if (strcmp(temp->name, name) == 0)
- return temp;
- temp = temp->next;
- }
- return NULL;
-}
-
-struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
- const char *name)
-{
- struct proc_dir_entry *temp;
-
- LPROCFS_SRCH_ENTRY();
- temp = __lprocfs_srch(head, name);
- LPROCFS_SRCH_EXIT();
- return temp;
-}
-EXPORT_SYMBOL(lprocfs_srch);
-
-static int __lprocfs_add_vars(struct proc_dir_entry *root,
- struct lprocfs_vars *list,
- void *data)
-{
- int rc = 0;
-
- if (root == NULL || list == NULL)
- return -EINVAL;
-
- while (list->name != NULL) {
- struct proc_dir_entry *cur_root, *proc;
- char *pathcopy, *cur, *next, pathbuf[64];
- int pathsize = strlen(list->name) + 1;
-
- proc = NULL;
- cur_root = root;
-
- /* need copy of path for strsep */
- if (strlen(list->name) > sizeof(pathbuf) - 1) {
- OBD_ALLOC(pathcopy, pathsize);
- if (pathcopy == NULL)
- GOTO(out, rc = -ENOMEM);
- } else {
- pathcopy = pathbuf;
- }
-
- next = pathcopy;
- strcpy(pathcopy, list->name);
-
- while (cur_root != NULL && (cur = strsep(&next, "/"))) {
- if (*cur =='\0') /* skip double/trailing "/" */
- continue;
-
- proc = __lprocfs_srch(cur_root, cur);
- CDEBUG(D_OTHER, "cur_root=%s, cur=%s, next=%s, (%s)\n",
- cur_root->name, cur, next,
- (proc ? "exists" : "new"));
- if (next != NULL) {
- cur_root = (proc ? proc :
- proc_mkdir(cur, cur_root));
- } else if (proc == NULL) {
- mode_t mode = 0;
- if (list->proc_mode != 0000) {
- mode = list->proc_mode;
- } else {
- if (list->read_fptr)
- mode = 0444;
- if (list->write_fptr)
- mode |= 0200;
- }
- proc = create_proc_entry(cur, mode, cur_root);
- }
- }
-
- if (pathcopy != pathbuf)
- OBD_FREE(pathcopy, pathsize);
-
- if (cur_root == NULL || proc == NULL) {
- CERROR("LprocFS: No memory to create /proc entry %s\n",
- list->name);
- GOTO(out, rc = -ENOMEM);
- }
-
- if (list->fops)
- proc->proc_fops = list->fops;
- else
- proc->proc_fops = &lprocfs_generic_fops;
- proc->read_proc = list->read_fptr;
- proc->write_proc = list->write_fptr;
- proc->data = (list->data ? list->data : data);
- list++;
- }
-out:
- return rc;
-}
-
-int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
- void *data)
-{
- int rc = 0;
-
- LPROCFS_WRITE_ENTRY();
- rc = __lprocfs_add_vars(root, list, data);
- LPROCFS_WRITE_EXIT();
-
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_add_vars);
-#endif
/**
* Add /proc entries.
* < 0 on error
*/
int
-lprocfs_seq_add_vars(struct proc_dir_entry *root, struct lprocfs_seq_vars *list,
- void *data)
+lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
+ void *data)
{
if (root == NULL || list == NULL)
return -EINVAL;
}
return 0;
}
-EXPORT_SYMBOL(lprocfs_seq_add_vars);
+EXPORT_SYMBOL(lprocfs_add_vars);
+
+#ifndef HAVE_REMOVE_PROC_SUBTREE
+/* for b=10866, global variable */
+DECLARE_RWSEM(_lprocfs_lock);
+EXPORT_SYMBOL(_lprocfs_lock);
-#ifndef HAVE_ONLY_PROCFS_SEQ
static void lprocfs_remove_nolock(struct proc_dir_entry **proot)
{
struct proc_dir_entry *root = *proot;
break;
}
}
-#endif
-
-void lprocfs_remove(struct proc_dir_entry **rooth)
-{
-#ifndef HAVE_ONLY_PROCFS_SEQ
- LPROCFS_WRITE_ENTRY(); /* search vs remove race */
- lprocfs_remove_nolock(rooth);
- LPROCFS_WRITE_EXIT();
-#else
- proc_remove(*rooth);
- *rooth = NULL;
-#endif
-}
-EXPORT_SYMBOL(lprocfs_remove);
-
-void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
-{
- LASSERT(parent != NULL);
- remove_proc_entry(name, parent);
-}
-EXPORT_SYMBOL(lprocfs_remove_proc_entry);
-#ifndef HAVE_ONLY_PROCFS_SEQ
-void lprocfs_try_remove_proc_entry(const char *name,
- struct proc_dir_entry *parent)
+int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
{
struct proc_dir_entry *t = NULL;
struct proc_dir_entry **p;
LASSERT(parent != NULL);
len = strlen(name);
- LPROCFS_WRITE_ENTRY();
-
+ down_write(&_lprocfs_lock);
/* lookup target name */
for (p = &parent->subdir; *p; p = &(*p)->next) {
if ((*p)->namelen != len)
if (busy == 0)
lprocfs_remove_nolock(&t);
- LPROCFS_WRITE_EXIT();
-
- return;
+ up_write(&_lprocfs_lock);
+ return 0;
}
-EXPORT_SYMBOL(lprocfs_try_remove_proc_entry);
+#endif /* !HAVE_REMOVE_PROC_SUBTREE */
-struct proc_dir_entry *lprocfs_register(const char *name,
- struct proc_dir_entry *parent,
- struct lprocfs_vars *list, void *data)
+#ifndef HAVE_PROC_REMOVE
+void proc_remove(struct proc_dir_entry *de)
{
- struct proc_dir_entry *entry;
- int rc;
-
- LPROCFS_WRITE_ENTRY();
- entry = __lprocfs_srch(parent, name);
- if (entry != NULL) {
- CERROR("entry '%s' already registered\n", name);
- GOTO(out, entry = ERR_PTR(-EALREADY));
- }
+#ifndef HAVE_REMOVE_PROC_SUBTREE
+ down_write(&_lprocfs_lock); /* search vs remove race */
+ lprocfs_remove_nolock(&de);
+ up_write(&_lprocfs_lock);
+#else
+ if (de)
+ remove_proc_subtree(de->name, de->parent);
+#endif
+}
+#endif
- entry = proc_mkdir(name, parent);
- if (entry == NULL)
- GOTO(out, entry = ERR_PTR(-ENOMEM));
+void lprocfs_remove(struct proc_dir_entry **rooth)
+{
+ proc_remove(*rooth);
+ *rooth = NULL;
+}
+EXPORT_SYMBOL(lprocfs_remove);
- if (list != NULL) {
- rc = __lprocfs_add_vars(entry, list, data);
- if (rc != 0) {
- lprocfs_remove_nolock(&entry);
- GOTO(out, entry = ERR_PTR(rc));
- }
- }
-out:
- LPROCFS_WRITE_EXIT();
- return entry;
+void lprocfs_remove_proc_entry(const char *name, struct proc_dir_entry *parent)
+{
+ LASSERT(parent != NULL);
+ remove_proc_entry(name, parent);
}
-EXPORT_SYMBOL(lprocfs_register);
-#endif
+EXPORT_SYMBOL(lprocfs_remove_proc_entry);
struct proc_dir_entry *
-lprocfs_seq_register(const char *name, struct proc_dir_entry *parent,
- struct lprocfs_seq_vars *list, void *data)
+lprocfs_register(const char *name, struct proc_dir_entry *parent,
+ struct lprocfs_vars *list, void *data)
{
struct proc_dir_entry *newchild;
return ERR_PTR(-ENOMEM);
if (list != NULL) {
- int rc = lprocfs_seq_add_vars(newchild, list, data);
+ int rc = lprocfs_add_vars(newchild, list, data);
if (rc) {
lprocfs_remove(&newchild);
return ERR_PTR(rc);
}
return newchild;
}
-EXPORT_SYMBOL(lprocfs_seq_register);
+EXPORT_SYMBOL(lprocfs_register);
/* Generic callbacks */
int lprocfs_uint_seq_show(struct seq_file *m, void *data)
lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
}
-EXPORT_SYMBOL(lprocfs_stats_collect);
/**
* Append a space separated list of current set flags to str.
"lfsck",
"unknown",
"unlink_close",
- "unknown",
+ "multi_mod_rpcs",
"dir_stripe",
+ "fileset_mount",
+ "bulk_mbits",
"unknown",
NULL
};
static void obd_connect_data_seqprint(struct seq_file *m,
struct obd_connect_data *ocd)
{
- int flags;
+ __u64 flags;
LASSERT(ocd != NULL);
flags = ocd->ocd_connect_flags;
if (flags & OBD_CONNECT_MAXBYTES)
seq_printf(m, " max_object_bytes: "LPU64"\n",
ocd->ocd_maxbytes);
+ if (flags & OBD_CONNECT_MULTIMODRPCS)
+ seq_printf(m, " max_mod_rpcs: %hu\n",
+ ocd->ocd_maxmodrpcs);
}
int lprocfs_import_seq_show(struct seq_file *m, void *data)
{
+ char nidstr[LNET_NIDSTR_SIZE];
struct lprocfs_counter ret;
struct lprocfs_counter_header *header;
struct obd_device *obd = (struct obd_device *)data;
spin_lock(&imp->imp_lock);
j = 0;
list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
- seq_printf(m, "%s%s", j ? ", " : "",
- libcfs_nid2str(conn->oic_conn->c_peer.nid));
+ libcfs_nid2str_r(conn->oic_conn->c_peer.nid,
+ nidstr, sizeof(nidstr));
+ seq_printf(m, "%s%s", j ? ", " : "", nidstr);
j++;
}
+ if (imp->imp_connection != NULL)
+ libcfs_nid2str_r(imp->imp_connection->c_peer.nid,
+ nidstr, sizeof(nidstr));
+ else
+ strncpy(nidstr, "<none>", sizeof(nidstr));
seq_printf(m, " ]\n"
" current_connection: %s\n"
" connection_attempts: %u\n"
" generation: %u\n"
" in-progress_invalidations: %u\n",
- imp->imp_connection == NULL ? "<none>" :
- libcfs_nid2str(imp->imp_connection->c_peer.nid),
+ nidstr,
imp->imp_conn_cnt,
imp->imp_generation,
atomic_read(&imp->imp_inval_count));
}
EXPORT_SYMBOL(lprocfs_state_seq_show);
-int lprocfs_seq_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at)
+int lprocfs_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at)
{
int i;
for (i = 0; i < AT_BINS; i++)
seq_printf(m, "\n");
return 0;
}
-EXPORT_SYMBOL(lprocfs_seq_at_hist_helper);
+EXPORT_SYMBOL(lprocfs_at_hist_helper);
/* See also ptlrpc_lprocfs_timeouts_show_seq */
int lprocfs_timeouts_seq_show(struct seq_file *m, void *data)
s2dhms(&ts, now - worstt);
seq_printf(m, "%-10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
"network", cur, worst, worstt, DHMS_VARS(&ts));
- lprocfs_seq_at_hist_helper(m, &imp->imp_at.iat_net_latency);
+ lprocfs_at_hist_helper(m, &imp->imp_at.iat_net_latency);
for(i = 0; i < IMP_AT_MAX_PORTALS; i++) {
if (imp->imp_at.iat_portal[i] == 0)
seq_printf(m, "portal %-2d : cur %3u worst %3u (at %ld, "
DHMS_FMT" ago) ", imp->imp_at.iat_portal[i],
cur, worst, worstt, DHMS_VARS(&ts));
- lprocfs_seq_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]);
+ lprocfs_at_hist_helper(m, &imp->imp_at.iat_service_estimate[i]);
}
LPROCFS_CLIMP_EXIT(obd);
LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
LASSERT(obd->obd_type->typ_procroot != NULL);
- obd->obd_proc_entry = lprocfs_seq_register(obd->obd_name,
- obd->obd_type->typ_procroot,
- obd->obd_vars, obd);
+ obd->obd_proc_entry = lprocfs_register(obd->obd_name,
+ obd->obd_type->typ_procroot,
+ obd->obd_vars, obd);
if (IS_ERR(obd->obd_proc_entry)) {
rc = PTR_ERR(obd->obd_proc_entry);
CERROR("error %d setting up lprocfs for %s\n",rc,obd->obd_name);
LPROCFS_MD_OP_INIT(num_private_stats, stats, find_cbdata);
LPROCFS_MD_OP_INIT(num_private_stats, stats, close);
LPROCFS_MD_OP_INIT(num_private_stats, stats, create);
- LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_name);
LPROCFS_MD_OP_INIT(num_private_stats, stats, init_ea_size);
LPROCFS_MD_OP_INIT(num_private_stats, stats, get_lustre_md);
LPROCFS_MD_OP_INIT(num_private_stats, stats, free_lustre_md);
- LPROCFS_MD_OP_INIT(num_private_stats, stats, update_lsm_md);
LPROCFS_MD_OP_INIT(num_private_stats, stats, merge_attr);
LPROCFS_MD_OP_INIT(num_private_stats, stats, set_open_replay_data);
LPROCFS_MD_OP_INIT(num_private_stats, stats, clear_open_replay_data);
LPROCFS_MD_OP_INIT(num_private_stats, stats, set_lock_data);
LPROCFS_MD_OP_INIT(num_private_stats, stats, lock_match);
LPROCFS_MD_OP_INIT(num_private_stats, stats, cancel_unused);
- LPROCFS_MD_OP_INIT(num_private_stats, stats, renew_capa);
- LPROCFS_MD_OP_INIT(num_private_stats, stats, unpack_capa);
LPROCFS_MD_OP_INIT(num_private_stats, stats, get_remote_perm);
LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_getattr_async);
LPROCFS_MD_OP_INIT(num_private_stats, stats, revalidate_lock);
}
-EXPORT_SYMBOL(lprocfs_init_mps_stats);
int lprocfs_alloc_md_stats(struct obd_device *obd,
unsigned int num_private_stats)
buffer[prtn++] ='\n';
return prtn;
}
-EXPORT_SYMBOL(lprocfs_read_frac_helper);
int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult)
{
return rc;
}
-EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc);
int lprocfs_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *data)
{
char *kernbuf = NULL;
char *errmsg;
struct list_head tmp;
+ int len = count;
ENTRY;
if (count > 4096) {
kernbuf[count] = '\0';
if (count > 0 && kernbuf[count - 1] == '\n')
- kernbuf[count - 1] = '\0';
+ len = count - 1;
- if (strcmp(kernbuf, "NONE") == 0 || strcmp(kernbuf, "clear") == 0) {
+ if ((len == 4 && strncmp(kernbuf, "NONE", len) == 0) ||
+ (len == 5 && strncmp(kernbuf, "clear", len) == 0)) {
/* empty string is special case */
down_write(&squash->rsi_sem);
if (!list_empty(&squash->rsi_nosquash_nids))