| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* client.c: NFS client sharing and management code |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. |
|---|
| 4 | 5 | * Written by David Howells (dhowells@redhat.com) |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | |
|---|
| .. | .. |
|---|
| 53 | 49 | #include "pnfs.h" |
|---|
| 54 | 50 | #include "nfs.h" |
|---|
| 55 | 51 | #include "netns.h" |
|---|
| 52 | +#include "sysfs.h" |
|---|
| 53 | +#include "nfs42.h" |
|---|
| 56 | 54 | |
|---|
| 57 | 55 | #define NFSDBG_FACILITY NFSDBG_CLIENT |
|---|
| 58 | 56 | |
|---|
| .. | .. |
|---|
| 151 | 149 | struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) |
|---|
| 152 | 150 | { |
|---|
| 153 | 151 | struct nfs_client *clp; |
|---|
| 154 | | - struct rpc_cred *cred; |
|---|
| 155 | 152 | int err = -ENOMEM; |
|---|
| 156 | 153 | |
|---|
| 157 | 154 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) |
|---|
| .. | .. |
|---|
| 182 | 179 | |
|---|
| 183 | 180 | clp->cl_flags = cl_init->init_flags; |
|---|
| 184 | 181 | clp->cl_proto = cl_init->proto; |
|---|
| 182 | + clp->cl_nconnect = cl_init->nconnect; |
|---|
| 185 | 183 | clp->cl_net = get_net(cl_init->net); |
|---|
| 186 | 184 | |
|---|
| 187 | | - cred = rpc_lookup_machine_cred("*"); |
|---|
| 188 | | - if (!IS_ERR(cred)) |
|---|
| 189 | | - clp->cl_machine_cred = cred; |
|---|
| 185 | + clp->cl_principal = "*"; |
|---|
| 190 | 186 | nfs_fscache_get_client_cookie(clp); |
|---|
| 191 | 187 | |
|---|
| 192 | 188 | return clp; |
|---|
| .. | .. |
|---|
| 201 | 197 | EXPORT_SYMBOL_GPL(nfs_alloc_client); |
|---|
| 202 | 198 | |
|---|
| 203 | 199 | #if IS_ENABLED(CONFIG_NFS_V4) |
|---|
| 204 | | -void nfs_cleanup_cb_ident_idr(struct net *net) |
|---|
| 200 | +static void nfs_cleanup_cb_ident_idr(struct net *net) |
|---|
| 205 | 201 | { |
|---|
| 206 | 202 | struct nfs_net *nn = net_generic(net, nfs_net_id); |
|---|
| 207 | 203 | |
|---|
| .. | .. |
|---|
| 223 | 219 | } |
|---|
| 224 | 220 | |
|---|
| 225 | 221 | #else |
|---|
| 226 | | -void nfs_cleanup_cb_ident_idr(struct net *net) |
|---|
| 222 | +static void nfs_cleanup_cb_ident_idr(struct net *net) |
|---|
| 227 | 223 | { |
|---|
| 228 | 224 | } |
|---|
| 229 | 225 | |
|---|
| .. | .. |
|---|
| 247 | 243 | /* -EIO all pending I/O */ |
|---|
| 248 | 244 | if (!IS_ERR(clp->cl_rpcclient)) |
|---|
| 249 | 245 | rpc_shutdown_client(clp->cl_rpcclient); |
|---|
| 250 | | - |
|---|
| 251 | | - if (clp->cl_machine_cred != NULL) |
|---|
| 252 | | - put_rpccred(clp->cl_machine_cred); |
|---|
| 253 | 246 | |
|---|
| 254 | 247 | put_net(clp->cl_net); |
|---|
| 255 | 248 | put_nfs_version(clp->cl_nfs_mod); |
|---|
| .. | .. |
|---|
| 322 | 315 | /* Match nfsv4 minorversion */ |
|---|
| 323 | 316 | if (clp->cl_minorversion != data->minorversion) |
|---|
| 324 | 317 | continue; |
|---|
| 318 | + |
|---|
| 319 | + /* Match request for a dedicated DS */ |
|---|
| 320 | + if (test_bit(NFS_CS_DS, &data->init_flags) != |
|---|
| 321 | + test_bit(NFS_CS_DS, &clp->cl_flags)) |
|---|
| 322 | + continue; |
|---|
| 323 | + |
|---|
| 325 | 324 | /* Match the full socket address */ |
|---|
| 326 | 325 | if (!rpc_cmp_addr_port(sap, clap)) |
|---|
| 327 | 326 | /* Match all xprt_switch full socket addresses */ |
|---|
| .. | .. |
|---|
| 477 | 476 | to->to_maxval = to->to_initval; |
|---|
| 478 | 477 | to->to_exponential = 0; |
|---|
| 479 | 478 | break; |
|---|
| 479 | +#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT |
|---|
| 480 | 480 | case XPRT_TRANSPORT_UDP: |
|---|
| 481 | 481 | if (retrans == NFS_UNSPEC_RETRANS) |
|---|
| 482 | 482 | to->to_retries = NFS_DEF_UDP_RETRANS; |
|---|
| .. | .. |
|---|
| 487 | 487 | to->to_maxval = NFS_MAX_UDP_TIMEOUT; |
|---|
| 488 | 488 | to->to_exponential = 1; |
|---|
| 489 | 489 | break; |
|---|
| 490 | +#endif |
|---|
| 490 | 491 | default: |
|---|
| 491 | 492 | BUG(); |
|---|
| 492 | 493 | } |
|---|
| .. | .. |
|---|
| 504 | 505 | struct rpc_create_args args = { |
|---|
| 505 | 506 | .net = clp->cl_net, |
|---|
| 506 | 507 | .protocol = clp->cl_proto, |
|---|
| 508 | + .nconnect = clp->cl_nconnect, |
|---|
| 507 | 509 | .address = (struct sockaddr *)&clp->cl_addr, |
|---|
| 508 | 510 | .addrsize = clp->cl_addrlen, |
|---|
| 509 | 511 | .timeout = cl_init->timeparms, |
|---|
| .. | .. |
|---|
| 512 | 514 | .program = &nfs_program, |
|---|
| 513 | 515 | .version = clp->rpc_ops->version, |
|---|
| 514 | 516 | .authflavor = flavor, |
|---|
| 517 | + .cred = cl_init->cred, |
|---|
| 515 | 518 | }; |
|---|
| 516 | 519 | |
|---|
| 517 | 520 | if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags)) |
|---|
| .. | .. |
|---|
| 522 | 525 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; |
|---|
| 523 | 526 | if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags)) |
|---|
| 524 | 527 | args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS; |
|---|
| 528 | + if (test_bit(NFS_CS_NOPING, &clp->cl_flags)) |
|---|
| 529 | + args.flags |= RPC_CLNT_CREATE_NOPING; |
|---|
| 530 | + if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags)) |
|---|
| 531 | + args.flags |= RPC_CLNT_CREATE_REUSEPORT; |
|---|
| 525 | 532 | |
|---|
| 526 | 533 | if (!IS_ERR(clp->cl_rpcclient)) |
|---|
| 527 | 534 | return 0; |
|---|
| .. | .. |
|---|
| 533 | 540 | return PTR_ERR(clnt); |
|---|
| 534 | 541 | } |
|---|
| 535 | 542 | |
|---|
| 543 | + clnt->cl_principal = clp->cl_principal; |
|---|
| 536 | 544 | clp->cl_rpcclient = clnt; |
|---|
| 537 | 545 | return 0; |
|---|
| 538 | 546 | } |
|---|
| .. | .. |
|---|
| 563 | 571 | 1 : 0, |
|---|
| 564 | 572 | .net = clp->cl_net, |
|---|
| 565 | 573 | .nlmclnt_ops = clp->cl_nfs_mod->rpc_ops->nlmclnt_ops, |
|---|
| 574 | + .cred = current_cred(), |
|---|
| 566 | 575 | }; |
|---|
| 567 | 576 | |
|---|
| 568 | 577 | if (nlm_init.nfs_version > 3) |
|---|
| .. | .. |
|---|
| 575 | 584 | default: |
|---|
| 576 | 585 | nlm_init.protocol = IPPROTO_TCP; |
|---|
| 577 | 586 | break; |
|---|
| 587 | +#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT |
|---|
| 578 | 588 | case XPRT_TRANSPORT_UDP: |
|---|
| 579 | 589 | nlm_init.protocol = IPPROTO_UDP; |
|---|
| 590 | +#endif |
|---|
| 580 | 591 | } |
|---|
| 581 | 592 | |
|---|
| 582 | 593 | host = nlmclnt_init(&nlm_init); |
|---|
| .. | .. |
|---|
| 609 | 620 | sizeof(server->client->cl_timeout_default)); |
|---|
| 610 | 621 | server->client->cl_timeout = &server->client->cl_timeout_default; |
|---|
| 611 | 622 | server->client->cl_softrtry = 0; |
|---|
| 623 | + if (server->flags & NFS_MOUNT_SOFTERR) |
|---|
| 624 | + server->client->cl_softerr = 1; |
|---|
| 612 | 625 | if (server->flags & NFS_MOUNT_SOFT) |
|---|
| 613 | 626 | server->client->cl_softrtry = 1; |
|---|
| 614 | 627 | |
|---|
| .. | .. |
|---|
| 651 | 664 | * Create a version 2 or 3 client |
|---|
| 652 | 665 | */ |
|---|
| 653 | 666 | static int nfs_init_server(struct nfs_server *server, |
|---|
| 654 | | - const struct nfs_parsed_mount_data *data, |
|---|
| 655 | | - struct nfs_subversion *nfs_mod) |
|---|
| 667 | + const struct fs_context *fc) |
|---|
| 656 | 668 | { |
|---|
| 669 | + const struct nfs_fs_context *ctx = nfs_fc2context(fc); |
|---|
| 657 | 670 | struct rpc_timeout timeparms; |
|---|
| 658 | 671 | struct nfs_client_initdata cl_init = { |
|---|
| 659 | | - .hostname = data->nfs_server.hostname, |
|---|
| 660 | | - .addr = (const struct sockaddr *)&data->nfs_server.address, |
|---|
| 661 | | - .addrlen = data->nfs_server.addrlen, |
|---|
| 662 | | - .nfs_mod = nfs_mod, |
|---|
| 663 | | - .proto = data->nfs_server.protocol, |
|---|
| 664 | | - .net = data->net, |
|---|
| 672 | + .hostname = ctx->nfs_server.hostname, |
|---|
| 673 | + .addr = (const struct sockaddr *)&ctx->nfs_server.address, |
|---|
| 674 | + .addrlen = ctx->nfs_server.addrlen, |
|---|
| 675 | + .nfs_mod = ctx->nfs_mod, |
|---|
| 676 | + .proto = ctx->nfs_server.protocol, |
|---|
| 677 | + .net = fc->net_ns, |
|---|
| 665 | 678 | .timeparms = &timeparms, |
|---|
| 679 | + .cred = server->cred, |
|---|
| 680 | + .nconnect = ctx->nfs_server.nconnect, |
|---|
| 681 | + .init_flags = (1UL << NFS_CS_REUSEPORT), |
|---|
| 666 | 682 | }; |
|---|
| 667 | 683 | struct nfs_client *clp; |
|---|
| 668 | 684 | int error; |
|---|
| 669 | 685 | |
|---|
| 670 | | - nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, |
|---|
| 671 | | - data->timeo, data->retrans); |
|---|
| 672 | | - if (data->flags & NFS_MOUNT_NORESVPORT) |
|---|
| 686 | + nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol, |
|---|
| 687 | + ctx->timeo, ctx->retrans); |
|---|
| 688 | + if (ctx->flags & NFS_MOUNT_NORESVPORT) |
|---|
| 673 | 689 | set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); |
|---|
| 674 | 690 | |
|---|
| 675 | 691 | /* Allocate or find a client reference we can use */ |
|---|
| .. | .. |
|---|
| 680 | 696 | server->nfs_client = clp; |
|---|
| 681 | 697 | |
|---|
| 682 | 698 | /* Initialise the client representation from the mount data */ |
|---|
| 683 | | - server->flags = data->flags; |
|---|
| 684 | | - server->options = data->options; |
|---|
| 699 | + server->flags = ctx->flags; |
|---|
| 700 | + server->options = ctx->options; |
|---|
| 685 | 701 | server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| |
|---|
| 686 | 702 | NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP| |
|---|
| 687 | 703 | NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME; |
|---|
| 688 | 704 | |
|---|
| 689 | | - if (data->rsize) |
|---|
| 690 | | - server->rsize = nfs_block_size(data->rsize, NULL); |
|---|
| 691 | | - if (data->wsize) |
|---|
| 692 | | - server->wsize = nfs_block_size(data->wsize, NULL); |
|---|
| 705 | + if (ctx->rsize) |
|---|
| 706 | + server->rsize = nfs_block_size(ctx->rsize, NULL); |
|---|
| 707 | + if (ctx->wsize) |
|---|
| 708 | + server->wsize = nfs_block_size(ctx->wsize, NULL); |
|---|
| 693 | 709 | |
|---|
| 694 | | - server->acregmin = data->acregmin * HZ; |
|---|
| 695 | | - server->acregmax = data->acregmax * HZ; |
|---|
| 696 | | - server->acdirmin = data->acdirmin * HZ; |
|---|
| 697 | | - server->acdirmax = data->acdirmax * HZ; |
|---|
| 710 | + server->acregmin = ctx->acregmin * HZ; |
|---|
| 711 | + server->acregmax = ctx->acregmax * HZ; |
|---|
| 712 | + server->acdirmin = ctx->acdirmin * HZ; |
|---|
| 713 | + server->acdirmax = ctx->acdirmax * HZ; |
|---|
| 698 | 714 | |
|---|
| 699 | 715 | /* Start lockd here, before we might error out */ |
|---|
| 700 | 716 | error = nfs_start_lockd(server); |
|---|
| 701 | 717 | if (error < 0) |
|---|
| 702 | 718 | goto error; |
|---|
| 703 | 719 | |
|---|
| 704 | | - server->port = data->nfs_server.port; |
|---|
| 705 | | - server->auth_info = data->auth_info; |
|---|
| 720 | + server->port = ctx->nfs_server.port; |
|---|
| 721 | + server->auth_info = ctx->auth_info; |
|---|
| 706 | 722 | |
|---|
| 707 | 723 | error = nfs_init_server_rpcclient(server, &timeparms, |
|---|
| 708 | | - data->selected_flavor); |
|---|
| 724 | + ctx->selected_flavor); |
|---|
| 709 | 725 | if (error < 0) |
|---|
| 710 | 726 | goto error; |
|---|
| 711 | 727 | |
|---|
| 712 | 728 | /* Preserve the values of mount_server-related mount options */ |
|---|
| 713 | | - if (data->mount_server.addrlen) { |
|---|
| 714 | | - memcpy(&server->mountd_address, &data->mount_server.address, |
|---|
| 715 | | - data->mount_server.addrlen); |
|---|
| 716 | | - server->mountd_addrlen = data->mount_server.addrlen; |
|---|
| 729 | + if (ctx->mount_server.addrlen) { |
|---|
| 730 | + memcpy(&server->mountd_address, &ctx->mount_server.address, |
|---|
| 731 | + ctx->mount_server.addrlen); |
|---|
| 732 | + server->mountd_addrlen = ctx->mount_server.addrlen; |
|---|
| 717 | 733 | } |
|---|
| 718 | | - server->mountd_version = data->mount_server.version; |
|---|
| 719 | | - server->mountd_port = data->mount_server.port; |
|---|
| 720 | | - server->mountd_protocol = data->mount_server.protocol; |
|---|
| 734 | + server->mountd_version = ctx->mount_server.version; |
|---|
| 735 | + server->mountd_port = ctx->mount_server.port; |
|---|
| 736 | + server->mountd_protocol = ctx->mount_server.protocol; |
|---|
| 721 | 737 | |
|---|
| 722 | | - server->namelen = data->namlen; |
|---|
| 738 | + server->namelen = ctx->namlen; |
|---|
| 723 | 739 | return 0; |
|---|
| 724 | 740 | |
|---|
| 725 | 741 | error: |
|---|
| .. | .. |
|---|
| 734 | 750 | static void nfs_server_set_fsinfo(struct nfs_server *server, |
|---|
| 735 | 751 | struct nfs_fsinfo *fsinfo) |
|---|
| 736 | 752 | { |
|---|
| 737 | | - unsigned long max_rpc_payload; |
|---|
| 753 | + unsigned long max_rpc_payload, raw_max_rpc_payload; |
|---|
| 738 | 754 | |
|---|
| 739 | 755 | /* Work out a lot of parameters */ |
|---|
| 740 | 756 | if (server->rsize == 0) |
|---|
| .. | .. |
|---|
| 747 | 763 | if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax) |
|---|
| 748 | 764 | server->wsize = nfs_block_size(fsinfo->wtmax, NULL); |
|---|
| 749 | 765 | |
|---|
| 750 | | - max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); |
|---|
| 766 | + raw_max_rpc_payload = rpc_max_payload(server->client); |
|---|
| 767 | + max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL); |
|---|
| 768 | + |
|---|
| 751 | 769 | if (server->rsize > max_rpc_payload) |
|---|
| 752 | 770 | server->rsize = max_rpc_payload; |
|---|
| 753 | 771 | if (server->rsize > NFS_MAX_FILE_IO_SIZE) |
|---|
| .. | .. |
|---|
| 780 | 798 | server->clone_blksize = fsinfo->clone_blksize; |
|---|
| 781 | 799 | /* We're airborne Set socket buffersize */ |
|---|
| 782 | 800 | rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); |
|---|
| 801 | + |
|---|
| 802 | +#ifdef CONFIG_NFS_V4_2 |
|---|
| 803 | + /* |
|---|
| 804 | + * Defaults until limited by the session parameters. |
|---|
| 805 | + */ |
|---|
| 806 | + server->gxasize = min_t(unsigned int, raw_max_rpc_payload, |
|---|
| 807 | + XATTR_SIZE_MAX); |
|---|
| 808 | + server->sxasize = min_t(unsigned int, raw_max_rpc_payload, |
|---|
| 809 | + XATTR_SIZE_MAX); |
|---|
| 810 | + server->lxasize = min_t(unsigned int, raw_max_rpc_payload, |
|---|
| 811 | + nfs42_listxattr_xdrsize(XATTR_LIST_MAX)); |
|---|
| 812 | + |
|---|
| 813 | + if (fsinfo->xattr_support) |
|---|
| 814 | + server->caps |= NFS_CAP_XATTR; |
|---|
| 815 | +#endif |
|---|
| 783 | 816 | } |
|---|
| 784 | 817 | |
|---|
| 785 | 818 | /* |
|---|
| .. | .. |
|---|
| 931 | 964 | ida_destroy(&server->lockowner_id); |
|---|
| 932 | 965 | ida_destroy(&server->openowner_id); |
|---|
| 933 | 966 | nfs_free_iostats(server->io_stats); |
|---|
| 967 | + put_cred(server->cred); |
|---|
| 934 | 968 | kfree(server); |
|---|
| 935 | 969 | nfs_release_automount_timer(); |
|---|
| 936 | 970 | } |
|---|
| .. | .. |
|---|
| 940 | 974 | * Create a version 2 or 3 volume record |
|---|
| 941 | 975 | * - keyed on server and FSID |
|---|
| 942 | 976 | */ |
|---|
| 943 | | -struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info, |
|---|
| 944 | | - struct nfs_subversion *nfs_mod) |
|---|
| 977 | +struct nfs_server *nfs_create_server(struct fs_context *fc) |
|---|
| 945 | 978 | { |
|---|
| 979 | + struct nfs_fs_context *ctx = nfs_fc2context(fc); |
|---|
| 946 | 980 | struct nfs_server *server; |
|---|
| 947 | 981 | struct nfs_fattr *fattr; |
|---|
| 948 | 982 | int error; |
|---|
| .. | .. |
|---|
| 951 | 985 | if (!server) |
|---|
| 952 | 986 | return ERR_PTR(-ENOMEM); |
|---|
| 953 | 987 | |
|---|
| 988 | + server->cred = get_cred(current_cred()); |
|---|
| 989 | + |
|---|
| 954 | 990 | error = -ENOMEM; |
|---|
| 955 | 991 | fattr = nfs_alloc_fattr(); |
|---|
| 956 | 992 | if (fattr == NULL) |
|---|
| 957 | 993 | goto error; |
|---|
| 958 | 994 | |
|---|
| 959 | 995 | /* Get a client representation */ |
|---|
| 960 | | - error = nfs_init_server(server, mount_info->parsed, nfs_mod); |
|---|
| 996 | + error = nfs_init_server(server, fc); |
|---|
| 961 | 997 | if (error < 0) |
|---|
| 962 | 998 | goto error; |
|---|
| 963 | 999 | |
|---|
| 964 | 1000 | /* Probe the root fh to retrieve its FSID */ |
|---|
| 965 | | - error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr); |
|---|
| 1001 | + error = nfs_probe_fsinfo(server, ctx->mntfh, fattr); |
|---|
| 966 | 1002 | if (error < 0) |
|---|
| 967 | 1003 | goto error; |
|---|
| 968 | 1004 | if (server->nfs_client->rpc_ops->version == 3) { |
|---|
| 969 | 1005 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) |
|---|
| 970 | 1006 | server->namelen = NFS3_MAXNAMLEN; |
|---|
| 971 | | - if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS)) |
|---|
| 1007 | + if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS)) |
|---|
| 972 | 1008 | server->caps |= NFS_CAP_READDIRPLUS; |
|---|
| 973 | 1009 | } else { |
|---|
| 974 | 1010 | if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) |
|---|
| .. | .. |
|---|
| 976 | 1012 | } |
|---|
| 977 | 1013 | |
|---|
| 978 | 1014 | if (!(fattr->valid & NFS_ATTR_FATTR)) { |
|---|
| 979 | | - error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, |
|---|
| 980 | | - fattr, NULL, NULL); |
|---|
| 1015 | + error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh, |
|---|
| 1016 | + fattr, NULL, NULL); |
|---|
| 981 | 1017 | if (error < 0) { |
|---|
| 982 | 1018 | dprintk("nfs_create_server: getattr error = %d\n", -error); |
|---|
| 983 | 1019 | goto error; |
|---|
| .. | .. |
|---|
| 1016 | 1052 | server = nfs_alloc_server(); |
|---|
| 1017 | 1053 | if (!server) |
|---|
| 1018 | 1054 | return ERR_PTR(-ENOMEM); |
|---|
| 1055 | + |
|---|
| 1056 | + server->cred = get_cred(source->cred); |
|---|
| 1019 | 1057 | |
|---|
| 1020 | 1058 | error = -ENOMEM; |
|---|
| 1021 | 1059 | fattr_fsinfo = nfs_alloc_fattr(); |
|---|
| .. | .. |
|---|
| 1072 | 1110 | #endif |
|---|
| 1073 | 1111 | spin_lock_init(&nn->nfs_client_lock); |
|---|
| 1074 | 1112 | nn->boot_time = ktime_get_real(); |
|---|
| 1113 | + |
|---|
| 1114 | + nfs_netns_sysfs_setup(nn, net); |
|---|
| 1115 | +} |
|---|
| 1116 | + |
|---|
| 1117 | +void nfs_clients_exit(struct net *net) |
|---|
| 1118 | +{ |
|---|
| 1119 | + struct nfs_net *nn = net_generic(net, nfs_net_id); |
|---|
| 1120 | + |
|---|
| 1121 | + nfs_netns_sysfs_destroy(nn); |
|---|
| 1122 | + nfs_cleanup_cb_ident_idr(net); |
|---|
| 1123 | + WARN_ON_ONCE(!list_empty(&nn->nfs_client_list)); |
|---|
| 1124 | + WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list)); |
|---|
| 1075 | 1125 | } |
|---|
| 1076 | 1126 | |
|---|
| 1077 | 1127 | #ifdef CONFIG_PROC_FS |
|---|