Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

netfs: Fix the handling of stream->front by removing it

The netfs_io_stream::front member is meant to point to the subrequest
currently being collected on a stream, but it isn't actually used this way
by direct write (which mostly ignores it). However, there's a tracepoint
which looks at it. Further, stream->front is actually redundant with
stream->subrequests.next.

Fix the potential problem in the direct code by just removing the member
and using stream->subrequests.next instead, thereby also simplifying the
code.

Fixes: a0b4c7a49137 ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Reported-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/4158599.1774426817@warthog.procyon.org.uk
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

David Howells and committed by
Christian Brauner
0e764b9d f621324d

+11 -17
+1 -2
fs/netfs/buffered_read.c
··· 171 171 spin_lock(&rreq->lock); 172 172 list_add_tail(&subreq->rreq_link, &stream->subrequests); 173 173 if (list_is_first(&subreq->rreq_link, &stream->subrequests)) { 174 - stream->front = subreq; 175 174 if (!stream->active) { 176 - stream->collected_to = stream->front->start; 175 + stream->collected_to = subreq->start; 177 176 /* Store list pointers before active flag */ 178 177 smp_store_release(&stream->active, true); 179 178 }
+1 -2
fs/netfs/direct_read.c
··· 71 71 spin_lock(&rreq->lock); 72 72 list_add_tail(&subreq->rreq_link, &stream->subrequests); 73 73 if (list_is_first(&subreq->rreq_link, &stream->subrequests)) { 74 - stream->front = subreq; 75 74 if (!stream->active) { 76 - stream->collected_to = stream->front->start; 75 + stream->collected_to = subreq->start; 77 76 /* Store list pointers before active flag */ 78 77 smp_store_release(&stream->active, true); 79 78 }
-1
fs/netfs/direct_write.c
··· 111 111 netfs_prepare_write(wreq, stream, wreq->start + wreq->transferred); 112 112 subreq = stream->construct; 113 113 stream->construct = NULL; 114 - stream->front = NULL; 115 114 } 116 115 117 116 /* Check if (re-)preparation failed. */
+2 -2
fs/netfs/read_collect.c
··· 205 205 * in progress. The issuer thread may be adding stuff to the tail 206 206 * whilst we're doing this. 207 207 */ 208 - front = READ_ONCE(stream->front); 208 + front = list_first_entry_or_null(&stream->subrequests, 209 + struct netfs_io_subrequest, rreq_link); 209 210 while (front) { 210 211 size_t transferred; 211 212 ··· 302 301 list_del_init(&front->rreq_link); 303 302 front = list_first_entry_or_null(&stream->subrequests, 304 303 struct netfs_io_subrequest, rreq_link); 305 - stream->front = front; 306 304 spin_unlock(&rreq->lock); 307 305 netfs_put_subrequest(remove, 308 306 notes & ABANDON_SREQ ?
-1
fs/netfs/read_single.c
··· 107 107 spin_lock(&rreq->lock); 108 108 list_add_tail(&subreq->rreq_link, &stream->subrequests); 109 109 trace_netfs_sreq(subreq, netfs_sreq_trace_added); 110 - stream->front = subreq; 111 110 /* Store list pointers before active flag */ 112 111 smp_store_release(&stream->active, true); 113 112 spin_unlock(&rreq->lock);
+2 -2
fs/netfs/write_collect.c
··· 228 228 if (!smp_load_acquire(&stream->active)) 229 229 continue; 230 230 231 - front = stream->front; 231 + front = list_first_entry_or_null(&stream->subrequests, 232 + struct netfs_io_subrequest, rreq_link); 232 233 while (front) { 233 234 trace_netfs_collect_sreq(wreq, front); 234 235 //_debug("sreq [%x] %llx %zx/%zx", ··· 280 279 list_del_init(&front->rreq_link); 281 280 front = list_first_entry_or_null(&stream->subrequests, 282 281 struct netfs_io_subrequest, rreq_link); 283 - stream->front = front; 284 282 spin_unlock(&wreq->lock); 285 283 netfs_put_subrequest(remove, 286 284 notes & SAW_FAILURE ?
+1 -2
fs/netfs/write_issue.c
··· 206 206 spin_lock(&wreq->lock); 207 207 list_add_tail(&subreq->rreq_link, &stream->subrequests); 208 208 if (list_is_first(&subreq->rreq_link, &stream->subrequests)) { 209 - stream->front = subreq; 210 209 if (!stream->active) { 211 - stream->collected_to = stream->front->start; 210 + stream->collected_to = subreq->start; 212 211 /* Write list pointers before active flag */ 213 212 smp_store_release(&stream->active, true); 214 213 }
-1
include/linux/netfs.h
··· 140 140 void (*issue_write)(struct netfs_io_subrequest *subreq); 141 141 /* Collection tracking */ 142 142 struct list_head subrequests; /* Contributory I/O operations */ 143 - struct netfs_io_subrequest *front; /* Op being collected */ 144 143 unsigned long long collected_to; /* Position we've collected results to */ 145 144 size_t transferred; /* The amount transferred from this stream */ 146 145 unsigned short error; /* Aggregate error for the stream */
+4 -4
include/trace/events/netfs.h
··· 740 740 __field(unsigned int, wreq) 741 741 __field(unsigned char, stream) 742 742 __field(unsigned long long, collected_to) 743 - __field(unsigned long long, front) 743 + __field(unsigned long long, issued_to) 744 744 ), 745 745 746 746 TP_fast_assign( 747 747 __entry->wreq = wreq->debug_id; 748 748 __entry->stream = stream->stream_nr; 749 749 __entry->collected_to = stream->collected_to; 750 - __entry->front = stream->front ? stream->front->start : UINT_MAX; 750 + __entry->issued_to = atomic64_read(&wreq->issued_to); 751 751 ), 752 752 753 - TP_printk("R=%08x[%x:] cto=%llx frn=%llx", 753 + TP_printk("R=%08x[%x:] cto=%llx ito=%llx", 754 754 __entry->wreq, __entry->stream, 755 - __entry->collected_to, __entry->front) 755 + __entry->collected_to, __entry->issued_to) 756 756 ); 757 757 758 758 TRACE_EVENT(netfs_folioq,