[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