Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / obdclass / lprocfs_status.c
index 6f9d903..01ac77b 100644 (file)
@@ -38,6 +38,8 @@
 
 #if defined(LPROCFS)
 
+#define MAX_STRING_SIZE 128
+
 /* for bug 10866, global variable */
 DECLARE_RWSEM(_lprocfs_lock);
 EXPORT_SYMBOL(_lprocfs_lock);
@@ -181,6 +183,36 @@ static struct file_operations lprocfs_generic_fops = {
         .write = lprocfs_fops_write,
 };
 
+int lprocfs_evict_client_open(struct inode *inode, struct file *f)
+{
+        struct proc_dir_entry *dp = PDE(f->f_dentry->d_inode);
+        struct obd_device *obd = dp->data;
+
+        atomic_inc(&obd->obd_evict_inprogress);
+
+        return 0;
+}
+
+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;
+
+        atomic_dec(&obd->obd_evict_inprogress);
+        wake_up(&obd->obd_evict_inprogress_waitq);
+
+        return 0;
+}
+
+struct file_operations lprocfs_evict_client_fops = {
+        .owner = THIS_MODULE,
+        .read = lprocfs_fops_read,
+        .write = lprocfs_fops_write,
+        .open = lprocfs_evict_client_open,
+        .release = lprocfs_evict_client_release,
+};
+EXPORT_SYMBOL(lprocfs_evict_client_fops);
+
 int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
                      void *data)
 {
@@ -237,7 +269,10 @@ int lprocfs_add_vars(struct proc_dir_entry *root, struct lprocfs_vars *list,
                         return -ENOMEM;
                 }
 
-                proc->proc_fops = &lprocfs_generic_fops;
+                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);
@@ -309,6 +344,31 @@ struct proc_dir_entry *lprocfs_register(const char *name,
 }
 
 /* Generic callbacks */
+int lprocfs_rd_uint(char *page, char **start, off_t off,
+                    int count, int *eof, void *data)
+{
+        unsigned int *temp = (unsigned int *)data;
+        return snprintf(page, count, "%u\n", *temp);
+}
+
+int lprocfs_wr_uint(struct file *file, const char *buffer,
+                    unsigned long count, void *data)
+{
+        unsigned *p = data;
+        char dummy[MAX_STRING_SIZE + 1], *end;
+        unsigned long tmp;
+
+        dummy[MAX_STRING_SIZE] = '\0';
+        if (copy_from_user(dummy, buffer, MAX_STRING_SIZE))
+                return -EFAULT;
+
+        tmp = simple_strtoul(dummy, &end, 0);
+        if (dummy == end)
+                return -EINVAL;
+
+        *p = (unsigned int)tmp;
+        return count;
+}
 
 int lprocfs_rd_u64(char *page, char **start, off_t off,
                    int count, int *eof, void *data)
@@ -327,6 +387,24 @@ int lprocfs_rd_atomic(char *page, char **start, off_t off,
         return snprintf(page, count, "%d\n", atomic_read(atom));
 }
 
+int lprocfs_wr_atomic(struct file *file, const char *buffer,
+                      unsigned long count, void *data)
+{
+        atomic_t *atm = data;
+        int val = 0;
+        int rc;
+        
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc < 0)
+                return rc;
+
+        if (val <= 0)
+                return -ERANGE;
+                
+        atomic_set(atm, val);
+        return count;
+}
+
 int lprocfs_rd_uuid(char *page, char **start, off_t off, int count,
                     int *eof, void *data)
 {
@@ -505,9 +583,9 @@ static const char *obd_connect_names[] = {
         "request_portal",
         "acl",
         "xattr",
-        "real_conn",
+        "create_on_write",
         "truncate_lock",
-        "obsoleted",
+        "initial_transno",
         "inode_bit_locks",
         "join_file",
         "getattr_by_fid",
@@ -518,8 +596,12 @@ static const char *obd_connect_names[] = {
         "64bit_qdata",
         "mds_capability",
         "oss_capability",
-        "mds_mds_connection",
+        "early_lock_cancel",
         "size_on_mds",
+        "adaptive_timeouts",
+        "lru_resize",
+        "mds_mds_connection",
+        "real_conn",
         NULL
 };
 
@@ -599,31 +681,49 @@ int lprocfs_obd_cleanup(struct obd_device *obd)
         return 0;
 }
 
-struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num)
+struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
+                                          enum lprocfs_stats_flags flags)
 {
         struct lprocfs_stats *stats;
         struct lprocfs_percpu *percpu;
         unsigned int percpusize;
         unsigned int i;
+        unsigned int num_cpu;
 
         if (num == 0)
                 return NULL;
 
-        OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
+        if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
+                num_cpu = 1;
+        else
+                num_cpu = num_possible_cpus();
+
+        OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
         if (stats == NULL)
                 return NULL;
 
-        percpusize = L1_CACHE_ALIGN(offsetof(typeof(*percpu), lp_cntr[num]));
-        stats->ls_percpu_size = num_online_cpus() * percpusize;
+        if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+                stats->ls_flags = flags;
+                spin_lock_init(&stats->ls_lock);
+                /* Use this lock only if there are no percpu areas */
+        } else {
+                stats->ls_flags = 0;
+        }
+
+        percpusize = offsetof(typeof(*percpu), lp_cntr[num]);
+        if (num_cpu > 1)
+                percpusize = L1_CACHE_ALIGN(percpusize);
+
+        stats->ls_percpu_size = num_cpu * percpusize;
         OBD_ALLOC(stats->ls_percpu[0], stats->ls_percpu_size);
         if (stats->ls_percpu[0] == NULL) {
                 OBD_FREE(stats, offsetof(typeof(*stats),
-                                         ls_percpu[num_online_cpus()]));
+                                         ls_percpu[num_cpu]));
                 return NULL;
         }
 
         stats->ls_num = num;
