From nobody Mon Feb 9 09:00:39 2026 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (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 1DB32247280 for ; Thu, 25 Dec 2025 11:03:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766660610; cv=none; b=LI3LDqub6jo3qzxolJmWvEGjWlSwVhSFqfBCeAHMa9YtiPW/irGnRQII1oM6xqOVNNhZCHRjEFBN99QDhhXDNO8W3nJ4l9AIqXCDefSdZAUNYqeBTzpqHlgniW912OyYmBRZ9wi/YVXCnP+Ym38hSH2AawvRgo9bxBfeH+vCMlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766660610; c=relaxed/simple; bh=tI1Ypizqxx8Gds2Tmljnz8yWDwROFZD/XML9Err/7Mg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Yqx0CzH03vp+gJEnp8IhifYqGI2ci7jNKtPbDnS6xSkzi2A4MgnQSuQMj3vcGx1RQwetmxc8hPaPrmxP5rWOOb5JHz2sEI1j3Cp1irsnqlN8dX1+Y7toqgRfGklrf76aaSi0fLNvlNvNMcniFvBClqUiYuLD+DFsFrABeV7dlm8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com; spf=pass smtp.mailfrom=bytedance.com; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b=gsSdh1H6; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bytedance.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b="gsSdh1H6" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-29f0f875bc5so96436435ad.3 for ; Thu, 25 Dec 2025 03:03:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1766660606; x=1767265406; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=fOfAb/cDxM0z/UBeWl882eHVeaGsbb539Q/v1BEVtNA=; b=gsSdh1H6QuKsQ6esysbuGI+Pl8pOo5x2iqFd2r4OAu9hrpkmOCsrL4slQU4p9XVHFo Y7gK6zRcsfaDuWsiBgal3sOoSwckboEPAiAcNC0bbAHeioJj7OQVxA/mPWg89y6XST+D wGFQFjTQetTrxXgJcN9WH9z0dUATgiqtQHN7vXkBNBU8BnPqg70ia03YoV+9/ExZ7wed v6XsXKhB/DA7FSTwdOjT9j5UmL4Dvmf7d4Hhb+DVha3QN1xU2oNwEpMO6GYOHrYVTMmf aVMgKBwG3/iIXhLZ0hotLfGg0u2nNxe3pvkbRbxgh25/D4xdzYcKPP0NnVqBPurgNsOR ZcDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766660606; x=1767265406; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fOfAb/cDxM0z/UBeWl882eHVeaGsbb539Q/v1BEVtNA=; b=N7poEvNla4eAQwd4bsr6dwotZcHQddgPhA13uYlVKkTmk+2Mt/1vPqOInNOHdbfmPI YKW6msMgt7d/RCF+HovR4rBRsXT6UCaAumoqHfq7sHLmhSW9X29+HLjy6l6Tx+SHgT+w W/QhsCmlP1zCgqsOKAMUIBbH6EV4wjk+8jL/R+E3WwSTR6DDEJ+ISz1+1OxBfvAB4nTv IJzY8O1kGxOQyyOb7pS+lBVPTnIuE8BmaiVsywH9hS+7DO7xheGzCbITZOCFK0rI0bZI /Dp33Hi3uIcG6R1ZjZW2bpJjlxNIcnLRZsp2tHyqjBnjhyJVuv9ppvyvfk/4DMTD8DjZ 2d+Q== X-Forwarded-Encrypted: i=1; AJvYcCU69LNdWmWwWw3UwQ/HLVB4Y5PDoNvEdydo5gEEPzRChjT+Eosh5g5+qQf+y/D/Wo/OHMOJeZF+E4ycM60=@vger.kernel.org X-Gm-Message-State: AOJu0YxgorYtYLKktQJ3kEGUVo3kv+xydVu6NsGrb0NP69nxdAUlHWvI +ejNxnF8YuCbYh8xRWTuO5eU025rO0M2iqE5Xp0ptYgiJe/LnPCsEpTM60A91Spmck4= X-Gm-Gg: AY/fxX5xJj7BSklS2HPNTO3mJpX1hMk0Xk4S0OPps78XvQHvwTvK91VLB3GLDtxmqlL wQaaP36SBAxG5Zzm2DLTQ8WMzWM5YwN6MRGXaqPuRz4L5Qogt93KWMKLZZyGDuRYvzKnrwVAf++ Kw+l9BstYLP8jIvK7KOcb5mvEw1gmZTP4697FjDsyTGwI/03RNb8sY6/cPJ7oy696ZCZS9y4kEn i7rJAYGvlFoyHUthaqpmk6B9DMQIgJHuk2irKf5qiAhVnPt9qCpaYr9fBaIdxwAYEvvCq2WV/NP YkHylL+7MdAsZmHOb14kIq+8ugRaZO2BbnY4HqoilZ5XIOb5GCdz5v3rNhMAQUQdBVU6CE/f+qX XIXwoA+tkiBgSTTo2+xSDf1fjjYgxAmjXqWe2Kpf3W9qGYcCH5TOzeK3GygFi5BsA8PoEY6Gfui re8c+tzGCcDvdUgqktM4k3quhg1c9fJTsuFHAW8PwGpsCwjwZwfQ== X-Google-Smtp-Source: AGHT+IH3XPmY+UAPzt+NqHa7fMAWWV3ZVFeTsNmlT8QpIftTwApy1z3U7dbB5m1U13R9cBXmkgm1LA== X-Received: by 2002:a17:902:db0e:b0:297:ebb2:f4a1 with SMTP id d9443c01a7336-2a2f2736c0emr201540755ad.38.1766660606273; Thu, 25 Dec 2025 03:03:26 -0800 (PST) Received: from tianci-mac.bytedance.net ([61.213.176.9]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-34e92228b64sm17825760a91.10.2025.12.25.03.03.23 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 25 Dec 2025 03:03:25 -0800 (PST) From: Zhang Tianci To: miklos@szeredi.hu Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Zhang Tianci , Geng Xueyu , Wang Jian , Xie Yongji Subject: [PATCH] fuse: fix the bug of missing EPOLLET event wakeup Date: Thu, 25 Dec 2025 19:03:18 +0800 Message-ID: <20251225110318.46261-1-zhangtianci.1997@bytedance.com> X-Mailer: git-send-email 2.48.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Users using Go have reported an issue to us: When performing read/write operations with goroutines, since fuse's file->f_ops->poll is not empty, read/write operations are conducted via epoll. Additionally, goroutines use the EPOLLET wake-up mode. Currently, the implementation of fuse_file_poll has the following problem: After receiving EAGAIN during read/write operations, the goroutine calls epoll_wait again, but then results in permanent blocking. This is because a wake-up event is required in EPOLLET mode. The modification idea of this patch is based on the implementation of epoll_wait: After epoll_wait calls ->poll() for EPOLLET events, it does not reinsert them into the ready list. In this case, ep_poll_callback() needs to be used to reinsert them into the ready list, so that the behavior of EPOLLET is consistent with that of non-EPOLLET. Reported-by: Geng Xueyu Reported-by: Wang Jian Suggested-by: Xie Yongji Signed-off-by: Zhang Tianci --- Here is the reproducer for the bug: 1. Change libfuse/example/passthrough.c's xmp_read() to always return -EAGAIN and mount it on /mnt_fuse.=20 2. Then create test file: dd if=3D/dev/zero of=3D/mnt_fuse/test_poll bs=3D1M count=3D10 3. compile and run the following test case. #include #include #include #include #include #include #include #define MAX_EVENTS 10 #define BUF_SIZE 4096 int main() { int epfd, nfds, fd; struct epoll_event ev, events[MAX_EVENTS]; char buffer[BUF_SIZE]; fd =3D open("/mnt_fuse/test_poll", O_RDWR|O_NONBLOCK|O_CREAT, 0644); if (fd =3D=3D -1) { perror("open"); return -1; } epfd =3D epoll_create1(0); if (epfd =3D=3D -1) { perror("epoll_create1"); return -1; } ev.data.fd =3D fd; ev.events =3D EPOLLIN | EPOLLET; if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) =3D=3D -1) { perror("epoll_ctl: fd"); return -1; } printf("Epoll is monitoring fd=3D%d.\n", fd); while (1) { nfds =3D epoll_wait(epfd, events, MAX_EVENTS, -1); if (nfds =3D=3D -1) { if (errno =3D=3D EINTR) { continue; } perror("epoll_wait"); return -1; } for (int i =3D 0; i < nfds; ++i) { int current_fd =3D events[i].data.fd; if (current_fd =3D=3D fd) { printf("[Notification] Data arrived on fd\n", fd); while (1) { ssize_t count =3D read(current_fd, buffer, BUF_SIZE); if (count =3D=3D -1) { if (errno =3D=3D EAGAIN || errno =3D=3D EWOULDBLOCK= ) { printf("[Info] Buffer is empty, waiting for nex= t event...\n"); break; } else { perror("read"); close(current_fd); return -1; } } else if (count =3D=3D 0) { printf("[Info] EOF detected. Closing.\n"); close(current_fd); return 0; } printf(">>> Read %zd bytes\n", count); } } } } close(epfd); return 0; } fs/fuse/file.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 01bc894e9c2ba..025eea58232c2 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2735,10 +2735,11 @@ __poll_t fuse_file_poll(struct file *file, poll_tab= le *wait) FUSE_ARGS(args); int err; =20 + poll_wait(file, &ff->poll_wait, wait); + if (fm->fc->no_poll) - return DEFAULT_POLLMASK; + goto no_poll; =20 - poll_wait(file, &ff->poll_wait, wait); inarg.events =3D mangle_poll(poll_requested_events(wait)); =20 /* @@ -2764,9 +2765,13 @@ __poll_t fuse_file_poll(struct file *file, poll_tabl= e *wait) return demangle_poll(outarg.revents); if (err =3D=3D -ENOSYS) { fm->fc->no_poll =3D 1; - return DEFAULT_POLLMASK; + goto no_poll; } return EPOLLERR; + +no_poll: + wake_up_interruptible_sync(&ff->poll_wait); + return DEFAULT_POLLMASK; } EXPORT_SYMBOL_GPL(fuse_file_poll); =20 --=20 2.39.5