netfs: Provide helpers to perform NETFS_RREQ_IN_PROGRESS flag wangling
authorDavid Howells <dhowells@redhat.com>
Tue, 1 Jul 2025 16:38:38 +0000 (17:38 +0100)
committerChristian Brauner <brauner@kernel.org>
Tue, 1 Jul 2025 20:37:13 +0000 (22:37 +0200)
Provide helpers to clear and test the NETFS_RREQ_IN_PROGRESS and to insert
the appropriate barrierage.

Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/20250701163852.2171681-4-dhowells@redhat.com
Tested-by: Steve French <sfrench@samba.org>
Reviewed-by: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/netfs/internal.h
fs/netfs/misc.c
fs/netfs/read_collect.c
fs/netfs/write_collect.c

index e2ee9183392b932ec5a05b6b7a59a3ac360870cc..d6656d2b54abd2faaa4c7e3487b199df04635ffa 100644 (file)
@@ -274,6 +274,24 @@ static inline void netfs_wake_rreq_flag(struct netfs_io_request *rreq,
        }
 }
 
+/*
+ * Test the NETFS_RREQ_IN_PROGRESS flag, inserting an appropriate barrier.
+ */
+static inline bool netfs_check_rreq_in_progress(const struct netfs_io_request *rreq)
+{
+       /* Order read of flags before read of anything else, such as error. */
+       return test_bit_acquire(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
+}
+
+/*
+ * Test the NETFS_SREQ_IN_PROGRESS flag, inserting an appropriate barrier.
+ */
+static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subrequest *subreq)
+{
+       /* Order read of flags before read of anything else, such as error. */
+       return test_bit_acquire(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+}
+
 /*
  * fscache-cache.c
  */
index 8cf73b237269a9a492d2909ae3cd66730aeb9a85..7f31c3cbfe015f6eb1875fc66bda3e2db658947e 100644 (file)
@@ -356,14 +356,14 @@ void netfs_wait_for_in_progress_stream(struct netfs_io_request *rreq,
        DEFINE_WAIT(myself);
 
        list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
-               if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
+               if (!netfs_check_subreq_in_progress(subreq))
                        continue;
 
                trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
                for (;;) {
                        prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
 
-                       if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
+                       if (!netfs_check_subreq_in_progress(subreq))
                                break;
 
                        trace_netfs_sreq(subreq, netfs_sreq_trace_wait_for);
@@ -400,7 +400,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
                                                  struct netfs_io_subrequest,
                                                  rreq_link);
                if (subreq &&
-                   (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
+                   (!netfs_check_subreq_in_progress(subreq) ||
                     test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
                        need_collect = true;
                        break;
@@ -451,7 +451,7 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
                        }
                }
 
-               if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags))
+               if (!netfs_check_rreq_in_progress(rreq))
                        break;
 
                schedule();
@@ -518,7 +518,7 @@ static void netfs_wait_for_pause(struct netfs_io_request *rreq,
                        }
                }
 
-               if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags) ||
+               if (!netfs_check_rreq_in_progress(rreq) ||
                    !test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
                        break;
 
index 96ee18af28ef82996b4101b237a6ba1c9b36d781..cceed9d629c6ccec0acb87f233be04be3ea7262d 100644 (file)
@@ -218,7 +218,7 @@ reassess:
                        stream->collected_to = front->start;
                }
 
-               if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags))
+               if (netfs_check_subreq_in_progress(front))
                        notes |= HIT_PENDING;
                smp_rmb(); /* Read counters after IN_PROGRESS flag. */
                transferred = READ_ONCE(front->transferred);
@@ -445,7 +445,7 @@ void netfs_read_collection_worker(struct work_struct *work)
        struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);
 
        netfs_see_request(rreq, netfs_rreq_trace_see_work);
-       if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
+       if (netfs_check_rreq_in_progress(rreq)) {
                if (netfs_read_collection(rreq))
                        /* Drop the ref from the IN_PROGRESS flag. */
                        netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
index e2b102ffb768345cfc227c1085d1ce58a727d8e5..2ac85a819b71db70da524c286de420ec165256dc 100644 (file)
@@ -240,7 +240,7 @@ reassess_streams:
                        }
 
                        /* Stall if the front is still undergoing I/O. */
-                       if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags)) {
+                       if (netfs_check_subreq_in_progress(front)) {
                                notes |= HIT_PENDING;
                                break;
                        }
@@ -434,7 +434,7 @@ void netfs_write_collection_worker(struct work_struct *work)
        struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);
 
        netfs_see_request(rreq, netfs_rreq_trace_see_work);
-       if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
+       if (netfs_check_rreq_in_progress(rreq)) {
                if (netfs_write_collection(rreq))
                        /* Drop the ref from the IN_PROGRESS flag. */
                        netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);