Whamcloud - gitweb
b=11089
[fs/lustre-release.git] / lustre / obdfilter / filter.c
index 24d3ff9..a1597f3 100644 (file)
@@ -160,14 +160,35 @@ static void init_brw_stats(struct brw_stats *brw_stats)
                 spin_lock_init(&brw_stats->hist[i].oh_lock);
 }
 
+static int lprocfs_init_rw_stats(struct obd_device *obd,
+                                 struct lprocfs_stats **stats)
+{
+        int num_stats;
+
+        num_stats = (sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
+                                                        LPROC_FILTER_LAST - 1;
+        *stats = lprocfs_alloc_stats(num_stats, 0);
+        if (*stats == NULL)
+                return -ENOMEM;
+
+        lprocfs_init_ops_stats(LPROC_FILTER_LAST, *stats);
+        lprocfs_counter_init(*stats, LPROC_FILTER_READ_BYTES,
+                             LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
+        lprocfs_counter_init(*stats, LPROC_FILTER_WRITE_BYTES,
+                             LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
+
+        return(0);
+}
+
 /* brw_stats are 2128, ops are 3916, ldlm are 204, so 6248 bytes per client,
    plus the procfs overhead :( */
 static int filter_export_stats_init(struct obd_device *obd,
-                                    struct obd_export *exp)
+                                    struct obd_export *exp,
+                                    lnet_nid_t client_nid)
 {
         struct filter_export_data *fed = &exp->exp_filter_data;
         struct proc_dir_entry *brw_entry;
-        int rc, num_stats;
+        int rc, newnid = 0;
         ENTRY;
 
         init_brw_stats(&fed->fed_brw_stats);
@@ -176,30 +197,38 @@ static int filter_export_stats_init(struct obd_device *obd,
                 /* Self-export gets no proc entry */
                 RETURN(0);
 
-        rc = lprocfs_exp_setup(exp);
+        rc = lprocfs_exp_setup(exp, client_nid, &newnid);
         if (rc)
                 RETURN(rc);
 
-        /* Create a per export proc entry for brw_stats */
-        brw_entry = create_proc_entry("brw_stats", 0644, exp->exp_proc);
-        if (brw_entry == NULL)
-               RETURN(-ENOMEM);
-        brw_entry->proc_fops = &filter_per_export_stats_fops;
-        brw_entry->data = fed;
+        if (client_nid && newnid) {
+                struct nid_stat *tmp = exp->exp_nid_stats;
+                LASSERT(tmp != NULL);
+
+                OBD_ALLOC(tmp->nid_brw_stats, sizeof(struct brw_stats));
+                if (tmp->nid_brw_stats == NULL)
+                        RETURN(-ENOMEM);
+
+                init_brw_stats(tmp->nid_brw_stats);
+
+                brw_entry = create_proc_entry("brw_stats", 0644,
+                                              exp->exp_nid_stats->nid_proc);
+                if (brw_entry == NULL)
+                       RETURN(-ENOMEM);
+
+                brw_entry->proc_fops = &filter_per_nid_stats_fops;
+                brw_entry->data = exp->exp_nid_stats;
+
+                rc = lprocfs_init_rw_stats(obd, &exp->exp_nid_stats->nid_stats);
+                if (rc)
+                        RETURN(rc);
+
+                rc = lprocfs_register_stats(tmp->nid_proc, "stats",
+                                            tmp->nid_stats);
+                if (rc)
+                        RETURN(rc);
+        }
 
-        /* Create a per export proc entry for ops stats */
-        num_stats = (sizeof(*obd->obd_type->typ_dt_ops) / sizeof(void *)) +
-                     LPROC_FILTER_LAST - 1;
-        exp->exp_ops_stats = lprocfs_alloc_stats(num_stats,
-                                                 LPROCFS_STATS_FLAG_NOPERCPU);
-        if (exp->exp_ops_stats == NULL)
-              RETURN(-ENOMEM);
-        lprocfs_init_ops_stats(LPROC_FILTER_LAST, exp->exp_ops_stats);
-        lprocfs_counter_init(exp->exp_ops_stats, LPROC_FILTER_READ_BYTES,
-                             LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
-        lprocfs_counter_init(exp->exp_ops_stats, LPROC_FILTER_WRITE_BYTES,
-                             LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
-        lprocfs_register_stats(exp->exp_proc, "stats", exp->exp_ops_stats);
         RETURN(0);
 }
 
@@ -208,7 +237,7 @@ static int filter_export_stats_init(struct obd_device *obd,
  * Otherwise, we have just read the data from the last_rcvd file and
  * we know its offset. */
 static int filter_client_add(struct obd_device *obd, struct obd_export *exp,
-                             int cl_idx)
+                             int cl_idx, lnet_nid_t client_nid)
 {
         struct filter_obd *filter = &obd->u.filter;
         struct filter_export_data *fed = &exp->exp_filter_data;
@@ -772,8 +801,8 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp)
                         fed = &exp->exp_filter_data;
                         fed->fed_fcd = fcd;
                         fed->fed_group = le32_to_cpu(fcd->fcd_group);
-                        filter_export_stats_init(obd, exp);
-                        rc = filter_client_add(obd, exp, cl_idx);
+                        filter_export_stats_init(obd, exp, 0);
+                        rc = filter_client_add(obd, exp, cl_idx, 0);
                         /* can't fail for existing client */
                         LASSERTF(rc == 0, "rc = %d\n", rc);
 
@@ -2083,9 +2112,13 @@ static int filter_setup(struct obd_device *obd, struct lustre_cfg* lcfg)
                                      "write_bytes", "bytes");
 
                 lproc_filter_attach_seqstat(obd);
-                obd->obd_proc_exports = proc_mkdir("exports",
-                                                   obd->obd_proc_entry);
+                obd->obd_proc_exports_entry = proc_mkdir("exports",
+                                                         obd->obd_proc_entry);
         }
+        if (obd->obd_proc_exports_entry)
+                lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
+                                   lprocfs_nid_stats_clear_read,
+                                   lprocfs_nid_stats_clear_write, obd);
 
         memcpy((void *)addr, lustre_cfg_buf(lcfg, 4),
                LUSTRE_CFG_BUFLEN(lcfg, 4));
@@ -2093,8 +2126,10 @@ static int filter_setup(struct obd_device *obd, struct lustre_cfg* lcfg)
         OBD_PAGE_FREE(page);
 
         if (rc) {
-                lprocfs_obd_cleanup(obd);
+                remove_proc_entry("clear", obd->obd_proc_exports_entry);
+                lprocfs_free_per_client_stats(obd);
                 lprocfs_free_obd_stats(obd);
+                lprocfs_obd_cleanup(obd);
         }
 
         return rc;
@@ -2354,8 +2389,10 @@ static int filter_cleanup(struct obd_device *obd)
                 }
         }
 
