[RHEL7,COMMIT] fs/fuse kio: add storage_version attribute to control filesystem

Submitted by Konstantin Khorenko on May 25, 2020, 12:56 p.m.

Details

Message ID 202005251256.04PCuanV002986@finist-ce7.sw.ru
State New
Series "fs/fuse kio: add storage_version attribute to control filesystem"
Headers show

Commit Message

Konstantin Khorenko May 25, 2020, 12:56 p.m.
The commit is pushed to "branch-rh7-3.10.0-1127.8.2.vz7.161.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.8.2.vz7.161.1
------>
commit 96a38ce0222b03088ede42bc8af0b15c569db74b
Author: Ildar Ismagilov <Ildar.Ismagilov@acronis.com>
Date:   Mon May 25 15:56:35 2020 +0300

    fs/fuse kio: add storage_version attribute to control filesystem
    
    This patch provides the ability to check and update storage version
    throught sysfs '/sys/fs/fuse/connections/<mnt_id>/kio_stat/storage_version'.
    
    It seems to me that the "kio_stat" directory should be renamed to more
    general "kio", and should be used for all Fast-Path related attributes
    and statistics.
    
    https://pmc.acronis.com/browse/VSTOR-33830
    
    Signed-off-by: Ildar Ismagilov <ildar.ismagilov@virtuozzo.com>
    Acked-by: Andrey Zaitsev <azaitsev@virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet@acronis.com>
---
 fs/fuse/kio/pcs/fuse_stat.c        | 73 ++++++++++++++++++++++++++++++++++++++
 fs/fuse/kio/pcs/fuse_stat.h        |  1 +
 fs/fuse/kio/pcs/pcs_cluster_core.c | 13 +++++++
 fs/fuse/kio/pcs/pcs_prot_types.h   |  2 ++
 fs/fuse/kio/pcs/pcs_req.h          |  2 ++
 5 files changed, 91 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/fuse_stat.c b/fs/fuse/kio/pcs/fuse_stat.c
index c91bfe8b3bf7f..1bcffa9641a36 100644
--- a/fs/fuse/kio/pcs/fuse_stat.c
+++ b/fs/fuse/kio/pcs/fuse_stat.c
@@ -400,6 +400,72 @@  static const struct file_operations pcs_fuse_cs_stats_ops = {
 	.release = single_release,
 };
 
+static ssize_t pcs_fuse_storage_version_read(struct file *file,
+					     char __user *buf, size_t len,
+					     loff_t *ppos)
+{
+	struct pcs_fuse_stat *stat;
+	struct pcs_cluster_core *cc;
+	char ver[32];
+	size_t size;
+	ssize_t ret = 0;
+
+	mutex_lock(&fuse_mutex);
+
+	stat = file_inode(file)->i_private;
+	if (!stat)
+		goto out;
+	cc = container_of(stat, struct pcs_cluster_core, stat);
+
+	size = snprintf(ver, sizeof(ver), "%d\n",
+			atomic_read(&cc->storage_version));
+	ret = simple_read_from_buffer(buf, len, ppos, ver, size);
+
+out:
+	mutex_unlock(&fuse_mutex);
+
+	return ret;
+}
+
+static ssize_t pcs_fuse_storage_version_write(struct file *file,
+					      const char __user *buf,
+					      size_t count, loff_t *ppos)
+{
+	struct pcs_fuse_stat *stat;
+	struct pcs_cluster_core *cc;
+	unsigned int ver;
+	int err;
+
+	if (*ppos)
+		return -EINVAL;
+
+	err = kstrtouint_from_user(buf, count, 0, &ver);
+	if (err)
+		return err;
+
+	mutex_lock(&fuse_mutex);
+
+	stat = file_inode(file)->i_private;
+	if (!stat)
+		goto out;
+	cc = container_of(stat, struct pcs_cluster_core, stat);
+
+	pcs_cc_update_storage_versions(cc, ver);
+
+out:
+	mutex_unlock(&fuse_mutex);
+
+	return count;
+}
+
+static const struct file_operations pcs_fuse_storage_version_ops = {
+	.owner   = THIS_MODULE,
+	.open    = nonseekable_open,
+	.read    = pcs_fuse_storage_version_read,
+	.write   = pcs_fuse_storage_version_write,
+	.llseek  = no_llseek,
+};
+
 static void fuse_kio_fstat_lat_itr(struct fuse_file *ff,
 				   struct pcs_dentry_info *di, void *ctx)
 {
@@ -847,6 +913,11 @@  void pcs_fuse_stat_init(struct pcs_fuse_stat *stat)
 	stat->cs_stats = fuse_kio_add_dentry(stat->kio_stat, fc, "cs_stats",
 					     S_IFREG | S_IRUSR, 1, NULL,
 					     &pcs_fuse_cs_stats_ops, stat);
+	stat->storage_version = fuse_kio_add_dentry(stat->kio_stat, fc,
+						    "storage_version",
+						    S_IFREG | S_IRUSR | S_IWUSR, 1, NULL,
+						    &pcs_fuse_storage_version_ops,
+						    stat);
 	mutex_unlock(&fuse_mutex);
 	return;
 
@@ -876,6 +947,8 @@  void pcs_fuse_stat_fini(struct pcs_fuse_stat *stat)
 			fuse_kio_rm_dentry(stat->fstat_lat);
 		if (stat->cs_stats)
 			fuse_kio_rm_dentry(stat->cs_stats);
+		if (stat->storage_version)
+			fuse_kio_rm_dentry(stat->storage_version);
 		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
index 438836898437f..36ff8472a1172 100644
--- a/fs/fuse/kio/pcs/fuse_stat.h
+++ b/fs/fuse/kio/pcs/fuse_stat.h
@@ -37,6 +37,7 @@  struct pcs_fuse_stat {
 	struct dentry *fstat;
 	struct dentry *fstat_lat;
 	struct dentry *cs_stats;
+	struct dentry *storage_version;
 };
 
 enum {
diff --git a/fs/fuse/kio/pcs/pcs_cluster_core.c b/fs/fuse/kio/pcs/pcs_cluster_core.c
index 180e5f726de51..a2b16f8c89ae4 100644
--- a/fs/fuse/kio/pcs/pcs_cluster_core.c
+++ b/fs/fuse/kio/pcs/pcs_cluster_core.c
@@ -116,6 +116,18 @@  static void cc_completion_handler(struct work_struct *w)
 	}
 }
 
