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

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

Puyll NFS client updates from Anna Schumaker:
"Stable bugfixes:
- Fix memory leaks and corruption in readdir # v2.6.37+
- Directory page cache needs to be locked when read # v2.6.37+

New features:
- Convert NFS to use the new mount API
- Add "softreval" mount option to let clients use cache if server goes down
- Add a config option to compile without UDP support
- Limit the number of inactive delegations the client can cache at once
- Improved readdir concurrency using iterate_shared()

Other bugfixes and cleanups:
- More 64-bit time conversions
- Add additional diagnostic tracepoints
- Check for holes in swapfiles, and add dependency on CONFIG_SWAP
- Various xprtrdma cleanups to prepare for 5.7's changes
- Several fixes for NFS writeback and commit handling
- Fix acls over krb5i/krb5p mounts
- Recover from premature loss of openstateids
- Fix NFS v3 chacl and chmod bug
- Compare creds using cred_fscmp()
- Use kmemdup_nul() in more places
- Optimize readdir cache page invalidation
- Lease renewal and recovery fixes"

* tag 'nfs-for-5.6-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (93 commits)
NFSv4.0: nfs4_do_fsinfo() should not do implicit lease renewals
NFSv4: try lease recovery on NFS4ERR_EXPIRED
NFS: Fix memory leaks
nfs: optimise readdir cache page invalidation
NFS: Switch readdir to using iterate_shared()
NFS: Use kmemdup_nul() in nfs_readdir_make_qstr()
NFS: Directory page cache pages need to be locked when read
NFS: Fix memory leaks and corruption in readdir
SUNRPC: Use kmemdup_nul() in rpc_parse_scope_id()
NFS: Replace various occurrences of kstrndup() with kmemdup_nul()
NFSv4: Limit the total number of cached delegations
NFSv4: Add accounting for the number of active delegations held
NFSv4: Try to return the delegation immediately when marked for return on close
NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returned
NFSv4: nfs_inode_evict_delegation() should set NFS_DELEGATION_RETURNING
NFS: nfs_find_open_context() should use cred_fscmp()
NFS: nfs_access_get_cached_rcu() should use cred_fscmp()
NFSv4: pnfs_roc() must use cred_fscmp() to compare creds
NFS: remove unused macros
nfs: Return EINVAL rather than ERANGE for mount parse errors
...

+3223 -2907
+10 -1
fs/nfs/Kconfig
··· 90 90 config NFS_SWAP 91 91 bool "Provide swap over NFS support" 92 92 default n 93 - depends on NFS_FS 93 + depends on NFS_FS && SWAP 94 94 select SUNRPC_SWAP 95 95 help 96 96 This option enables swapon to work on files located on NFS mounts. ··· 196 196 depends on NFS_FS && SUNRPC_DEBUG 197 197 select CRC32 198 198 default y 199 + 200 + config NFS_DISABLE_UDP_SUPPORT 201 + bool "NFS: Disable NFS UDP protocol support" 202 + depends on NFS_FS 203 + default y 204 + help 205 + Choose Y here to disable the use of NFS over UDP. NFS over UDP 206 + on modern networks (1Gb+) can lead to data corruption caused by 207 + fragmentation during high loads.
+1 -1
fs/nfs/Makefile
··· 9 9 nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ 10 10 io.o direct.o pagelist.o read.o symlink.o unlink.o \ 11 11 write.o namespace.o mount_clnt.o nfstrace.o \ 12 - export.o sysfs.o 12 + export.o sysfs.o fs_context.o 13 13 nfs-$(CONFIG_ROOT_NFS) += nfsroot.o 14 14 nfs-$(CONFIG_SYSCTL) += sysctl.o 15 15 nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
+8 -3
fs/nfs/callback_xdr.c
··· 18 18 #include "callback.h" 19 19 #include "internal.h" 20 20 #include "nfs4session.h" 21 + #include "nfs4trace.h" 21 22 22 23 #define CB_OP_TAGLEN_MAXSZ (512) 23 24 #define CB_OP_HDR_RES_MAXSZ (2 * 4) // opcode, status ··· 947 946 948 947 if (hdr_arg.minorversion == 0) { 949 948 cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident); 950 - if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) { 951 - if (cps.clp) 952 - nfs_put_client(cps.clp); 949 + if (!cps.clp) { 950 + trace_nfs_cb_no_clp(rqstp->rq_xid, hdr_arg.cb_ident); 951 + goto out_invalidcred; 952 + } 953 + if (!check_gss_callback_principal(cps.clp, rqstp)) { 954 + trace_nfs_cb_badprinc(rqstp->rq_xid, hdr_arg.cb_ident); 955 + nfs_put_client(cps.clp); 953 956 goto out_invalidcred; 954 957 } 955 958 }
+44 -40
fs/nfs/client.c
··· 474 474 to->to_maxval = to->to_initval; 475 475 to->to_exponential = 0; 476 476 break; 477 + #ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT 477 478 case XPRT_TRANSPORT_UDP: 478 479 if (retrans == NFS_UNSPEC_RETRANS) 479 480 to->to_retries = NFS_DEF_UDP_RETRANS; ··· 485 484 to->to_maxval = NFS_MAX_UDP_TIMEOUT; 486 485 to->to_exponential = 1; 487 486 break; 487 + #endif 488 488 default: 489 489 BUG(); 490 490 } ··· 582 580 default: 583 581 nlm_init.protocol = IPPROTO_TCP; 584 582 break; 583 + #ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT 585 584 case XPRT_TRANSPORT_UDP: 586 585 nlm_init.protocol = IPPROTO_UDP; 586 + #endif 587 587 } 588 588 589 589 host = nlmclnt_init(&nlm_init); ··· 662 658 * Create a version 2 or 3 client 663 659 */ 664 660 static int nfs_init_server(struct nfs_server *server, 665 - const struct nfs_parsed_mount_data *data, 666 - struct nfs_subversion *nfs_mod) 661 + const struct fs_context *fc) 667 662 { 663 + const struct nfs_fs_context *ctx = nfs_fc2context(fc); 668 664 struct rpc_timeout timeparms; 669 665 struct nfs_client_initdata cl_init = { 670 - .hostname = data->nfs_server.hostname, 671 - .addr = (const struct sockaddr *)&data->nfs_server.address, 672 - .addrlen = data->nfs_server.addrlen, 673 - .nfs_mod = nfs_mod, 674 - .proto = data->nfs_server.protocol, 675 - .net = data->net, 666 + .hostname = ctx->nfs_server.hostname, 667 + .addr = (const struct sockaddr *)&ctx->nfs_server.address, 668 + .addrlen = ctx->nfs_server.addrlen, 669 + .nfs_mod = ctx->nfs_mod, 670 + .proto = ctx->nfs_server.protocol, 671 + .net = fc->net_ns, 676 672 .timeparms = &timeparms, 677 673 .cred = server->cred, 678 - .nconnect = data->nfs_server.nconnect, 674 + .nconnect = ctx->nfs_server.nconnect, 679 675 .init_flags = (1UL << NFS_CS_REUSEPORT), 680 676 }; 681 677 struct nfs_client *clp; 682 678 int error; 683 679 684 - nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 685 - data->timeo, data->retrans); 686 - if (data->flags & NFS_MOUNT_NORESVPORT) 680 + nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol, 681 + ctx->timeo, ctx->retrans); 682 + if (ctx->flags & NFS_MOUNT_NORESVPORT) 687 683 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); 688 684 689 685 /* Allocate or find a client reference we can use */ ··· 694 690 server->nfs_client = clp; 695 691 696 692 /* Initialise the client representation from the mount data */ 697 - server->flags = data->flags; 698 - server->options = data->options; 693 + server->flags = ctx->flags; 694 + server->options = ctx->options; 699 695 server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| 700 696 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP| 701 697 NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME; 702 698 703 - if (data->rsize) 704 - server->rsize = nfs_block_size(data->rsize, NULL); 705 - if (data->wsize) 706 - server->wsize = nfs_block_size(data->wsize, NULL); 699 + if (ctx->rsize) 700 + server->rsize = nfs_block_size(ctx->rsize, NULL); 701 + if (ctx->wsize) 702 + server->wsize = nfs_block_size(ctx->wsize, NULL); 707 703 708 - server->acregmin = data->acregmin * HZ; 709 - server->acregmax = data->acregmax * HZ; 710 - server->acdirmin = data->acdirmin * HZ; 711 - server->acdirmax = data->acdirmax * HZ; 704 + server->acregmin = ctx->acregmin * HZ; 705 + server->acregmax = ctx->acregmax * HZ; 706 + server->acdirmin = ctx->acdirmin * HZ; 707 + server->acdirmax = ctx->acdirmax * HZ; 712 708 713 709 /* Start lockd here, before we might error out */ 714 710 error = nfs_start_lockd(server); 715 711 if (error < 0) 716 712 goto error; 717 713 718 - server->port = data->nfs_server.port; 719 - server->auth_info = data->auth_info; 714 + server->port = ctx->nfs_server.port; 715 + server->auth_info = ctx->auth_info; 720 716 721 717 error = nfs_init_server_rpcclient(server, &timeparms, 722 - data->selected_flavor); 718 + ctx->selected_flavor); 723 719 if (error < 0) 724 720 goto error; 725 721 726 722 /* Preserve the values of mount_server-related mount options */ 727 - if (data->mount_server.addrlen) { 728 - memcpy(&server->mountd_address, &data->mount_server.address, 729 - data->mount_server.addrlen); 730 - server->mountd_addrlen = data->mount_server.addrlen; 723 + if (ctx->mount_server.addrlen) { 724 + memcpy(&server->mountd_address, &ctx->mount_server.address, 725 + ctx->mount_server.addrlen); 726 + server->mountd_addrlen = ctx->mount_server.addrlen; 731 727 } 732 - server->mountd_version = data->mount_server.version; 733 - server->mountd_port = data->mount_server.port; 734 - server->mountd_protocol = data->mount_server.protocol; 728 + server->mountd_version = ctx->mount_server.version; 729 + server->mountd_port = ctx->mount_server.port; 730 + server->mountd_protocol = ctx->mount_server.protocol; 735 731 736 - server->namelen = data->namlen; 732 + server->namelen = ctx->namlen; 737 733 return 0; 738 734 739 735 error: ··· 955 951 * Create a version 2 or 3 volume record 956 952 * - keyed on server and FSID 957 953 */ 958 - struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info, 959 - struct nfs_subversion *nfs_mod) 954 + struct nfs_server *nfs_create_server(struct fs_context *fc) 960 955 { 956 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 961 957 struct nfs_server *server; 962 958 struct nfs_fattr *fattr; 963 959 int error; ··· 974 970 goto error; 975 971 976 972 /* Get a client representation */ 977 - error = nfs_init_server(server, mount_info->parsed, nfs_mod); 973 + error = nfs_init_server(server, fc); 978 974 if (error < 0) 979 975 goto error; 980 976 981 977 /* Probe the root fh to retrieve its FSID */ 982 - error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr); 978 + error = nfs_probe_fsinfo(server, ctx->mntfh, fattr); 983 979 if (error < 0) 984 980 goto error; 985 981 if (server->nfs_client->rpc_ops->version == 3) { 986 982 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) 987 983 server->namelen = NFS3_MAXNAMLEN; 988 - if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS)) 984 + if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS)) 989 985 server->caps |= NFS_CAP_READDIRPLUS; 990 986 } else { 991 987 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) ··· 993 989 } 994 990 995 991 if (!(fattr->valid & NFS_ATTR_FATTR)) { 996 - error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, 997 - fattr, NULL, NULL); 992 + error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh, 993 + fattr, NULL, NULL); 998 994 if (error < 0) { 999 995 dprintk("nfs_create_server: getattr error = %d\n", -error); 1000 996 goto error;
+67 -13
fs/nfs/delegation.c
··· 25 25 #include "internal.h" 26 26 #include "nfs4trace.h" 27 27 28 - static void nfs_free_delegation(struct nfs_delegation *delegation) 28 + #define NFS_DEFAULT_DELEGATION_WATERMARK (5000U) 29 + 30 + static atomic_long_t nfs_active_delegations; 31 + static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK; 32 + 33 + static void __nfs_free_delegation(struct nfs_delegation *delegation) 29 34 { 30 35 put_cred(delegation->cred); 31 36 delegation->cred = NULL; 32 37 kfree_rcu(delegation, rcu); 38 + } 39 + 40 + static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation) 41 + { 42 + if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { 43 + delegation->stateid.type = NFS4_INVALID_STATEID_TYPE; 44 + atomic_long_dec(&nfs_active_delegations); 45 + } 46 + } 47 + 48 + static void nfs_free_delegation(struct nfs_delegation *delegation) 49 + { 50 + nfs_mark_delegation_revoked(delegation); 51 + __nfs_free_delegation(delegation); 33 52 } 34 53 35 54 /** ··· 362 343 delegation->stateid.seqid = update->stateid.seqid; 363 344 smp_wmb(); 364 345 delegation->type = update->type; 365 - clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags); 346 + if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) 347 + atomic_long_inc(&nfs_active_delegations); 366 348 } 367 349 } 368 350 ··· 443 423 rcu_assign_pointer(nfsi->delegation, delegation); 444 424 delegation = NULL; 445 425 426 + atomic_long_inc(&nfs_active_delegations); 427 + 446 428 trace_nfs4_set_delegation(inode, type); 447 429 448 430 spin_lock(&inode->i_lock); ··· 454 432 out: 455 433 spin_unlock(&clp->cl_lock); 456 434 if (delegation != NULL) 457 - nfs_free_delegation(delegation); 435 + __nfs_free_delegation(delegation); 458 436 if (freeme != NULL) { 459 437 nfs_do_return_delegation(inode, freeme, 0); 460 438 nfs_free_delegation(freeme); ··· 501 479 502 480 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags)) 503 481 ret = true; 504 - if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) { 482 + else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) { 505 483 struct inode *inode; 506 484 507 485 spin_lock(&delegation->lock); ··· 510 488 ret = true; 511 489 spin_unlock(&delegation->lock); 512 490 } 491 + if (ret) 492 + clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); 513 493 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) || 514 494 test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) 515 495 ret = false; ··· 631 607 632 608 delegation = nfs_inode_detach_delegation(inode); 633 609 if (delegation != NULL) { 610 + set_bit(NFS_DELEGATION_RETURNING, &delegation->flags); 634 611 set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags); 635 612 nfs_do_return_delegation(inode, delegation, 1); 636 613 nfs_free_delegation(delegation); ··· 659 634 if (delegation != NULL) 660 635 err = nfs_end_delegation_return(inode, delegation, 1); 661 636 return err; 637 + } 638 + 639 + /** 640 + * nfs_inode_return_delegation_on_close - asynchronously return a delegation 641 + * @inode: inode to process 642 + * 643 + * This routine is called on file close in order to determine if the 644 + * inode delegation needs to be returned immediately. 645 + */ 646 + void nfs4_inode_return_delegation_on_close(struct inode *inode) 647 + { 648 + struct nfs_delegation *delegation; 649 + struct nfs_delegation *ret = NULL; 650 + 651 + if (!inode) 652 + return; 653 + rcu_read_lock(); 654 + delegation = nfs4_get_valid_delegation(inode); 655 + if (!delegation) 656 + goto out; 657 + if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) || 658 + atomic_long_read(&nfs_active_delegations) >= nfs_delegation_watermark) { 659 + spin_lock(&delegation->lock); 660 + if (delegation->inode && 661 + list_empty(&NFS_I(inode)->open_files) && 662 + !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { 663 + clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags); 664 + ret = delegation; 665 + } 666 + spin_unlock(&delegation->lock); 667 + } 668 + out: 669 + rcu_read_unlock(); 670 + nfs_end_delegation_return(inode, ret, 0); 662 671 } 663 672 664 673 /** ··· 819 760 rcu_read_unlock(); 820 761 } 821 762 822 - static void nfs_mark_delegation_revoked(struct nfs_server *server, 823 - struct nfs_delegation *delegation) 824 - { 825 - set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); 826 - delegation->stateid.type = NFS4_INVALID_STATEID_TYPE; 827 - } 828 - 829 763 static void nfs_revoke_delegation(struct inode *inode, 830 764 const nfs4_stateid *stateid) 831 765 { ··· 846 794 } 847 795 spin_unlock(&delegation->lock); 848 796 } 849 - nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation); 797 + nfs_mark_delegation_revoked(delegation); 850 798 ret = true; 851 799 out: 852 800 rcu_read_unlock(); ··· 885 833 delegation->stateid.seqid = stateid->seqid; 886 834 } 887 835 888 - nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation); 836 + nfs_mark_delegation_revoked(delegation); 889 837 890 838 out_clear_returning: 891 839 clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags); ··· 1369 1317 rcu_read_unlock(); 1370 1318 return ret; 1371 1319 } 1320 + 1321 + module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);
+1
fs/nfs/delegation.h
··· 42 42 void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, 43 43 fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit); 44 44 int nfs4_inode_return_delegation(struct inode *inode); 45 + void nfs4_inode_return_delegation_on_close(struct inode *inode); 45 46 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); 46 47 void nfs_inode_evict_delegation(struct inode *inode); 47 48
+58 -25
fs/nfs/dir.c
··· 58 58 const struct file_operations nfs_dir_operations = { 59 59 .llseek = nfs_llseek_dir, 60 60 .read = generic_read_dir, 61 - .iterate = nfs_readdir, 61 + .iterate_shared = nfs_readdir, 62 62 .open = nfs_opendir, 63 63 .release = nfs_closedir, 64 64 .fsync = nfs_fsync_dir, ··· 162 162 bool eof; 163 163 } nfs_readdir_descriptor_t; 164 164 165 + static 166 + void nfs_readdir_init_array(struct page *page) 167 + { 168 + struct nfs_cache_array *array; 169 + 170 + array = kmap_atomic(page); 171 + memset(array, 0, sizeof(struct nfs_cache_array)); 172 + array->eof_index = -1; 173 + kunmap_atomic(array); 174 + } 175 + 165 176 /* 166 177 * we are freeing strings created by nfs_add_to_readdir_array() 167 178 */ ··· 185 174 array = kmap_atomic(page); 186 175 for (i = 0; i < array->size; i++) 187 176 kfree(array->array[i].string.name); 177 + array->size = 0; 188 178 kunmap_atomic(array); 189 179 } 190 180 ··· 198 186 int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len) 199 187 { 200 188 string->len = len; 201 - string->name = kmemdup(name, len, GFP_KERNEL); 189 + string->name = kmemdup_nul(name, len, GFP_KERNEL); 202 190 if (string->name == NULL) 203 191 return -ENOMEM; 204 192 /* ··· 449 437 if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) && 450 438 !list_empty(&nfsi->open_files)) { 451 439 set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags); 452 - invalidate_mapping_pages(dir->i_mapping, 0, -1); 440 + invalidate_mapping_pages(dir->i_mapping, 441 + nfsi->page_index + 1, -1); 453 442 } 454 443 } 455 444 ··· 623 610 int status = -ENOMEM; 624 611 unsigned int array_size = ARRAY_SIZE(pages); 625 612 613 + nfs_readdir_init_array(page); 614 + 626 615 entry.prev_cookie = 0; 627 616 entry.cookie = desc->last_cookie; 628 617 entry.eof = 0; ··· 641 626 } 642 627 643 628 array = kmap(page); 644 - memset(array, 0, sizeof(struct nfs_cache_array)); 645 - array->eof_index = -1; 646 629 647 630 status = nfs_readdir_alloc_pages(pages, array_size); 648 631 if (status < 0) ··· 695 682 unlock_page(page); 696 683 return 0; 697 684 error: 685 + nfs_readdir_clear_array(page); 698 686 unlock_page(page); 699 687 return ret; 700 688 } ··· 703 689 static 704 690 void cache_page_release(nfs_readdir_descriptor_t *desc) 705 691 { 706 - if (!desc->page->mapping) 707 - nfs_readdir_clear_array(desc->page); 708 692 put_page(desc->page); 709 693 desc->page = NULL; 710 694 } ··· 716 704 717 705 /* 718 706 * Returns 0 if desc->dir_cookie was found on page desc->page_index 707 + * and locks the page to prevent removal from the page cache. 719 708 */ 720 709 static 721 - int find_cache_page(nfs_readdir_descriptor_t *desc) 710 + int find_and_lock_cache_page(nfs_readdir_descriptor_t *desc) 722 711 { 712 + struct inode *inode = file_inode(desc->file); 713 + struct nfs_inode *nfsi = NFS_I(inode); 723 714 int res; 724 715 725 716 desc->page = get_cache_page(desc); 726 717 if (IS_ERR(desc->page)) 727 718 return PTR_ERR(desc->page); 728 - 729 - res = nfs_readdir_search_array(desc); 719 + res = lock_page_killable(desc->page); 730 720 if (res != 0) 731 - cache_page_release(desc); 721 + goto error; 722 + res = -EAGAIN; 723 + if (desc->page->mapping != NULL) { 724 + res = nfs_readdir_search_array(desc); 725 + if (res == 0) { 726 + nfsi->page_index = desc->page_index; 727 + return 0; 728 + } 729 + } 730 + unlock_page(desc->page); 731 + error: 732 + cache_page_release(desc); 732 733 return res; 733 734 } 734 735 ··· 756 731 desc->last_cookie = 0; 757 732 } 758 733 do { 759 - res = find_cache_page(desc); 734 + res = find_and_lock_cache_page(desc); 760 735 } while (res == -EAGAIN); 761 736 return res; 762 737 } ··· 795 770 desc->eof = true; 796 771 797 772 kunmap(desc->page); 798 - cache_page_release(desc); 799 773 dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", 800 774 (unsigned long long)*desc->dir_cookie, res); 801 775 return res; ··· 840 816 841 817 status = nfs_do_filldir(desc); 842 818 819 + out_release: 820 + nfs_readdir_clear_array(desc->page); 821 + cache_page_release(desc); 843 822 out: 844 823 dfprintk(DIRCACHE, "NFS: %s: returns %d\n", 845 824 __func__, status); 846 825 return status; 847 - out_release: 848 - cache_page_release(desc); 849 - goto out; 850 826 } 851 827 852 828 /* The file offset position represents the dirent entry number. A ··· 911 887 break; 912 888 913 889 res = nfs_do_filldir(desc); 890 + unlock_page(desc->page); 891 + cache_page_release(desc); 914 892 if (res < 0) 915 893 break; 916 894 } while (!desc->eof); ··· 1168 1142 if (fhandle == NULL || fattr == NULL || IS_ERR(label)) 1169 1143 goto out; 1170 1144 1171 - ret = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1145 + ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label); 1172 1146 if (ret < 0) { 1173 - if (ret == -ESTALE || ret == -ENOENT) 1147 + switch (ret) { 1148 + case -ESTALE: 1149 + case -ENOENT: 1174 1150 ret = 0; 1151 + break; 1152 + case -ETIMEDOUT: 1153 + if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL) 1154 + ret = 1; 1155 + } 1175 1156 goto out; 1176 1157 } 1177 1158 ret = 0; ··· 1441 1408 goto out; 1442 1409 1443 1410 trace_nfs_lookup_enter(dir, dentry, flags); 1444 - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1411 + error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label); 1445 1412 if (error == -ENOENT) 1446 1413 goto no_entry; 1447 1414 if (error < 0) { ··· 1716 1683 d_drop(dentry); 1717 1684 1718 1685 if (fhandle->size == 0) { 1719 - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL); 1686 + error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, NULL); 1720 1687 if (error) 1721 1688 goto out_error; 1722 1689 } ··· 2345 2312 /* Found an entry, is our attribute cache valid? */ 2346 2313 if (!nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) 2347 2314 break; 2315 + if (!retry) 2316 + break; 2348 2317 err = -ECHILD; 2349 2318 if (!may_block) 2350 2319 goto out; 2351 - if (!retry) 2352 - goto out_zap; 2353 2320 spin_unlock(&inode->i_lock); 2354 2321 err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); 2355 2322 if (err) ··· 2386 2353 lh = rcu_dereference(nfsi->access_cache_entry_lru.prev); 2387 2354 cache = list_entry(lh, struct nfs_access_entry, lru); 2388 2355 if (lh == &nfsi->access_cache_entry_lru || 2389 - cred != cache->cred) 2356 + cred_fscmp(cred, cache->cred) != 0) 2390 2357 cache = NULL; 2391 2358 if (cache == NULL) 2392 2359 goto out; ··· 2509 2476 { 2510 2477 struct nfs_access_entry cache; 2511 2478 bool may_block = (mask & MAY_NOT_BLOCK) == 0; 2512 - int cache_mask; 2479 + int cache_mask = -1; 2513 2480 int status; 2514 2481 2515 2482 trace_nfs_access_enter(inode); ··· 2548 2515 if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0) 2549 2516 status = -EACCES; 2550 2517 out: 2551 - trace_nfs_access_exit(inode, status); 2518 + trace_nfs_access_exit(inode, mask, cache_mask, status); 2552 2519 return status; 2553 2520 } 2554 2521
+4 -3
fs/nfs/direct.c
··· 245 245 data->ds_commit_index); 246 246 247 247 /* verifier not set so always fail */ 248 - if (verfp->committed < 0) 248 + if (verfp->committed < 0 || data->res.verf->committed <= NFS_UNSTABLE) 249 249 return 1; 250 250 251 - return nfs_direct_cmp_verf(verfp, &data->verf); 251 + return nfs_direct_cmp_verf(verfp, data->res.verf); 252 252 } 253 253 254 254 /** ··· 824 824 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 825 825 /* fake unstable write to let common nfs resend pages */ 826 826 hdr->verf.committed = NFS_UNSTABLE; 827 - hdr->good_bytes = hdr->args.count; 827 + hdr->good_bytes = hdr->args.offset + hdr->args.count - 828 + hdr->io_start; 828 829 } 829 830 spin_unlock(&dreq->lock); 830 831 }
+1 -1
fs/nfs/dns_resolve.c
··· 93 93 key = container_of(ckey, struct nfs_dns_ent, h); 94 94 95 95 kfree(new->hostname); 96 - new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); 96 + new->hostname = kmemdup_nul(key->hostname, key->namelen, GFP_KERNEL); 97 97 if (new->hostname) { 98 98 new->namelen = key->namelen; 99 99 nfs_dns_ent_update(cnew, ckey);
+28 -21
fs/nfs/file.c
··· 204 204 static int 205 205 nfs_file_fsync_commit(struct file *file, int datasync) 206 206 { 207 - struct nfs_open_context *ctx = nfs_file_open_context(file); 208 207 struct inode *inode = file_inode(file); 209 - int do_resend, status; 210 - int ret = 0; 208 + int ret; 211 209 212 210 dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync); 213 211 214 212 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 215 - do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); 216 - status = nfs_commit_inode(inode, FLUSH_SYNC); 217 - if (status == 0) 218 - status = file_check_and_advance_wb_err(file); 219 - if (status < 0) { 220 - ret = status; 221 - goto out; 222 - } 223 - do_resend |= test_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags); 224 - if (do_resend) 225 - ret = -EAGAIN; 226 - out: 227 - return ret; 213 + ret = nfs_commit_inode(inode, FLUSH_SYNC); 214 + if (ret < 0) 215 + return ret; 216 + return file_check_and_advance_wb_err(file); 228 217 } 229 218 230 219 int 231 220 nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) 232 221 { 233 - int ret; 222 + struct nfs_open_context *ctx = nfs_file_open_context(file); 234 223 struct inode *inode = file_inode(file); 224 + int ret; 235 225 236 226 trace_nfs_fsync_enter(inode); 237 227 238 - do { 228 + for (;;) { 239 229 ret = file_write_and_wait_range(file, start, end); 240 230 if (ret != 0) 241 231 break; 242 232 ret = nfs_file_fsync_commit(file, datasync); 243 - if (!ret) 244 - ret = pnfs_sync_inode(inode, !!datasync); 233 + if (ret != 0) 234 + break; 235 + ret = pnfs_sync_inode(inode, !!datasync); 236 + if (ret != 0) 237 + break; 238 + if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags)) 239 + break; 245 240 /* 246 241 * If nfs_file_fsync_commit detected a server reboot, then 247 242 * resend all dirty pages that might have been covered by ··· 244 249 */ 245 250 start = 0; 246 251 end = LLONG_MAX; 247 - } while (ret == -EAGAIN); 252 + } 248 253 249 254 trace_nfs_fsync_exit(inode, ret); 250 255 return ret; ··· 484 489 static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, 485 490 sector_t *span) 486 491 { 492 + unsigned long blocks; 493 + long long isize; 487 494 struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host); 495 + struct inode *inode = file->f_mapping->host; 496 + 497 + spin_lock(&inode->i_lock); 498 + blocks = inode->i_blocks; 499 + isize = inode->i_size; 500 + spin_unlock(&inode->i_lock); 501 + if (blocks*512 < isize) { 502 + pr_warn("swap activate: swapfile has holes\n"); 503 + return -EINVAL; 504 + } 488 505 489 506 *span = sis->pages; 490 507
+22 -12
fs/nfs/flexfilelayout/flexfilelayout.c
··· 1266 1266 1267 1267 static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, 1268 1268 int idx, u64 offset, u64 length, 1269 - u32 status, int opnum, int error) 1269 + u32 *op_status, int opnum, int error) 1270 1270 { 1271 1271 struct nfs4_ff_layout_mirror *mirror; 1272 + u32 status = *op_status; 1272 1273 int err; 1273 1274 1274 1275 if (status == 0) { ··· 1287 1286 case -ENOBUFS: 1288 1287 case -EPIPE: 1289 1288 case -EPERM: 1290 - status = NFS4ERR_NXIO; 1289 + *op_status = status = NFS4ERR_NXIO; 1291 1290 break; 1292 1291 case -EACCES: 1293 - status = NFS4ERR_ACCESS; 1292 + *op_status = status = NFS4ERR_ACCESS; 1294 1293 break; 1295 1294 default: 1296 1295 return; ··· 1322 1321 int new_idx = hdr->pgio_mirror_idx; 1323 1322 int err; 1324 1323 1325 - trace_nfs4_pnfs_read(hdr, task->tk_status); 1326 - if (task->tk_status < 0) 1324 + if (task->tk_status < 0) { 1327 1325 ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx, 1328 1326 hdr->args.offset, hdr->args.count, 1329 - hdr->res.op_status, OP_READ, 1327 + &hdr->res.op_status, OP_READ, 1330 1328 task->tk_status); 1329 + trace_ff_layout_read_error(hdr); 1330 + } 1331 + 1331 1332 err = ff_layout_async_handle_error(task, hdr->args.context->state, 1332 1333 hdr->ds_clp, hdr->lseg, 1333 1334 hdr->pgio_mirror_idx); 1334 1335 1336 + trace_nfs4_pnfs_read(hdr, err); 1335 1337 clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1336 1338 clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1337 1339 switch (err) { ··· 1498 1494 loff_t end_offs = 0; 1499 1495 int err; 1500 1496 1501 - trace_nfs4_pnfs_write(hdr, task->tk_status); 1502 - if (task->tk_status < 0) 1497 + if (task->tk_status < 0) { 1503 1498 ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx, 1504 1499 hdr->args.offset, hdr->args.count, 1505 - hdr->res.op_status, OP_WRITE, 1500 + &hdr->res.op_status, OP_WRITE, 1506 1501 task->tk_status); 1502 + trace_ff_layout_write_error(hdr); 1503 + } 1504 + 1507 1505 err = ff_layout_async_handle_error(task, hdr->args.context->state, 1508 1506 hdr->ds_clp, hdr->lseg, 1509 1507 hdr->pgio_mirror_idx); 1510 1508 1509 + trace_nfs4_pnfs_write(hdr, err); 1511 1510 clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); 1512 1511 clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); 1513 1512 switch (err) { ··· 1544 1537 { 1545 1538 int err; 1546 1539 1547 - trace_nfs4_pnfs_commit_ds(data, task->tk_status); 1548 - if (task->tk_status < 0) 1540 + if (task->tk_status < 0) { 1549 1541 ff_layout_io_track_ds_error(data->lseg, data->ds_commit_index, 1550 1542 data->args.offset, data->args.count, 1551 - data->res.op_status, OP_COMMIT, 1543 + &data->res.op_status, OP_COMMIT, 1552 1544 task->tk_status); 1545 + trace_ff_layout_commit_error(data); 1546 + } 1547 + 1553 1548 err = ff_layout_async_handle_error(task, NULL, data->ds_clp, 1554 1549 data->lseg, data->ds_commit_index); 1555 1550 1551 + trace_nfs4_pnfs_commit_ds(data, err); 1556 1552 switch (err) { 1557 1553 case -NFS4ERR_RESET_TO_PNFS: 1558 1554 pnfs_generic_prepare_to_resend_writes(data);
+1437
fs/nfs/fs_context.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * linux/fs/nfs/fs_context.c 4 + * 5 + * Copyright (C) 1992 Rick Sladkey 6 + * Conversion to new mount api Copyright (C) David Howells 7 + * 8 + * NFS mount handling. 9 + * 10 + * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com> 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/fs.h> 15 + #include <linux/fs_context.h> 16 + #include <linux/fs_parser.h> 17 + #include <linux/nfs_fs.h> 18 + #include <linux/nfs_mount.h> 19 + #include <linux/nfs4_mount.h> 20 + #include "nfs.h" 21 + #include "internal.h" 22 + 23 + #define NFSDBG_FACILITY NFSDBG_MOUNT 24 + 25 + #if IS_ENABLED(CONFIG_NFS_V3) 26 + #define NFS_DEFAULT_VERSION 3 27 + #else 28 + #define NFS_DEFAULT_VERSION 2 29 + #endif 30 + 31 + #define NFS_MAX_CONNECTIONS 16 32 + 33 + enum nfs_param { 34 + Opt_ac, 35 + Opt_acdirmax, 36 + Opt_acdirmin, 37 + Opt_acl, 38 + Opt_acregmax, 39 + Opt_acregmin, 40 + Opt_actimeo, 41 + Opt_addr, 42 + Opt_bg, 43 + Opt_bsize, 44 + Opt_clientaddr, 45 + Opt_cto, 46 + Opt_fg, 47 + Opt_fscache, 48 + Opt_hard, 49 + Opt_intr, 50 + Opt_local_lock, 51 + Opt_lock, 52 + Opt_lookupcache, 53 + Opt_migration, 54 + Opt_minorversion, 55 + Opt_mountaddr, 56 + Opt_mounthost, 57 + Opt_mountport, 58 + Opt_mountproto, 59 + Opt_mountvers, 60 + Opt_namelen, 61 + Opt_nconnect, 62 + Opt_port, 63 + Opt_posix, 64 + Opt_proto, 65 + Opt_rdirplus, 66 + Opt_rdma, 67 + Opt_resvport, 68 + Opt_retrans, 69 + Opt_retry, 70 + Opt_rsize, 71 + Opt_sec, 72 + Opt_sharecache, 73 + Opt_sloppy, 74 + Opt_soft, 75 + Opt_softerr, 76 + Opt_softreval, 77 + Opt_source, 78 + Opt_tcp, 79 + Opt_timeo, 80 + Opt_udp, 81 + Opt_v, 82 + Opt_vers, 83 + Opt_wsize, 84 + }; 85 + 86 + static const struct fs_parameter_spec nfs_param_specs[] = { 87 + fsparam_flag_no("ac", Opt_ac), 88 + fsparam_u32 ("acdirmax", Opt_acdirmax), 89 + fsparam_u32 ("acdirmin", Opt_acdirmin), 90 + fsparam_flag_no("acl", Opt_acl), 91 + fsparam_u32 ("acregmax", Opt_acregmax), 92 + fsparam_u32 ("acregmin", Opt_acregmin), 93 + fsparam_u32 ("actimeo", Opt_actimeo), 94 + fsparam_string("addr", Opt_addr), 95 + fsparam_flag ("bg", Opt_bg), 96 + fsparam_u32 ("bsize", Opt_bsize), 97 + fsparam_string("clientaddr", Opt_clientaddr), 98 + fsparam_flag_no("cto", Opt_cto), 99 + fsparam_flag ("fg", Opt_fg), 100 + __fsparam(fs_param_is_string, "fsc", Opt_fscache, 101 + fs_param_neg_with_no|fs_param_v_optional), 102 + fsparam_flag ("hard", Opt_hard), 103 + __fsparam(fs_param_is_flag, "intr", Opt_intr, 104 + fs_param_neg_with_no|fs_param_deprecated), 105 + fsparam_enum ("local_lock", Opt_local_lock), 106 + fsparam_flag_no("lock", Opt_lock), 107 + fsparam_enum ("lookupcache", Opt_lookupcache), 108 + fsparam_flag_no("migration", Opt_migration), 109 + fsparam_u32 ("minorversion", Opt_minorversion), 110 + fsparam_string("mountaddr", Opt_mountaddr), 111 + fsparam_string("mounthost", Opt_mounthost), 112 + fsparam_u32 ("mountport", Opt_mountport), 113 + fsparam_string("mountproto", Opt_mountproto), 114 + fsparam_u32 ("mountvers", Opt_mountvers), 115 + fsparam_u32 ("namlen", Opt_namelen), 116 + fsparam_u32 ("nconnect", Opt_nconnect), 117 + fsparam_string("nfsvers", Opt_vers), 118 + fsparam_u32 ("port", Opt_port), 119 + fsparam_flag_no("posix", Opt_posix), 120 + fsparam_string("proto", Opt_proto), 121 + fsparam_flag_no("rdirplus", Opt_rdirplus), 122 + fsparam_flag ("rdma", Opt_rdma), 123 + fsparam_flag_no("resvport", Opt_resvport), 124 + fsparam_u32 ("retrans", Opt_retrans), 125 + fsparam_string("retry", Opt_retry), 126 + fsparam_u32 ("rsize", Opt_rsize), 127 + fsparam_string("sec", Opt_sec), 128 + fsparam_flag_no("sharecache", Opt_sharecache), 129 + fsparam_flag ("sloppy", Opt_sloppy), 130 + fsparam_flag ("soft", Opt_soft), 131 + fsparam_flag ("softerr", Opt_softerr), 132 + fsparam_flag ("softreval", Opt_softreval), 133 + fsparam_string("source", Opt_source), 134 + fsparam_flag ("tcp", Opt_tcp), 135 + fsparam_u32 ("timeo", Opt_timeo), 136 + fsparam_flag ("udp", Opt_udp), 137 + fsparam_flag ("v2", Opt_v), 138 + fsparam_flag ("v3", Opt_v), 139 + fsparam_flag ("v4", Opt_v), 140 + fsparam_flag ("v4.0", Opt_v), 141 + fsparam_flag ("v4.1", Opt_v), 142 + fsparam_flag ("v4.2", Opt_v), 143 + fsparam_string("vers", Opt_vers), 144 + fsparam_u32 ("wsize", Opt_wsize), 145 + {} 146 + }; 147 + 148 + enum { 149 + Opt_local_lock_all, 150 + Opt_local_lock_flock, 151 + Opt_local_lock_none, 152 + Opt_local_lock_posix, 153 + }; 154 + 155 + enum { 156 + Opt_lookupcache_all, 157 + Opt_lookupcache_none, 158 + Opt_lookupcache_positive, 159 + }; 160 + 161 + static const struct fs_parameter_enum nfs_param_enums[] = { 162 + { Opt_local_lock, "all", Opt_local_lock_all }, 163 + { Opt_local_lock, "flock", Opt_local_lock_flock }, 164 + { Opt_local_lock, "none", Opt_local_lock_none }, 165 + { Opt_local_lock, "posix", Opt_local_lock_posix }, 166 + { Opt_lookupcache, "all", Opt_lookupcache_all }, 167 + { Opt_lookupcache, "none", Opt_lookupcache_none }, 168 + { Opt_lookupcache, "pos", Opt_lookupcache_positive }, 169 + { Opt_lookupcache, "positive", Opt_lookupcache_positive }, 170 + {} 171 + }; 172 + 173 + static const struct fs_parameter_description nfs_fs_parameters = { 174 + .name = "nfs", 175 + .specs = nfs_param_specs, 176 + .enums = nfs_param_enums, 177 + }; 178 + 179 + enum { 180 + Opt_vers_2, 181 + Opt_vers_3, 182 + Opt_vers_4, 183 + Opt_vers_4_0, 184 + Opt_vers_4_1, 185 + Opt_vers_4_2, 186 + }; 187 + 188 + static const struct constant_table nfs_vers_tokens[] = { 189 + { "2", Opt_vers_2 }, 190 + { "3", Opt_vers_3 }, 191 + { "4", Opt_vers_4 }, 192 + { "4.0", Opt_vers_4_0 }, 193 + { "4.1", Opt_vers_4_1 }, 194 + { "4.2", Opt_vers_4_2 }, 195 + }; 196 + 197 + enum { 198 + Opt_xprt_rdma, 199 + Opt_xprt_rdma6, 200 + Opt_xprt_tcp, 201 + Opt_xprt_tcp6, 202 + Opt_xprt_udp, 203 + Opt_xprt_udp6, 204 + nr__Opt_xprt 205 + }; 206 + 207 + static const struct constant_table nfs_xprt_protocol_tokens[nr__Opt_xprt] = { 208 + { "rdma", Opt_xprt_rdma }, 209 + { "rdma6", Opt_xprt_rdma6 }, 210 + { "tcp", Opt_xprt_tcp }, 211 + { "tcp6", Opt_xprt_tcp6 }, 212 + { "udp", Opt_xprt_udp }, 213 + { "udp6", Opt_xprt_udp6 }, 214 + }; 215 + 216 + enum { 217 + Opt_sec_krb5, 218 + Opt_sec_krb5i, 219 + Opt_sec_krb5p, 220 + Opt_sec_lkey, 221 + Opt_sec_lkeyi, 222 + Opt_sec_lkeyp, 223 + Opt_sec_none, 224 + Opt_sec_spkm, 225 + Opt_sec_spkmi, 226 + Opt_sec_spkmp, 227 + Opt_sec_sys, 228 + nr__Opt_sec 229 + }; 230 + 231 + static const struct constant_table nfs_secflavor_tokens[] = { 232 + { "krb5", Opt_sec_krb5 }, 233 + { "krb5i", Opt_sec_krb5i }, 234 + { "krb5p", Opt_sec_krb5p }, 235 + { "lkey", Opt_sec_lkey }, 236 + { "lkeyi", Opt_sec_lkeyi }, 237 + { "lkeyp", Opt_sec_lkeyp }, 238 + { "none", Opt_sec_none }, 239 + { "null", Opt_sec_none }, 240 + { "spkm3", Opt_sec_spkm }, 241 + { "spkm3i", Opt_sec_spkmi }, 242 + { "spkm3p", Opt_sec_spkmp }, 243 + { "sys", Opt_sec_sys }, 244 + }; 245 + 246 + /* 247 + * Sanity-check a server address provided by the mount command. 248 + * 249 + * Address family must be initialized, and address must not be 250 + * the ANY address for that family. 251 + */ 252 + static int nfs_verify_server_address(struct sockaddr *addr) 253 + { 254 + switch (addr->sa_family) { 255 + case AF_INET: { 256 + struct sockaddr_in *sa = (struct sockaddr_in *)addr; 257 + return sa->sin_addr.s_addr != htonl(INADDR_ANY); 258 + } 259 + case AF_INET6: { 260 + struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; 261 + return !ipv6_addr_any(sa); 262 + } 263 + } 264 + 265 + dfprintk(MOUNT, "NFS: Invalid IP address specified\n"); 266 + return 0; 267 + } 268 + 269 + /* 270 + * Sanity check the NFS transport protocol. 271 + * 272 + */ 273 + static void nfs_validate_transport_protocol(struct nfs_fs_context *ctx) 274 + { 275 + switch (ctx->nfs_server.protocol) { 276 + case XPRT_TRANSPORT_UDP: 277 + case XPRT_TRANSPORT_TCP: 278 + case XPRT_TRANSPORT_RDMA: 279 + break; 280 + default: 281 + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; 282 + } 283 + } 284 + 285 + /* 286 + * For text based NFSv2/v3 mounts, the mount protocol transport default 287 + * settings should depend upon the specified NFS transport. 288 + */ 289 + static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx) 290 + { 291 + nfs_validate_transport_protocol(ctx); 292 + 293 + if (ctx->mount_server.protocol == XPRT_TRANSPORT_UDP || 294 + ctx->mount_server.protocol == XPRT_TRANSPORT_TCP) 295 + return; 296 + switch (ctx->nfs_server.protocol) { 297 + case XPRT_TRANSPORT_UDP: 298 + ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; 299 + break; 300 + case XPRT_TRANSPORT_TCP: 301 + case XPRT_TRANSPORT_RDMA: 302 + ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; 303 + } 304 + } 305 + 306 + /* 307 + * Add 'flavor' to 'auth_info' if not already present. 308 + * Returns true if 'flavor' ends up in the list, false otherwise 309 + */ 310 + static int nfs_auth_info_add(struct fs_context *fc, 311 + struct nfs_auth_info *auth_info, 312 + rpc_authflavor_t flavor) 313 + { 314 + unsigned int i; 315 + unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors); 316 + 317 + /* make sure this flavor isn't already in the list */ 318 + for (i = 0; i < auth_info->flavor_len; i++) { 319 + if (flavor == auth_info->flavors[i]) 320 + return 0; 321 + } 322 + 323 + if (auth_info->flavor_len + 1 >= max_flavor_len) 324 + return nfs_invalf(fc, "NFS: too many sec= flavors"); 325 + 326 + auth_info->flavors[auth_info->flavor_len++] = flavor; 327 + return 0; 328 + } 329 + 330 + /* 331 + * Parse the value of the 'sec=' option. 332 + */ 333 + static int nfs_parse_security_flavors(struct fs_context *fc, 334 + struct fs_parameter *param) 335 + { 336 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 337 + rpc_authflavor_t pseudoflavor; 338 + char *string = param->string, *p; 339 + int ret; 340 + 341 + dfprintk(MOUNT, "NFS: parsing %s=%s option\n", param->key, param->string); 342 + 343 + while ((p = strsep(&string, ":")) != NULL) { 344 + if (!*p) 345 + continue; 346 + switch (lookup_constant(nfs_secflavor_tokens, p, -1)) { 347 + case Opt_sec_none: 348 + pseudoflavor = RPC_AUTH_NULL; 349 + break; 350 + case Opt_sec_sys: 351 + pseudoflavor = RPC_AUTH_UNIX; 352 + break; 353 + case Opt_sec_krb5: 354 + pseudoflavor = RPC_AUTH_GSS_KRB5; 355 + break; 356 + case Opt_sec_krb5i: 357 + pseudoflavor = RPC_AUTH_GSS_KRB5I; 358 + break; 359 + case Opt_sec_krb5p: 360 + pseudoflavor = RPC_AUTH_GSS_KRB5P; 361 + break; 362 + case Opt_sec_lkey: 363 + pseudoflavor = RPC_AUTH_GSS_LKEY; 364 + break; 365 + case Opt_sec_lkeyi: 366 + pseudoflavor = RPC_AUTH_GSS_LKEYI; 367 + break; 368 + case Opt_sec_lkeyp: 369 + pseudoflavor = RPC_AUTH_GSS_LKEYP; 370 + break; 371 + case Opt_sec_spkm: 372 + pseudoflavor = RPC_AUTH_GSS_SPKM; 373 + break; 374 + case Opt_sec_spkmi: 375 + pseudoflavor = RPC_AUTH_GSS_SPKMI; 376 + break; 377 + case Opt_sec_spkmp: 378 + pseudoflavor = RPC_AUTH_GSS_SPKMP; 379 + break; 380 + default: 381 + return nfs_invalf(fc, "NFS: sec=%s option not recognized", p); 382 + } 383 + 384 + ret = nfs_auth_info_add(fc, &ctx->auth_info, pseudoflavor); 385 + if (ret < 0) 386 + return ret; 387 + } 388 + 389 + return 0; 390 + } 391 + 392 + static int nfs_parse_version_string(struct fs_context *fc, 393 + const char *string) 394 + { 395 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 396 + 397 + ctx->flags &= ~NFS_MOUNT_VER3; 398 + switch (lookup_constant(nfs_vers_tokens, string, -1)) { 399 + case Opt_vers_2: 400 + ctx->version = 2; 401 + break; 402 + case Opt_vers_3: 403 + ctx->flags |= NFS_MOUNT_VER3; 404 + ctx->version = 3; 405 + break; 406 + case Opt_vers_4: 407 + /* Backward compatibility option. In future, 408 + * the mount program should always supply 409 + * a NFSv4 minor version number. 410 + */ 411 + ctx->version = 4; 412 + break; 413 + case Opt_vers_4_0: 414 + ctx->version = 4; 415 + ctx->minorversion = 0; 416 + break; 417 + case Opt_vers_4_1: 418 + ctx->version = 4; 419 + ctx->minorversion = 1; 420 + break; 421 + case Opt_vers_4_2: 422 + ctx->version = 4; 423 + ctx->minorversion = 2; 424 + break; 425 + default: 426 + return nfs_invalf(fc, "NFS: Unsupported NFS version"); 427 + } 428 + return 0; 429 + } 430 + 431 + /* 432 + * Parse a single mount parameter. 433 + */ 434 + static int nfs_fs_context_parse_param(struct fs_context *fc, 435 + struct fs_parameter *param) 436 + { 437 + struct fs_parse_result result; 438 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 439 + unsigned short protofamily, mountfamily; 440 + unsigned int len; 441 + int ret, opt; 442 + 443 + dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key); 444 + 445 + opt = fs_parse(fc, &nfs_fs_parameters, param, &result); 446 + if (opt < 0) 447 + return ctx->sloppy ? 1 : opt; 448 + 449 + switch (opt) { 450 + case Opt_source: 451 + if (fc->source) 452 + return nfs_invalf(fc, "NFS: Multiple sources not supported"); 453 + fc->source = param->string; 454 + param->string = NULL; 455 + break; 456 + 457 + /* 458 + * boolean options: foo/nofoo 459 + */ 460 + case Opt_soft: 461 + ctx->flags |= NFS_MOUNT_SOFT; 462 + ctx->flags &= ~NFS_MOUNT_SOFTERR; 463 + break; 464 + case Opt_softerr: 465 + ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL; 466 + ctx->flags &= ~NFS_MOUNT_SOFT; 467 + break; 468 + case Opt_hard: 469 + ctx->flags &= ~(NFS_MOUNT_SOFT | 470 + NFS_MOUNT_SOFTERR | 471 + NFS_MOUNT_SOFTREVAL); 472 + break; 473 + case Opt_softreval: 474 + if (result.negated) 475 + ctx->flags &= ~NFS_MOUNT_SOFTREVAL; 476 + else 477 + ctx->flags &= NFS_MOUNT_SOFTREVAL; 478 + break; 479 + case Opt_posix: 480 + if (result.negated) 481 + ctx->flags &= ~NFS_MOUNT_POSIX; 482 + else 483 + ctx->flags |= NFS_MOUNT_POSIX; 484 + break; 485 + case Opt_cto: 486 + if (result.negated) 487 + ctx->flags |= NFS_MOUNT_NOCTO; 488 + else 489 + ctx->flags &= ~NFS_MOUNT_NOCTO; 490 + break; 491 + case Opt_ac: 492 + if (result.negated) 493 + ctx->flags |= NFS_MOUNT_NOAC; 494 + else 495 + ctx->flags &= ~NFS_MOUNT_NOAC; 496 + break; 497 + case Opt_lock: 498 + if (result.negated) { 499 + ctx->flags |= NFS_MOUNT_NONLM; 500 + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 501 + } else { 502 + ctx->flags &= ~NFS_MOUNT_NONLM; 503 + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL); 504 + } 505 + break; 506 + case Opt_udp: 507 + ctx->flags &= ~NFS_MOUNT_TCP; 508 + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; 509 + break; 510 + case Opt_tcp: 511 + ctx->flags |= NFS_MOUNT_TCP; 512 + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; 513 + break; 514 + case Opt_rdma: 515 + ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */ 516 + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 517 + xprt_load_transport(param->key); 518 + break; 519 + case Opt_acl: 520 + if (result.negated) 521 + ctx->flags |= NFS_MOUNT_NOACL; 522 + else 523 + ctx->flags &= ~NFS_MOUNT_NOACL; 524 + break; 525 + case Opt_rdirplus: 526 + if (result.negated) 527 + ctx->flags |= NFS_MOUNT_NORDIRPLUS; 528 + else 529 + ctx->flags &= ~NFS_MOUNT_NORDIRPLUS; 530 + break; 531 + case Opt_sharecache: 532 + if (result.negated) 533 + ctx->flags |= NFS_MOUNT_UNSHARED; 534 + else 535 + ctx->flags &= ~NFS_MOUNT_UNSHARED; 536 + break; 537 + case Opt_resvport: 538 + if (result.negated) 539 + ctx->flags |= NFS_MOUNT_NORESVPORT; 540 + else 541 + ctx->flags &= ~NFS_MOUNT_NORESVPORT; 542 + break; 543 + case Opt_fscache: 544 + kfree(ctx->fscache_uniq); 545 + ctx->fscache_uniq = param->string; 546 + param->string = NULL; 547 + if (result.negated) 548 + ctx->options &= ~NFS_OPTION_FSCACHE; 549 + else 550 + ctx->options |= NFS_OPTION_FSCACHE; 551 + break; 552 + case Opt_migration: 553 + if (result.negated) 554 + ctx->options &= ~NFS_OPTION_MIGRATION; 555 + else 556 + ctx->options |= NFS_OPTION_MIGRATION; 557 + break; 558 + 559 + /* 560 + * options that take numeric values 561 + */ 562 + case Opt_port: 563 + if (result.uint_32 > USHRT_MAX) 564 + goto out_of_bounds; 565 + ctx->nfs_server.port = result.uint_32; 566 + break; 567 + case Opt_rsize: 568 + ctx->rsize = result.uint_32; 569 + break; 570 + case Opt_wsize: 571 + ctx->wsize = result.uint_32; 572 + break; 573 + case Opt_bsize: 574 + ctx->bsize = result.uint_32; 575 + break; 576 + case Opt_timeo: 577 + if (result.uint_32 < 1 || result.uint_32 > INT_MAX) 578 + goto out_of_bounds; 579 + ctx->timeo = result.uint_32; 580 + break; 581 + case Opt_retrans: 582 + if (result.uint_32 > INT_MAX) 583 + goto out_of_bounds; 584 + ctx->retrans = result.uint_32; 585 + break; 586 + case Opt_acregmin: 587 + ctx->acregmin = result.uint_32; 588 + break; 589 + case Opt_acregmax: 590 + ctx->acregmax = result.uint_32; 591 + break; 592 + case Opt_acdirmin: 593 + ctx->acdirmin = result.uint_32; 594 + break; 595 + case Opt_acdirmax: 596 + ctx->acdirmax = result.uint_32; 597 + break; 598 + case Opt_actimeo: 599 + ctx->acregmin = result.uint_32; 600 + ctx->acregmax = result.uint_32; 601 + ctx->acdirmin = result.uint_32; 602 + ctx->acdirmax = result.uint_32; 603 + break; 604 + case Opt_namelen: 605 + ctx->namlen = result.uint_32; 606 + break; 607 + case Opt_mountport: 608 + if (result.uint_32 > USHRT_MAX) 609 + goto out_of_bounds; 610 + ctx->mount_server.port = result.uint_32; 611 + break; 612 + case Opt_mountvers: 613 + if (result.uint_32 < NFS_MNT_VERSION || 614 + result.uint_32 > NFS_MNT3_VERSION) 615 + goto out_of_bounds; 616 + ctx->mount_server.version = result.uint_32; 617 + break; 618 + case Opt_minorversion: 619 + if (result.uint_32 > NFS4_MAX_MINOR_VERSION) 620 + goto out_of_bounds; 621 + ctx->minorversion = result.uint_32; 622 + break; 623 + 624 + /* 625 + * options that take text values 626 + */ 627 + case Opt_v: 628 + ret = nfs_parse_version_string(fc, param->key + 1); 629 + if (ret < 0) 630 + return ret; 631 + break; 632 + case Opt_vers: 633 + ret = nfs_parse_version_string(fc, param->string); 634 + if (ret < 0) 635 + return ret; 636 + break; 637 + case Opt_sec: 638 + ret = nfs_parse_security_flavors(fc, param); 639 + if (ret < 0) 640 + return ret; 641 + break; 642 + 643 + case Opt_proto: 644 + protofamily = AF_INET; 645 + switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) { 646 + case Opt_xprt_udp6: 647 + protofamily = AF_INET6; 648 + /* fall through */ 649 + case Opt_xprt_udp: 650 + ctx->flags &= ~NFS_MOUNT_TCP; 651 + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; 652 + break; 653 + case Opt_xprt_tcp6: 654 + protofamily = AF_INET6; 655 + /* fall through */ 656 + case Opt_xprt_tcp: 657 + ctx->flags |= NFS_MOUNT_TCP; 658 + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; 659 + break; 660 + case Opt_xprt_rdma6: 661 + protofamily = AF_INET6; 662 + /* fall through */ 663 + case Opt_xprt_rdma: 664 + /* vector side protocols to TCP */ 665 + ctx->flags |= NFS_MOUNT_TCP; 666 + ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 667 + xprt_load_transport(param->string); 668 + break; 669 + default: 670 + return nfs_invalf(fc, "NFS: Unrecognized transport protocol"); 671 + } 672 + 673 + ctx->protofamily = protofamily; 674 + break; 675 + 676 + case Opt_mountproto: 677 + mountfamily = AF_INET; 678 + switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) { 679 + case Opt_xprt_udp6: 680 + mountfamily = AF_INET6; 681 + /* fall through */ 682 + case Opt_xprt_udp: 683 + ctx->mount_server.protocol = XPRT_TRANSPORT_UDP; 684 + break; 685 + case Opt_xprt_tcp6: 686 + mountfamily = AF_INET6; 687 + /* fall through */ 688 + case Opt_xprt_tcp: 689 + ctx->mount_server.protocol = XPRT_TRANSPORT_TCP; 690 + break; 691 + case Opt_xprt_rdma: /* not used for side protocols */ 692 + default: 693 + return nfs_invalf(fc, "NFS: Unrecognized transport protocol"); 694 + } 695 + ctx->mountfamily = mountfamily; 696 + break; 697 + 698 + case Opt_addr: 699 + len = rpc_pton(fc->net_ns, param->string, param->size, 700 + &ctx->nfs_server.address, 701 + sizeof(ctx->nfs_server._address)); 702 + if (len == 0) 703 + goto out_invalid_address; 704 + ctx->nfs_server.addrlen = len; 705 + break; 706 + case Opt_clientaddr: 707 + kfree(ctx->client_address); 708 + ctx->client_address = param->string; 709 + param->string = NULL; 710 + break; 711 + case Opt_mounthost: 712 + kfree(ctx->mount_server.hostname); 713 + ctx->mount_server.hostname = param->string; 714 + param->string = NULL; 715 + break; 716 + case Opt_mountaddr: 717 + len = rpc_pton(fc->net_ns, param->string, param->size, 718 + &ctx->mount_server.address, 719 + sizeof(ctx->mount_server._address)); 720 + if (len == 0) 721 + goto out_invalid_address; 722 + ctx->mount_server.addrlen = len; 723 + break; 724 + case Opt_nconnect: 725 + if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS) 726 + goto out_of_bounds; 727 + ctx->nfs_server.nconnect = result.uint_32; 728 + break; 729 + case Opt_lookupcache: 730 + switch (result.uint_32) { 731 + case Opt_lookupcache_all: 732 + ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); 733 + break; 734 + case Opt_lookupcache_positive: 735 + ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; 736 + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; 737 + break; 738 + case Opt_lookupcache_none: 739 + ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; 740 + break; 741 + default: 742 + goto out_invalid_value; 743 + } 744 + break; 745 + case Opt_local_lock: 746 + switch (result.uint_32) { 747 + case Opt_local_lock_all: 748 + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | 749 + NFS_MOUNT_LOCAL_FCNTL); 750 + break; 751 + case Opt_local_lock_flock: 752 + ctx->flags |= NFS_MOUNT_LOCAL_FLOCK; 753 + break; 754 + case Opt_local_lock_posix: 755 + ctx->flags |= NFS_MOUNT_LOCAL_FCNTL; 756 + break; 757 + case Opt_local_lock_none: 758 + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | 759 + NFS_MOUNT_LOCAL_FCNTL); 760 + break; 761 + default: 762 + goto out_invalid_value; 763 + } 764 + break; 765 + 766 + /* 767 + * Special options 768 + */ 769 + case Opt_sloppy: 770 + ctx->sloppy = true; 771 + dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); 772 + break; 773 + } 774 + 775 + return 0; 776 + 777 + out_invalid_value: 778 + return nfs_invalf(fc, "NFS: Bad mount option value specified"); 779 + out_invalid_address: 780 + return nfs_invalf(fc, "NFS: Bad IP address specified"); 781 + out_of_bounds: 782 + return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key); 783 + } 784 + 785 + /* 786 + * Split fc->source into "hostname:export_path". 787 + * 788 + * The leftmost colon demarks the split between the server's hostname 789 + * and the export path. If the hostname starts with a left square 790 + * bracket, then it may contain colons. 791 + * 792 + * Note: caller frees hostname and export path, even on error. 793 + */ 794 + static int nfs_parse_source(struct fs_context *fc, 795 + size_t maxnamlen, size_t maxpathlen) 796 + { 797 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 798 + const char *dev_name = fc->source; 799 + size_t len; 800 + const char *end; 801 + 802 + if (unlikely(!dev_name || !*dev_name)) { 803 + dfprintk(MOUNT, "NFS: device name not specified\n"); 804 + return -EINVAL; 805 + } 806 + 807 + /* Is the host name protected with square brakcets? */ 808 + if (*dev_name == '[') { 809 + end = strchr(++dev_name, ']'); 810 + if (end == NULL || end[1] != ':') 811 + goto out_bad_devname; 812 + 813 + len = end - dev_name; 814 + end++; 815 + } else { 816 + const char *comma; 817 + 818 + end = strchr(dev_name, ':'); 819 + if (end == NULL) 820 + goto out_bad_devname; 821 + len = end - dev_name; 822 + 823 + /* kill possible hostname list: not supported */ 824 + comma = memchr(dev_name, ',', len); 825 + if (comma) 826 + len = comma - dev_name; 827 + } 828 + 829 + if (len > maxnamlen) 830 + goto out_hostname; 831 + 832 + /* N.B. caller will free nfs_server.hostname in all cases */ 833 + ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); 834 + if (!ctx->nfs_server.hostname) 835 + goto out_nomem; 836 + len = strlen(++end); 837 + if (len > maxpathlen) 838 + goto out_path; 839 + ctx->nfs_server.export_path = kmemdup_nul(end, len, GFP_KERNEL); 840 + if (!ctx->nfs_server.export_path) 841 + goto out_nomem; 842 + 843 + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", ctx->nfs_server.export_path); 844 + return 0; 845 + 846 + out_bad_devname: 847 + return nfs_invalf(fc, "NFS: device name not in host:path format"); 848 + out_nomem: 849 + nfs_errorf(fc, "NFS: not enough memory to parse device name"); 850 + return -ENOMEM; 851 + out_hostname: 852 + nfs_errorf(fc, "NFS: server hostname too long"); 853 + return -ENAMETOOLONG; 854 + out_path: 855 + nfs_errorf(fc, "NFS: export pathname too long"); 856 + return -ENAMETOOLONG; 857 + } 858 + 859 + static inline bool is_remount_fc(struct fs_context *fc) 860 + { 861 + return fc->root != NULL; 862 + } 863 + 864 + /* 865 + * Parse monolithic NFS2/NFS3 mount data 866 + * - fills in the mount root filehandle 867 + * 868 + * For option strings, user space handles the following behaviors: 869 + * 870 + * + DNS: mapping server host name to IP address ("addr=" option) 871 + * 872 + * + failure mode: how to behave if a mount request can't be handled 873 + * immediately ("fg/bg" option) 874 + * 875 + * + retry: how often to retry a mount request ("retry=" option) 876 + * 877 + * + breaking back: trying proto=udp after proto=tcp, v2 after v3, 878 + * mountproto=tcp after mountproto=udp, and so on 879 + */ 880 + static int nfs23_parse_monolithic(struct fs_context *fc, 881 + struct nfs_mount_data *data) 882 + { 883 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 884 + struct nfs_fh *mntfh = ctx->mntfh; 885 + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 886 + int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; 887 + 888 + if (data == NULL) 889 + goto out_no_data; 890 + 891 + ctx->version = NFS_DEFAULT_VERSION; 892 + switch (data->version) { 893 + case 1: 894 + data->namlen = 0; /* fall through */ 895 + case 2: 896 + data->bsize = 0; /* fall through */ 897 + case 3: 898 + if (data->flags & NFS_MOUNT_VER3) 899 + goto out_no_v3; 900 + data->root.size = NFS2_FHSIZE; 901 + memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 902 + /* Turn off security negotiation */ 903 + extra_flags |= NFS_MOUNT_SECFLAVOUR; 904 + /* fall through */ 905 + case 4: 906 + if (data->flags & NFS_MOUNT_SECFLAVOUR) 907 + goto out_no_sec; 908 + /* fall through */ 909 + case 5: 910 + memset(data->context, 0, sizeof(data->context)); 911 + /* fall through */ 912 + case 6: 913 + if (data->flags & NFS_MOUNT_VER3) { 914 + if (data->root.size > NFS3_FHSIZE || data->root.size == 0) 915 + goto out_invalid_fh; 916 + mntfh->size = data->root.size; 917 + ctx->version = 3; 918 + } else { 919 + mntfh->size = NFS2_FHSIZE; 920 + ctx->version = 2; 921 + } 922 + 923 + 924 + memcpy(mntfh->data, data->root.data, mntfh->size); 925 + if (mntfh->size < sizeof(mntfh->data)) 926 + memset(mntfh->data + mntfh->size, 0, 927 + sizeof(mntfh->data) - mntfh->size); 928 + 929 + /* 930 + * Translate to nfs_fs_context, which nfs_fill_super 931 + * can deal with. 932 + */ 933 + ctx->flags = data->flags & NFS_MOUNT_FLAGMASK; 934 + ctx->flags |= extra_flags; 935 + ctx->rsize = data->rsize; 936 + ctx->wsize = data->wsize; 937 + ctx->timeo = data->timeo; 938 + ctx->retrans = data->retrans; 939 + ctx->acregmin = data->acregmin; 940 + ctx->acregmax = data->acregmax; 941 + ctx->acdirmin = data->acdirmin; 942 + ctx->acdirmax = data->acdirmax; 943 + ctx->need_mount = false; 944 + 945 + memcpy(sap, &data->addr, sizeof(data->addr)); 946 + ctx->nfs_server.addrlen = sizeof(data->addr); 947 + ctx->nfs_server.port = ntohs(data->addr.sin_port); 948 + if (sap->sa_family != AF_INET || 949 + !nfs_verify_server_address(sap)) 950 + goto out_no_address; 951 + 952 + if (!(data->flags & NFS_MOUNT_TCP)) 953 + ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; 954 + /* N.B. caller will free nfs_server.hostname in all cases */ 955 + ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); 956 + if (!ctx->nfs_server.hostname) 957 + goto out_nomem; 958 + 959 + ctx->namlen = data->namlen; 960 + ctx->bsize = data->bsize; 961 + 962 + if (data->flags & NFS_MOUNT_SECFLAVOUR) 963 + ctx->selected_flavor = data->pseudoflavor; 964 + else 965 + ctx->selected_flavor = RPC_AUTH_UNIX; 966 + 967 + if (!(data->flags & NFS_MOUNT_NONLM)) 968 + ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| 969 + NFS_MOUNT_LOCAL_FCNTL); 970 + else 971 + ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK| 972 + NFS_MOUNT_LOCAL_FCNTL); 973 + 974 + /* 975 + * The legacy version 6 binary mount data from userspace has a 976 + * field used only to transport selinux information into the 977 + * the kernel. To continue to support that functionality we 978 + * have a touch of selinux knowledge here in the NFS code. The 979 + * userspace code converted context=blah to just blah so we are 980 + * converting back to the full string selinux understands. 981 + */ 982 + if (data->context[0]){ 983 + #ifdef CONFIG_SECURITY_SELINUX 984 + int ret; 985 + 986 + data->context[NFS_MAX_CONTEXT_LEN] = '\0'; 987 + ret = vfs_parse_fs_string(fc, "context", 988 + data->context, strlen(data->context)); 989 + if (ret < 0) 990 + return ret; 991 + #else 992 + return -EINVAL; 993 + #endif 994 + } 995 + 996 + break; 997 + default: 998 + goto generic; 999 + } 1000 + 1001 + ctx->skip_reconfig_option_check = true; 1002 + return 0; 1003 + 1004 + generic: 1005 + return generic_parse_monolithic(fc, data); 1006 + 1007 + out_no_data: 1008 + if (is_remount_fc(fc)) { 1009 + ctx->skip_reconfig_option_check = true; 1010 + return 0; 1011 + } 1012 + return nfs_invalf(fc, "NFS: mount program didn't pass any mount data"); 1013 + 1014 + out_no_v3: 1015 + return nfs_invalf(fc, "NFS: nfs_mount_data version does not support v3"); 1016 + 1017 + out_no_sec: 1018 + return nfs_invalf(fc, "NFS: nfs_mount_data version supports only AUTH_SYS"); 1019 + 1020 + out_nomem: 1021 + dfprintk(MOUNT, "NFS: not enough memory to handle mount options"); 1022 + return -ENOMEM; 1023 + 1024 + out_no_address: 1025 + return nfs_invalf(fc, "NFS: mount program didn't pass remote address"); 1026 + 1027 + out_invalid_fh: 1028 + return nfs_invalf(fc, "NFS: invalid root filehandle"); 1029 + } 1030 + 1031 + #if IS_ENABLED(CONFIG_NFS_V4) 1032 + /* 1033 + * Validate NFSv4 mount options 1034 + */ 1035 + static int nfs4_parse_monolithic(struct fs_context *fc, 1036 + struct nfs4_mount_data *data) 1037 + { 1038 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1039 + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 1040 + char *c; 1041 + 1042 + if (data == NULL) 1043 + goto out_no_data; 1044 + 1045 + ctx->version = 4; 1046 + 1047 + switch (data->version) { 1048 + case 1: 1049 + if (data->host_addrlen > sizeof(ctx->nfs_server.address)) 1050 + goto out_no_address; 1051 + if (data->host_addrlen == 0) 1052 + goto out_no_address; 1053 + ctx->nfs_server.addrlen = data->host_addrlen; 1054 + if (copy_from_user(sap, data->host_addr, data->host_addrlen)) 1055 + return -EFAULT; 1056 + if (!nfs_verify_server_address(sap)) 1057 + goto out_no_address; 1058 + ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 1059 + 1060 + if (data->auth_flavourlen) { 1061 + rpc_authflavor_t pseudoflavor; 1062 + if (data->auth_flavourlen > 1) 1063 + goto out_inval_auth; 1064 + if (copy_from_user(&pseudoflavor, 1065 + data->auth_flavours, 1066 + sizeof(pseudoflavor))) 1067 + return -EFAULT; 1068 + ctx->selected_flavor = pseudoflavor; 1069 + } else 1070 + ctx->selected_flavor = RPC_AUTH_UNIX; 1071 + 1072 + c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 1073 + if (IS_ERR(c)) 1074 + return PTR_ERR(c); 1075 + ctx->nfs_server.hostname = c; 1076 + 1077 + c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); 1078 + if (IS_ERR(c)) 1079 + return PTR_ERR(c); 1080 + ctx->nfs_server.export_path = c; 1081 + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1082 + 1083 + c = strndup_user(data->client_addr.data, 16); 1084 + if (IS_ERR(c)) 1085 + return PTR_ERR(c); 1086 + ctx->client_address = c; 1087 + 1088 + /* 1089 + * Translate to nfs_fs_context, which nfs_fill_super 1090 + * can deal with. 1091 + */ 1092 + 1093 + ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1094 + ctx->rsize = data->rsize; 1095 + ctx->wsize = data->wsize; 1096 + ctx->timeo = data->timeo; 1097 + ctx->retrans = data->retrans; 1098 + ctx->acregmin = data->acregmin; 1099 + ctx->acregmax = data->acregmax; 1100 + ctx->acdirmin = data->acdirmin; 1101 + ctx->acdirmax = data->acdirmax; 1102 + ctx->nfs_server.protocol = data->proto; 1103 + nfs_validate_transport_protocol(ctx); 1104 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1105 + goto out_invalid_transport_udp; 1106 + 1107 + break; 1108 + default: 1109 + goto generic; 1110 + } 1111 + 1112 + ctx->skip_reconfig_option_check = true; 1113 + return 0; 1114 + 1115 + generic: 1116 + return generic_parse_monolithic(fc, data); 1117 + 1118 + out_no_data: 1119 + if (is_remount_fc(fc)) { 1120 + ctx->skip_reconfig_option_check = true; 1121 + return 0; 1122 + } 1123 + return nfs_invalf(fc, "NFS4: mount program didn't pass any mount data"); 1124 + 1125 + out_inval_auth: 1126 + return nfs_invalf(fc, "NFS4: Invalid number of RPC auth flavours %d", 1127 + data->auth_flavourlen); 1128 + 1129 + out_no_address: 1130 + return nfs_invalf(fc, "NFS4: mount program didn't pass remote address"); 1131 + 1132 + out_invalid_transport_udp: 1133 + return nfs_invalf(fc, "NFSv4: Unsupported transport protocol udp"); 1134 + } 1135 + #endif 1136 + 1137 + /* 1138 + * Parse a monolithic block of data from sys_mount(). 1139 + */ 1140 + static int nfs_fs_context_parse_monolithic(struct fs_context *fc, 1141 + void *data) 1142 + { 1143 + if (fc->fs_type == &nfs_fs_type) 1144 + return nfs23_parse_monolithic(fc, data); 1145 + 1146 + #if IS_ENABLED(CONFIG_NFS_V4) 1147 + if (fc->fs_type == &nfs4_fs_type) 1148 + return nfs4_parse_monolithic(fc, data); 1149 + #endif 1150 + 1151 + return nfs_invalf(fc, "NFS: Unsupported monolithic data version"); 1152 + } 1153 + 1154 + /* 1155 + * Validate the preparsed information in the config. 1156 + */ 1157 + static int nfs_fs_context_validate(struct fs_context *fc) 1158 + { 1159 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1160 + struct nfs_subversion *nfs_mod; 1161 + struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 1162 + int max_namelen = PAGE_SIZE; 1163 + int max_pathlen = NFS_MAXPATHLEN; 1164 + int port = 0; 1165 + int ret; 1166 + 1167 + if (!fc->source) 1168 + goto out_no_device_name; 1169 + 1170 + /* Check for sanity first. */ 1171 + if (ctx->minorversion && ctx->version != 4) 1172 + goto out_minorversion_mismatch; 1173 + 1174 + if (ctx->options & NFS_OPTION_MIGRATION && 1175 + (ctx->version != 4 || ctx->minorversion != 0)) 1176 + goto out_migration_misuse; 1177 + 1178 + /* Verify that any proto=/mountproto= options match the address 1179 + * families in the addr=/mountaddr= options. 1180 + */ 1181 + if (ctx->protofamily != AF_UNSPEC && 1182 + ctx->protofamily != ctx->nfs_server.address.sa_family) 1183 + goto out_proto_mismatch; 1184 + 1185 + if (ctx->mountfamily != AF_UNSPEC) { 1186 + if (ctx->mount_server.addrlen) { 1187 + if (ctx->mountfamily != ctx->mount_server.address.sa_family) 1188 + goto out_mountproto_mismatch; 1189 + } else { 1190 + if (ctx->mountfamily != ctx->nfs_server.address.sa_family) 1191 + goto out_mountproto_mismatch; 1192 + } 1193 + } 1194 + 1195 + if (!nfs_verify_server_address(sap)) 1196 + goto out_no_address; 1197 + 1198 + if (ctx->version == 4) { 1199 + if (IS_ENABLED(CONFIG_NFS_V4)) { 1200 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1201 + port = NFS_RDMA_PORT; 1202 + else 1203 + port = NFS_PORT; 1204 + max_namelen = NFS4_MAXNAMLEN; 1205 + max_pathlen = NFS4_MAXPATHLEN; 1206 + nfs_validate_transport_protocol(ctx); 1207 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1208 + goto out_invalid_transport_udp; 1209 + ctx->flags &= ~(NFS_MOUNT_NONLM | NFS_MOUNT_NOACL | 1210 + NFS_MOUNT_VER3 | NFS_MOUNT_LOCAL_FLOCK | 1211 + NFS_MOUNT_LOCAL_FCNTL); 1212 + } else { 1213 + goto out_v4_not_compiled; 1214 + } 1215 + } else { 1216 + nfs_set_mount_transport_protocol(ctx); 1217 + #ifdef CONFIG_NFS_DISABLE_UDP_SUPPORT 1218 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1219 + goto out_invalid_transport_udp; 1220 + #endif 1221 + if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1222 + port = NFS_RDMA_PORT; 1223 + } 1224 + 1225 + nfs_set_port(sap, &ctx->nfs_server.port, port); 1226 + 1227 + ret = nfs_parse_source(fc, max_namelen, max_pathlen); 1228 + if (ret < 0) 1229 + return ret; 1230 + 1231 + /* Load the NFS protocol module if we haven't done so yet */ 1232 + if (!ctx->nfs_mod) { 1233 + nfs_mod = get_nfs_version(ctx->version); 1234 + if (IS_ERR(nfs_mod)) { 1235 + ret = PTR_ERR(nfs_mod); 1236 + goto out_version_unavailable; 1237 + } 1238 + ctx->nfs_mod = nfs_mod; 1239 + } 1240 + return 0; 1241 + 1242 + out_no_device_name: 1243 + return nfs_invalf(fc, "NFS: Device name not specified"); 1244 + out_v4_not_compiled: 1245 + nfs_errorf(fc, "NFS: NFSv4 is not compiled into kernel"); 1246 + return -EPROTONOSUPPORT; 1247 + out_invalid_transport_udp: 1248 + return nfs_invalf(fc, "NFSv4: Unsupported transport protocol udp"); 1249 + out_no_address: 1250 + return nfs_invalf(fc, "NFS: mount program didn't pass remote address"); 1251 + out_mountproto_mismatch: 1252 + return nfs_invalf(fc, "NFS: Mount server address does not match mountproto= option"); 1253 + out_proto_mismatch: 1254 + return nfs_invalf(fc, "NFS: Server address does not match proto= option"); 1255 + out_minorversion_mismatch: 1256 + return nfs_invalf(fc, "NFS: Mount option vers=%u does not support minorversion=%u", 1257 + ctx->version, ctx->minorversion); 1258 + out_migration_misuse: 1259 + return nfs_invalf(fc, "NFS: 'Migration' not supported for this NFS version"); 1260 + out_version_unavailable: 1261 + nfs_errorf(fc, "NFS: Version unavailable"); 1262 + return ret; 1263 + } 1264 + 1265 + /* 1266 + * Create an NFS superblock by the appropriate method. 1267 + */ 1268 + static int nfs_get_tree(struct fs_context *fc) 1269 + { 1270 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1271 + int err = nfs_fs_context_validate(fc); 1272 + 1273 + if (err) 1274 + return err; 1275 + if (!ctx->internal) 1276 + return ctx->nfs_mod->rpc_ops->try_get_tree(fc); 1277 + else 1278 + return nfs_get_tree_common(fc); 1279 + } 1280 + 1281 + /* 1282 + * Handle duplication of a configuration. The caller copied *src into *sc, but 1283 + * it can't deal with resource pointers in the filesystem context, so we have 1284 + * to do that. We need to clear pointers, copy data or get extra refs as 1285 + * appropriate. 1286 + */ 1287 + static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) 1288 + { 1289 + struct nfs_fs_context *src = nfs_fc2context(src_fc), *ctx; 1290 + 1291 + ctx = kmemdup(src, sizeof(struct nfs_fs_context), GFP_KERNEL); 1292 + if (!ctx) 1293 + return -ENOMEM; 1294 + 1295 + ctx->mntfh = nfs_alloc_fhandle(); 1296 + if (!ctx->mntfh) { 1297 + kfree(ctx); 1298 + return -ENOMEM; 1299 + } 1300 + nfs_copy_fh(ctx->mntfh, src->mntfh); 1301 + 1302 + __module_get(ctx->nfs_mod->owner); 1303 + ctx->client_address = NULL; 1304 + ctx->mount_server.hostname = NULL; 1305 + ctx->nfs_server.export_path = NULL; 1306 + ctx->nfs_server.hostname = NULL; 1307 + ctx->fscache_uniq = NULL; 1308 + ctx->clone_data.fattr = NULL; 1309 + fc->fs_private = ctx; 1310 + return 0; 1311 + } 1312 + 1313 + static void nfs_fs_context_free(struct fs_context *fc) 1314 + { 1315 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1316 + 1317 + if (ctx) { 1318 + if (ctx->server) 1319 + nfs_free_server(ctx->server); 1320 + if (ctx->nfs_mod) 1321 + put_nfs_version(ctx->nfs_mod); 1322 + kfree(ctx->client_address); 1323 + kfree(ctx->mount_server.hostname); 1324 + kfree(ctx->nfs_server.export_path); 1325 + kfree(ctx->nfs_server.hostname); 1326 + kfree(ctx->fscache_uniq); 1327 + nfs_free_fhandle(ctx->mntfh); 1328 + nfs_free_fattr(ctx->clone_data.fattr); 1329 + kfree(ctx); 1330 + } 1331 + } 1332 + 1333 + static const struct fs_context_operations nfs_fs_context_ops = { 1334 + .free = nfs_fs_context_free, 1335 + .dup = nfs_fs_context_dup, 1336 + .parse_param = nfs_fs_context_parse_param, 1337 + .parse_monolithic = nfs_fs_context_parse_monolithic, 1338 + .get_tree = nfs_get_tree, 1339 + .reconfigure = nfs_reconfigure, 1340 + }; 1341 + 1342 + /* 1343 + * Prepare superblock configuration. We use the namespaces attached to the 1344 + * context. This may be the current process's namespaces, or it may be a 1345 + * container's namespaces. 1346 + */ 1347 + static int nfs_init_fs_context(struct fs_context *fc) 1348 + { 1349 + struct nfs_fs_context *ctx; 1350 + 1351 + ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL); 1352 + if (unlikely(!ctx)) 1353 + return -ENOMEM; 1354 + 1355 + ctx->mntfh = nfs_alloc_fhandle(); 1356 + if (unlikely(!ctx->mntfh)) { 1357 + kfree(ctx); 1358 + return -ENOMEM; 1359 + } 1360 + 1361 + ctx->protofamily = AF_UNSPEC; 1362 + ctx->mountfamily = AF_UNSPEC; 1363 + ctx->mount_server.port = NFS_UNSPEC_PORT; 1364 + 1365 + if (fc->root) { 1366 + /* reconfigure, start with the current config */ 1367 + struct nfs_server *nfss = fc->root->d_sb->s_fs_info; 1368 + struct net *net = nfss->nfs_client->cl_net; 1369 + 1370 + ctx->flags = nfss->flags; 1371 + ctx->rsize = nfss->rsize; 1372 + ctx->wsize = nfss->wsize; 1373 + ctx->retrans = nfss->client->cl_timeout->to_retries; 1374 + ctx->selected_flavor = nfss->client->cl_auth->au_flavor; 1375 + ctx->acregmin = nfss->acregmin / HZ; 1376 + ctx->acregmax = nfss->acregmax / HZ; 1377 + ctx->acdirmin = nfss->acdirmin / HZ; 1378 + ctx->acdirmax = nfss->acdirmax / HZ; 1379 + ctx->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; 1380 + ctx->nfs_server.port = nfss->port; 1381 + ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; 1382 + ctx->version = nfss->nfs_client->rpc_ops->version; 1383 + ctx->minorversion = nfss->nfs_client->cl_minorversion; 1384 + 1385 + memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr, 1386 + ctx->nfs_server.addrlen); 1387 + 1388 + if (fc->net_ns != net) { 1389 + put_net(fc->net_ns); 1390 + fc->net_ns = get_net(net); 1391 + } 1392 + 1393 + ctx->nfs_mod = nfss->nfs_client->cl_nfs_mod; 1394 + __module_get(ctx->nfs_mod->owner); 1395 + } else { 1396 + /* defaults */ 1397 + ctx->timeo = NFS_UNSPEC_TIMEO; 1398 + ctx->retrans = NFS_UNSPEC_RETRANS; 1399 + ctx->acregmin = NFS_DEF_ACREGMIN; 1400 + ctx->acregmax = NFS_DEF_ACREGMAX; 1401 + ctx->acdirmin = NFS_DEF_ACDIRMIN; 1402 + ctx->acdirmax = NFS_DEF_ACDIRMAX; 1403 + ctx->nfs_server.port = NFS_UNSPEC_PORT; 1404 + ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1405 + ctx->selected_flavor = RPC_AUTH_MAXFLAVOR; 1406 + ctx->minorversion = 0; 1407 + ctx->need_mount = true; 1408 + } 1409 + fc->fs_private = ctx; 1410 + fc->ops = &nfs_fs_context_ops; 1411 + return 0; 1412 + } 1413 + 1414 + struct file_system_type nfs_fs_type = { 1415 + .owner = THIS_MODULE, 1416 + .name = "nfs", 1417 + .init_fs_context = nfs_init_fs_context, 1418 + .parameters = &nfs_fs_parameters, 1419 + .kill_sb = nfs_kill_super, 1420 + .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 1421 + }; 1422 + MODULE_ALIAS_FS("nfs"); 1423 + EXPORT_SYMBOL_GPL(nfs_fs_type); 1424 + 1425 + #if IS_ENABLED(CONFIG_NFS_V4) 1426 + struct file_system_type nfs4_fs_type = { 1427 + .owner = THIS_MODULE, 1428 + .name = "nfs4", 1429 + .init_fs_context = nfs_init_fs_context, 1430 + .parameters = &nfs_fs_parameters, 1431 + .kill_sb = nfs_kill_super, 1432 + .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 1433 + }; 1434 + MODULE_ALIAS_FS("nfs4"); 1435 + MODULE_ALIAS("nfs4"); 1436 + EXPORT_SYMBOL_GPL(nfs4_fs_type); 1437 + #endif /* CONFIG_NFS_V4 */
+1 -1
fs/nfs/fscache.c
··· 128 128 return; 129 129 130 130 key->nfs_client = nfss->nfs_client; 131 - key->key.super.s_flags = sb->s_flags & NFS_MS_MASK; 131 + key->key.super.s_flags = sb->s_flags & NFS_SB_MASK; 132 132 key->key.nfs_server.flags = nfss->flags; 133 133 key->key.nfs_server.rsize = nfss->rsize; 134 134 key->key.nfs_server.wsize = nfss->wsize;
+39 -34
fs/nfs/getroot.c
··· 64 64 /* 65 65 * get an NFS2/NFS3 root dentry from the root filehandle 66 66 */ 67 - struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh, 68 - const char *devname) 67 + int nfs_get_root(struct super_block *s, struct fs_context *fc) 69 68 { 70 - struct nfs_server *server = NFS_SB(sb); 69 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 70 + struct nfs_server *server = NFS_SB(s); 71 71 struct nfs_fsinfo fsinfo; 72 - struct dentry *ret; 72 + struct dentry *root; 73 73 struct inode *inode; 74 - void *name = kstrdup(devname, GFP_KERNEL); 75 - int error; 74 + char *name; 75 + int error = -ENOMEM; 76 76 77 + name = kstrdup(fc->source, GFP_KERNEL); 77 78 if (!name) 78 - return ERR_PTR(-ENOMEM); 79 + goto out; 79 80 80 81 /* get the actual root for this mount */ 81 82 fsinfo.fattr = nfs_alloc_fattr(); 82 - if (fsinfo.fattr == NULL) { 83 - kfree(name); 84 - return ERR_PTR(-ENOMEM); 85 - } 83 + if (fsinfo.fattr == NULL) 84 + goto out_name; 86 85 87 - error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); 86 + error = server->nfs_client->rpc_ops->getroot(server, ctx->mntfh, &fsinfo); 88 87 if (error < 0) { 89 88 dprintk("nfs_get_root: getattr error = %d\n", -error); 90 - ret = ERR_PTR(error); 91 - goto out; 89 + nfs_errorf(fc, "NFS: Couldn't getattr on root"); 90 + goto out_fattr; 92 91 } 93 92 94 - inode = nfs_fhget(sb, mntfh, fsinfo.fattr, NULL); 93 + inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr, NULL); 95 94 if (IS_ERR(inode)) { 96 95 dprintk("nfs_get_root: get root inode failed\n"); 97 - ret = ERR_CAST(inode); 98 - goto out; 96 + error = PTR_ERR(inode); 97 + nfs_errorf(fc, "NFS: Couldn't get root inode"); 98 + goto out_fattr; 99 99 } 100 100 101 - error = nfs_superblock_set_dummy_root(sb, inode); 102 - if (error != 0) { 103 - ret = ERR_PTR(error); 104 - goto out; 105 - } 101 + error = nfs_superblock_set_dummy_root(s, inode); 102 + if (error != 0) 103 + goto out_fattr; 106 104 107 105 /* root dentries normally start off anonymous and get spliced in later 108 106 * if the dentry tree reaches them; however if the dentry already 109 107 * exists, we'll pick it up at this point and use it as the root 110 108 */ 111 - ret = d_obtain_root(inode); 112 - if (IS_ERR(ret)) { 109 + root = d_obtain_root(inode); 110 + if (IS_ERR(root)) { 113 111 dprintk("nfs_get_root: get root dentry failed\n"); 114 - goto out; 112 + error = PTR_ERR(root); 113 + nfs_errorf(fc, "NFS: Couldn't get root dentry"); 114 + goto out_fattr; 115 115 } 116 116 117 - security_d_instantiate(ret, inode); 118 - spin_lock(&ret->d_lock); 119 - if (IS_ROOT(ret) && !ret->d_fsdata && 120 - !(ret->d_flags & DCACHE_NFSFS_RENAMED)) { 121 - ret->d_fsdata = name; 117 + security_d_instantiate(root, inode); 118 + spin_lock(&root->d_lock); 119 + if (IS_ROOT(root) && !root->d_fsdata && 120 + !(root->d_flags & DCACHE_NFSFS_RENAMED)) { 121 + root->d_fsdata = name; 122 122 name = NULL; 123 123 } 124 - spin_unlock(&ret->d_lock); 125 - out: 126 - kfree(name); 124 + spin_unlock(&root->d_lock); 125 + fc->root = root; 126 + error = 0; 127 + 128 + out_fattr: 127 129 nfs_free_fattr(fsinfo.fattr); 128 - return ret; 130 + out_name: 131 + kfree(name); 132 + out: 133 + return error; 129 134 }
+8 -2
fs/nfs/inode.c
··· 1061 1061 1062 1062 rcu_read_lock(); 1063 1063 list_for_each_entry_rcu(pos, &nfsi->open_files, list) { 1064 - if (cred != NULL && pos->cred != cred) 1064 + if (cred != NULL && cred_fscmp(pos->cred, cred) != 0) 1065 1065 continue; 1066 1066 if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode) 1067 1067 continue; ··· 1156 1156 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n", 1157 1157 inode->i_sb->s_id, 1158 1158 (unsigned long long)NFS_FILEID(inode), status); 1159 - if (status == -ESTALE) { 1159 + switch (status) { 1160 + case -ETIMEDOUT: 1161 + /* A soft timeout occurred. Use cached information? */ 1162 + if (server->flags & NFS_MOUNT_SOFTREVAL) 1163 + status = 0; 1164 + break; 1165 + case -ESTALE: 1160 1166 nfs_zap_caches(inode); 1161 1167 if (!S_ISDIR(inode->i_mode)) 1162 1168 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
+78 -65
fs/nfs/internal.h
··· 4 4 */ 5 5 6 6 #include "nfs4_fs.h" 7 - #include <linux/mount.h> 7 + #include <linux/fs_context.h> 8 8 #include <linux/security.h> 9 9 #include <linux/crc32.h> 10 + #include <linux/sunrpc/addr.h> 10 11 #include <linux/nfs_page.h> 11 12 #include <linux/wait_bit.h> 12 13 13 - #define NFS_MS_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) 14 + #define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) 14 15 15 16 extern const struct export_operations nfs_export_ops; 16 17 17 18 struct nfs_string; 19 + struct nfs_pageio_descriptor; 18 20 19 21 static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr) 20 22 { ··· 33 31 return 1; 34 32 } 35 33 36 - struct nfs_clone_mount { 37 - const struct super_block *sb; 38 - const struct dentry *dentry; 39 - struct nfs_fh *fh; 40 - struct nfs_fattr *fattr; 41 - char *hostname; 42 - char *mnt_path; 43 - struct sockaddr *addr; 44 - size_t addrlen; 45 - rpc_authflavor_t authflavor; 46 - }; 34 + static inline bool nfs_lookup_is_soft_revalidate(const struct dentry *dentry) 35 + { 36 + if (!(NFS_SB(dentry->d_sb)->flags & NFS_MOUNT_SOFTREVAL)) 37 + return false; 38 + if (!d_is_positive(dentry) || !NFS_FH(d_inode(dentry))->size) 39 + return false; 40 + return true; 41 + } 47 42 48 43 /* 49 44 * Note: RFC 1813 doesn't limit the number of auth flavors that ··· 81 82 /* 82 83 * In-kernel mount arguments 83 84 */ 84 - struct nfs_parsed_mount_data { 85 - int flags; 85 + struct nfs_fs_context { 86 + bool internal; 87 + bool skip_reconfig_option_check; 88 + bool need_mount; 89 + bool sloppy; 90 + unsigned int flags; /* NFS{,4}_MOUNT_* flags */ 86 91 unsigned int rsize, wsize; 87 92 unsigned int timeo, retrans; 88 - unsigned int acregmin, acregmax, 89 - acdirmin, acdirmax; 93 + unsigned int acregmin, acregmax; 94 + unsigned int acdirmin, acdirmax; 90 95 unsigned int namlen; 91 96 unsigned int options; 92 97 unsigned int bsize; ··· 100 97 unsigned int version; 101 98 unsigned int minorversion; 102 99 char *fscache_uniq; 103 - bool need_mount; 100 + unsigned short protofamily; 101 + unsigned short mountfamily; 104 102 105 103 struct { 106 - struct sockaddr_storage address; 104 + union { 105 + struct sockaddr address; 106 + struct sockaddr_storage _address; 107 + }; 107 108 size_t addrlen; 108 109 char *hostname; 109 110 u32 version; ··· 116 109 } mount_server; 117 110 118 111 struct { 119 - struct sockaddr_storage address; 112 + union { 113 + struct sockaddr address; 114 + struct sockaddr_storage _address; 115 + }; 120 116 size_t addrlen; 121 117 char *hostname; 122 118 char *export_path; 123 119 int port; 124 120 unsigned short protocol; 125 121 unsigned short nconnect; 122 + unsigned short export_path_len; 126 123 } nfs_server; 127 124 128 - void *lsm_opts; 129 - struct net *net; 125 + struct nfs_fh *mntfh; 126 + struct nfs_server *server; 127 + struct nfs_subversion *nfs_mod; 128 + 129 + /* Information for a cloned mount. */ 130 + struct nfs_clone_mount { 131 + struct super_block *sb; 132 + struct dentry *dentry; 133 + struct nfs_fattr *fattr; 134 + unsigned int inherited_bsize; 135 + } clone_data; 130 136 }; 137 + 138 + #define nfs_errorf(fc, fmt, ...) errorf(fc, fmt, ## __VA_ARGS__) 139 + #define nfs_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__) 140 + #define nfs_warnf(fc, fmt, ...) warnf(fc, fmt, ## __VA_ARGS__) 141 + 142 + static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc) 143 + { 144 + return fc->fs_private; 145 + } 131 146 132 147 /* mount_clnt.c */ 133 148 struct nfs_mount_request { ··· 164 135 unsigned int *auth_flav_len; 165 136 rpc_authflavor_t *auth_flavs; 166 137 struct net *net; 167 - }; 168 - 169 - struct nfs_mount_info { 170 - void (*fill_super)(struct super_block *, struct nfs_mount_info *); 171 - int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *); 172 - struct nfs_parsed_mount_data *parsed; 173 - struct nfs_clone_mount *cloned; 174 - struct nfs_fh *mntfh; 175 138 }; 176 139 177 140 extern int nfs_mount(struct nfs_mount_request *info); ··· 191 170 extern struct nfs_client * 192 171 nfs4_find_client_sessionid(struct net *, const struct sockaddr *, 193 172 struct nfs4_sessionid *, u32); 194 - extern struct nfs_server *nfs_create_server(struct nfs_mount_info *, 195 - struct nfs_subversion *); 196 - extern struct nfs_server *nfs4_create_server( 197 - struct nfs_mount_info *, 198 - struct nfs_subversion *); 199 - extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, 200 - struct nfs_fh *); 173 + extern struct nfs_server *nfs_create_server(struct fs_context *); 174 + extern struct nfs_server *nfs4_create_server(struct fs_context *); 175 + extern struct nfs_server *nfs4_create_referral_server(struct fs_context *); 201 176 extern int nfs4_update_server(struct nfs_server *server, const char *hostname, 202 177 struct sockaddr *sap, size_t salen, 203 178 struct net *net); ··· 244 227 extern const struct svc_version nfs4_callback_version1; 245 228 extern const struct svc_version nfs4_callback_version4; 246 229 247 - struct nfs_pageio_descriptor; 230 + /* fs_context.c */ 231 + extern struct file_system_type nfs_fs_type; 232 + 248 233 /* pagelist.c */ 249 234 extern int __init nfs_init_nfspagecache(void); 250 235 extern void nfs_destroy_nfspagecache(void); ··· 406 387 407 388 /* super.c */ 408 389 extern const struct super_operations nfs_sops; 409 - extern struct file_system_type nfs_fs_type; 410 - extern struct file_system_type nfs_xdev_fs_type; 411 - #if IS_ENABLED(CONFIG_NFS_V4) 412 - extern struct file_system_type nfs4_referral_fs_type; 413 - #endif 414 390 bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); 415 - struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, 416 - struct nfs_subversion *); 417 - int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); 418 - int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); 419 - struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *, 420 - struct nfs_mount_info *, struct nfs_subversion *); 421 - struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); 422 - struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, 423 - const char *, struct nfs_mount_info *); 391 + int nfs_try_get_tree(struct fs_context *); 392 + int nfs_get_tree_common(struct fs_context *); 424 393 void nfs_kill_super(struct super_block *); 425 - void nfs_fill_super(struct super_block *, struct nfs_mount_info *); 426 394 427 395 extern struct rpc_stat nfs_rpcstat; 428 396 ··· 436 430 extern char *nfs_path(char **p, struct dentry *dentry, 437 431 char *buffer, ssize_t buflen, unsigned flags); 438 432 extern struct vfsmount *nfs_d_automount(struct path *path); 439 - struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, 440 - struct nfs_fh *, struct nfs_fattr *); 441 - struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *, 442 - struct nfs_fattr *, rpc_authflavor_t); 433 + int nfs_submount(struct fs_context *, struct nfs_server *); 434 + int nfs_do_submount(struct fs_context *); 443 435 444 436 /* getroot.c */ 445 - extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, 446 - const char *); 437 + extern int nfs_get_root(struct super_block *s, struct fs_context *fc); 447 438 #if IS_ENABLED(CONFIG_NFS_V4) 448 - extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, 449 - const char *); 450 - 451 439 extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool); 452 440 #endif 453 441 ··· 460 460 int nfs_show_devname(struct seq_file *, struct dentry *); 461 461 int nfs_show_path(struct seq_file *, struct dentry *); 462 462 int nfs_show_stats(struct seq_file *, struct dentry *); 463 - int nfs_remount(struct super_block *sb, int *flags, char *raw_data); 463 + int nfs_reconfigure(struct fs_context *); 464 464 465 465 /* write.c */ 466 466 extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, ··· 706 706 } 707 707 708 708 /* 709 - * Convert a struct timespec into a 64-bit change attribute 709 + * Convert a struct timespec64 into a 64-bit change attribute 710 710 * 711 - * This does approximately the same thing as timespec_to_ns(), 711 + * This does approximately the same thing as timespec64_to_ns(), 712 712 * but for calculation efficiency, we multiply the seconds by 713 713 * 1024*1024*1024. 714 714 */ ··· 776 776 return false; 777 777 } 778 778 return nfs_error_is_fatal(err); 779 + } 780 + 781 + /* 782 + * Select between a default port value and a user-specified port value. 783 + * If a zero value is set, then autobind will be used. 784 + */ 785 + static inline void nfs_set_port(struct sockaddr *sap, int *port, 786 + const unsigned short default_port) 787 + { 788 + if (*port == NFS_UNSPEC_PORT) 789 + *port = default_port; 790 + 791 + rpc_set_port(sap, *port); 779 792 }
-2
fs/nfs/mount_clnt.c
··· 29 29 */ 30 30 #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) 31 31 #define MNT_status_sz (1) 32 - #define MNT_fhs_status_sz (1) 33 32 #define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE) 34 - #define MNT_fhandle3_sz (1 + XDR_QUADLEN(NFS3_FHSIZE)) 35 33 #define MNT_authflav3_sz (1 + NFS_MAX_SECFLAVORS) 36 34 37 35 /*
+89 -51
fs/nfs/namespace.c
··· 19 19 #include <linux/vfs.h> 20 20 #include <linux/sunrpc/gss_api.h> 21 21 #include "internal.h" 22 + #include "nfs.h" 22 23 23 24 #define NFSDBG_FACILITY NFSDBG_VFS 24 25 ··· 140 139 */ 141 140 struct vfsmount *nfs_d_automount(struct path *path) 142 141 { 143 - struct vfsmount *mnt; 142 + struct nfs_fs_context *ctx; 143 + struct fs_context *fc; 144 + struct vfsmount *mnt = ERR_PTR(-ENOMEM); 144 145 struct nfs_server *server = NFS_SERVER(d_inode(path->dentry)); 145 - struct nfs_fh *fh = NULL; 146 - struct nfs_fattr *fattr = NULL; 146 + struct nfs_client *client = server->nfs_client; 147 + int ret; 147 148 148 149 if (IS_ROOT(path->dentry)) 149 150 return ERR_PTR(-ESTALE); 150 151 151 - mnt = ERR_PTR(-ENOMEM); 152 - fh = nfs_alloc_fhandle(); 153 - fattr = nfs_alloc_fattr(); 154 - if (fh == NULL || fattr == NULL) 155 - goto out; 152 + /* Open a new filesystem context, transferring parameters from the 153 + * parent superblock, including the network namespace. 154 + */ 155 + fc = fs_context_for_submount(&nfs_fs_type, path->dentry); 156 + if (IS_ERR(fc)) 157 + return ERR_CAST(fc); 156 158 157 - mnt = server->nfs_client->rpc_ops->submount(server, path->dentry, fh, fattr); 159 + ctx = nfs_fc2context(fc); 160 + ctx->clone_data.dentry = path->dentry; 161 + ctx->clone_data.sb = path->dentry->d_sb; 162 + ctx->clone_data.fattr = nfs_alloc_fattr(); 163 + if (!ctx->clone_data.fattr) 164 + goto out_fc; 165 + 166 + if (fc->net_ns != client->cl_net) { 167 + put_net(fc->net_ns); 168 + fc->net_ns = get_net(client->cl_net); 169 + } 170 + 171 + /* for submounts we want the same server; referrals will reassign */ 172 + memcpy(&ctx->nfs_server.address, &client->cl_addr, client->cl_addrlen); 173 + ctx->nfs_server.addrlen = client->cl_addrlen; 174 + ctx->nfs_server.port = server->port; 175 + 176 + ctx->version = client->rpc_ops->version; 177 + ctx->minorversion = client->cl_minorversion; 178 + ctx->nfs_mod = client->cl_nfs_mod; 179 + __module_get(ctx->nfs_mod->owner); 180 + 181 + ret = client->rpc_ops->submount(fc, server); 182 + if (ret < 0) { 183 + mnt = ERR_PTR(ret); 184 + goto out_fc; 185 + } 186 + 187 + up_write(&fc->root->d_sb->s_umount); 188 + mnt = vfs_create_mount(fc); 158 189 if (IS_ERR(mnt)) 159 - goto out; 190 + goto out_fc; 160 191 161 192 if (nfs_mountpoint_expiry_timeout < 0) 162 - goto out; 193 + goto out_fc; 163 194 164 195 mntget(mnt); /* prevent immediate expiration */ 165 196 mnt_set_expiry(mnt, &nfs_automount_list); 166 197 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); 167 198 168 - out: 169 - nfs_free_fattr(fattr); 170 - nfs_free_fhandle(fh); 199 + out_fc: 200 + put_fs_context(fc); 171 201 return mnt; 172 202 } 173 203 ··· 245 213 cancel_delayed_work(&nfs_automount_task); 246 214 } 247 215 248 - /* 249 - * Clone a mountpoint of the appropriate type 250 - */ 251 - static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, 252 - const char *devname, 253 - struct nfs_clone_mount *mountdata) 254 - { 255 - return vfs_submount(mountdata->dentry, &nfs_xdev_fs_type, devname, mountdata); 256 - } 257 - 258 216 /** 259 217 * nfs_do_submount - set up mountpoint when crossing a filesystem boundary 260 218 * @dentry: parent directory ··· 253 231 * @authflavor: security flavor to use when performing the mount 254 232 * 255 233 */ 256 - struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh, 257 - struct nfs_fattr *fattr, rpc_authflavor_t authflavor) 234 + int nfs_do_submount(struct fs_context *fc) 258 235 { 259 - struct nfs_clone_mount mountdata = { 260 - .sb = dentry->d_sb, 261 - .dentry = dentry, 262 - .fh = fh, 263 - .fattr = fattr, 264 - .authflavor = authflavor, 265 - }; 266 - struct vfsmount *mnt; 267 - char *page = (char *) __get_free_page(GFP_USER); 268 - char *devname; 236 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 237 + struct dentry *dentry = ctx->clone_data.dentry; 238 + struct nfs_server *server; 239 + char *buffer, *p; 240 + int ret; 269 241 270 - if (page == NULL) 271 - return ERR_PTR(-ENOMEM); 242 + /* create a new volume representation */ 243 + server = ctx->nfs_mod->rpc_ops->clone_server(NFS_SB(ctx->clone_data.sb), 244 + ctx->mntfh, 245 + ctx->clone_data.fattr, 246 + ctx->selected_flavor); 272 247 273 - devname = nfs_devname(dentry, page, PAGE_SIZE); 274 - if (IS_ERR(devname)) 275 - mnt = ERR_CAST(devname); 276 - else 277 - mnt = nfs_do_clone_mount(NFS_SB(dentry->d_sb), devname, &mountdata); 248 + if (IS_ERR(server)) 249 + return PTR_ERR(server); 278 250 279 - free_page((unsigned long)page); 280 - return mnt; 251 + ctx->server = server; 252 + 253 + buffer = kmalloc(4096, GFP_USER); 254 + if (!buffer) 255 + return -ENOMEM; 256 + 257 + ctx->internal = true; 258 + ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits; 259 + 260 + p = nfs_devname(dentry, buffer, 4096); 261 + if (IS_ERR(p)) { 262 + nfs_errorf(fc, "NFS: Couldn't determine submount pathname"); 263 + ret = PTR_ERR(p); 264 + } else { 265 + ret = vfs_parse_fs_string(fc, "source", p, buffer + 4096 - p); 266 + if (!ret) 267 + ret = vfs_get_tree(fc); 268 + } 269 + kfree(buffer); 270 + return ret; 281 271 } 282 272 EXPORT_SYMBOL_GPL(nfs_do_submount); 283 273 284 - struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry, 285 - struct nfs_fh *fh, struct nfs_fattr *fattr) 274 + int nfs_submount(struct fs_context *fc, struct nfs_server *server) 286 275 { 287 - int err; 276 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 277 + struct dentry *dentry = ctx->clone_data.dentry; 288 278 struct dentry *parent = dget_parent(dentry); 279 + int err; 289 280 290 281 /* Look it up again to get its attributes */ 291 - err = server->nfs_client->rpc_ops->lookup(d_inode(parent), &dentry->d_name, fh, fattr, NULL); 282 + err = server->nfs_client->rpc_ops->lookup(d_inode(parent), dentry, 283 + ctx->mntfh, ctx->clone_data.fattr, 284 + NULL); 292 285 dput(parent); 293 286 if (err != 0) 294 - return ERR_PTR(err); 287 + return err; 295 288 296 - return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor); 289 + ctx->selected_flavor = server->client->cl_auth->au_flavor; 290 + return nfs_do_submount(fc); 297 291 } 298 292 EXPORT_SYMBOL_GPL(nfs_submount);
+6 -6
fs/nfs/nfs2xdr.c
··· 360 360 else 361 361 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 362 362 363 - if (attr->ia_valid & ATTR_ATIME_SET) { 363 + if (attr->ia_valid & ATTR_ATIME_SET) 364 364 p = xdr_encode_time(p, &attr->ia_atime); 365 - } else if (attr->ia_valid & ATTR_ATIME) { 365 + else if (attr->ia_valid & ATTR_ATIME) 366 366 p = xdr_encode_current_server_time(p, &attr->ia_atime); 367 - } else 367 + else 368 368 p = xdr_time_not_set(p); 369 - if (attr->ia_valid & ATTR_MTIME_SET) { 369 + if (attr->ia_valid & ATTR_MTIME_SET) 370 370 xdr_encode_time(p, &attr->ia_mtime); 371 - } else if (attr->ia_valid & ATTR_MTIME) { 371 + else if (attr->ia_valid & ATTR_MTIME) 372 372 xdr_encode_current_server_time(p, &attr->ia_mtime); 373 - } else 373 + else 374 374 xdr_time_not_set(p); 375 375 } 376 376
+1 -1
fs/nfs/nfs3_fs.h
··· 27 27 #endif /* CONFIG_NFS_V3_ACL */ 28 28 29 29 /* nfs3client.c */ 30 - struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *); 30 + struct nfs_server *nfs3_create_server(struct fs_context *); 31 31 struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *, 32 32 struct nfs_fattr *, rpc_authflavor_t); 33 33
+3 -3
fs/nfs/nfs3client.c
··· 46 46 } 47 47 #endif 48 48 49 - struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info, 50 - struct nfs_subversion *nfs_mod) 49 + struct nfs_server *nfs3_create_server(struct fs_context *fc) 51 50 { 52 - struct nfs_server *server = nfs_create_server(mount_info, nfs_mod); 51 + struct nfs_server *server = nfs_create_server(fc); 52 + 53 53 /* Create a client RPC handle for the NFS v3 ACL management interface */ 54 54 if (!IS_ERR(server)) 55 55 nfs_init_server_aclclient(server);
+19 -9
fs/nfs/nfs3proc.c
··· 110 110 .rpc_resp = fattr, 111 111 }; 112 112 int status; 113 + unsigned short task_flags = 0; 114 + 115 + /* Is this is an attribute revalidation, subject to softreval? */ 116 + if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) 117 + task_flags |= RPC_TASK_TIMEOUT; 113 118 114 119 dprintk("NFS call getattr\n"); 115 120 nfs_fattr_init(fattr); 116 - status = rpc_call_sync(server->client, &msg, 0); 121 + status = rpc_call_sync(server->client, &msg, task_flags); 117 122 dprintk("NFS reply getattr: %d\n", status); 118 123 return status; 119 124 } ··· 145 140 nfs_fattr_init(fattr); 146 141 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 147 142 if (status == 0) { 143 + nfs_setattr_update_inode(inode, sattr, fattr); 148 144 if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) 149 145 nfs_zap_acl_cache(inode); 150 - nfs_setattr_update_inode(inode, sattr, fattr); 151 146 } 152 147 dprintk("NFS reply setattr: %d\n", status); 153 148 return status; 154 149 } 155 150 156 151 static int 157 - nfs3_proc_lookup(struct inode *dir, const struct qstr *name, 152 + nfs3_proc_lookup(struct inode *dir, struct dentry *dentry, 158 153 struct nfs_fh *fhandle, struct nfs_fattr *fattr, 159 154 struct nfs4_label *label) 160 155 { 161 156 struct nfs3_diropargs arg = { 162 157 .fh = NFS_FH(dir), 163 - .name = name->name, 164 - .len = name->len 158 + .name = dentry->d_name.name, 159 + .len = dentry->d_name.len 165 160 }; 166 161 struct nfs3_diropres res = { 167 162 .fh = fhandle, ··· 173 168 .rpc_resp = &res, 174 169 }; 175 170 int status; 171 + unsigned short task_flags = 0; 176 172 177 - dprintk("NFS call lookup %s\n", name->name); 173 + /* Is this is an attribute revalidation, subject to softreval? */ 174 + if (nfs_lookup_is_soft_revalidate(dentry)) 175 + task_flags |= RPC_TASK_TIMEOUT; 176 + 177 + dprintk("NFS call lookup %pd2\n", dentry); 178 178 res.dir_attr = nfs_alloc_fattr(); 179 179 if (res.dir_attr == NULL) 180 180 return -ENOMEM; 181 181 182 182 nfs_fattr_init(fattr); 183 - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 183 + status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags); 184 184 nfs_refresh_inode(dir, res.dir_attr); 185 185 if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { 186 186 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; 187 187 msg.rpc_argp = fhandle; 188 188 msg.rpc_resp = fattr; 189 - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 189 + status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags); 190 190 } 191 191 nfs_free_fattr(res.dir_attr); 192 192 dprintk("NFS reply lookup: %d\n", status); ··· 1000 990 .nlmclnt_ops = &nlmclnt_fl_close_lock_ops, 1001 991 .getroot = nfs3_proc_get_root, 1002 992 .submount = nfs_submount, 1003 - .try_mount = nfs_try_mount, 993 + .try_get_tree = nfs_try_get_tree, 1004 994 .getattr = nfs3_proc_getattr, 1005 995 .setattr = nfs3_proc_setattr, 1006 996 .lookup = nfs3_proc_lookup,
+4 -1
fs/nfs/nfs3xdr.c
··· 2334 2334 void *data) 2335 2335 { 2336 2336 struct nfs_commitres *result = data; 2337 + struct nfs_writeverf *verf = result->verf; 2337 2338 enum nfs_stat status; 2338 2339 int error; 2339 2340 ··· 2347 2346 result->op_status = status; 2348 2347 if (status != NFS3_OK) 2349 2348 goto out_status; 2350 - error = decode_writeverf3(xdr, &result->verf->verifier); 2349 + error = decode_writeverf3(xdr, &verf->verifier); 2350 + if (!error) 2351 + verf->committed = NFS_FILE_SYNC; 2351 2352 out: 2352 2353 return error; 2353 2354 out_status:
+30 -10
fs/nfs/nfs42proc.c
··· 61 61 62 62 status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context, 63 63 lock, FMODE_WRITE); 64 - if (status) 64 + if (status) { 65 + if (status == -EAGAIN) 66 + status = -NFS4ERR_BAD_STATEID; 65 67 return status; 68 + } 66 69 67 70 res.falloc_fattr = nfs_alloc_fattr(); 68 71 if (!res.falloc_fattr) ··· 290 287 } else { 291 288 status = nfs4_set_rw_stateid(&args->src_stateid, 292 289 src_lock->open_context, src_lock, FMODE_READ); 293 - if (status) 290 + if (status) { 291 + if (status == -EAGAIN) 292 + status = -NFS4ERR_BAD_STATEID; 294 293 return status; 294 + } 295 295 } 296 296 status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping, 297 297 pos_src, pos_src + (loff_t)count - 1); ··· 303 297 304 298 status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context, 305 299 dst_lock, FMODE_WRITE); 306 - if (status) 300 + if (status) { 301 + if (status == -EAGAIN) 302 + status = -NFS4ERR_BAD_STATEID; 307 303 return status; 304 + } 308 305 309 306 status = nfs_sync_inode(dst_inode); 310 307 if (status) ··· 343 334 status = handle_async_copy(res, dst_server, src_server, src, 344 335 dst, &args->src_stateid, restart); 345 336 if (status) 346 - return status; 337 + goto out; 347 338 } 348 339 349 340 if ((!res->synchronous || !args->sync) && 350 341 res->write_res.verifier.committed != NFS_FILE_SYNC) { 351 342 status = process_copy_commit(dst, pos_dst, res); 352 343 if (status) 353 - return status; 344 + goto out; 354 345 } 355 346 356 347 truncate_pagecache_range(dst_inode, pos_dst, ··· 555 546 status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx, 556 547 FMODE_READ); 557 548 nfs_put_lock_context(l_ctx); 558 - if (status) 549 + if (status) { 550 + if (status == -EAGAIN) 551 + status = -NFS4ERR_BAD_STATEID; 559 552 return status; 553 + } 560 554 561 555 status = nfs4_call_sync(src_server->client, src_server, &msg, 562 556 &args->cna_seq_args, &res->cnr_seq_res, 0); ··· 630 618 631 619 status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context, 632 620 lock, FMODE_READ); 633 - if (status) 621 + if (status) { 622 + if (status == -EAGAIN) 623 + status = -NFS4ERR_BAD_STATEID; 634 624 return status; 625 + } 635 626 636 627 status = nfs_filemap_write_and_wait_range(inode->i_mapping, 637 628 offset, LLONG_MAX); ··· 1009 994 1010 995 status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context, 1011 996 src_lock, FMODE_READ); 1012 - if (status) 997 + if (status) { 998 + if (status == -EAGAIN) 999 + status = -NFS4ERR_BAD_STATEID; 1013 1000 return status; 1014 - 1001 + } 1015 1002 status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context, 1016 1003 dst_lock, FMODE_WRITE); 1017 - if (status) 1004 + if (status) { 1005 + if (status == -EAGAIN) 1006 + status = -NFS4ERR_BAD_STATEID; 1018 1007 return status; 1008 + } 1019 1009 1020 1010 res.dst_fattr = nfs_alloc_fattr(); 1021 1011 if (!res.dst_fattr)
+10 -9
fs/nfs/nfs4_fs.h
··· 268 268 int nfs_atomic_open(struct inode *, struct dentry *, struct file *, 269 269 unsigned, umode_t); 270 270 271 - /* super.c */ 271 + /* fs_context.c */ 272 272 extern struct file_system_type nfs4_fs_type; 273 273 274 274 /* nfs4namespace.c */ 275 275 struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, 276 276 const struct qstr *); 277 - struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *, 278 - struct nfs_fh *, struct nfs_fattr *); 277 + int nfs4_submount(struct fs_context *, struct nfs_server *); 279 278 int nfs4_replace_transport(struct nfs_server *server, 280 279 const struct nfs4_fs_locations *locations); 281 280 ··· 302 303 extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *, 303 304 struct page *page, const struct cred *); 304 305 extern int nfs4_proc_fsid_present(struct inode *, const struct cred *); 305 - extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, const struct qstr *, 306 - struct nfs_fh *, struct nfs_fattr *); 306 + extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, 307 + struct dentry *, 308 + struct nfs_fh *, 309 + struct nfs_fattr *); 307 310 extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); 308 311 extern const struct xattr_handler *nfs4_xattr_handlers[]; 309 312 extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, ··· 447 446 extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); 448 447 extern void nfs4_kill_renewd(struct nfs_client *); 449 448 extern void nfs4_renew_state(struct work_struct *); 450 - extern void nfs4_set_lease_period(struct nfs_client *clp, 451 - unsigned long lease, 452 - unsigned long lastrenewed); 449 + extern void nfs4_set_lease_period(struct nfs_client *clp, unsigned long lease); 453 450 454 451 455 452 /* nfs4state.c */ ··· 525 526 /* nfs4super.c */ 526 527 struct nfs_mount_info; 527 528 extern struct nfs_subversion nfs_v4; 528 - struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); 529 529 extern bool nfs4_disable_idmapping; 530 530 extern unsigned short max_session_slots; 531 531 extern unsigned short max_session_cb_slots; ··· 533 535 534 536 #define NFS4_CLIENT_ID_UNIQ_LEN (64) 535 537 extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN]; 538 + 539 + extern int nfs4_try_get_tree(struct fs_context *); 540 + extern int nfs4_get_referral_tree(struct fs_context *); 536 541 537 542 /* nfs4sysctl.c */ 538 543 #ifdef CONFIG_SYSCTL
+50 -49
fs/nfs/nfs4client.c
··· 1055 1055 /* 1056 1056 * Create a version 4 volume record 1057 1057 */ 1058 - static int nfs4_init_server(struct nfs_server *server, 1059 - struct nfs_parsed_mount_data *data) 1058 + static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) 1060 1059 { 1060 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1061 1061 struct rpc_timeout timeparms; 1062 1062 int error; 1063 1063 1064 - nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 1065 - data->timeo, data->retrans); 1064 + nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol, 1065 + ctx->timeo, ctx->retrans); 1066 1066 1067 1067 /* Initialise the client representation from the mount data */ 1068 - server->flags = data->flags; 1069 - server->options = data->options; 1070 - server->auth_info = data->auth_info; 1068 + server->flags = ctx->flags; 1069 + server->options = ctx->options; 1070 + server->auth_info = ctx->auth_info; 1071 1071 1072 1072 /* Use the first specified auth flavor. If this flavor isn't 1073 1073 * allowed by the server, use the SECINFO path to try the 1074 1074 * other specified flavors */ 1075 - if (data->auth_info.flavor_len >= 1) 1076 - data->selected_flavor = data->auth_info.flavors[0]; 1075 + if (ctx->auth_info.flavor_len >= 1) 1076 + ctx->selected_flavor = ctx->auth_info.flavors[0]; 1077 1077 else 1078 - data->selected_flavor = RPC_AUTH_UNIX; 1078 + ctx->selected_flavor = RPC_AUTH_UNIX; 1079 1079 1080 1080 /* Get a client record */ 1081 1081 error = nfs4_set_client(server, 1082 - data->nfs_server.hostname, 1083 - (const struct sockaddr *)&data->nfs_server.address, 1084 - data->nfs_server.addrlen, 1085 - data->client_address, 1086 - data->nfs_server.protocol, 1087 - &timeparms, 1088 - data->minorversion, 1089 - data->nfs_server.nconnect, 1090 - data->net); 1082 + ctx->nfs_server.hostname, 1083 + &ctx->nfs_server.address, 1084 + ctx->nfs_server.addrlen, 1085 + ctx->client_address, 1086 + ctx->nfs_server.protocol, 1087 + &timeparms, 1088 + ctx->minorversion, 1089 + ctx->nfs_server.nconnect, 1090 + fc->net_ns); 1091 1091 if (error < 0) 1092 1092 return error; 1093 1093 1094 - if (data->rsize) 1095 - server->rsize = nfs_block_size(data->rsize, NULL); 1096 - if (data->wsize) 1097 - server->wsize = nfs_block_size(data->wsize, NULL); 1094 + if (ctx->rsize) 1095 + server->rsize = nfs_block_size(ctx->rsize, NULL); 1096 + if (ctx->wsize) 1097 + server->wsize = nfs_block_size(ctx->wsize, NULL); 1098 1098 1099 - server->acregmin = data->acregmin * HZ; 1100 - server->acregmax = data->acregmax * HZ; 1101 - server->acdirmin = data->acdirmin * HZ; 1102 - server->acdirmax = data->acdirmax * HZ; 1103 - server->port = data->nfs_server.port; 1099 + server->acregmin = ctx->acregmin * HZ; 1100 + server->acregmax = ctx->acregmax * HZ; 1101 + server->acdirmin = ctx->acdirmin * HZ; 1102 + server->acdirmax = ctx->acdirmax * HZ; 1103 + server->port = ctx->nfs_server.port; 1104 1104 1105 1105 return nfs_init_server_rpcclient(server, &timeparms, 1106 - data->selected_flavor); 1106 + ctx->selected_flavor); 1107 1107 } 1108 1108 1109 1109 /* 1110 1110 * Create a version 4 volume record 1111 1111 * - keyed on server and FSID 1112 1112 */ 1113 - /*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, 1114 - struct nfs_fh *mntfh)*/ 1115 - struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info, 1116 - struct nfs_subversion *nfs_mod) 1113 + struct nfs_server *nfs4_create_server(struct fs_context *fc) 1117 1114 { 1115 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1118 1116 struct nfs_server *server; 1119 1117 bool auth_probe; 1120 1118 int error; ··· 1123 1125 1124 1126 server->cred = get_cred(current_cred()); 1125 1127 1126 - auth_probe = mount_info->parsed->auth_info.flavor_len < 1; 1128 + auth_probe = ctx->auth_info.flavor_len < 1; 1127 1129 1128 1130 /* set up the general RPC client */ 1129 - error = nfs4_init_server(server, mount_info->parsed); 1131 + error = nfs4_init_server(server, fc); 1130 1132 if (error < 0) 1131 1133 goto error; 1132 1134 1133 - error = nfs4_server_common_setup(server, mount_info->mntfh, auth_probe); 1135 + error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe); 1134 1136 if (error < 0) 1135 1137 goto error; 1136 1138 ··· 1144 1146 /* 1145 1147 * Create an NFS4 referral server record 1146 1148 */ 1147 - struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, 1148 - struct nfs_fh *mntfh) 1149 + struct nfs_server *nfs4_create_referral_server(struct fs_context *fc) 1149 1150 { 1151 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1150 1152 struct nfs_client *parent_client; 1151 1153 struct nfs_server *server, *parent_server; 1152 1154 bool auth_probe; ··· 1156 1158 if (!server) 1157 1159 return ERR_PTR(-ENOMEM); 1158 1160 1159 - parent_server = NFS_SB(data->sb); 1161 + parent_server = NFS_SB(ctx->clone_data.sb); 1160 1162 parent_client = parent_server->nfs_client; 1161 1163 1162 1164 server->cred = get_cred(parent_server->cred); ··· 1166 1168 1167 1169 /* Get a client representation */ 1168 1170 #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) 1169 - rpc_set_port(data->addr, NFS_RDMA_PORT); 1170 - error = nfs4_set_client(server, data->hostname, 1171 - data->addr, 1172 - data->addrlen, 1171 + rpc_set_port(&ctx->nfs_server.address, NFS_RDMA_PORT); 1172 + error = nfs4_set_client(server, 1173 + ctx->nfs_server.hostname, 1174 + &ctx->nfs_server.address, 1175 + ctx->nfs_server.addrlen, 1173 1176 parent_client->cl_ipaddr, 1174 1177 XPRT_TRANSPORT_RDMA, 1175 1178 parent_server->client->cl_timeout, ··· 1181 1182 goto init_server; 1182 1183 #endif /* IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) */ 1183 1184 1184 - rpc_set_port(data->addr, NFS_PORT); 1185 - error = nfs4_set_client(server, data->hostname, 1186 - data->addr, 1187 - data->addrlen, 1185 + rpc_set_port(&ctx->nfs_server.address, NFS_PORT); 1186 + error = nfs4_set_client(server, 1187 + ctx->nfs_server.hostname, 1188 + &ctx->nfs_server.address, 1189 + ctx->nfs_server.addrlen, 1188 1190 parent_client->cl_ipaddr, 1189 1191 XPRT_TRANSPORT_TCP, 1190 1192 parent_server->client->cl_timeout, ··· 1198 1198 #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) 1199 1199 init_server: 1200 1200 #endif 1201 - error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); 1201 + error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, 1202 + ctx->selected_flavor); 1202 1203 if (error < 0) 1203 1204 goto error; 1204 1205 1205 1206 auth_probe = parent_server->auth_info.flavor_len < 1; 1206 1207 1207 - error = nfs4_server_common_setup(server, mntfh, auth_probe); 1208 + error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe); 1208 1209 if (error < 0) 1209 1210 goto error; 1210 1211
+1
fs/nfs/nfs4file.c
··· 7 7 #include <linux/fs.h> 8 8 #include <linux/file.h> 9 9 #include <linux/falloc.h> 10 + #include <linux/mount.h> 10 11 #include <linux/nfs_fs.h> 11 12 #include "delegation.h" 12 13 #include "internal.h"
+175 -127
fs/nfs/nfs4namespace.c
··· 8 8 * NFSv4 namespace 9 9 */ 10 10 11 + #include <linux/module.h> 11 12 #include <linux/dcache.h> 12 13 #include <linux/mount.h> 13 14 #include <linux/namei.h> ··· 22 21 #include <linux/inet.h> 23 22 #include "internal.h" 24 23 #include "nfs4_fs.h" 24 + #include "nfs.h" 25 25 #include "dns_resolve.h" 26 26 27 27 #define NFSDBG_FACILITY NFSDBG_VFS 28 28 29 29 /* 30 - * Convert the NFSv4 pathname components into a standard posix path. 31 - * 32 - * Note that the resulting string will be placed at the end of the buffer 30 + * Work out the length that an NFSv4 path would render to as a standard posix 31 + * path, with a leading slash but no terminating slash. 33 32 */ 34 - static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, 35 - char *buffer, ssize_t buflen) 33 + static ssize_t nfs4_pathname_len(const struct nfs4_pathname *pathname) 36 34 { 37 - char *end = buffer + buflen; 38 - int n; 35 + ssize_t len = 0; 36 + int i; 39 37 40 - *--end = '\0'; 41 - buflen--; 38 + for (i = 0; i < pathname->ncomponents; i++) { 39 + const struct nfs4_string *component = &pathname->components[i]; 42 40 43 - n = pathname->ncomponents; 44 - while (--n >= 0) { 45 - const struct nfs4_string *component = &pathname->components[n]; 46 - buflen -= component->len + 1; 47 - if (buflen < 0) 48 - goto Elong; 49 - end -= component->len; 50 - memcpy(end, component->data, component->len); 51 - *--end = '/'; 41 + if (component->len > NAME_MAX) 42 + goto too_long; 43 + len += 1 + component->len; /* Adding "/foo" */ 44 + if (len > PATH_MAX) 45 + goto too_long; 52 46 } 53 - return end; 54 - Elong: 55 - return ERR_PTR(-ENAMETOOLONG); 47 + return len; 48 + 49 + too_long: 50 + return -ENAMETOOLONG; 51 + } 52 + 53 + /* 54 + * Convert the NFSv4 pathname components into a standard posix path. 55 + */ 56 + static char *nfs4_pathname_string(const struct nfs4_pathname *pathname, 57 + unsigned short *_len) 58 + { 59 + ssize_t len; 60 + char *buf, *p; 61 + int i; 62 + 63 + len = nfs4_pathname_len(pathname); 64 + if (len < 0) 65 + return ERR_PTR(len); 66 + *_len = len; 67 + 68 + p = buf = kmalloc(len + 1, GFP_KERNEL); 69 + if (!buf) 70 + return ERR_PTR(-ENOMEM); 71 + 72 + for (i = 0; i < pathname->ncomponents; i++) { 73 + const struct nfs4_string *component = &pathname->components[i]; 74 + 75 + *p++ = '/'; 76 + memcpy(p, component->data, component->len); 77 + p += component->len; 78 + } 79 + 80 + *p = 0; 81 + return buf; 56 82 } 57 83 58 84 /* ··· 128 100 */ 129 101 static int nfs4_validate_fspath(struct dentry *dentry, 130 102 const struct nfs4_fs_locations *locations, 131 - char *page, char *page2) 103 + struct nfs_fs_context *ctx) 132 104 { 133 - const char *path, *fs_path; 105 + const char *path; 106 + char *fs_path; 107 + unsigned short len; 108 + char *buf; 109 + int n; 134 110 135 - path = nfs4_path(dentry, page, PAGE_SIZE); 136 - if (IS_ERR(path)) 111 + buf = kmalloc(4096, GFP_KERNEL); 112 + if (!buf) 113 + return -ENOMEM; 114 + 115 + path = nfs4_path(dentry, buf, 4096); 116 + if (IS_ERR(path)) { 117 + kfree(buf); 137 118 return PTR_ERR(path); 119 + } 138 120 139 - fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE); 140 - if (IS_ERR(fs_path)) 121 + fs_path = nfs4_pathname_string(&locations->fs_path, &len); 122 + if (IS_ERR(fs_path)) { 123 + kfree(buf); 141 124 return PTR_ERR(fs_path); 125 + } 142 126 143 - if (strncmp(path, fs_path, strlen(fs_path)) != 0) { 127 + n = strncmp(path, fs_path, len); 128 + kfree(buf); 129 + kfree(fs_path); 130 + if (n != 0) { 144 131 dprintk("%s: path %s does not begin with fsroot %s\n", 145 - __func__, path, fs_path); 132 + __func__, path, ctx->nfs_server.export_path); 146 133 return -ENOENT; 147 134 } 148 135 ··· 279 236 return new; 280 237 } 281 238 282 - static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, 283 - char *page, char *page2, 284 - const struct nfs4_fs_location *location) 239 + static int try_location(struct fs_context *fc, 240 + const struct nfs4_fs_location *location) 285 241 { 286 - const size_t addr_bufsize = sizeof(struct sockaddr_storage); 287 - struct net *net = rpc_net_ns(NFS_SB(mountdata->sb)->client); 288 - struct vfsmount *mnt = ERR_PTR(-ENOENT); 289 - char *mnt_path; 290 - unsigned int maxbuflen; 291 - unsigned int s; 242 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 243 + unsigned int len, s; 244 + char *export_path, *source, *p; 245 + int ret = -ENOENT; 292 246 293 - mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); 294 - if (IS_ERR(mnt_path)) 295 - return ERR_CAST(mnt_path); 296 - mountdata->mnt_path = mnt_path; 297 - maxbuflen = mnt_path - 1 - page2; 298 - 299 - mountdata->addr = kmalloc(addr_bufsize, GFP_KERNEL); 300 - if (mountdata->addr == NULL) 301 - return ERR_PTR(-ENOMEM); 302 - 247 + /* Allocate a buffer big enough to hold any of the hostnames plus a 248 + * terminating char and also a buffer big enough to hold the hostname 249 + * plus a colon plus the path. 250 + */ 251 + len = 0; 303 252 for (s = 0; s < location->nservers; s++) { 304 253 const struct nfs4_string *buf = &location->servers[s]; 254 + if (buf->len > len) 255 + len = buf->len; 256 + } 305 257 306 - if (buf->len <= 0 || buf->len >= maxbuflen) 307 - continue; 258 + kfree(ctx->nfs_server.hostname); 259 + ctx->nfs_server.hostname = kmalloc(len + 1, GFP_KERNEL); 260 + if (!ctx->nfs_server.hostname) 261 + return -ENOMEM; 262 + 263 + export_path = nfs4_pathname_string(&location->rootpath, 264 + &ctx->nfs_server.export_path_len); 265 + if (IS_ERR(export_path)) 266 + return PTR_ERR(export_path); 267 + 268 + ctx->nfs_server.export_path = export_path; 269 + 270 + source = kmalloc(len + 1 + ctx->nfs_server.export_path_len + 1, 271 + GFP_KERNEL); 272 + if (!source) 273 + return -ENOMEM; 274 + 275 + kfree(fc->source); 276 + fc->source = source; 277 + for (s = 0; s < location->nservers; s++) { 278 + const struct nfs4_string *buf = &location->servers[s]; 308 279 309 280 if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) 310 281 continue; 311 282 312 - mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len, 313 - mountdata->addr, addr_bufsize, net); 314 - if (mountdata->addrlen == 0) 283 + ctx->nfs_server.addrlen = 284 + nfs_parse_server_name(buf->data, buf->len, 285 + &ctx->nfs_server.address, 286 + sizeof(ctx->nfs_server._address), 287 + fc->net_ns); 288 + if (ctx->nfs_server.addrlen == 0) 315 289 continue; 316 290 317 - memcpy(page2, buf->data, buf->len); 318 - page2[buf->len] = '\0'; 319 - mountdata->hostname = page2; 291 + rpc_set_port(&ctx->nfs_server.address, NFS_PORT); 320 292 321 - snprintf(page, PAGE_SIZE, "%s:%s", 322 - mountdata->hostname, 323 - mountdata->mnt_path); 293 + memcpy(ctx->nfs_server.hostname, buf->data, buf->len); 294 + ctx->nfs_server.hostname[buf->len] = '\0'; 324 295 325 - mnt = vfs_submount(mountdata->dentry, &nfs4_referral_fs_type, page, mountdata); 326 - if (!IS_ERR(mnt)) 327 - break; 296 + p = source; 297 + memcpy(p, buf->data, buf->len); 298 + p += buf->len; 299 + *p++ = ':'; 300 + memcpy(p, ctx->nfs_server.export_path, ctx->nfs_server.export_path_len); 301 + p += ctx->nfs_server.export_path_len; 302 + *p = 0; 303 + 304 + ret = nfs4_get_referral_tree(fc); 305 + if (ret == 0) 306 + return 0; 328 307 } 329 - kfree(mountdata->addr); 330 - return mnt; 308 + 309 + return ret; 331 310 } 332 311 333 312 /** ··· 358 293 * @locations: array of NFSv4 server location information 359 294 * 360 295 */ 361 - static struct vfsmount *nfs_follow_referral(struct dentry *dentry, 362 - const struct nfs4_fs_locations *locations) 296 + static int nfs_follow_referral(struct fs_context *fc, 297 + const struct nfs4_fs_locations *locations) 363 298 { 364 - struct vfsmount *mnt = ERR_PTR(-ENOENT); 365 - struct nfs_clone_mount mountdata = { 366 - .sb = dentry->d_sb, 367 - .dentry = dentry, 368 - .authflavor = NFS_SB(dentry->d_sb)->client->cl_auth->au_flavor, 369 - }; 370 - char *page = NULL, *page2 = NULL; 299 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 371 300 int loc, error; 372 301 373 302 if (locations == NULL || locations->nlocations <= 0) 374 - goto out; 303 + return -ENOENT; 375 304 376 - dprintk("%s: referral at %pd2\n", __func__, dentry); 377 - 378 - page = (char *) __get_free_page(GFP_USER); 379 - if (!page) 380 - goto out; 381 - 382 - page2 = (char *) __get_free_page(GFP_USER); 383 - if (!page2) 384 - goto out; 305 + dprintk("%s: referral at %pd2\n", __func__, ctx->clone_data.dentry); 385 306 386 307 /* Ensure fs path is a prefix of current dentry path */ 387 - error = nfs4_validate_fspath(dentry, locations, page, page2); 388 - if (error < 0) { 389 - mnt = ERR_PTR(error); 390 - goto out; 391 - } 308 + error = nfs4_validate_fspath(ctx->clone_data.dentry, locations, ctx); 309 + if (error < 0) 310 + return error; 392 311 312 + error = -ENOENT; 393 313 for (loc = 0; loc < locations->nlocations; loc++) { 394 314 const struct nfs4_fs_location *location = &locations->locations[loc]; 395 315 ··· 382 332 location->rootpath.ncomponents == 0) 383 333 continue; 384 334 385 - mnt = try_location(&mountdata, page, page2, location); 386 - if (!IS_ERR(mnt)) 387 - break; 335 + error = try_location(fc, location); 336 + if (error == 0) 337 + return 0; 388 338 } 389 339 390 - out: 391 - free_page((unsigned long) page); 392 - free_page((unsigned long) page2); 393 - return mnt; 340 + return error; 394 341 } 395 342 396 343 /* ··· 395 348 * @dentry - dentry of referral 396 349 * 397 350 */ 398 - static struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) 351 + static int nfs_do_refmount(struct fs_context *fc, struct rpc_clnt *client) 399 352 { 400 - struct vfsmount *mnt = ERR_PTR(-ENOMEM); 401 - struct dentry *parent; 353 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 354 + struct dentry *dentry, *parent; 402 355 struct nfs4_fs_locations *fs_locations = NULL; 403 356 struct page *page; 404 - int err; 357 + int err = -ENOMEM; 405 358 406 359 /* BUG_ON(IS_ROOT(dentry)); */ 407 360 page = alloc_page(GFP_KERNEL); 408 - if (page == NULL) 409 - return mnt; 361 + if (!page) 362 + return -ENOMEM; 410 363 411 364 fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); 412 - if (fs_locations == NULL) 365 + if (!fs_locations) 413 366 goto out_free; 414 367 415 368 /* Get locations */ 416 - mnt = ERR_PTR(-ENOENT); 417 - 369 + dentry = ctx->clone_data.dentry; 418 370 parent = dget_parent(dentry); 419 371 dprintk("%s: getting locations for %pd2\n", 420 372 __func__, dentry); 421 373 422 374 err = nfs4_proc_fs_locations(client, d_inode(parent), &dentry->d_name, fs_locations, page); 423 375 dput(parent); 424 - if (err != 0 || 425 - fs_locations->nlocations <= 0 || 426 - fs_locations->fs_path.ncomponents <= 0) 427 - goto out_free; 376 + if (err != 0) 377 + goto out_free_2; 428 378 429 - mnt = nfs_follow_referral(dentry, fs_locations); 379 + err = -ENOENT; 380 + if (fs_locations->nlocations <= 0 || 381 + fs_locations->fs_path.ncomponents <= 0) 382 + goto out_free_2; 383 + 384 + err = nfs_follow_referral(fc, fs_locations); 385 + out_free_2: 386 + kfree(fs_locations); 430 387 out_free: 431 388 __free_page(page); 432 - kfree(fs_locations); 433 - return mnt; 389 + return err; 434 390 } 435 391 436 - struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry, 437 - struct nfs_fh *fh, struct nfs_fattr *fattr) 392 + int nfs4_submount(struct fs_context *fc, struct nfs_server *server) 438 393 { 439 - rpc_authflavor_t flavor = server->client->cl_auth->au_flavor; 394 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 395 + struct dentry *dentry = ctx->clone_data.dentry; 440 396 struct dentry *parent = dget_parent(dentry); 441 397 struct inode *dir = d_inode(parent); 442 - const struct qstr *name = &dentry->d_name; 443 398 struct rpc_clnt *client; 444 - struct vfsmount *mnt; 399 + int ret; 445 400 446 401 /* Look it up again to get its attributes and sec flavor */ 447 - client = nfs4_proc_lookup_mountpoint(dir, name, fh, fattr); 402 + client = nfs4_proc_lookup_mountpoint(dir, dentry, ctx->mntfh, 403 + ctx->clone_data.fattr); 448 404 dput(parent); 449 405 if (IS_ERR(client)) 450 - return ERR_CAST(client); 406 + return PTR_ERR(client); 451 407 452 - if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { 453 - mnt = nfs_do_refmount(client, dentry); 454 - goto out; 408 + ctx->selected_flavor = client->cl_auth->au_flavor; 409 + if (ctx->clone_data.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { 410 + ret = nfs_do_refmount(fc, client); 411 + } else { 412 + ret = nfs_do_submount(fc); 455 413 } 456 414 457 - if (client->cl_auth->au_flavor != flavor) 458 - flavor = client->cl_auth->au_flavor; 459 - mnt = nfs_do_submount(dentry, fh, fattr, flavor); 460 - out: 461 415 rpc_shutdown_client(client); 462 - return mnt; 416 + return ret; 463 417 } 464 418 465 419 /* ··· 501 453 rpc_set_port(sap, NFS_PORT); 502 454 503 455 error = -ENOMEM; 504 - hostname = kstrndup(buf->data, buf->len, GFP_KERNEL); 456 + hostname = kmemdup_nul(buf->data, buf->len, GFP_KERNEL); 505 457 if (hostname == NULL) 506 458 break; 507 459
+75 -29
fs/nfs/nfs4proc.c
··· 1097 1097 return ret; 1098 1098 } 1099 1099 1100 - static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, 1101 - struct nfs_server *server, 1102 - struct rpc_message *msg, 1103 - struct nfs4_sequence_args *args, 1104 - struct nfs4_sequence_res *res) 1100 + static int nfs4_do_call_sync(struct rpc_clnt *clnt, 1101 + struct nfs_server *server, 1102 + struct rpc_message *msg, 1103 + struct nfs4_sequence_args *args, 1104 + struct nfs4_sequence_res *res, 1105 + unsigned short task_flags) 1105 1106 { 1106 1107 struct nfs_client *clp = server->nfs_client; 1107 1108 struct nfs4_call_sync_data data = { ··· 1114 1113 .rpc_client = clnt, 1115 1114 .rpc_message = msg, 1116 1115 .callback_ops = clp->cl_mvops->call_sync_ops, 1117 - .callback_data = &data 1116 + .callback_data = &data, 1117 + .flags = task_flags, 1118 1118 }; 1119 1119 1120 1120 return nfs4_call_sync_custom(&task_setup); 1121 1121 } 1122 + 1123 + static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, 1124 + struct nfs_server *server, 1125 + struct rpc_message *msg, 1126 + struct nfs4_sequence_args *args, 1127 + struct nfs4_sequence_res *res) 1128 + { 1129 + return nfs4_do_call_sync(clnt, server, msg, args, res, 0); 1130 + } 1131 + 1122 1132 1123 1133 int nfs4_call_sync(struct rpc_clnt *clnt, 1124 1134 struct nfs_server *server, ··· 3199 3187 exception.retry = 1; 3200 3188 continue; 3201 3189 } 3190 + if (status == -NFS4ERR_EXPIRED) { 3191 + nfs4_schedule_lease_recovery(server->nfs_client); 3192 + exception.retry = 1; 3193 + continue; 3194 + } 3202 3195 if (status == -EAGAIN) { 3203 3196 /* We must have found a delegation */ 3204 3197 exception.retry = 1; ··· 3256 3239 nfs_put_lock_context(l_ctx); 3257 3240 if (status == -EIO) 3258 3241 return -EBADF; 3242 + else if (status == -EAGAIN) 3243 + goto zero_stateid; 3259 3244 } else { 3260 3245 zero_stateid: 3261 3246 nfs4_stateid_copy(&arg->stateid, &zero_stateid); ··· 4083 4064 .rpc_argp = &args, 4084 4065 .rpc_resp = &res, 4085 4066 }; 4067 + unsigned short task_flags = 0; 4068 + 4069 + /* Is this is an attribute revalidation, subject to softreval? */ 4070 + if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) 4071 + task_flags |= RPC_TASK_TIMEOUT; 4086 4072 4087 4073 nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode); 4088 4074 4089 4075 nfs_fattr_init(fattr); 4090 - return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 4076 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0); 4077 + return nfs4_do_call_sync(server->client, server, &msg, 4078 + &args.seq_args, &res.seq_res, task_flags); 4091 4079 } 4092 4080 4093 4081 int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, ··· 4182 4156 } 4183 4157 4184 4158 static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, 4185 - const struct qstr *name, struct nfs_fh *fhandle, 4159 + struct dentry *dentry, struct nfs_fh *fhandle, 4186 4160 struct nfs_fattr *fattr, struct nfs4_label *label) 4187 4161 { 4188 4162 struct nfs_server *server = NFS_SERVER(dir); ··· 4190 4164 struct nfs4_lookup_arg args = { 4191 4165 .bitmask = server->attr_bitmask, 4192 4166 .dir_fh = NFS_FH(dir), 4193 - .name = name, 4167 + .name = &dentry->d_name, 4194 4168 }; 4195 4169 struct nfs4_lookup_res res = { 4196 4170 .server = server, ··· 4203 4177 .rpc_argp = &args, 4204 4178 .rpc_resp = &res, 4205 4179 }; 4180 + unsigned short task_flags = 0; 4181 + 4182 + /* Is this is an attribute revalidation, subject to softreval? */ 4183 + if (nfs_lookup_is_soft_revalidate(dentry)) 4184 + task_flags |= RPC_TASK_TIMEOUT; 4206 4185 4207 4186 args.bitmask = nfs4_bitmask(server, label); 4208 4187 4209 4188 nfs_fattr_init(fattr); 4210 4189 4211 - dprintk("NFS call lookup %s\n", name->name); 4212 - status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0); 4190 + dprintk("NFS call lookup %pd2\n", dentry); 4191 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0); 4192 + status = nfs4_do_call_sync(clnt, server, &msg, 4193 + &args.seq_args, &res.seq_res, task_flags); 4213 4194 dprintk("NFS reply lookup: %d\n", status); 4214 4195 return status; 4215 4196 } ··· 4230 4197 } 4231 4198 4232 4199 static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, 4233 - const struct qstr *name, struct nfs_fh *fhandle, 4200 + struct dentry *dentry, struct nfs_fh *fhandle, 4234 4201 struct nfs_fattr *fattr, struct nfs4_label *label) 4235 4202 { 4236 4203 struct nfs4_exception exception = { 4237 4204 .interruptible = true, 4238 4205 }; 4239 4206 struct rpc_clnt *client = *clnt; 4207 + const struct qstr *name = &dentry->d_name; 4240 4208 int err; 4241 4209 do { 4242 - err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label); 4210 + err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label); 4243 4211 trace_nfs4_lookup(dir, name, err); 4244 4212 switch (err) { 4245 4213 case -NFS4ERR_BADNAME: ··· 4275 4241 return err; 4276 4242 } 4277 4243 4278 - static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name, 4244 + static int nfs4_proc_lookup(struct inode *dir, struct dentry *dentry, 4279 4245 struct nfs_fh *fhandle, struct nfs_fattr *fattr, 4280 4246 struct nfs4_label *label) 4281 4247 { 4282 4248 int status; 4283 4249 struct rpc_clnt *client = NFS_CLIENT(dir); 4284 4250 4285 - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, label); 4251 + status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label); 4286 4252 if (client != NFS_CLIENT(dir)) { 4287 4253 rpc_shutdown_client(client); 4288 4254 nfs_fixup_secinfo_attributes(fattr); ··· 4291 4257 } 4292 4258 4293 4259 struct rpc_clnt * 4294 - nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name, 4260 + nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry, 4295 4261 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 4296 4262 { 4297 4263 struct rpc_clnt *client = NFS_CLIENT(dir); 4298 4264 int status; 4299 4265 4300 - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL); 4266 + status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL); 4301 4267 if (status < 0) 4302 4268 return ERR_PTR(status); 4303 4269 return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client; ··· 5053 5019 struct nfs4_exception exception = { 5054 5020 .interruptible = true, 5055 5021 }; 5056 - unsigned long now = jiffies; 5057 5022 int err; 5058 5023 5059 5024 do { 5060 5025 err = _nfs4_do_fsinfo(server, fhandle, fsinfo); 5061 5026 trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err); 5062 5027 if (err == 0) { 5063 - nfs4_set_lease_period(server->nfs_client, 5064 - fsinfo->lease_time * HZ, 5065 - now); 5028 + nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time * HZ); 5066 5029 break; 5067 5030 } 5068 5031 err = nfs4_handle_exception(server, err, &exception); ··· 5613 5582 */ 5614 5583 static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) 5615 5584 { 5616 - struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, }; 5585 + struct page **pages; 5617 5586 struct nfs_getaclargs args = { 5618 5587 .fh = NFS_FH(inode), 5619 - .acl_pages = pages, 5620 5588 .acl_len = buflen, 5621 5589 }; 5622 5590 struct nfs_getaclres res = { ··· 5626 5596 .rpc_argp = &args, 5627 5597 .rpc_resp = &res, 5628 5598 }; 5629 - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1; 5599 + unsigned int npages; 5630 5600 int ret = -ENOMEM, i; 5601 + struct nfs_server *server = NFS_SERVER(inode); 5631 5602 5632 - if (npages > ARRAY_SIZE(pages)) 5633 - return -ERANGE; 5603 + if (buflen == 0) 5604 + buflen = server->rsize; 5605 + 5606 + npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1; 5607 + pages = kmalloc_array(npages, sizeof(struct page *), GFP_NOFS); 5608 + if (!pages) 5609 + return -ENOMEM; 5610 + 5611 + args.acl_pages = pages; 5634 5612 5635 5613 for (i = 0; i < npages; i++) { 5636 5614 pages[i] = alloc_page(GFP_KERNEL); ··· 5684 5646 __free_page(pages[i]); 5685 5647 if (res.acl_scratch) 5686 5648 __free_page(res.acl_scratch); 5649 + kfree(pages); 5687 5650 return ret; 5688 5651 } 5689 5652 ··· 6123 6084 .callback_data = &setclientid, 6124 6085 .flags = RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN, 6125 6086 }; 6087 + unsigned long now = jiffies; 6126 6088 int status; 6127 6089 6128 6090 /* nfs_client_id4 */ ··· 6156 6116 clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred); 6157 6117 put_rpccred(setclientid.sc_cred); 6158 6118 } 6119 + 6120 + if (status == 0) 6121 + do_renew_lease(clp, now); 6159 6122 out: 6160 6123 trace_nfs4_setclientid(clp, status); 6161 6124 dprintk("NFS reply setclientid: %d\n", status); ··· 6902 6859 case -NFS4ERR_STALE_STATEID: 6903 6860 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; 6904 6861 nfs4_schedule_lease_recovery(server->nfs_client); 6905 - }; 6862 + } 6906 6863 } 6907 6864 6908 6865 static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type) ··· 8246 8203 struct rpc_task *task; 8247 8204 struct nfs41_exchange_id_args *argp; 8248 8205 struct nfs41_exchange_id_res *resp; 8206 + unsigned long now = jiffies; 8249 8207 int status; 8250 8208 8251 8209 task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL); ··· 8266 8222 status = nfs4_sp4_select_mode(clp, &resp->state_protect); 8267 8223 if (status != 0) 8268 8224 goto out; 8225 + 8226 + do_renew_lease(clp, now); 8269 8227 8270 8228 clp->cl_clientid = resp->clientid; 8271 8229 clp->cl_exchange_flags = resp->flags; ··· 8672 8626 case -EACCES: 8673 8627 case -EAGAIN: 8674 8628 goto out; 8675 - }; 8629 + } 8676 8630 8677 8631 clp->cl_seqid++; 8678 8632 if (!status) { ··· 10047 10001 .file_ops = &nfs4_file_operations, 10048 10002 .getroot = nfs4_proc_get_root, 10049 10003 .submount = nfs4_submount, 10050 - .try_mount = nfs4_try_mount, 10004 + .try_get_tree = nfs4_try_get_tree, 10051 10005 .getattr = nfs4_proc_getattr, 10052 10006 .setattr = nfs4_proc_setattr, 10053 10007 .lookup = nfs4_proc_lookup,
+1 -4
fs/nfs/nfs4renewd.c
··· 138 138 * 139 139 * @clp: pointer to nfs_client 140 140 * @lease: new value for lease period 141 - * @lastrenewed: time at which lease was last renewed 142 141 */ 143 142 void nfs4_set_lease_period(struct nfs_client *clp, 144 - unsigned long lease, 145 - unsigned long lastrenewed) 143 + unsigned long lease) 146 144 { 147 145 spin_lock(&clp->cl_lock); 148 146 clp->cl_lease_time = lease; 149 - clp->cl_last_renewal = lastrenewed; 150 147 spin_unlock(&clp->cl_lock); 151 148 152 149 /* Cap maximum reconnect timeout at 1/2 lease period */
+3 -4
fs/nfs/nfs4state.c
··· 92 92 { 93 93 int status; 94 94 struct nfs_fsinfo fsinfo; 95 - unsigned long now; 96 95 97 96 if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) { 98 97 nfs4_schedule_state_renewal(clp); 99 98 return 0; 100 99 } 101 100 102 - now = jiffies; 103 101 status = nfs4_proc_get_lease_time(clp, &fsinfo); 104 102 if (status == 0) { 105 - nfs4_set_lease_period(clp, fsinfo.lease_time * HZ, now); 103 + nfs4_set_lease_period(clp, fsinfo.lease_time * HZ); 106 104 nfs4_schedule_state_renewal(clp); 107 105 } 108 106 ··· 764 766 list_del(&state->open_states); 765 767 spin_unlock(&inode->i_lock); 766 768 spin_unlock(&owner->so_lock); 769 + nfs4_inode_return_delegation_on_close(inode); 767 770 iput(inode); 768 771 nfs4_free_open_state(state); 769 772 nfs4_put_state_owner(owner); ··· 1134 1135 case -NFS4ERR_MOVED: 1135 1136 /* Non-seqid mutating errors */ 1136 1137 return; 1137 - }; 1138 + } 1138 1139 /* 1139 1140 * Note: no locking needed as we are guaranteed to be first 1140 1141 * on the sequence list
+98 -161
fs/nfs/nfs4super.c
··· 4 4 */ 5 5 #include <linux/init.h> 6 6 #include <linux/module.h> 7 + #include <linux/mount.h> 7 8 #include <linux/nfs4_mount.h> 8 9 #include <linux/nfs_fs.h> 9 10 #include "delegation.h" ··· 19 18 20 19 static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc); 21 20 static void nfs4_evict_inode(struct inode *inode); 22 - static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, 23 - int flags, const char *dev_name, void *raw_data); 24 - static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, 25 - int flags, const char *dev_name, void *raw_data); 26 - static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, 27 - int flags, const char *dev_name, void *raw_data); 28 - 29 - static struct file_system_type nfs4_remote_fs_type = { 30 - .owner = THIS_MODULE, 31 - .name = "nfs4", 32 - .mount = nfs4_remote_mount, 33 - .kill_sb = nfs_kill_super, 34 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 35 - }; 36 - 37 - static struct file_system_type nfs4_remote_referral_fs_type = { 38 - .owner = THIS_MODULE, 39 - .name = "nfs4", 40 - .mount = nfs4_remote_referral_mount, 41 - .kill_sb = nfs_kill_super, 42 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 43 - }; 44 - 45 - struct file_system_type nfs4_referral_fs_type = { 46 - .owner = THIS_MODULE, 47 - .name = "nfs4", 48 - .mount = nfs4_referral_mount, 49 - .kill_sb = nfs_kill_super, 50 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 51 - }; 52 21 53 22 static const struct super_operations nfs4_sops = { 54 23 .alloc_inode = nfs_alloc_inode, ··· 32 61 .show_devname = nfs_show_devname, 33 62 .show_path = nfs_show_path, 34 63 .show_stats = nfs_show_stats, 35 - .remount_fs = nfs_remount, 36 64 }; 37 65 38 66 struct nfs_subversion nfs_v4 = { 39 - .owner = THIS_MODULE, 40 - .nfs_fs = &nfs4_fs_type, 41 - .rpc_vers = &nfs_version4, 42 - .rpc_ops = &nfs_v4_clientops, 43 - .sops = &nfs4_sops, 44 - .xattr = nfs4_xattr_handlers, 67 + .owner = THIS_MODULE, 68 + .nfs_fs = &nfs4_fs_type, 69 + .rpc_vers = &nfs_version4, 70 + .rpc_ops = &nfs_v4_clientops, 71 + .sops = &nfs4_sops, 72 + .xattr = nfs4_xattr_handlers, 45 73 }; 46 74 47 75 static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc) ··· 69 99 pnfs_destroy_layout(NFS_I(inode)); 70 100 /* First call standard NFS clear_inode() code */ 71 101 nfs_clear_inode(inode); 72 - } 73 - 74 - /* 75 - * Get the superblock for the NFS4 root partition 76 - */ 77 - static struct dentry * 78 - nfs4_remote_mount(struct file_system_type *fs_type, int flags, 79 - const char *dev_name, void *info) 80 - { 81 - struct nfs_mount_info *mount_info = info; 82 - struct nfs_server *server; 83 - struct dentry *mntroot = ERR_PTR(-ENOMEM); 84 - 85 - mount_info->set_security = nfs_set_sb_security; 86 - 87 - /* Get a volume representation */ 88 - server = nfs4_create_server(mount_info, &nfs_v4); 89 - if (IS_ERR(server)) { 90 - mntroot = ERR_CAST(server); 91 - goto out; 92 - } 93 - 94 - mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4); 95 - 96 - out: 97 - return mntroot; 98 - } 99 - 100 - static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, 101 - int flags, void *data, const char *hostname) 102 - { 103 - struct vfsmount *root_mnt; 104 - char *root_devname; 105 - size_t len; 106 - 107 - len = strlen(hostname) + 5; 108 - root_devname = kmalloc(len, GFP_KERNEL); 109 - if (root_devname == NULL) 110 - return ERR_PTR(-ENOMEM); 111 - /* Does hostname needs to be enclosed in brackets? */ 112 - if (strchr(hostname, ':')) 113 - snprintf(root_devname, len, "[%s]:/", hostname); 114 - else 115 - snprintf(root_devname, len, "%s:/", hostname); 116 - root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data); 117 - kfree(root_devname); 118 - return root_mnt; 119 102 } 120 103 121 104 struct nfs_referral_count { ··· 137 214 kfree(p); 138 215 } 139 216 140 - static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt, 141 - const char *export_path) 217 + static int do_nfs4_mount(struct nfs_server *server, 218 + struct fs_context *fc, 219 + const char *hostname, 220 + const char *export_path) 142 221 { 222 + struct nfs_fs_context *root_ctx; 223 + struct fs_context *root_fc; 224 + struct vfsmount *root_mnt; 143 225 struct dentry *dentry; 144 - int err; 226 + size_t len; 227 + int ret; 228 + 229 + struct fs_parameter param = { 230 + .key = "source", 231 + .type = fs_value_is_string, 232 + .dirfd = -1, 233 + }; 234 + 235 + if (IS_ERR(server)) 236 + return PTR_ERR(server); 237 + 238 + root_fc = vfs_dup_fs_context(fc); 239 + if (IS_ERR(root_fc)) { 240 + nfs_free_server(server); 241 + return PTR_ERR(root_fc); 242 + } 243 + kfree(root_fc->source); 244 + root_fc->source = NULL; 245 + 246 + root_ctx = nfs_fc2context(root_fc); 247 + root_ctx->internal = true; 248 + root_ctx->server = server; 249 + /* We leave export_path unset as it's not used to find the root. */ 250 + 251 + len = strlen(hostname) + 5; 252 + param.string = kmalloc(len, GFP_KERNEL); 253 + if (param.string == NULL) { 254 + put_fs_context(root_fc); 255 + return -ENOMEM; 256 + } 257 + 258 + /* Does hostname needs to be enclosed in brackets? */ 259 + if (strchr(hostname, ':')) 260 + param.size = snprintf(param.string, len, "[%s]:/", hostname); 261 + else 262 + param.size = snprintf(param.string, len, "%s:/", hostname); 263 + ret = vfs_parse_fs_param(root_fc, &param); 264 + kfree(param.string); 265 + if (ret < 0) { 266 + put_fs_context(root_fc); 267 + return ret; 268 + } 269 + root_mnt = fc_mount(root_fc); 270 + put_fs_context(root_fc); 145 271 146 272 if (IS_ERR(root_mnt)) 147 - return ERR_CAST(root_mnt); 273 + return PTR_ERR(root_mnt); 148 274 149 - err = nfs_referral_loop_protect(); 150 - if (err) { 275 + ret = nfs_referral_loop_protect(); 276 + if (ret) { 151 277 mntput(root_mnt); 152 - return ERR_PTR(err); 278 + return ret; 153 279 } 154 280 155 281 dentry = mount_subtree(root_mnt, export_path); 156 282 nfs_referral_loop_unprotect(); 157 283 158 - return dentry; 284 + if (IS_ERR(dentry)) 285 + return PTR_ERR(dentry); 286 + 287 + fc->root = dentry; 288 + return 0; 159 289 } 160 290 161 - struct dentry *nfs4_try_mount(int flags, const char *dev_name, 162 - struct nfs_mount_info *mount_info, 163 - struct nfs_subversion *nfs_mod) 291 + int nfs4_try_get_tree(struct fs_context *fc) 164 292 { 165 - char *export_path; 166 - struct vfsmount *root_mnt; 167 - struct dentry *res; 168 - struct nfs_parsed_mount_data *data = mount_info->parsed; 293 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 294 + int err; 169 295 170 - dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 296 + dfprintk(MOUNT, "--> nfs4_try_get_tree()\n"); 171 297 172 - export_path = data->nfs_server.export_path; 173 - data->nfs_server.export_path = "/"; 174 - root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 175 - data->nfs_server.hostname); 176 - data->nfs_server.export_path = export_path; 177 - 178 - res = nfs_follow_remote_path(root_mnt, export_path); 179 - 180 - dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", 181 - PTR_ERR_OR_ZERO(res), 182 - IS_ERR(res) ? " [error]" : ""); 183 - return res; 184 - } 185 - 186 - static struct dentry * 187 - nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, 188 - const char *dev_name, void *raw_data) 189 - { 190 - struct nfs_mount_info mount_info = { 191 - .fill_super = nfs_fill_super, 192 - .set_security = nfs_clone_sb_security, 193 - .cloned = raw_data, 194 - }; 195 - struct nfs_server *server; 196 - struct dentry *mntroot = ERR_PTR(-ENOMEM); 197 - 198 - dprintk("--> nfs4_referral_get_sb()\n"); 199 - 200 - mount_info.mntfh = nfs_alloc_fhandle(); 201 - if (mount_info.cloned == NULL || mount_info.mntfh == NULL) 202 - goto out; 203 - 204 - /* create a new volume representation */ 205 - server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh); 206 - if (IS_ERR(server)) { 207 - mntroot = ERR_CAST(server); 208 - goto out; 298 + /* We create a mount for the server's root, walk to the requested 299 + * location and then create another mount for that. 300 + */ 301 + err= do_nfs4_mount(nfs4_create_server(fc), 302 + fc, ctx->nfs_server.hostname, 303 + ctx->nfs_server.export_path); 304 + if (err) { 305 + nfs_errorf(fc, "NFS4: Couldn't follow remote path"); 306 + dfprintk(MOUNT, "<-- nfs4_try_get_tree() = %d [error]\n", err); 307 + } else { 308 + dfprintk(MOUNT, "<-- nfs4_try_get_tree() = 0\n"); 209 309 } 210 - 211 - mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4); 212 - out: 213 - nfs_free_fhandle(mount_info.mntfh); 214 - return mntroot; 310 + return err; 215 311 } 216 312 217 313 /* 218 314 * Create an NFS4 server record on referral traversal 219 315 */ 220 - static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, 221 - int flags, const char *dev_name, void *raw_data) 316 + int nfs4_get_referral_tree(struct fs_context *fc) 222 317 { 223 - struct nfs_clone_mount *data = raw_data; 224 - char *export_path; 225 - struct vfsmount *root_mnt; 226 - struct dentry *res; 318 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 319 + int err; 227 320 228 321 dprintk("--> nfs4_referral_mount()\n"); 229 322 230 - export_path = data->mnt_path; 231 - data->mnt_path = "/"; 232 - 233 - root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type, 234 - flags, data, data->hostname); 235 - data->mnt_path = export_path; 236 - 237 - res = nfs_follow_remote_path(root_mnt, export_path); 238 - dprintk("<-- nfs4_referral_mount() = %d%s\n", 239 - PTR_ERR_OR_ZERO(res), 240 - IS_ERR(res) ? " [error]" : ""); 241 - return res; 323 + /* create a new volume representation */ 324 + err = do_nfs4_mount(nfs4_create_referral_server(fc), 325 + fc, ctx->nfs_server.hostname, 326 + ctx->nfs_server.export_path); 327 + if (err) { 328 + nfs_errorf(fc, "NFS4: Couldn't follow remote path"); 329 + dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = %d [error]\n", err); 330 + } else { 331 + dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = 0\n"); 332 + } 333 + return err; 242 334 } 243 - 244 335 245 336 static int __init init_nfs_v4(void) 246 337 {
+4
fs/nfs/nfs4trace.c
··· 24 24 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_write_done); 25 25 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_read_pagelist); 26 26 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_write_pagelist); 27 + 28 + EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_read_error); 29 + EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_write_error); 30 + EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_commit_error); 27 31 #endif
+202 -35
fs/nfs/nfs4trace.h
··· 155 155 TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); 156 156 TRACE_DEFINE_ENUM(NFS4ERR_XDEV); 157 157 158 + TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); 159 + TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); 160 + 158 161 #define show_nfsv4_errors(error) \ 159 162 __print_symbolic(error, \ 160 163 { NFS4_OK, "OK" }, \ ··· 308 305 { NFS4ERR_WRONGSEC, "WRONGSEC" }, \ 309 306 { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ 310 307 { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ 311 - { NFS4ERR_XDEV, "XDEV" }) 308 + { NFS4ERR_XDEV, "XDEV" }, \ 309 + /* ***** Internal to Linux NFS client ***** */ \ 310 + { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ 311 + { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) 312 312 313 313 #define show_open_flags(flags) \ 314 314 __print_flags(flags, "|", \ ··· 358 352 ), 359 353 360 354 TP_fast_assign( 361 - __entry->error = error; 355 + __entry->error = error < 0 ? -error : 0; 362 356 __assign_str(dstaddr, clp->cl_hostname); 363 357 ), 364 358 ··· 438 432 __entry->target_highest_slotid = 439 433 res->sr_target_highest_slotid; 440 434 __entry->status_flags = res->sr_status_flags; 441 - __entry->error = res->sr_status; 435 + __entry->error = res->sr_status < 0 ? 436 + -res->sr_status : 0; 442 437 ), 443 438 TP_printk( 444 439 "error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u " ··· 647 640 ), 648 641 649 642 TP_fast_assign( 650 - __entry->error = status; 643 + __entry->error = status < 0 ? -status : 0; 651 644 __entry->state = clp->cl_state; 652 645 __assign_str(hostname, clp->cl_hostname); 653 646 __assign_str(section, section); ··· 666 659 TP_PROTO( 667 660 const struct xdr_stream *xdr, 668 661 u32 op, 669 - int error 662 + u32 error 670 663 ), 671 664 672 665 TP_ARGS(xdr, op, error), ··· 697 690 __entry->op 698 691 ) 699 692 ); 693 + 694 + DECLARE_EVENT_CLASS(nfs4_cb_error_class, 695 + TP_PROTO( 696 + __be32 xid, 697 + u32 cb_ident 698 + ), 699 + 700 + TP_ARGS(xid, cb_ident), 701 + 702 + TP_STRUCT__entry( 703 + __field(u32, xid) 704 + __field(u32, cbident) 705 + ), 706 + 707 + TP_fast_assign( 708 + __entry->xid = be32_to_cpu(xid); 709 + __entry->cbident = cb_ident; 710 + ), 711 + 712 + TP_printk( 713 + "xid=0x%08x cb_ident=0x%08x", 714 + __entry->xid, __entry->cbident 715 + ) 716 + ); 717 + 718 + #define DEFINE_CB_ERROR_EVENT(name) \ 719 + DEFINE_EVENT(nfs4_cb_error_class, nfs_cb_##name, \ 720 + TP_PROTO( \ 721 + __be32 xid, \ 722 + u32 cb_ident \ 723 + ), \ 724 + TP_ARGS(xid, cb_ident)) 725 + 726 + DEFINE_CB_ERROR_EVENT(no_clp); 727 + DEFINE_CB_ERROR_EVENT(badprinc); 700 728 701 729 DECLARE_EVENT_CLASS(nfs4_open_event, 702 730 TP_PROTO( ··· 891 849 __entry->fileid = NFS_FILEID(inode); 892 850 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); 893 851 __entry->fmode = (__force unsigned int)state->state; 894 - __entry->error = error; 852 + __entry->error = error < 0 ? -error : 0; 895 853 __entry->stateid_seq = 896 854 be32_to_cpu(args->stateid.seqid); 897 855 __entry->stateid_hash = ··· 956 914 TP_fast_assign( 957 915 const struct inode *inode = state->inode; 958 916 959 - __entry->error = error; 917 + __entry->error = error < 0 ? -error : 0; 960 918 __entry->cmd = cmd; 961 919 __entry->type = request->fl_type; 962 920 __entry->start = request->fl_start; ··· 1028 986 TP_fast_assign( 1029 987 const struct inode *inode = state->inode; 1030 988 1031 - __entry->error = error; 989 + __entry->error = error < 0 ? -error : 0; 1032 990 __entry->cmd = cmd; 1033 991 __entry->type = request->fl_type; 1034 992 __entry->start = request->fl_start; ··· 1206 1164 TP_fast_assign( 1207 1165 __entry->dev = res->server->s_dev; 1208 1166 __entry->fhandle = nfs_fhandle_hash(args->fhandle); 1209 - __entry->error = error; 1167 + __entry->error = error < 0 ? -error : 0; 1210 1168 __entry->stateid_seq = 1211 1169 be32_to_cpu(args->stateid->seqid); 1212 1170 __entry->stateid_hash = ··· 1246 1204 TP_fast_assign( 1247 1205 const struct inode *inode = state->inode; 1248 1206 1249 - __entry->error = error; 1207 + __entry->error = error < 0 ? -error : 0; 1250 1208 __entry->dev = inode->i_sb->s_dev; 1251 1209 __entry->fileid = NFS_FILEID(inode); 1252 1210 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); ··· 1348 1306 TP_fast_assign( 1349 1307 __entry->dev = inode->i_sb->s_dev; 1350 1308 __entry->ino = NFS_FILEID(inode); 1351 - __entry->error = error; 1309 + __entry->error = error < 0 ? -error : 0; 1352 1310 ), 1353 1311 1354 1312 TP_printk( ··· 1384 1342 __entry->dev = olddir->i_sb->s_dev; 1385 1343 __entry->olddir = NFS_FILEID(olddir); 1386 1344 __entry->newdir = NFS_FILEID(newdir); 1387 - __entry->error = error; 1345 + __entry->error = error < 0 ? -error : 0; 1388 1346 __assign_str(oldname, oldname->name); 1389 1347 __assign_str(newname, newname->name); 1390 1348 ), ··· 1475 1433 __entry->dev = inode->i_sb->s_dev; 1476 1434 __entry->fileid = NFS_FILEID(inode); 1477 1435 __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); 1478 - __entry->error = error; 1436 + __entry->error = error < 0 ? -error : 0; 1479 1437 __entry->stateid_seq = 1480 1438 be32_to_cpu(stateid->seqid); 1481 1439 __entry->stateid_hash = ··· 1531 1489 __entry->valid = fattr->valid; 1532 1490 __entry->fhandle = nfs_fhandle_hash(fhandle); 1533 1491 __entry->fileid = (fattr->valid & NFS_ATTR_FATTR_FILEID) ? fattr->fileid : 0; 1534 - __entry->error = error; 1492 + __entry->error = error < 0 ? -error : 0; 1535 1493 ), 1536 1494 1537 1495 TP_printk( ··· 1578 1536 ), 1579 1537 1580 1538 TP_fast_assign( 1581 - __entry->error = error; 1539 + __entry->error = error < 0 ? -error : 0; 1582 1540 __entry->fhandle = nfs_fhandle_hash(fhandle); 1583 1541 if (!IS_ERR_OR_NULL(inode)) { 1584 1542 __entry->fileid = NFS_FILEID(inode); ··· 1635 1593 ), 1636 1594 1637 1595 TP_fast_assign( 1638 - __entry->error = error; 1596 + __entry->error = error < 0 ? -error : 0; 1639 1597 __entry->fhandle = nfs_fhandle_hash(fhandle); 1640 1598 if (!IS_ERR_OR_NULL(inode)) { 1641 1599 __entry->fileid = NFS_FILEID(inode); ··· 1736 1694 __field(u32, fhandle) 1737 1695 __field(u64, fileid) 1738 1696 __field(loff_t, offset) 1739 - __field(size_t, count) 1697 + __field(u32, arg_count) 1698 + __field(u32, res_count) 1740 1699 __field(unsigned long, error) 1741 1700 __field(int, stateid_seq) 1742 1701 __field(u32, stateid_hash) ··· 1745 1702 1746 1703 TP_fast_assign( 1747 1704 const struct inode *inode = hdr->inode; 1705 + const struct nfs_inode *nfsi = NFS_I(inode); 1706 + const struct nfs_fh *fh = hdr->args.fh ? 1707 + hdr->args.fh : &nfsi->fh; 1748 1708 const struct nfs4_state *state = 1749 1709 hdr->args.context->state; 1710 + 1750 1711 __entry->dev = inode->i_sb->s_dev; 1751 - __entry->fileid = NFS_FILEID(inode); 1752 - __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); 1712 + __entry->fileid = nfsi->fileid; 1713 + __entry->fhandle = nfs_fhandle_hash(fh); 1753 1714 __entry->offset = hdr->args.offset; 1754 - __entry->count = hdr->args.count; 1715 + __entry->arg_count = hdr->args.count; 1716 + __entry->res_count = hdr->res.count; 1755 1717 __entry->error = error < 0 ? -error : 0; 1756 1718 __entry->stateid_seq = 1757 1719 be32_to_cpu(state->stateid.seqid); ··· 1766 1718 1767 1719 TP_printk( 1768 1720 "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 1769 - "offset=%lld count=%zu stateid=%d:0x%08x", 1721 + "offset=%lld count=%u res=%u stateid=%d:0x%08x", 1770 1722 -__entry->error, 1771 1723 show_nfsv4_errors(__entry->error), 1772 1724 MAJOR(__entry->dev), MINOR(__entry->dev), 1773 1725 (unsigned long long)__entry->fileid, 1774 1726 __entry->fhandle, 1775 1727 (long long)__entry->offset, 1776 - __entry->count, 1728 + __entry->arg_count, __entry->res_count, 1777 1729 __entry->stateid_seq, __entry->stateid_hash 1778 1730 ) 1779 1731 ); ··· 1802 1754 __field(u32, fhandle) 1803 1755 __field(u64, fileid) 1804 1756 __field(loff_t, offset) 1805 - __field(size_t, count) 1757 + __field(u32, arg_count) 1758 + __field(u32, res_count) 1806 1759 __field(unsigned long, error) 1807 1760 __field(int, stateid_seq) 1808 1761 __field(u32, stateid_hash) ··· 1811 1762 1812 1763 TP_fast_assign( 1813 1764 const struct inode *inode = hdr->inode; 1765 + const struct nfs_inode *nfsi = NFS_I(inode); 1766 + const struct nfs_fh *fh = hdr->args.fh ? 1767 + hdr->args.fh : &nfsi->fh; 1814 1768 const struct nfs4_state *state = 1815 1769 hdr->args.context->state; 1770 + 1816 1771 __entry->dev = inode->i_sb->s_dev; 1817 - __entry->fileid = NFS_FILEID(inode); 1818 - __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); 1772 + __entry->fileid = nfsi->fileid; 1773 + __entry->fhandle = nfs_fhandle_hash(fh); 1819 1774 __entry->offset = hdr->args.offset; 1820 - __entry->count = hdr->args.count; 1775 + __entry->arg_count = hdr->args.count; 1776 + __entry->res_count = hdr->res.count; 1821 1777 __entry->error = error < 0 ? -error : 0; 1822 1778 __entry->stateid_seq = 1823 1779 be32_to_cpu(state->stateid.seqid); ··· 1832 1778 1833 1779 TP_printk( 1834 1780 "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 1835 - "offset=%lld count=%zu stateid=%d:0x%08x", 1781 + "offset=%lld count=%u res=%u stateid=%d:0x%08x", 1836 1782 -__entry->error, 1837 1783 show_nfsv4_errors(__entry->error), 1838 1784 MAJOR(__entry->dev), MINOR(__entry->dev), 1839 1785 (unsigned long long)__entry->fileid, 1840 1786 __entry->fhandle, 1841 1787 (long long)__entry->offset, 1842 - __entry->count, 1788 + __entry->arg_count, __entry->res_count, 1843 1789 __entry->stateid_seq, __entry->stateid_hash 1844 1790 ) 1845 1791 ); ··· 1868 1814 __field(dev_t, dev) 1869 1815 __field(u32, fhandle) 1870 1816 __field(u64, fileid) 1871 - __field(loff_t, offset) 1872 - __field(size_t, count) 1873 1817 __field(unsigned long, error) 1818 + __field(loff_t, offset) 1819 + __field(u32, count) 1874 1820 ), 1875 1821 1876 1822 TP_fast_assign( 1877 1823 const struct inode *inode = data->inode; 1824 + const struct nfs_inode *nfsi = NFS_I(inode); 1825 + const struct nfs_fh *fh = data->args.fh ? 1826 + data->args.fh : &nfsi->fh; 1827 + 1878 1828 __entry->dev = inode->i_sb->s_dev; 1879 - __entry->fileid = NFS_FILEID(inode); 1880 - __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); 1829 + __entry->fileid = nfsi->fileid; 1830 + __entry->fhandle = nfs_fhandle_hash(fh); 1881 1831 __entry->offset = data->args.offset; 1882 1832 __entry->count = data->args.count; 1883 - __entry->error = error; 1833 + __entry->error = error < 0 ? -error : 0; 1884 1834 ), 1885 1835 1886 1836 TP_printk( 1887 1837 "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 1888 - "offset=%lld count=%zu", 1838 + "offset=%lld count=%u", 1889 1839 -__entry->error, 1890 1840 show_nfsv4_errors(__entry->error), 1891 1841 MAJOR(__entry->dev), MINOR(__entry->dev), ··· 1954 1896 __entry->iomode = args->iomode; 1955 1897 __entry->offset = args->offset; 1956 1898 __entry->count = args->length; 1957 - __entry->error = error; 1899 + __entry->error = error < 0 ? -error : 0; 1958 1900 __entry->stateid_seq = 1959 1901 be32_to_cpu(state->stateid.seqid); 1960 1902 __entry->stateid_hash = ··· 2151 2093 DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_write_done); 2152 2094 DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_read_pagelist); 2153 2095 DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_write_pagelist); 2096 + 2097 + DECLARE_EVENT_CLASS(nfs4_flexfiles_io_event, 2098 + TP_PROTO( 2099 + const struct nfs_pgio_header *hdr 2100 + ), 2101 + 2102 + TP_ARGS(hdr), 2103 + 2104 + TP_STRUCT__entry( 2105 + __field(unsigned long, error) 2106 + __field(dev_t, dev) 2107 + __field(u32, fhandle) 2108 + __field(u64, fileid) 2109 + __field(loff_t, offset) 2110 + __field(u32, count) 2111 + __field(int, stateid_seq) 2112 + __field(u32, stateid_hash) 2113 + __string(dstaddr, hdr->ds_clp ? 2114 + rpc_peeraddr2str(hdr->ds_clp->cl_rpcclient, 2115 + RPC_DISPLAY_ADDR) : "unknown") 2116 + ), 2117 + 2118 + TP_fast_assign( 2119 + const struct inode *inode = hdr->inode; 2120 + 2121 + __entry->error = hdr->res.op_status; 2122 + __entry->fhandle = nfs_fhandle_hash(hdr->args.fh); 2123 + __entry->fileid = NFS_FILEID(inode); 2124 + __entry->dev = inode->i_sb->s_dev; 2125 + __entry->offset = hdr->args.offset; 2126 + __entry->count = hdr->args.count; 2127 + __entry->stateid_seq = 2128 + be32_to_cpu(hdr->args.stateid.seqid); 2129 + __entry->stateid_hash = 2130 + nfs_stateid_hash(&hdr->args.stateid); 2131 + __assign_str(dstaddr, hdr->ds_clp ? 2132 + rpc_peeraddr2str(hdr->ds_clp->cl_rpcclient, 2133 + RPC_DISPLAY_ADDR) : "unknown"); 2134 + ), 2135 + 2136 + TP_printk( 2137 + "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 2138 + "offset=%llu count=%u stateid=%d:0x%08x dstaddr=%s", 2139 + -__entry->error, 2140 + show_nfsv4_errors(__entry->error), 2141 + MAJOR(__entry->dev), MINOR(__entry->dev), 2142 + (unsigned long long)__entry->fileid, 2143 + __entry->fhandle, 2144 + __entry->offset, __entry->count, 2145 + __entry->stateid_seq, __entry->stateid_hash, 2146 + __get_str(dstaddr) 2147 + ) 2148 + ); 2149 + 2150 + #define DEFINE_NFS4_FLEXFILES_IO_EVENT(name) \ 2151 + DEFINE_EVENT(nfs4_flexfiles_io_event, name, \ 2152 + TP_PROTO( \ 2153 + const struct nfs_pgio_header *hdr \ 2154 + ), \ 2155 + TP_ARGS(hdr)) 2156 + DEFINE_NFS4_FLEXFILES_IO_EVENT(ff_layout_read_error); 2157 + DEFINE_NFS4_FLEXFILES_IO_EVENT(ff_layout_write_error); 2158 + 2159 + TRACE_EVENT(ff_layout_commit_error, 2160 + TP_PROTO( 2161 + const struct nfs_commit_data *data 2162 + ), 2163 + 2164 + TP_ARGS(data), 2165 + 2166 + TP_STRUCT__entry( 2167 + __field(unsigned long, error) 2168 + __field(dev_t, dev) 2169 + __field(u32, fhandle) 2170 + __field(u64, fileid) 2171 + __field(loff_t, offset) 2172 + __field(u32, count) 2173 + __string(dstaddr, data->ds_clp ? 2174 + rpc_peeraddr2str(data->ds_clp->cl_rpcclient, 2175 + RPC_DISPLAY_ADDR) : "unknown") 2176 + ), 2177 + 2178 + TP_fast_assign( 2179 + const struct inode *inode = data->inode; 2180 + 2181 + __entry->error = data->res.op_status; 2182 + __entry->fhandle = nfs_fhandle_hash(data->args.fh); 2183 + __entry->fileid = NFS_FILEID(inode); 2184 + __entry->dev = inode->i_sb->s_dev; 2185 + __entry->offset = data->args.offset; 2186 + __entry->count = data->args.count; 2187 + __assign_str(dstaddr, data->ds_clp ? 2188 + rpc_peeraddr2str(data->ds_clp->cl_rpcclient, 2189 + RPC_DISPLAY_ADDR) : "unknown"); 2190 + ), 2191 + 2192 + TP_printk( 2193 + "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 2194 + "offset=%llu count=%u dstaddr=%s", 2195 + -__entry->error, 2196 + show_nfsv4_errors(__entry->error), 2197 + MAJOR(__entry->dev), MINOR(__entry->dev), 2198 + (unsigned long long)__entry->fileid, 2199 + __entry->fhandle, 2200 + __entry->offset, __entry->count, 2201 + __get_str(dstaddr) 2202 + ) 2203 + ); 2204 + 2154 2205 2155 2206 #endif /* CONFIG_NFS_V4_1 */ 2156 2207
+5 -2
fs/nfs/nfs4xdr.c
··· 1061 1061 static __be32 * 1062 1062 xdr_encode_nfstime4(__be32 *p, const struct timespec64 *t) 1063 1063 { 1064 - p = xdr_encode_hyper(p, (__s64)t->tv_sec); 1064 + p = xdr_encode_hyper(p, t->tv_sec); 1065 1065 *p++ = cpu_to_be32(t->tv_nsec); 1066 1066 return p; 1067 1067 } ··· 4313 4313 4314 4314 static int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res) 4315 4315 { 4316 + struct nfs_writeverf *verf = res->verf; 4316 4317 int status; 4317 4318 4318 4319 status = decode_op_hdr(xdr, OP_COMMIT); 4319 4320 if (!status) 4320 - status = decode_write_verifier(xdr, &res->verf->verifier); 4321 + status = decode_write_verifier(xdr, &verf->verifier); 4322 + if (!status) 4323 + verf->committed = NFS_FILE_SYNC; 4321 4324 return status; 4322 4325 } 4323 4326
+204 -71
fs/nfs/nfstrace.h
··· 198 198 DEFINE_NFS_INODE_EVENT(nfs_fsync_enter); 199 199 DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit); 200 200 DEFINE_NFS_INODE_EVENT(nfs_access_enter); 201 - DEFINE_NFS_INODE_EVENT_DONE(nfs_access_exit); 201 + 202 + TRACE_EVENT(nfs_access_exit, 203 + TP_PROTO( 204 + const struct inode *inode, 205 + unsigned int mask, 206 + unsigned int permitted, 207 + int error 208 + ), 209 + 210 + TP_ARGS(inode, mask, permitted, error), 211 + 212 + TP_STRUCT__entry( 213 + __field(unsigned long, error) 214 + __field(dev_t, dev) 215 + __field(u32, fhandle) 216 + __field(unsigned char, type) 217 + __field(u64, fileid) 218 + __field(u64, version) 219 + __field(loff_t, size) 220 + __field(unsigned long, nfsi_flags) 221 + __field(unsigned long, cache_validity) 222 + __field(unsigned int, mask) 223 + __field(unsigned int, permitted) 224 + ), 225 + 226 + TP_fast_assign( 227 + const struct nfs_inode *nfsi = NFS_I(inode); 228 + __entry->error = error < 0 ? -error : 0; 229 + __entry->dev = inode->i_sb->s_dev; 230 + __entry->fileid = nfsi->fileid; 231 + __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 232 + __entry->type = nfs_umode_to_dtype(inode->i_mode); 233 + __entry->version = inode_peek_iversion_raw(inode); 234 + __entry->size = i_size_read(inode); 235 + __entry->nfsi_flags = nfsi->flags; 236 + __entry->cache_validity = nfsi->cache_validity; 237 + __entry->mask = mask; 238 + __entry->permitted = permitted; 239 + ), 240 + 241 + TP_printk( 242 + "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " 243 + "type=%u (%s) version=%llu size=%lld " 244 + "cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s) " 245 + "mask=0x%x permitted=0x%x", 246 + -__entry->error, nfs_show_status(__entry->error), 247 + MAJOR(__entry->dev), MINOR(__entry->dev), 248 + (unsigned long long)__entry->fileid, 249 + __entry->fhandle, 250 + __entry->type, 251 + nfs_show_file_type(__entry->type), 252 + (unsigned long long)__entry->version, 253 + (long long)__entry->size, 254 + __entry->cache_validity, 255 + nfs_show_cache_validity(__entry->cache_validity), 256 + __entry->nfsi_flags, 257 + nfs_show_nfsi_flags(__entry->nfsi_flags), 258 + __entry->mask, __entry->permitted 259 + ) 260 + ); 202 261 203 262 TRACE_DEFINE_ENUM(LOOKUP_FOLLOW); 204 263 TRACE_DEFINE_ENUM(LOOKUP_DIRECTORY); ··· 877 818 878 819 TRACE_EVENT(nfs_initiate_read, 879 820 TP_PROTO( 880 - const struct inode *inode, 881 - loff_t offset, unsigned long count 821 + const struct nfs_pgio_header *hdr 882 822 ), 883 823 884 - TP_ARGS(inode, offset, count), 824 + TP_ARGS(hdr), 885 825 886 826 TP_STRUCT__entry( 887 - __field(loff_t, offset) 888 - __field(unsigned long, count) 889 827 __field(dev_t, dev) 890 828 __field(u32, fhandle) 891 829 __field(u64, fileid) 830 + __field(loff_t, offset) 831 + __field(u32, count) 892 832 ), 893 833 894 834 TP_fast_assign( 835 + const struct inode *inode = hdr->inode; 895 836 const struct nfs_inode *nfsi = NFS_I(inode); 837 + const struct nfs_fh *fh = hdr->args.fh ? 838 + hdr->args.fh : &nfsi->fh; 896 839 897 - __entry->offset = offset; 898 - __entry->count = count; 840 + __entry->offset = hdr->args.offset; 841 + __entry->count = hdr->args.count; 899 842 __entry->dev = inode->i_sb->s_dev; 900 843 __entry->fileid = nfsi->fileid; 901 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 844 + __entry->fhandle = nfs_fhandle_hash(fh); 902 845 ), 903 846 904 847 TP_printk( 905 848 "fileid=%02x:%02x:%llu fhandle=0x%08x " 906 - "offset=%lld count=%lu", 849 + "offset=%lld count=%u", 907 850 MAJOR(__entry->dev), MINOR(__entry->dev), 908 851 (unsigned long long)__entry->fileid, 909 852 __entry->fhandle, 910 - __entry->offset, __entry->count 853 + (long long)__entry->offset, __entry->count 911 854 ) 912 855 ); 913 856 914 857 TRACE_EVENT(nfs_readpage_done, 915 858 TP_PROTO( 916 - const struct inode *inode, 917 - int status, loff_t offset, bool eof 859 + const struct rpc_task *task, 860 + const struct nfs_pgio_header *hdr 918 861 ), 919 862 920 - TP_ARGS(inode, status, offset, eof), 863 + TP_ARGS(task, hdr), 921 864 922 865 TP_STRUCT__entry( 923 - __field(int, status) 924 - __field(loff_t, offset) 925 - __field(bool, eof) 926 866 __field(dev_t, dev) 927 867 __field(u32, fhandle) 928 868 __field(u64, fileid) 869 + __field(loff_t, offset) 870 + __field(u32, arg_count) 871 + __field(u32, res_count) 872 + __field(bool, eof) 873 + __field(int, status) 929 874 ), 930 875 931 876 TP_fast_assign( 877 + const struct inode *inode = hdr->inode; 932 878 const struct nfs_inode *nfsi = NFS_I(inode); 879 + const struct nfs_fh *fh = hdr->args.fh ? 880 + hdr->args.fh : &nfsi->fh; 933 881 934 - __entry->status = status; 935 - __entry->offset = offset; 936 - __entry->eof = eof; 882 + __entry->status = task->tk_status; 883 + __entry->offset = hdr->args.offset; 884 + __entry->arg_count = hdr->args.count; 885 + __entry->res_count = hdr->res.count; 886 + __entry->eof = hdr->res.eof; 937 887 __entry->dev = inode->i_sb->s_dev; 938 888 __entry->fileid = nfsi->fileid; 939 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 889 + __entry->fhandle = nfs_fhandle_hash(fh); 940 890 ), 941 891 942 892 TP_printk( 943 893 "fileid=%02x:%02x:%llu fhandle=0x%08x " 944 - "offset=%lld status=%d%s", 894 + "offset=%lld count=%u res=%u status=%d%s", 945 895 MAJOR(__entry->dev), MINOR(__entry->dev), 946 896 (unsigned long long)__entry->fileid, 947 897 __entry->fhandle, 948 - __entry->offset, __entry->status, 898 + (long long)__entry->offset, __entry->arg_count, 899 + __entry->res_count, __entry->status, 949 900 __entry->eof ? " eof" : "" 950 901 ) 951 902 ); ··· 972 903 973 904 TRACE_EVENT(nfs_initiate_write, 974 905 TP_PROTO( 975 - const struct inode *inode, 976 - loff_t offset, unsigned long count, 977 - enum nfs3_stable_how stable 906 + const struct nfs_pgio_header *hdr 978 907 ), 979 908 980 - TP_ARGS(inode, offset, count, stable), 909 + TP_ARGS(hdr), 981 910 982 911 TP_STRUCT__entry( 983 - __field(loff_t, offset) 984 - __field(unsigned long, count) 985 - __field(enum nfs3_stable_how, stable) 986 912 __field(dev_t, dev) 987 913 __field(u32, fhandle) 988 914 __field(u64, fileid) 915 + __field(loff_t, offset) 916 + __field(u32, count) 917 + __field(enum nfs3_stable_how, stable) 989 918 ), 990 919 991 920 TP_fast_assign( 921 + const struct inode *inode = hdr->inode; 992 922 const struct nfs_inode *nfsi = NFS_I(inode); 923 + const struct nfs_fh *fh = hdr->args.fh ? 924 + hdr->args.fh : &nfsi->fh; 993 925 994 - __entry->offset = offset; 995 - __entry->count = count; 996 - __entry->stable = stable; 926 + __entry->offset = hdr->args.offset; 927 + __entry->count = hdr->args.count; 928 + __entry->stable = hdr->args.stable; 997 929 __entry->dev = inode->i_sb->s_dev; 998 930 __entry->fileid = nfsi->fileid; 999 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 931 + __entry->fhandle = nfs_fhandle_hash(fh); 1000 932 ), 1001 933 1002 934 TP_printk( 1003 935 "fileid=%02x:%02x:%llu fhandle=0x%08x " 1004 - "offset=%lld count=%lu stable=%s", 936 + "offset=%lld count=%u stable=%s", 1005 937 MAJOR(__entry->dev), MINOR(__entry->dev), 1006 938 (unsigned long long)__entry->fileid, 1007 939 __entry->fhandle, 1008 - __entry->offset, __entry->count, 940 + (long long)__entry->offset, __entry->count, 1009 941 nfs_show_stable(__entry->stable) 1010 942 ) 1011 943 ); 1012 944 1013 945 TRACE_EVENT(nfs_writeback_done, 1014 946 TP_PROTO( 1015 - const struct inode *inode, 1016 - int status, 1017 - loff_t offset, 1018 - struct nfs_writeverf *writeverf 947 + const struct rpc_task *task, 948 + const struct nfs_pgio_header *hdr 1019 949 ), 1020 950 1021 - TP_ARGS(inode, status, offset, writeverf), 951 + TP_ARGS(task, hdr), 1022 952 1023 953 TP_STRUCT__entry( 1024 - __field(int, status) 1025 - __field(loff_t, offset) 1026 - __field(enum nfs3_stable_how, stable) 1027 - __field(unsigned long long, verifier) 1028 954 __field(dev_t, dev) 1029 955 __field(u32, fhandle) 1030 956 __field(u64, fileid) 957 + __field(loff_t, offset) 958 + __field(u32, arg_count) 959 + __field(u32, res_count) 960 + __field(int, status) 961 + __field(enum nfs3_stable_how, stable) 962 + __array(char, verifier, NFS4_VERIFIER_SIZE) 1031 963 ), 1032 964 1033 965 TP_fast_assign( 966 + const struct inode *inode = hdr->inode; 1034 967 const struct nfs_inode *nfsi = NFS_I(inode); 968 + const struct nfs_fh *fh = hdr->args.fh ? 969 + hdr->args.fh : &nfsi->fh; 970 + const struct nfs_writeverf *verf = hdr->res.verf; 1035 971 1036 - __entry->status = status; 1037 - __entry->offset = offset; 1038 - __entry->stable = writeverf->committed; 1039 - memcpy(&__entry->verifier, &writeverf->verifier, 1040 - sizeof(__entry->verifier)); 972 + __entry->status = task->tk_status; 973 + __entry->offset = hdr->args.offset; 974 + __entry->arg_count = hdr->args.count; 975 + __entry->res_count = hdr->res.count; 976 + __entry->stable = verf->committed; 977 + memcpy(__entry->verifier, 978 + &verf->verifier, 979 + NFS4_VERIFIER_SIZE); 1041 980 __entry->dev = inode->i_sb->s_dev; 1042 981 __entry->fileid = nfsi->fileid; 1043 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 982 + __entry->fhandle = nfs_fhandle_hash(fh); 1044 983 ), 1045 984 1046 985 TP_printk( 1047 986 "fileid=%02x:%02x:%llu fhandle=0x%08x " 1048 - "offset=%lld status=%d stable=%s " 1049 - "verifier 0x%016llx", 987 + "offset=%lld count=%u res=%u status=%d stable=%s " 988 + "verifier=%s", 1050 989 MAJOR(__entry->dev), MINOR(__entry->dev), 1051 990 (unsigned long long)__entry->fileid, 1052 991 __entry->fhandle, 1053 - __entry->offset, __entry->status, 992 + (long long)__entry->offset, __entry->arg_count, 993 + __entry->res_count, __entry->status, 1054 994 nfs_show_stable(__entry->stable), 1055 - __entry->verifier 995 + __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE) 1056 996 ) 1057 997 ); 998 + 999 + DECLARE_EVENT_CLASS(nfs_page_error_class, 1000 + TP_PROTO( 1001 + const struct nfs_page *req, 1002 + int error 1003 + ), 1004 + 1005 + TP_ARGS(req, error), 1006 + 1007 + TP_STRUCT__entry( 1008 + __field(const void *, req) 1009 + __field(pgoff_t, index) 1010 + __field(unsigned int, offset) 1011 + __field(unsigned int, pgbase) 1012 + __field(unsigned int, bytes) 1013 + __field(int, error) 1014 + ), 1015 + 1016 + TP_fast_assign( 1017 + __entry->req = req; 1018 + __entry->index = req->wb_index; 1019 + __entry->offset = req->wb_offset; 1020 + __entry->pgbase = req->wb_pgbase; 1021 + __entry->bytes = req->wb_bytes; 1022 + __entry->error = error; 1023 + ), 1024 + 1025 + TP_printk( 1026 + "req=%p index=%lu offset=%u pgbase=%u bytes=%u error=%d", 1027 + __entry->req, __entry->index, __entry->offset, 1028 + __entry->pgbase, __entry->bytes, __entry->error 1029 + ) 1030 + ); 1031 + 1032 + #define DEFINE_NFS_PAGEERR_EVENT(name) \ 1033 + DEFINE_EVENT(nfs_page_error_class, name, \ 1034 + TP_PROTO( \ 1035 + const struct nfs_page *req, \ 1036 + int error \ 1037 + ), \ 1038 + TP_ARGS(req, error)) 1039 + 1040 + DEFINE_NFS_PAGEERR_EVENT(nfs_write_error); 1041 + DEFINE_NFS_PAGEERR_EVENT(nfs_comp_error); 1042 + DEFINE_NFS_PAGEERR_EVENT(nfs_commit_error); 1058 1043 1059 1044 TRACE_EVENT(nfs_initiate_commit, 1060 1045 TP_PROTO( ··· 1118 995 TP_ARGS(data), 1119 996 1120 997 TP_STRUCT__entry( 1121 - __field(loff_t, offset) 1122 - __field(unsigned long, count) 1123 998 __field(dev_t, dev) 1124 999 __field(u32, fhandle) 1125 1000 __field(u64, fileid) 1001 + __field(loff_t, offset) 1002 + __field(u32, count) 1126 1003 ), 1127 1004 1128 1005 TP_fast_assign( 1129 1006 const struct inode *inode = data->inode; 1130 1007 const struct nfs_inode *nfsi = NFS_I(inode); 1008 + const struct nfs_fh *fh = data->args.fh ? 1009 + data->args.fh : &nfsi->fh; 1131 1010 1132 1011 __entry->offset = data->args.offset; 1133 1012 __entry->count = data->args.count; 1134 1013 __entry->dev = inode->i_sb->s_dev; 1135 1014 __entry->fileid = nfsi->fileid; 1136 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 1015 + __entry->fhandle = nfs_fhandle_hash(fh); 1137 1016 ), 1138 1017 1139 1018 TP_printk( 1140 1019 "fileid=%02x:%02x:%llu fhandle=0x%08x " 1141 - "offset=%lld count=%lu", 1020 + "offset=%lld count=%u", 1142 1021 MAJOR(__entry->dev), MINOR(__entry->dev), 1143 1022 (unsigned long long)__entry->fileid, 1144 1023 __entry->fhandle, 1145 - __entry->offset, __entry->count 1024 + (long long)__entry->offset, __entry->count 1146 1025 ) 1147 1026 ); 1148 1027 1149 1028 TRACE_EVENT(nfs_commit_done, 1150 1029 TP_PROTO( 1030 + const struct rpc_task *task, 1151 1031 const struct nfs_commit_data *data 1152 1032 ), 1153 1033 1154 - TP_ARGS(data), 1034 + TP_ARGS(task, data), 1155 1035 1156 1036 TP_STRUCT__entry( 1157 - __field(int, status) 1158 - __field(loff_t, offset) 1159 - __field(unsigned long long, verifier) 1160 1037 __field(dev_t, dev) 1161 1038 __field(u32, fhandle) 1162 1039 __field(u64, fileid) 1040 + __field(loff_t, offset) 1041 + __field(int, status) 1042 + __field(enum nfs3_stable_how, stable) 1043 + __array(char, verifier, NFS4_VERIFIER_SIZE) 1163 1044 ), 1164 1045 1165 1046 TP_fast_assign( 1166 1047 const struct inode *inode = data->inode; 1167 1048 const struct nfs_inode *nfsi = NFS_I(inode); 1049 + const struct nfs_fh *fh = data->args.fh ? 1050 + data->args.fh : &nfsi->fh; 1051 + const struct nfs_writeverf *verf = data->res.verf; 1168 1052 1169 - __entry->status = data->res.op_status; 1053 + __entry->status = task->tk_status; 1170 1054 __entry->offset = data->args.offset; 1171 - memcpy(&__entry->verifier, &data->verf.verifier, 1172 - sizeof(__entry->verifier)); 1055 + __entry->stable = verf->committed; 1056 + memcpy(__entry->verifier, 1057 + &verf->verifier, 1058 + NFS4_VERIFIER_SIZE); 1173 1059 __entry->dev = inode->i_sb->s_dev; 1174 1060 __entry->fileid = nfsi->fileid; 1175 - __entry->fhandle = nfs_fhandle_hash(&nfsi->fh); 1061 + __entry->fhandle = nfs_fhandle_hash(fh); 1176 1062 ), 1177 1063 1178 1064 TP_printk( 1179 1065 "fileid=%02x:%02x:%llu fhandle=0x%08x " 1180 - "offset=%lld status=%d verifier 0x%016llx", 1066 + "offset=%lld status=%d stable=%s verifier=%s", 1181 1067 MAJOR(__entry->dev), MINOR(__entry->dev), 1182 1068 (unsigned long long)__entry->fileid, 1183 1069 __entry->fhandle, 1184 - __entry->offset, __entry->status, 1185 - __entry->verifier 1070 + (long long)__entry->offset, __entry->status, 1071 + nfs_show_stable(__entry->stable), 1072 + __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE) 1186 1073 ) 1187 1074 ); 1188 1075
+1 -3
fs/nfs/pnfs.c
··· 1425 1425 /* lo ref dropped in pnfs_roc_release() */ 1426 1426 layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &iomode); 1427 1427 /* If the creds don't match, we can't compound the layoutreturn */ 1428 - if (!layoutreturn || cred != lo->plh_lc_cred) 1428 + if (!layoutreturn || cred_fscmp(cred, lo->plh_lc_cred) != 0) 1429 1429 goto out_noroc; 1430 1430 1431 1431 roc = layoutreturn; ··· 1998 1998 trace_pnfs_update_layout(ino, pos, count, 1999 1999 iomode, lo, lseg, 2000 2000 PNFS_UPDATE_LAYOUT_INVALID_OPEN); 2001 - if (status != -EAGAIN) 2002 - goto out_unlock; 2003 2001 spin_unlock(&ino->i_lock); 2004 2002 nfs4_schedule_stateid_recovery(server, ctx->state); 2005 2003 pnfs_clear_first_layoutget(lo);
+4 -4
fs/nfs/pnfs.h
··· 79 79 PNFS_TRY_AGAIN = 2, 80 80 }; 81 81 82 + /* error codes for internal use */ 83 + #define NFS4ERR_RESET_TO_MDS 12001 84 + #define NFS4ERR_RESET_TO_PNFS 12002 85 + 82 86 #ifdef CONFIG_NFS_V4_1 83 87 84 88 #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4" ··· 94 90 #define NFS4_DEF_DS_TIMEO 600 /* in tenths of a second */ 95 91 #define NFS4_DEF_DS_RETRANS 5 96 92 #define PNFS_DEVICE_RETRY_TIMEOUT (120*HZ) 97 - 98 - /* error codes for internal use */ 99 - #define NFS4ERR_RESET_TO_MDS 12001 100 - #define NFS4ERR_RESET_TO_PNFS 12002 101 93 102 94 enum { 103 95 NFS_LAYOUT_RO_FAILED = 0, /* get ro layout failed stop trying */
+3 -4
fs/nfs/pnfs_nfs.c
··· 31 31 /* Fake up some data that will cause nfs_commit_release to retry the writes. */ 32 32 void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data) 33 33 { 34 - struct nfs_page *first = nfs_list_entry(data->pages.next); 34 + struct nfs_writeverf *verf = data->res.verf; 35 35 36 36 data->task.tk_status = 0; 37 - memcpy(&data->verf.verifier, &first->wb_verf, 38 - sizeof(data->verf.verifier)); 39 - data->verf.verifier.data[0]++; /* ensure verifier mismatch */ 37 + memset(&verf->verifier, 0, sizeof(verf->verifier)); 38 + verf->committed = NFS_UNSTABLE; 40 39 } 41 40 EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes); 42 41
+17 -7
fs/nfs/proc.c
··· 108 108 .rpc_resp = fattr, 109 109 }; 110 110 int status; 111 + unsigned short task_flags = 0; 112 + 113 + /* Is this is an attribute revalidation, subject to softreval? */ 114 + if (inode && (server->flags & NFS_MOUNT_SOFTREVAL)) 115 + task_flags |= RPC_TASK_TIMEOUT; 111 116 112 117 dprintk("NFS call getattr\n"); 113 118 nfs_fattr_init(fattr); 114 - status = rpc_call_sync(server->client, &msg, 0); 119 + status = rpc_call_sync(server->client, &msg, task_flags); 115 120 dprintk("NFS reply getattr: %d\n", status); 116 121 return status; 117 122 } ··· 152 147 } 153 148 154 149 static int 155 - nfs_proc_lookup(struct inode *dir, const struct qstr *name, 150 + nfs_proc_lookup(struct inode *dir, struct dentry *dentry, 156 151 struct nfs_fh *fhandle, struct nfs_fattr *fattr, 157 152 struct nfs4_label *label) 158 153 { 159 154 struct nfs_diropargs arg = { 160 155 .fh = NFS_FH(dir), 161 - .name = name->name, 162 - .len = name->len 156 + .name = dentry->d_name.name, 157 + .len = dentry->d_name.len 163 158 }; 164 159 struct nfs_diropok res = { 165 160 .fh = fhandle, ··· 171 166 .rpc_resp = &res, 172 167 }; 173 168 int status; 169 + unsigned short task_flags = 0; 174 170 175 - dprintk("NFS call lookup %s\n", name->name); 171 + /* Is this is an attribute revalidation, subject to softreval? */ 172 + if (nfs_lookup_is_soft_revalidate(dentry)) 173 + task_flags |= RPC_TASK_TIMEOUT; 174 + 175 + dprintk("NFS call lookup %pd2\n", dentry); 176 176 nfs_fattr_init(fattr); 177 - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 177 + status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags); 178 178 dprintk("NFS reply lookup: %d\n", status); 179 179 return status; 180 180 } ··· 720 710 .file_ops = &nfs_file_operations, 721 711 .getroot = nfs_proc_get_root, 722 712 .submount = nfs_submount, 723 - .try_mount = nfs_try_mount, 713 + .try_get_tree = nfs_try_get_tree, 724 714 .getattr = nfs_proc_getattr, 725 715 .setattr = nfs_proc_setattr, 726 716 .lookup = nfs_proc_lookup,
+4 -3
fs/nfs/read.c
··· 214 214 215 215 task_setup_data->flags |= swap_flags; 216 216 rpc_ops->read_setup(hdr, msg); 217 - trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes); 217 + trace_nfs_initiate_read(hdr); 218 218 } 219 219 220 220 static void ··· 247 247 return status; 248 248 249 249 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count); 250 - trace_nfs_readpage_done(inode, task->tk_status, 251 - hdr->args.offset, hdr->res.eof); 250 + trace_nfs_readpage_done(task, hdr); 252 251 253 252 if (task->tk_status == -ESTALE) { 254 253 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); ··· 281 282 argp->offset += resp->count; 282 283 argp->pgbase += resp->count; 283 284 argp->count -= resp->count; 285 + resp->count = 0; 286 + resp->eof = 0; 284 287 rpc_restart_call_prepare(task); 285 288 } 286 289
+166 -1804
fs/nfs/super.c
··· 69 69 #include "nfs.h" 70 70 71 71 #define NFSDBG_FACILITY NFSDBG_VFS 72 - #define NFS_TEXT_DATA 1 73 - 74 - #if IS_ENABLED(CONFIG_NFS_V3) 75 - #define NFS_DEFAULT_VERSION 3 76 - #else 77 - #define NFS_DEFAULT_VERSION 2 78 - #endif 79 - 80 - #define NFS_MAX_CONNECTIONS 16 81 - 82 - enum { 83 - /* Mount options that take no arguments */ 84 - Opt_soft, Opt_softerr, Opt_hard, 85 - Opt_posix, Opt_noposix, 86 - Opt_cto, Opt_nocto, 87 - Opt_ac, Opt_noac, 88 - Opt_lock, Opt_nolock, 89 - Opt_udp, Opt_tcp, Opt_rdma, 90 - Opt_acl, Opt_noacl, 91 - Opt_rdirplus, Opt_nordirplus, 92 - Opt_sharecache, Opt_nosharecache, 93 - Opt_resvport, Opt_noresvport, 94 - Opt_fscache, Opt_nofscache, 95 - Opt_migration, Opt_nomigration, 96 - 97 - /* Mount options that take integer arguments */ 98 - Opt_port, 99 - Opt_rsize, Opt_wsize, Opt_bsize, 100 - Opt_timeo, Opt_retrans, 101 - Opt_acregmin, Opt_acregmax, 102 - Opt_acdirmin, Opt_acdirmax, 103 - Opt_actimeo, 104 - Opt_namelen, 105 - Opt_mountport, 106 - Opt_mountvers, 107 - Opt_minorversion, 108 - 109 - /* Mount options that take string arguments */ 110 - Opt_nfsvers, 111 - Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, 112 - Opt_addr, Opt_mountaddr, Opt_clientaddr, 113 - Opt_nconnect, 114 - Opt_lookupcache, 115 - Opt_fscache_uniq, 116 - Opt_local_lock, 117 - 118 - /* Special mount options */ 119 - Opt_userspace, Opt_deprecated, Opt_sloppy, 120 - 121 - Opt_err 122 - }; 123 - 124 - static const match_table_t nfs_mount_option_tokens = { 125 - { Opt_userspace, "bg" }, 126 - { Opt_userspace, "fg" }, 127 - { Opt_userspace, "retry=%s" }, 128 - 129 - { Opt_sloppy, "sloppy" }, 130 - 131 - { Opt_soft, "soft" }, 132 - { Opt_softerr, "softerr" }, 133 - { Opt_hard, "hard" }, 134 - { Opt_deprecated, "intr" }, 135 - { Opt_deprecated, "nointr" }, 136 - { Opt_posix, "posix" }, 137 - { Opt_noposix, "noposix" }, 138 - { Opt_cto, "cto" }, 139 - { Opt_nocto, "nocto" }, 140 - { Opt_ac, "ac" }, 141 - { Opt_noac, "noac" }, 142 - { Opt_lock, "lock" }, 143 - { Opt_nolock, "nolock" }, 144 - { Opt_udp, "udp" }, 145 - { Opt_tcp, "tcp" }, 146 - { Opt_rdma, "rdma" }, 147 - { Opt_acl, "acl" }, 148 - { Opt_noacl, "noacl" }, 149 - { Opt_rdirplus, "rdirplus" }, 150 - { Opt_nordirplus, "nordirplus" }, 151 - { Opt_sharecache, "sharecache" }, 152 - { Opt_nosharecache, "nosharecache" }, 153 - { Opt_resvport, "resvport" }, 154 - { Opt_noresvport, "noresvport" }, 155 - { Opt_fscache, "fsc" }, 156 - { Opt_nofscache, "nofsc" }, 157 - { Opt_migration, "migration" }, 158 - { Opt_nomigration, "nomigration" }, 159 - 160 - { Opt_port, "port=%s" }, 161 - { Opt_rsize, "rsize=%s" }, 162 - { Opt_wsize, "wsize=%s" }, 163 - { Opt_bsize, "bsize=%s" }, 164 - { Opt_timeo, "timeo=%s" }, 165 - { Opt_retrans, "retrans=%s" }, 166 - { Opt_acregmin, "acregmin=%s" }, 167 - { Opt_acregmax, "acregmax=%s" }, 168 - { Opt_acdirmin, "acdirmin=%s" }, 169 - { Opt_acdirmax, "acdirmax=%s" }, 170 - { Opt_actimeo, "actimeo=%s" }, 171 - { Opt_namelen, "namlen=%s" }, 172 - { Opt_mountport, "mountport=%s" }, 173 - { Opt_mountvers, "mountvers=%s" }, 174 - { Opt_minorversion, "minorversion=%s" }, 175 - 176 - { Opt_nfsvers, "nfsvers=%s" }, 177 - { Opt_nfsvers, "vers=%s" }, 178 - 179 - { Opt_sec, "sec=%s" }, 180 - { Opt_proto, "proto=%s" }, 181 - { Opt_mountproto, "mountproto=%s" }, 182 - { Opt_addr, "addr=%s" }, 183 - { Opt_clientaddr, "clientaddr=%s" }, 184 - { Opt_mounthost, "mounthost=%s" }, 185 - { Opt_mountaddr, "mountaddr=%s" }, 186 - 187 - { Opt_nconnect, "nconnect=%s" }, 188 - 189 - { Opt_lookupcache, "lookupcache=%s" }, 190 - { Opt_fscache_uniq, "fsc=%s" }, 191 - { Opt_local_lock, "local_lock=%s" }, 192 - 193 - /* The following needs to be listed after all other options */ 194 - { Opt_nfsvers, "v%s" }, 195 - 196 - { Opt_err, NULL } 197 - }; 198 - 199 - enum { 200 - Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma, 201 - Opt_xprt_rdma6, 202 - 203 - Opt_xprt_err 204 - }; 205 - 206 - static const match_table_t nfs_xprt_protocol_tokens = { 207 - { Opt_xprt_udp, "udp" }, 208 - { Opt_xprt_udp6, "udp6" }, 209 - { Opt_xprt_tcp, "tcp" }, 210 - { Opt_xprt_tcp6, "tcp6" }, 211 - { Opt_xprt_rdma, "rdma" }, 212 - { Opt_xprt_rdma6, "rdma6" }, 213 - 214 - { Opt_xprt_err, NULL } 215 - }; 216 - 217 - enum { 218 - Opt_sec_none, Opt_sec_sys, 219 - Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, 220 - Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp, 221 - Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp, 222 - 223 - Opt_sec_err 224 - }; 225 - 226 - static const match_table_t nfs_secflavor_tokens = { 227 - { Opt_sec_none, "none" }, 228 - { Opt_sec_none, "null" }, 229 - { Opt_sec_sys, "sys" }, 230 - 231 - { Opt_sec_krb5, "krb5" }, 232 - { Opt_sec_krb5i, "krb5i" }, 233 - { Opt_sec_krb5p, "krb5p" }, 234 - 235 - { Opt_sec_lkey, "lkey" }, 236 - { Opt_sec_lkeyi, "lkeyi" }, 237 - { Opt_sec_lkeyp, "lkeyp" }, 238 - 239 - { Opt_sec_spkm, "spkm3" }, 240 - { Opt_sec_spkmi, "spkm3i" }, 241 - { Opt_sec_spkmp, "spkm3p" }, 242 - 243 - { Opt_sec_err, NULL } 244 - }; 245 - 246 - enum { 247 - Opt_lookupcache_all, Opt_lookupcache_positive, 248 - Opt_lookupcache_none, 249 - 250 - Opt_lookupcache_err 251 - }; 252 - 253 - static match_table_t nfs_lookupcache_tokens = { 254 - { Opt_lookupcache_all, "all" }, 255 - { Opt_lookupcache_positive, "pos" }, 256 - { Opt_lookupcache_positive, "positive" }, 257 - { Opt_lookupcache_none, "none" }, 258 - 259 - { Opt_lookupcache_err, NULL } 260 - }; 261 - 262 - enum { 263 - Opt_local_lock_all, Opt_local_lock_flock, Opt_local_lock_posix, 264 - Opt_local_lock_none, 265 - 266 - Opt_local_lock_err 267 - }; 268 - 269 - static match_table_t nfs_local_lock_tokens = { 270 - { Opt_local_lock_all, "all" }, 271 - { Opt_local_lock_flock, "flock" }, 272 - { Opt_local_lock_posix, "posix" }, 273 - { Opt_local_lock_none, "none" }, 274 - 275 - { Opt_local_lock_err, NULL } 276 - }; 277 - 278 - enum { 279 - Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0, 280 - Opt_vers_4_1, Opt_vers_4_2, 281 - 282 - Opt_vers_err 283 - }; 284 - 285 - static match_table_t nfs_vers_tokens = { 286 - { Opt_vers_2, "2" }, 287 - { Opt_vers_3, "3" }, 288 - { Opt_vers_4, "4" }, 289 - { Opt_vers_4_0, "4.0" }, 290 - { Opt_vers_4_1, "4.1" }, 291 - { Opt_vers_4_2, "4.2" }, 292 - 293 - { Opt_vers_err, NULL } 294 - }; 295 - 296 - static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, 297 - int flags, const char *dev_name, void *raw_data); 298 - 299 - struct file_system_type nfs_fs_type = { 300 - .owner = THIS_MODULE, 301 - .name = "nfs", 302 - .mount = nfs_fs_mount, 303 - .kill_sb = nfs_kill_super, 304 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 305 - }; 306 - MODULE_ALIAS_FS("nfs"); 307 - EXPORT_SYMBOL_GPL(nfs_fs_type); 308 - 309 - struct file_system_type nfs_xdev_fs_type = { 310 - .owner = THIS_MODULE, 311 - .name = "nfs", 312 - .mount = nfs_xdev_mount, 313 - .kill_sb = nfs_kill_super, 314 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 315 - }; 316 72 317 73 const struct super_operations nfs_sops = { 318 74 .alloc_inode = nfs_alloc_inode, ··· 82 326 .show_devname = nfs_show_devname, 83 327 .show_path = nfs_show_path, 84 328 .show_stats = nfs_show_stats, 85 - .remount_fs = nfs_remount, 86 329 }; 87 330 EXPORT_SYMBOL_GPL(nfs_sops); 88 331 89 332 #if IS_ENABLED(CONFIG_NFS_V4) 90 - static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); 91 - static int nfs4_validate_mount_data(void *options, 92 - struct nfs_parsed_mount_data *args, const char *dev_name); 93 - 94 - struct file_system_type nfs4_fs_type = { 95 - .owner = THIS_MODULE, 96 - .name = "nfs4", 97 - .mount = nfs_fs_mount, 98 - .kill_sb = nfs_kill_super, 99 - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 100 - }; 101 - MODULE_ALIAS_FS("nfs4"); 102 - MODULE_ALIAS("nfs4"); 103 - EXPORT_SYMBOL_GPL(nfs4_fs_type); 104 - 105 333 static int __init register_nfs4_fs(void) 106 334 { 107 335 return register_filesystem(&nfs4_fs_type); ··· 375 635 } nfs_info[] = { 376 636 { NFS_MOUNT_SOFT, ",soft", "" }, 377 637 { NFS_MOUNT_SOFTERR, ",softerr", "" }, 638 + { NFS_MOUNT_SOFTREVAL, ",softreval", "" }, 378 639 { NFS_MOUNT_POSIX, ",posix", "" }, 379 640 { NFS_MOUNT_NOCTO, ",nocto", "" }, 380 641 { NFS_MOUNT_NOAC, ",noac", "" }, ··· 672 931 } 673 932 EXPORT_SYMBOL_GPL(nfs_umount_begin); 674 933 675 - static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) 676 - { 677 - struct nfs_parsed_mount_data *data; 678 - 679 - data = kzalloc(sizeof(*data), GFP_KERNEL); 680 - if (data) { 681 - data->timeo = NFS_UNSPEC_TIMEO; 682 - data->retrans = NFS_UNSPEC_RETRANS; 683 - data->acregmin = NFS_DEF_ACREGMIN; 684 - data->acregmax = NFS_DEF_ACREGMAX; 685 - data->acdirmin = NFS_DEF_ACDIRMIN; 686 - data->acdirmax = NFS_DEF_ACDIRMAX; 687 - data->mount_server.port = NFS_UNSPEC_PORT; 688 - data->nfs_server.port = NFS_UNSPEC_PORT; 689 - data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 690 - data->selected_flavor = RPC_AUTH_MAXFLAVOR; 691 - data->minorversion = 0; 692 - data->need_mount = true; 693 - data->net = current->nsproxy->net_ns; 694 - data->lsm_opts = NULL; 695 - } 696 - return data; 697 - } 698 - 699 - static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data) 700 - { 701 - if (data) { 702 - kfree(data->client_address); 703 - kfree(data->mount_server.hostname); 704 - kfree(data->nfs_server.export_path); 705 - kfree(data->nfs_server.hostname); 706 - kfree(data->fscache_uniq); 707 - security_free_mnt_opts(&data->lsm_opts); 708 - kfree(data); 709 - } 710 - } 711 - 712 - /* 713 - * Sanity-check a server address provided by the mount command. 714 - * 715 - * Address family must be initialized, and address must not be 716 - * the ANY address for that family. 717 - */ 718 - static int nfs_verify_server_address(struct sockaddr *addr) 719 - { 720 - switch (addr->sa_family) { 721 - case AF_INET: { 722 - struct sockaddr_in *sa = (struct sockaddr_in *)addr; 723 - return sa->sin_addr.s_addr != htonl(INADDR_ANY); 724 - } 725 - case AF_INET6: { 726 - struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; 727 - return !ipv6_addr_any(sa); 728 - } 729 - } 730 - 731 - dfprintk(MOUNT, "NFS: Invalid IP address specified\n"); 732 - return 0; 733 - } 734 - 735 - /* 736 - * Select between a default port value and a user-specified port value. 737 - * If a zero value is set, then autobind will be used. 738 - */ 739 - static void nfs_set_port(struct sockaddr *sap, int *port, 740 - const unsigned short default_port) 741 - { 742 - if (*port == NFS_UNSPEC_PORT) 743 - *port = default_port; 744 - 745 - rpc_set_port(sap, *port); 746 - } 747 - 748 - /* 749 - * Sanity check the NFS transport protocol. 750 - * 751 - */ 752 - static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) 753 - { 754 - switch (mnt->nfs_server.protocol) { 755 - case XPRT_TRANSPORT_UDP: 756 - case XPRT_TRANSPORT_TCP: 757 - case XPRT_TRANSPORT_RDMA: 758 - break; 759 - default: 760 - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 761 - } 762 - } 763 - 764 - /* 765 - * For text based NFSv2/v3 mounts, the mount protocol transport default 766 - * settings should depend upon the specified NFS transport. 767 - */ 768 - static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) 769 - { 770 - nfs_validate_transport_protocol(mnt); 771 - 772 - if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP || 773 - mnt->mount_server.protocol == XPRT_TRANSPORT_TCP) 774 - return; 775 - switch (mnt->nfs_server.protocol) { 776 - case XPRT_TRANSPORT_UDP: 777 - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; 778 - break; 779 - case XPRT_TRANSPORT_TCP: 780 - case XPRT_TRANSPORT_RDMA: 781 - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; 782 - } 783 - } 784 - 785 - /* 786 - * Add 'flavor' to 'auth_info' if not already present. 787 - * Returns true if 'flavor' ends up in the list, false otherwise 788 - */ 789 - static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, 790 - rpc_authflavor_t flavor) 791 - { 792 - unsigned int i; 793 - unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors); 794 - 795 - /* make sure this flavor isn't already in the list */ 796 - for (i = 0; i < auth_info->flavor_len; i++) { 797 - if (flavor == auth_info->flavors[i]) 798 - return true; 799 - } 800 - 801 - if (auth_info->flavor_len + 1 >= max_flavor_len) { 802 - dfprintk(MOUNT, "NFS: too many sec= flavors\n"); 803 - return false; 804 - } 805 - 806 - auth_info->flavors[auth_info->flavor_len++] = flavor; 807 - return true; 808 - } 809 - 810 934 /* 811 935 * Return true if 'match' is in auth_info or auth_info is empty. 812 936 * Return false otherwise. ··· 693 1087 EXPORT_SYMBOL_GPL(nfs_auth_info_match); 694 1088 695 1089 /* 696 - * Parse the value of the 'sec=' option. 697 - */ 698 - static int nfs_parse_security_flavors(char *value, 699 - struct nfs_parsed_mount_data *mnt) 700 - { 701 - substring_t args[MAX_OPT_ARGS]; 702 - rpc_authflavor_t pseudoflavor; 703 - char *p; 704 - 705 - dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); 706 - 707 - while ((p = strsep(&value, ":")) != NULL) { 708 - switch (match_token(p, nfs_secflavor_tokens, args)) { 709 - case Opt_sec_none: 710 - pseudoflavor = RPC_AUTH_NULL; 711 - break; 712 - case Opt_sec_sys: 713 - pseudoflavor = RPC_AUTH_UNIX; 714 - break; 715 - case Opt_sec_krb5: 716 - pseudoflavor = RPC_AUTH_GSS_KRB5; 717 - break; 718 - case Opt_sec_krb5i: 719 - pseudoflavor = RPC_AUTH_GSS_KRB5I; 720 - break; 721 - case Opt_sec_krb5p: 722 - pseudoflavor = RPC_AUTH_GSS_KRB5P; 723 - break; 724 - case Opt_sec_lkey: 725 - pseudoflavor = RPC_AUTH_GSS_LKEY; 726 - break; 727 - case Opt_sec_lkeyi: 728 - pseudoflavor = RPC_AUTH_GSS_LKEYI; 729 - break; 730 - case Opt_sec_lkeyp: 731 - pseudoflavor = RPC_AUTH_GSS_LKEYP; 732 - break; 733 - case Opt_sec_spkm: 734 - pseudoflavor = RPC_AUTH_GSS_SPKM; 735 - break; 736 - case Opt_sec_spkmi: 737 - pseudoflavor = RPC_AUTH_GSS_SPKMI; 738 - break; 739 - case Opt_sec_spkmp: 740 - pseudoflavor = RPC_AUTH_GSS_SPKMP; 741 - break; 742 - default: 743 - dfprintk(MOUNT, 744 - "NFS: sec= option '%s' not recognized\n", p); 745 - return 0; 746 - } 747 - 748 - if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) 749 - return 0; 750 - } 751 - 752 - return 1; 753 - } 754 - 755 - static int nfs_parse_version_string(char *string, 756 - struct nfs_parsed_mount_data *mnt, 757 - substring_t *args) 758 - { 759 - mnt->flags &= ~NFS_MOUNT_VER3; 760 - switch (match_token(string, nfs_vers_tokens, args)) { 761 - case Opt_vers_2: 762 - mnt->version = 2; 763 - break; 764 - case Opt_vers_3: 765 - mnt->flags |= NFS_MOUNT_VER3; 766 - mnt->version = 3; 767 - break; 768 - case Opt_vers_4: 769 - /* Backward compatibility option. In future, 770 - * the mount program should always supply 771 - * a NFSv4 minor version number. 772 - */ 773 - mnt->version = 4; 774 - break; 775 - case Opt_vers_4_0: 776 - mnt->version = 4; 777 - mnt->minorversion = 0; 778 - break; 779 - case Opt_vers_4_1: 780 - mnt->version = 4; 781 - mnt->minorversion = 1; 782 - break; 783 - case Opt_vers_4_2: 784 - mnt->version = 4; 785 - mnt->minorversion = 2; 786 - break; 787 - default: 788 - return 0; 789 - } 790 - return 1; 791 - } 792 - 793 - static int nfs_get_option_str(substring_t args[], char **option) 794 - { 795 - kfree(*option); 796 - *option = match_strdup(args); 797 - return !*option; 798 - } 799 - 800 - static int nfs_get_option_ul(substring_t args[], unsigned long *option) 801 - { 802 - int rc; 803 - char *string; 804 - 805 - string = match_strdup(args); 806 - if (string == NULL) 807 - return -ENOMEM; 808 - rc = kstrtoul(string, 10, option); 809 - kfree(string); 810 - 811 - return rc; 812 - } 813 - 814 - static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option, 815 - unsigned long l_bound, unsigned long u_bound) 816 - { 817 - int ret; 818 - 819 - ret = nfs_get_option_ul(args, option); 820 - if (ret != 0) 821 - return ret; 822 - if (*option < l_bound || *option > u_bound) 823 - return -ERANGE; 824 - return 0; 825 - } 826 - 827 - /* 828 - * Error-check and convert a string of mount options from user space into 829 - * a data structure. The whole mount string is processed; bad options are 830 - * skipped as they are encountered. If there were no errors, return 1; 831 - * otherwise return 0 (zero). 832 - */ 833 - static int nfs_parse_mount_options(char *raw, 834 - struct nfs_parsed_mount_data *mnt) 835 - { 836 - char *p, *string; 837 - int rc, sloppy = 0, invalid_option = 0; 838 - unsigned short protofamily = AF_UNSPEC; 839 - unsigned short mountfamily = AF_UNSPEC; 840 - 841 - if (!raw) { 842 - dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 843 - return 1; 844 - } 845 - dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 846 - 847 - rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts); 848 - if (rc) 849 - goto out_security_failure; 850 - 851 - while ((p = strsep(&raw, ",")) != NULL) { 852 - substring_t args[MAX_OPT_ARGS]; 853 - unsigned long option; 854 - int token; 855 - 856 - if (!*p) 857 - continue; 858 - 859 - dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); 860 - 861 - token = match_token(p, nfs_mount_option_tokens, args); 862 - switch (token) { 863 - 864 - /* 865 - * boolean options: foo/nofoo 866 - */ 867 - case Opt_soft: 868 - mnt->flags |= NFS_MOUNT_SOFT; 869 - mnt->flags &= ~NFS_MOUNT_SOFTERR; 870 - break; 871 - case Opt_softerr: 872 - mnt->flags |= NFS_MOUNT_SOFTERR; 873 - mnt->flags &= ~NFS_MOUNT_SOFT; 874 - break; 875 - case Opt_hard: 876 - mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); 877 - break; 878 - case Opt_posix: 879 - mnt->flags |= NFS_MOUNT_POSIX; 880 - break; 881 - case Opt_noposix: 882 - mnt->flags &= ~NFS_MOUNT_POSIX; 883 - break; 884 - case Opt_cto: 885 - mnt->flags &= ~NFS_MOUNT_NOCTO; 886 - break; 887 - case Opt_nocto: 888 - mnt->flags |= NFS_MOUNT_NOCTO; 889 - break; 890 - case Opt_ac: 891 - mnt->flags &= ~NFS_MOUNT_NOAC; 892 - break; 893 - case Opt_noac: 894 - mnt->flags |= NFS_MOUNT_NOAC; 895 - break; 896 - case Opt_lock: 897 - mnt->flags &= ~NFS_MOUNT_NONLM; 898 - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | 899 - NFS_MOUNT_LOCAL_FCNTL); 900 - break; 901 - case Opt_nolock: 902 - mnt->flags |= NFS_MOUNT_NONLM; 903 - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | 904 - NFS_MOUNT_LOCAL_FCNTL); 905 - break; 906 - case Opt_udp: 907 - mnt->flags &= ~NFS_MOUNT_TCP; 908 - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 909 - break; 910 - case Opt_tcp: 911 - mnt->flags |= NFS_MOUNT_TCP; 912 - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 913 - break; 914 - case Opt_rdma: 915 - mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ 916 - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 917 - xprt_load_transport(p); 918 - break; 919 - case Opt_acl: 920 - mnt->flags &= ~NFS_MOUNT_NOACL; 921 - break; 922 - case Opt_noacl: 923 - mnt->flags |= NFS_MOUNT_NOACL; 924 - break; 925 - case Opt_rdirplus: 926 - mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; 927 - break; 928 - case Opt_nordirplus: 929 - mnt->flags |= NFS_MOUNT_NORDIRPLUS; 930 - break; 931 - case Opt_sharecache: 932 - mnt->flags &= ~NFS_MOUNT_UNSHARED; 933 - break; 934 - case Opt_nosharecache: 935 - mnt->flags |= NFS_MOUNT_UNSHARED; 936 - break; 937 - case Opt_resvport: 938 - mnt->flags &= ~NFS_MOUNT_NORESVPORT; 939 - break; 940 - case Opt_noresvport: 941 - mnt->flags |= NFS_MOUNT_NORESVPORT; 942 - break; 943 - case Opt_fscache: 944 - mnt->options |= NFS_OPTION_FSCACHE; 945 - kfree(mnt->fscache_uniq); 946 - mnt->fscache_uniq = NULL; 947 - break; 948 - case Opt_nofscache: 949 - mnt->options &= ~NFS_OPTION_FSCACHE; 950 - kfree(mnt->fscache_uniq); 951 - mnt->fscache_uniq = NULL; 952 - break; 953 - case Opt_migration: 954 - mnt->options |= NFS_OPTION_MIGRATION; 955 - break; 956 - case Opt_nomigration: 957 - mnt->options &= ~NFS_OPTION_MIGRATION; 958 - break; 959 - 960 - /* 961 - * options that take numeric values 962 - */ 963 - case Opt_port: 964 - if (nfs_get_option_ul(args, &option) || 965 - option > USHRT_MAX) 966 - goto out_invalid_value; 967 - mnt->nfs_server.port = option; 968 - break; 969 - case Opt_rsize: 970 - if (nfs_get_option_ul(args, &option)) 971 - goto out_invalid_value; 972 - mnt->rsize = option; 973 - break; 974 - case Opt_wsize: 975 - if (nfs_get_option_ul(args, &option)) 976 - goto out_invalid_value; 977 - mnt->wsize = option; 978 - break; 979 - case Opt_bsize: 980 - if (nfs_get_option_ul(args, &option)) 981 - goto out_invalid_value; 982 - mnt->bsize = option; 983 - break; 984 - case Opt_timeo: 985 - if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX)) 986 - goto out_invalid_value; 987 - mnt->timeo = option; 988 - break; 989 - case Opt_retrans: 990 - if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX)) 991 - goto out_invalid_value; 992 - mnt->retrans = option; 993 - break; 994 - case Opt_acregmin: 995 - if (nfs_get_option_ul(args, &option)) 996 - goto out_invalid_value; 997 - mnt->acregmin = option; 998 - break; 999 - case Opt_acregmax: 1000 - if (nfs_get_option_ul(args, &option)) 1001 - goto out_invalid_value; 1002 - mnt->acregmax = option; 1003 - break; 1004 - case Opt_acdirmin: 1005 - if (nfs_get_option_ul(args, &option)) 1006 - goto out_invalid_value; 1007 - mnt->acdirmin = option; 1008 - break; 1009 - case Opt_acdirmax: 1010 - if (nfs_get_option_ul(args, &option)) 1011 - goto out_invalid_value; 1012 - mnt->acdirmax = option; 1013 - break; 1014 - case Opt_actimeo: 1015 - if (nfs_get_option_ul(args, &option)) 1016 - goto out_invalid_value; 1017 - mnt->acregmin = mnt->acregmax = 1018 - mnt->acdirmin = mnt->acdirmax = option; 1019 - break; 1020 - case Opt_namelen: 1021 - if (nfs_get_option_ul(args, &option)) 1022 - goto out_invalid_value; 1023 - mnt->namlen = option; 1024 - break; 1025 - case Opt_mountport: 1026 - if (nfs_get_option_ul(args, &option) || 1027 - option > USHRT_MAX) 1028 - goto out_invalid_value; 1029 - mnt->mount_server.port = option; 1030 - break; 1031 - case Opt_mountvers: 1032 - if (nfs_get_option_ul(args, &option) || 1033 - option < NFS_MNT_VERSION || 1034 - option > NFS_MNT3_VERSION) 1035 - goto out_invalid_value; 1036 - mnt->mount_server.version = option; 1037 - break; 1038 - case Opt_minorversion: 1039 - if (nfs_get_option_ul(args, &option)) 1040 - goto out_invalid_value; 1041 - if (option > NFS4_MAX_MINOR_VERSION) 1042 - goto out_invalid_value; 1043 - mnt->minorversion = option; 1044 - break; 1045 - 1046 - /* 1047 - * options that take text values 1048 - */ 1049 - case Opt_nfsvers: 1050 - string = match_strdup(args); 1051 - if (string == NULL) 1052 - goto out_nomem; 1053 - rc = nfs_parse_version_string(string, mnt, args); 1054 - kfree(string); 1055 - if (!rc) 1056 - goto out_invalid_value; 1057 - break; 1058 - case Opt_sec: 1059 - string = match_strdup(args); 1060 - if (string == NULL) 1061 - goto out_nomem; 1062 - rc = nfs_parse_security_flavors(string, mnt); 1063 - kfree(string); 1064 - if (!rc) { 1065 - dfprintk(MOUNT, "NFS: unrecognized " 1066 - "security flavor\n"); 1067 - return 0; 1068 - } 1069 - break; 1070 - case Opt_proto: 1071 - string = match_strdup(args); 1072 - if (string == NULL) 1073 - goto out_nomem; 1074 - token = match_token(string, 1075 - nfs_xprt_protocol_tokens, args); 1076 - 1077 - protofamily = AF_INET; 1078 - switch (token) { 1079 - case Opt_xprt_udp6: 1080 - protofamily = AF_INET6; 1081 - /* fall through */ 1082 - case Opt_xprt_udp: 1083 - mnt->flags &= ~NFS_MOUNT_TCP; 1084 - mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1085 - break; 1086 - case Opt_xprt_tcp6: 1087 - protofamily = AF_INET6; 1088 - /* fall through */ 1089 - case Opt_xprt_tcp: 1090 - mnt->flags |= NFS_MOUNT_TCP; 1091 - mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1092 - break; 1093 - case Opt_xprt_rdma6: 1094 - protofamily = AF_INET6; 1095 - /* fall through */ 1096 - case Opt_xprt_rdma: 1097 - /* vector side protocols to TCP */ 1098 - mnt->flags |= NFS_MOUNT_TCP; 1099 - mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1100 - xprt_load_transport(string); 1101 - break; 1102 - default: 1103 - dfprintk(MOUNT, "NFS: unrecognized " 1104 - "transport protocol\n"); 1105 - kfree(string); 1106 - return 0; 1107 - } 1108 - kfree(string); 1109 - break; 1110 - case Opt_mountproto: 1111 - string = match_strdup(args); 1112 - if (string == NULL) 1113 - goto out_nomem; 1114 - token = match_token(string, 1115 - nfs_xprt_protocol_tokens, args); 1116 - kfree(string); 1117 - 1118 - mountfamily = AF_INET; 1119 - switch (token) { 1120 - case Opt_xprt_udp6: 1121 - mountfamily = AF_INET6; 1122 - /* fall through */ 1123 - case Opt_xprt_udp: 1124 - mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; 1125 - break; 1126 - case Opt_xprt_tcp6: 1127 - mountfamily = AF_INET6; 1128 - /* fall through */ 1129 - case Opt_xprt_tcp: 1130 - mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; 1131 - break; 1132 - case Opt_xprt_rdma: /* not used for side protocols */ 1133 - default: 1134 - dfprintk(MOUNT, "NFS: unrecognized " 1135 - "transport protocol\n"); 1136 - return 0; 1137 - } 1138 - break; 1139 - case Opt_addr: 1140 - string = match_strdup(args); 1141 - if (string == NULL) 1142 - goto out_nomem; 1143 - mnt->nfs_server.addrlen = 1144 - rpc_pton(mnt->net, string, strlen(string), 1145 - (struct sockaddr *) 1146 - &mnt->nfs_server.address, 1147 - sizeof(mnt->nfs_server.address)); 1148 - kfree(string); 1149 - if (mnt->nfs_server.addrlen == 0) 1150 - goto out_invalid_address; 1151 - break; 1152 - case Opt_clientaddr: 1153 - if (nfs_get_option_str(args, &mnt->client_address)) 1154 - goto out_nomem; 1155 - break; 1156 - case Opt_mounthost: 1157 - if (nfs_get_option_str(args, 1158 - &mnt->mount_server.hostname)) 1159 - goto out_nomem; 1160 - break; 1161 - case Opt_mountaddr: 1162 - string = match_strdup(args); 1163 - if (string == NULL) 1164 - goto out_nomem; 1165 - mnt->mount_server.addrlen = 1166 - rpc_pton(mnt->net, string, strlen(string), 1167 - (struct sockaddr *) 1168 - &mnt->mount_server.address, 1169 - sizeof(mnt->mount_server.address)); 1170 - kfree(string); 1171 - if (mnt->mount_server.addrlen == 0) 1172 - goto out_invalid_address; 1173 - break; 1174 - case Opt_nconnect: 1175 - if (nfs_get_option_ul_bound(args, &option, 1, NFS_MAX_CONNECTIONS)) 1176 - goto out_invalid_value; 1177 - mnt->nfs_server.nconnect = option; 1178 - break; 1179 - case Opt_lookupcache: 1180 - string = match_strdup(args); 1181 - if (string == NULL) 1182 - goto out_nomem; 1183 - token = match_token(string, 1184 - nfs_lookupcache_tokens, args); 1185 - kfree(string); 1186 - switch (token) { 1187 - case Opt_lookupcache_all: 1188 - mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE); 1189 - break; 1190 - case Opt_lookupcache_positive: 1191 - mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE; 1192 - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG; 1193 - break; 1194 - case Opt_lookupcache_none: 1195 - mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; 1196 - break; 1197 - default: 1198 - dfprintk(MOUNT, "NFS: invalid " 1199 - "lookupcache argument\n"); 1200 - return 0; 1201 - } 1202 - break; 1203 - case Opt_fscache_uniq: 1204 - if (nfs_get_option_str(args, &mnt->fscache_uniq)) 1205 - goto out_nomem; 1206 - mnt->options |= NFS_OPTION_FSCACHE; 1207 - break; 1208 - case Opt_local_lock: 1209 - string = match_strdup(args); 1210 - if (string == NULL) 1211 - goto out_nomem; 1212 - token = match_token(string, nfs_local_lock_tokens, 1213 - args); 1214 - kfree(string); 1215 - switch (token) { 1216 - case Opt_local_lock_all: 1217 - mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK | 1218 - NFS_MOUNT_LOCAL_FCNTL); 1219 - break; 1220 - case Opt_local_lock_flock: 1221 - mnt->flags |= NFS_MOUNT_LOCAL_FLOCK; 1222 - break; 1223 - case Opt_local_lock_posix: 1224 - mnt->flags |= NFS_MOUNT_LOCAL_FCNTL; 1225 - break; 1226 - case Opt_local_lock_none: 1227 - mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | 1228 - NFS_MOUNT_LOCAL_FCNTL); 1229 - break; 1230 - default: 1231 - dfprintk(MOUNT, "NFS: invalid " 1232 - "local_lock argument\n"); 1233 - return 0; 1234 - } 1235 - break; 1236 - 1237 - /* 1238 - * Special options 1239 - */ 1240 - case Opt_sloppy: 1241 - sloppy = 1; 1242 - dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); 1243 - break; 1244 - case Opt_userspace: 1245 - case Opt_deprecated: 1246 - dfprintk(MOUNT, "NFS: ignoring mount option " 1247 - "'%s'\n", p); 1248 - break; 1249 - 1250 - default: 1251 - invalid_option = 1; 1252 - dfprintk(MOUNT, "NFS: unrecognized mount option " 1253 - "'%s'\n", p); 1254 - } 1255 - } 1256 - 1257 - if (!sloppy && invalid_option) 1258 - return 0; 1259 - 1260 - if (mnt->minorversion && mnt->version != 4) 1261 - goto out_minorversion_mismatch; 1262 - 1263 - if (mnt->options & NFS_OPTION_MIGRATION && 1264 - (mnt->version != 4 || mnt->minorversion != 0)) 1265 - goto out_migration_misuse; 1266 - 1267 - /* 1268 - * verify that any proto=/mountproto= options match the address 1269 - * families in the addr=/mountaddr= options. 1270 - */ 1271 - if (protofamily != AF_UNSPEC && 1272 - protofamily != mnt->nfs_server.address.ss_family) 1273 - goto out_proto_mismatch; 1274 - 1275 - if (mountfamily != AF_UNSPEC) { 1276 - if (mnt->mount_server.addrlen) { 1277 - if (mountfamily != mnt->mount_server.address.ss_family) 1278 - goto out_mountproto_mismatch; 1279 - } else { 1280 - if (mountfamily != mnt->nfs_server.address.ss_family) 1281 - goto out_mountproto_mismatch; 1282 - } 1283 - } 1284 - 1285 - return 1; 1286 - 1287 - out_mountproto_mismatch: 1288 - printk(KERN_INFO "NFS: mount server address does not match mountproto= " 1289 - "option\n"); 1290 - return 0; 1291 - out_proto_mismatch: 1292 - printk(KERN_INFO "NFS: server address does not match proto= option\n"); 1293 - return 0; 1294 - out_invalid_address: 1295 - printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); 1296 - return 0; 1297 - out_invalid_value: 1298 - printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p); 1299 - return 0; 1300 - out_minorversion_mismatch: 1301 - printk(KERN_INFO "NFS: mount option vers=%u does not support " 1302 - "minorversion=%u\n", mnt->version, mnt->minorversion); 1303 - return 0; 1304 - out_migration_misuse: 1305 - printk(KERN_INFO 1306 - "NFS: 'migration' not supported for this NFS version\n"); 1307 - return 0; 1308 - out_nomem: 1309 - printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1310 - return 0; 1311 - out_security_failure: 1312 - printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1313 - return 0; 1314 - } 1315 - 1316 - /* 1317 - * Ensure that a specified authtype in args->auth_info is supported by 1318 - * the server. Returns 0 and sets args->selected_flavor if it's ok, and 1090 + * Ensure that a specified authtype in ctx->auth_info is supported by 1091 + * the server. Returns 0 and sets ctx->selected_flavor if it's ok, and 1319 1092 * -EACCES if not. 1320 1093 */ 1321 - static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, 1322 - rpc_authflavor_t *server_authlist, unsigned int count) 1094 + static int nfs_verify_authflavors(struct nfs_fs_context *ctx, 1095 + rpc_authflavor_t *server_authlist, 1096 + unsigned int count) 1323 1097 { 1324 1098 rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; 1325 1099 bool found_auth_null = false; ··· 720 1734 for (i = 0; i < count; i++) { 721 1735 flavor = server_authlist[i]; 722 1736 723 - if (nfs_auth_info_match(&args->auth_info, flavor)) 1737 + if (nfs_auth_info_match(&ctx->auth_info, flavor)) 724 1738 goto out; 725 1739 726 1740 if (flavor == RPC_AUTH_NULL) ··· 728 1742 } 729 1743 730 1744 if (found_auth_null) { 731 - flavor = args->auth_info.flavors[0]; 1745 + flavor = ctx->auth_info.flavors[0]; 732 1746 goto out; 733 1747 } 734 1748 ··· 737 1751 return -EACCES; 738 1752 739 1753 out: 740 - args->selected_flavor = flavor; 741 - dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor); 1754 + ctx->selected_flavor = flavor; 1755 + dfprintk(MOUNT, "NFS: using auth flavor %u\n", ctx->selected_flavor); 742 1756 return 0; 743 1757 } 744 1758 ··· 746 1760 * Use the remote server's MOUNT service to request the NFS file handle 747 1761 * corresponding to the provided path. 748 1762 */ 749 - static int nfs_request_mount(struct nfs_parsed_mount_data *args, 1763 + static int nfs_request_mount(struct fs_context *fc, 750 1764 struct nfs_fh *root_fh, 751 1765 rpc_authflavor_t *server_authlist, 752 1766 unsigned int *server_authlist_len) 753 1767 { 1768 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 754 1769 struct nfs_mount_request request = { 755 1770 .sap = (struct sockaddr *) 756 - &args->mount_server.address, 757 - .dirpath = args->nfs_server.export_path, 758 - .protocol = args->mount_server.protocol, 1771 + &ctx->mount_server.address, 1772 + .dirpath = ctx->nfs_server.export_path, 1773 + .protocol = ctx->mount_server.protocol, 759 1774 .fh = root_fh, 760 - .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1775 + .noresvport = ctx->flags & NFS_MOUNT_NORESVPORT, 761 1776 .auth_flav_len = server_authlist_len, 762 1777 .auth_flavs = server_authlist, 763 - .net = args->net, 1778 + .net = fc->net_ns, 764 1779 }; 765 1780 int status; 766 1781 767 - if (args->mount_server.version == 0) { 768 - switch (args->version) { 1782 + if (ctx->mount_server.version == 0) { 1783 + switch (ctx->version) { 769 1784 default: 770 - args->mount_server.version = NFS_MNT3_VERSION; 1785 + ctx->mount_server.version = NFS_MNT3_VERSION; 771 1786 break; 772 1787 case 2: 773 - args->mount_server.version = NFS_MNT_VERSION; 1788 + ctx->mount_server.version = NFS_MNT_VERSION; 774 1789 } 775 1790 } 776 - request.version = args->mount_server.version; 1791 + request.version = ctx->mount_server.version; 777 1792 778 - if (args->mount_server.hostname) 779 - request.hostname = args->mount_server.hostname; 1793 + if (ctx->mount_server.hostname) 1794 + request.hostname = ctx->mount_server.hostname; 780 1795 else 781 - request.hostname = args->nfs_server.hostname; 1796 + request.hostname = ctx->nfs_server.hostname; 782 1797 783 1798 /* 784 1799 * Construct the mount server's address. 785 1800 */ 786 - if (args->mount_server.address.ss_family == AF_UNSPEC) { 787 - memcpy(request.sap, &args->nfs_server.address, 788 - args->nfs_server.addrlen); 789 - args->mount_server.addrlen = args->nfs_server.addrlen; 1801 + if (ctx->mount_server.address.sa_family == AF_UNSPEC) { 1802 + memcpy(request.sap, &ctx->nfs_server.address, 1803 + ctx->nfs_server.addrlen); 1804 + ctx->mount_server.addrlen = ctx->nfs_server.addrlen; 790 1805 } 791 - request.salen = args->mount_server.addrlen; 792 - nfs_set_port(request.sap, &args->mount_server.port, 0); 1806 + request.salen = ctx->mount_server.addrlen; 1807 + nfs_set_port(request.sap, &ctx->mount_server.port, 0); 793 1808 794 1809 /* 795 1810 * Now ask the mount server to map our export path ··· 806 1819 return 0; 807 1820 } 808 1821 809 - static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info, 810 - struct nfs_subversion *nfs_mod) 1822 + static struct nfs_server *nfs_try_mount_request(struct fs_context *fc) 811 1823 { 1824 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 812 1825 int status; 813 1826 unsigned int i; 814 1827 bool tried_auth_unix = false; 815 1828 bool auth_null_in_list = false; 816 1829 struct nfs_server *server = ERR_PTR(-EACCES); 817 - struct nfs_parsed_mount_data *args = mount_info->parsed; 818 1830 rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS]; 819 1831 unsigned int authlist_len = ARRAY_SIZE(authlist); 820 1832 821 - status = nfs_request_mount(args, mount_info->mntfh, authlist, 822 - &authlist_len); 1833 + status = nfs_request_mount(fc, ctx->mntfh, authlist, &authlist_len); 823 1834 if (status) 824 1835 return ERR_PTR(status); 825 1836 ··· 825 1840 * Was a sec= authflavor specified in the options? First, verify 826 1841 * whether the server supports it, and then just try to use it if so. 827 1842 */ 828 - if (args->auth_info.flavor_len > 0) { 829 - status = nfs_verify_authflavors(args, authlist, authlist_len); 1843 + if (ctx->auth_info.flavor_len > 0) { 1844 + status = nfs_verify_authflavors(ctx, authlist, authlist_len); 830 1845 dfprintk(MOUNT, "NFS: using auth flavor %u\n", 831 - args->selected_flavor); 1846 + ctx->selected_flavor); 832 1847 if (status) 833 1848 return ERR_PTR(status); 834 - return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1849 + return ctx->nfs_mod->rpc_ops->create_server(fc); 835 1850 } 836 1851 837 1852 /* ··· 857 1872 /* Fallthrough */ 858 1873 } 859 1874 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); 860 - args->selected_flavor = flavor; 861 - server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1875 + ctx->selected_flavor = flavor; 1876 + server = ctx->nfs_mod->rpc_ops->create_server(fc); 862 1877 if (!IS_ERR(server)) 863 1878 return server; 864 1879 } ··· 873 1888 874 1889 /* Last chance! Try AUTH_UNIX */ 875 1890 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); 876 - args->selected_flavor = RPC_AUTH_UNIX; 877 - return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1891 + ctx->selected_flavor = RPC_AUTH_UNIX; 1892 + return ctx->nfs_mod->rpc_ops->create_server(fc); 878 1893 } 879 1894 880 - struct dentry *nfs_try_mount(int flags, const char *dev_name, 881 - struct nfs_mount_info *mount_info, 882 - struct nfs_subversion *nfs_mod) 1895 + int nfs_try_get_tree(struct fs_context *fc) 883 1896 { 884 - struct nfs_server *server; 1897 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 885 1898 886 - if (mount_info->parsed->need_mount) 887 - server = nfs_try_mount_request(mount_info, nfs_mod); 1899 + if (ctx->need_mount) 1900 + ctx->server = nfs_try_mount_request(fc); 888 1901 else 889 - server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1902 + ctx->server = ctx->nfs_mod->rpc_ops->create_server(fc); 890 1903 891 - if (IS_ERR(server)) 892 - return ERR_CAST(server); 893 - 894 - return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod); 1904 + return nfs_get_tree_common(fc); 895 1905 } 896 - EXPORT_SYMBOL_GPL(nfs_try_mount); 1906 + EXPORT_SYMBOL_GPL(nfs_try_get_tree); 897 1907 898 - /* 899 - * Split "dev_name" into "hostname:export_path". 900 - * 901 - * The leftmost colon demarks the split between the server's hostname 902 - * and the export path. If the hostname starts with a left square 903 - * bracket, then it may contain colons. 904 - * 905 - * Note: caller frees hostname and export path, even on error. 906 - */ 907 - static int nfs_parse_devname(const char *dev_name, 908 - char **hostname, size_t maxnamlen, 909 - char **export_path, size_t maxpathlen) 910 - { 911 - size_t len; 912 - char *end; 913 - 914 - if (unlikely(!dev_name || !*dev_name)) { 915 - dfprintk(MOUNT, "NFS: device name not specified\n"); 916 - return -EINVAL; 917 - } 918 - 919 - /* Is the host name protected with square brakcets? */ 920 - if (*dev_name == '[') { 921 - end = strchr(++dev_name, ']'); 922 - if (end == NULL || end[1] != ':') 923 - goto out_bad_devname; 924 - 925 - len = end - dev_name; 926 - end++; 927 - } else { 928 - char *comma; 929 - 930 - end = strchr(dev_name, ':'); 931 - if (end == NULL) 932 - goto out_bad_devname; 933 - len = end - dev_name; 934 - 935 - /* kill possible hostname list: not supported */ 936 - comma = strchr(dev_name, ','); 937 - if (comma != NULL && comma < end) 938 - len = comma - dev_name; 939 - } 940 - 941 - if (len > maxnamlen) 942 - goto out_hostname; 943 - 944 - /* N.B. caller will free nfs_server.hostname in all cases */ 945 - *hostname = kstrndup(dev_name, len, GFP_KERNEL); 946 - if (*hostname == NULL) 947 - goto out_nomem; 948 - len = strlen(++end); 949 - if (len > maxpathlen) 950 - goto out_path; 951 - *export_path = kstrndup(end, len, GFP_KERNEL); 952 - if (!*export_path) 953 - goto out_nomem; 954 - 955 - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path); 956 - return 0; 957 - 958 - out_bad_devname: 959 - dfprintk(MOUNT, "NFS: device name not in host:path format\n"); 960 - return -EINVAL; 961 - 962 - out_nomem: 963 - dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); 964 - return -ENOMEM; 965 - 966 - out_hostname: 967 - dfprintk(MOUNT, "NFS: server hostname too long\n"); 968 - return -ENAMETOOLONG; 969 - 970 - out_path: 971 - dfprintk(MOUNT, "NFS: export pathname too long\n"); 972 - return -ENAMETOOLONG; 973 - } 974 - 975 - /* 976 - * Validate the NFS2/NFS3 mount data 977 - * - fills in the mount root filehandle 978 - * 979 - * For option strings, user space handles the following behaviors: 980 - * 981 - * + DNS: mapping server host name to IP address ("addr=" option) 982 - * 983 - * + failure mode: how to behave if a mount request can't be handled 984 - * immediately ("fg/bg" option) 985 - * 986 - * + retry: how often to retry a mount request ("retry=" option) 987 - * 988 - * + breaking back: trying proto=udp after proto=tcp, v2 after v3, 989 - * mountproto=tcp after mountproto=udp, and so on 990 - */ 991 - static int nfs23_validate_mount_data(void *options, 992 - struct nfs_parsed_mount_data *args, 993 - struct nfs_fh *mntfh, 994 - const char *dev_name) 995 - { 996 - struct nfs_mount_data *data = (struct nfs_mount_data *)options; 997 - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 998 - int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; 999 - 1000 - if (data == NULL) 1001 - goto out_no_data; 1002 - 1003 - args->version = NFS_DEFAULT_VERSION; 1004 - switch (data->version) { 1005 - case 1: 1006 - data->namlen = 0; /* fall through */ 1007 - case 2: 1008 - data->bsize = 0; /* fall through */ 1009 - case 3: 1010 - if (data->flags & NFS_MOUNT_VER3) 1011 - goto out_no_v3; 1012 - data->root.size = NFS2_FHSIZE; 1013 - memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 1014 - /* Turn off security negotiation */ 1015 - extra_flags |= NFS_MOUNT_SECFLAVOUR; 1016 - /* fall through */ 1017 - case 4: 1018 - if (data->flags & NFS_MOUNT_SECFLAVOUR) 1019 - goto out_no_sec; 1020 - /* fall through */ 1021 - case 5: 1022 - memset(data->context, 0, sizeof(data->context)); 1023 - /* fall through */ 1024 - case 6: 1025 - if (data->flags & NFS_MOUNT_VER3) { 1026 - if (data->root.size > NFS3_FHSIZE || data->root.size == 0) 1027 - goto out_invalid_fh; 1028 - mntfh->size = data->root.size; 1029 - args->version = 3; 1030 - } else { 1031 - mntfh->size = NFS2_FHSIZE; 1032 - args->version = 2; 1033 - } 1034 - 1035 - 1036 - memcpy(mntfh->data, data->root.data, mntfh->size); 1037 - if (mntfh->size < sizeof(mntfh->data)) 1038 - memset(mntfh->data + mntfh->size, 0, 1039 - sizeof(mntfh->data) - mntfh->size); 1040 - 1041 - /* 1042 - * Translate to nfs_parsed_mount_data, which nfs_fill_super 1043 - * can deal with. 1044 - */ 1045 - args->flags = data->flags & NFS_MOUNT_FLAGMASK; 1046 - args->flags |= extra_flags; 1047 - args->rsize = data->rsize; 1048 - args->wsize = data->wsize; 1049 - args->timeo = data->timeo; 1050 - args->retrans = data->retrans; 1051 - args->acregmin = data->acregmin; 1052 - args->acregmax = data->acregmax; 1053 - args->acdirmin = data->acdirmin; 1054 - args->acdirmax = data->acdirmax; 1055 - args->need_mount = false; 1056 - 1057 - memcpy(sap, &data->addr, sizeof(data->addr)); 1058 - args->nfs_server.addrlen = sizeof(data->addr); 1059 - args->nfs_server.port = ntohs(data->addr.sin_port); 1060 - if (sap->sa_family != AF_INET || 1061 - !nfs_verify_server_address(sap)) 1062 - goto out_no_address; 1063 - 1064 - if (!(data->flags & NFS_MOUNT_TCP)) 1065 - args->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1066 - /* N.B. caller will free nfs_server.hostname in all cases */ 1067 - args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); 1068 - args->namlen = data->namlen; 1069 - args->bsize = data->bsize; 1070 - 1071 - if (data->flags & NFS_MOUNT_SECFLAVOUR) 1072 - args->selected_flavor = data->pseudoflavor; 1073 - else 1074 - args->selected_flavor = RPC_AUTH_UNIX; 1075 - if (!args->nfs_server.hostname) 1076 - goto out_nomem; 1077 - 1078 - if (!(data->flags & NFS_MOUNT_NONLM)) 1079 - args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| 1080 - NFS_MOUNT_LOCAL_FCNTL); 1081 - else 1082 - args->flags |= (NFS_MOUNT_LOCAL_FLOCK| 1083 - NFS_MOUNT_LOCAL_FCNTL); 1084 - /* 1085 - * The legacy version 6 binary mount data from userspace has a 1086 - * field used only to transport selinux information into the 1087 - * the kernel. To continue to support that functionality we 1088 - * have a touch of selinux knowledge here in the NFS code. The 1089 - * userspace code converted context=blah to just blah so we are 1090 - * converting back to the full string selinux understands. 1091 - */ 1092 - if (data->context[0]){ 1093 - #ifdef CONFIG_SECURITY_SELINUX 1094 - int rc; 1095 - data->context[NFS_MAX_CONTEXT_LEN] = '\0'; 1096 - rc = security_add_mnt_opt("context", data->context, 1097 - strlen(data->context), &args->lsm_opts); 1098 - if (rc) 1099 - return rc; 1100 - #else 1101 - return -EINVAL; 1102 - #endif 1103 - } 1104 - 1105 - break; 1106 - default: 1107 - return NFS_TEXT_DATA; 1108 - } 1109 - 1110 - return 0; 1111 - 1112 - out_no_data: 1113 - dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n"); 1114 - return -EINVAL; 1115 - 1116 - out_no_v3: 1117 - dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n", 1118 - data->version); 1119 - return -EINVAL; 1120 - 1121 - out_no_sec: 1122 - dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); 1123 - return -EINVAL; 1124 - 1125 - out_nomem: 1126 - dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); 1127 - return -ENOMEM; 1128 - 1129 - out_no_address: 1130 - dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 1131 - return -EINVAL; 1132 - 1133 - out_invalid_fh: 1134 - dfprintk(MOUNT, "NFS: invalid root filehandle\n"); 1135 - return -EINVAL; 1136 - } 1137 - 1138 - #if IS_ENABLED(CONFIG_NFS_V4) 1139 - static int nfs_validate_mount_data(struct file_system_type *fs_type, 1140 - void *options, 1141 - struct nfs_parsed_mount_data *args, 1142 - struct nfs_fh *mntfh, 1143 - const char *dev_name) 1144 - { 1145 - if (fs_type == &nfs_fs_type) 1146 - return nfs23_validate_mount_data(options, args, mntfh, dev_name); 1147 - return nfs4_validate_mount_data(options, args, dev_name); 1148 - } 1149 - #else 1150 - static int nfs_validate_mount_data(struct file_system_type *fs_type, 1151 - void *options, 1152 - struct nfs_parsed_mount_data *args, 1153 - struct nfs_fh *mntfh, 1154 - const char *dev_name) 1155 - { 1156 - return nfs23_validate_mount_data(options, args, mntfh, dev_name); 1157 - } 1158 - #endif 1159 - 1160 - static int nfs_validate_text_mount_data(void *options, 1161 - struct nfs_parsed_mount_data *args, 1162 - const char *dev_name) 1163 - { 1164 - int port = 0; 1165 - int max_namelen = PAGE_SIZE; 1166 - int max_pathlen = NFS_MAXPATHLEN; 1167 - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 1168 - 1169 - if (nfs_parse_mount_options((char *)options, args) == 0) 1170 - return -EINVAL; 1171 - 1172 - if (!nfs_verify_server_address(sap)) 1173 - goto out_no_address; 1174 - 1175 - if (args->version == 4) { 1176 - #if IS_ENABLED(CONFIG_NFS_V4) 1177 - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1178 - port = NFS_RDMA_PORT; 1179 - else 1180 - port = NFS_PORT; 1181 - max_namelen = NFS4_MAXNAMLEN; 1182 - max_pathlen = NFS4_MAXPATHLEN; 1183 - nfs_validate_transport_protocol(args); 1184 - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1185 - goto out_invalid_transport_udp; 1186 - nfs4_validate_mount_flags(args); 1187 - #else 1188 - goto out_v4_not_compiled; 1189 - #endif /* CONFIG_NFS_V4 */ 1190 - } else { 1191 - nfs_set_mount_transport_protocol(args); 1192 - if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1193 - port = NFS_RDMA_PORT; 1194 - } 1195 - 1196 - nfs_set_port(sap, &args->nfs_server.port, port); 1197 - 1198 - return nfs_parse_devname(dev_name, 1199 - &args->nfs_server.hostname, 1200 - max_namelen, 1201 - &args->nfs_server.export_path, 1202 - max_pathlen); 1203 - 1204 - #if !IS_ENABLED(CONFIG_NFS_V4) 1205 - out_v4_not_compiled: 1206 - dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 1207 - return -EPROTONOSUPPORT; 1208 - #else 1209 - out_invalid_transport_udp: 1210 - dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1211 - return -EINVAL; 1212 - #endif /* !CONFIG_NFS_V4 */ 1213 - 1214 - out_no_address: 1215 - dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 1216 - return -EINVAL; 1217 - } 1218 1908 1219 1909 #define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \ 1220 1910 | NFS_MOUNT_SECURE \ ··· 906 2246 907 2247 static int 908 2248 nfs_compare_remount_data(struct nfs_server *nfss, 909 - struct nfs_parsed_mount_data *data) 2249 + struct nfs_fs_context *ctx) 910 2250 { 911 - if ((data->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK || 912 - data->rsize != nfss->rsize || 913 - data->wsize != nfss->wsize || 914 - data->version != nfss->nfs_client->rpc_ops->version || 915 - data->minorversion != nfss->nfs_client->cl_minorversion || 916 - data->retrans != nfss->client->cl_timeout->to_retries || 917 - !nfs_auth_info_match(&data->auth_info, nfss->client->cl_auth->au_flavor) || 918 - data->acregmin != nfss->acregmin / HZ || 919 - data->acregmax != nfss->acregmax / HZ || 920 - data->acdirmin != nfss->acdirmin / HZ || 921 - data->acdirmax != nfss->acdirmax / HZ || 922 - data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || 923 - (data->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) || 924 - data->nfs_server.port != nfss->port || 925 - data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || 926 - !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address, 2251 + if ((ctx->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK || 2252 + ctx->rsize != nfss->rsize || 2253 + ctx->wsize != nfss->wsize || 2254 + ctx->version != nfss->nfs_client->rpc_ops->version || 2255 + ctx->minorversion != nfss->nfs_client->cl_minorversion || 2256 + ctx->retrans != nfss->client->cl_timeout->to_retries || 2257 + !nfs_auth_info_match(&ctx->auth_info, nfss->client->cl_auth->au_flavor) || 2258 + ctx->acregmin != nfss->acregmin / HZ || 2259 + ctx->acregmax != nfss->acregmax / HZ || 2260 + ctx->acdirmin != nfss->acdirmin / HZ || 2261 + ctx->acdirmax != nfss->acdirmax / HZ || 2262 + ctx->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || 2263 + (ctx->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) || 2264 + ctx->nfs_server.port != nfss->port || 2265 + ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || 2266 + !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address, 927 2267 (struct sockaddr *)&nfss->nfs_client->cl_addr)) 928 2268 return -EINVAL; 929 2269 930 2270 return 0; 931 2271 } 932 2272 933 - int 934 - nfs_remount(struct super_block *sb, int *flags, char *raw_data) 2273 + int nfs_reconfigure(struct fs_context *fc) 935 2274 { 936 - int error; 2275 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 2276 + struct super_block *sb = fc->root->d_sb; 937 2277 struct nfs_server *nfss = sb->s_fs_info; 938 - struct nfs_parsed_mount_data *data; 939 - struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data; 940 - struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; 941 - u32 nfsvers = nfss->nfs_client->rpc_ops->version; 942 2278 943 2279 sync_filesystem(sb); 944 2280 ··· 944 2288 * ones were explicitly specified. Fall back to legacy behavior and 945 2289 * just return success. 946 2290 */ 947 - if ((nfsvers == 4 && (!options4 || options4->version == 1)) || 948 - (nfsvers <= 3 && (!options || (options->version >= 1 && 949 - options->version <= 6)))) 2291 + if (ctx->skip_reconfig_option_check) 950 2292 return 0; 951 - 952 - data = nfs_alloc_parsed_mount_data(); 953 - if (data == NULL) 954 - return -ENOMEM; 955 - 956 - /* fill out struct with values from existing mount */ 957 - data->flags = nfss->flags; 958 - data->rsize = nfss->rsize; 959 - data->wsize = nfss->wsize; 960 - data->retrans = nfss->client->cl_timeout->to_retries; 961 - data->selected_flavor = nfss->client->cl_auth->au_flavor; 962 - data->acregmin = nfss->acregmin / HZ; 963 - data->acregmax = nfss->acregmax / HZ; 964 - data->acdirmin = nfss->acdirmin / HZ; 965 - data->acdirmax = nfss->acdirmax / HZ; 966 - data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; 967 - data->nfs_server.port = nfss->port; 968 - data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; 969 - data->version = nfsvers; 970 - data->minorversion = nfss->nfs_client->cl_minorversion; 971 - data->net = current->nsproxy->net_ns; 972 - memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, 973 - data->nfs_server.addrlen); 974 - 975 - /* overwrite those values with any that were specified */ 976 - error = -EINVAL; 977 - if (!nfs_parse_mount_options((char *)options, data)) 978 - goto out; 979 2293 980 2294 /* 981 2295 * noac is a special case. It implies -o sync, but that's not 982 - * necessarily reflected in the mtab options. do_remount_sb 2296 + * necessarily reflected in the mtab options. reconfigure_super 983 2297 * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the 984 2298 * remount options, so we have to explicitly reset it. 985 2299 */ 986 - if (data->flags & NFS_MOUNT_NOAC) 987 - *flags |= SB_SYNCHRONOUS; 2300 + if (ctx->flags & NFS_MOUNT_NOAC) { 2301 + fc->sb_flags |= SB_SYNCHRONOUS; 2302 + fc->sb_flags_mask |= SB_SYNCHRONOUS; 2303 + } 988 2304 989 2305 /* compare new mount options with old ones */ 990 - error = nfs_compare_remount_data(nfss, data); 991 - if (!error) 992 - error = security_sb_remount(sb, data->lsm_opts); 993 - out: 994 - nfs_free_parsed_mount_data(data); 995 - return error; 2306 + return nfs_compare_remount_data(nfss, ctx); 996 2307 } 997 - EXPORT_SYMBOL_GPL(nfs_remount); 2308 + EXPORT_SYMBOL_GPL(nfs_reconfigure); 998 2309 999 2310 /* 1000 - * Initialise the common bits of the superblock 2311 + * Finish setting up an NFS superblock 1001 2312 */ 1002 - static void nfs_initialise_sb(struct super_block *sb) 2313 + static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx) 1003 2314 { 1004 - struct nfs_server *server = NFS_SB(sb); 1005 - 1006 - sb->s_magic = NFS_SUPER_MAGIC; 1007 - 1008 - /* We probably want something more informative here */ 1009 - snprintf(sb->s_id, sizeof(sb->s_id), 1010 - "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev)); 1011 - 1012 - if (sb->s_blocksize == 0) 1013 - sb->s_blocksize = nfs_block_bits(server->wsize, 1014 - &sb->s_blocksize_bits); 1015 - 1016 - nfs_super_set_maxbytes(sb, server->maxfilesize); 1017 - } 1018 - 1019 - /* 1020 - * Finish setting up an NFS2/3 superblock 1021 - */ 1022 - void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) 1023 - { 1024 - struct nfs_parsed_mount_data *data = mount_info->parsed; 1025 2315 struct nfs_server *server = NFS_SB(sb); 1026 2316 1027 2317 sb->s_blocksize_bits = 0; 1028 2318 sb->s_blocksize = 0; 1029 2319 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; 1030 2320 sb->s_op = server->nfs_client->cl_nfs_mod->sops; 1031 - if (data && data->bsize) 1032 - sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); 2321 + if (ctx && ctx->bsize) 2322 + sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits); 1033 2323 1034 2324 if (server->nfs_client->rpc_ops->version != 2) { 1035 2325 /* The VFS shouldn't apply the umask to mode bits. We will do ··· 995 2393 sb->s_time_max = S64_MAX; 996 2394 } 997 2395 998 - nfs_initialise_sb(sb); 999 - } 1000 - EXPORT_SYMBOL_GPL(nfs_fill_super); 2396 + sb->s_magic = NFS_SUPER_MAGIC; 1001 2397 1002 - /* 1003 - * Finish setting up a cloned NFS2/3/4 superblock 1004 - */ 1005 - static void nfs_clone_super(struct super_block *sb, 1006 - struct nfs_mount_info *mount_info) 1007 - { 1008 - const struct super_block *old_sb = mount_info->cloned->sb; 1009 - struct nfs_server *server = NFS_SB(sb); 2398 + /* We probably want something more informative here */ 2399 + snprintf(sb->s_id, sizeof(sb->s_id), 2400 + "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev)); 1010 2401 1011 - sb->s_blocksize_bits = old_sb->s_blocksize_bits; 1012 - sb->s_blocksize = old_sb->s_blocksize; 1013 - sb->s_maxbytes = old_sb->s_maxbytes; 1014 - sb->s_xattr = old_sb->s_xattr; 1015 - sb->s_op = old_sb->s_op; 1016 - sb->s_export_op = old_sb->s_export_op; 2402 + if (sb->s_blocksize == 0) 2403 + sb->s_blocksize = nfs_block_bits(server->wsize, 2404 + &sb->s_blocksize_bits); 1017 2405 1018 - if (server->nfs_client->rpc_ops->version != 2) { 1019 - /* The VFS shouldn't apply the umask to mode bits. We will do 1020 - * so ourselves when necessary. 1021 - */ 1022 - sb->s_flags |= SB_POSIXACL; 1023 - sb->s_time_gran = 1; 1024 - } else 1025 - sb->s_time_gran = 1000; 1026 - 1027 - if (server->nfs_client->rpc_ops->version != 4) { 1028 - sb->s_time_min = 0; 1029 - sb->s_time_max = U32_MAX; 1030 - } else { 1031 - sb->s_time_min = S64_MIN; 1032 - sb->s_time_max = S64_MAX; 1033 - } 1034 - 1035 - nfs_initialise_sb(sb); 2406 + nfs_super_set_maxbytes(sb, server->maxfilesize); 1036 2407 } 1037 2408 1038 - static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) 2409 + static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, 2410 + const struct fs_context *fc) 1039 2411 { 1040 2412 const struct nfs_server *a = s->s_fs_info; 1041 2413 const struct rpc_clnt *clnt_a = a->client; 1042 2414 const struct rpc_clnt *clnt_b = b->client; 1043 2415 1044 - if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK)) 2416 + if ((s->s_flags & NFS_SB_MASK) != (fc->sb_flags & NFS_SB_MASK)) 1045 2417 goto Ebusy; 1046 2418 if (a->nfs_client != b->nfs_client) 1047 2419 goto Ebusy; ··· 1040 2464 return 0; 1041 2465 } 1042 2466 1043 - struct nfs_sb_mountdata { 1044 - struct nfs_server *server; 1045 - int mntflags; 1046 - }; 1047 - 1048 - static int nfs_set_super(struct super_block *s, void *data) 2467 + static int nfs_set_super(struct super_block *s, struct fs_context *fc) 1049 2468 { 1050 - struct nfs_sb_mountdata *sb_mntdata = data; 1051 - struct nfs_server *server = sb_mntdata->server; 2469 + struct nfs_server *server = fc->s_fs_info; 1052 2470 int ret; 1053 2471 1054 - s->s_flags = sb_mntdata->mntflags; 1055 - s->s_fs_info = server; 1056 2472 s->s_d_op = server->nfs_client->rpc_ops->dentry_ops; 1057 2473 ret = set_anon_super(s, server); 1058 2474 if (ret == 0) ··· 1109 2541 return 1; 1110 2542 } 1111 2543 1112 - static int nfs_compare_super(struct super_block *sb, void *data) 2544 + static int nfs_compare_super(struct super_block *sb, struct fs_context *fc) 1113 2545 { 1114 - struct nfs_sb_mountdata *sb_mntdata = data; 1115 - struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb); 1116 - int mntflags = sb_mntdata->mntflags; 2546 + struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb); 1117 2547 1118 2548 if (!nfs_compare_super_address(old, server)) 1119 2549 return 0; ··· 1122 2556 return 0; 1123 2557 if (!nfs_compare_userns(old, server)) 1124 2558 return 0; 1125 - return nfs_compare_mount_options(sb, server, mntflags); 2559 + return nfs_compare_mount_options(sb, server, fc); 1126 2560 } 1127 2561 1128 2562 #ifdef CONFIG_NFS_FSCACHE 1129 2563 static void nfs_get_cache_cookie(struct super_block *sb, 1130 - struct nfs_parsed_mount_data *parsed, 1131 - struct nfs_clone_mount *cloned) 2564 + struct nfs_fs_context *ctx) 1132 2565 { 1133 2566 struct nfs_server *nfss = NFS_SB(sb); 1134 2567 char *uniq = NULL; ··· 1136 2571 nfss->fscache_key = NULL; 1137 2572 nfss->fscache = NULL; 1138 2573 1139 - if (parsed) { 1140 - if (!(parsed->options & NFS_OPTION_FSCACHE)) 1141 - return; 1142 - if (parsed->fscache_uniq) { 1143 - uniq = parsed->fscache_uniq; 1144 - ulen = strlen(parsed->fscache_uniq); 1145 - } 1146 - } else if (cloned) { 1147 - struct nfs_server *mnt_s = NFS_SB(cloned->sb); 2574 + if (!ctx) 2575 + return; 2576 + 2577 + if (ctx->clone_data.sb) { 2578 + struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb); 1148 2579 if (!(mnt_s->options & NFS_OPTION_FSCACHE)) 1149 2580 return; 1150 2581 if (mnt_s->fscache_key) { 1151 2582 uniq = mnt_s->fscache_key->key.uniquifier; 1152 2583 ulen = mnt_s->fscache_key->key.uniq_len; 1153 2584 } 1154 - } else 2585 + } else { 2586 + if (!(ctx->options & NFS_OPTION_FSCACHE)) 2587 + return; 2588 + if (ctx->fscache_uniq) { 2589 + uniq = ctx->fscache_uniq; 2590 + ulen = strlen(ctx->fscache_uniq); 2591 + } 1155 2592 return; 2593 + } 1156 2594 1157 2595 nfs_fscache_get_super_cookie(sb, uniq, ulen); 1158 2596 } 1159 2597 #else 1160 2598 static void nfs_get_cache_cookie(struct super_block *sb, 1161 - struct nfs_parsed_mount_data *parsed, 1162 - struct nfs_clone_mount *cloned) 2599 + struct nfs_fs_context *ctx) 1163 2600 { 1164 2601 } 1165 2602 #endif 1166 - 1167 - int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot, 1168 - struct nfs_mount_info *mount_info) 1169 - { 1170 - int error; 1171 - unsigned long kflags = 0, kflags_out = 0; 1172 - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) 1173 - kflags |= SECURITY_LSM_NATIVE_LABELS; 1174 - 1175 - error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts, 1176 - kflags, &kflags_out); 1177 - if (error) 1178 - goto err; 1179 - 1180 - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && 1181 - !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) 1182 - NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; 1183 - err: 1184 - return error; 1185 - } 1186 - EXPORT_SYMBOL_GPL(nfs_set_sb_security); 1187 - 1188 - int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, 1189 - struct nfs_mount_info *mount_info) 1190 - { 1191 - int error; 1192 - unsigned long kflags = 0, kflags_out = 0; 1193 - 1194 - /* clone any lsm security options from the parent to the new sb */ 1195 - if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) 1196 - return -ESTALE; 1197 - 1198 - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) 1199 - kflags |= SECURITY_LSM_NATIVE_LABELS; 1200 - 1201 - error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags, 1202 - &kflags_out); 1203 - if (error) 1204 - return error; 1205 - 1206 - if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && 1207 - !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) 1208 - NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; 1209 - return 0; 1210 - } 1211 - EXPORT_SYMBOL_GPL(nfs_clone_sb_security); 1212 2603 1213 2604 static void nfs_set_readahead(struct backing_dev_info *bdi, 1214 2605 unsigned long iomax_pages) ··· 1173 2652 bdi->io_pages = iomax_pages; 1174 2653 } 1175 2654 1176 - struct dentry *nfs_fs_mount_common(struct nfs_server *server, 1177 - int flags, const char *dev_name, 1178 - struct nfs_mount_info *mount_info, 1179 - struct nfs_subversion *nfs_mod) 2655 + int nfs_get_tree_common(struct fs_context *fc) 1180 2656 { 2657 + struct nfs_fs_context *ctx = nfs_fc2context(fc); 1181 2658 struct super_block *s; 1182 - struct dentry *mntroot = ERR_PTR(-ENOMEM); 1183 - int (*compare_super)(struct super_block *, void *) = nfs_compare_super; 1184 - struct nfs_sb_mountdata sb_mntdata = { 1185 - .mntflags = flags, 1186 - .server = server, 1187 - }; 2659 + int (*compare_super)(struct super_block *, struct fs_context *) = nfs_compare_super; 2660 + struct nfs_server *server = ctx->server; 2661 + unsigned long kflags = 0, kflags_out = 0; 1188 2662 int error; 2663 + 2664 + ctx->server = NULL; 2665 + if (IS_ERR(server)) 2666 + return PTR_ERR(server); 1189 2667 1190 2668 if (server->flags & NFS_MOUNT_UNSHARED) 1191 2669 compare_super = NULL; 1192 2670 1193 2671 /* -o noac implies -o sync */ 1194 2672 if (server->flags & NFS_MOUNT_NOAC) 1195 - sb_mntdata.mntflags |= SB_SYNCHRONOUS; 2673 + fc->sb_flags |= SB_SYNCHRONOUS; 1196 2674 1197 - if (mount_info->cloned != NULL && mount_info->cloned->sb != NULL) 1198 - if (mount_info->cloned->sb->s_flags & SB_SYNCHRONOUS) 1199 - sb_mntdata.mntflags |= SB_SYNCHRONOUS; 2675 + if (ctx->clone_data.sb) 2676 + if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS) 2677 + fc->sb_flags |= SB_SYNCHRONOUS; 2678 + 2679 + if (server->caps & NFS_CAP_SECURITY_LABEL) 2680 + fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS; 1200 2681 1201 2682 /* Get a superblock - note that we may end up sharing one that already exists */ 1202 - s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); 2683 + fc->s_fs_info = server; 2684 + s = sget_fc(fc, compare_super, nfs_set_super); 2685 + fc->s_fs_info = NULL; 1203 2686 if (IS_ERR(s)) { 1204 - mntroot = ERR_CAST(s); 2687 + error = PTR_ERR(s); 2688 + nfs_errorf(fc, "NFS: Couldn't get superblock"); 1205 2689 goto out_err_nosb; 1206 2690 } 1207 2691 ··· 1216 2690 } else { 1217 2691 error = super_setup_bdi_name(s, "%u:%u", MAJOR(server->s_dev), 1218 2692 MINOR(server->s_dev)); 1219 - if (error) { 1220 - mntroot = ERR_PTR(error); 2693 + if (error) 1221 2694 goto error_splat_super; 1222 - } 1223 2695 nfs_set_readahead(s->s_bdi, server->rpages); 1224 2696 server->super = s; 1225 2697 } 1226 2698 1227 2699 if (!s->s_root) { 2700 + unsigned bsize = ctx->clone_data.inherited_bsize; 1228 2701 /* initial superblock/root creation */ 1229 - mount_info->fill_super(s, mount_info); 1230 - nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned); 1231 - if (!(server->flags & NFS_MOUNT_UNSHARED)) 1232 - s->s_iflags |= SB_I_MULTIROOT; 2702 + nfs_fill_super(s, ctx); 2703 + if (bsize) { 2704 + s->s_blocksize_bits = bsize; 2705 + s->s_blocksize = 1U << bsize; 2706 + } 2707 + nfs_get_cache_cookie(s, ctx); 1233 2708 } 1234 2709 1235 - mntroot = nfs_get_root(s, mount_info->mntfh, dev_name); 1236 - if (IS_ERR(mntroot)) 2710 + error = nfs_get_root(s, fc); 2711 + if (error < 0) { 2712 + nfs_errorf(fc, "NFS: Couldn't get root dentry"); 1237 2713 goto error_splat_super; 2714 + } 1238 2715 1239 - error = mount_info->set_security(s, mntroot, mount_info); 2716 + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) 2717 + kflags |= SECURITY_LSM_NATIVE_LABELS; 2718 + if (ctx->clone_data.sb) { 2719 + if (d_inode(fc->root)->i_fop != &nfs_dir_operations) { 2720 + error = -ESTALE; 2721 + goto error_splat_root; 2722 + } 2723 + /* clone any lsm security options from the parent to the new sb */ 2724 + error = security_sb_clone_mnt_opts(ctx->clone_data.sb, s, kflags, 2725 + &kflags_out); 2726 + } else { 2727 + error = security_sb_set_mnt_opts(s, fc->security, 2728 + kflags, &kflags_out); 2729 + } 1240 2730 if (error) 1241 2731 goto error_splat_root; 2732 + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && 2733 + !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) 2734 + NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; 1242 2735 1243 2736 s->s_flags |= SB_ACTIVE; 2737 + error = 0; 1244 2738 1245 2739 out: 1246 - return mntroot; 2740 + return error; 1247 2741 1248 2742 out_err_nosb: 1249 2743 nfs_free_server(server); 1250 2744 goto out; 1251 2745 1252 2746 error_splat_root: 1253 - dput(mntroot); 1254 - mntroot = ERR_PTR(error); 2747 + dput(fc->root); 2748 + fc->root = NULL; 1255 2749 error_splat_super: 1256 2750 deactivate_locked_super(s); 1257 2751 goto out; 1258 2752 } 1259 - EXPORT_SYMBOL_GPL(nfs_fs_mount_common); 1260 - 1261 - struct dentry *nfs_fs_mount(struct file_system_type *fs_type, 1262 - int flags, const char *dev_name, void *raw_data) 1263 - { 1264 - struct nfs_mount_info mount_info = { 1265 - .fill_super = nfs_fill_super, 1266 - .set_security = nfs_set_sb_security, 1267 - }; 1268 - struct dentry *mntroot = ERR_PTR(-ENOMEM); 1269 - struct nfs_subversion *nfs_mod; 1270 - int error; 1271 - 1272 - mount_info.parsed = nfs_alloc_parsed_mount_data(); 1273 - mount_info.mntfh = nfs_alloc_fhandle(); 1274 - if (mount_info.parsed == NULL || mount_info.mntfh == NULL) 1275 - goto out; 1276 - 1277 - /* Validate the mount data */ 1278 - error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mount_info.mntfh, dev_name); 1279 - if (error == NFS_TEXT_DATA) 1280 - error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name); 1281 - if (error < 0) { 1282 - mntroot = ERR_PTR(error); 1283 - goto out; 1284 - } 1285 - 1286 - nfs_mod = get_nfs_version(mount_info.parsed->version); 1287 - if (IS_ERR(nfs_mod)) { 1288 - mntroot = ERR_CAST(nfs_mod); 1289 - goto out; 1290 - } 1291 - 1292 - mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod); 1293 - 1294 - put_nfs_version(nfs_mod); 1295 - out: 1296 - nfs_free_parsed_mount_data(mount_info.parsed); 1297 - nfs_free_fhandle(mount_info.mntfh); 1298 - return mntroot; 1299 - } 1300 - EXPORT_SYMBOL_GPL(nfs_fs_mount); 1301 2753 1302 2754 /* 1303 2755 * Destroy an NFS2/3 superblock ··· 1294 2790 } 1295 2791 EXPORT_SYMBOL_GPL(nfs_kill_super); 1296 2792 1297 - /* 1298 - * Clone an NFS2/3/4 server record on xdev traversal (FSID-change) 1299 - */ 1300 - static struct dentry * 1301 - nfs_xdev_mount(struct file_system_type *fs_type, int flags, 1302 - const char *dev_name, void *raw_data) 1303 - { 1304 - struct nfs_clone_mount *data = raw_data; 1305 - struct nfs_mount_info mount_info = { 1306 - .fill_super = nfs_clone_super, 1307 - .set_security = nfs_clone_sb_security, 1308 - .cloned = data, 1309 - }; 1310 - struct nfs_server *server; 1311 - struct dentry *mntroot = ERR_PTR(-ENOMEM); 1312 - struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; 1313 - 1314 - dprintk("--> nfs_xdev_mount()\n"); 1315 - 1316 - mount_info.mntfh = mount_info.cloned->fh; 1317 - 1318 - /* create a new volume representation */ 1319 - server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); 1320 - 1321 - if (IS_ERR(server)) 1322 - mntroot = ERR_CAST(server); 1323 - else 1324 - mntroot = nfs_fs_mount_common(server, flags, 1325 - dev_name, &mount_info, nfs_mod); 1326 - 1327 - dprintk("<-- nfs_xdev_mount() = %ld\n", 1328 - IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L); 1329 - return mntroot; 1330 - } 1331 - 1332 2793 #if IS_ENABLED(CONFIG_NFS_V4) 1333 - 1334 - static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) 1335 - { 1336 - args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| 1337 - NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); 1338 - } 1339 - 1340 - /* 1341 - * Validate NFSv4 mount options 1342 - */ 1343 - static int nfs4_validate_mount_data(void *options, 1344 - struct nfs_parsed_mount_data *args, 1345 - const char *dev_name) 1346 - { 1347 - struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 1348 - struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; 1349 - char *c; 1350 - 1351 - if (data == NULL) 1352 - goto out_no_data; 1353 - 1354 - args->version = 4; 1355 - 1356 - switch (data->version) { 1357 - case 1: 1358 - if (data->host_addrlen > sizeof(args->nfs_server.address)) 1359 - goto out_no_address; 1360 - if (data->host_addrlen == 0) 1361 - goto out_no_address; 1362 - args->nfs_server.addrlen = data->host_addrlen; 1363 - if (copy_from_user(sap, data->host_addr, data->host_addrlen)) 1364 - return -EFAULT; 1365 - if (!nfs_verify_server_address(sap)) 1366 - goto out_no_address; 1367 - args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 1368 - 1369 - if (data->auth_flavourlen) { 1370 - rpc_authflavor_t pseudoflavor; 1371 - if (data->auth_flavourlen > 1) 1372 - goto out_inval_auth; 1373 - if (copy_from_user(&pseudoflavor, 1374 - data->auth_flavours, 1375 - sizeof(pseudoflavor))) 1376 - return -EFAULT; 1377 - args->selected_flavor = pseudoflavor; 1378 - } else 1379 - args->selected_flavor = RPC_AUTH_UNIX; 1380 - 1381 - c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 1382 - if (IS_ERR(c)) 1383 - return PTR_ERR(c); 1384 - args->nfs_server.hostname = c; 1385 - 1386 - c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); 1387 - if (IS_ERR(c)) 1388 - return PTR_ERR(c); 1389 - args->nfs_server.export_path = c; 1390 - dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1391 - 1392 - c = strndup_user(data->client_addr.data, 16); 1393 - if (IS_ERR(c)) 1394 - return PTR_ERR(c); 1395 - args->client_address = c; 1396 - 1397 - /* 1398 - * Translate to nfs_parsed_mount_data, which nfs4_fill_super 1399 - * can deal with. 1400 - */ 1401 - 1402 - args->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1403 - args->rsize = data->rsize; 1404 - args->wsize = data->wsize; 1405 - args->timeo = data->timeo; 1406 - args->retrans = data->retrans; 1407 - args->acregmin = data->acregmin; 1408 - args->acregmax = data->acregmax; 1409 - args->acdirmin = data->acdirmin; 1410 - args->acdirmax = data->acdirmax; 1411 - args->nfs_server.protocol = data->proto; 1412 - nfs_validate_transport_protocol(args); 1413 - if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1414 - goto out_invalid_transport_udp; 1415 - 1416 - break; 1417 - default: 1418 - return NFS_TEXT_DATA; 1419 - } 1420 - 1421 - return 0; 1422 - 1423 - out_no_data: 1424 - dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n"); 1425 - return -EINVAL; 1426 - 1427 - out_inval_auth: 1428 - dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n", 1429 - data->auth_flavourlen); 1430 - return -EINVAL; 1431 - 1432 - out_no_address: 1433 - dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 1434 - return -EINVAL; 1435 - 1436 - out_invalid_transport_udp: 1437 - dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1438 - return -EINVAL; 1439 - } 1440 2794 1441 2795 /* 1442 2796 * NFS v4 module parameters need to stay in the
+23 -9
fs/nfs/write.c
··· 243 243 /* A writeback failed: mark the page as bad, and invalidate the page cache */ 244 244 static void nfs_set_pageerror(struct address_space *mapping) 245 245 { 246 + struct inode *inode = mapping->host; 247 + 246 248 nfs_zap_mapping(mapping->host, mapping); 249 + /* Force file size revalidation */ 250 + spin_lock(&inode->i_lock); 251 + NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED | 252 + NFS_INO_REVAL_PAGECACHE | 253 + NFS_INO_INVALID_SIZE; 254 + spin_unlock(&inode->i_lock); 247 255 } 248 256 249 257 static void nfs_mapping_set_error(struct page *page, int error) 250 258 { 259 + struct address_space *mapping = page_file_mapping(page); 260 + 251 261 SetPageError(page); 252 - mapping_set_error(page_file_mapping(page), error); 262 + mapping_set_error(mapping, error); 263 + nfs_set_pageerror(mapping); 253 264 } 254 265 255 266 /* ··· 603 592 604 593 static void nfs_write_error(struct nfs_page *req, int error) 605 594 { 606 - nfs_set_pageerror(page_file_mapping(req->wb_page)); 595 + trace_nfs_write_error(req, error); 607 596 nfs_mapping_set_error(req->wb_page, error); 608 597 nfs_inode_remove_request(req); 609 598 nfs_end_page_writeback(req); ··· 1009 998 nfs_list_remove_request(req); 1010 999 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && 1011 1000 (hdr->good_bytes < bytes)) { 1012 - nfs_set_pageerror(page_file_mapping(req->wb_page)); 1001 + trace_nfs_comp_error(req, hdr->error); 1013 1002 nfs_mapping_set_error(req->wb_page, hdr->error); 1014 1003 goto remove_req; 1015 1004 } ··· 1414 1403 1415 1404 task_setup_data->priority = priority; 1416 1405 rpc_ops->write_setup(hdr, msg, &task_setup_data->rpc_client); 1417 - trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes, 1418 - hdr->args.stable); 1406 + trace_nfs_initiate_write(hdr); 1419 1407 } 1420 1408 1421 1409 /* If a nfs_flush_* function fails, it should remove reqs from @head and ··· 1578 1568 return status; 1579 1569 1580 1570 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); 1581 - trace_nfs_writeback_done(inode, task->tk_status, 1582 - hdr->args.offset, hdr->res.verf); 1571 + trace_nfs_writeback_done(task, hdr); 1583 1572 1584 1573 if (hdr->res.verf->committed < hdr->args.stable && 1585 1574 task->tk_status >= 0) { ··· 1658 1649 */ 1659 1650 argp->stable = NFS_FILE_SYNC; 1660 1651 } 1652 + resp->count = 0; 1653 + resp->verf->committed = 0; 1661 1654 rpc_restart_call_prepare(task); 1662 1655 } 1663 1656 } ··· 1835 1824 1836 1825 /* Call the NFS version-specific code */ 1837 1826 NFS_PROTO(data->inode)->commit_done(task, data); 1838 - trace_nfs_commit_done(data); 1827 + trace_nfs_commit_done(task, data); 1839 1828 } 1840 1829 1841 1830 static void nfs_commit_release_pages(struct nfs_commit_data *data) 1842 1831 { 1832 + const struct nfs_writeverf *verf = data->res.verf; 1843 1833 struct nfs_page *req; 1844 1834 int status = data->task.tk_status; 1845 1835 struct nfs_commit_info cinfo; ··· 1859 1847 (long long)req_offset(req)); 1860 1848 if (status < 0) { 1861 1849 if (req->wb_page) { 1850 + trace_nfs_commit_error(req, status); 1862 1851 nfs_mapping_set_error(req->wb_page, status); 1863 1852 nfs_inode_remove_request(req); 1864 1853 } ··· 1869 1856 1870 1857 /* Okay, COMMIT succeeded, apparently. Check the verifier 1871 1858 * returned by the server against all stored verfs. */ 1872 - if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) { 1859 + if (verf->committed > NFS_UNSTABLE && 1860 + !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier)) { 1873 1861 /* We have a match */ 1874 1862 if (req->wb_page) 1875 1863 nfs_inode_remove_request(req);
+3
include/linux/nfs_fs.h
··· 168 168 struct rw_semaphore rmdir_sem; 169 169 struct mutex commit_mutex; 170 170 171 + /* track last access to cached pages */ 172 + unsigned long page_index; 173 + 171 174 #if IS_ENABLED(CONFIG_NFS_V4) 172 175 struct nfs4_cached_acl *nfs4_acl; 173 176 /* NFSv4 state */
+1
include/linux/nfs_fs_sb.h
··· 152 152 #define NFS_MOUNT_LOCAL_FLOCK 0x100000 153 153 #define NFS_MOUNT_LOCAL_FCNTL 0x200000 154 154 #define NFS_MOUNT_SOFTERR 0x400000 155 + #define NFS_MOUNT_SOFTREVAL 0x800000 155 156 156 157 unsigned int caps; /* server capabilities */ 157 158 unsigned int rsize; /* read size */
+5 -6
include/linux/nfs_xdr.h
··· 1639 1639 struct nfs_mount_info; 1640 1640 struct nfs_client_initdata; 1641 1641 struct nfs_pageio_descriptor; 1642 + struct fs_context; 1642 1643 1643 1644 /* 1644 1645 * RPC procedure vector for NFSv2/NFSv3 demuxing ··· 1654 1653 1655 1654 int (*getroot) (struct nfs_server *, struct nfs_fh *, 1656 1655 struct nfs_fsinfo *); 1657 - struct vfsmount *(*submount) (struct nfs_server *, struct dentry *, 1658 - struct nfs_fh *, struct nfs_fattr *); 1659 - struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *, 1660 - struct nfs_subversion *); 1656 + int (*submount) (struct fs_context *, struct nfs_server *); 1657 + int (*try_get_tree) (struct fs_context *); 1661 1658 int (*getattr) (struct nfs_server *, struct nfs_fh *, 1662 1659 struct nfs_fattr *, struct nfs4_label *, 1663 1660 struct inode *); 1664 1661 int (*setattr) (struct dentry *, struct nfs_fattr *, 1665 1662 struct iattr *); 1666 - int (*lookup) (struct inode *, const struct qstr *, 1663 + int (*lookup) (struct inode *, struct dentry *, 1667 1664 struct nfs_fh *, struct nfs_fattr *, 1668 1665 struct nfs4_label *); 1669 1666 int (*lookupp) (struct inode *, struct nfs_fh *, ··· 1722 1723 struct nfs_client *(*init_client) (struct nfs_client *, 1723 1724 const struct nfs_client_initdata *); 1724 1725 void (*free_client) (struct nfs_client *); 1725 - struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); 1726 + struct nfs_server *(*create_server)(struct fs_context *); 1726 1727 struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, 1727 1728 struct nfs_fattr *, rpc_authflavor_t); 1728 1729 };
-2
include/linux/sunrpc/auth.h
··· 113 113 int (*hash_cred)(struct auth_cred *, unsigned int); 114 114 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); 115 115 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int, gfp_t); 116 - int (*list_pseudoflavors)(rpc_authflavor_t *, int); 117 116 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); 118 117 int (*flavor2info)(rpc_authflavor_t, 119 118 struct rpcsec_gss_info *); ··· 157 158 struct rpcsec_gss_info *); 158 159 int rpcauth_get_gssinfo(rpc_authflavor_t, 159 160 struct rpcsec_gss_info *); 160 - int rpcauth_list_flavors(rpc_authflavor_t *, int); 161 161 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int, gfp_t); 162 162 void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 163 163 struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
-3
include/linux/sunrpc/gss_api.h
··· 150 150 /* Similar, but get by pseudoflavor. */ 151 151 struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); 152 152 153 - /* Fill in an array with a list of supported pseudoflavors */ 154 - int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int); 155 - 156 153 struct gss_api_mech * gss_mech_get(struct gss_api_mech *); 157 154 158 155 /* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
+8 -4
include/trace/events/rpcrdma.h
··· 729 729 730 730 TP_STRUCT__entry( 731 731 __field(const void *, req) 732 + __field(const void *, sc) 732 733 __field(unsigned int, task_id) 733 734 __field(unsigned int, client_id) 734 735 __field(int, num_sge) ··· 744 743 __entry->client_id = rqst->rq_task->tk_client ? 745 744 rqst->rq_task->tk_client->cl_clid : -1; 746 745 __entry->req = req; 746 + __entry->sc = req->rl_sendctx; 747 747 __entry->num_sge = req->rl_wr.num_sge; 748 748 __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; 749 749 __entry->status = status; 750 750 ), 751 751 752 - TP_printk("task:%u@%u req=%p (%d SGE%s) %sstatus=%d", 752 + TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d", 753 753 __entry->task_id, __entry->client_id, 754 - __entry->req, __entry->num_sge, 754 + __entry->req, __entry->sc, __entry->num_sge, 755 755 (__entry->num_sge == 1 ? "" : "s"), 756 756 (__entry->signaled ? "signaled " : ""), 757 757 __entry->status ··· 851 849 852 850 TP_STRUCT__entry( 853 851 __field(const void *, req) 852 + __field(const void *, sc) 854 853 __field(unsigned int, unmap_count) 855 854 __field(unsigned int, status) 856 855 __field(unsigned int, vendor_err) ··· 859 856 860 857 TP_fast_assign( 861 858 __entry->req = sc->sc_req; 859 + __entry->sc = sc; 862 860 __entry->unmap_count = sc->sc_unmap_count; 863 861 __entry->status = wc->status; 864 862 __entry->vendor_err = __entry->status ? wc->vendor_err : 0; 865 863 ), 866 864 867 - TP_printk("req=%p, unmapped %u pages: %s (%u/0x%x)", 868 - __entry->req, __entry->unmap_count, 865 + TP_printk("req=%p sc=%p unmapped=%u: %s (%u/0x%x)", 866 + __entry->req, __entry->sc, __entry->unmap_count, 869 867 rdma_show_wc_status(__entry->status), 870 868 __entry->status, __entry->vendor_err 871 869 )
+1
include/trace/events/sunrpc.h
··· 185 185 DEFINE_RPC_RUNNING_EVENT(begin); 186 186 DEFINE_RPC_RUNNING_EVENT(run_action); 187 187 DEFINE_RPC_RUNNING_EVENT(complete); 188 + DEFINE_RPC_RUNNING_EVENT(signalled); 188 189 DEFINE_RPC_RUNNING_EVENT(end); 189 190 190 191 DECLARE_EVENT_CLASS(rpc_task_queued,
+1 -1
net/sunrpc/addr.c
··· 175 175 return 0; 176 176 177 177 len = (buf + buflen) - delim - 1; 178 - p = kstrndup(delim + 1, len, GFP_KERNEL); 178 + p = kmemdup_nul(delim + 1, len, GFP_KERNEL); 179 179 if (p) { 180 180 u32 scope_id = 0; 181 181 struct net_device *dev;
-49
net/sunrpc/auth.c
··· 221 221 } 222 222 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo); 223 223 224 - /** 225 - * rpcauth_list_flavors - discover registered flavors and pseudoflavors 226 - * @array: array to fill in 227 - * @size: size of "array" 228 - * 229 - * Returns the number of array items filled in, or a negative errno. 230 - * 231 - * The returned array is not sorted by any policy. Callers should not 232 - * rely on the order of the items in the returned array. 233 - */ 234 - int 235 - rpcauth_list_flavors(rpc_authflavor_t *array, int size) 236 - { 237 - const struct rpc_authops *ops; 238 - rpc_authflavor_t flavor, pseudos[4]; 239 - int i, len, result = 0; 240 - 241 - rcu_read_lock(); 242 - for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) { 243 - ops = rcu_dereference(auth_flavors[flavor]); 244 - if (result >= size) { 245 - result = -ENOMEM; 246 - break; 247 - } 248 - 249 - if (ops == NULL) 250 - continue; 251 - if (ops->list_pseudoflavors == NULL) { 252 - array[result++] = ops->au_flavor; 253 - continue; 254 - } 255 - len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos)); 256 - if (len < 0) { 257 - result = len; 258 - break; 259 - } 260 - for (i = 0; i < len; i++) { 261 - if (result >= size) { 262 - result = -ENOMEM; 263 - break; 264 - } 265 - array[result++] = pseudos[i]; 266 - } 267 - } 268 - rcu_read_unlock(); 269 - return result; 270 - } 271 - EXPORT_SYMBOL_GPL(rpcauth_list_flavors); 272 - 273 224 struct rpc_auth * 274 225 rpcauth_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 275 226 {
-1
net/sunrpc/auth_gss/auth_gss.c
··· 2118 2118 .hash_cred = gss_hash_cred, 2119 2119 .lookup_cred = gss_lookup_cred, 2120 2120 .crcreate = gss_create_cred, 2121 - .list_pseudoflavors = gss_mech_list_pseudoflavors, 2122 2121 .info2flavor = gss_mech_info2flavor, 2123 2122 .flavor2info = gss_mech_flavor2info, 2124 2123 };
-29
net/sunrpc/auth_gss/gss_mech_switch.c
··· 220 220 } 221 221 222 222 /** 223 - * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors 224 - * @array_ptr: array to fill in 225 - * @size: size of "array" 226 - * 227 - * Returns the number of array items filled in, or a negative errno. 228 - * 229 - * The returned array is not sorted by any policy. Callers should not 230 - * rely on the order of the items in the returned array. 231 - */ 232 - int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size) 233 - { 234 - struct gss_api_mech *pos = NULL; 235 - int j, i = 0; 236 - 237 - rcu_read_lock(); 238 - list_for_each_entry_rcu(pos, &registered_mechs, gm_list) { 239 - for (j = 0; j < pos->gm_pf_num; j++) { 240 - if (i >= size) { 241 - spin_unlock(&registered_mechs_lock); 242 - return -ENOMEM; 243 - } 244 - array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; 245 - } 246 - } 247 - rcu_read_unlock(); 248 - return i; 249 - } 250 - 251 - /** 252 223 * gss_svc_to_pseudoflavor - map a GSS service number to a pseudoflavor 253 224 * @gm: GSS mechanism handle 254 225 * @qop: GSS quality-of-protection value
+1
net/sunrpc/clnt.c
··· 2130 2130 case -ENETUNREACH: 2131 2131 case -EHOSTUNREACH: 2132 2132 case -EPIPE: 2133 + case -EPROTO: 2133 2134 xprt_conditional_disconnect(task->tk_rqstp->rq_xprt, 2134 2135 task->tk_rqstp->rq_connect_cookie); 2135 2136 if (RPC_IS_SOFTCONN(task))
+3 -1
net/sunrpc/sched.c
··· 846 846 847 847 if (!RPC_IS_ACTIVATED(task)) 848 848 return; 849 + 850 + trace_rpc_task_signalled(task, task->tk_action); 849 851 set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate); 850 852 smp_mb__after_atomic(); 851 853 queue = READ_ONCE(task->tk_waitqueue); ··· 951 949 * clean up after sleeping on some queue, we don't 952 950 * break the loop here, but go around once more. 953 951 */ 954 - dprintk("RPC: %5u got signal\n", task->tk_pid); 952 + trace_rpc_task_signalled(task, task->tk_action); 955 953 set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate); 956 954 task->tk_rpc_status = -ERESTARTSYS; 957 955 rpc_exit(task, -ERESTARTSYS);
+1 -1
net/sunrpc/xdr.c
··· 1079 1079 } 1080 1080 EXPORT_SYMBOL_GPL(xdr_enter_page); 1081 1081 1082 - static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; 1082 + static const struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; 1083 1083 1084 1084 void 1085 1085 xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
+4
net/sunrpc/xprtrdma/backchannel.c
··· 194 194 req = rpcrdma_req_create(r_xprt, size, GFP_KERNEL); 195 195 if (!req) 196 196 return NULL; 197 + if (rpcrdma_req_setup(r_xprt, req)) { 198 + rpcrdma_req_destroy(req); 199 + return NULL; 200 + } 197 201 198 202 xprt->bc_alloc_count++; 199 203 rqst = &req->rl_slot;
+47 -57
net/sunrpc/xprtrdma/frwr_ops.c
··· 51 51 #endif 52 52 53 53 /** 54 - * frwr_is_supported - Check if device supports FRWR 55 - * @device: interface adapter to check 56 - * 57 - * Returns true if device supports FRWR, otherwise false 58 - */ 59 - bool frwr_is_supported(struct ib_device *device) 60 - { 61 - struct ib_device_attr *attrs = &device->attrs; 62 - 63 - if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) 64 - goto out_not_supported; 65 - if (attrs->max_fast_reg_page_list_len == 0) 66 - goto out_not_supported; 67 - return true; 68 - 69 - out_not_supported: 70 - pr_info("rpcrdma: 'frwr' mode is not supported by device %s\n", 71 - device->name); 72 - return false; 73 - } 74 - 75 - /** 76 54 * frwr_release_mr - Destroy one MR 77 55 * @mr: MR allocated by frwr_init_mr 78 56 * ··· 148 170 } 149 171 150 172 /** 151 - * frwr_open - Prepare an endpoint for use with FRWR 152 - * @ia: interface adapter this endpoint will use 153 - * @ep: endpoint to prepare 173 + * frwr_query_device - Prepare a transport for use with FRWR 174 + * @r_xprt: controlling transport instance 175 + * @device: RDMA device to query 154 176 * 155 177 * On success, sets: 156 - * ep->rep_attr.cap.max_send_wr 157 - * ep->rep_attr.cap.max_recv_wr 178 + * ep->rep_attr 158 179 * ep->rep_max_requests 159 - * ia->ri_max_segs 180 + * ia->ri_max_rdma_segs 160 181 * 161 182 * And these FRWR-related fields: 162 183 * ia->ri_max_frwr_depth 163 184 * ia->ri_mrtype 164 185 * 165 - * On failure, a negative errno is returned. 186 + * Return values: 187 + * On success, returns zero. 188 + * %-EINVAL - the device does not support FRWR memory registration 189 + * %-ENOMEM - the device is not sufficiently capable for NFS/RDMA 166 190 */ 167 - int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep) 191 + int frwr_query_device(struct rpcrdma_xprt *r_xprt, 192 + const struct ib_device *device) 168 193 { 169 - struct ib_device_attr *attrs = &ia->ri_id->device->attrs; 194 + const struct ib_device_attr *attrs = &device->attrs; 195 + struct rpcrdma_ia *ia = &r_xprt->rx_ia; 196 + struct rpcrdma_ep *ep = &r_xprt->rx_ep; 170 197 int max_qp_wr, depth, delta; 198 + unsigned int max_sge; 199 + 200 + if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) || 201 + attrs->max_fast_reg_page_list_len == 0) { 202 + pr_err("rpcrdma: 'frwr' mode is not supported by device %s\n", 203 + device->name); 204 + return -EINVAL; 205 + } 206 + 207 + max_sge = min_t(unsigned int, attrs->max_send_sge, 208 + RPCRDMA_MAX_SEND_SGES); 209 + if (max_sge < RPCRDMA_MIN_SEND_SGES) { 210 + pr_err("rpcrdma: HCA provides only %u send SGEs\n", max_sge); 211 + return -ENOMEM; 212 + } 213 + ep->rep_attr.cap.max_send_sge = max_sge; 214 + ep->rep_attr.cap.max_recv_sge = 1; 171 215 172 216 ia->ri_mrtype = IB_MR_TYPE_MEM_REG; 173 217 if (attrs->device_cap_flags & IB_DEVICE_SG_GAPS_REG) ··· 199 199 * capability, but perform optimally when the MRs are not larger 200 200 * than a page. 201 201 */ 202 - if (attrs->max_sge_rd > 1) 202 + if (attrs->max_sge_rd > RPCRDMA_MAX_HDR_SEGS) 203 203 ia->ri_max_frwr_depth = attrs->max_sge_rd; 204 204 else 205 205 ia->ri_max_frwr_depth = attrs->max_fast_reg_page_list_len; 206 206 if (ia->ri_max_frwr_depth > RPCRDMA_MAX_DATA_SEGS) 207 207 ia->ri_max_frwr_depth = RPCRDMA_MAX_DATA_SEGS; 208 - dprintk("RPC: %s: max FR page list depth = %u\n", 209 - __func__, ia->ri_max_frwr_depth); 210 208 211 209 /* Add room for frwr register and invalidate WRs. 212 210 * 1. FRWR reg WR for head ··· 228 230 } while (delta > 0); 229 231 } 230 232 231 - max_qp_wr = ia->ri_id->device->attrs.max_qp_wr; 233 + max_qp_wr = attrs->max_qp_wr; 232 234 max_qp_wr -= RPCRDMA_BACKWARD_WRS; 233 235 max_qp_wr -= 1; 234 236 if (max_qp_wr < RPCRDMA_MIN_SLOT_TABLE) ··· 239 241 if (ep->rep_attr.cap.max_send_wr > max_qp_wr) { 240 242 ep->rep_max_requests = max_qp_wr / depth; 241 243 if (!ep->rep_max_requests) 242 - return -EINVAL; 244 + return -ENOMEM; 243 245 ep->rep_attr.cap.max_send_wr = ep->rep_max_requests * depth; 244 246 } 245 247 ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS; ··· 248 250 ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS; 249 251 ep->rep_attr.cap.max_recv_wr += 1; /* for ib_drain_rq */ 250 252 251 - ia->ri_max_segs = 253 + ia->ri_max_rdma_segs = 252 254 DIV_ROUND_UP(RPCRDMA_MAX_DATA_SEGS, ia->ri_max_frwr_depth); 253 255 /* Reply chunks require segments for head and tail buffers */ 254 - ia->ri_max_segs += 2; 255 - if (ia->ri_max_segs > RPCRDMA_MAX_HDR_SEGS) 256 - ia->ri_max_segs = RPCRDMA_MAX_HDR_SEGS; 256 + ia->ri_max_rdma_segs += 2; 257 + if (ia->ri_max_rdma_segs > RPCRDMA_MAX_HDR_SEGS) 258 + ia->ri_max_rdma_segs = RPCRDMA_MAX_HDR_SEGS; 259 + 260 + /* Ensure the underlying device is capable of conveying the 261 + * largest r/wsize NFS will ask for. This guarantees that 262 + * failing over from one RDMA device to another will not 263 + * break NFS I/O. 264 + */ 265 + if ((ia->ri_max_rdma_segs * ia->ri_max_frwr_depth) < RPCRDMA_MAX_SEGS) 266 + return -ENOMEM; 267 + 257 268 return 0; 258 - } 259 - 260 - /** 261 - * frwr_maxpages - Compute size of largest payload 262 - * @r_xprt: transport 263 - * 264 - * Returns maximum size of an RPC message, in pages. 265 - * 266 - * FRWR mode conveys a list of pages per chunk segment. The 267 - * maximum length of that list is the FRWR page list depth. 268 - */ 269 - size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt) 270 - { 271 - struct rpcrdma_ia *ia = &r_xprt->rx_ia; 272 - 273 - return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS, 274 - (ia->ri_max_segs - 2) * ia->ri_max_frwr_depth); 275 269 } 276 270 277 271 /**
+8 -12
net/sunrpc/xprtrdma/rpc_rdma.c
··· 111 111 */ 112 112 void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *r_xprt) 113 113 { 114 - unsigned int maxsegs = r_xprt->rx_ia.ri_max_segs; 114 + unsigned int maxsegs = r_xprt->rx_ia.ri_max_rdma_segs; 115 115 struct rpcrdma_ep *ep = &r_xprt->rx_ep; 116 116 117 117 ep->rep_max_inline_send = ··· 145 145 remaining -= min_t(unsigned int, 146 146 PAGE_SIZE - offset, remaining); 147 147 offset = 0; 148 - if (++count > r_xprt->rx_ia.ri_max_send_sges) 148 + if (++count > r_xprt->rx_ep.rep_attr.cap.max_send_sge) 149 149 return false; 150 150 } 151 151 } ··· 580 580 581 581 /* Prepare an SGE for the RPC-over-RDMA transport header. 582 582 */ 583 - static bool rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt, 583 + static void rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt, 584 584 struct rpcrdma_req *req, u32 len) 585 585 { 586 586 struct rpcrdma_sendctx *sc = req->rl_sendctx; 587 587 struct rpcrdma_regbuf *rb = req->rl_rdmabuf; 588 588 struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++]; 589 589 590 - if (!rpcrdma_regbuf_dma_map(r_xprt, rb)) 591 - return false; 592 590 sge->addr = rdmab_addr(rb); 593 591 sge->length = len; 594 592 sge->lkey = rdmab_lkey(rb); 595 593 596 594 ib_dma_sync_single_for_device(rdmab_device(rb), sge->addr, sge->length, 597 595 DMA_TO_DEVICE); 598 - return true; 599 596 } 600 597 601 598 /* The head iovec is straightforward, as it is usually already ··· 833 836 req->rl_wr.num_sge = 0; 834 837 req->rl_wr.opcode = IB_WR_SEND; 835 838 836 - ret = -EIO; 837 - if (!rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen)) 838 - goto out_unmap; 839 + rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen); 839 840 841 + ret = -EIO; 840 842 switch (rtype) { 841 843 case rpcrdma_noch_pullup: 842 844 if (!rpcrdma_prepare_noch_pullup(r_xprt, req, xdr)) ··· 905 909 goto out_err; 906 910 *p++ = rqst->rq_xid; 907 911 *p++ = rpcrdma_version; 908 - *p++ = cpu_to_be32(r_xprt->rx_buf.rb_max_requests); 912 + *p++ = r_xprt->rx_buf.rb_max_requests; 909 913 910 914 /* When the ULP employs a GSS flavor that guarantees integrity 911 915 * or privacy, direct data placement of individual data items ··· 1476 1480 1477 1481 if (credits == 0) 1478 1482 credits = 1; /* don't deadlock */ 1479 - else if (credits > buf->rb_max_requests) 1480 - credits = buf->rb_max_requests; 1483 + else if (credits > r_xprt->rx_ep.rep_max_requests) 1484 + credits = r_xprt->rx_ep.rep_max_requests; 1481 1485 if (buf->rb_credits != credits) 1482 1486 rpcrdma_update_cwnd(r_xprt, credits); 1483 1487 rpcrdma_post_recvs(r_xprt, false);
+6 -11
net/sunrpc/xprtrdma/transport.c
··· 316 316 if (args->addrlen > sizeof(xprt->addr)) 317 317 return ERR_PTR(-EBADF); 318 318 319 - xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 0, 0); 319 + xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 0, 320 + xprt_rdma_slot_table_entries); 320 321 if (!xprt) 321 322 return ERR_PTR(-ENOMEM); 322 323 ··· 359 358 if (rc) 360 359 goto out3; 361 360 362 - INIT_DELAYED_WORK(&new_xprt->rx_connect_worker, 363 - xprt_rdma_connect_worker); 364 - 365 - xprt->max_payload = frwr_maxpages(new_xprt); 366 - if (xprt->max_payload == 0) 367 - goto out4; 368 - xprt->max_payload <<= PAGE_SHIFT; 369 - dprintk("RPC: %s: transport data payload maximum: %zu bytes\n", 370 - __func__, xprt->max_payload); 371 - 372 361 if (!try_module_get(THIS_MODULE)) 373 362 goto out4; 363 + 364 + INIT_DELAYED_WORK(&new_xprt->rx_connect_worker, 365 + xprt_rdma_connect_worker); 366 + xprt->max_payload = RPCRDMA_MAX_DATA_SEGS << PAGE_SHIFT; 374 367 375 368 dprintk("RPC: %s: %s:%s\n", __func__, 376 369 xprt->address_strings[RPC_DISPLAY_ADDR],
+123 -92
net/sunrpc/xprtrdma/verbs.c
··· 74 74 /* 75 75 * internal functions 76 76 */ 77 + static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt); 78 + static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt); 77 79 static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt, 78 80 struct rpcrdma_sendctx *sc); 81 + static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt); 79 82 static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt); 83 + static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep); 80 84 static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt); 81 85 static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt); 82 86 static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt); ··· 178 174 return; 179 175 180 176 out_flushed: 181 - rpcrdma_recv_buffer_put(rep); 177 + rpcrdma_rep_destroy(rep); 182 178 } 183 179 184 180 static void rpcrdma_update_cm_private(struct rpcrdma_xprt *r_xprt, ··· 370 366 goto out_err; 371 367 } 372 368 373 - switch (xprt_rdma_memreg_strategy) { 374 - case RPCRDMA_FRWR: 375 - if (frwr_is_supported(ia->ri_id->device)) 376 - break; 377 - /*FALLTHROUGH*/ 378 - default: 379 - pr_err("rpcrdma: Device %s does not support memreg mode %d\n", 380 - ia->ri_id->device->name, xprt_rdma_memreg_strategy); 381 - rc = -EINVAL; 382 - goto out_err; 383 - } 384 - 385 369 return 0; 386 370 387 371 out_err: ··· 383 391 * 384 392 * Divest transport H/W resources associated with this adapter, 385 393 * but allow it to be restored later. 394 + * 395 + * Caller must hold the transport send lock. 386 396 */ 387 397 void 388 398 rpcrdma_ia_remove(struct rpcrdma_ia *ia) ··· 392 398 struct rpcrdma_xprt *r_xprt = container_of(ia, struct rpcrdma_xprt, 393 399 rx_ia); 394 400 struct rpcrdma_ep *ep = &r_xprt->rx_ep; 395 - struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 396 - struct rpcrdma_req *req; 397 401 398 402 /* This is similar to rpcrdma_ep_destroy, but: 399 403 * - Don't cancel the connect worker. ··· 414 422 * mappings and MRs are gone. 415 423 */ 416 424 rpcrdma_reps_unmap(r_xprt); 417 - list_for_each_entry(req, &buf->rb_allreqs, rl_all) { 418 - rpcrdma_regbuf_dma_unmap(req->rl_rdmabuf); 419 - rpcrdma_regbuf_dma_unmap(req->rl_sendbuf); 420 - rpcrdma_regbuf_dma_unmap(req->rl_recvbuf); 421 - } 425 + rpcrdma_reqs_reset(r_xprt); 422 426 rpcrdma_mrs_destroy(r_xprt); 427 + rpcrdma_sendctxs_destroy(r_xprt); 423 428 ib_dealloc_pd(ia->ri_pd); 424 429 ia->ri_pd = NULL; 425 430 ··· 459 470 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 460 471 struct rpcrdma_connect_private *pmsg = &ep->rep_cm_private; 461 472 struct ib_cq *sendcq, *recvcq; 462 - unsigned int max_sge; 463 473 int rc; 464 474 465 - ep->rep_max_requests = xprt_rdma_slot_table_entries; 475 + ep->rep_max_requests = r_xprt->rx_xprt.max_reqs; 466 476 ep->rep_inline_send = xprt_rdma_max_inline_write; 467 477 ep->rep_inline_recv = xprt_rdma_max_inline_read; 468 478 469 - max_sge = min_t(unsigned int, ia->ri_id->device->attrs.max_send_sge, 470 - RPCRDMA_MAX_SEND_SGES); 471 - if (max_sge < RPCRDMA_MIN_SEND_SGES) { 472 - pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); 473 - return -ENOMEM; 474 - } 475 - ia->ri_max_send_sges = max_sge; 476 - 477 - rc = frwr_open(ia, ep); 479 + rc = frwr_query_device(r_xprt, ia->ri_id->device); 478 480 if (rc) 479 481 return rc; 482 + r_xprt->rx_buf.rb_max_requests = cpu_to_be32(ep->rep_max_requests); 480 483 481 484 ep->rep_attr.event_handler = rpcrdma_qp_event_handler; 482 485 ep->rep_attr.qp_context = ep; 483 486 ep->rep_attr.srq = NULL; 484 - ep->rep_attr.cap.max_send_sge = max_sge; 485 - ep->rep_attr.cap.max_recv_sge = 1; 486 487 ep->rep_attr.cap.max_inline_data = 0; 487 488 ep->rep_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 488 489 ep->rep_attr.qp_type = IB_QPT_RC; ··· 695 716 rpcrdma_reset_cwnd(r_xprt); 696 717 rpcrdma_post_recvs(r_xprt, true); 697 718 719 + rc = rpcrdma_sendctxs_create(r_xprt); 720 + if (rc) 721 + goto out; 722 + 698 723 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma); 699 724 if (rc) 700 725 goto out; ··· 713 730 goto out; 714 731 } 715 732 733 + rc = rpcrdma_reqs_setup(r_xprt); 734 + if (rc) { 735 + rpcrdma_ep_disconnect(ep, ia); 736 + goto out; 737 + } 716 738 rpcrdma_mrs_create(r_xprt); 717 739 718 740 out: ··· 756 768 rpcrdma_xprt_drain(r_xprt); 757 769 rpcrdma_reqs_reset(r_xprt); 758 770 rpcrdma_mrs_destroy(r_xprt); 771 + rpcrdma_sendctxs_destroy(r_xprt); 759 772 } 760 773 761 774 /* Fixed-size circular FIFO queue. This implementation is wait-free and ··· 776 787 * queue activity, and rpcrdma_xprt_drain has flushed all remaining 777 788 * Send requests. 778 789 */ 779 - static void rpcrdma_sendctxs_destroy(struct rpcrdma_buffer *buf) 790 + static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt) 780 791 { 792 + struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 781 793 unsigned long i; 782 794 795 + if (!buf->rb_sc_ctxs) 796 + return; 783 797 for (i = 0; i <= buf->rb_sc_last; i++) 784 798 kfree(buf->rb_sc_ctxs[i]); 785 799 kfree(buf->rb_sc_ctxs); 800 + buf->rb_sc_ctxs = NULL; 786 801 } 787 802 788 - static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ia *ia) 803 + static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ep *ep) 789 804 { 790 805 struct rpcrdma_sendctx *sc; 791 806 792 - sc = kzalloc(struct_size(sc, sc_sges, ia->ri_max_send_sges), 807 + sc = kzalloc(struct_size(sc, sc_sges, ep->rep_attr.cap.max_send_sge), 793 808 GFP_KERNEL); 794 809 if (!sc) 795 810 return NULL; ··· 813 820 * the ->send_request call to fail temporarily before too many 814 821 * Sends are posted. 815 822 */ 816 - i = buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; 817 - dprintk("RPC: %s: allocating %lu send_ctxs\n", __func__, i); 823 + i = r_xprt->rx_ep.rep_max_requests + RPCRDMA_MAX_BC_REQUESTS; 818 824 buf->rb_sc_ctxs = kcalloc(i, sizeof(sc), GFP_KERNEL); 819 825 if (!buf->rb_sc_ctxs) 820 826 return -ENOMEM; 821 827 822 828 buf->rb_sc_last = i - 1; 823 829 for (i = 0; i <= buf->rb_sc_last; i++) { 824 - sc = rpcrdma_sendctx_create(&r_xprt->rx_ia); 830 + sc = rpcrdma_sendctx_create(&r_xprt->rx_ep); 825 831 if (!sc) 826 832 return -ENOMEM; 827 833 828 834 buf->rb_sc_ctxs[i] = sc; 829 835 } 830 836 837 + buf->rb_sc_head = 0; 838 + buf->rb_sc_tail = 0; 831 839 return 0; 832 840 } 833 841 ··· 927 933 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 928 934 unsigned int count; 929 935 930 - for (count = 0; count < ia->ri_max_segs; count++) { 936 + for (count = 0; count < ia->ri_max_rdma_segs; count++) { 931 937 struct rpcrdma_mr *mr; 932 938 int rc; 933 939 ··· 999 1005 gfp_t flags) 1000 1006 { 1001 1007 struct rpcrdma_buffer *buffer = &r_xprt->rx_buf; 1002 - struct rpcrdma_regbuf *rb; 1003 1008 struct rpcrdma_req *req; 1004 - size_t maxhdrsize; 1005 1009 1006 1010 req = kzalloc(sizeof(*req), flags); 1007 1011 if (req == NULL) 1008 1012 goto out1; 1009 1013 1010 - /* Compute maximum header buffer size in bytes */ 1011 - maxhdrsize = rpcrdma_fixed_maxsz + 3 + 1012 - r_xprt->rx_ia.ri_max_segs * rpcrdma_readchunk_maxsz; 1013 - maxhdrsize *= sizeof(__be32); 1014 - rb = rpcrdma_regbuf_alloc(__roundup_pow_of_two(maxhdrsize), 1015 - DMA_TO_DEVICE, flags); 1016 - if (!rb) 1017 - goto out2; 1018 - req->rl_rdmabuf = rb; 1019 - xdr_buf_init(&req->rl_hdrbuf, rdmab_data(rb), rdmab_length(rb)); 1020 - 1021 1014 req->rl_sendbuf = rpcrdma_regbuf_alloc(size, DMA_TO_DEVICE, flags); 1022 1015 if (!req->rl_sendbuf) 1023 - goto out3; 1016 + goto out2; 1024 1017 1025 1018 req->rl_recvbuf = rpcrdma_regbuf_alloc(size, DMA_NONE, flags); 1026 1019 if (!req->rl_recvbuf) 1027 - goto out4; 1020 + goto out3; 1028 1021 1029 1022 INIT_LIST_HEAD(&req->rl_free_mrs); 1030 1023 INIT_LIST_HEAD(&req->rl_registered); ··· 1020 1039 spin_unlock(&buffer->rb_lock); 1021 1040 return req; 1022 1041 1023 - out4: 1024 - kfree(req->rl_sendbuf); 1025 1042 out3: 1026 - kfree(req->rl_rdmabuf); 1043 + kfree(req->rl_sendbuf); 1027 1044 out2: 1028 1045 kfree(req); 1029 1046 out1: ··· 1029 1050 } 1030 1051 1031 1052 /** 1032 - * rpcrdma_reqs_reset - Reset all reqs owned by a transport 1053 + * rpcrdma_req_setup - Per-connection instance setup of an rpcrdma_req object 1033 1054 * @r_xprt: controlling transport instance 1055 + * @req: rpcrdma_req object to set up 1034 1056 * 1035 - * ASSUMPTION: the rb_allreqs list is stable for the duration, 1057 + * Returns zero on success, and a negative errno on failure. 1058 + */ 1059 + int rpcrdma_req_setup(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) 1060 + { 1061 + struct rpcrdma_regbuf *rb; 1062 + size_t maxhdrsize; 1063 + 1064 + /* Compute maximum header buffer size in bytes */ 1065 + maxhdrsize = rpcrdma_fixed_maxsz + 3 + 1066 + r_xprt->rx_ia.ri_max_rdma_segs * rpcrdma_readchunk_maxsz; 1067 + maxhdrsize *= sizeof(__be32); 1068 + rb = rpcrdma_regbuf_alloc(__roundup_pow_of_two(maxhdrsize), 1069 + DMA_TO_DEVICE, GFP_KERNEL); 1070 + if (!rb) 1071 + goto out; 1072 + 1073 + if (!__rpcrdma_regbuf_dma_map(r_xprt, rb)) 1074 + goto out_free; 1075 + 1076 + req->rl_rdmabuf = rb; 1077 + xdr_buf_init(&req->rl_hdrbuf, rdmab_data(rb), rdmab_length(rb)); 1078 + return 0; 1079 + 1080 + out_free: 1081 + rpcrdma_regbuf_free(rb); 1082 + out: 1083 + return -ENOMEM; 1084 + } 1085 + 1086 + /* ASSUMPTION: the rb_allreqs list is stable for the duration, 1087 + * and thus can be walked without holding rb_lock. Eg. the 1088 + * caller is holding the transport send lock to exclude 1089 + * device removal or disconnection. 1090 + */ 1091 + static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt) 1092 + { 1093 + struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1094 + struct rpcrdma_req *req; 1095 + int rc; 1096 + 1097 + list_for_each_entry(req, &buf->rb_allreqs, rl_all) { 1098 + rc = rpcrdma_req_setup(r_xprt, req); 1099 + if (rc) 1100 + return rc; 1101 + } 1102 + return 0; 1103 + } 1104 + 1105 + static void rpcrdma_req_reset(struct rpcrdma_req *req) 1106 + { 1107 + /* Credits are valid for only one connection */ 1108 + req->rl_slot.rq_cong = 0; 1109 + 1110 + rpcrdma_regbuf_free(req->rl_rdmabuf); 1111 + req->rl_rdmabuf = NULL; 1112 + 1113 + rpcrdma_regbuf_dma_unmap(req->rl_sendbuf); 1114 + rpcrdma_regbuf_dma_unmap(req->rl_recvbuf); 1115 + } 1116 + 1117 + /* ASSUMPTION: the rb_allreqs list is stable for the duration, 1036 1118 * and thus can be walked without holding rb_lock. Eg. the 1037 1119 * caller is holding the transport send lock to exclude 1038 1120 * device removal or disconnection. ··· 1103 1063 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1104 1064 struct rpcrdma_req *req; 1105 1065 1106 - list_for_each_entry(req, &buf->rb_allreqs, rl_all) { 1107 - /* Credits are valid only for one connection */ 1108 - req->rl_slot.rq_cong = 0; 1109 - } 1066 + list_for_each_entry(req, &buf->rb_allreqs, rl_all) 1067 + rpcrdma_req_reset(req); 1110 1068 } 1111 1069 1112 - static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt, 1113 - bool temp) 1070 + /* No locking needed here. This function is called only by the 1071 + * Receive completion handler. 1072 + */ 1073 + static noinline 1074 + struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt, 1075 + bool temp) 1114 1076 { 1115 1077 struct rpcrdma_rep *rep; 1116 1078 ··· 1124 1082 DMA_FROM_DEVICE, GFP_KERNEL); 1125 1083 if (!rep->rr_rdmabuf) 1126 1084 goto out_free; 1085 + 1086 + if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) 1087 + goto out_free_regbuf; 1127 1088 1128 1089 xdr_buf_init(&rep->rr_hdrbuf, rdmab_data(rep->rr_rdmabuf), 1129 1090 rdmab_length(rep->rr_rdmabuf)); ··· 1140 1095 list_add(&rep->rr_all, &r_xprt->rx_buf.rb_all_reps); 1141 1096 return rep; 1142 1097 1098 + out_free_regbuf: 1099 + rpcrdma_regbuf_free(rep->rr_rdmabuf); 1143 1100 out_free: 1144 1101 kfree(rep); 1145 1102 out: 1146 1103 return NULL; 1147 1104 } 1148 1105 1106 + /* No locking needed here. This function is invoked only by the 1107 + * Receive completion handler, or during transport shutdown. 1108 + */ 1149 1109 static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep) 1150 1110 { 1151 1111 list_del(&rep->rr_all); ··· 1180 1130 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1181 1131 struct rpcrdma_rep *rep; 1182 1132 1183 - list_for_each_entry(rep, &buf->rb_all_reps, rr_all) 1133 + list_for_each_entry(rep, &buf->rb_all_reps, rr_all) { 1184 1134 rpcrdma_regbuf_dma_unmap(rep->rr_rdmabuf); 1135 + rep->rr_temp = true; 1136 + } 1185 1137 } 1186 1138 1187 1139 static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf) ··· 1205 1153 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1206 1154 int i, rc; 1207 1155 1208 - buf->rb_max_requests = r_xprt->rx_ep.rep_max_requests; 1209 1156 buf->rb_bc_srv_max_requests = 0; 1210 1157 spin_lock_init(&buf->rb_lock); 1211 1158 INIT_LIST_HEAD(&buf->rb_mrs); ··· 1216 1165 INIT_LIST_HEAD(&buf->rb_all_reps); 1217 1166 1218 1167 rc = -ENOMEM; 1219 - for (i = 0; i < buf->rb_max_requests; i++) { 1168 + for (i = 0; i < r_xprt->rx_xprt.max_reqs; i++) { 1220 1169 struct rpcrdma_req *req; 1221 1170 1222 1171 req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE * 2, ··· 1227 1176 } 1228 1177 1229 1178 init_llist_head(&buf->rb_free_reps); 1230 - 1231 - rc = rpcrdma_sendctxs_create(r_xprt); 1232 - if (rc) 1233 - goto out; 1234 1179 1235 1180 return 0; 1236 1181 out: ··· 1303 1256 void 1304 1257 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) 1305 1258 { 1306 - rpcrdma_sendctxs_destroy(buf); 1307 1259 rpcrdma_reps_destroy(buf); 1308 1260 1309 1261 while (!list_empty(&buf->rb_send_bufs)) { ··· 1543 1497 { 1544 1498 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1545 1499 struct rpcrdma_ep *ep = &r_xprt->rx_ep; 1546 - struct ib_recv_wr *i, *wr, *bad_wr; 1500 + struct ib_recv_wr *wr, *bad_wr; 1547 1501 struct rpcrdma_rep *rep; 1548 1502 int needed, count, rc; 1549 1503 ··· 1570 1524 if (!rep) 1571 1525 break; 1572 1526 1527 + trace_xprtrdma_post_recv(rep); 1573 1528 rep->rr_recv_wr.next = wr; 1574 1529 wr = &rep->rr_recv_wr; 1575 1530 --needed; 1531 + ++count; 1576 1532 } 1577 1533 if (!wr) 1578 1534 goto out; 1579 - 1580 - for (i = wr; i; i = i->next) { 1581 - rep = container_of(i, struct rpcrdma_rep, rr_recv_wr); 1582 - 1583 - if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) 1584 - goto release_wrs; 1585 - 1586 - trace_xprtrdma_post_recv(rep); 1587 - ++count; 1588 - } 1589 1535 1590 1536 rc = ib_post_recv(r_xprt->rx_ia.ri_id->qp, wr, 1591 1537 (const struct ib_recv_wr **)&bad_wr); ··· 1595 1557 } 1596 1558 ep->rep_receive_count += count; 1597 1559 return; 1598 - 1599 - release_wrs: 1600 - for (i = wr; i;) { 1601 - rep = container_of(i, struct rpcrdma_rep, rr_recv_wr); 1602 - i = i->next; 1603 - rpcrdma_recv_buffer_put(rep); 1604 - } 1605 1560 }
+6 -8
net/sunrpc/xprtrdma/xprt_rdma.h
··· 71 71 struct rdma_cm_id *ri_id; 72 72 struct ib_pd *ri_pd; 73 73 int ri_async_rc; 74 - unsigned int ri_max_segs; 74 + unsigned int ri_max_rdma_segs; 75 75 unsigned int ri_max_frwr_depth; 76 - unsigned int ri_max_send_sges; 77 76 bool ri_implicit_roundup; 78 77 enum ib_mr_type ri_mrtype; 79 78 unsigned long ri_flags; ··· 98 99 wait_queue_head_t rep_connect_wait; 99 100 struct rpcrdma_connect_private rep_cm_private; 100 101 struct rdma_conn_param rep_remote_cma; 101 - unsigned int rep_max_requests; /* set by /proc */ 102 + unsigned int rep_max_requests; /* depends on device */ 102 103 unsigned int rep_inline_send; /* negotiated */ 103 104 unsigned int rep_inline_recv; /* negotiated */ 104 105 int rep_receive_count; ··· 372 373 373 374 struct llist_head rb_free_reps; 374 375 375 - u32 rb_max_requests; 376 + __be32 rb_max_requests; 376 377 u32 rb_credits; /* most recent credit grant */ 377 378 378 379 u32 rb_bc_srv_max_requests; ··· 478 479 */ 479 480 struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size, 480 481 gfp_t flags); 482 + int rpcrdma_req_setup(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req); 481 483 void rpcrdma_req_destroy(struct rpcrdma_req *req); 482 484 int rpcrdma_buffer_create(struct rpcrdma_xprt *); 483 485 void rpcrdma_buffer_destroy(struct rpcrdma_buffer *); ··· 535 535 536 536 /* Memory registration calls xprtrdma/frwr_ops.c 537 537 */ 538 - bool frwr_is_supported(struct ib_device *device); 539 538 void frwr_reset(struct rpcrdma_req *req); 540 - int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep); 539 + int frwr_query_device(struct rpcrdma_xprt *r_xprt, 540 + const struct ib_device *device); 541 541 int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr); 542 542 void frwr_release_mr(struct rpcrdma_mr *mr); 543 - size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt); 544 543 struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt, 545 544 struct rpcrdma_mr_seg *seg, 546 545 int nsegs, bool writing, __be32 xid, ··· 582 583 583 584 /* RPC/RDMA module init - xprtrdma/transport.c 584 585 */ 585 - extern unsigned int xprt_rdma_slot_table_entries; 586 586 extern unsigned int xprt_rdma_max_inline_read; 587 587 extern unsigned int xprt_rdma_max_inline_write; 588 588 void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);