int lprocfs_single_release(struct inode *inode, struct file *file)
{
- LPROCFS_EXIT();
return single_release(inode, file);
}
EXPORT_SYMBOL(lprocfs_single_release);
int lprocfs_seq_release(struct inode *inode, struct file *file)
{
- LPROCFS_EXIT();
return seq_release(inode, file);
}
EXPORT_SYMBOL(lprocfs_seq_release);
if (page == NULL)
return -ENOMEM;
- if (LPROCFS_ENTRY_AND_CHECK(dp)) {
+ if (LPROCFS_ENTRY_CHECK(dp)) {
rc = -ENOENT;
goto out;
}
if (dp->read_proc)
rc = dp->read_proc(page, &start, *ppos, PAGE_CACHE_SIZE,
&eof, dp->data);
- LPROCFS_EXIT();
if (rc <= 0)
goto out;
struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
int rc = -EIO;
- if (LPROCFS_ENTRY_AND_CHECK(dp))
+ if (LPROCFS_ENTRY_CHECK(dp))
return -ENOENT;
if (dp->write_proc)
rc = dp->write_proc(f, buf, size, dp->data);
- LPROCFS_EXIT();
return rc;
}
int lprocfs_evict_client_release(struct inode *inode, struct file *f)
{
- struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
- struct obd_device *obd = dp->data;
+ struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
+ struct obd_device *obd = dp->data;
- cfs_atomic_dec(&obd->obd_evict_inprogress);
- cfs_waitq_signal(&obd->obd_evict_inprogress_waitq);
+ cfs_atomic_dec(&obd->obd_evict_inprogress);
+ wake_up(&obd->obd_evict_inprogress_waitq);
- return 0;
+ return 0;
}
struct file_operations lprocfs_evict_client_fops = {
"lightweight_conn",
"short_io",
"pingless",
+ "flock_deadlock",
"unknown",
NULL
};
if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
num_entry = 1;
else
- num_entry = cfs_num_possible_cpus();
+ num_entry = num_possible_cpus();
/* alloc percpu pointers for all possible cpu slots */
LIBCFS_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_entry]));
if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
num_entry = 1;
else
- num_entry = cfs_num_possible_cpus();
+ num_entry = num_possible_cpus();
percpusize = lprocfs_stats_counter_size(stats);
for (i = 0; i < num_entry; i++)
if (idx == 0) {
struct timeval now;
- cfs_gettimeofday(&now);
+ do_gettimeofday(&now);
rc = seq_printf(p, "%-25s %lu.%lu secs.usecs\n",
"snapshot_time", now.tv_sec, now.tv_usec);
if (rc < 0)
struct seq_file *seq;
int rc;
- if (LPROCFS_ENTRY_AND_CHECK(dp))
+ if (LPROCFS_ENTRY_CHECK(dp))
return -ENOENT;
rc = seq_open(file, &lprocfs_stats_seq_sops);
- if (rc) {
- LPROCFS_EXIT();
+ if (rc)
return rc;
- }
seq = file->private_data;
seq->private = dp->data;
return 0;
LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
+
+ CLASSERT(NUM_OBD_STATS == OBD_COUNTER_OFFSET(putref) + 1);
}
EXPORT_SYMBOL(lprocfs_init_ops_stats);
LASSERT(obd->obd_proc_entry != NULL);
LASSERT(obd->obd_cntr_base == 0);
- num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
- num_private_stats - 1 /* o_owner */;
+ num_stats = NUM_OBD_STATS + num_private_stats;
stats = lprocfs_alloc_stats(num_stats, 0);
if (stats == NULL)
return -ENOMEM;
}
EXPORT_SYMBOL(lprocfs_free_obd_stats);
-#define LPROCFS_MD_OP_INIT(base, stats, op) \
-do { \
- unsigned int coffset = base + MD_COUNTER_OFFSET(op); \
- LASSERT(coffset < stats->ls_num); \
- lprocfs_counter_init(stats, coffset, 0, #op, "reqs"); \
-} while (0)
+/* Note that we only init md counters for ops whose offset is less
+ * than NUM_MD_STATS. This is explained in a comment in the definition
+ * of struct md_ops. */
+#define LPROCFS_MD_OP_INIT(base, stats, op) \
+ do { \
+ unsigned int _idx = base + MD_COUNTER_OFFSET(op); \
+ \
+ if (MD_COUNTER_OFFSET(op) < NUM_MD_STATS) { \
+ LASSERT(_idx < stats->ls_num); \
+ lprocfs_counter_init(stats, _idx, 0, #op, "reqs"); \
+ } \
+ } while (0)
void lprocfs_init_mps_stats(int num_private_stats, struct lprocfs_stats *stats)
{
LPROCFS_MD_OP_INIT(num_private_stats, stats, rename);
LPROCFS_MD_OP_INIT(num_private_stats, stats, is_subdir);
LPROCFS_MD_OP_INIT(num_private_stats, stats, setattr);
- LPROCFS_MD_OP_INIT(num_private_stats, stats, sync);
+ LPROCFS_MD_OP_INIT(num_private_stats, stats, fsync);
LPROCFS_MD_OP_INIT(num_private_stats, stats, readpage);
LPROCFS_MD_OP_INIT(num_private_stats, stats, unlink);
LPROCFS_MD_OP_INIT(num_private_stats, stats, setxattr);
EXPORT_SYMBOL(lprocfs_init_mps_stats);
int lprocfs_alloc_md_stats(struct obd_device *obd,
- unsigned num_private_stats)
-{
- struct lprocfs_stats *stats;
- unsigned int num_stats;
- int rc, i;
-
- LASSERT(obd->md_stats == NULL);
- LASSERT(obd->obd_proc_entry != NULL);
- LASSERT(obd->md_cntr_base == 0);
+ unsigned int num_private_stats)
+{
+ struct lprocfs_stats *stats;
+ unsigned int num_stats;
+ int rc, i;
+
+ CLASSERT(offsetof(struct md_ops, MD_STATS_FIRST_OP) == 0);
+ CLASSERT(_MD_COUNTER_OFFSET(MD_STATS_FIRST_OP) == 0);
+ CLASSERT(_MD_COUNTER_OFFSET(MD_STATS_LAST_OP) > 0);
+
+ /* TODO Ensure that this function is only used where
+ * appropriate by adding an assertion to the effect that
+ * obd->obd_type->typ_md_ops is not NULL. We can't do this now
+ * because mdt_procfs_init() uses this function to allocate
+ * the stats backing /proc/fs/lustre/mdt/.../md_stats but the
+ * mdt layer does not use the md_ops interface. This is
+ * confusing and a waste of memory. See LU-2484.
+ */
+ LASSERT(obd->obd_proc_entry != NULL);
+ LASSERT(obd->obd_md_stats == NULL);
+ LASSERT(obd->obd_md_cntr_base == 0);
- num_stats = 1 + MD_COUNTER_OFFSET(revalidate_lock) +
- num_private_stats;
- stats = lprocfs_alloc_stats(num_stats, 0);
- if (stats == NULL)
- return -ENOMEM;
+ num_stats = NUM_MD_STATS + num_private_stats;
+ stats = lprocfs_alloc_stats(num_stats, 0);
+ if (stats == NULL)
+ return -ENOMEM;
- lprocfs_init_mps_stats(num_private_stats, stats);
+ lprocfs_init_mps_stats(num_private_stats, stats);
- for (i = num_private_stats; i < num_stats; i++) {
+ for (i = num_private_stats; i < num_stats; i++) {
if (stats->ls_cnt_header[i].lc_name == NULL) {
- CERROR("Missing md_stat initializer md_op "
- "operation at offset %d. Aborting.\n",
- i - num_private_stats);
- LBUG();
- }
- }
- rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
- if (rc < 0) {
- lprocfs_free_stats(&stats);
- } else {
- obd->md_stats = stats;
- obd->md_cntr_base = num_private_stats;
- }
- return rc;
+ CERROR("Missing md_stat initializer md_op "
+ "operation at offset %d. Aborting.\n",
+ i - num_private_stats);
+ LBUG();
+ }
+ }
+
+ rc = lprocfs_register_stats(obd->obd_proc_entry, "md_stats", stats);
+ if (rc < 0) {
+ lprocfs_free_stats(&stats);
+ } else {
+ obd->obd_md_stats = stats;
+ obd->obd_md_cntr_base = num_private_stats;
+ }
+
+ return rc;
}
EXPORT_SYMBOL(lprocfs_alloc_md_stats);
void lprocfs_free_md_stats(struct obd_device *obd)
{
- struct lprocfs_stats *stats = obd->md_stats;
+ struct lprocfs_stats *stats = obd->obd_md_stats;
- if (stats != NULL) {
- obd->md_stats = NULL;
- obd->md_cntr_base = 0;
- lprocfs_free_stats(&stats);
- }
+ if (stats != NULL) {
+ obd->obd_md_stats = NULL;
+ obd->obd_md_cntr_base = 0;
+ lprocfs_free_stats(&stats);
+ }
}
EXPORT_SYMBOL(lprocfs_free_md_stats);
if (!nid || *nid == LNET_NID_ANY)
RETURN(0);
+ spin_lock(&exp->exp_lock);
+ if (exp->exp_nid_stats != NULL) {
+ spin_unlock(&exp->exp_lock);
+ RETURN(-EALREADY);
+ }
+ spin_unlock(&exp->exp_lock);
+
obd = exp->exp_obd;
CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash);
old_stat, libcfs_nid2str(*nid),
cfs_atomic_read(&new_stat->nid_exp_ref_count));
- /* We need to release old stats because lprocfs_exp_cleanup() hasn't
- * been and will never be called. */
- if (exp->exp_nid_stats) {
- nidstat_putref(exp->exp_nid_stats);
- exp->exp_nid_stats = NULL;
- }
-
- /* Return -EALREADY here so that we know that the /proc
- * entry already has been created */
- if (old_stat != new_stat) {
- exp->exp_nid_stats = old_stat;
- GOTO(destroy_new, rc = -EALREADY);
- }
+ /* Return -EALREADY here so that we know that the /proc
+ * entry already has been created */
+ if (old_stat != new_stat) {
+ nidstat_putref(old_stat);
+ GOTO(destroy_new, rc = -EALREADY);
+ }
/* not found - create */
OBD_ALLOC(buffer, LNET_NIDSTR_SIZE);
if (buffer == NULL)
GOTO(destroy_new_ns, rc);
}
- exp->exp_nid_stats = new_stat;
+ spin_lock(&exp->exp_lock);
+ exp->exp_nid_stats = new_stat;
+ spin_unlock(&exp->exp_lock);
*newnid = 1;
/* protect competitive add to list, not need locking on destroy */
spin_lock(&obd->obd_nid_lock);
}
units = 1;
- switch(*end) {
- case 'p': case 'P':
- units <<= 10;
- case 't': case 'T':
- units <<= 10;
- case 'g': case 'G':
- units <<= 10;
- case 'm': case 'M':
- units <<= 10;
- case 'k': case 'K':
- units <<= 10;
- }
+ if (end != NULL) {
+ switch (*end) {
+ case 'p': case 'P':
+ units <<= 10;
+ case 't': case 'T':
+ units <<= 10;
+ case 'g': case 'G':
+ units <<= 10;
+ case 'm': case 'M':
+ units <<= 10;
+ case 'k': case 'K':
+ units <<= 10;
+ }
+ }
/* Specified units override the multiplier */
if (units)
mult = mult < 0 ? -units : units;
void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
{
- unsigned int val;
+ unsigned int val = 0;
- for (val = 0; ((1 << val) < value) && (val <= OBD_HIST_MAX); val++)
- ;
+ if (likely(value != 0))
+ val = min(fls(value - 1), OBD_HIST_MAX);
- lprocfs_oh_tally(oh, val);
+ lprocfs_oh_tally(oh, val);
}
EXPORT_SYMBOL(lprocfs_oh_tally_log2);