From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f44.google.com (mail-oa1-f44.google.com [209.85.160.44]) (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 D47A137C0F8 for ; Tue, 16 Jun 2026 01:44:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.44 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781574270; cv=none; b=BHtDmkzH9uIfuQR1AcXMuS48ZIeVHY+aSz5ws0SPSTNRaUD7a9qZ2J0x5XRzh6XoyJka/khfrKmxt58rkOkJjD7sYIiWyxPhcPvQ5EyeBA+U+gkmqOsO5yuMdvW2pkiUCXfltJJmFgk4mo7QQHNalcj7hTvoOBB7vj5a+nIk1ag= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781574270; c=relaxed/simple; bh=9rYPaGYsOYUIgGN1Dln2YFc3H/t6q4g3GdGVslp0cVY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L7NKhiJYOqdylQKfOuScg+NBA8uBGpBcP1B/rfkteREdXj8ndgmdEKRbfzLOMYY/B87IzeLFKWxaG0u5YZafvao10jknlayy2SNaagIZOP/8nw8kl4yKJgboMyr7i7Xxi9PRoznM141puYK3xRDHf0wb7PzxzqFI25tn2j8/o4E= 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=GgQV9ayV; arc=none smtp.client-ip=209.85.160.44 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="GgQV9ayV" Received: by mail-oa1-f44.google.com with SMTP id 586e51a60fabf-43ccf0ba2e5so1631970fac.3 for ; Mon, 15 Jun 2026 18:44:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781574268; x=1782179068; 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; bh=106sFJEsXiYesLx4tGkbN/uNTqLMyOGAl2xASJCN0Xk=; b=GgQV9ayVYgF6oVVi2yPYs3/Ntp07rHfU2SeM0bxOnWamOtZqDV2rTcsUDxdp0AA+ti mLlWbew5KeRfwmjABYClxuVJL2nS4UW/5Ja8yIpSFK/zxGrhgcOCmoobpus3ziQHLZ5h mXobuRa57Qhds5MlcOx/rup1cWTCz6D5Kg8G2X2JigwwmosdYhlgV+wNWzq9/+jg6K0v AlO3Xmg4vvzcv0Yi+vsuiYUZGokNJdJjXsjLD8T9YNRgWa3jsTt0FH2jGWmcpKiJuDZ+ 1zDQ+LukgcLGjSvYFJsgtXn54Lc7bsUWoLoCXmNKbuGtNG8BFtw+hLlZEvvpnW2fPzET Dwpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781574268; x=1782179068; 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; bh=106sFJEsXiYesLx4tGkbN/uNTqLMyOGAl2xASJCN0Xk=; b=TA6NiJITZXnp4X9U2Eotex4iQX2ZPZe7CoRakNMOMXJk9j9qHsn1aIh9O4zSM/Jn24 KJYsMHk7IQsxHSjs1kFOMewrxR9HvLgTiiA6q/RIn60aV9O9BfKfyPNWnZ6YO8RVaGE/ BZ/nZh6jrRWPLkXoa1r7lsSGXrpiPAuHIg1UrniZ6jsOPfzm1yi9Y2jrm41HEz/gEsma /oJa5BPmnlgOhUmePzSUPEYoZ2cYhvKhCR1hlYRKVSZ2WfYEshwsZSWf/o3GHCHm5hAt Fl57rCXwA1cDcNATTsBnUniGceeycJRQszE/Hcw+or7VrHfAK+Jb0S6ijyb6GB3iF4eX hptQ== X-Forwarded-Encrypted: i=1; AFNElJ/vIz18hePNdx7yqvgpO7v8vbf/ZJOZux/RshyBQ1o7hfGf2DbeK3ZE47hovkOr/U0f0ffQB92WS7I/2A4=@vger.kernel.org X-Gm-Message-State: AOJu0YwtHg2xPY9JNVoXoZ+loeogsV8/emhvvJP0Hllsn303WYADFB8I cs92/Fd635gShjYQLuNf9kdxL9aIUYukzS4+F4m53yy9jztrhuMmiKaH99VUEw== X-Gm-Gg: Acq92OGHLiFv5Ii9UhmmCzfLLEFG1KanuscLYH95fBAbSUlFyvZ7QIk7YO91mCCtCX4 uFU4pPGAXqXrwOhaUKloGBMPkDsT6IvFZX3uuLwPBObElybgUVDvEln+25SixcgSZtyyIZtSKbM HgeUJGCOIXTNZStDp19w3/u2YR9JFvB6PoT0znjg4EOQXesHW0UQtQfNqBrTD9YbOV6E345x+Cy UaMCUGDWT+8dMub/ARAHW+0r14iyCs5A0JOSjtVmvjBDKMxFk1Akw5YpJhCR4ghbjiJvjd2Gm9j o6h3O+30oDmWfy3Qh9F/wDNKAWdlGEElzWmZu3XSFnAGEdYvn2RNMtlyVP1sEH/YxEICb2VsFvW J8zy4IIo77kBw+AJwOdsOrweUilT775tfj8k4RTIzQeFKQVatICJdQVLegTWbEJTWmmfnmAhLVa jfOOaVch9pUvX00S+LxwBGEeVZfmAFfMnpRTHC1T13hV+yya40E5WsOqu92VmT39l7WCFWfQx7X kZw5/Y3pMJtHyr1MphXgeb58PcjU3Un2bKkQbdhcxRn1LhzY7IVdw+RxIeKR1qYbw== X-Received: by 2002:a05:6820:1a06:b0:69e:41d8:f7e6 with SMTP id 006d021491bc7-69edc620781mr10181870eaf.13.1781574267764; Mon, 15 Jun 2026 18:44:27 -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 006d021491bc7-69f00b41ed1sm4093011eaf.0.2026.06.15.18.44.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Jun 2026 18:44:27 -0700 (PDT) From: Russ Fellows To: miklos@szeredi.hu Cc: fuse-devel@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, amir73il@gmail.com, Russ Fellows Subject: [PATCH v2 2/2] fuse: allow parallel direct writes in passthrough write_iter Date: Tue, 16 Jun 2026 01:44:19 +0000 Message-ID: <20260616014419.7913-3-russ.fellows@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260616014419.7913-1-russ.fellows@gmail.com> References: <20260529031918.7361-1-russ.fellows@gmail.com> <20260616014419.7913-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 From: Russ Fellows fuse_passthrough_write_iter() currently relies on the generic fuse_dio_lock() path to decide whether writes may run under a shared inode lock. That couples passthrough to the regular direct-IO helpers and does not make the passthrough-specific safety conditions explicit. Keep the decision local to passthrough.c instead. Allow shared inode locking only when all of the following are true: - the open carries FOPEN_PARALLEL_DIRECT_WRITES - the write is direct I/O - the write is not append - the write does not extend past EOF Buffered writes, append writes, and EOF-extending writes remain serialized under the exclusive inode lock. This preserves the parallel direct-write win for safe overwrite I/O without exporting extra helper APIs from file.c. Signed-off-by: Russ Fellows --- fs/fuse/passthrough.c | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index ee822a983..c32b35a6d 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -25,6 +25,38 @@ static void fuse_passthrough_end_write(struct kiocb *iocb, ssize_t ret) fuse_write_update_attr(inode, iocb->ki_pos, ret); } +static bool fuse_passthrough_io_past_eof(struct kiocb *iocb, + struct iov_iter *iter) +{ + struct inode *inode = file_inode(iocb->ki_filp); + + return iocb->ki_pos + iov_iter_count(iter) > i_size_read(inode); +} + +static bool fuse_passthrough_write_exclusive(struct kiocb *iocb, + struct iov_iter *iter) +{ + struct file *file = iocb->ki_filp; + struct fuse_file *ff = file->private_data; + + if (!(ff->open_flags & FOPEN_PARALLEL_DIRECT_WRITES)) + return true; + + /* + * Passthrough writes do not use the regular FUSE direct-IO iomode path. + * Allow shared locking only for direct overwrite I/O; buffered writes, + * append writes, and writes that may extend EOF remain serialized. + */ + if (!(iocb->ki_flags & IOCB_DIRECT)) + return true; + if (iocb->ki_flags & IOCB_APPEND) + return true; + if (fuse_passthrough_io_past_eof(iocb, iter)) + return true; + + return false; +} + ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; @@ -54,6 +86,7 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); struct fuse_file *ff = file->private_data; struct file *backing_file = fuse_file_passthrough(ff); size_t count = iov_iter_count(iter); @@ -70,10 +103,19 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb, if (!count) return 0; - fuse_dio_lock(iocb, iter, &exclusive); + exclusive = fuse_passthrough_write_exclusive(iocb, iter); + if (exclusive) + inode_lock(inode); + else + inode_lock_shared(inode); + ret = backing_file_write_iter(backing_file, iter, iocb, iocb->ki_flags, &ctx); - fuse_dio_unlock(iocb, exclusive); + + if (exclusive) + inode_unlock(inode); + else + inode_unlock_shared(inode); return ret; } -- 2.51.0