From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18D10E7717D for ; Mon, 9 Dec 2024 15:07:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9FDB48D007A; Mon, 9 Dec 2024 10:07:08 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 986E38D0058; Mon, 9 Dec 2024 10:07:08 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 800728D007A; Mon, 9 Dec 2024 10:07:08 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 562418D0058 for ; Mon, 9 Dec 2024 10:07:08 -0500 (EST) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 1D195ADC97 for ; Mon, 9 Dec 2024 15:07:08 +0000 (UTC) X-FDA: 82875747654.27.9D190F1 Received: from mail-il1-f197.google.com (mail-il1-f197.google.com [209.85.166.197]) by imf27.hostedemail.com (Postfix) with ESMTP id 2B16D40005 for ; Mon, 9 Dec 2024 15:06:42 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=none; spf=pass (imf27.hostedemail.com: domain of 3mQdXZwkbAEY067sittmzixxql.owwotm20mzkwv1mv1.kwu@M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com designates 209.85.166.197 as permitted sender) smtp.mailfrom=3mQdXZwkbAEY067sittmzixxql.owwotm20mzkwv1mv1.kwu@M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=appspotmail.com (policy=none) ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1733756816; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references; bh=vGQBWcDcxC8PTUtma5Rl3wbg+XdVdV4St9AhsdLUDTI=; b=gXeBgZEHWQ0b/y++QJ2S7qX2j5jHFnT8hK9kUYRutRzLh3ekUW91ehvVCLRZ2HGPZmOWVX qFsO5hgxyV6xjPYjMeuyiUfS1khFHHDQrz0XtTyTRjxBrUhbGlHBmnYG8WGYWMfdovk0f1 oQASrLXdieFsrkssp0GJ5n3gf5aTOzY= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1733756816; a=rsa-sha256; cv=none; b=OpcBnzBz6lwhe49KtebVTQ/xObWfIFPRG9Mx4oPZM7QRSWJCE8/VE8FGQxtQuOb9ZJnFJk fsy7APjucA64j6c+nqGeF+WZGUmLmReYvXPD8S0E3/h79jwYEr5umYLLMID5x8J6c13g0r u45wkdBjfBxkTYrKMJk58vhMt5i4pdc= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=none; spf=pass (imf27.hostedemail.com: domain of 3mQdXZwkbAEY067sittmzixxql.owwotm20mzkwv1mv1.kwu@M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com designates 209.85.166.197 as permitted sender) smtp.mailfrom=3mQdXZwkbAEY067sittmzixxql.owwotm20mzkwv1mv1.kwu@M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=appspotmail.com (policy=none) Received: by mail-il1-f197.google.com with SMTP id e9e14a558f8ab-3a817be161bso23605285ab.1 for ; Mon, 09 Dec 2024 07:07:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733756825; x=1734361625; h=cc:to:from:subject:message-id:in-reply-to:date:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vGQBWcDcxC8PTUtma5Rl3wbg+XdVdV4St9AhsdLUDTI=; b=mY0UFjrYRNyXOvMJCNLrZQ0KemWyf9W2fxo01r8us+gm7Ct5TBce2HXC5kYiP3peOQ rPhG4ZZuC4kNiF3+cA+S7qGisOQe784xMQ10yI3wSfZMfWAfRw8vgM+3HzutrKTSpEDM BAYPNK4N+JRAX7y5bEeKCy3pL0tUlVq9bslr/UtH6Q/Bq/QlJ1W0DGO7KbtTKFakGB2o BFrpwsNX6zChQjuqAAUuWl/ClqwtYPRvG5t5G3OU6K8Se68SGYO8iksXoKTiIEJLbyTP HTSes2POSVEgdYLdfZzYTrC8k7mhdWfiEq9nZC1F1G9iisMuoDRFXp/cOBNN9Lb7twg4 JL4A== X-Forwarded-Encrypted: i=1; AJvYcCU5+7fk19IFmhq8lEmNQdAFdqm3R80sa4sj9rbe3SrhHDfSsWbQWO9wOL/dIKIhact4lFxtRjU2kA==@kvack.org X-Gm-Message-State: AOJu0YwxVugZ3RgR1y03Bh3yINgvva+Kjq5QYfNibfkBOcqbZe6bO/Ba eZqtw5YAIW1N4uRgAbaKg2xkv9aqWrx7qNorIYlSHznozl0LoZFPwYkhIv8PYZPViNWYG/F8Feq iy3IJlLsP0TEqyKiuAAigRxzQrDSMH4Pzg3ftObMiX9Z+j9mK9s5qx9o= X-Google-Smtp-Source: AGHT+IFRIi9dd8FkLIwn/Td/R1grHmgTm25yl5feYxK8cblH/9KhVr7xCO/WQGh0mAllToNsKcrr7EqVVYiiApC+jAkWiOJlfwkv MIME-Version: 1.0 X-Received: by 2002:a05:6e02:218a:b0:3a7:c81e:825f with SMTP id e9e14a558f8ab-3a811e02ee5mr136405305ab.9.1733756825068; Mon, 09 Dec 2024 07:07:05 -0800 (PST) Date: Mon, 09 Dec 2024 07:07:05 -0800 In-Reply-To: <2131863.1733756813@warthog.procyon.org.uk> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <67570799.050a0220.a30f1.01a6.GAE@google.com> Subject: Re: [syzbot] [mm?] [v9fs?] BUG: stack guard page was hit in sys_open From: syzbot To: dhowells@redhat.com Cc: akpm@linux-foundation.org, asmadeus@codewreck.org, dhowells@redhat.com, ericvh@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux_oss@crudebyte.com, lucho@ionkov.net, syzkaller-bugs@googlegroups.com, v9fs@lists.linux.dev Content-Type: text/plain; charset="UTF-8" X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 2B16D40005 X-Stat-Signature: g5y4g7mjfq4tj77mkhqes8qhj8o3dz15 X-Rspam-User: X-HE-Tag: 1733756802-289935 X-HE-Meta: U2FsdGVkX1+QWUKf7DIqdyia633zjMYsYUtyP87fTo8jFLqwvjQ2WNZmruuIZg+SqkYk8lOHapKw7i0xa33ZtbT6m5wgl3j5eG5Ly2i0nJQENkFDQ8t9iQEkij455wOG9IGpcF0Q7fgcPMcFNlAlQJu5aeAiU/8pOpyYzUHiE0R18zyyj3rGsPM3WpyTfNG6m5SlqhGEoUHwiEDqGsz5aXuV60rVVOcs8w/PMWn8LPITWDXXPMP50focIUU6ZwXnr+fPDxauUxDHOn1BQDeWbMai0cUMG8Hf3pS4rtwRfO6fcznv5byKJAIJPmkAGQMwe5S4xcvd+QK4jgaNBhBgw4RhC1ySDP32D0e3Yc8OZTjZNU0YiYEoUtjqSa8gbCilsH6wOHCDIicJvCigHAZmTU5FMo5mJ7vKGT35dQgsWFP9XTRJSp+4TqLLFcmqjfDztBPdb3Ja6vA28dODjIxyxQ4s1eedKpg2ECzeuPTNqKaNS6XieTyfWTN76c0nu5GWz8FVGfWCwwSVu07Y12rjQIpnjXaSfSx7+vgDPfg6ursW53+5Xj1VtkWHCJykzbKyRiop8OEcjlEICqYjey+VsYNDJIi52ofQDYb9rwZK8Sg56wI/GAI1B9dIpRfoO1CYNd1wJPXwNEekXHUSl7TkdUqWiT5EvrxE6EIVYAWickVAik6ETgYJlY0ryXCyG+znJd2DV7Ry4ocFsdak9JRj24v30HJhWPq99cPpQ7p+nF8ccrgEO6LjhCNStiu6lj17w92GIbLHYiFPxkLVgSxjn3aC9qR8xmp/v/a/MA4lYZnFzThjxHwUXrEQDkU4JmQiZnCv7I6ZzRigzZSXXacucb3POSq+3VDiSCXg0WI7NLrc+R5vwO/wnegTmqEAC5bNYQBTOo/9lcITO0AwsVMeussX0+fT9+IkDL8h5vzongZz+TeMA1BDlAGRXo5VxcW48jwKinKtLwW522QWKbe f4FrtXtW X1kLRBeu38T08JGVuHpiWm9ZBZWI/B4mb6/s6k55j0BECqJ40vg1jtTGr+i1a31e19dfERMDYvVoE/xLnWCaJmDBQWZmFx4qloLKKJZx5oyl8/aztZd9oXiR3/uD/djIBuv0UM0zAulZrjl7h5vQByWYfGAvXSEs4UavdWpKinJ4zGyZqLRYSOQ3FfNV9LK0bfvF7DiLsjemQ3gzjcwUO8rHx4Jmfv8e0PvvxjC0xx4wb5tybQOtn8+d/f62+LP8vXsieHvC01HuB7uIgFUx22YUpcPgVgv9qk37doMN8Nqn7wlwRnQCyPM+Ocv41oW9crOxC+lUzcuc1eEHxt6zvI2TmBkndQ1Rd+pQDJ5DnOBmQGKBTDPKUwXHlOZBNqb45paE2uDmqhaYLlWqK+8O2T+gAcXEbFcDPFOjFCq5/14Q0XJpWxtE3p+oxVFcovnf8STW49OCoFyYprLwgrwkQNSlpY2UkJK/W3bAt1h1EYoFeTSeHn1hpLP6BuC3/gJy9qBBN5wUBVl71dMb4HtfUrHFXsWwBMEnvD1a44SoEJ3fXxOUQdpF4N37oFBGVmUYe7AnNQKgG5jDRz9nkNt5Fklg/Z6d/SY/srrSC2PlIoku+vZSJykC0rDmtJO1LM7+BJIh0YlDUegYRozqGPjTWvjY31s3+is8dr0XraaENNiZoFDcHuMyeUv81qtFWnZ4CEXhU+cXPCIwkSJcYZt912uE3/GKYhMiG/39OkF6XK84AbgXXeUWZf5ue0c/elUn9UB68E4bWKnhHqMgNRrHgBU1isawqY5fDLdT1NrXBbPl2VEOEurrepmPZHcPVOx2FFh0E8FnhrgVOPfaDIGk4PRBvIDxaM+f9WzAg6vfDsMSh/D7nInVD56vH3tMBRn9tAHMxDF4bzjN/AYQkZlFJMLjSLGwqCWqzsfkuXgUiN9uDs+WZrahsSOEljqWDVucLlo0GhmItQa1Pu4rZLEV8cKJX5y9o NGPX+dM+ DOxu60YCrTE= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: > #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git want either no args or 2 args (repo, branch), got 3 > > commit 78513c0ee0d9a767b5c2568c6c220a941e73529c > Author: Lizhi Xu > Date: Fri Nov 8 11:40:20 2024 +0800 > > netfs: If didn't read new data then abandon retry > > syzkaller reported a three-level circle calls (netfs_rreq_assess, > netfs_retry_reads, netfs_rreq_terminated), during an unbuffered or direct > I/O read. [1] > > netfs_rreq_terminated() only checks that subreq's transferred is greater > than consumed and then sets the retry flag. There is no limit on the number > of retries, and there is no judgment on whether the retry is effective in > reading new data. This hitting the stack guard page. > > To avoid the issue, let's add retry read times and the length of the data > just read in struct netfs_io_subrequest, use them to assess the state of a > read request and decide what to do retry. > > [1] > BUG: TASK stack guard page was hit at ffffc9000482ff48 (stack is ffffc90004830000..ffffc90004838000) > Oops: stack guard page: 0000 [#1] PREEMPT SMP KASAN NOPTI > CPU: 3 UID: 0 PID: 6237 Comm: syz-executor663 Not tainted 6.12.0-rc6-syzkaller-00077-g2e1b3cc9d7f7 #0 > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > RIP: 0010:mark_lock+0x25/0xc60 kernel/locking/lockdep.c:4686 > Code: 90 90 90 90 90 55 48 89 e5 41 57 41 56 41 89 d6 48 ba 00 00 00 00 00 fc ff df 41 55 41 54 53 48 83 e4 f0 48 81 ec 10 01 00 00 <48> c7 44 24 30 b3 8a b5 41 48 8d 44 24 30 48 c7 44 24 38 c0 4d 7a > RSP: 0018:ffffc9000482ff50 EFLAGS: 00010086 > RAX: 000000000000000c RBX: ffff8880306c2fba RCX: 0000000000000002 > RDX: dffffc0000000000 RSI: ffff8880306c2f98 RDI: ffff8880306c2440 > RBP: ffffc90004830088 R08: 0000000000000000 R09: 0000000000000006 > R10: ffffffff96e2dd27 R11: 0000000000000000 R12: dffffc0000000000 > R13: ffff8880306c2f98 R14: 0000000000000008 R15: ffff8880306c2440 > FS: 00007fedf3b6e6c0(0000) GS:ffff88806a900000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: ffffc9000482ff48 CR3: 000000002c910000 CR4: 0000000000352ef0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 > Call Trace: > <#DF> > > > mark_usage kernel/locking/lockdep.c:4646 [inline] > __lock_acquire+0x906/0x3ce0 kernel/locking/lockdep.c:5156 > lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5825 > local_lock_acquire include/linux/local_lock_internal.h:29 [inline] > ___slab_alloc+0x123/0x1880 mm/slub.c:3695 > __slab_alloc.constprop.0+0x56/0xb0 mm/slub.c:3908 > __slab_alloc_node mm/slub.c:3961 [inline] > slab_alloc_node mm/slub.c:4122 [inline] > kmem_cache_alloc_noprof+0x2a7/0x2f0 mm/slub.c:4141 > radix_tree_node_alloc.constprop.0+0x1e8/0x350 lib/radix-tree.c:253 > idr_get_free+0x528/0xa40 lib/radix-tree.c:1506 > idr_alloc_u32+0x191/0x2f0 lib/idr.c:46 > idr_alloc+0xc1/0x130 lib/idr.c:87 > p9_tag_alloc+0x394/0x870 net/9p/client.c:321 > p9_client_prepare_req+0x19f/0x4d0 net/9p/client.c:644 > p9_client_zc_rpc.constprop.0+0x105/0x880 net/9p/client.c:793 > p9_client_read_once+0x443/0x820 net/9p/client.c:1570 > p9_client_read+0x13f/0x1b0 net/9p/client.c:1534 > v9fs_issue_read+0x115/0x310 fs/9p/vfs_addr.c:74 > netfs_retry_read_subrequests fs/netfs/read_retry.c:60 [inline] > netfs_retry_reads+0x153a/0x1d00 fs/netfs/read_retry.c:232 > netfs_rreq_assess+0x5d3/0x870 fs/netfs/read_collect.c:371 > netfs_rreq_terminated+0xe5/0x110 fs/netfs/read_collect.c:407 > netfs_retry_reads+0x155e/0x1d00 fs/netfs/read_retry.c:235 > netfs_rreq_assess+0x5d3/0x870 fs/netfs/read_collect.c:371 > netfs_rreq_terminated+0xe5/0x110 fs/netfs/read_collect.c:407 > netfs_retry_reads+0x155e/0x1d00 fs/netfs/read_retry.c:235 > netfs_rreq_assess+0x5d3/0x870 fs/netfs/read_collect.c:371 > ... > netfs_rreq_terminated+0xe5/0x110 fs/netfs/read_collect.c:407 > netfs_retry_reads+0x155e/0x1d00 fs/netfs/read_retry.c:235 > netfs_rreq_assess+0x5d3/0x870 fs/netfs/read_collect.c:371 > netfs_rreq_terminated+0xe5/0x110 fs/netfs/read_collect.c:407 > netfs_retry_reads+0x155e/0x1d00 fs/netfs/read_retry.c:235 > netfs_rreq_assess+0x5d3/0x870 fs/netfs/read_collect.c:371 > netfs_rreq_terminated+0xe5/0x110 fs/netfs/read_collect.c:407 > netfs_dispatch_unbuffered_reads fs/netfs/direct_read.c:103 [inline] > netfs_unbuffered_read fs/netfs/direct_read.c:127 [inline] > netfs_unbuffered_read_iter_locked+0x12f6/0x19b0 fs/netfs/direct_read.c:221 > netfs_unbuffered_read_iter+0xc5/0x100 fs/netfs/direct_read.c:256 > v9fs_file_read_iter+0xbf/0x100 fs/9p/vfs_file.c:361 > do_iter_readv_writev+0x614/0x7f0 fs/read_write.c:832 > vfs_readv+0x4cf/0x890 fs/read_write.c:1025 > do_preadv fs/read_write.c:1142 [inline] > __do_sys_preadv fs/read_write.c:1192 [inline] > __se_sys_preadv fs/read_write.c:1187 [inline] > __x64_sys_preadv+0x22d/0x310 fs/read_write.c:1187 > do_syscall_x64 arch/x86/entry/common.c:52 [inline] > do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > RIP: 0033:0x7fedf3bd4dd9 > Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007fedf3b6e168 EFLAGS: 00000246 ORIG_RAX: 0000000000000127 > RAX: ffffffffffffffda RBX: 00007fedf3c5e318 RCX: 00007fedf3bd4dd9 > RDX: 0000000000000001 RSI: 00000000200015c0 RDI: 0000000000000003 > RBP: 00007fedf3c5e310 R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 00007fedf3c5e31c > R13: 000000000000000b R14: 00007fffe9d355b0 R15: 00007fffe9d35698 > > > Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading") > Closes: https://syzkaller.appspot.com/bug?extid=1fc6f64c40a9d143cfb6 > Signed-off-by: David Howells > Suggested-by: Lizhi Xu [2] > cc: Dominique Martinet > cc: Jeff Layton > cc: v9fs@lists.linux.dev > cc: netfs@lists.linux.dev > cc: linux-fsdevel@vger.kernel.org > Link: https://lore.kernel.org/r/20241108034020.3695718-1-lizhi.xu@windriver.com/ [2] > > diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c > index 819c75233235..3bc9ce6c575e 100644 > --- a/fs/9p/vfs_addr.c > +++ b/fs/9p/vfs_addr.c > @@ -57,6 +57,8 @@ static void v9fs_issue_write(struct netfs_io_subrequest *subreq) > int err, len; > > len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err); > + if (len > 0) > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > netfs_write_subrequest_terminated(subreq, len ?: err, false); > } > > @@ -80,8 +82,10 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq) > if (pos + total >= i_size_read(rreq->inode)) > __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags); > > - if (!err) > + if (!err) { > subreq->transferred += total; > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > + } > > netfs_read_subreq_terminated(subreq, err, false); > } > diff --git a/fs/afs/write.c b/fs/afs/write.c > index 34107b55f834..ccb6aa8027c5 100644 > --- a/fs/afs/write.c > +++ b/fs/afs/write.c > @@ -122,7 +122,7 @@ static void afs_issue_write_worker(struct work_struct *work) > if (subreq->debug_index == 3) > return netfs_write_subrequest_terminated(subreq, -ENOANO, false); > > - if (!test_bit(NETFS_SREQ_RETRYING, &subreq->flags)) { > + if (!subreq->retry_count) { > set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > return netfs_write_subrequest_terminated(subreq, -EAGAIN, false); > } > @@ -149,6 +149,9 @@ static void afs_issue_write_worker(struct work_struct *work) > afs_wait_for_operation(op); > ret = afs_put_operation(op); > switch (ret) { > + case 0: > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > + break; > case -EACCES: > case -EPERM: > case -ENOKEY: > diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c > index 46ce3b7adf07..47ed3a5044e2 100644 > --- a/fs/netfs/read_collect.c > +++ b/fs/netfs/read_collect.c > @@ -438,7 +438,7 @@ void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq, > rreq->origin == NETFS_READPAGE || > rreq->origin == NETFS_READ_FOR_WRITE)) { > netfs_consume_read_data(subreq, was_async); > - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > } > } > EXPORT_SYMBOL(netfs_read_subreq_progress); > @@ -497,7 +497,7 @@ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq, > rreq->origin == NETFS_READPAGE || > rreq->origin == NETFS_READ_FOR_WRITE)) { > netfs_consume_read_data(subreq, was_async); > - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > } > rreq->transferred += subreq->transferred; > } > @@ -511,10 +511,13 @@ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq, > } else { > trace_netfs_sreq(subreq, netfs_sreq_trace_short); > if (subreq->transferred > subreq->consumed) { > - __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); > - set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); > - } else if (!__test_and_set_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags)) { > + /* If we didn't read new data, abandon retry. */ > + if (subreq->retry_count && > + test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags)) { > + __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > + set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); > + } > + } else if (test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags)) { > __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); > } else { > diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c > index 0350592ea804..0e72e9226fc8 100644 > --- a/fs/netfs/read_retry.c > +++ b/fs/netfs/read_retry.c > @@ -56,6 +56,8 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq) > if (test_bit(NETFS_SREQ_FAILED, &subreq->flags)) > break; > if (__test_and_clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) { > + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > + subreq->retry_count++; > netfs_reset_iter(subreq); > netfs_reissue_read(rreq, subreq); > } > @@ -137,7 +139,8 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq) > stream0->sreq_max_len = subreq->len; > > __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); > + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > + subreq->retry_count++; > > spin_lock_bh(&rreq->lock); > list_add_tail(&subreq->rreq_link, &rreq->subrequests); > @@ -213,7 +216,6 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq) > subreq->error = -ENOMEM; > __clear_bit(NETFS_SREQ_FAILED, &subreq->flags); > __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > - __clear_bit(NETFS_SREQ_RETRYING, &subreq->flags); > } > spin_lock_bh(&rreq->lock); > list_splice_tail_init(&queue, &rreq->subrequests); > diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c > index 82290c92ba7a..ca3a11ed9b54 100644 > --- a/fs/netfs/write_collect.c > +++ b/fs/netfs/write_collect.c > @@ -179,7 +179,6 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq, > struct iov_iter source = subreq->io_iter; > > iov_iter_revert(&source, subreq->len - source.count); > - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); > netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit); > netfs_reissue_write(stream, subreq, &source); > } > @@ -234,7 +233,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq, > /* Renegotiate max_len (wsize) */ > trace_netfs_sreq(subreq, netfs_sreq_trace_retry); > __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); > - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); > + subreq->retry_count++; > stream->prepare_write(subreq); > > part = min(len, stream->sreq_max_len); > @@ -279,7 +278,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq, > subreq->start = start; > subreq->debug_index = atomic_inc_return(&wreq->subreq_counter); > subreq->stream_nr = to->stream_nr; > - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); > + subreq->retry_count = 1; > > trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index, > refcount_read(&subreq->ref), > diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c > index bf6d507578e5..ff0e82505a0b 100644 > --- a/fs/netfs/write_issue.c > +++ b/fs/netfs/write_issue.c > @@ -244,6 +244,8 @@ void netfs_reissue_write(struct netfs_io_stream *stream, > iov_iter_advance(source, size); > iov_iter_truncate(&subreq->io_iter, size); > > + subreq->retry_count++; > + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); > __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); > netfs_do_issue_write(stream, subreq); > } > diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c > index bd42a419458e..6cb1e81993f8 100644 > --- a/fs/smb/client/cifssmb.c > +++ b/fs/smb/client/cifssmb.c > @@ -1319,14 +1319,16 @@ cifs_readv_callback(struct mid_q_entry *mid) > } > > if (rdata->result == -ENODATA) { > - __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); > rdata->result = 0; > + __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); > } else { > size_t trans = rdata->subreq.transferred + rdata->got_bytes; > if (trans < rdata->subreq.len && > rdata->subreq.start + trans == ictx->remote_i_size) { > - __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); > rdata->result = 0; > + __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); > + } else if (rdata->got_bytes > 0) { > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); > } > } > > @@ -1670,10 +1672,13 @@ cifs_writev_callback(struct mid_q_entry *mid) > if (written > wdata->subreq.len) > written &= 0xFFFF; > > - if (written < wdata->subreq.len) > + if (written < wdata->subreq.len) { > result = -ENOSPC; > - else > + } else { > result = written; > + if (written > 0) > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); > + } > break; > case MID_REQUEST_SUBMITTED: > case MID_RETRY_NEEDED: > diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c > index 010eae9d6c47..458b53d1f9cb 100644 > --- a/fs/smb/client/smb2pdu.c > +++ b/fs/smb/client/smb2pdu.c > @@ -4615,6 +4615,7 @@ smb2_readv_callback(struct mid_q_entry *mid) > __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); > rdata->result = 0; > } > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); > } > trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, > server->credits, server->in_flight, > @@ -4840,10 +4841,12 @@ smb2_writev_callback(struct mid_q_entry *mid) > if (written > wdata->subreq.len) > written &= 0xFFFF; > > - if (written < wdata->subreq.len) > + if (written < wdata->subreq.len) { > wdata->result = -ENOSPC; > - else > + } else if (written > 0) { > wdata->subreq.len = written; > + __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); > + } > break; > case MID_REQUEST_SUBMITTED: > case MID_RETRY_NEEDED: > @@ -5012,7 +5015,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) > } > #endif > > - if (test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags)) > + if (wdata->subreq.retry_count > 0) > smb2_set_replay(server, &rqst); > > cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n", > diff --git a/include/linux/netfs.h b/include/linux/netfs.h > index 5eaceef41e6c..4083d77e3f39 100644 > --- a/include/linux/netfs.h > +++ b/include/linux/netfs.h > @@ -185,6 +185,7 @@ struct netfs_io_subrequest { > short error; /* 0 or error that occurred */ > unsigned short debug_index; /* Index in list (for debugging output) */ > unsigned int nr_segs; /* Number of segs in io_iter */ > + u8 retry_count; /* The number of retries (0 on initial pass) */ > enum netfs_io_source source; /* Where to read from/write to */ > unsigned char stream_nr; /* I/O stream this belongs to */ > unsigned char curr_folioq_slot; /* Folio currently being read */ > @@ -194,14 +195,13 @@ struct netfs_io_subrequest { > #define NETFS_SREQ_COPY_TO_CACHE 0 /* Set if should copy the data to the cache */ > #define NETFS_SREQ_CLEAR_TAIL 1 /* Set if the rest of the read should be cleared */ > #define NETFS_SREQ_SEEK_DATA_READ 3 /* Set if ->read() should SEEK_DATA first */ > -#define NETFS_SREQ_NO_PROGRESS 4 /* Set if we didn't manage to read any data */ > +#define NETFS_SREQ_MADE_PROGRESS 4 /* Set if we transferred at least some data */ > #define NETFS_SREQ_ONDEMAND 5 /* Set if it's from on-demand read mode */ > #define NETFS_SREQ_BOUNDARY 6 /* Set if ends on hard boundary (eg. ceph object) */ > #define NETFS_SREQ_HIT_EOF 7 /* Set if short due to EOF */ > #define NETFS_SREQ_IN_PROGRESS 8 /* Unlocked when the subrequest completes */ > #define NETFS_SREQ_NEED_RETRY 9 /* Set if the filesystem requests a retry */ > -#define NETFS_SREQ_RETRYING 10 /* Set if we're retrying */ > -#define NETFS_SREQ_FAILED 11 /* Set if the subreq failed unretryably */ > +#define NETFS_SREQ_FAILED 10 /* Set if the subreq failed unretryably */ > }; > > enum netfs_io_origin { >