[Devel] [PATCH RHEL7 COMMIT] fuse kio: Reorder process_pcs_init_reply() and free memory on failure
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Oct 9 11:50:44 MSK 2018
The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.4
------>
commit b34569afc392a28d336e7e2d503bb00997ba5fda
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Tue Oct 9 11:50:42 2018 +0300
fuse kio: Reorder process_pcs_init_reply() and free memory on failure
Free pfc in case of allocation failure and reorder the function
in the way, that kio.op are assigned in case of success only.
Also, check for parallel abort, and skip initialization in this way.
My assumption is places dereferencing fc->kio.op can't
be executed in parallel, since the connection is not set
as initialized (all request allocation should wait till
fc->initialized is set 1). This allows not to introduce
complexity like SRCU around such the places.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 6512107bdafb..fb7e4fc16ea8 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -86,12 +86,6 @@ static void process_pcs_init_reply(struct fuse_conn *fc, struct fuse_req *req)
goto out;
}
- /*
- * It looks like all potential tasks, which can dereference
- * fc->kio.op, are waiting for fuse_set_initialized().
- */
- fc->kio.op = fc->kio.cached_op;
-
pfc = kvmalloc(sizeof(*pfc), GFP_KERNEL);
if (!pfc) {
fc->conn_error = 1;
@@ -100,16 +94,36 @@ static void process_pcs_init_reply(struct fuse_conn *fc, struct fuse_req *req)
if (pcs_cluster_init(pfc, pcs_wq, fc, &info->cluster_id, &info->node_id)) {
fc->conn_error = 1;
+ kvfree(pfc);
goto out;
}
- fc->kio.ctx = pfc;
+ fuse_ktrace_setup(fc);
+ fc->ktrace_level = LOG_TRACE;
+
printk("FUSE: kio_pcs: cl: " CLUSTER_ID_FMT ", clientid: " NODE_FMT "\n",
CLUSTER_ID_ARGS(info->cluster_id), NODE_ARGS(info->node_id));
- fuse_ktrace_setup(fc);
- fc->ktrace_level = LOG_TRACE;
+ spin_lock(&fc->lock);
+ if (fc->initialized) {
+ /* Parallel abort */
+ fc->conn_error = 1;
+ } else {
+ /*
+ * It looks like all potential tasks, which can dereference
+ * fc->kio.op, are waiting for fuse_set_initialized().
+ */
+ fc->kio.op = fc->kio.cached_op;
+ fc->kio.ctx = pfc;
+ pfc = NULL;
+ }
+ spin_unlock(&fc->lock);
+ if (pfc) {
+ fuse_ktrace_remove(fc);
+ pcs_cluster_fini(pfc);
+ kvfree(pfc);
+ }
out:
kfree(info);
/* We are called from process_init_reply before connection
More information about the Devel
mailing list