-        lprocfs_obd_cleanup(obd);
+        remove_proc_entry("clear", obd->obd_proc_exports_entry);
+        lprocfs_free_per_client_stats(obd);
         lprocfs_free_obd_stats(obd);
+        lprocfs_obd_cleanup(obd);
         lquota_cleanup(filter_quota_interface_ref, obd);
 
         /* Stop recovery before namespace cleanup. */
@@ -2511,12 +2548,13 @@ static int filter_reconnect(const struct lu_env *env,
 static int filter_connect(const struct lu_env *env,
                           struct lustre_handle *conn, struct obd_device *obd,
                           struct obd_uuid *cluuid,
-                          struct obd_connect_data *data)
+                          struct obd_connect_data *data, void *localdata)
 {
         struct lvfs_run_ctxt saved;
         struct obd_export *exp;
         struct filter_export_data *fed;
         struct filter_client_data *fcd = NULL;
+        lnet_nid_t client_nid;
         __u32 group;
         int rc;
         ENTRY;
@@ -2524,6 +2562,12 @@ static int filter_connect(const struct lu_env *env,
         if (conn == NULL || obd == NULL || cluuid == NULL)
                 RETURN(-EINVAL);
 
+        if (localdata != NULL)
+                client_nid = *(lnet_nid_t *)localdata;
+        else
+                client_nid = 0ULL;
+
+
         rc = class_connect(conn, obd, cluuid);
         if (rc)
                 RETURN(rc);
@@ -2536,7 +2580,7 @@ static int filter_connect(const struct lu_env *env,
         if (rc)
                 GOTO(cleanup, rc);
 
-        filter_export_stats_init(obd, exp);
+        filter_export_stats_init(obd, exp, client_nid);
         group = data->ocd_group;
         if (obd->obd_replayable) {
                 OBD_ALLOC(fcd, sizeof(*fcd));
@@ -2548,7 +2592,7 @@ static int filter_connect(const struct lu_env *env,
                 memcpy(fcd->fcd_uuid, cluuid, sizeof(fcd->fcd_uuid));
                 fed->fed_fcd = fcd;
                 fed->fed_fcd->fcd_group = group;
-                rc = filter_client_add(obd, exp, -1);
+                rc = filter_client_add(obd, exp, -1, client_nid);
                 if (rc)
                         GOTO(cleanup, rc);
         }