-        for (i = 1; i < num_online_cpus(); i++)
+        for (i = 1; i < num_cpu; i++)
                 stats->ls_percpu[i] = (void *)(stats->ls_percpu[i - 1]) +
                         percpusize;
 
@@ -633,21 +733,30 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num)
 void lprocfs_free_stats(struct lprocfs_stats **statsh)
 {
         struct lprocfs_stats *stats = *statsh;
+        unsigned int num_cpu;
 
         if (stats == NULL || stats->ls_num == 0)
                 return;
         *statsh = NULL;
 
+        if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
+                num_cpu = 1;
+        else
+                num_cpu = num_possible_cpus();
+
         OBD_FREE(stats->ls_percpu[0], stats->ls_percpu_size);
-        OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_online_cpus()]));
+        OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
 }
 
 void lprocfs_clear_stats(struct lprocfs_stats *stats)
 {
         struct lprocfs_counter *percpu_cntr;
         int i,j;
+        unsigned int num_cpu;
 
-        for (i = 0; i < num_online_cpus(); i++) {
+        num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
+
+        for (i = 0; i < num_cpu; i++) {
                 for (j = 0; j < stats->ls_num; j++) {        
                         percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j];
                         atomic_inc(&percpu_cntr->lc_cntl.la_entry);
@@ -659,6 +768,8 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats)
                         atomic_inc(&percpu_cntr->lc_cntl.la_exit);
                 }
         }
+
+        lprocfs_stats_unlock(stats);
 }
 
 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
@@ -699,6 +810,7 @@ static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
        struct lprocfs_counter  *cntr = v;
        struct lprocfs_counter  t, ret = { .lc_min = ~(__u64)0 };
        int i, idx, rc;
+       unsigned int num_cpu;
 
        if (cntr == &(stats->ls_percpu[0])->lp_cntr[0]) {
                struct timeval now;
@@ -710,7 +822,12 @@ static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
        }
        idx = cntr - &(stats->ls_percpu[0])->lp_cntr[0];
 
-       for (i = 0; i < num_online_cpus(); i++) {
+       if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
+               num_cpu = 1;
+       else
+               num_cpu = num_possible_cpus();
+
+       for (i = 0; i < num_cpu; i++) {
                struct lprocfs_counter *percpu_cntr =
                        &(stats->ls_percpu[i])->lp_cntr[idx];
                int centry;
@@ -805,9 +922,13 @@ void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
 {
         struct lprocfs_counter *c;
         int i;
+        unsigned int num_cpu;
 
         LASSERT(stats != NULL);
-        for (i = 0; i < num_online_cpus(); i++) {
+
+        num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
+
+        for (i = 0; i < num_cpu; i++) {
                 c = &(stats->ls_percpu[i]->lp_cntr[index]);
                 c->lc_config = conf;
                 c->lc_count = 0;
@@ -817,6 +938,8 @@ void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
                 c->lc_name = name;
                 c->lc_units = units;
         }
+
+        lprocfs_stats_unlock(stats);
 }
 EXPORT_SYMBOL(lprocfs_counter_init);
 
@@ -854,6 +977,7 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats)
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, checkmd);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate);
+        LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, create);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy);
         LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr);
@@ -911,7 +1035,7 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
 
         num_stats = ((int)sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
                 num_private_stats - 1 /* o_owner */;
-        stats = lprocfs_alloc_stats(num_stats);
+        stats = lprocfs_alloc_stats(num_stats, 0);
         if (stats == NULL)
                 return -ENOMEM;
 
@@ -963,7 +1087,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd,
 
         num_stats = 1 + MD_COUNTER_OFFSET(get_remote_perm) +
                     num_private_stats;
-        stats = lprocfs_alloc_stats(num_stats);
+        stats = lprocfs_alloc_stats(num_stats, 0);
         if (stats == NULL)
                 return -ENOMEM;
 
@@ -1079,7 +1203,7 @@ int lprocfs_exp_setup(struct obd_export *exp)
                 GOTO(out, rc);
         /* Always add ldlm stats */
         exp->exp_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC 
-                                                  - LDLM_FIRST_OPC);
+                                                  - LDLM_FIRST_OPC, 0);
         if (exp->exp_ldlm_stats == NULL) {
                 lprocfs_remove(&exp->exp_proc);
                 GOTO(out, rc = -ENOMEM);
@@ -1473,6 +1597,9 @@ EXPORT_SYMBOL(lprocfs_exp_cleanup);
 
 EXPORT_SYMBOL(lprocfs_rd_u64);
 EXPORT_SYMBOL(lprocfs_rd_atomic);
+EXPORT_SYMBOL(lprocfs_wr_atomic);
+EXPORT_SYMBOL(lprocfs_rd_uint);
+EXPORT_SYMBOL(lprocfs_wr_uint);
 EXPORT_SYMBOL(lprocfs_rd_uuid);
 EXPORT_SYMBOL(lprocfs_rd_name);
 EXPORT_SYMBOL(lprocfs_rd_fstype);