All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Liu Kui <kui.liu@virtuozzo.com>, devel@openvz.org
Cc: azaitsev@virtuozzo.com
Subject: Re: [Devel] [PATCH VZ10] fs/fuse kio: track pending kRPC connect via state machine only
Date: Fri, 28 Aug 2026 19:13:16 +0200	[thread overview]
Message-ID: <6480e7d4-d5d0-4133-bfa9-992cabb31d21@virtuozzo.com> (raw)
In-Reply-To: <20260827123712.84476-1-kui.liu@virtuozzo.com>

Liu, please explain what do i do with that patch?
Should i revert ("fs/fuse kio: fix kRPC connect issues") and push this patch instead?

Should we release it as an RK? If yes - for which kernels and where are the corresponding bugs?
Currently i understand nothing, sorry.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 8/27/26 14:37, Liu Kui wrote:
> Rework the previous fix ("fs/fuse kio: fix kRPC connect issues") to not
> require the new struct pcs_krpc member "connect_req", so the fix can be
> shipped as a livepatch.
> 
> Both things connect_req was tracking are already derivable from the
> existing state machine once PCS_KRPC_STATE_CONNECT is made to mean
> exactly "a connect req is in flight":
> 
>  - krpc_connect_done() settles a failed connect back to UNCONN instead
>    of leaving the state in CONNECT forever;
> 
>  - pcs_krpc_abort() no longer resets CONNECT to UNCONN: the req is
>    still in flight, and only its completion settles the state;
> 
>  - pcs_krpc_connect() proceeds only from UNCONN or ABORTED, refusing
>    new connects (-EPERM) while a req is in flight - at most one connect
>    req exists at a time, same as with the connect_req check;
> 
>  - pcs_krpc_poll() reports EPOLLERR on UNCONN: poll bails out earlier
>    unless ctx->gen == krpc->gen, and the current session can only be in
>    UNCONN if its connect failed or was aborted, which is what the
>    (CONNECT && !connect_req) test used to detect.
> 
> gen only advances in pcs_krpc_connect(), which is blocked during
> CONNECT, so within that state the in-flight req always carries the
> current gen and krpc_connect_done()'s existing staleness check is
> sufficient.
> 
> Related to:
> https://virtuozzo.atlassian.net/browse/VSTOR-135626
> 
> Signed-off-by: Liu Kui <kui.liu@virtuozzo.com>
> ---
>  fs/fuse/kio/pcs/pcs_krpc.c | 39 ++++++++++++++++++++++++++++----------
>  fs/fuse/kio/pcs/pcs_krpc.h |  2 --
>  2 files changed, 29 insertions(+), 12 deletions(-)
> 
> diff --git a/fs/fuse/kio/pcs/pcs_krpc.c b/fs/fuse/kio/pcs/pcs_krpc.c
> index b55c093c13d0..bcfbfc6d9304 100644
> --- a/fs/fuse/kio/pcs/pcs_krpc.c
> +++ b/fs/fuse/kio/pcs/pcs_krpc.c
> @@ -738,8 +738,12 @@ static int pcs_krpc_abort(struct pcs_krpc *krpc)
>  	spin_lock(&krpc->lock);
>  
>  	if (krpc->state != PCS_KRPC_STATE_CONNECTED) {
> -		if (krpc->state == PCS_KRPC_STATE_CONNECT)
> -			krpc->state = PCS_KRPC_STATE_UNCONN;
> +		/*
> +		 * A pending connect stays in CONNECT state: its connect req
> +		 * is still in flight and krpc_connect_done() will settle the
> +		 * state to UNCONN when it completes.  Until then new connects
> +		 * are refused, so at most one connect req exists at a time.
> +		 */
>  		spin_unlock(&krpc->lock);
>  		return 0;
>  	}
> @@ -907,8 +911,13 @@ static __poll_t pcs_krpc_poll(struct file *file, poll_table *wait)
>  
>  	spin_lock(&krpc->lock);
>  
> +	/*
> +	 * ctx->gen == krpc->gen (checked above) means this is the current
> +	 * session, so UNCONN here can only mean its connect attempt has
> +	 * failed (see krpc_connect_done()) or the session was aborted.
> +	 */
>  	if (krpc->state == PCS_KRPC_STATE_ABORTED ||
> -	    (krpc->state == PCS_KRPC_STATE_CONNECT && !krpc->connect_req)) {
> +	    krpc->state == PCS_KRPC_STATE_UNCONN) {
>  		pollflags |= EPOLLERR;
>  	} else if (krpc->state == PCS_KRPC_STATE_CONNECTED) {
>  		pollflags |= EPOLLOUT;
> @@ -999,7 +1008,6 @@ int pcs_krpc_create(struct pcs_krpc_set *krpcs, PCS_NODE_ID_T *id,
>  	krpc->gen = 0;
>  	krpc->state = PCS_KRPC_STATE_UNCONN;
>  	krpc->cs = NULL;
> -	krpc->connect_req = NULL;
>  
>  	krpc->rpc = pcs_rpc_clnt_create(&cc_from_krpcset(krpcs)->eng, id, addr, cs_flags);
>  	if (!krpc->rpc) {
> @@ -1051,8 +1059,6 @@ static void krpc_connect_done(struct pcs_msg *msg)
>  	}
>  
>  	spin_lock(&krpc->lock);
> -	if (krpc->connect_req == req)
> -		krpc->connect_req = NULL;
>  	/* from a stale session, do nothing  */
>  	if (req->gen != krpc->gen || krpc->state != PCS_KRPC_STATE_CONNECT) {
>  		spin_unlock(&krpc->lock);
> @@ -1062,6 +1068,14 @@ static void krpc_connect_done(struct pcs_msg *msg)
>  	if (!pcs_if_error(&msg->error)) {
>  		krpc->state = PCS_KRPC_STATE_CONNECTED;
>  		pollflags = EPOLLOUT;
> +	} else {
> +		/*
> +		 * Connect failed: settle back to UNCONN so that a new connect
> +		 * is allowed again, and report the failure to poll().  Since
> +		 * gen is unchanged, the current session's poll sees UNCONN
> +		 * and returns EPOLLERR.
> +		 */
> +		krpc->state = PCS_KRPC_STATE_UNCONN;
>  	}
>  	spin_unlock(&krpc->lock);
>  
> @@ -1119,9 +1133,15 @@ int pcs_krpc_connect(struct pcs_krpc_set *krpcs, PCS_NODE_ID_T *id)
>  	}
>  
>  	spin_lock(&krpc->lock);
> -	if (krpc->state == PCS_KRPC_STATE_CONNECTED ||
> -	    krpc->state == PCS_KRPC_STATE_DESTROYED ||
> -	    krpc->connect_req) {
> +	/*
> +	 * A connect is allowed only when there is neither an established
> +	 * session nor a connect req in flight (CONNECT state, see
> +	 * krpc_connect_done()).  This limits connect reqs to one at a time:
> +	 * if userspace gave up on a connect and retries, the new connect
> +	 * fails immediately until the old req completes.
> +	 */
> +	if (krpc->state != PCS_KRPC_STATE_UNCONN &&
> +	    krpc->state != PCS_KRPC_STATE_ABORTED) {
>  		spin_unlock(&krpc->lock);
>  		err = -EPERM;
>  		/* fput() drops ctx and its krpc reference via pcs_krpc_release() */
> @@ -1133,7 +1153,6 @@ int pcs_krpc_connect(struct pcs_krpc_set *krpcs, PCS_NODE_ID_T *id)
>  	connect_req->gen = krpc->gen;
>  	connect_req->krpc = pcs_krpc_get(krpc);
>  	krpc->state = PCS_KRPC_STATE_CONNECT;
> -	krpc->connect_req = connect_req;
>  	spin_unlock(&krpc->lock);
>  
>  	/* publish the fd only after the connect is committed */
> diff --git a/fs/fuse/kio/pcs/pcs_krpc.h b/fs/fuse/kio/pcs/pcs_krpc.h
> index 3db9e9712019..6a090ef66185 100644
> --- a/fs/fuse/kio/pcs/pcs_krpc.h
> +++ b/fs/fuse/kio/pcs/pcs_krpc.h
> @@ -82,8 +82,6 @@ struct pcs_krpc {
>  	/** Wait queue head for poll */
>  	wait_queue_head_t		poll_wait;
>  	struct pcs_cs			*cs;
> -
> -	struct krpc_connect_req *connect_req;
>  };
>  
>  struct pcs_krpc_context {

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-08-28 17:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 12:37 Liu Kui
2026-08-28 17:13 ` Konstantin Khorenko [this message]
2026-09-01 20:59 ` Konstantin Khorenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6480e7d4-d5d0-4133-bfa9-992cabb31d21@virtuozzo.com \
    --to=khorenko@virtuozzo.com \
    --cc=azaitsev@virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=kui.liu@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.