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.

Merge patch series "netfs, ceph, nfs, cachefiles: Miscellaneous fixes/changes"

David Howells <dhowells@redhat.com> says:

Here are some miscellaneous fixes and changes for netfslib and the ceph and
nfs filesystems:

(1) Ignore silly-rename files from afs and nfs when building the header
archive in a kernel build.

(2) netfs: Fix the way read result collection applies results to folios
when each folio is being read by multiple subrequests and the results
come out of order.

(3) netfs: Fix ENOMEM handling in buffered reads.

(4) nfs: Fix an oops in nfs_netfs_init_request() when copying to the cache.

(5) cachefiles: Parse the "secctx" command immediately to get the correct
error rather than leaving it to the "bind" command.

(6) netfs: Remove a redundant smp_rmb(). This isn't a bug per se and
could be deferred.

(7) netfs: Fix missing barriers by using clear_and_wake_up_bit().

(8) netfs: Work around recursion in read retry by failing and abandoning
the retried subrequest if no I/O is performed.

[!] NOTE: This only works around the recursion problem if the
recursion keeps returning no data. If the server manages, say, to
repeatedly return a single byte of data faster than the retry
algorithm can complete, it will still recurse and the stack
overrun may still occur. Actually fixing this requires quite an
intrusive change which will hopefully make the next merge window.

