linux/fs/nfs/client.c
<<
>>
Prefs
   1/* client.c: NFS client sharing and management code
   2 *
   3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
   4 * 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 */
  11
  12
  13#include <linux/module.h>
  14#include <linux/init.h>
  15#include <linux/sched.h>
  16#include <linux/time.h>
  17#include <linux/kernel.h>
  18#include <linux/mm.h>
  19#include <linux/string.h>
  20#include <linux/stat.h>
  21#include <linux/errno.h>
  22#include <linux/unistd.h>
  23#include <linux/sunrpc/clnt.h>
  24#include <linux/sunrpc/stats.h>
  25#include <linux/sunrpc/metrics.h>
  26#include <linux/sunrpc/xprtsock.h>
  27#include <linux/sunrpc/xprtrdma.h>
  28#include <linux/nfs_fs.h>
  29#include <linux/nfs_mount.h>
  30#include <linux/nfs4_mount.h>
  31#include <linux/lockd/bind.h>
  32#include <linux/seq_file.h>
  33#include <linux/mount.h>
  34#include <linux/nfs_idmap.h>
  35#include <linux/vfs.h>
  36#include <linux/inet.h>
  37#include <linux/in6.h>
  38#include <net/ipv6.h>
  39#include <linux/nfs_xdr.h>
  40#include <linux/sunrpc/bc_xprt.h>
  41
  42#include <asm/system.h>
  43
  44#include "nfs4_fs.h"
  45#include "callback.h"
  46#include "delegation.h"
  47#include "iostat.h"
  48#include "internal.h"
  49#include "fscache.h"
  50
  51#define NFSDBG_FACILITY         NFSDBG_CLIENT
  52
  53static DEFINE_SPINLOCK(nfs_client_lock);
  54static LIST_HEAD(nfs_client_list);
  55static LIST_HEAD(nfs_volume_list);
  56static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
  57
  58/*
  59 * RPC cruft for NFS
  60 */
  61static struct rpc_version *nfs_version[5] = {
  62        [2]                     = &nfs_version2,
  63#ifdef CONFIG_NFS_V3
  64        [3]                     = &nfs_version3,
  65#endif
  66#ifdef CONFIG_NFS_V4
  67        [4]                     = &nfs_version4,
  68#endif
  69};
  70
  71struct rpc_program nfs_program = {
  72        .name                   = "nfs",
  73        .number                 = NFS_PROGRAM,
  74        .nrvers                 = ARRAY_SIZE(nfs_version),
  75        .version                = nfs_version,
  76        .stats                  = &nfs_rpcstat,
  77        .pipe_dir_name          = "/nfs",
  78};
  79
  80struct rpc_stat nfs_rpcstat = {
  81        .program                = &nfs_program
  82};
  83
  84
  85#ifdef CONFIG_NFS_V3_ACL
  86static struct rpc_stat          nfsacl_rpcstat = { &nfsacl_program };
  87static struct rpc_version *     nfsacl_version[] = {
  88        [3]                     = &nfsacl_version3,
  89};
  90
  91struct rpc_program              nfsacl_program = {
  92        .name                   = "nfsacl",
  93        .number                 = NFS_ACL_PROGRAM,
  94        .nrvers                 = ARRAY_SIZE(nfsacl_version),
  95        .version                = nfsacl_version,
  96        .stats                  = &nfsacl_rpcstat,
  97};
  98#endif  /* CONFIG_NFS_V3_ACL */
  99
 100struct nfs_client_initdata {
 101        const char *hostname;
 102        const struct sockaddr *addr;
 103        size_t addrlen;
 104        const struct nfs_rpc_ops *rpc_ops;
 105        int proto;
 106        u32 minorversion;
 107};
 108
 109/*
 110 * Allocate a shared client record
 111 *
 112 * Since these are allocated/deallocated very rarely, we don't
 113 * bother putting them in a slab cache...
 114 */
 115static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 116{
 117        struct nfs_client *clp;
 118        struct rpc_cred *cred;
 119        int err = -ENOMEM;
 120
 121        if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
 122                goto error_0;
 123
 124        clp->rpc_ops = cl_init->rpc_ops;
 125
 126        atomic_set(&clp->cl_count, 1);
 127        clp->cl_cons_state = NFS_CS_INITING;
 128
 129        memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
 130        clp->cl_addrlen = cl_init->addrlen;
 131
 132        if (cl_init->hostname) {
 133                err = -ENOMEM;
 134                clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
 135                if (!clp->cl_hostname)
 136                        goto error_cleanup;
 137        }
 138
 139        INIT_LIST_HEAD(&clp->cl_superblocks);
 140        clp->cl_rpcclient = ERR_PTR(-EINVAL);
 141
 142        clp->cl_proto = cl_init->proto;
 143
 144#ifdef CONFIG_NFS_V4
 145        INIT_LIST_HEAD(&clp->cl_delegations);
 146        spin_lock_init(&clp->cl_lock);
 147        INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
 148        rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
 149        clp->cl_boot_time = CURRENT_TIME;
 150        clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
 151        clp->cl_minorversion = cl_init->minorversion;
 152#endif
 153        cred = rpc_lookup_machine_cred();
 154        if (!IS_ERR(cred))
 155                clp->cl_machine_cred = cred;
 156
 157        nfs_fscache_get_client_cookie(clp);
 158
 159        return clp;
 160
 161error_cleanup:
 162        kfree(clp);
 163error_0:
 164        return ERR_PTR(err);
 165}
 166
 167static void nfs4_shutdown_client(struct nfs_client *clp)
 168{
 169#ifdef CONFIG_NFS_V4
 170        if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
 171                nfs4_kill_renewd(clp);
 172        BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
 173        if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
 174                nfs_idmap_delete(clp);
 175
 176        rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
 177#endif
 178}
 179
 180/*
 181 * Destroy the NFS4 callback service
 182 */
 183static void nfs4_destroy_callback(struct nfs_client *clp)
 184{
 185#ifdef CONFIG_NFS_V4
 186        if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
 187                nfs_callback_down(clp->cl_minorversion);
 188#endif /* CONFIG_NFS_V4 */
 189}
 190
 191/*
 192 * Clears/puts all minor version specific parts from an nfs_client struct
 193 * reverting it to minorversion 0.
 194 */
 195static void nfs4_clear_client_minor_version(struct nfs_client *clp)
 196{
 197#ifdef CONFIG_NFS_V4_1
 198        if (nfs4_has_session(clp)) {
 199                nfs4_destroy_session(clp->cl_session);
 200                clp->cl_session = NULL;
 201        }
 202
 203        clp->cl_call_sync = _nfs4_call_sync;
 204#endif /* CONFIG_NFS_V4_1 */
 205
 206        nfs4_destroy_callback(clp);
 207}
 208
 209/*
 210 * Destroy a shared client record
 211 */
 212static void nfs_free_client(struct nfs_client *clp)
 213{
 214        dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
 215
 216        nfs4_clear_client_minor_version(clp);
 217        nfs4_shutdown_client(clp);
 218
 219        nfs_fscache_release_client_cookie(clp);
 220
 221        /* -EIO all pending I/O */
 222        if (!IS_ERR(clp->cl_rpcclient))
 223                rpc_shutdown_client(clp->cl_rpcclient);
 224
 225        if (clp->cl_machine_cred != NULL)
 226                put_rpccred(clp->cl_machine_cred);
 227
 228        kfree(clp->cl_hostname);
 229        kfree(clp);
 230
 231        dprintk("<-- nfs_free_client()\n");
 232}
 233
 234/*
 235 * Release a reference to a shared client record
 236 */
 237void nfs_put_client(struct nfs_client *clp)
 238{
 239        if (!clp)
 240                return;
 241
 242        dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count));
 243
 244        if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) {
 245                list_del(&clp->cl_share_link);
 246                spin_unlock(&nfs_client_lock);
 247
 248                BUG_ON(!list_empty(&clp->cl_superblocks));
 249
 250                nfs_free_client(clp);
 251        }
 252}
 253
 254#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 255/*
 256 * Test if two ip6 socket addresses refer to the same socket by
 257 * comparing relevant fields. The padding bytes specifically, are not
 258 * compared. sin6_flowinfo is not compared because it only affects QoS
 259 * and sin6_scope_id is only compared if the address is "link local"
 260 * because "link local" addresses need only be unique to a specific
 261 * link. Conversely, ordinary unicast addresses might have different
 262 * sin6_scope_id.
 263 *
 264 * The caller should ensure both socket addresses are AF_INET6.
 265 */
 266static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
 267                                      const struct sockaddr *sa2)
 268{
 269        const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
 270        const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
 271
 272        if (ipv6_addr_scope(&sin1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL &&
 273            sin1->sin6_scope_id != sin2->sin6_scope_id)
 274                return 0;
 275
 276        return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr);
 277}
 278#else   /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
 279static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
 280                                      const struct sockaddr *sa2)
 281{
 282        return 0;
 283}
 284#endif
 285
 286/*
 287 * Test if two ip4 socket addresses refer to the same socket, by
 288 * comparing relevant fields. The padding bytes specifically, are
 289 * not compared.
 290 *
 291 * The caller should ensure both socket addresses are AF_INET.
 292 */
 293static int nfs_sockaddr_match_ipaddr4(const struct sockaddr *sa1,
 294                                      const struct sockaddr *sa2)
 295{
 296        const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
 297        const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
 298
 299        return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
 300}
 301
 302static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1,
 303                                const struct sockaddr *sa2)
 304{
 305        const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
 306        const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
 307
 308        return nfs_sockaddr_match_ipaddr6(sa1, sa2) &&
 309                (sin1->sin6_port == sin2->sin6_port);
 310}
 311
 312static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
 313                                const struct sockaddr *sa2)
 314{
 315        const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
 316        const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
 317
 318        return nfs_sockaddr_match_ipaddr4(sa1, sa2) &&
 319                (sin1->sin_port == sin2->sin_port);
 320}
 321
 322/*
 323 * Test if two socket addresses represent the same actual socket,
 324 * by comparing (only) relevant fields, excluding the port number.
 325 */
 326static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
 327                                     const struct sockaddr *sa2)
 328{
 329        if (sa1->sa_family != sa2->sa_family)
 330                return 0;
 331
 332        switch (sa1->sa_family) {
 333        case AF_INET:
 334                return nfs_sockaddr_match_ipaddr4(sa1, sa2);
 335        case AF_INET6:
 336                return nfs_sockaddr_match_ipaddr6(sa1, sa2);
 337        }
 338        return 0;
 339}
 340
 341/*
 342 * Test if two socket addresses represent the same actual socket,
 343 * by comparing (only) relevant fields, including the port number.
 344 */
 345static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
 346                            const struct sockaddr *sa2)
 347{
 348        if (sa1->sa_family != sa2->sa_family)
 349                return 0;
 350
 351        switch (sa1->sa_family) {
 352        case AF_INET:
 353                return nfs_sockaddr_cmp_ip4(sa1, sa2);
 354        case AF_INET6:
 355                return nfs_sockaddr_cmp_ip6(sa1, sa2);
 356        }
 357        return 0;
 358}
 359
 360/*
 361 * Find a client by IP address and protocol version
 362 * - returns NULL if no such client
 363 */
 364struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
 365{
 366        struct nfs_client *clp;
 367
 368        spin_lock(&nfs_client_lock);
 369        list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
 370                struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
 371
 372                /* Don't match clients that failed to initialise properly */
 373                if (!(clp->cl_cons_state == NFS_CS_READY ||
 374                      clp->cl_cons_state == NFS_CS_SESSION_INITING))
 375                        continue;
 376
 377                /* Different NFS versions cannot share the same nfs_client */
 378                if (clp->rpc_ops->version != nfsversion)
 379                        continue;
 380
 381                /* Match only the IP address, not the port number */
 382                if (!nfs_sockaddr_match_ipaddr(addr, clap))
 383                        continue;
 384
 385                atomic_inc(&clp->cl_count);
 386                spin_unlock(&nfs_client_lock);
 387                return clp;
 388        }
 389        spin_unlock(&nfs_client_lock);
 390        return NULL;
 391}
 392
 393/*
 394 * Find a client by IP address and protocol version
 395 * - returns NULL if no such client
 396 */
 397struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
 398{
 399        struct sockaddr *sap = (struct sockaddr *)&clp->cl_addr;
 400        u32 nfsvers = clp->rpc_ops->version;
 401
 402        spin_lock(&nfs_client_lock);
 403        list_for_each_entry_continue(clp, &nfs_client_list, cl_share_link) {
 404                struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
 405
 406                /* Don't match clients that failed to initialise properly */
 407                if (clp->cl_cons_state != NFS_CS_READY)
 408                        continue;
 409
 410                /* Different NFS versions cannot share the same nfs_client */
 411                if (clp->rpc_ops->version != nfsvers)
 412                        continue;
 413
 414                /* Match only the IP address, not the port number */
 415                if (!nfs_sockaddr_match_ipaddr(sap, clap))
 416                        continue;
 417
 418                atomic_inc(&clp->cl_count);
 419                spin_unlock(&nfs_client_lock);
 420                return clp;
 421        }
 422        spin_unlock(&nfs_client_lock);
 423        return NULL;
 424}
 425
 426/*
 427 * Find an nfs_client on the list that matches the initialisation data
 428 * that is supplied.
 429 */
 430static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
 431{
 432        struct nfs_client *clp;
 433        const struct sockaddr *sap = data->addr;
 434
 435        list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
 436                const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
 437                /* Don't match clients that failed to initialise properly */
 438                if (clp->cl_cons_state < 0)
 439                        continue;
 440
 441                /* Different NFS versions cannot share the same nfs_client */
 442                if (clp->rpc_ops != data->rpc_ops)
 443                        continue;
 444
 445                if (clp->cl_proto != data->proto)
 446                        continue;
 447                /* Match nfsv4 minorversion */
 448                if (clp->cl_minorversion != data->minorversion)
 449                        continue;
 450                /* Match the full socket address */
 451                if (!nfs_sockaddr_cmp(sap, clap))
 452                        continue;
 453
 454                atomic_inc(&clp->cl_count);
 455                return clp;
 456        }
 457        return NULL;
 458}
 459
 460/*
 461 * Look up a client by IP address and protocol version
 462 * - creates a new record if one doesn't yet exist
 463 */
 464static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
 465{
 466        struct nfs_client *clp, *new = NULL;
 467        int error;
 468
 469        dprintk("--> nfs_get_client(%s,v%u)\n",
 470                cl_init->hostname ?: "", cl_init->rpc_ops->version);
 471
 472        /* see if the client already exists */
 473        do {
 474                spin_lock(&nfs_client_lock);
 475
 476                clp = nfs_match_client(cl_init);
 477                if (clp)
 478                        goto found_client;
 479                if (new)
 480                        goto install_client;
 481
 482                spin_unlock(&nfs_client_lock);
 483
 484                new = nfs_alloc_client(cl_init);
 485        } while (!IS_ERR(new));
 486
 487        dprintk("--> nfs_get_client() = %ld [failed]\n", PTR_ERR(new));
 488        return new;
 489
 490        /* install a new client and return with it unready */
 491install_client:
 492        clp = new;
 493        list_add(&clp->cl_share_link, &nfs_client_list);
 494        spin_unlock(&nfs_client_lock);
 495        dprintk("--> nfs_get_client() = %p [new]\n", clp);
 496        return clp;
 497
 498        /* found an existing client
 499         * - make sure it's ready before returning
 500         */
 501found_client:
 502        spin_unlock(&nfs_client_lock);
 503
 504        if (new)
 505                nfs_free_client(new);
 506
 507        error = wait_event_killable(nfs_client_active_wq,
 508                                clp->cl_cons_state < NFS_CS_INITING);
 509        if (error < 0) {
 510                nfs_put_client(clp);
 511                return ERR_PTR(-ERESTARTSYS);
 512        }
 513
 514        if (clp->cl_cons_state < NFS_CS_READY) {
 515                error = clp->cl_cons_state;
 516                nfs_put_client(clp);
 517                return ERR_PTR(error);
 518        }
 519
 520        BUG_ON(clp->cl_cons_state != NFS_CS_READY);
 521
 522        dprintk("--> nfs_get_client() = %p [share]\n", clp);
 523        return clp;
 524}
 525
 526/*
 527 * Mark a server as ready or failed
 528 */
 529void nfs_mark_client_ready(struct nfs_client *clp, int state)
 530{
 531        clp->cl_cons_state = state;
 532        wake_up_all(&nfs_client_active_wq);
 533}
 534
 535/*
 536 * With sessions, the client is not marked ready until after a
 537 * successful EXCHANGE_ID and CREATE_SESSION.
 538 *
 539 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
 540 * other versions of NFS can be tried.
 541 */
 542int nfs4_check_client_ready(struct nfs_client *clp)
 543{
 544        if (!nfs4_has_session(clp))
 545                return 0;
 546        if (clp->cl_cons_state < NFS_CS_READY)
 547                return -EPROTONOSUPPORT;
 548        return 0;
 549}
 550
 551/*
 552 * Initialise the timeout values for a connection
 553 */
 554static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
 555                                    unsigned int timeo, unsigned int retrans)
 556{
 557        to->to_initval = timeo * HZ / 10;
 558        to->to_retries = retrans;
 559
 560        switch (proto) {
 561        case XPRT_TRANSPORT_TCP:
 562        case XPRT_TRANSPORT_RDMA:
 563                if (to->to_retries == 0)
 564                        to->to_retries = NFS_DEF_TCP_RETRANS;
 565                if (to->to_initval == 0)
 566                        to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10;
 567                if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
 568                        to->to_initval = NFS_MAX_TCP_TIMEOUT;
 569                to->to_increment = to->to_initval;
 570                to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
 571                if (to->to_maxval > NFS_MAX_TCP_TIMEOUT)
 572                        to->to_maxval = NFS_MAX_TCP_TIMEOUT;
 573                if (to->to_maxval < to->to_initval)
 574                        to->to_maxval = to->to_initval;
 575                to->to_exponential = 0;
 576                break;
 577        case XPRT_TRANSPORT_UDP:
 578                if (to->to_retries == 0)
 579                        to->to_retries = NFS_DEF_UDP_RETRANS;
 580                if (!to->to_initval)
 581                        to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10;
 582                if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
 583                        to->to_initval = NFS_MAX_UDP_TIMEOUT;
 584                to->to_maxval = NFS_MAX_UDP_TIMEOUT;
 585                to->to_exponential = 1;
 586                break;
 587        default:
 588                BUG();
 589        }
 590}
 591
 592/*
 593 * Create an RPC client handle
 594 */
 595static int nfs_create_rpc_client(struct nfs_client *clp,
 596                                 const struct rpc_timeout *timeparms,
 597                                 rpc_authflavor_t flavor,
 598                                 int discrtry, int noresvport)
 599{
 600        struct rpc_clnt         *clnt = NULL;
 601        struct rpc_create_args args = {
 602                .protocol       = clp->cl_proto,
 603                .address        = (struct sockaddr *)&clp->cl_addr,
 604                .addrsize       = clp->cl_addrlen,
 605                .timeout        = timeparms,
 606                .servername     = clp->cl_hostname,
 607                .program        = &nfs_program,
 608                .version        = clp->rpc_ops->version,
 609                .authflavor     = flavor,
 610        };
 611
 612        if (discrtry)
 613                args.flags |= RPC_CLNT_CREATE_DISCRTRY;
 614        if (noresvport)
 615                args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
 616
 617        if (!IS_ERR(clp->cl_rpcclient))
 618                return 0;
 619
 620        clnt = rpc_create(&args);
 621        if (IS_ERR(clnt)) {
 622                dprintk("%s: cannot create RPC client. Error = %ld\n",
 623                                __func__, PTR_ERR(clnt));
 624                return PTR_ERR(clnt);
 625        }
 626
 627        clp->cl_rpcclient = clnt;
 628        return 0;
 629}
 630
 631/*
 632 * Version 2 or 3 client destruction
 633 */
 634static void nfs_destroy_server(struct nfs_server *server)
 635{
 636        if (!(server->flags & NFS_MOUNT_NONLM))
 637                nlmclnt_done(server->nlm_host);
 638}
 639
 640/*
 641 * Version 2 or 3 lockd setup
 642 */
 643static int nfs_start_lockd(struct nfs_server *server)
 644{
 645        struct nlm_host *host;
 646        struct nfs_client *clp = server->nfs_client;
 647        struct nlmclnt_initdata nlm_init = {
 648                .hostname       = clp->cl_hostname,
 649                .address        = (struct sockaddr *)&clp->cl_addr,
 650                .addrlen        = clp->cl_addrlen,
 651                .nfs_version    = clp->rpc_ops->version,
 652                .noresvport     = server->flags & NFS_MOUNT_NORESVPORT ?
 653                                        1 : 0,
 654        };
 655
 656        if (nlm_init.nfs_version > 3)
 657                return 0;
 658        if (server->flags & NFS_MOUNT_NONLM)
 659                return 0;
 660
 661        switch (clp->cl_proto) {
 662                default:
 663                        nlm_init.protocol = IPPROTO_TCP;
 664                        break;
 665                case XPRT_TRANSPORT_UDP:
 666                        nlm_init.protocol = IPPROTO_UDP;
 667        }
 668
 669        host = nlmclnt_init(&nlm_init);
 670        if (IS_ERR(host))
 671                return PTR_ERR(host);
 672
 673        server->nlm_host = host;
 674        server->destroy = nfs_destroy_server;
 675        return 0;
 676}
 677
 678/*
 679 * Initialise an NFSv3 ACL client connection
 680 */
 681#ifdef CONFIG_NFS_V3_ACL
 682static void nfs_init_server_aclclient(struct nfs_server *server)
 683{
 684        if (server->nfs_client->rpc_ops->version != 3)
 685                goto out_noacl;
 686        if (server->flags & NFS_MOUNT_NOACL)
 687                goto out_noacl;
 688
 689        server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
 690        if (IS_ERR(server->client_acl))
 691                goto out_noacl;
 692
 693        /* No errors! Assume that Sun nfsacls are supported */
 694        server->caps |= NFS_CAP_ACLS;
 695        return;
 696
 697out_noacl:
 698        server->caps &= ~NFS_CAP_ACLS;
 699}
 700#else
 701static inline void nfs_init_server_aclclient(struct nfs_server *server)
 702{
 703        server->flags &= ~NFS_MOUNT_NOACL;
 704        server->caps &= ~NFS_CAP_ACLS;
 705}
 706#endif
 707
 708/*
 709 * Create a general RPC client
 710 */
 711static int nfs_init_server_rpcclient(struct nfs_server *server,
 712                const struct rpc_timeout *timeo,
 713                rpc_authflavor_t pseudoflavour)
 714{
 715        struct nfs_client *clp = server->nfs_client;
 716
 717        server->client = rpc_clone_client(clp->cl_rpcclient);
 718        if (IS_ERR(server->client)) {
 719                dprintk("%s: couldn't create rpc_client!\n", __func__);
 720                return PTR_ERR(server->client);
 721        }
 722
 723        memcpy(&server->client->cl_timeout_default,
 724                        timeo,
 725                        sizeof(server->client->cl_timeout_default));
 726        server->client->cl_timeout = &server->client->cl_timeout_default;
 727
 728        if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
 729                struct rpc_auth *auth;
 730
 731                auth = rpcauth_create(pseudoflavour, server->client);
 732                if (IS_ERR(auth)) {
 733                        dprintk("%s: couldn't create credcache!\n", __func__);
 734                        return PTR_ERR(auth);
 735                }
 736        }
 737        server->client->cl_softrtry = 0;
 738        if (server->flags & NFS_MOUNT_SOFT)
 739                server->client->cl_softrtry = 1;
 740
 741        return 0;
 742}
 743
 744/*
 745 * Initialise an NFS2 or NFS3 client
 746 */
 747static int nfs_init_client(struct nfs_client *clp,
 748                           const struct rpc_timeout *timeparms,
 749                           const struct nfs_parsed_mount_data *data)
 750{
 751        int error;
 752
 753        if (clp->cl_cons_state == NFS_CS_READY) {
 754                /* the client is already initialised */
 755                dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);
 756                return 0;
 757        }
 758
 759        /*
 760         * Create a client RPC handle for doing FSSTAT with UNIX auth only
 761         * - RFC 2623, sec 2.3.2
 762         */
 763        error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX,
 764                                      0, data->flags & NFS_MOUNT_NORESVPORT);
 765        if (error < 0)
 766                goto error;
 767        nfs_mark_client_ready(clp, NFS_CS_READY);
 768        return 0;
 769
 770error:
 771        nfs_mark_client_ready(clp, error);
 772        dprintk("<-- nfs_init_client() = xerror %d\n", error);
 773        return error;
 774}
 775
 776/*
 777 * Create a version 2 or 3 client
 778 */
 779static int nfs_init_server(struct nfs_server *server,
 780                           const struct nfs_parsed_mount_data *data)
 781{
 782        struct nfs_client_initdata cl_init = {
 783                .hostname = data->nfs_server.hostname,
 784                .addr = (const struct sockaddr *)&data->nfs_server.address,
 785                .addrlen = data->nfs_server.addrlen,
 786                .rpc_ops = &nfs_v2_clientops,
 787                .proto = data->nfs_server.protocol,
 788        };
 789        struct rpc_timeout timeparms;
 790        struct nfs_client *clp;
 791        int error;
 792
 793        dprintk("--> nfs_init_server()\n");
 794
 795#ifdef CONFIG_NFS_V3
 796        if (data->version == 3)
 797                cl_init.rpc_ops = &nfs_v3_clientops;
 798#endif
 799
 800        /* Allocate or find a client reference we can use */
 801        clp = nfs_get_client(&cl_init);
 802        if (IS_ERR(clp)) {
 803                dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
 804                return PTR_ERR(clp);
 805        }
 806
 807        nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
 808                        data->timeo, data->retrans);
 809        error = nfs_init_client(clp, &timeparms, data);
 810        if (error < 0)
 811                goto error;
 812
 813        server->nfs_client = clp;
 814
 815        /* Initialise the client representation from the mount data */
 816        server->flags = data->flags;
 817        server->options = data->options;
 818        server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
 819                NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
 820                NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
 821
 822        if (data->rsize)
 823                server->rsize = nfs_block_size(data->rsize, NULL);
 824        if (data->wsize)
 825                server->wsize = nfs_block_size(data->wsize, NULL);
 826
 827        server->acregmin = data->acregmin * HZ;
 828        server->acregmax = data->acregmax * HZ;
 829        server->acdirmin = data->acdirmin * HZ;
 830        server->acdirmax = data->acdirmax * HZ;
 831
 832        /* Start lockd here, before we might error out */
 833        error = nfs_start_lockd(server);
 834        if (error < 0)
 835                goto error;
 836
 837        server->port = data->nfs_server.port;
 838
 839        error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
 840        if (error < 0)
 841                goto error;
 842
 843        /* Preserve the values of mount_server-related mount options */
 844        if (data->mount_server.addrlen) {
 845                memcpy(&server->mountd_address, &data->mount_server.address,
 846                        data->mount_server.addrlen);
 847                server->mountd_addrlen = data->mount_server.addrlen;
 848        }
 849        server->mountd_version = data->mount_server.version;
 850        server->mountd_port = data->mount_server.port;
 851        server->mountd_protocol = data->mount_server.protocol;
 852
 853        server->namelen  = data->namlen;
 854        /* Create a client RPC handle for the NFSv3 ACL management interface */
 855        nfs_init_server_aclclient(server);
 856        dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
 857        return 0;
 858
 859error:
 860        server->nfs_client = NULL;
 861        nfs_put_client(clp);
 862        dprintk("<-- nfs_init_server() = xerror %d\n", error);
 863        return error;
 864}
 865
 866/*
 867 * Load up the server record from information gained in an fsinfo record
 868 */
 869static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo)
 870{
 871        unsigned long max_rpc_payload;
 872
 873        /* Work out a lot of parameters */
 874        if (server->rsize == 0)
 875                server->rsize = nfs_block_size(fsinfo->rtpref, NULL);
 876        if (server->wsize == 0)
 877                server->wsize = nfs_block_size(fsinfo->wtpref, NULL);
 878
 879        if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
 880                server->rsize = nfs_block_size(fsinfo->rtmax, NULL);
 881        if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
 882                server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
 883
 884        max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
 885        if (server->rsize > max_rpc_payload)
 886                server->rsize = max_rpc_payload;
 887        if (server->rsize > NFS_MAX_FILE_IO_SIZE)
 888                server->rsize = NFS_MAX_FILE_IO_SIZE;
 889        server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 890
 891        server->backing_dev_info.name = "nfs";
 892        server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
 893
 894        if (server->wsize > max_rpc_payload)
 895                server->wsize = max_rpc_payload;
 896        if (server->wsize > NFS_MAX_FILE_IO_SIZE)
 897                server->wsize = NFS_MAX_FILE_IO_SIZE;
 898        server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 899        server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
 900
 901        server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
 902        if (server->dtsize > PAGE_CACHE_SIZE)
 903                server->dtsize = PAGE_CACHE_SIZE;
 904        if (server->dtsize > server->rsize)
 905                server->dtsize = server->rsize;
 906
 907        if (server->flags & NFS_MOUNT_NOAC) {
 908                server->acregmin = server->acregmax = 0;
 909                server->acdirmin = server->acdirmax = 0;
 910        }
 911
 912        server->maxfilesize = fsinfo->maxfilesize;
 913
 914        /* We're airborne Set socket buffersize */
 915        rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
 916}
 917
 918/*
 919 * Probe filesystem information, including the FSID on v2/v3
 920 */
 921static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
 922{
 923        struct nfs_fsinfo fsinfo;
 924        struct nfs_client *clp = server->nfs_client;
 925        int error;
 926
 927        dprintk("--> nfs_probe_fsinfo()\n");
 928
 929        if (clp->rpc_ops->set_capabilities != NULL) {
 930                error = clp->rpc_ops->set_capabilities(server, mntfh);
 931                if (error < 0)
 932                        goto out_error;
 933        }
 934
 935        fsinfo.fattr = fattr;
 936        nfs_fattr_init(fattr);
 937        error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
 938        if (error < 0)
 939                goto out_error;
 940
 941        nfs_server_set_fsinfo(server, &fsinfo);
 942
 943        /* Get some general file system info */
 944        if (server->namelen == 0) {
 945                struct nfs_pathconf pathinfo;
 946
 947                pathinfo.fattr = fattr;
 948                nfs_fattr_init(fattr);
 949
 950                if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
 951                        server->namelen = pathinfo.max_namelen;
 952        }
 953
 954        dprintk("<-- nfs_probe_fsinfo() = 0\n");
 955        return 0;
 956
 957out_error:
 958        dprintk("nfs_probe_fsinfo: error = %d\n", -error);
 959        return error;
 960}
 961
 962/*
 963 * Copy useful information when duplicating a server record
 964 */
 965static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
 966{
 967        target->flags = source->flags;
 968        target->acregmin = source->acregmin;
 969        target->acregmax = source->acregmax;
 970        target->acdirmin = source->acdirmin;
 971        target->acdirmax = source->acdirmax;
 972        target->caps = source->caps;
 973        target->options = source->options;
 974}
 975
 976/*
 977 * Allocate and initialise a server record
 978 */
 979static struct nfs_server *nfs_alloc_server(void)
 980{
 981        struct nfs_server *server;
 982
 983        server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
 984        if (!server)
 985                return NULL;
 986
 987        server->client = server->client_acl = ERR_PTR(-EINVAL);
 988
 989        /* Zero out the NFS state stuff */
 990        INIT_LIST_HEAD(&server->client_link);
 991        INIT_LIST_HEAD(&server->master_link);
 992
 993        atomic_set(&server->active, 0);
 994
 995        server->io_stats = nfs_alloc_iostats();
 996        if (!server->io_stats) {
 997                kfree(server);
 998                return NULL;
 999        }
1000
1001        if (bdi_init(&server->backing_dev_info)) {
1002                nfs_free_iostats(server->io_stats);
1003                kfree(server);
1004                return NULL;
1005        }
1006
1007        return server;
1008}
1009
1010/*
1011 * Free up a server record
1012 */
1013void nfs_free_server(struct nfs_server *server)
1014{
1015        dprintk("--> nfs_free_server()\n");
1016
1017        spin_lock(&nfs_client_lock);
1018        list_del(&server->client_link);
1019        list_del(&server->master_link);
1020        spin_unlock(&nfs_client_lock);
1021
1022        if (server->destroy != NULL)
1023                server->destroy(server);
1024
1025        if (!IS_ERR(server->client_acl))
1026                rpc_shutdown_client(server->client_acl);
1027        if (!IS_ERR(server->client))
1028                rpc_shutdown_client(server->client);
1029
1030        nfs_put_client(server->nfs_client);
1031
1032        nfs_free_iostats(server->io_stats);
1033        bdi_destroy(&server->backing_dev_info);
1034        kfree(server);
1035        nfs_release_automount_timer();
1036        dprintk("<-- nfs_free_server()\n");
1037}
1038
1039/*
1040 * Create a version 2 or 3 volume record
1041 * - keyed on server and FSID
1042 */
1043struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1044                                     struct nfs_fh *mntfh)
1045{
1046        struct nfs_server *server;
1047        struct nfs_fattr fattr;
1048        int error;
1049
1050        server = nfs_alloc_server();
1051        if (!server)
1052                return ERR_PTR(-ENOMEM);
1053
1054        /* Get a client representation */
1055        error = nfs_init_server(server, data);
1056        if (error < 0)
1057                goto error;
1058
1059        BUG_ON(!server->nfs_client);
1060        BUG_ON(!server->nfs_client->rpc_ops);
1061        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1062
1063        /* Probe the root fh to retrieve its FSID */
1064        error = nfs_probe_fsinfo(server, mntfh, &fattr);
1065        if (error < 0)
1066                goto error;
1067        if (server->nfs_client->rpc_ops->version == 3) {
1068                if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
1069                        server->namelen = NFS3_MAXNAMLEN;
1070                if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
1071                        server->caps |= NFS_CAP_READDIRPLUS;
1072        } else {
1073                if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
1074                        server->namelen = NFS2_MAXNAMLEN;
1075        }
1076
1077        if (!(fattr.valid & NFS_ATTR_FATTR)) {
1078                error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
1079                if (error < 0) {
1080                        dprintk("nfs_create_server: getattr error = %d\n", -error);
1081                        goto error;
1082                }
1083        }
1084        memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
1085
1086        dprintk("Server FSID: %llx:%llx\n",
1087                (unsigned long long) server->fsid.major,
1088                (unsigned long long) server->fsid.minor);
1089
1090        spin_lock(&nfs_client_lock);
1091        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1092        list_add_tail(&server->master_link, &nfs_volume_list);
1093        spin_unlock(&nfs_client_lock);
1094
1095        server->mount_time = jiffies;
1096        return server;
1097
1098error:
1099        nfs_free_server(server);
1100        return ERR_PTR(error);
1101}
1102
1103#ifdef CONFIG_NFS_V4
1104/*
1105 * Initialize the NFS4 callback service
1106 */
1107static int nfs4_init_callback(struct nfs_client *clp)
1108{
1109        int error;
1110
1111        if (clp->rpc_ops->version == 4) {
1112                if (nfs4_has_session(clp)) {
1113                        error = xprt_setup_backchannel(
1114                                                clp->cl_rpcclient->cl_xprt,
1115                                                NFS41_BC_MIN_CALLBACKS);
1116                        if (error < 0)
1117                                return error;
1118                }
1119
1120                error = nfs_callback_up(clp->cl_minorversion,
1121                                        clp->cl_rpcclient->cl_xprt);
1122                if (error < 0) {
1123                        dprintk("%s: failed to start callback. Error = %d\n",
1124                                __func__, error);
1125                        return error;
1126                }
1127                __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
1128        }
1129        return 0;
1130}
1131
1132/*
1133 * Initialize the minor version specific parts of an NFS4 client record
1134 */
1135static int nfs4_init_client_minor_version(struct nfs_client *clp)
1136{
1137        clp->cl_call_sync = _nfs4_call_sync;
1138
1139#if defined(CONFIG_NFS_V4_1)
1140        if (clp->cl_minorversion) {
1141                struct nfs4_session *session = NULL;
1142                /*
1143                 * Create the session and mark it expired.
1144                 * When a SEQUENCE operation encounters the expired session
1145                 * it will do session recovery to initialize it.
1146                 */
1147                session = nfs4_alloc_session(clp);
1148                if (!session)
1149                        return -ENOMEM;
1150
1151                clp->cl_session = session;
1152                clp->cl_call_sync = _nfs4_call_sync_session;
1153        }
1154#endif /* CONFIG_NFS_V4_1 */
1155
1156        return nfs4_init_callback(clp);
1157}
1158
1159/*
1160 * Initialise an NFS4 client record
1161 */
1162static int nfs4_init_client(struct nfs_client *clp,
1163                const struct rpc_timeout *timeparms,
1164                const char *ip_addr,
1165                rpc_authflavor_t authflavour,
1166                int flags)
1167{
1168        int error;
1169
1170        if (clp->cl_cons_state == NFS_CS_READY) {
1171                /* the client is initialised already */
1172                dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
1173                return 0;
1174        }
1175
1176        /* Check NFS protocol revision and initialize RPC op vector */
1177        clp->rpc_ops = &nfs_v4_clientops;
1178
1179        error = nfs_create_rpc_client(clp, timeparms, authflavour,
1180                                      1, flags & NFS_MOUNT_NORESVPORT);
1181        if (error < 0)
1182                goto error;
1183        strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
1184
1185        error = nfs_idmap_new(clp);
1186        if (error < 0) {
1187                dprintk("%s: failed to create idmapper. Error = %d\n",
1188                        __func__, error);
1189                goto error;
1190        }
1191        __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
1192
1193        error = nfs4_init_client_minor_version(clp);
1194        if (error < 0)
1195                goto error;
1196
1197        if (!nfs4_has_session(clp))
1198                nfs_mark_client_ready(clp, NFS_CS_READY);
1199        return 0;
1200
1201error:
1202        nfs_mark_client_ready(clp, error);
1203        dprintk("<-- nfs4_init_client() = xerror %d\n", error);
1204        return error;
1205}
1206
1207/*
1208 * Set up an NFS4 client
1209 */
1210static int nfs4_set_client(struct nfs_server *server,
1211                const char *hostname,
1212                const struct sockaddr *addr,
1213                const size_t addrlen,
1214                const char *ip_addr,
1215                rpc_authflavor_t authflavour,
1216                int proto, const struct rpc_timeout *timeparms,
1217                u32 minorversion)
1218{
1219        struct nfs_client_initdata cl_init = {
1220                .hostname = hostname,
1221                .addr = addr,
1222                .addrlen = addrlen,
1223                .rpc_ops = &nfs_v4_clientops,
1224                .proto = proto,
1225                .minorversion = minorversion,
1226        };
1227        struct nfs_client *clp;
1228        int error;
1229
1230        dprintk("--> nfs4_set_client()\n");
1231
1232        /* Allocate or find a client reference we can use */
1233        clp = nfs_get_client(&cl_init);
1234        if (IS_ERR(clp)) {
1235                error = PTR_ERR(clp);
1236                goto error;
1237        }
1238        error = nfs4_init_client(clp, timeparms, ip_addr, authflavour,
1239                                        server->flags);
1240        if (error < 0)
1241                goto error_put;
1242
1243        server->nfs_client = clp;
1244        dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);
1245        return 0;
1246
1247error_put:
1248        nfs_put_client(clp);
1249error:
1250        dprintk("<-- nfs4_set_client() = xerror %d\n", error);
1251        return error;
1252}
1253
1254
1255/*
1256 * Session has been established, and the client marked ready.
1257 * Set the mount rsize and wsize with negotiated fore channel
1258 * attributes which will be bound checked in nfs_server_set_fsinfo.
1259 */
1260static void nfs4_session_set_rwsize(struct nfs_server *server)
1261{
1262#ifdef CONFIG_NFS_V4_1
1263        if (!nfs4_has_session(server->nfs_client))
1264                return;
1265        server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
1266        server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
1267#endif /* CONFIG_NFS_V4_1 */
1268}
1269
1270/*
1271 * Create a version 4 volume record
1272 */
1273static int nfs4_init_server(struct nfs_server *server,
1274                const struct nfs_parsed_mount_data *data)
1275{
1276        struct rpc_timeout timeparms;
1277        int error;
1278
1279        dprintk("--> nfs4_init_server()\n");
1280
1281        nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
1282                        data->timeo, data->retrans);
1283
1284        /* Initialise the client representation from the mount data */
1285        server->flags = data->flags;
1286        server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
1287        server->options = data->options;
1288
1289        /* Get a client record */
1290        error = nfs4_set_client(server,
1291                        data->nfs_server.hostname,
1292                        (const struct sockaddr *)&data->nfs_server.address,
1293                        data->nfs_server.addrlen,
1294                        data->client_address,
1295                        data->auth_flavors[0],
1296                        data->nfs_server.protocol,
1297                        &timeparms,
1298                        data->minorversion);
1299        if (error < 0)
1300                goto error;
1301
1302        if (data->rsize)
1303                server->rsize = nfs_block_size(data->rsize, NULL);
1304        if (data->wsize)
1305                server->wsize = nfs_block_size(data->wsize, NULL);
1306
1307        server->acregmin = data->acregmin * HZ;
1308        server->acregmax = data->acregmax * HZ;
1309        server->acdirmin = data->acdirmin * HZ;
1310        server->acdirmax = data->acdirmax * HZ;
1311
1312        server->port = data->nfs_server.port;
1313
1314        error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
1315
1316error:
1317        /* Done */
1318        dprintk("<-- nfs4_init_server() = %d\n", error);
1319        return error;
1320}
1321
1322/*
1323 * Create a version 4 volume record
1324 * - keyed on server and FSID
1325 */
1326struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1327                                      struct nfs_fh *mntfh)
1328{
1329        struct nfs_fattr fattr;
1330        struct nfs_server *server;
1331        int error;
1332
1333        dprintk("--> nfs4_create_server()\n");
1334
1335        server = nfs_alloc_server();
1336        if (!server)
1337                return ERR_PTR(-ENOMEM);
1338
1339        /* set up the general RPC client */
1340        error = nfs4_init_server(server, data);
1341        if (error < 0)
1342                goto error;
1343
1344        BUG_ON(!server->nfs_client);
1345        BUG_ON(!server->nfs_client->rpc_ops);
1346        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1347
1348        error = nfs4_init_session(server);
1349        if (error < 0)
1350                goto error;
1351
1352        /* Probe the root fh to retrieve its FSID */
1353        error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
1354        if (error < 0)
1355                goto error;
1356
1357        dprintk("Server FSID: %llx:%llx\n",
1358                (unsigned long long) server->fsid.major,
1359                (unsigned long long) server->fsid.minor);
1360        dprintk("Mount FH: %d\n", mntfh->size);
1361
1362        nfs4_session_set_rwsize(server);
1363
1364        error = nfs_probe_fsinfo(server, mntfh, &fattr);
1365        if (error < 0)
1366                goto error;
1367
1368        if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1369                server->namelen = NFS4_MAXNAMLEN;
1370
1371        spin_lock(&nfs_client_lock);
1372        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1373        list_add_tail(&server->master_link, &nfs_volume_list);
1374        spin_unlock(&nfs_client_lock);
1375
1376        server->mount_time = jiffies;
1377        dprintk("<-- nfs4_create_server() = %p\n", server);
1378        return server;
1379
1380error:
1381        nfs_free_server(server);
1382        dprintk("<-- nfs4_create_server() = error %d\n", error);
1383        return ERR_PTR(error);
1384}
1385
1386/*
1387 * Create an NFS4 referral server record
1388 */
1389struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1390                                               struct nfs_fh *mntfh)
1391{
1392        struct nfs_client *parent_client;
1393        struct nfs_server *server, *parent_server;
1394        struct nfs_fattr fattr;
1395        int error;
1396
1397        dprintk("--> nfs4_create_referral_server()\n");
1398
1399        server = nfs_alloc_server();
1400        if (!server)
1401                return ERR_PTR(-ENOMEM);
1402
1403        parent_server = NFS_SB(data->sb);
1404        parent_client = parent_server->nfs_client;
1405
1406        /* Initialise the client representation from the parent server */
1407        nfs_server_copy_userdata(server, parent_server);
1408        server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
1409
1410        /* Get a client representation.
1411         * Note: NFSv4 always uses TCP, */
1412        error = nfs4_set_client(server, data->hostname,
1413                                data->addr,
1414                                data->addrlen,
1415                                parent_client->cl_ipaddr,
1416                                data->authflavor,
1417                                parent_server->client->cl_xprt->prot,
1418                                parent_server->client->cl_timeout,
1419                                parent_client->cl_minorversion);
1420        if (error < 0)
1421                goto error;
1422
1423        error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
1424        if (error < 0)
1425                goto error;
1426
1427        BUG_ON(!server->nfs_client);
1428        BUG_ON(!server->nfs_client->rpc_ops);
1429        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1430
1431        /* Probe the root fh to retrieve its FSID and filehandle */
1432        error = nfs4_path_walk(server, mntfh, data->mnt_path);
1433        if (error < 0)
1434                goto error;
1435
1436        /* probe the filesystem info for this server filesystem */
1437        error = nfs_probe_fsinfo(server, mntfh, &fattr);
1438        if (error < 0)
1439                goto error;
1440
1441        if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1442                server->namelen = NFS4_MAXNAMLEN;
1443
1444        dprintk("Referral FSID: %llx:%llx\n",
1445                (unsigned long long) server->fsid.major,
1446                (unsigned long long) server->fsid.minor);
1447
1448        spin_lock(&nfs_client_lock);
1449        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1450        list_add_tail(&server->master_link, &nfs_volume_list);
1451        spin_unlock(&nfs_client_lock);
1452
1453        server->mount_time = jiffies;
1454
1455        dprintk("<-- nfs_create_referral_server() = %p\n", server);
1456        return server;
1457
1458error:
1459        nfs_free_server(server);
1460        dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
1461        return ERR_PTR(error);
1462}
1463
1464#endif /* CONFIG_NFS_V4 */
1465
1466/*
1467 * Clone an NFS2, NFS3 or NFS4 server record
1468 */
1469struct nfs_server *nfs_clone_server(struct nfs_server *source,
1470                                    struct nfs_fh *fh,
1471                                    struct nfs_fattr *fattr)
1472{
1473        struct nfs_server *server;
1474        struct nfs_fattr fattr_fsinfo;
1475        int error;
1476
1477        dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
1478                (unsigned long long) fattr->fsid.major,
1479                (unsigned long long) fattr->fsid.minor);
1480
1481        server = nfs_alloc_server();
1482        if (!server)
1483                return ERR_PTR(-ENOMEM);
1484
1485        /* Copy data from the source */
1486        server->nfs_client = source->nfs_client;
1487        atomic_inc(&server->nfs_client->cl_count);
1488        nfs_server_copy_userdata(server, source);
1489
1490        server->fsid = fattr->fsid;
1491
1492        error = nfs_init_server_rpcclient(server,
1493                        source->client->cl_timeout,
1494                        source->client->cl_auth->au_flavor);
1495        if (error < 0)
1496                goto out_free_server;
1497        if (!IS_ERR(source->client_acl))
1498                nfs_init_server_aclclient(server);
1499
1500        /* probe the filesystem info for this server filesystem */
1501        error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
1502        if (error < 0)
1503                goto out_free_server;
1504
1505        if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1506                server->namelen = NFS4_MAXNAMLEN;
1507
1508        dprintk("Cloned FSID: %llx:%llx\n",
1509                (unsigned long long) server->fsid.major,
1510                (unsigned long long) server->fsid.minor);
1511
1512        error = nfs_start_lockd(server);
1513        if (error < 0)
1514                goto out_free_server;
1515
1516        spin_lock(&nfs_client_lock);
1517        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1518        list_add_tail(&server->master_link, &nfs_volume_list);
1519        spin_unlock(&nfs_client_lock);
1520
1521        server->mount_time = jiffies;
1522
1523        dprintk("<-- nfs_clone_server() = %p\n", server);
1524        return server;
1525
1526out_free_server:
1527        nfs_free_server(server);
1528        dprintk("<-- nfs_clone_server() = error %d\n", error);
1529        return ERR_PTR(error);
1530}
1531
1532#ifdef CONFIG_PROC_FS
1533static struct proc_dir_entry *proc_fs_nfs;
1534
1535static int nfs_server_list_open(struct inode *inode, struct file *file);
1536static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
1537static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
1538static void nfs_server_list_stop(struct seq_file *p, void *v);
1539static int nfs_server_list_show(struct seq_file *m, void *v);
1540
1541static const struct seq_operations nfs_server_list_ops = {
1542        .start  = nfs_server_list_start,
1543        .next   = nfs_server_list_next,
1544        .stop   = nfs_server_list_stop,
1545        .show   = nfs_server_list_show,
1546};
1547
1548static const struct file_operations nfs_server_list_fops = {
1549        .open           = nfs_server_list_open,
1550        .read           = seq_read,
1551        .llseek         = seq_lseek,
1552        .release        = seq_release,
1553        .owner          = THIS_MODULE,
1554};
1555
1556static int nfs_volume_list_open(struct inode *inode, struct file *file);
1557static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
1558static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
1559static void nfs_volume_list_stop(struct seq_file *p, void *v);
1560static int nfs_volume_list_show(struct seq_file *m, void *v);
1561
1562static const struct seq_operations nfs_volume_list_ops = {
1563        .start  = nfs_volume_list_start,
1564        .next   = nfs_volume_list_next,
1565        .stop   = nfs_volume_list_stop,
1566        .show   = nfs_volume_list_show,
1567};
1568
1569static const struct file_operations nfs_volume_list_fops = {
1570        .open           = nfs_volume_list_open,
1571        .read           = seq_read,
1572        .llseek         = seq_lseek,
1573        .release        = seq_release,
1574        .owner          = THIS_MODULE,
1575};
1576
1577/*
1578 * open "/proc/fs/nfsfs/servers" which provides a summary of servers with which
1579 * we're dealing
1580 */
1581static int nfs_server_list_open(struct inode *inode, struct file *file)
1582{
1583        struct seq_file *m;
1584        int ret;
1585
1586        ret = seq_open(file, &nfs_server_list_ops);
1587        if (ret < 0)
1588                return ret;
1589
1590        m = file->private_data;
1591        m->private = PDE(inode)->data;
1592
1593        return 0;
1594}
1595
1596/*
1597 * set up the iterator to start reading from the server list and return the first item
1598 */
1599static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
1600{
1601        /* lock the list against modification */
1602        spin_lock(&nfs_client_lock);
1603        return seq_list_start_head(&nfs_client_list, *_pos);
1604}
1605
1606/*
1607 * move to next server
1608 */
1609static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
1610{
1611        return seq_list_next(v, &nfs_client_list, pos);
1612}
1613
1614/*
1615 * clean up after reading from the transports list
1616 */
1617static void nfs_server_list_stop(struct seq_file *p, void *v)
1618{
1619        spin_unlock(&nfs_client_lock);
1620}
1621
1622/*
1623 * display a header line followed by a load of call lines
1624 */
1625static int nfs_server_list_show(struct seq_file *m, void *v)
1626{
1627        struct nfs_client *clp;
1628
1629        /* display header on line 1 */
1630        if (v == &nfs_client_list) {
1631                seq_puts(m, "NV SERVER   PORT USE HOSTNAME\n");
1632                return 0;
1633        }
1634
1635        /* display one transport per line on subsequent lines */
1636        clp = list_entry(v, struct nfs_client, cl_share_link);
1637
1638        seq_printf(m, "v%u %s %s %3d %s\n",
1639                   clp->rpc_ops->version,
1640                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1641                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1642                   atomic_read(&clp->cl_count),
1643                   clp->cl_hostname);
1644
1645        return 0;
1646}
1647
1648/*
1649 * open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes
1650 */
1651static int nfs_volume_list_open(struct inode *inode, struct file *file)
1652{
1653        struct seq_file *m;
1654        int ret;
1655
1656        ret = seq_open(file, &nfs_volume_list_ops);
1657        if (ret < 0)
1658                return ret;
1659
1660        m = file->private_data;
1661        m->private = PDE(inode)->data;
1662
1663        return 0;
1664}
1665
1666/*
1667 * set up the iterator to start reading from the volume list and return the first item
1668 */
1669static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1670{
1671        /* lock the list against modification */
1672        spin_lock(&nfs_client_lock);
1673        return seq_list_start_head(&nfs_volume_list, *_pos);
1674}
1675
1676/*
1677 * move to next volume
1678 */
1679static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
1680{
1681        return seq_list_next(v, &nfs_volume_list, pos);
1682}
1683
1684/*
1685 * clean up after reading from the transports list
1686 */
1687static void nfs_volume_list_stop(struct seq_file *p, void *v)
1688{
1689        spin_unlock(&nfs_client_lock);
1690}
1691
1692/*
1693 * display a header line followed by a load of call lines
1694 */
1695static int nfs_volume_list_show(struct seq_file *m, void *v)
1696{
1697        struct nfs_server *server;
1698        struct nfs_client *clp;
1699        char dev[8], fsid[17];
1700
1701        /* display header on line 1 */
1702        if (v == &nfs_volume_list) {
1703                seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
1704                return 0;
1705        }
1706        /* display one transport per line on subsequent lines */
1707        server = list_entry(v, struct nfs_server, master_link);
1708        clp = server->nfs_client;
1709
1710        snprintf(dev, 8, "%u:%u",
1711                 MAJOR(server->s_dev), MINOR(server->s_dev));
1712
1713        snprintf(fsid, 17, "%llx:%llx",
1714                 (unsigned long long) server->fsid.major,
1715                 (unsigned long long) server->fsid.minor);
1716
1717        seq_printf(m, "v%u %s %s %-7s %-17s %s\n",
1718                   clp->rpc_ops->version,
1719                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1720                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1721                   dev,
1722                   fsid,
1723                   nfs_server_fscache_state(server));
1724
1725        return 0;
1726}
1727
1728/*
1729 * initialise the /proc/fs/nfsfs/ directory
1730 */
1731int __init nfs_fs_proc_init(void)
1732{
1733        struct proc_dir_entry *p;
1734
1735        proc_fs_nfs = proc_mkdir("fs/nfsfs", NULL);
1736        if (!proc_fs_nfs)
1737                goto error_0;
1738
1739        /* a file of servers with which we're dealing */
1740        p = proc_create("servers", S_IFREG|S_IRUGO,
1741                        proc_fs_nfs, &nfs_server_list_fops);
1742        if (!p)
1743                goto error_1;
1744
1745        /* a file of volumes that we have mounted */
1746        p = proc_create("volumes", S_IFREG|S_IRUGO,
1747                        proc_fs_nfs, &nfs_volume_list_fops);
1748        if (!p)
1749                goto error_2;
1750        return 0;
1751
1752error_2:
1753        remove_proc_entry("servers", proc_fs_nfs);
1754error_1:
1755        remove_proc_entry("fs/nfsfs", NULL);
1756error_0:
1757        return -ENOMEM;
1758}
1759
1760/*
1761 * clean up the /proc/fs/nfsfs/ directory
1762 */
1763void nfs_fs_proc_exit(void)
1764{
1765        remove_proc_entry("volumes", proc_fs_nfs);
1766        remove_proc_entry("servers", proc_fs_nfs);
1767        remove_proc_entry("fs/nfsfs", NULL);
1768}
1769
1770#endif /* CONFIG_PROC_FS */
1771