-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
struct obd_histogram hist[BRW_LAST];
};
+enum {
+ RENAME_SAMEDIR_SIZE = 0,
+ RENAME_CROSSDIR_SRC_SIZE,
+ RENAME_CROSSDIR_TGT_SIZE,
+ RENAME_LAST,
+};
+
+struct rename_stats {
+ struct obd_histogram hist[RENAME_LAST];
+};
/* An lprocfs counter can be configured using the enum bit masks below.
*
};
struct lprocfs_percpu {
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
- __s64 pad;
+#ifndef __GNUC__
+ __s64 pad;
#endif
struct lprocfs_counter lp_cntr[0];
};
#define LPROCFS_GET_SMP_ID 0x0002
enum lprocfs_stats_flags {
- LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */
- LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu
- * area and need locking */
+ LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */
+ LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu
+ * area and need locking */
+ LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */
};
enum lprocfs_fields_flags {
};
struct lprocfs_stats {
- unsigned int ls_num; /* # of counters */
- int ls_flags; /* See LPROCFS_STATS_FLAG_* */
- cfs_spinlock_t ls_lock; /* Lock used only when there are
- * no percpu stats areas */
- struct lprocfs_percpu *ls_percpu[0];
+ unsigned short ls_num; /* # of counters */
+ unsigned short ls_biggest_alloc_num;
+ /* 1 + the highest slot index which has
+ * been allocated, the 0th entry is
+ * a statically intialized template */
+ int ls_flags; /* See LPROCFS_STATS_FLAG_* */
+ /* Lock used when there are no percpu stats areas; For percpu stats,
+ * it is used to protect ls_biggest_alloc_num change */
+ cfs_spinlock_t ls_lock;
+ struct lprocfs_percpu *ls_percpu[0];
};
#define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC)
#define DHMS_FMT "%dd%dh%02dm%02ds"
#define DHMS_VARS(x) (x)->d, (x)->h, (x)->m, (x)->s
+#define JOBSTATS_JOBID_VAR_MAX_LEN 20
+#define JOBSTATS_DISABLE "disable"
+#define JOBSTATS_PROCNAME_UID "procname_uid"
+
+typedef void (*cntr_init_callback)(struct lprocfs_stats *stats);
+
+struct obd_job_stats {
+ cfs_hash_t *ojs_hash;
+ cfs_list_t ojs_list;
+ cfs_rwlock_t ojs_lock; /* protect the obj_list */
+ cntr_init_callback ojs_cntr_init_fn;
+ int ojs_cntr_num;
+ int ojs_cleanup_interval;
+ time_t ojs_last_cleanup;
+};
#ifdef LPROCFS
-static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc)
+extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats,
+ unsigned int cpuid);
+/*
+ * \return value
+ * < 0 : on error (only possible for opc as LPROCFS_GET_SMP_ID)
+ */
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc,
+ unsigned long *flags)
{
- switch (opc) {
- default:
- LBUG();
-
- case LPROCFS_GET_SMP_ID:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- cfs_spin_lock(&stats->ls_lock);
- return 0;
- } else {
- return cfs_get_cpu();
- }
-
- case LPROCFS_GET_NUM_CPU:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- cfs_spin_lock(&stats->ls_lock);
- return 1;
- } else {
- return cfs_num_possible_cpus();
- }
- }
+ int rc = 0;
+ unsigned int cpuid;
+
+ switch (opc) {
+ default:
+ LBUG();
+
+ case LPROCFS_GET_SMP_ID:
+ /* percpu counter stats */
+ if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0) {
+ cpuid = cfs_get_cpu();
+
+ if (unlikely(stats->ls_percpu[cpuid + 1] == NULL))
+ rc = lprocfs_stats_alloc_one(stats, cpuid + 1);
+ return rc < 0 ? rc : cpuid + 1;
+ }
+
+ /* non-percpu counter stats */
+ if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+ cfs_spin_lock_irqsave(&stats->ls_lock, *flags);
+ else
+ cfs_spin_lock(&stats->ls_lock);
+ return 0;
+
+ case LPROCFS_GET_NUM_CPU:
+ /* percpu counter stats */
+ if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0)
+ return stats->ls_biggest_alloc_num;
+
+ /* non-percpu counter stats */
+ if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+ cfs_spin_lock_irqsave(&stats->ls_lock, *flags);
+ else
+ cfs_spin_lock(&stats->ls_lock);
+ return 1;
+ }
}
-static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc)
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc,
+ unsigned long *flags)
{
- switch (opc) {
- default:
- LBUG();
-
- case LPROCFS_GET_SMP_ID:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
- cfs_spin_unlock(&stats->ls_lock);
- else
- cfs_put_cpu();
- return;
-
- case LPROCFS_GET_NUM_CPU:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
- cfs_spin_unlock(&stats->ls_lock);
- return;
- }
+ switch (opc) {
+ default:
+ LBUG();
+
+ case LPROCFS_GET_SMP_ID:
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+ cfs_spin_unlock_irqrestore(&stats->ls_lock,
+ *flags);
+ } else {
+ cfs_spin_unlock(&stats->ls_lock);
+ }
+ } else {
+ cfs_put_cpu();
+ }
+ return;
+
+ case LPROCFS_GET_NUM_CPU:
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+ cfs_spin_unlock_irqrestore(&stats->ls_lock,
+ *flags);
+ } else {
+ cfs_spin_unlock(&stats->ls_lock);
+ }
+ }
+ return;
+ }
}
/* Two optimized LPROCFS counter increment functions are provided:
int idx,
enum lprocfs_fields_flags field)
{
- __u64 ret = 0;
- int i;
-
- LASSERT(stats != NULL);
- for (i = 0; i < cfs_num_possible_cpus(); i++)
- ret += lprocfs_read_helper(&(stats->ls_percpu[i]->lp_cntr[idx]),
- field);
- return ret;
+ int i;
+ unsigned int num_cpu;
+ unsigned long flags = 0;
+ __u64 ret = 0;
+
+ LASSERT(stats != NULL);
+
+ num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
+ for (i = 0; i < num_cpu; i++) {
+ if (stats->ls_percpu[i] == NULL)
+ continue;
+ ret += lprocfs_read_helper(&(stats->ls_percpu[i]->lp_cntr[idx]),
+ field);
+ }
+ lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
+ return ret;
}
extern struct lprocfs_stats *
extern void lprocfs_remove(cfs_proc_dir_entry_t **root);
extern void lprocfs_remove_proc_entry(const char *name,
struct proc_dir_entry *parent);
+extern void lprocfs_try_remove_proc_entry(const char *name,
+ struct proc_dir_entry *parent);
extern cfs_proc_dir_entry_t *lprocfs_srch(cfs_proc_dir_entry_t *root,
const char *name);
extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
extern int lprocfs_obd_cleanup(struct obd_device *obd);
-extern void lprocfs_free_per_client_stats(struct obd_device *obd);
extern struct file_operations lprocfs_evict_client_fops;
extern int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name,
unsigned long count, void *data);
extern int lprocfs_wr_import(struct file *file, const char *buffer,
unsigned long count, void *data);
+extern int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+ unsigned long count, void *data);
/* Statfs helpers */
extern int lprocfs_rd_blksize(char *page, char **start, off_t off,
int count, int *eof, void *data);
extern int lprocfs_rd_filegroups(char *page, char **start, off_t off,
int count, int *eof, void *data);
+extern int lprocfs_osd_rd_blksize(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_osd_rd_kbytesfree(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_osd_rd_kbytesavail(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_osd_rd_filestotal(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_osd_rd_filesfree(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_osd_rd_kbytestotal(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+
extern int lprocfs_write_helper(const char *buffer, unsigned long count,
int *val);
int lprocfs_obd_wr_ir_factor(struct file *file, const char *buffer,
unsigned long count, void *data);
+extern int lprocfs_single_release(cfs_inode_t *, struct file *);
extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
/* You must use these macros when you want to refer to
a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally,
call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */
#define __LPROC_SEQ_FOPS(name, custom_seq_write) \
-static int name##_seq_open(cfs_inode_t *inode, struct file *file) { \
+static int name##_single_open(cfs_inode_t *inode, struct file *file) { \
struct proc_dir_entry *dp = PDE(inode); \
int rc; \
LPROCFS_ENTRY_AND_CHECK(dp); \
} \
struct file_operations name##_fops = { \
.owner = THIS_MODULE, \
- .open = name##_seq_open, \
+ .open = name##_single_open, \
.read = seq_read, \
.write = custom_seq_write, \
.llseek = seq_lseek, \
- .release = lprocfs_seq_release, \
+ .release = lprocfs_single_release, \
}
#define LPROC_SEQ_FOPS_RO(name) __LPROC_SEQ_FOPS(name, NULL)
#define LPROC_SEQ_FOPS(name) __LPROC_SEQ_FOPS(name, name##_seq_write)
+/* lprocfs_jobstats.c */
+int lprocfs_job_stats_log(struct obd_device *obd, char *jobid,
+ int event, long amount);
+void lprocfs_job_stats_fini(struct obd_device *obd);
+int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+ cntr_init_callback fn);
+int lprocfs_rd_job_interval(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+int lprocfs_wr_job_interval(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+
/* lproc_ptlrpc.c */
struct ptlrpc_request;
extern void target_print_req(void *seq_file, struct ptlrpc_request *req);
#else
/* LPROCFS is not defined */
-
+#define proc_lustre_root NULL
static inline void lprocfs_counter_add(struct lprocfs_stats *stats,
int index, long amount)
static inline void lprocfs_remove_proc_entry(const char *name,
struct proc_dir_entry *parent)
{ return; }
+static inline void lprocfs_try_remove_proc_entry(const char *name,
+ struct proc_dir_entry *parent)
+{ return; }
static inline cfs_proc_dir_entry_t *lprocfs_srch(cfs_proc_dir_entry_t *head,
const char *name)
{ return 0; }
static inline int lprocfs_rd_import(char *page, char **start, off_t off,
int count, int *eof, void *data)
{ return 0; }
+static inline int lprocfs_rd_pinger_recov(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{ return 0; }
static inline int lprocfs_rd_state(char *page, char **start, off_t off,
int count, int *eof, void *data)
{ return 0; }
static inline int lprocfs_wr_import(struct file *file, const char *buffer,
unsigned long count, void *data)
{ return 0; }
+static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{ return 0; }
/* Statfs helpers */
static inline
#define LPROC_SEQ_FOPS_RO(name)
#define LPROC_SEQ_FOPS(name)
+/* lprocfs_jobstats.c */
+static inline
+int lprocfs_job_stats_log(struct obd_device *obd, char *jobid, int event,
+ long amount)
+{ return 0; }
+static inline
+void lprocfs_job_stats_fini(struct obd_device *obd)
+{ return; }
+static inline
+int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+ cntr_init_callback fn)
+{ return 0; }
+
+
/* lproc_ptlrpc.c */
#define target_print_req NULL