(9) netfs: Fix the clearance of a folio_queue when unlocking the page if
we're going to want to subsequently send the queue for copying to the
cache (if, for example, we're using ceph).

(10) netfs: Fix the lack of cancellation of copy-to-cache when the cache
for a file is temporarily disabled (for example when a DIO write is
done to the file). This patch and (9) fix hangs with ceph.

With these patches, I can run xfstest -g quick to completion on ceph with a
local cache.

The patches can also be found here with a bonus cifs patch:

https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=netfs-fixes

* patches from https://lore.kernel.org/r/20241213135013.2964079-1-dhowells@redhat.com:
netfs: Fix is-caching check in read-retry
netfs: Fix the (non-)cancellation of copy when cache is temporarily disabled
netfs: Fix ceph copy to cache on write-begin
netfs: Work around recursion by abandoning retry if nothing read
netfs: Fix missing barriers by using clear_and_wake_up_bit()
netfs: Remove redundant use of smp_rmb()
cachefiles: Parse the "secctx" immediately
nfs: Fix oops in nfs_netfs_init_request() when copying to cache
netfs: Fix enomem handling in buffered reads
netfs: Fix non-contiguous donation between completed reads
kheaders: Ignore silly-rename files

Link: https://lore.kernel.org/r/20241213135013.2964079-1-dhowells@redhat.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

+99 -64
+5 -1
fs/9p/vfs_addr.c
··· 57 57 int err, len; 58 58 59 59 len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err); 60 + if (len > 0) 61 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 60 62 netfs_write_subrequest_terminated(subreq, len ?: err, false); 61 63 } 62 64 ··· 82 80 if (pos + total >= i_size_read(rreq->inode)) 83 81 __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags); 84 82 85 - if (!err) 83 + if (!err) { 86 84 subreq->transferred += total; 85 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 86 + } 87 87 88 88 netfs_read_subreq_terminated(subreq, err, false); 89 89 }
+4 -1
fs/afs/write.c
··· 122 122 if (subreq->debug_index == 3) 123 123 return netfs_write_subrequest_terminated(subreq, -ENOANO, false); 124 124 125 - if (!test_bit(NETFS_SREQ_RETRYING, &subreq->flags)) { 125 + if (!subreq->retry_count) { 126 126 set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 127 127 return netfs_write_subrequest_terminated(subreq, -EAGAIN, false); 128 128 } ··· 149 149 afs_wait_for_operation(op); 150 150 ret = afs_put_operation(op); 151 151 switch (ret) { 152 + case 0: 153 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 154 + break; 152 155 case -EACCES: 153 156 case -EPERM: 154 157 case -ENOKEY:
+7 -7
fs/cachefiles/daemon.c
··· 15 15 #include <linux/namei.h> 16 16 #include <linux/poll.h> 17 17 #include <linux/mount.h> 18 + #include <linux/security.h> 18 19 #include <linux/statfs.h> 19 20 #include <linux/ctype.h> 20 21 #include <linux/string.h> ··· 577 576 */ 578 577 static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args) 579 578 { 580 - char *secctx; 579 + int err; 581 580 582 581 _enter(",%s", args); 583 582 ··· 586 585 return -EINVAL; 587 586 } 588 587 589 - if (cache->secctx) { 588 + if (cache->have_secid) { 590 589 pr_err("Second security context specified\n"); 591 590 return -EINVAL; 592 591 } 593 592 594 - secctx = kstrdup(args, GFP_KERNEL); 595 - if (!secctx) 596 - return -ENOMEM; 593 + err = security_secctx_to_secid(args, strlen(args), &cache->secid); 594 + if (err) 595 + return err; 597 596 598 - cache->secctx = secctx; 597 + cache->have_secid = true; 599 598 return 0; 600 599 } 601 600 ··· 821 820 put_cred(cache->cache_cred); 822 821 823 822 kfree(cache->rootdirname); 824 - kfree(cache->secctx); 825 823 kfree(cache->tag); 826 824 827 825 _leave("");
+2 -1
fs/cachefiles/internal.h
··· 122 122 #define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ 123 123 #define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */ 124 124 char *rootdirname; /* name of cache root directory */ 125 - char *secctx; /* LSM security context */ 126 125 char *tag; /* cache binding tag */ 127 126 refcount_t unbind_pincount;/* refcount to do daemon unbind */ 128 127 struct xarray reqs; /* xarray of pending on-demand requests */ ··· 129 130 struct xarray ondemand_ids; /* xarray for ondemand_id allocation */ 130 131 u32 ondemand_id_next; 131 132 u32 msg_id_next; 133 + u32 secid; /* LSM security id */ 134 + bool have_secid; /* whether "secid" was set */ 132 135 }; 133 136 134 137 static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)
+3 -3
fs/cachefiles/security.c
··· 18 18 struct cred *new; 19 19 int ret; 20 20 21 - _enter("{%s}", cache->secctx); 21 + _enter("{%u}", cache->have_secid ? cache->secid : 0); 22 22 23 23 new = prepare_kernel_cred(current); 24 24 if (!new) { ··· 26 26 goto error; 27 27 } 28 28 29 - if (cache->secctx) { 30 - ret = set_security_override_from_ctx(new, cache->secctx); 29 + if (cache->have_secid) { 30 + ret = set_security_override(new, cache->secid); 31 31 if (ret < 0) { 32 32 put_cred(new); 33 33 pr_err("Security denies permission to nominate security context: error %d\n",
+16 -12
fs/netfs/buffered_read.c
··· 275 275 netfs_stat(&netfs_n_rh_download); 276 276 if (rreq->netfs_ops->prepare_read) { 277 277 ret = rreq->netfs_ops->prepare_read(subreq); 278 - if (ret < 0) { 279 - atomic_dec(&rreq->nr_outstanding); 280 - netfs_put_subrequest(subreq, false, 281 - netfs_sreq_trace_put_cancel); 282 - break; 283 - } 278 + if (ret < 0) 279 + goto prep_failed; 284 280 trace_netfs_sreq(subreq, netfs_sreq_trace_prepare); 285 281 } 286 282 287 283 slice = netfs_prepare_read_iterator(subreq); 288 - if (slice < 0) { 289 - atomic_dec(&rreq->nr_outstanding); 290 - netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel); 291 - ret = slice; 292 - break; 293 - } 284 + if (slice < 0) 285 + goto prep_iter_failed; 294 286 295 287 rreq->netfs_ops->issue_read(subreq); 296 288 goto done; ··· 294 302 trace_netfs_sreq(subreq, netfs_sreq_trace_submit); 295 303 netfs_stat(&netfs_n_rh_zero); 296 304 slice = netfs_prepare_read_iterator(subreq); 305 + if (slice < 0) 306 + goto prep_iter_failed; 297 307 __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags); 298 308 netfs_read_subreq_terminated(subreq, 0, false); 299 309 goto done; ··· 304 310 if (source == NETFS_READ_FROM_CACHE) { 305 311 trace_netfs_sreq(subreq, netfs_sreq_trace_submit); 306 312 slice = netfs_prepare_read_iterator(subreq); 313 + if (slice < 0) 314 + goto prep_iter_failed; 307 315 netfs_read_cache_to_pagecache(rreq, subreq); 308 316 goto done; 309 317 } 310 318 311 319 pr_err("Unexpected read source %u\n", source); 312 320 WARN_ON_ONCE(1); 321 + break; 322 + 323 + prep_iter_failed: 324 + ret = slice; 325 + prep_failed: 326 + subreq->error = ret; 327 + atomic_dec(&rreq->nr_outstanding); 328 + netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel); 313 329 break; 314 330 315 331 done:
-1
fs/netfs/direct_write.c
··· 104 104 trace_netfs_rreq(wreq, netfs_rreq_trace_wait_ip); 105 105 wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS, 106 106 TASK_UNINTERRUPTIBLE); 107 - smp_rmb(); /* Read error/transferred after RIP flag */ 108 107 ret = wreq->error; 109 108 if (ret == 0) { 110 109 ret = wreq->transferred;
+19 -14
fs/netfs/read_collect.c
··· 62 62 } else { 63 63 trace_netfs_folio(folio, netfs_folio_trace_read_done); 64 64 } 65 + 66 + folioq_clear(folioq, slot); 65 67 } else { 66 68 // TODO: Use of PG_private_2 is deprecated. 67 69 if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) 68 70 netfs_pgpriv2_mark_copy_to_cache(subreq, rreq, folioq, slot); 71 + else 72 + folioq_clear(folioq, slot); 69 73 } 70 74 71 75 if (!test_bit(NETFS_RREQ_DONT_UNLOCK_FOLIOS, &rreq->flags)) { ··· 81 77 folio_unlock(folio); 82 78 } 83 79 } 84 - 85 - folioq_clear(folioq, slot); 86 80 } 87 81 88 82 /* ··· 249 247 250 248 /* Deal with the trickiest case: that this subreq is in the middle of a 251 249 * folio, not touching either edge, but finishes first. In such a 252 - * case, we donate to the previous subreq, if there is one, so that the 253 - * donation is only handled when that completes - and remove this 254 - * subreq from the list. 250 + * case, we donate to the previous subreq, if there is one and if it is 251 + * contiguous, so that the donation is only handled when that completes 252 + * - and remove this subreq from the list. 255 253 * 256 254 * If the previous subreq finished first, we will have acquired their 257 255 * donation and should be able to unlock folios and/or donate nextwards. 258 256 */ 259 257 if (!subreq->consumed && 260 258 !prev_donated && 261 - !list_is_first(&subreq->rreq_link, &rreq->subrequests)) { 259 + !list_is_first(&subreq->rreq_link, &rreq->subrequests) && 260 + subreq->start == prev->start + prev->len) { 262 261 prev = list_prev_entry(subreq, rreq_link); 263 262 WRITE_ONCE(prev->next_donated, prev->next_donated + subreq->len); 264 263 subreq->start += subreq->len; ··· 381 378 task_io_account_read(rreq->transferred); 382 379 383 380 trace_netfs_rreq(rreq, netfs_rreq_trace_wake_ip); 384 - clear_bit_unlock(NETFS_RREQ_IN_PROGRESS, &rreq->flags); 385 - wake_up_bit(&rreq->flags, NETFS_RREQ_IN_PROGRESS); 381 + clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags); 386 382 387 383 trace_netfs_rreq(rreq, netfs_rreq_trace_done); 388 384 netfs_clear_subrequests(rreq, false); ··· 440 438 rreq->origin == NETFS_READPAGE || 441 439 rreq->origin == NETFS_READ_FOR_WRITE)) { 442 440 netfs_consume_read_data(subreq, was_async); 443 - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); 441 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 444 442 } 445 443 } 446 444 EXPORT_SYMBOL(netfs_read_subreq_progress); ··· 499 497 rreq->origin == NETFS_READPAGE || 500 498 rreq->origin == NETFS_READ_FOR_WRITE)) { 501 499 netfs_consume_read_data(subreq, was_async); 502 - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); 500 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 503 501 } 504 502 rreq->transferred += subreq->transferred; 505 503 } ··· 513 511 } else { 514 512 trace_netfs_sreq(subreq, netfs_sreq_trace_short); 515 513 if (subreq->transferred > subreq->consumed) { 516 - __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 517 - __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags); 518 - set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); 519 - } else if (!__test_and_set_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags)) { 514 + /* If we didn't read new data, abandon retry. */ 515 + if (subreq->retry_count && 516 + test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags)) { 517 + __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 518 + set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); 519 + } 520 + } else if (test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags)) { 520 521 __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 521 522 set_bit(NETFS_RREQ_NEED_RETRY, &rreq->flags); 522 523 } else {
+4
fs/netfs/read_pgpriv2.c
··· 170 170 171 171 trace_netfs_write(wreq, netfs_write_trace_copy_to_cache); 172 172 netfs_stat(&netfs_n_wh_copy_to_cache); 173 + if (!wreq->io_streams[1].avail) { 174 + netfs_put_request(wreq, false, netfs_rreq_trace_put_return); 175 + goto couldnt_start; 176 + } 173 177 174 178 for (;;) { 175 179 error = netfs_pgpriv2_copy_folio(wreq, folio);
+5 -3
fs/netfs/read_retry.c
··· 49 49 * up to the first permanently failed one. 50 50 */ 51 51 if (!rreq->netfs_ops->prepare_read && 52 - !test_bit(NETFS_RREQ_COPY_TO_CACHE, &rreq->flags)) { 52 + !rreq->cache_resources.ops) { 53 53 struct netfs_io_subrequest *subreq; 54 54 55 55 list_for_each_entry(subreq, &rreq->subrequests, rreq_link) { 56 56 if (test_bit(NETFS_SREQ_FAILED, &subreq->flags)) 57 57 break; 58 58 if (__test_and_clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) { 59 + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 60 + subreq->retry_count++; 59 61 netfs_reset_iter(subreq); 60 62 netfs_reissue_read(rreq, subreq); 61 63 } ··· 139 137 stream0->sreq_max_len = subreq->len; 140 138 141 139 __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 142 - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); 140 + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 141 + subreq->retry_count++; 143 142 144 143 spin_lock_bh(&rreq->lock); 145 144 list_add_tail(&subreq->rreq_link, &rreq->subrequests); ··· 216 213 subreq->error = -ENOMEM; 217 214 __clear_bit(NETFS_SREQ_FAILED, &subreq->flags); 218 215 __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 219 - __clear_bit(NETFS_SREQ_RETRYING, &subreq->flags); 220 216 } 221 217 spin_lock_bh(&rreq->lock); 222 218 list_splice_tail_init(&queue, &rreq->subrequests);
+5 -9
fs/netfs/write_collect.c
··· 179 179 struct iov_iter source = subreq->io_iter; 180 180 181 181 iov_iter_revert(&source, subreq->len - source.count); 182 - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); 183 182 netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit); 184 183 netfs_reissue_write(stream, subreq, &source); 185 184 } ··· 233 234 /* Renegotiate max_len (wsize) */ 234 235 trace_netfs_sreq(subreq, netfs_sreq_trace_retry); 235 236 __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); 236 - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); 237 + subreq->retry_count++; 237 238 stream->prepare_write(subreq); 238 239 239 240 part = min(len, stream->sreq_max_len); ··· 278 279 subreq->start = start; 279 280 subreq->debug_index = atomic_inc_return(&wreq->subreq_counter); 280 281 subreq->stream_nr = to->stream_nr; 281 - __set_bit(NETFS_SREQ_RETRYING, &subreq->flags); 282 + subreq->retry_count = 1; 282 283 283 284 trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index, 284 285 refcount_read(&subreq->ref), ··· 500 501 goto need_retry; 501 502 if ((notes & MADE_PROGRESS) && test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) { 502 503 trace_netfs_rreq(wreq, netfs_rreq_trace_unpause); 503 - clear_bit_unlock(NETFS_RREQ_PAUSE, &wreq->flags); 504 - wake_up_bit(&wreq->flags, NETFS_RREQ_PAUSE); 504 + clear_and_wake_up_bit(NETFS_RREQ_PAUSE, &wreq->flags); 505 505 } 506 506 507 507 if (notes & NEED_REASSESS) { ··· 603 605 604 606 _debug("finished"); 605 607 trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip); 606 - clear_bit_unlock(NETFS_RREQ_IN_PROGRESS, &wreq->flags); 607 - wake_up_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS); 608 + clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags); 608 609 609 610 if (wreq->iocb) { 610 611 size_t written = min(wreq->transferred, wreq->len); ··· 711 714 712 715 trace_netfs_sreq(subreq, netfs_sreq_trace_terminated); 713 716 714 - clear_bit_unlock(NETFS_SREQ_IN_PROGRESS, &subreq->flags); 715 - wake_up_bit(&subreq->flags, NETFS_SREQ_IN_PROGRESS); 717 + clear_and_wake_up_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); 716 718 717 719 /* If we are at the head of the queue, wake up the collector, 718 720 * transferring a ref to it if we were the ones to do so.
+2
fs/netfs/write_issue.c
··· 244 244 iov_iter_advance(source, size); 245 245 iov_iter_truncate(&subreq->io_iter, size); 246 246 247 + subreq->retry_count++; 248 + __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags); 247 249 __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); 248 250 netfs_do_issue_write(stream, subreq); 249 251 }
+8 -1
fs/nfs/fscache.c
··· 263 263 static atomic_t nfs_netfs_debug_id; 264 264 static int nfs_netfs_init_request(struct netfs_io_request *rreq, struct file *file) 265 265 { 266 + if (!file) { 267 + if (WARN_ON_ONCE(rreq->origin != NETFS_PGPRIV2_COPY_TO_CACHE)) 268 + return -EIO; 269 + return 0; 270 + } 271 + 266 272 rreq->netfs_priv = get_nfs_open_context(nfs_file_open_context(file)); 267 273 rreq->debug_id = atomic_inc_return(&nfs_netfs_debug_id); 268 274 /* [DEPRECATED] Use PG_private_2 to mark folio being written to the cache. */ ··· 280 274 281 275 static void nfs_netfs_free_request(struct netfs_io_request *rreq) 282 276 { 283 - put_nfs_open_context(rreq->netfs_priv); 277 + if (rreq->netfs_priv) 278 + put_nfs_open_context(rreq->netfs_priv); 284 279 } 285 280 286 281 static struct nfs_netfs_io_data *nfs_netfs_alloc(struct netfs_io_subrequest *sreq)
+9 -4
fs/smb/client/cifssmb.c
··· 1319 1319 } 1320 1320 1321 1321 if (rdata->result == -ENODATA) { 1322 - __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1323 1322 rdata->result = 0; 1323 + __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1324 1324 } else { 1325 1325 size_t trans = rdata->subreq.transferred + rdata->got_bytes; 1326 1326 if (trans < rdata->subreq.len && 1327 1327 rdata->subreq.start + trans == ictx->remote_i_size) { 1328 - __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1329 1328 rdata->result = 0; 1329 + __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1330 + } else if (rdata->got_bytes > 0) { 1331 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 1330 1332 } 1331 1333 } 1332 1334 ··· 1672 1670 if (written > wdata->subreq.len) 1673 1671 written &= 0xFFFF; 1674 1672 1675 - if (written < wdata->subreq.len) 1673 + if (written < wdata->subreq.len) { 1676 1674 result = -ENOSPC; 1677 - else 1675 + } else { 1678 1676 result = written; 1677 + if (written > 0) 1678 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); 1679 + } 1679 1680 break; 1680 1681 case MID_REQUEST_SUBMITTED: 1681 1682 case MID_RETRY_NEEDED:
+6 -3
fs/smb/client/smb2pdu.c
··· 4615 4615 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 4616 4616 rdata->result = 0; 4617 4617 } 4618 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 4618 4619 } 4619 4620 trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, 4620 4621 server->credits, server->in_flight, ··· 4841 4840 if (written > wdata->subreq.len) 4842 4841 written &= 0xFFFF; 4843 4842 4844 - if (written < wdata->subreq.len) 4843 + if (written < wdata->subreq.len) { 4845 4844 wdata->result = -ENOSPC; 4846 - else 4845 + } else if (written > 0) { 4847 4846 wdata->subreq.len = written; 4847 + __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); 4848 + } 4848 4849 break; 4849 4850 case MID_REQUEST_SUBMITTED: 4850 4851 case MID_RETRY_NEEDED: ··· 5015 5012 } 5016 5013 #endif 5017 5014 5018 - if (test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags)) 5015 + if (wdata->subreq.retry_count > 0) 5019 5016 smb2_set_replay(server, &rqst); 5020 5017 5021 5018 cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
+3 -4
include/linux/netfs.h
··· 185 185 short error; /* 0 or error that occurred */ 186 186 unsigned short debug_index; /* Index in list (for debugging output) */ 187 187 unsigned int nr_segs; /* Number of segs in io_iter */ 188 + u8 retry_count; /* The number of retries (0 on initial pass) */ 188 189 enum netfs_io_source source; /* Where to read from/write to */ 189 190 unsigned char stream_nr; /* I/O stream this belongs to */ 190 191 unsigned char curr_folioq_slot; /* Folio currently being read */ ··· 195 194 #define NETFS_SREQ_COPY_TO_CACHE 0 /* Set if should copy the data to the cache */ 196 195 #define NETFS_SREQ_CLEAR_TAIL 1 /* Set if the rest of the read should be cleared */ 197 196 #define NETFS_SREQ_SEEK_DATA_READ 3 /* Set if ->read() should SEEK_DATA first */ 198 - #define NETFS_SREQ_NO_PROGRESS 4 /* Set if we didn't manage to read any data */ 197 + #define NETFS_SREQ_MADE_PROGRESS 4 /* Set if we transferred at least some data */ 199 198 #define NETFS_SREQ_ONDEMAND 5 /* Set if it's from on-demand read mode */ 200 199 #define NETFS_SREQ_BOUNDARY 6 /* Set if ends on hard boundary (eg. ceph object) */ 201 200 #define NETFS_SREQ_HIT_EOF 7 /* Set if short due to EOF */ 202 201 #define NETFS_SREQ_IN_PROGRESS 8 /* Unlocked when the subrequest completes */ 203 202 #define NETFS_SREQ_NEED_RETRY 9 /* Set if the filesystem requests a retry */ 204 - #define NETFS_SREQ_RETRYING 10 /* Set if we're retrying */ 205 - #define NETFS_SREQ_FAILED 11 /* Set if the subreq failed unretryably */ 203 + #define NETFS_SREQ_FAILED 10 /* Set if the subreq failed unretryably */ 206 204 }; 207 205 208 206 enum netfs_io_origin { ··· 269 269 size_t prev_donated; /* Fallback for subreq->prev_donated */ 270 270 refcount_t ref; 271 271 unsigned long flags; 272 - #define NETFS_RREQ_COPY_TO_CACHE 1 /* Need to write to the cache */ 273 272 #define NETFS_RREQ_NO_UNLOCK_FOLIO 2 /* Don't unlock no_unlock_folio on completion */ 274 273 #define NETFS_RREQ_DONT_UNLOCK_FOLIOS 3 /* Don't unlock the folios on completion */ 275 274 #define NETFS_RREQ_FAILED 4 /* The request failed */
+1
kernel/gen_kheaders.sh
··· 89 89 90 90 # Create archive and try to normalize metadata for reproducibility. 91 91 tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ 92 + --exclude=".__afs*" --exclude=".nfs*" \ 92 93 --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \ 93 94 -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null 94 95