From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 389754C81 for ; Sun, 26 Jul 2026 01:59:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785031198; cv=none; b=gq+Yz3U/DN6Yos1cQeuuft3raVco0HFJFApJ8r1zJiXqzLybIpZL2ofqYFug1F/CPO6LTTZfiqH/soHAWArSrewXWJP8DHZmL7JdNOJx0ubIZQvlsLHOO737aaScoltVJ3BRhrrD28E6sB4AGZ3PjEQ30sFMbiPHMB1Y4apFM+Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785031198; c=relaxed/simple; bh=B4IYYuGph/em9rYUeyTrjgFnY/FPWkD9+tX1J0lcrvk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hnr/rCR4HeKwH/U+HIPirCaAKFju3QxQ//6/e7/9J8XoWcmS+920J7dwF2uzurxmpqxl47jSiU8csiNkm0EGDedYTRCpEFqXLuw2T/OgLrgGVWtik+96nzchRrYUgC4INU1eWvVhrm0mJdSMtwGLv1v7ORUD9Zouw/eJGRw1Hl8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IBlkG3SL; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IBlkG3SL" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-7ee37dc91f5so890417a34.3 for ; Sat, 25 Jul 2026 18:59:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785031196; x=1785635996; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Dp1m+he2iASF586QKTRoFR35aZ7KbKPACpgwKYAXwl8=; b=IBlkG3SLhcxdbNKay4J36gniVsEKrjjMJ+KVis26n1LtuFQ1PhoGJcqMV+GsjCPALH qgVB68v4RsJiKUbCQVyVNlviYIgjT3hYAT8whXTQZY/rIZvlKDyz1XKPYp/0NGT2Say/ ILQL54GqDgWlPrzpB4eNt/ozLt/3t3CwAblQ04SEiu1ris0r9yEA+taMsaCwFxvK2VPO F2AJ6yac58XbG/LL8stlASsDsd5q3gUOmtVyigDT74gOBrII0YxcQVH2RrDjlZNO5h08 T/1jaxqhxSsyyUgKfVgdq2Tab9bP7Ja+E0d17iieJrJ3/LvqXGFKrEHhj3ohixjWr2z3 Dqeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785031196; x=1785635996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Dp1m+he2iASF586QKTRoFR35aZ7KbKPACpgwKYAXwl8=; b=moRPGBEMDGo/IXek7W0NNPGtkVRCIRArwOlR3SLydrOphb6h+5jE7piyo0IXQhRxAF WjfjxaNfaJgzVDRU4PfreiMVVw3H2ECpDTLjbVpMtKOejGpzNCmeRaRnPtpPlri2FpoE KJPxks9a7DWYtb8Efu3RKe9BWWqNpE5mReBifNCWylBLjS9yJoDd/R3CbkgUv9DzINrk vs5aRUcSFd95f5RtIlwoS2A+uV+m5hNWYHiGzuq7YjFgE8b4/N1PFgRV9RwYq4IT/b1g g85OFGaVv0lZjGMIRVjQXGXVDjxN8TigRHkHC7Ou5g5S0yCiJ0rkYCeTb3dg4BOuITAG hQQg== X-Forwarded-Encrypted: i=1; AHgh+RpOm4ibh1lu7jFZ1bS0KV/HrbPEC3eJHDekv6Gwga7LBALlV3twseixhYbUJEN9Iqt2/xbCHSz89t9qkhs=@vger.kernel.org X-Gm-Message-State: AOJu0YyT+pJ4No7TIcVKkbW+/6fesaX09JHgC7kXSFJwMv5ogFI16gHL SCv3QJuCJ0Ngse10f69t/vDWnQCi+maS1ngJngelk33ZvTmZ1c5UCm2Z X-Gm-Gg: AR+sD13DULJWPOLQkYrV3+TnhdL5ypokovnkKB1EIYAZqEg5+fuiVW5JVJ+112zJF4s SePnBgNUoT0+Lh0KC1+QOPpAlia4Jk4DGdxephqJt6gkR15cMveob1M8r9ylphDJWdl6QK/Ocbd IsYYe2JmjWxUFZVEXWFlmAY5hbNCk1XVamv7UyfHWd9hhb1vrh5TM6TsVAfpmlbywCgt4BU+Tju Y8PmGu+UhRa/hwAHoXTULXZ3aa8tTFHDY/UO/PJXP4y9CwVCH0DQVxePdu/QWLI1Z4U8zvFAr3K yXYJt2p0C0w1gzfI00KWmD1xoPeoyKu91y9KoGgx5VHqI1iGnDjG1KBvKydhwZRUI2tdPsMhjRg hrmAPj4dh7XseI2TOi5WWNLvTSEqrCT7TFWu3N1XXDMIwRJHzjv+4nI2doZH57tWbV1EmRZl43D ZodzlhuWydFtTrns9cnP5n+uKCAshCJ3fDclR5DVrj9pBrzg5cKzc4aIdJ/HT8UHrorww/VmMIg qhM7mJ35O1KubTCCLcGfoA57nfUfoj86Q== X-Received: by 2002:a05:6830:2405:b0:7e9:b4d0:53af with SMTP id 46e09a7af769-7ee78e4e3fdmr3203784a34.32.1785031196089; Sat, 25 Jul 2026 18:59:56 -0700 (PDT) Received: from rdf-gcp2.us-central1-b.c.storage-xlrait-66065.internal (163.80.112.136.bc.googleusercontent.com. [136.112.80.163]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7ee29e0ec5bsm9335656a34.10.2026.07.25.18.59.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 25 Jul 2026 18:59:55 -0700 (PDT) From: Russ Fellows To: miklos@szeredi.hu Cc: amir73il@gmail.com, fuse-devel@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Russ Fellows Subject: [PATCH v4 0/2] fuse: allow parallel direct writes for passthrough Date: Sun, 26 Jul 2026 01:59:53 +0000 Message-ID: <20260726015955.319132-1-russ.fellows@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260616231325.16788-1-russ.fellows@gmail.com> References: <20260616231325.16788-1-russ.fellows@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit This is v4, about six weeks after v3 [1] -- apologies for the delay. Thanks to Amir Goldstein for the detailed review of v3 and for the suggested patches; this revision implements that feedback. The v3 thread [1] has the full context and Amir's comments. The series is also available at: https://github.com/russfellows/linux-fuse-passthrough-patches FUSE passthrough writes are fully serialised on the inode lock, even when the server advertises FOPEN_PARALLEL_DIRECT_WRITES and the write is a direct, non-append, within-EOF overwrite. Native FUSE direct-IO writes already take a shared lock in that case; there is no reason passthrough cannot do the same. With a passthrough backing file on XFS, this is the difference between serialised and fully parallel 4K random-write O_DIRECT throughput. Patch 1 stops fuse_file_io_open() from stripping FOPEN_PARALLEL_DIRECT_WRITES on passthrough opens (which bypass the page cache without FOPEN_DIRECT_IO). Patch 2 lets fuse_passthrough_write_iter() take the shared lock for eligible writes by sharing the existing direct-IO write-lock helper rather than duplicating it. Rebased onto v6.18.39 (LTS). Changes since v3: - Patch 1: keep only the FOPEN_IOMODE_CACHED() helper (drop the IS_DIRECT / IS_PASSTHROUGH macros, which described how I/O is performed rather than the ff->iomode state and were misleading); fold the O_DIRECT/fcntl note into the FOPEN_PARALLEL_DIRECT_WRITES comment; and simplify fuse_file_io_open() so a pure direct-IO open needs no early return. (Per Amir's review and suggested diff.) - Patch 2: instead of duplicating fuse_dio_lock() into passthrough.c, generalise it: fuse_io_wr_exclusive_lock() now also handles passthrough, the uncached-io refcount is factored into fuse_parallel_dio_start/end() (no-ops for passthrough's permanent uncached iomode), and fuse_dio_lock()/fuse_dio_unlock() are renamed fuse_io_wr_lock()/ fuse_io_wr_unlock() and shared by both write paths. (Per Amir's review and suggested diff.) Testing (fstests / xfstests) ---------------------------- Run with the libfuse passthrough_hp server under xfstests (FSTYP=fuse), './check -fuse -g quick' (642 tests), on v6.18.39, backing XFS on a RAM-backed null_blk device. An unpatched v6.18.39 baseline was captured first, then the same tree with this series applied; results were diffed to isolate any patch-induced change. Two server configs were exercised, as suggested by Amir: passthrough (default): unpatched 25 failed / patched 25 failed passthrough --direct-io: unpatched 27 failed / patched 27 failed In both configs the failing set is identical with and without the series (the --direct-io set is the default set plus generic/355 and generic/362). Every failure is pre-existing on the unpatched kernel and is a known passthrough_hp / fuse limitation (permission/ACL/atime/mmap-coherency tests), unrelated to this change: => zero regressions introduced by the series in either config. No kernel warnings, lockdep reports, or splats were observed in any run. Performance ----------- Custom FUSE passthrough daemon advertising FOPEN_PASSTHROUGH | FOPEN_PARALLEL_DIRECT_WRITES, XFS on a RAM-backed null_blk device, kernel v6.18.39. fio 4K random write, O_DIRECT, libaio, iodepth=64, single shared file: numjobs | unpatched (IOPS) | patched (IOPS) --------|------------------|--------------- 1 | 352,000 | 352,000 2 | 440,000 | 648,000 3 | 429,000 | 951,000 4 | 423,000 | 987,000 Unpatched write throughput is flat regardless of job count (the exclusive inode lock serialises all writers to the file); with the series it scales with concurrency, ~2.3x at 4 jobs, up to the backing device ceiling. Single-job is unchanged (no lock contention), and 4K random *read* throughput is unchanged (~1.37M IOPS with and without the series), since reads never took the exclusive lock. [1] v3: https://lore.kernel.org/all/20260616231325.16788-1-russ.fellows@gmail.com/ Russ Fellows (2): fuse: preserve FOPEN_PARALLEL_DIRECT_WRITES for passthrough opens fuse: allow parallel direct writes in passthrough write_iter fs/fuse/file.c | 53 ++++++++++++++++++++++++++++++++++--------- fs/fuse/fuse_i.h | 2 ++ fs/fuse/iomode.c | 23 ++++++++++--------- fs/fuse/passthrough.c | 6 ++--- 4 files changed, 59 insertions(+), 25 deletions(-) -- 2.51.0