+void pcs_cc_update_storage_versions(struct pcs_cluster_core *cc, int version)
+{
+	int old;
+
+	do {
+		old = atomic_read(&cc->storage_version);
+		if (old >= version)
+			break;
+		TRACE("storage version up %d -> %d", old, version);
+	} while (atomic_cmpxchg(&cc->storage_version, old, version) != old);
+}
+
 int pcs_cc_init(struct pcs_cluster_core *cc, struct workqueue_struct *wq,
 		const char *cluster_name, struct pcs_cluster_core_attr *attr)
 {
@@ -132,6 +144,7 @@  int pcs_cc_init(struct pcs_cluster_core *cc, struct workqueue_struct *wq,
 	INIT_WORK(&cc->fiemap_work, fiemap_work_func);
 	cc->wq = wq;
 	snprintf(cc->cluster_name, sizeof(cc->cluster_name), "%s", cluster_name);
+	atomic_set(&cc->storage_version, PCS_VERSION_UNKNOWN);
 
 	pcs_csset_init(&cc->css);
 
diff --git a/fs/fuse/kio/pcs/pcs_prot_types.h b/fs/fuse/kio/pcs/pcs_prot_types.h
index 11986252f23c7..638b076674678 100644
--- a/fs/fuse/kio/pcs/pcs_prot_types.h
+++ b/fs/fuse/kio/pcs/pcs_prot_types.h
@@ -12,6 +12,8 @@ 
 /* Current version */
 #define PCS_VERSION 121
 
+#define PCS_VERSION_UNKNOWN 0
+
 #define PCS_VZ7_VERSION 100
 
 /* milliseconds since Jan 1970 */
diff --git a/fs/fuse/kio/pcs/pcs_req.h b/fs/fuse/kio/pcs/pcs_req.h
index 4fb38d2dd8f43..33f0fe9e7cb55 100644
--- a/fs/fuse/kio/pcs/pcs_req.h
+++ b/fs/fuse/kio/pcs/pcs_req.h
@@ -238,6 +238,7 @@  struct pcs_cluster_core
 	spinlock_t		lock;
 
 	char cluster_name[NAME_MAX];
+	atomic_t storage_version;
 };
 
 static inline struct pcs_cluster_core *cc_from_csset(struct pcs_cs_set * css)
@@ -257,6 +258,7 @@  static inline struct pcs_cluster_core *cc_from_maps(struct pcs_map_set *maps)
 
 void pcs_cc_submit(struct pcs_cluster_core *cc, struct pcs_int_request* ireq);
 void pcs_cc_requeue(struct pcs_cluster_core *cc, struct list_head * q);
+void pcs_cc_update_storage_versions(struct pcs_cluster_core *cc, int version);
 ////// FROM pcs_cluster.h
 static inline void pcs_sreq_attach(struct pcs_int_request * sreq, struct pcs_int_request * parent)
 {