[02/15] fs/fuse kio: create sysfs stat directory

Submitted by Pavel Butsykin on May 17, 2019, 1:20 p.m.

Details

Message ID 20190517132048.13162-3-pbutsykin@virtuozzo.com
State New
Series "Statistics for vstorage kernel fast-path"
Headers show

Commit Message

Pavel Butsykin May 17, 2019, 1:20 p.m.
This patch implements the interfaces for initialize/finalize kio stat subsystem
and adds the creation of stat directory. The sysfs directory will be created
separately for each point.

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/Makefile                   |  3 +-
 fs/fuse/control.c                  |  3 +-
 fs/fuse/inode.c                    |  1 +
 fs/fuse/kio/pcs/fuse_stat.c        | 83 ++++++++++++++++++++++++++++++++++++++
 fs/fuse/kio/pcs/fuse_stat.h        | 11 +++++
 fs/fuse/kio/pcs/pcs_cluster_core.c |  3 ++
 fs/fuse/kio/pcs/pcs_req.h          |  2 +
 7 files changed, 104 insertions(+), 2 deletions(-)
 create mode 100644 fs/fuse/kio/pcs/fuse_stat.c
 create mode 100644 fs/fuse/kio/pcs/fuse_stat.h

Patch hide | download patch | download mbox

diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
index 3eb06648da2c..87f655c596e6 100644
--- a/fs/fuse/Makefile
+++ b/fs/fuse/Makefile
@@ -24,6 +24,7 @@  fuse_kio_pcs-objs := kio/pcs/pcs_fuse_kdirect.o \
 	kio/pcs/pcs_cluster.o \
 	kio/pcs/pcs_cluster_core.o \
 	kio/pcs/pcs_cs.o \
-	kio/pcs/fuse_io.o
+	kio/pcs/fuse_io.o \
+	kio/pcs/fuse_stat.o
 
 fuse-objs := dev.o dir.o file.o inode.o control.o
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 5ea8ab2165cf..e9734d597419 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -18,7 +18,8 @@ 
  * This is non-NULL when the single instance of the control filesystem
  * exists.  Protected by fuse_mutex
  */
