From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (unknown [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id CB55080275 for ; Fri, 4 Sep 2026 01:59:17 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6841w35k026828; Fri, 4 Sep 2026 04:58:04 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6841w35k026828 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="VD1/R6Ep" Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6841w2C4026824 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Fri, 4 Sep 2026 04:58:02 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6841w2C4026824 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-4855e47d062so274559f8f.1 for ; Thu, 03 Sep 2026 18:58:02 -0700 (PDT) X-Gm-Message-State: AFuF++k3+bDp3N68X2EmVQj3e9vYrmG2jGKP3NwOj/PpGqx/ZUUWhe91 8b1xMTOzwY9BBR1wZkW7nKqki5rtbGKt4AW++ojanvFKybQaltFp8tGhBT+0nLeoKtBnqf5UFSr jcVYVeEnsKlmeEhDKF6zWN/hq3D8gmpunbx7vS0julHvSxPxeVgCrKg== X-Gm-Gg: AYBFou3/XAPB90wez777ODVsU1eyk15FnIQXvlAL2BLUG7BQaxAPhqoqAjFEFen0K6a afrWzsPGVE+dSDPzxgIJySzPkGRP/T8QZkukFAc/u83vFQ3fGC+mh65VKcNECh42H1qppt/nRGB MBBC4ttskGC+BqpdLy7x43JYNiWCLbDteG2WvIP3nm1mvFVmMpr9T/CRX/nq9CBGCgH9CBanHM0 9tSoU2bWAwX/QqfRdj/aRE+oanW8yQVFHXHz7Hool1c0Pn4UzuTrauPzhAJIzmyHKvtF7aLtRGq ZjOJguBlu+9hi/AslxDZZXxT38Ojh1fkvBAlDbUa4V7S0f+3HwqICGe9PTQReiF2tm8BHLPQW0C T/ygFJt7l0C0QApo= X-Received: by 2002:a5d:5c82:0:b0:485:8a46:b3b5 with SMTP id ffacd0b85a97d-4858a46b479mr920857f8f.29.1788487082530; Thu, 03 Sep 2026 18:58:02 -0700 (PDT) X-Received: by 2002:a5d:5c82:0:b0:485:8a46:b3b5 with SMTP id ffacd0b85a97d-4858a46b479mr920830f8f.29.1788487082004; Thu, 03 Sep 2026 18:58:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1788487081; cv=none; d=google.com; s=arc-20260327; b=pZUrC+vVdqJGCYihtqV3J2MHqNSzStcxrrI89Kr0Y0KHNVkC/LYMlUOvtSmg2r3ZHN Y+JxeQYpRe4bRWxDqFRZ0tq5W7nZlLdnX+E58lNGJf0O358yWH9eSOLlv4r2omkz/2OG 4nIrVXWJnsEviO0FWf8mOY/kJWrq3i0mOs4PH4+AgFLMg4PiYb4QC/eWOrZ+Y2Toemqe 52CJFO0olSZC2rc8Uf9prYJ1UaL9t3LlH++Ja9pMNAT1oUlcV7Ntomcqx/Hc0gy7ta6/ DLCloY/cIXjUMLAJEaNQVa+/ijFTKMgwk7r5vwGxGoIMbMsYqx37pdlqsBCa3b9hwB35 kFUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=5zB2Tad1DHMwjWV0poUVeyTwSik6NUHSmW25b7G8czc=; fh=CyEa5k0km+zUBGOSzDGfbole2hTjTZicm1CHqnc8J2I=; b=kcAz0zAIJUceU0XRrjEe9B3e/2mPWlmCaUdsLFU9fSX4XtiWIzWObclOvl6jKOgNGl ai+H+k8j+eJjCXJcizmz/iUKWO9Bwft3m6xRJVBCjqExU3DlM6C/nqSAMblJp1i+kOm0 V8kCwYco6cxlJiaSoZPwKNJTcUgJmgS0sXVOoasB0f2wjSHEJ3LPys5LPcoR8e8snDg+ ZfKkh/43etNyQiiEpN8ZTs0j53juaeVVj8ffV+y9LP9RCDAWr8XWRqK8H+jJMkA1yBYE LUBtT4QH21M+L/AeCusPP8xGTPrXSII65VcYuGHTTi/x6WxCcQrxCupPupl/SvDUrkui bjPQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b="VD1/R6Ep"; spf=pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=kui.liu@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-485885e6217si2037775f8f.436.2026.09.03.18.58.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 18:58:01 -0700 (PDT) Received-SPF: pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b="VD1/R6Ep"; spf=pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=kui.liu@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=5zB2Tad1DHMwjWV0poUVeyTwSik6NUHSmW25b7G8czc=; b=VD1/R6Ep31yN DaFSqN46pVTBj0EwB3GSBRAD656Hgui9f9hUH4Le5+1h9iG0NfjbQfAJHuh2Q3jyE19/T91KBitEl g3/xOd7kSkcown4SK6Ab8GbunHbg0MStQrzs2gCR5fn+L0/qCDaOeUQnh7vgTkPmFiFu9x/aAv8jy cO/Q+dLsmFHXVyFsnI3w3m4skA8Mcz488EcMehdET5ewTl+TZHQYRIx33gMXVhkDSw6zsUYpS0KpU ZOQuzPrg2VCNBEWNdHUxZJ51J6F+rZoRL1yQilt/1KqARRpJ/ngTZyz8iCstRbAMnGurb5WDZRoex bARHn3aka+hB8ILFf19kWg==; Received: from ch-vpn.virtuozzo.com ([130.117.225.6] helo=localhost.localdomain) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1x2J9N-008rr4-1e; Fri, 04 Sep 2026 03:57:58 +0200 From: Liu Kui To: devel@openvz.org Date: Fri, 4 Sep 2026 09:57:55 +0800 Message-ID: <20260904015755.23985-1-kui.liu@virtuozzo.com> X-Mailer: git-send-email 2.50.1 MIME-Version: 1.0 X-OZ-Fwd: true Cc: azaitsev@virtuozzo.com, Liu Kui Subject: [Devel] [PATCH VZ10 v2] fs/fuse kio: track pending kRPC connect via state machine, not a pointer X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org 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: struct pcs_krpc objects are long-lived, and a patched kernel would dereference the new member on objects allocated before the livepatch was loaded, reading unallocated slab space. 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. It advances gen instead, disowning the pending req: when the req completes, krpc_connect_done() settles the state to UNCONN without committing the dead session, even if the late connect succeeded; - 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, which is what the (CONNECT && !connect_req) test used to detect. Within CONNECT the pending req carries the current gen unless the session was aborted, so a gen mismatch in krpc_connect_done() reliably identifies a disowned req. https://virtuozzo.atlassian.net/browse/VSTOR-135626 Signed-off-by: Liu Kui --- fs/fuse/kio/pcs/pcs_krpc.c | 63 ++++++++++++++++++++++++++++---------- fs/fuse/kio/pcs/pcs_krpc.h | 2 -- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_krpc.c b/fs/fuse/kio/pcs/pcs_krpc.c index 0930fb4adf12..9d534b037cd1 100644 --- a/fs/fuse/kio/pcs/pcs_krpc.c +++ b/fs/fuse/kio/pcs/pcs_krpc.c @@ -787,8 +787,15 @@ static int pcs_krpc_abort(struct pcs_krpc *krpc) spin_lock(&krpc->lock); if (krpc->state != PCS_KRPC_STATE_CONNECTED) { + /* + * A pending connect req stays in flight and the state stays + * CONNECT, refusing new connects until the req completes. + * Advancing gen disowns the req, so that a late completion + * settles the state to UNCONN in krpc_connect_done() instead + * of committing this dead session on success. + */ if (krpc->state == PCS_KRPC_STATE_CONNECT) - krpc->state = PCS_KRPC_STATE_UNCONN; + krpc->gen++; spin_unlock(&krpc->lock); return 0; } @@ -949,15 +956,15 @@ static __poll_t pcs_krpc_poll(struct file *file, poll_table *wait) poll_wait(file, &krpc->poll_wait, wait); - if (unlikely(ctx->gen != krpc->gen)) { - pollflags |= EPOLLERR; - return pollflags; - } - spin_lock(&krpc->lock); - if (krpc->state == PCS_KRPC_STATE_ABORTED || - (krpc->state == PCS_KRPC_STATE_CONNECT && !krpc->connect_req)) { + /* + * when ctx->gen == krpc->gen, UNCONN here can only mean its + * connect attempt has failed (see krpc_connect_done()). + */ + if (ctx->gen != krpc->gen || + krpc->state == PCS_KRPC_STATE_ABORTED || + krpc->state == PCS_KRPC_STATE_UNCONN) { pollflags |= EPOLLERR; } else if (krpc->state == PCS_KRPC_STATE_CONNECTED) { pollflags |= EPOLLOUT; @@ -1047,7 +1054,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) { @@ -1099,10 +1105,20 @@ 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) { + /* the session was aborted or destroyed, nothing to settle */ + if (krpc->state != PCS_KRPC_STATE_CONNECT) { + spin_unlock(&krpc->lock); + goto out; + } + + if (req->gen != krpc->gen) { + /* + * The session that started this connect was aborted while the + * req was in flight (pcs_krpc_abort() advanced gen): settle + * the state so a new connect is allowed, but never commit the + * dead session, even on success. + */ + krpc->state = PCS_KRPC_STATE_UNCONN; spin_unlock(&krpc->lock); goto out; } @@ -1110,6 +1126,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); @@ -1167,9 +1191,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() */ @@ -1181,7 +1211,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 803376895cc5..96b4815abf86 100644 --- a/fs/fuse/kio/pcs/pcs_krpc.h +++ b/fs/fuse/kio/pcs/pcs_krpc.h @@ -84,8 +84,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 { -- 2.50.1 (Apple Git-155) _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel