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 A2F258017D for ; Wed, 23 Sep 2026 16:15:01 +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 68NGDdlC003401; Wed, 23 Sep 2026 19:13:40 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68NGDdlC003401 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="I5gFlSYy" Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 68NGDbTw003397 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Wed, 23 Sep 2026 19:13:37 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68NGDbTw003397 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-486f768517dso865791f8f.1 for ; Wed, 23 Sep 2026 09:13:37 -0700 (PDT) X-Forwarded-Encrypted: i=2; AKwUvBzGwLIbqawzfXJT19tUUO9xpZYyDjCenaWR8PJwJuzAV+OnpUxtDsdTn1lAxA5ENoDVwfWmHA==@openvz.org X-Gm-Message-State: AFuF++kYPyQCLNZ8ApCSwuz4uYvtp3zgf5scf9aj4Mo7/htli4/KtfmD FpizzC2R7KMl6HoUODJMCF4swPN2aI5j2bKbBHv73DTrmik2RHCe7ICzRZw4KkS0d9wQqKv+jkW hpcMms7iIHctWkoAe0VXR2lvgGRaF2D2BS4j2l63nLzw1TuUvvfGDHg== X-Gm-Gg: AYBFou2cAlwmFspfxSk7gYNGpz/Fm39ZuQCUubM+paDtt5UXhcAkK0arZD9I7adJokr lhb1XExA05n4+Tqj/rsE1hXy3dcezu9p9utQbhUH3XScZTH458xi+VlEP4HOO8yP1Ex0l4ciPuC skA/9DZtvV1qEL6l/t8vv8N8NwbGqfjwzY/yytyTOMP1DlPdxlNbL9F/+1hsJxhjZzlt0GQLh5q yc6qvfjwMqD+8qa0msna/esZhpgrzSVrUMaprC5N92eoWYKALtaHTC6a8eCS4QkufPg1yUd2L8B l7po6R0leOoO+Qh3eOFmaGV3rXR+R/My5r702+dPiTp5yvpQ+slOMoJBuT9suNKhNHB6ej1u4Z+ oYGp64GNokUQzh02gJA== X-Received: by 2002:a05:6000:4b04:b0:487:27f9:838 with SMTP id ffacd0b85a97d-488670984bemr5850545f8f.45.1790180017060; Wed, 23 Sep 2026 09:13:37 -0700 (PDT) X-Received: by 2002:a05:6000:4b04:b0:487:27f9:838 with SMTP id ffacd0b85a97d-488670984bemr5850475f8f.45.1790180016468; Wed, 23 Sep 2026 09:13:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1790180016; cv=none; d=google.com; s=arc-20260327; b=YYeTIZ/jRAqQRwusrFRE8+TVOGh1sqCoHa9s5wJBzKrUyujIw1jXF71tFWxuLtYAav 1gsSI3doW5Lv6tY+bWiA/FPawPmdDI5hNaO4682pw87MjF6Uuu5dzcIkr+lRd7h659mG CQdE/Y6IeXG5/Gsr2FOgq6y/uUVu4n73a+lFMcjR/td9r4ynWQoWW5x1vxrU48gFiohm QxOpXN61mYDCoKBUrMZmtvAIPPkTqlXX3V1e4gALIArua4hVjajzm8IIPvf07i6FXmH3 4CqSbmfJ6o2w09mccDPG/2v8beFnDeTpYSqwE/9hU1ZgBpUiyAd7LcjEb8uuhxBLGSJb Yz6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=TTVO9w2DyKfJiKw1Dt6WIqk/6ENPFhpruQeByBZ2PEo=; fh=ZqzvOmtFyV7+63sP5bFEILTUBNC5RiAwOez9eHiry1U=; b=LELJGWDskUD8UjwgEwHnOpzytk3JT56xL7XPY+kvk1hxJ3Uqil6zIiOgSMAP9hIT1B GKK3y5otuHa6ZcJ/bekErpye8eSu8cg9waQW8S8aY18S1CtqVqIFLAXU59N3prSddRdc jzOsDAeFGtRWklo7Tn35WOMhBke75SdXMSNsrUUO5xnEWzy/6WJ3VkaGftLiHprKqd6j 93jRKUPVTWmb6aj0D7rinSYfJ/zg5tCn9RLezne3AUIFcQjFCE/ZV3a0gkONudlqoXXe v6NzGJlFntf67lZYGwirijcTY9O1tMv2sXfpxa4c0MiSoO+wzhz00anGODAr8fLrND4U bbtg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=I5gFlSYy; spf=pass (google.com: domain of khorenko@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=khorenko@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-488688e9af3si4819156f8f.446.2026.09.23.09.13.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Sep 2026 09:13:36 -0700 (PDT) Received-SPF: pass (google.com: domain of khorenko@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=I5gFlSYy; spf=pass (google.com: domain of khorenko@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=khorenko@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=TTVO9w2DyKfJiKw1Dt6WIqk/6ENPFhpruQeByBZ2PEo=; b=I5gFlSYyUHbQ 6X0K/knHnSrgLgAG6xahCwEtiKepyZ8WM2Nnlp+qtPhCumFxnF1FeEWHGlYjRpAPDuhyoLYTuQb0P N3MnSunNEDFXgNYhFRT66TSF+PhbthEyF8sdHF0mdmaWUi71f2sK3K8o6zX5Vs1xc+KPtuw6fXfcp 2zlZb3q1mCW4fcqe8p8wEAoLysm/Al9/PfRu0BqxOL0hccVsSzE2w6u7Ou+PDQWg7TKIC0FJCqP0W Eb2tEKxDqiF7sUZqHW+Ee/egKZjl7DjjwePonBJjRP4dwTMNq1Bz3UaiWEo34pJZNwKs483IUDIkL SNIwPhJGReeDoDR6QZQCCA==; Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=f0.vzint.dev) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1x9PYI-007alx-2N; Wed, 23 Sep 2026 18:13:35 +0200 From: Konstantin Khorenko To: Alexey Kuznetsov , OpenVZ devel list Date: Wed, 23 Sep 2026 18:13:35 +0200 Message-ID: <20260923161335.3110033-1-khorenko@virtuozzo.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-OZ-Fwd: true Cc: Liu Kui Subject: [Devel] [PATCH hci-8.1 v2] fs/fuse: strictly segregate vstorage features of generic fuse 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 From: Alexey Kuznetsov 1. Makes explicit use of option "close_wait" as specific to vstorage. The option requires some time to be fully engaged, the support should appear in kernel first then we use it in userspace, then we can get rid of original ugly way relying on special string name [pv]storage:// 2. Option "close_wait" is privileged. It cannot be used inside containers and ordinary users of fusermount are not allowed. 3. Our enhancements like multiple queues, zero-copy transfers, lease invalidate FUSE_NOTIFY_INVAL_FILES etc. are explicitly prohibited w/o close_wait. 4. When close_wait is enabled, we explicitly disallow to use creepy bug prone fuse features like fuse interrupts, resends, we reject all obscure notifications except for supported ones, which is now only FUSE_NOTIFY_INVAL_FILES and value 4, which will be dropped after old user space is washed out https://virtuozzo.atlassian.net/browse/VSTOR-144529 Feature: vStorage Signed-off-by: Alexey Kuznetsov Reviewed-by: Konstantin Khorenko --- v1 -> v2: - is_close_wait_allowed() returns bool instead of int (khorenko@) fs/fuse/dev.c | 32 ++++++++++++++++++-------- fs/fuse/fuse_i.h | 5 ----- fs/fuse/inode.c | 58 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 26 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index a9de0f815774a..6a22fa73330b7 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -2019,6 +2019,8 @@ static int fuse_notify_inval_files(struct fuse_dev *fud, unsigned int size, struct fuse_notify_inval_files_out outarg; int err = -EINVAL; + if (!fc->close_wait) + goto err; if (size != sizeof(outarg)) goto err; @@ -2048,8 +2050,19 @@ static int fuse_notify(struct fuse_dev *fud, enum fuse_notify_code code, cs->move_pages = 0; /* ASSUMPTION: pstorage fused doesn't use FUSE_NOTIFY_STORE */ - if (fc->compat_inval_files && code == 4) - code = FUSE_NOTIFY_INVAL_FILES; + if (fc->close_wait) { + if (code == 4) + code = FUSE_NOTIFY_INVAL_FILES; + if (code != FUSE_NOTIFY_INVAL_FILES) { + fuse_copy_finish(cs); + return -EINVAL; + } + } else { + if (code == FUSE_NOTIFY_INVAL_FILES) { + fuse_copy_finish(cs); + return -EINVAL; + } + } switch (code) { case FUSE_NOTIFY_POLL: @@ -2412,10 +2425,11 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, } err = -EINVAL; - if (oh.error != FUSE_OUT_SPLICES && - oh.error != FUSE_OUT_KRPCZC && - (oh.error <= -512 || oh.error > 0)) - goto copy_finish; + if (oh.error <= -512 || oh.error > 0) { + if (!fc->close_wait || + (oh.error != FUSE_OUT_SPLICES && oh.error != FUSE_OUT_KRPCZC)) + goto copy_finish; + } spin_lock(&fpq->lock); req = NULL; @@ -2438,7 +2452,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, err = -EINVAL; else if (oh.error == -ENOSYS) fc->no_interrupt = 1; - else if (oh.error == -EAGAIN) + else if (oh.error == -EAGAIN && !fc->no_interrupt) err = queue_interrupt(req->args->fiq, req); fuse_put_request(req); @@ -2455,10 +2469,10 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, if (!req->args->page_replace) cs->move_pages = 0; - if (oh.error == FUSE_OUT_SPLICES) { + if (oh.error == FUSE_OUT_SPLICES && fc->close_wait) { req->out.h.error = 0; err = copy_out_splices(cs, req->args, nbytes); - } else if (oh.error == FUSE_OUT_KRPCZC) { + } else if (oh.error == FUSE_OUT_KRPCZC && fc->close_wait) { req->out.h.error = 0; err = copy_out_krpczc(cs, req->args, nbytes); } else if (oh.error) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 8d90f43f01c92..21f8733376270 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -669,8 +669,6 @@ struct fuse_fs_context { bool umount_wait:1; bool close_wait:1; bool disable_close_wait:1; - bool compat_inval_files:1; - bool no_fiemap:1; bool kdirect_io:1; bool destroy:1; bool no_control:1; @@ -1056,9 +1054,6 @@ struct fuse_conn { /** Does the disable synchronous close? */ unsigned disable_close_wait:1; - /** Handle wrong FUSE_NOTIFY_INVAL_FILES from old fused */ - unsigned compat_inval_files:1; - /** No ioctl(FIEMAP) */ unsigned no_fiemap:1; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ea158367a1efd..eb2e9a4f87564 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -912,6 +912,7 @@ enum { OPT_ODIRECT, OPT_UMOUNT_WAIT, OPT_DISABLE_CLOSE_WAIT, + OPT_CLOSE_WAIT, OPT_ERR, OPT_KIO_NAME }; @@ -930,11 +931,18 @@ static const struct fs_parameter_spec fuse_fs_parameters[] = { fsparam_flag ("direct_enable", OPT_ODIRECT), fsparam_flag ("umount_wait", OPT_UMOUNT_WAIT), fsparam_flag ("disable_close_wait", OPT_DISABLE_CLOSE_WAIT), + fsparam_flag ("close_wait", OPT_CLOSE_WAIT), fsparam_string ("kdirect", OPT_KIO_NAME), fsparam_string ("subtype", OPT_SUBTYPE), {} }; +static bool is_close_wait_allowed(void) +{ + return ve_is_super(get_exec_env()) && capable(CAP_SYS_ADMIN) && + uid_eq(current_uid(), GLOBAL_ROOT_UID); +} + static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) { struct fs_parse_result result; @@ -966,19 +974,22 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) param->string = NULL; /* Hack to distinguish pcs fuse service and to force - * synchronous close for it. - * - * libfuse is not ready for fiemap autodetection, so disable - * fiemap support check in advance for all FUSE fs except for - * pStorage. + * synchronous close for it. It is on way out, we are going + * to switch to mount option "close_wait", but this requires + * full cycle: support mount option in kernel, switch + * user space, wait till old user space is gone. */ if (fsc->source && (strncmp(fsc->source, "pstorage://", 11) == 0 || strncmp(fsc->source, "vstorage://", 11) == 0)) { - ctx->close_wait = 1; - ctx->compat_inval_files = 1; - } else - ctx->no_fiemap = 1; + if (is_close_wait_allowed()) + ctx->close_wait = 1; + /* If not allowed, just ignore. We can use vstorage mount + * in restricted environment, but with disabled + * features like multiple queues, precise metadata + * tracking and kernel acceleration. + */ + } break; @@ -1066,6 +1077,13 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) ctx->close_wait = 0; break; + case OPT_CLOSE_WAIT: + if (is_close_wait_allowed()) + ctx->close_wait = 1; + else + return -EPERM; + break; + case OPT_KIO_NAME: { if (!ve_is_super(get_exec_env())) return -EPERM; @@ -1118,6 +1136,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",umount_wait"); if (fc->disable_close_wait) seq_puts(m, ",disable_close_wait"); + if (fc->close_wait) + seq_puts(m, ",close_wait"); if (fc->max_read != ~0) seq_printf(m, ",max_read=%u", fc->max_read); if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE) @@ -1241,6 +1261,9 @@ int fuse_install_iq_route(struct fuse_dev *fud, struct fuse_iq_routing *req) &fud->fc->rrt; struct fuse_rtable rtl; + if (!fud->fc->close_wait) + return -EINVAL; + if (rt->type != FUSE_ROUTING_NONE && rt->type != req->type) return -EINVAL; @@ -2182,17 +2205,28 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) fc->umount_wait = ctx->umount_wait; fc->close_wait = ctx->close_wait; fc->disable_close_wait = ctx->disable_close_wait; - fc->compat_inval_files = ctx->compat_inval_files; - fc->no_fiemap = ctx->no_fiemap; + fc->no_fiemap = 0; fc->writeback_cache = ctx->writeback_cache; fc->destroy = ctx->destroy || ctx->umount_wait; fc->no_control = ctx->no_control; fc->no_force_umount = ctx->no_force_umount; fc->kdirect_io = ctx->kdirect_io; + if (fc->close_wait) { + fc->no_interrupt = 1; + } else { + /* libfuse is not ready for fiemap autodetection, so disable + * fiemap support check in advance for all FUSE fs except for + * pStorage. + * NOTE as of 260912. This might be not true now, yet this + * still makes sense. + */ + fc->no_fiemap = 1; + } + if (fc->kdirect_io) { err = -EINVAL; - if (!fc->writeback_cache) + if (!fc->writeback_cache || !fc->close_wait) goto err_dev_free; fc->kio.cached_op = fuse_kio_get(fc, ctx->kio_name); -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel