+static int
+lprocfs_mdt_print_open_files(struct cfs_hash *hs, struct cfs_hash_bd *bd,
+ struct hlist_node *hnode, void *v)
+{
+ struct obd_export *exp = cfs_hash_object(hs, hnode);
+ struct seq_file *seq = v;
+
+ if (exp->exp_lock_hash != NULL) {
+ struct mdt_export_data *med = &exp->exp_mdt_data;
+ struct mdt_file_data *mfd;
+
+ spin_lock(&med->med_open_lock);
+ list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
+ seq_printf(seq, DFID"\n",
+ PFID(mdt_object_fid(mfd->mfd_object)));
+ }
+ spin_unlock(&med->med_open_lock);
+ }
+
+ return 0;
+}
+
+static int lprocfs_mdt_open_files_seq_show(struct seq_file *seq, void *v)
+{
+ struct nid_stat *stats = seq->private;
+ struct obd_device *obd = stats->nid_obd;
+
+ cfs_hash_for_each_key(obd->obd_nid_hash, &stats->nid,
+ lprocfs_mdt_print_open_files, seq);
+
+ return 0;
+}
+
+int lprocfs_mdt_open_files_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc;
+
+ rc = single_open(file, &lprocfs_mdt_open_files_seq_show, NULL);
+ if (rc != 0)
+ return rc;
+
+ seq = file->private_data;
+ seq->private = PDE_DATA(inode);
+
+ return 0;
+}
+
+void mdt_counter_incr(struct ptlrpc_request *req, int opcode)
+{
+ struct obd_export *exp = req->rq_export;
+
+ if (exp->exp_obd && exp->exp_obd->obd_md_stats)
+ lprocfs_counter_incr(exp->exp_obd->obd_md_stats, opcode);
+ if (exp->exp_nid_stats && exp->exp_nid_stats->nid_stats != NULL)
+ lprocfs_counter_incr(exp->exp_nid_stats->nid_stats, opcode);
+ if (exp->exp_obd && exp->exp_obd->u.obt.obt_jobstats.ojs_hash &&
+ (exp_connect_flags(exp) & OBD_CONNECT_JOBSTATS))
+ lprocfs_job_stats_log(exp->exp_obd,
+ lustre_msg_get_jobid(req->rq_reqmsg),
+ opcode, 1);
+}
+
+void mdt_stats_counter_init(struct lprocfs_stats *stats)
+{
+ lprocfs_counter_init(stats, LPROC_MDT_OPEN, 0, "open", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_CLOSE, 0, "close", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_MKNOD, 0, "mknod", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_LINK, 0, "link", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_UNLINK, 0, "unlink", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_MKDIR, 0, "mkdir", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_RMDIR, 0, "rmdir", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_RENAME, 0, "rename", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_GETATTR, 0, "getattr", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_SETATTR, 0, "setattr", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_GETXATTR, 0, "getxattr", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_SETXATTR, 0, "setxattr", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_STATFS, 0, "statfs", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_SYNC, 0, "sync", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_SAMEDIR_RENAME, 0,
+ "samedir_rename", "reqs");
+ lprocfs_counter_init(stats, LPROC_MDT_CROSSDIR_RENAME, 0,
+ "crossdir_rename", "reqs");
+}
+
+int mdt_procfs_init(struct mdt_device *mdt, const char *name)
+{
+ struct obd_device *obd = mdt2obd_dev(mdt);
+ int rc;
+ ENTRY;
+
+ LASSERT(name != NULL);
+
+ obd->obd_vars = lprocfs_mdt_obd_vars;
+ rc = lprocfs_obd_setup(obd);
+ if (rc) {
+ CERROR("%s: cannot create proc entries: rc = %d\n",
+ mdt_obd_name(mdt), rc);
+ return rc;
+ }
+
+ rc = hsm_cdt_procfs_init(mdt);
+ if (rc) {
+ CERROR("%s: cannot create hsm proc entries: rc = %d\n",
+ mdt_obd_name(mdt), rc);
+ return rc;
+ }
+
+ 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",
+ obd, &mdt_nid_stats_clear_fops);
+ rc = lprocfs_alloc_md_stats(obd, LPROC_MDT_LAST);
+ if (rc)
+ return rc;
+ mdt_stats_counter_init(obd->obd_md_stats);
+
+ rc = lprocfs_job_stats_init(obd, LPROC_MDT_LAST,
+ mdt_stats_counter_init);
+
+ rc = lproc_mdt_attach_rename_seqstat(mdt);
+ if (rc)
+ CERROR("%s: MDT can not create rename stats rc = %d\n",
+ mdt_obd_name(mdt), rc);
+
+ RETURN(rc);
+}