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

Merge tag 'nfs-for-6.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull nfs client updates from Anna Schumaker:
"New Features:
- Always ask for type with READDIR
- Remove nfs_writepage()

Bugfixes:
- Fix a suspicious RCU usage warning
- Fix a blocklayoutdriver reference leak
- Fix the block driver's calculation of layoutget size
- Fix handling NFS4ERR_RETURNCONFLICT
- Fix _xprt_switch_find_current_entry()
- Fix v4.1 backchannel request timeouts
- Don't add zero-length pnfs block devices
- Use the parent cred in nfs_access_login_time()

Cleanups:
- A few improvements when dealing with referring calls from the
server
- Clean up various unused variables, struct fields, and function
calls
- Various tracepoint improvements"

* tag 'nfs-for-6.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (21 commits)
NFSv4.1: Use the nfs_client's rpc timeouts for backchannel
SUNRPC: Fixup v4.1 backchannel request timeouts
rpc_pipefs: Replace one label in bl_resolve_deviceid()
nfs: Remove writepage
NFS: drop unused nfs_direct_req bytes_left
pNFS: Fix the pnfs block driver's calculation of layoutget size
nfs: print fileid in lookup tracepoints
nfs: rename the nfs_async_rename_done tracepoint
nfs: add new tracepoint at nfs4 revalidate entry point
SUNRPC: fix _xprt_switch_find_current_entry logic
NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT
NFSv4.1: if referring calls are complete, trust the stateid argument
NFSv4: Track the number of referring calls in struct cb_process_state
NFS: Use parent's objective cred in nfs_access_login_time()
NFSv4: Always ask for type with READDIR
pnfs/blocklayout: Don't add zero-length pnfs_block_dev
blocklayoutdriver: Fix reference leak of pnfs_device_node
SUNRPC: Fix a suspicious RCU usage warning
SUNRPC: Create a helper function for accessing the rpc_clnt's xprt_switch
SUNRPC: Remove unused function rpc_clnt_xprt_switch_put()
...

