[Devel] [PATCH RHEL7 COMMIT] fs/fuse kio: add storage_version attribute to control filesystem
Konstantin Khorenko
khorenko at virtuozzo.com
Mon May 25 15:56:36 MSK 2020
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 at 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 at virtuozzo.com>
Acked-by: Andrey Zaitsev <azaitsev at virtuozzo.com>
Acked-by: Alexey Kuznetsov <kuznet at 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(+)
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)
{
More information about the Devel
mailing list