-static struct super_block *fuse_control_sb;
+struct super_block *fuse_control_sb;
+EXPORT_SYMBOL_GPL(fuse_control_sb);
 
 static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file)
 {
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 25f6e0ceac37..ff3fbc0a779b 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -31,6 +31,7 @@  static struct kmem_cache *fuse_inode_cachep;
 static LIST_HEAD(fuse_kios_list);
 struct list_head fuse_conn_list;
 DEFINE_MUTEX(fuse_mutex);
+EXPORT_SYMBOL_GPL(fuse_mutex);
 
 static int fuse_ve_odirect;
 
diff --git a/fs/fuse/kio/pcs/fuse_stat.c b/fs/fuse/kio/pcs/fuse_stat.c
new file mode 100644
index 000000000000..da8428ebe600
--- /dev/null
+++ b/fs/fuse/kio/pcs/fuse_stat.c
@@ -0,0 +1,83 @@ 
+#include <net/sock.h>
+#include <linux/types.h>
+
+#include "fuse_stat.h"
+#include "pcs_cluster.h"
+
+extern struct super_block *fuse_control_sb;
+
+static struct dentry *fuse_kio_add_dentry(struct dentry *parent,
+					  struct fuse_conn *fc,
+					  const char *name,
+					  int mode, int nlink,
+					  const struct inode_operations *iop,
+					  const struct file_operations *fop,
+					  void *ctx)
+{
+	struct inode *inode;
+	struct dentry *dentry = d_alloc_name(parent, name);
+
+	if (!dentry)
+		return NULL;
+
+	inode = new_inode(fc->sb);
+	if (!inode) {
+		dput(dentry);
+		return NULL;
+	}
+
+	inode->i_ino = get_next_ino();
+	inode->i_mode = mode;
+	inode->i_uid = fc->user_id;
+	inode->i_gid = fc->group_id;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	if (iop)
+		inode->i_op = iop;
+	inode->i_fop = fop;
+	set_nlink(inode, nlink);
+	inode->i_private = ctx;
+	d_add(dentry, inode);
+
+	return dentry;
+}
+
+static void fuse_kio_rm_dentry(struct dentry *dentry)
+{
+	d_inode(dentry)->i_private = NULL;
+	d_drop(dentry);
+	dput(dentry);
+}
+
+void pcs_fuse_stat_init(struct pcs_fuse_stat *stat)
+{
+	struct fuse_conn *fc =
+		container_of(stat, struct pcs_fuse_cluster, cc.stat)->fc;
+
+	mutex_lock(&fuse_mutex);
+	if (!fuse_control_sb)
+		goto out;
+
+	stat->kio_stat = fuse_kio_add_dentry(fc->conn_ctl, fc, "kio_stat",
+					     S_IFDIR | S_IXUSR, 2,
+					     &simple_dir_inode_operations,
+					     &simple_dir_operations, fc);
+	if (!stat->kio_stat) {
+		pr_err("kio: can't create kio stat directory");
+		goto out;
+	}
+
+	/* Stat initialize */
+out:
+	mutex_unlock(&fuse_mutex);
+}
+
+void pcs_fuse_stat_fini(struct pcs_fuse_stat *stat)
+{
+	if (!stat->kio_stat)
+		return;
+
+	mutex_lock(&fuse_mutex);
+	if (fuse_control_sb)
+		fuse_kio_rm_dentry(stat->kio_stat);
+	mutex_unlock(&fuse_mutex);
+}
diff --git a/fs/fuse/kio/pcs/fuse_stat.h b/fs/fuse/kio/pcs/fuse_stat.h
new file mode 100644
index 000000000000..14687ffd83f2
--- /dev/null
+++ b/fs/fuse/kio/pcs/fuse_stat.h
@@ -0,0 +1,11 @@ 
+#ifndef _FUSE_STAT_H_
+#define _FUSE_STAT_H_ 1
+
+struct pcs_fuse_stat {
+	struct dentry *kio_stat;
+};
+
+void pcs_fuse_stat_init(struct pcs_fuse_stat *stat);
+void pcs_fuse_stat_fini(struct pcs_fuse_stat *stat);
+
+#endif /* _FUSE_STAT_H_ */
\ No newline at end of file
diff --git a/fs/fuse/kio/pcs/pcs_cluster_core.c b/fs/fuse/kio/pcs/pcs_cluster_core.c
index d1379c99ac6a..aa54ca8d6b45 100644
--- a/fs/fuse/kio/pcs/pcs_cluster_core.c
+++ b/fs/fuse/kio/pcs/pcs_cluster_core.c
@@ -151,6 +151,8 @@  int pcs_cc_init(struct pcs_cluster_core *cc, struct workqueue_struct *wq,
 	 * pcs_srandomdev(&cc->rng);
 	 */
 
+	pcs_fuse_stat_init(&cc->stat);
+
 	memset(&cc->cfg,   0, sizeof(cc->cfg));
 	memset(&cc->op,	   0, sizeof(cc->op));
 
@@ -177,6 +179,7 @@  void pcs_cc_fini(struct pcs_cluster_core *cc)
 	pcs_csset_fini(&cc->css);
 	pcs_mapset_fini(&cc->maps);
 	pcs_rpc_engine_fini(&cc->eng);
+	pcs_fuse_stat_fini(&cc->stat);
 
 	BUG_ON(!list_empty(&cc->completion_queue));
 	BUG_ON(!list_empty(&cc->work_queue));
diff --git a/fs/fuse/kio/pcs/pcs_req.h b/fs/fuse/kio/pcs/pcs_req.h
index e668e55f0b71..3a9534b1a5af 100644
--- a/fs/fuse/kio/pcs/pcs_req.h
+++ b/fs/fuse/kio/pcs/pcs_req.h
@@ -8,6 +8,7 @@ 
 #include "pcs_cs_prot.h"
 #include "pcs_rpc.h"
 #include "pcs_cs.h"
+#include "fuse_stat.h"
 
 ///////////////////////////
 
@@ -207,6 +208,7 @@  struct pcs_cluster_core
 ////	struct pcs_ratelimit	rlim;		/* Rate limiter */
 ////	struct pcs_rng		rng;
 	/* <SKIP */
+	struct pcs_fuse_stat	stat;
 
 	struct {
 		struct pcs_clnt_config	def;