+183 -125
+4 -3
fs/nfs/blocklayout/blocklayout.c
··· 580 580 nfs4_delete_deviceid(node->ld, node->nfs_client, id); 581 581 goto retry; 582 582 } 583 + 584 + nfs4_put_deviceid_node(node); 583 585 return ERR_PTR(-ENODEV); 584 586 } 585 587 ··· 895 893 } 896 894 897 895 if (pgio->pg_dreq == NULL) 898 - wb_size = pnfs_num_cont_bytes(pgio->pg_inode, 899 - req->wb_index); 896 + wb_size = pnfs_num_cont_bytes(pgio->pg_inode, req->wb_index); 900 897 else 901 - wb_size = nfs_dreq_bytes_left(pgio->pg_dreq); 898 + wb_size = nfs_dreq_bytes_left(pgio->pg_dreq, req_offset(req)); 902 899 903 900 pnfs_generic_pg_init_write(pgio, req, wb_size); 904 901
+3
fs/nfs/blocklayout/dev.c
··· 351 351 d->map = bl_map_simple; 352 352 d->pr_key = v->scsi.pr_key; 353 353 354 + if (d->len == 0) 355 + return -ENODEV; 356 + 354 357 pr_info("pNFS: using block device %s (reservation key 0x%llx)\n", 355 358 d->bdev_handle->bdev->bd_disk->disk_name, d->pr_key); 356 359
+1 -1
fs/nfs/blocklayout/rpc_pipefs.c
··· 75 75 msg->len = sizeof(*bl_msg) + b->simple.len; 76 76 msg->data = kzalloc(msg->len, gfp_mask); 77 77 if (!msg->data) 78 - goto out_free_data; 78 + goto out_unlock; 79 79 80 80 bl_msg = msg->data; 81 81 bl_msg->type = BL_DEVICE_MOUNT;
+3 -2
fs/nfs/callback.h
··· 21 21 22 22 struct nfs4_slot; 23 23 struct cb_process_state { 24 - __be32 drc_status; 25 24 struct nfs_client *clp; 26 25 struct nfs4_slot *slot; 27 - u32 minorversion; 28 26 struct net *net; 27 + u32 minorversion; 28 + __be32 drc_status; 29 + unsigned int referring_calls; 29 30 }; 30 31 31 32 struct cb_compound_hdr_arg {
+34 -25
fs/nfs/callback_proc.c
··· 207 207 * Enforce RFC5661 section 12.5.5.2.1. (Layout Recall and Return Sequencing) 208 208 */ 209 209 static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo, 210 - const nfs4_stateid *new) 210 + const nfs4_stateid *new, 211 + struct cb_process_state *cps) 211 212 { 212 213 u32 oldseq, newseq; 213 214 ··· 222 221 223 222 newseq = be32_to_cpu(new->seqid); 224 223 /* Are we already in a layout recall situation? */ 225 - if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) && 226 - lo->plh_return_seq != 0) { 227 - if (newseq < lo->plh_return_seq) 228 - return NFS4ERR_OLD_STATEID; 229 - if (newseq > lo->plh_return_seq) 230 - return NFS4ERR_DELAY; 231 - goto out; 232 - } 233 - 234 - /* Check that the stateid matches what we think it should be. */ 235 - oldseq = be32_to_cpu(lo->plh_stateid.seqid); 236 - if (newseq > oldseq + 1) 224 + if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) 237 225 return NFS4ERR_DELAY; 226 + 227 + /* 228 + * Check that the stateid matches what we think it should be. 229 + * Note that if the server sent us a list of referring calls, 230 + * and we know that those have completed, then we trust the 231 + * stateid argument is correct. 232 + */ 233 + oldseq = be32_to_cpu(lo->plh_stateid.seqid); 234 + if (newseq > oldseq + 1 && !cps->referring_calls) 235 + return NFS4ERR_DELAY; 236 + 238 237 /* Crazy server! */ 239 238 if (newseq <= oldseq) 240 239 return NFS4ERR_OLD_STATEID; 241 - out: 240 + 242 241 return NFS_OK; 243 242 } 244 243 245 244 static u32 initiate_file_draining(struct nfs_client *clp, 246 - struct cb_layoutrecallargs *args) 245 + struct cb_layoutrecallargs *args, 246 + struct cb_process_state *cps) 247 247 { 248 248 struct inode *ino; 249 249 struct pnfs_layout_hdr *lo; ··· 268 266 goto out; 269 267 } 270 268 pnfs_get_layout_hdr(lo); 271 - rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid); 269 + rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid, cps); 272 270 if (rv != NFS_OK) 273 271 goto unlock; 274 272 ··· 328 326 } 329 327 330 328 static u32 do_callback_layoutrecall(struct nfs_client *clp, 331 - struct cb_layoutrecallargs *args) 329 + struct cb_layoutrecallargs *args, 330 + struct cb_process_state *cps) 332 331 { 333 332 if (args->cbl_recall_type == RETURN_FILE) 334 - return initiate_file_draining(clp, args); 333 + return initiate_file_draining(clp, args, cps); 335 334 return initiate_bulk_draining(clp, args); 336 335 } 337 336 ··· 343 340 u32 res = NFS4ERR_OP_NOT_IN_SESSION; 344 341 345 342 if (cps->clp) 346 - res = do_callback_layoutrecall(cps->clp, args); 343 + res = do_callback_layoutrecall(cps->clp, args, cps); 347 344 return cpu_to_be32(res); 348 345 } 349 346 350 - static void pnfs_recall_all_layouts(struct nfs_client *clp) 347 + static void pnfs_recall_all_layouts(struct nfs_client *clp, 348 + struct cb_process_state *cps) 351 349 { 352 350 struct cb_layoutrecallargs args; 353 351 ··· 356 352 memset(&args, 0, sizeof(args)); 357 353 args.cbl_recall_type = RETURN_ALL; 358 354 /* FIXME we ignore errors, what should we do? */ 359 - do_callback_layoutrecall(clp, &args); 355 + do_callback_layoutrecall(clp, &args, cps); 360 356 } 361 357 362 358 __be32 nfs4_callback_devicenotify(void *argp, void *resp, ··· 454 450 __acquires(lock) 455 451 { 456 452 int status = 0; 453 + int found = 0; 457 454 int i, j; 458 455 struct nfs4_session *session; 459 456 struct nfs4_slot_table *tbl; ··· 483 478 spin_lock(lock); 484 479 if (status) 485 480 goto out; 481 + found++; 486 482 } 487 483 } 488 484 489 485 out: 490 - return status; 486 + return status < 0 ? status : found; 491 487 } 492 488 493 489 __be32 nfs4_callback_sequence(void *argp, void *resp, ··· 499 493 struct nfs4_slot_table *tbl; 500 494 struct nfs4_slot *slot; 501 495 struct nfs_client *clp; 496 + int ret; 502 497 int i; 503 498 __be32 status = htonl(NFS4ERR_BADSESSION); 504 499 ··· 559 552 * related callback was received before the response to the original 560 553 * call. 561 554 */ 562 - if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists, 563 - &tbl->slot_tbl_lock) < 0) { 555 + ret = referring_call_exists(clp, args->csa_nrclists, args->csa_rclists, 556 + &tbl->slot_tbl_lock); 557 + if (ret < 0) { 564 558 status = htonl(NFS4ERR_DELAY); 565 559 goto out_unlock; 566 560 } 561 + cps->referring_calls = ret; 567 562 568 563 /* 569 564 * RFC5661 20.9.3 ··· 626 617 nfs_expire_unused_delegation_types(cps->clp, flags); 627 618 628 619 if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_FILE_LAYOUT)) 629 - pnfs_recall_all_layouts(cps->clp); 620 + pnfs_recall_all_layouts(cps->clp, cps); 630 621 631 622 if (args->craa_type_mask & BIT(PNFS_FF_RCA4_TYPE_MASK_READ)) { 632 623 set_bit(NFS4CLNT_RECALL_ANY_LAYOUT_READ, &cps->clp->cl_state);
+5
fs/nfs/callback_xdr.c
··· 967 967 nops--; 968 968 } 969 969 970 + if (svc_is_backchannel(rqstp) && cps.clp) { 971 + rqstp->bc_to_initval = cps.clp->cl_rpcclient->cl_timeout->to_initval; 972 + rqstp->bc_to_retries = cps.clp->cl_rpcclient->cl_timeout->to_retries; 973 + } 974 + 970 975 *hdr_res.status = status; 971 976 *hdr_res.nops = htonl(nops); 972 977 nfs4_cb_free_slot(&cps);
+3 -1
fs/nfs/dir.c
··· 2194 2194 { 2195 2195 struct inode *inode; 2196 2196 2197 + trace_nfs_lookup_revalidate_enter(dir, dentry, flags); 2198 + 2197 2199 if (!(flags & LOOKUP_OPEN) || (flags & LOOKUP_DIRECTORY)) 2198 2200 goto full_reval; 2199 2201 if (d_mountpoint(dentry)) ··· 2965 2963 rcu_read_lock(); 2966 2964 for (;;) { 2967 2965 parent = rcu_dereference(task->real_parent); 2968 - pcred = rcu_dereference(parent->cred); 2966 + pcred = __task_cred(parent); 2969 2967 if (parent == task || cred_fscmp(pcred, cred) != 0) 2970 2968 break; 2971 2969 task = parent;
+5 -6
fs/nfs/direct.c
··· 205 205 kref_put(&dreq->kref, nfs_direct_req_free); 206 206 } 207 207 208 - ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq) 208 + ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset) 209 209 { 210 - return dreq->bytes_left; 210 + loff_t start = offset - dreq->io_start; 211 + return dreq->max_count - start; 211 212 } 212 213 EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); 213 214 ··· 369 368 bytes -= req_len; 370 369 requested_bytes += req_len; 371 370 pos += req_len; 372 - dreq->bytes_left -= req_len; 373 371 } 374 372 nfs_direct_release_pages(pagevec, npages); 375 373 kvfree(pagevec); ··· 440 440 goto out; 441 441 442 442 dreq->inode = inode; 443 - dreq->bytes_left = dreq->max_count = count; 443 + dreq->max_count = count; 444 444 dreq->io_start = iocb->ki_pos; 445 445 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 446 446 l_ctx = nfs_get_lock_context(dreq->ctx); ··· 873 873 bytes -= req_len; 874 874 requested_bytes += req_len; 875 875 pos += req_len; 876 - dreq->bytes_left -= req_len; 877 876 878 877 if (defer) { 879 878 nfs_mark_request_commit(req, NULL, &cinfo, 0); ··· 979 980 goto out; 980 981 981 982 dreq->inode = inode; 982 - dreq->bytes_left = dreq->max_count = count; 983 + dreq->max_count = count; 983 984 dreq->io_start = pos; 984 985 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 985 986 l_ctx = nfs_get_lock_context(dreq->ctx);
-1
fs/nfs/file.c
··· 558 558 .read_folio = nfs_read_folio, 559 559 .readahead = nfs_readahead, 560 560 .dirty_folio = filemap_dirty_folio, 561 - .writepage = nfs_writepage, 562 561 .writepages = nfs_writepages, 563 562 .write_begin = nfs_write_begin, 564 563 .write_end = nfs_write_end,
+1 -2
fs/nfs/internal.h
··· 655 655 /* direct.c */ 656 656 void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, 657 657 struct nfs_direct_req *dreq); 658 - extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); 658 + extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset); 659 659 660 660 /* nfs4proc.c */ 661 661 extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, ··· 936 936 loff_t io_start; /* Start offset for I/O */ 937 937 ssize_t count, /* bytes actually processed */ 938 938 max_count, /* max expected count */ 939 - bytes_left, /* bytes left to be sent */ 940 939 error; /* any reported error */ 941 940 struct completion completion; /* wait for i/o completion */ 942 941
+3
fs/nfs/nfs4proc.c
··· 170 170 case -NFS4ERR_RESOURCE: 171 171 case -NFS4ERR_LAYOUTTRYLATER: 172 172 case -NFS4ERR_RECALLCONFLICT: 173 + case -NFS4ERR_RETURNCONFLICT: 173 174 return -EREMOTEIO; 174 175 case -NFS4ERR_WRONGSEC: 175 176 case -NFS4ERR_WRONG_CRED: ··· 559 558 case -NFS4ERR_GRACE: 560 559 case -NFS4ERR_LAYOUTTRYLATER: 561 560 case -NFS4ERR_RECALLCONFLICT: 561 + case -NFS4ERR_RETURNCONFLICT: 562 562 exception->delay = 1; 563 563 return 0; 564 564 ··· 9693 9691 status = -EBUSY; 9694 9692 break; 9695 9693 case -NFS4ERR_RECALLCONFLICT: 9694 + case -NFS4ERR_RETURNCONFLICT: 9696 9695 status = -ERECALLCONFLICT; 9697 9696 break; 9698 9697 case -NFS4ERR_DELEG_REVOKED:
+16 -7
fs/nfs/nfs4xdr.c
··· 1602 1602 static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1603 1603 { 1604 1604 uint32_t attrs[3] = { 1605 - FATTR4_WORD0_RDATTR_ERROR, 1605 + FATTR4_WORD0_TYPE 1606 + | FATTR4_WORD0_RDATTR_ERROR, 1606 1607 FATTR4_WORD1_MOUNTED_ON_FILEID, 1607 1608 }; 1608 1609 uint32_t dircount = readdir->count; ··· 1613 1612 unsigned int i; 1614 1613 1615 1614 if (readdir->plus) { 1616 - attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| 1617 - FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID; 1618 - attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| 1619 - FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 1620 - FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 1621 - FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 1615 + attrs[0] |= FATTR4_WORD0_CHANGE 1616 + | FATTR4_WORD0_SIZE 1617 + | FATTR4_WORD0_FSID 1618 + | FATTR4_WORD0_FILEHANDLE 1619 + | FATTR4_WORD0_FILEID; 1620 + attrs[1] |= FATTR4_WORD1_MODE 1621 + | FATTR4_WORD1_NUMLINKS 1622 + | FATTR4_WORD1_OWNER 1623 + | FATTR4_WORD1_OWNER_GROUP 1624 + | FATTR4_WORD1_RAWDEV 1625 + | FATTR4_WORD1_SPACE_USED 1626 + | FATTR4_WORD1_TIME_ACCESS 1627 + | FATTR4_WORD1_TIME_METADATA 1628 + | FATTR4_WORD1_TIME_MODIFY; 1622 1629 attrs[2] |= FATTR4_WORD2_SECURITY_LABEL; 1623 1630 } 1624 1631 /* Use mounted_on_fileid only if the server supports it */
+13 -9
fs/nfs/nfstrace.h
··· 400 400 __field(unsigned long, flags) 401 401 __field(dev_t, dev) 402 402 __field(u64, dir) 403 + __field(u64, fileid) 403 404 __string(name, dentry->d_name.name) 404 405 ), 405 406 ··· 408 407 __entry->dev = dir->i_sb->s_dev; 409 408 __entry->dir = NFS_FILEID(dir); 410 409 __entry->flags = flags; 410 + __entry->fileid = d_is_negative(dentry) ? 0 : NFS_FILEID(d_inode(dentry)); 411 411 __assign_str(name, dentry->d_name.name); 412 412 ), 413 413 414 414 TP_printk( 415 - "flags=0x%lx (%s) name=%02x:%02x:%llu/%s", 415 + "flags=0x%lx (%s) name=%02x:%02x:%llu/%s fileid=%llu", 416 416 __entry->flags, 417 417 show_fs_lookup_flags(__entry->flags), 418 418 MAJOR(__entry->dev), MINOR(__entry->dev), 419 419 (unsigned long long)__entry->dir, 420 - __get_str(name) 420 + __get_str(name), 421 + __entry->fileid 421 422 ) 422 423 ); 423 424 ··· 447 444 __field(unsigned long, flags) 448 445 __field(dev_t, dev) 449 446 __field(u64, dir) 447 + __field(u64, fileid) 450 448 __string(name, dentry->d_name.name) 451 449 ), 452 450 ··· 456 452 __entry->dir = NFS_FILEID(dir); 457 453 __entry->error = error < 0 ? -error : 0; 458 454 __entry->flags = flags; 455 + __entry->fileid = d_is_negative(dentry) ? 0 : NFS_FILEID(d_inode(dentry)); 459 456 __assign_str(name, dentry->d_name.name); 460 457 ), 461 458 462 459 TP_printk( 463 - "error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s", 460 + "error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s fileid=%llu", 464 461 -__entry->error, show_nfs_status(__entry->error), 465 462 __entry->flags, 466 463 show_fs_lookup_flags(__entry->flags), 467 464 MAJOR(__entry->dev), MINOR(__entry->dev), 468 465 (unsigned long long)__entry->dir, 469 - __get_str(name) 466 + __get_str(name), 467 + __entry->fileid 470 468 ) 471 469 ); 472 470 ··· 899 893 DEFINE_NFS_RENAME_EVENT(nfs_rename_enter); 900 894 DEFINE_NFS_RENAME_EVENT_DONE(nfs_rename_exit); 901 895 902 - DEFINE_NFS_RENAME_EVENT_DONE(nfs_sillyrename_rename); 896 + DEFINE_NFS_RENAME_EVENT_DONE(nfs_async_rename_done); 903 897 904 898 TRACE_EVENT(nfs_sillyrename_unlink, 905 899 TP_PROTO( ··· 1545 1539 __field(u32, fhandle) 1546 1540 __field(loff_t, offset) 1547 1541 __field(ssize_t, count) 1548 - __field(ssize_t, bytes_left) 1549 1542 __field(ssize_t, error) 1550 1543 __field(int, flags) 1551 1544 ), ··· 1559 1554 __entry->fhandle = nfs_fhandle_hash(fh); 1560 1555 __entry->offset = dreq->io_start; 1561 1556 __entry->count = dreq->count; 1562 - __entry->bytes_left = dreq->bytes_left; 1563 1557 __entry->error = dreq->error; 1564 1558 __entry->flags = dreq->flags; 1565 1559 ), 1566 1560 1567 1561 TP_printk( 1568 1562 "error=%zd fileid=%02x:%02x:%llu fhandle=0x%08x " 1569 - "offset=%lld count=%zd bytes_left=%zd flags=%s", 1563 + "offset=%lld count=%zd flags=%s", 1570 1564 __entry->error, MAJOR(__entry->dev), 1571 1565 MINOR(__entry->dev), 1572 1566 (unsigned long long)__entry->fileid, 1573 1567 __entry->fhandle, __entry->offset, 1574 - __entry->count, __entry->bytes_left, 1568 + __entry->count, 1575 1569 nfs_show_direct_req_flags(__entry->flags) 1576 1570 ) 1577 1571 );
+2 -1
fs/nfs/pnfs.c
··· 2733 2733 if (pgio->pg_dreq == NULL) 2734 2734 rd_size = i_size_read(pgio->pg_inode) - req_offset(req); 2735 2735 else 2736 - rd_size = nfs_dreq_bytes_left(pgio->pg_dreq); 2736 + rd_size = nfs_dreq_bytes_left(pgio->pg_dreq, 2737 + req_offset(req)); 2737 2738 2738 2739 pgio->pg_lseg = 2739 2740 pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
+1 -1
fs/nfs/unlink.c
··· 267 267 struct inode *new_dir = data->new_dir; 268 268 struct dentry *old_dentry = data->old_dentry; 269 269 270 - trace_nfs_sillyrename_rename(old_dir, old_dentry, 270 + trace_nfs_async_rename_done(old_dir, old_dentry, 271 271 new_dir, data->new_dentry, task->tk_status); 272 272 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { 273 273 rpc_restart_call_prepare(task);
-11
fs/nfs/write.c
··· 680 680 return err; 681 681 } 682 682 683 - int nfs_writepage(struct page *page, struct writeback_control *wbc) 684 - { 685 - struct folio *folio = page_folio(page); 686 - int ret; 687 - 688 - ret = nfs_writepage_locked(folio, wbc); 689 - if (ret != AOP_WRITEPAGE_ACTIVATE) 690 - unlock_page(page); 691 - return ret; 692 - } 693 - 694 683 static int nfs_writepages_callback(struct folio *folio, 695 684 struct writeback_control *wbc, void *data) 696 685 {
-1
include/linux/nfs_fs.h
··· 595 595 * linux/fs/nfs/write.c 596 596 */ 597 597 extern int nfs_congestion_kb; 598 - extern int nfs_writepage(struct page *page, struct writeback_control *wbc); 599 598 extern int nfs_writepages(struct address_space *, struct writeback_control *); 600 599 extern int nfs_flush_incompatible(struct file *file, struct folio *folio); 601 600 extern int nfs_update_folio(struct file *file, struct folio *folio,
+2 -1
include/linux/sunrpc/bc_xprt.h
··· 20 20 #ifdef CONFIG_SUNRPC_BACKCHANNEL 21 21 struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid); 22 22 void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied); 23 - void xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task); 23 + void xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task, 24 + const struct rpc_timeout *to); 24 25 void xprt_free_bc_request(struct rpc_rqst *req); 25 26 int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); 26 27 void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
-1
include/linux/sunrpc/clnt.h
··· 252 252 253 253 const char *rpc_proc_name(const struct rpc_task *task); 254 254 255 - void rpc_clnt_xprt_switch_put(struct rpc_clnt *); 256 255 void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *); 257 256 void rpc_clnt_xprt_switch_remove_xprt(struct rpc_clnt *, struct rpc_xprt *); 258 257 bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
+13 -1
include/linux/sunrpc/sched.h
··· 38 38 }; 39 39 40 40 /* 41 + * This describes a timeout strategy 42 + */ 43 + struct rpc_timeout { 44 + unsigned long to_initval, /* initial timeout */ 45 + to_maxval, /* max timeout */ 46 + to_increment; /* if !exponential */ 47 + unsigned int to_retries; /* max # of retries */ 48 + unsigned char to_exponential; 49 + }; 50 + 51 + /* 41 52 * This is the RPC task struct 42 53 */ 43 54 struct rpc_task { ··· 216 205 */ 217 206 struct rpc_task *rpc_new_task(const struct rpc_task_setup *); 218 207 struct rpc_task *rpc_run_task(const struct rpc_task_setup *); 219 - struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req); 208 + struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, 209 + struct rpc_timeout *timeout); 220 210 void rpc_put_task(struct rpc_task *); 221 211 void rpc_put_task_async(struct rpc_task *); 222 212 bool rpc_task_set_rpc_status(struct rpc_task *task, int rpc_status);
+2
include/linux/sunrpc/svc.h
··· 231 231 struct net *rq_bc_net; /* pointer to backchannel's 232 232 * net namespace 233 233 */ 234 + unsigned long bc_to_initval; 235 + unsigned int bc_to_retries; 234 236 void ** rq_lease_breaker; /* The v4 client breaking a lease */ 235 237 unsigned int rq_status_counter; /* RPC processing counter */ 236 238 };
-11
include/linux/sunrpc/xprt.h
··· 30 30 #define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT) 31 31 #define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd) 32 32 33 - /* 34 - * This describes a timeout strategy 35 - */ 36 - struct rpc_timeout { 37 - unsigned long to_initval, /* initial timeout */ 38 - to_maxval, /* max timeout */ 39 - to_increment; /* if !exponential */ 40 - unsigned int to_retries; /* max # of retries */ 41 - unsigned char to_exponential; 42 - }; 43 - 44 33 enum rpc_display_format_t { 45 34 RPC_DISPLAY_ADDR = 0, 46 35 RPC_DISPLAY_PORT,
+25 -26
net/sunrpc/clnt.c
··· 803 803 } 804 804 EXPORT_SYMBOL_GPL(rpc_switch_client_transport); 805 805 806 - static 807 - int _rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi, 808 - void func(struct rpc_xprt_iter *xpi, struct rpc_xprt_switch *xps)) 806 + static struct rpc_xprt_switch *rpc_clnt_xprt_switch_get(struct rpc_clnt *clnt) 809 807 { 810 808 struct rpc_xprt_switch *xps; 811 809 812 810 rcu_read_lock(); 813 811 xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); 814 812 rcu_read_unlock(); 813 + 814 + return xps; 815 + } 816 + 817 + static 818 + int _rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi, 819 + void func(struct rpc_xprt_iter *xpi, struct rpc_xprt_switch *xps)) 820 + { 821 + struct rpc_xprt_switch *xps; 822 + 823 + xps = rpc_clnt_xprt_switch_get(clnt); 815 824 if (xps == NULL) 816 825 return -EAGAIN; 817 826 func(xpi, xps); ··· 1317 1308 * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run 1318 1309 * rpc_execute against it 1319 1310 * @req: RPC request 1311 + * @timeout: timeout values to use for this task 1320 1312 */ 1321 - struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req) 1313 + struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, 1314 + struct rpc_timeout *timeout) 1322 1315 { 1323 1316 struct rpc_task *task; 1324 1317 struct rpc_task_setup task_setup_data = { ··· 1339 1328 return task; 1340 1329 } 1341 1330 1342 - xprt_init_bc_request(req, task); 1331 + xprt_init_bc_request(req, task, timeout); 1343 1332 1344 1333 task->tk_action = call_bc_encode; 1345 1334 atomic_inc(&task->tk_count); ··· 2223 2212 struct rpc_xprt *saved = task->tk_xprt; 2224 2213 struct rpc_xprt_switch *xps; 2225 2214 2226 - rcu_read_lock(); 2227 - xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); 2228 - rcu_read_unlock(); 2215 + xps = rpc_clnt_xprt_switch_get(clnt); 2229 2216 if (xps->xps_nxprts > 1) { 2230 2217 long value; 2231 2218 ··· 3131 3122 struct rpc_xprt *xprt, 3132 3123 struct rpc_add_xprt_test *data) 3133 3124 { 3134 - struct rpc_xprt_switch *xps; 3135 3125 struct rpc_xprt *main_xprt; 3136 3126 int status = 0; 3137 3127 ··· 3138 3130 3139 3131 rcu_read_lock(); 3140 3132 main_xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); 3141 - xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); 3142 3133 status = rpc_cmp_addr_port((struct sockaddr *)&xprt->addr, 3143 3134 (struct sockaddr *)&main_xprt->addr); 3144 3135 rcu_read_unlock(); ··· 3148 3141 status = rpc_clnt_add_xprt_helper(clnt, xprt, data); 3149 3142 out: 3150 3143 xprt_put(xprt); 3151 - xprt_switch_put(xps); 3152 3144 return status; 3153 3145 } 3154 3146 ··· 3262 3256 } 3263 3257 EXPORT_SYMBOL_GPL(rpc_set_connect_timeout); 3264 3258 3265 - void rpc_clnt_xprt_switch_put(struct rpc_clnt *clnt) 3266 - { 3267 - rcu_read_lock(); 3268 - xprt_switch_put(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); 3269 - rcu_read_unlock(); 3270 - } 3271 - EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_put); 3272 - 3273 3259 void rpc_clnt_xprt_set_online(struct rpc_clnt *clnt, struct rpc_xprt *xprt) 3274 3260 { 3275 3261 struct rpc_xprt_switch *xps; 3276 3262 3277 - rcu_read_lock(); 3278 - xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); 3279 - rcu_read_unlock(); 3263 + xps = rpc_clnt_xprt_switch_get(clnt); 3280 3264 xprt_set_online_locked(xprt, xps); 3265 + xprt_switch_put(xps); 3281 3266 } 3282 3267 3283 3268 void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt) 3284 3269 { 3270 + struct rpc_xprt_switch *xps; 3271 + 3285 3272 if (rpc_clnt_xprt_switch_has_addr(clnt, 3286 3273 (const struct sockaddr *)&xprt->addr)) { 3287 3274 return rpc_clnt_xprt_set_online(clnt, xprt); 3288 3275 } 3289 - rcu_read_lock(); 3290 - rpc_xprt_switch_add_xprt(rcu_dereference(clnt->cl_xpi.xpi_xpswitch), 3291 - xprt); 3292 - rcu_read_unlock(); 3276 + 3277 + xps = rpc_clnt_xprt_switch_get(clnt); 3278 + rpc_xprt_switch_add_xprt(xps, xprt); 3279 + xprt_switch_put(xps); 3293 3280 } 3294 3281 EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt); 3295 3282
+10 -1
net/sunrpc/svc.c
··· 1550 1550 { 1551 1551 struct rpc_task *task; 1552 1552 int proc_error; 1553 + struct rpc_timeout timeout; 1553 1554 1554 1555 /* Build the svc_rqst used by the common processing routine */ 1555 1556 rqstp->rq_xid = req->rq_xid; ··· 1596 1595 return; 1597 1596 } 1598 1597 /* Finally, send the reply synchronously */ 1598 + if (rqstp->bc_to_initval > 0) { 1599 + timeout.to_initval = rqstp->bc_to_initval; 1600 + timeout.to_retries = rqstp->bc_to_initval; 1601 + } else { 1602 + timeout.to_initval = req->rq_xprt->timeout->to_initval; 1603 + timeout.to_initval = req->rq_xprt->timeout->to_retries; 1604 + } 1599 1605 memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf)); 1600 - task = rpc_run_bc_task(req); 1606 + task = rpc_run_bc_task(req, &timeout); 1607 + 1601 1608 if (IS_ERR(task)) 1602 1609 return; 1603 1610
+21 -10
net/sunrpc/xprt.c
··· 651 651 jiffies + nsecs_to_jiffies(-delta); 652 652 } 653 653 654 - static unsigned long xprt_calc_majortimeo(struct rpc_rqst *req) 654 + static unsigned long xprt_calc_majortimeo(struct rpc_rqst *req, 655 + const struct rpc_timeout *to) 655 656 { 656 - const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout; 657 657 unsigned long majortimeo = req->rq_timeout; 658 658 659 659 if (to->to_exponential) ··· 665 665 return majortimeo; 666 666 } 667 667 668 - static void xprt_reset_majortimeo(struct rpc_rqst *req) 668 + static void xprt_reset_majortimeo(struct rpc_rqst *req, 669 + const struct rpc_timeout *to) 669 670 { 670 - req->rq_majortimeo += xprt_calc_majortimeo(req); 671 + req->rq_majortimeo += xprt_calc_majortimeo(req, to); 671 672 } 672 673 673 674 static void xprt_reset_minortimeo(struct rpc_rqst *req) ··· 676 675 req->rq_minortimeo += req->rq_timeout; 677 676 } 678 677 679 - static void xprt_init_majortimeo(struct rpc_task *task, struct rpc_rqst *req) 678 + static void xprt_init_majortimeo(struct rpc_task *task, struct rpc_rqst *req, 679 + const struct rpc_timeout *to) 680 680 { 681 681 unsigned long time_init; 682 682 struct rpc_xprt *xprt = req->rq_xprt; ··· 686 684 time_init = jiffies; 687 685 else 688 686 time_init = xprt_abs_ktime_to_jiffies(task->tk_start); 689 - req->rq_timeout = task->tk_client->cl_timeout->to_initval; 690 - req->rq_majortimeo = time_init + xprt_calc_majortimeo(req); 687 + 688 + req->rq_timeout = to->to_initval; 689 + req->rq_majortimeo = time_init + xprt_calc_majortimeo(req, to); 691 690 req->rq_minortimeo = time_init + req->rq_timeout; 692 691 } 693 692 ··· 716 713 } else { 717 714 req->rq_timeout = to->to_initval; 718 715 req->rq_retries = 0; 719 - xprt_reset_majortimeo(req); 716 + xprt_reset_majortimeo(req, to); 720 717 /* Reset the RTT counters == "slow start" */ 721 718 spin_lock(&xprt->transport_lock); 722 719 rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval); ··· 1889 1886 req->rq_snd_buf.bvec = NULL; 1890 1887 req->rq_rcv_buf.bvec = NULL; 1891 1888 req->rq_release_snd_buf = NULL; 1892 - xprt_init_majortimeo(task, req); 1889 + xprt_init_majortimeo(task, req, task->tk_client->cl_timeout); 1893 1890 1894 1891 trace_xprt_reserve(req); 1895 1892 } ··· 1986 1983 1987 1984 #ifdef CONFIG_SUNRPC_BACKCHANNEL 1988 1985 void 1989 - xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task) 1986 + xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task, 1987 + const struct rpc_timeout *to) 1990 1988 { 1991 1989 struct xdr_buf *xbufp = &req->rq_snd_buf; 1992 1990 ··· 2000 1996 */ 2001 1997 xbufp->len = xbufp->head[0].iov_len + xbufp->page_len + 2002 1998 xbufp->tail[0].iov_len; 1999 + /* 2000 + * Backchannel Replies are sent with !RPC_TASK_SOFT and 2001 + * RPC_TASK_NO_RETRANS_TIMEOUT. The major timeout setting 2002 + * affects only how long each Reply waits to be sent when 2003 + * a transport connection cannot be established. 2004 + */ 2005 + xprt_init_majortimeo(task, req, to); 2003 2006 } 2004 2007 #endif 2005 2008
+16 -3
net/sunrpc/xprtmultipath.c
··· 284 284 if (cur == pos) 285 285 found = true; 286 286 if (found && ((find_active && xprt_is_active(pos)) || 287 - (!find_active && xprt_is_active(pos)))) 287 + (!find_active && !xprt_is_active(pos)))) 288 288 return pos; 289 289 } 290 290 return NULL; ··· 336 336 xprt_switch_find_current_entry_offline); 337 337 } 338 338 339 - bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, 340 - const struct sockaddr *sap) 339 + static 340 + bool __rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, 341 + const struct sockaddr *sap) 341 342 { 342 343 struct list_head *head; 343 344 struct rpc_xprt *pos; ··· 355 354 } 356 355 } 357 356 return false; 357 + } 358 + 359 + bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, 360 + const struct sockaddr *sap) 361 + { 362 + bool res; 363 + 364 + rcu_read_lock(); 365 + res = __rpc_xprt_switch_has_addr(xps, sap); 366 + rcu_read_unlock(); 367 + 368 + return res; 358 369 } 359 370 360 371 static