linux/fs/nfsd/nfssvc.c
<<
>>
Prefs
   1/*
   2 * Central processing for nfsd.
   3 *
   4 * Authors:     Olaf Kirch (okir@monad.swb.de)
   5 *
   6 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
   7 */
   8
   9#include <linux/sched/signal.h>
  10#include <linux/freezer.h>
  11#include <linux/module.h>
  12#include <linux/fs_struct.h>
  13#include <linux/swap.h>
  14
  15#include <linux/sunrpc/stats.h>
  16#include <linux/sunrpc/svcsock.h>
  17#include <linux/sunrpc/svc_xprt.h>
  18#include <linux/lockd/bind.h>
  19#include <linux/nfsacl.h>
  20#include <linux/seq_file.h>
  21#include <linux/inetdevice.h>
  22#include <net/addrconf.h>
  23#include <net/ipv6.h>
  24#include <net/net_namespace.h>
  25#include "nfsd.h"
  26#include "cache.h"
  27#include "vfs.h"
  28#include "netns.h"
  29
  30#define NFSDDBG_FACILITY        NFSDDBG_SVC
  31
  32extern struct svc_program       nfsd_program;
  33static int                      nfsd(void *vrqstp);
  34
  35/*
  36 * nfsd_mutex protects nn->nfsd_serv -- both the pointer itself and the members
  37 * of the svc_serv struct. In particular, ->sv_nrthreads but also to some
  38 * extent ->sv_temp_socks and ->sv_permsocks. It also protects nfsdstats.th_cnt
  39 *
  40 * If (out side the lock) nn->nfsd_serv is non-NULL, then it must point to a
  41 * properly initialised 'struct svc_serv' with ->sv_nrthreads > 0. That number
  42 * of nfsd threads must exist and each must listed in ->sp_all_threads in each
  43 * entry of ->sv_pools[].
  44 *
  45 * Transitions of the thread count between zero and non-zero are of particular
  46 * interest since the svc_serv needs to be created and initialized at that
  47 * point, or freed.
  48 *
  49 * Finally, the nfsd_mutex also protects some of the global variables that are
  50 * accessed when nfsd starts and that are settable via the write_* routines in
  51 * nfsctl.c. In particular:
  52 *
  53 *      user_recovery_dirname
  54 *      user_lease_time
  55 *      nfsd_versions
  56 */
  57DEFINE_MUTEX(nfsd_mutex);
  58
  59/*
  60 * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used.
  61 * nfsd_drc_max_pages limits the total amount of memory available for
  62 * version 4.1 DRC caches.
  63 * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage.
  64 */
  65spinlock_t      nfsd_drc_lock;
  66unsigned long   nfsd_drc_max_mem;
  67unsigned long   nfsd_drc_mem_used;
  68
  69#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
  70static struct svc_stat  nfsd_acl_svcstats;
  71static const struct svc_version *nfsd_acl_version[] = {
  72        [2] = &nfsd_acl_version2,
  73        [3] = &nfsd_acl_version3,
  74};
  75
  76#define NFSD_ACL_MINVERS            2
  77#define NFSD_ACL_NRVERS         ARRAY_SIZE(nfsd_acl_version)
  78static const struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
  79
  80static struct svc_program       nfsd_acl_program = {
  81        .pg_prog                = NFS_ACL_PROGRAM,
  82        .pg_nvers               = NFSD_ACL_NRVERS,
  83        .pg_vers                = nfsd_acl_versions,
  84        .pg_name                = "nfsacl",
  85        .pg_class               = "nfsd",
  86        .pg_stats               = &nfsd_acl_svcstats,
  87        .pg_authenticate        = &svc_set_client,
  88};
  89
  90static struct svc_stat  nfsd_acl_svcstats = {
  91        .program        = &nfsd_acl_program,
  92};
  93#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
  94
  95static const struct svc_version *nfsd_version[] = {
  96        [2] = &nfsd_version2,
  97#if defined(CONFIG_NFSD_V3)
  98        [3] = &nfsd_version3,
  99#endif
 100#if defined(CONFIG_NFSD_V4)
 101        [4] = &nfsd_version4,
 102#endif
 103};
 104
 105#define NFSD_MINVERS            2
 106#define NFSD_NRVERS             ARRAY_SIZE(nfsd_version)
 107static const struct svc_version *nfsd_versions[NFSD_NRVERS];
 108
 109struct svc_program              nfsd_program = {
 110#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 111        .pg_next                = &nfsd_acl_program,
 112#endif
 113        .pg_prog                = NFS_PROGRAM,          /* program number */
 114        .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
 115        .pg_vers                = nfsd_versions,        /* version table */
 116        .pg_name                = "nfsd",               /* program name */
 117        .pg_class               = "nfsd",               /* authentication class */
 118        .pg_stats               = &nfsd_svcstats,       /* version table */
 119        .pg_authenticate        = &svc_set_client,      /* export authentication */
 120
 121};
 122
 123static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
 124        [0] = 1,
 125        [1] = 1,
 126        [2] = 1,
 127};
 128
 129int nfsd_vers(int vers, enum vers_op change)
 130{
 131        if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
 132                return 0;
 133        switch(change) {
 134        case NFSD_SET:
 135                nfsd_versions[vers] = nfsd_version[vers];
 136#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 137                if (vers < NFSD_ACL_NRVERS)
 138                        nfsd_acl_versions[vers] = nfsd_acl_version[vers];
 139#endif
 140                break;
 141        case NFSD_CLEAR:
 142                nfsd_versions[vers] = NULL;
 143#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 144                if (vers < NFSD_ACL_NRVERS)
 145                        nfsd_acl_versions[vers] = NULL;
 146#endif
 147                break;
 148        case NFSD_TEST:
 149                return nfsd_versions[vers] != NULL;
 150        case NFSD_AVAIL:
 151                return nfsd_version[vers] != NULL;
 152        }
 153        return 0;
 154}
 155
 156static void
 157nfsd_adjust_nfsd_versions4(void)
 158{
 159        unsigned i;
 160
 161        for (i = 0; i <= NFSD_SUPPORTED_MINOR_VERSION; i++) {
 162                if (nfsd_supported_minorversions[i])
 163                        return;
 164        }
 165        nfsd_vers(4, NFSD_CLEAR);
 166}
 167
 168int nfsd_minorversion(u32 minorversion, enum vers_op change)
 169{
 170        if (minorversion > NFSD_SUPPORTED_MINOR_VERSION &&
 171            change != NFSD_AVAIL)
 172                return -1;
 173        switch(change) {
 174        case NFSD_SET:
 175                nfsd_supported_minorversions[minorversion] = true;
 176                nfsd_vers(4, NFSD_SET);
 177                break;
 178        case NFSD_CLEAR:
 179                nfsd_supported_minorversions[minorversion] = false;
 180                nfsd_adjust_nfsd_versions4();
 181                break;
 182        case NFSD_TEST:
 183                return nfsd_supported_minorversions[minorversion];
 184        case NFSD_AVAIL:
 185                return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
 186        }
 187        return 0;
 188}
 189
 190/*
 191 * Maximum number of nfsd processes
 192 */
 193#define NFSD_MAXSERVS           8192
 194
 195int nfsd_nrthreads(struct net *net)
 196{
 197        int rv = 0;
 198        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 199
 200        mutex_lock(&nfsd_mutex);
 201        if (nn->nfsd_serv)
 202                rv = nn->nfsd_serv->sv_nrthreads;
 203        mutex_unlock(&nfsd_mutex);
 204        return rv;
 205}
 206
 207static int nfsd_init_socks(struct net *net)
 208{
 209        int error;
 210        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 211
 212        if (!list_empty(&nn->nfsd_serv->sv_permsocks))
 213                return 0;
 214
 215        error = svc_create_xprt(nn->nfsd_serv, "udp", net, PF_INET, NFS_PORT,
 216                                        SVC_SOCK_DEFAULTS);
 217        if (error < 0)
 218                return error;
 219
 220        error = svc_create_xprt(nn->nfsd_serv, "tcp", net, PF_INET, NFS_PORT,
 221                                        SVC_SOCK_DEFAULTS);
 222        if (error < 0)
 223                return error;
 224
 225        return 0;
 226}
 227
 228static int nfsd_users = 0;
 229
 230static int nfsd_startup_generic(int nrservs)
 231{
 232        int ret;
 233
 234        if (nfsd_users++)
 235                return 0;
 236
 237        /*
 238         * Readahead param cache - will no-op if it already exists.
 239         * (Note therefore results will be suboptimal if number of
 240         * threads is modified after nfsd start.)
 241         */
 242        ret = nfsd_racache_init(2*nrservs);
 243        if (ret)
 244                goto dec_users;
 245
 246        ret = nfs4_state_start();
 247        if (ret)
 248                goto out_racache;
 249        return 0;
 250
 251out_racache:
 252        nfsd_racache_shutdown();
 253dec_users:
 254        nfsd_users--;
 255        return ret;
 256}
 257
 258static void nfsd_shutdown_generic(void)
 259{
 260        if (--nfsd_users)
 261                return;
 262
 263        nfs4_state_shutdown();
 264        nfsd_racache_shutdown();
 265}
 266
 267static bool nfsd_needs_lockd(void)
 268{
 269#if defined(CONFIG_NFSD_V3)
 270        return (nfsd_versions[2] != NULL) || (nfsd_versions[3] != NULL);
 271#else
 272        return (nfsd_versions[2] != NULL);
 273#endif
 274}
 275
 276static int nfsd_startup_net(int nrservs, struct net *net)
 277{
 278        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 279        int ret;
 280
 281        if (nn->nfsd_net_up)
 282                return 0;
 283
 284        ret = nfsd_startup_generic(nrservs);
 285        if (ret)
 286                return ret;
 287        ret = nfsd_init_socks(net);
 288        if (ret)
 289                goto out_socks;
 290
 291        if (nfsd_needs_lockd() && !nn->lockd_up) {
 292                ret = lockd_up(net);
 293                if (ret)
 294                        goto out_socks;
 295                nn->lockd_up = 1;
 296        }
 297
 298        ret = nfs4_state_start_net(net);
 299        if (ret)
 300                goto out_lockd;
 301
 302        nn->nfsd_net_up = true;
 303        return 0;
 304
 305out_lockd:
 306        if (nn->lockd_up) {
 307                lockd_down(net);
 308                nn->lockd_up = 0;
 309        }
 310out_socks:
 311        nfsd_shutdown_generic();
 312        return ret;
 313}
 314
 315static void nfsd_shutdown_net(struct net *net)
 316{
 317        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 318
 319        nfs4_state_shutdown_net(net);
 320        if (nn->lockd_up) {
 321                lockd_down(net);
 322                nn->lockd_up = 0;
 323        }
 324        nn->nfsd_net_up = false;
 325        nfsd_shutdown_generic();
 326}
 327
 328static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event,
 329        void *ptr)
 330{
 331        struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
 332        struct net_device *dev = ifa->ifa_dev->dev;
 333        struct net *net = dev_net(dev);
 334        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 335        struct sockaddr_in sin;
 336
 337        if (event != NETDEV_DOWN)
 338                goto out;
 339
 340        if (nn->nfsd_serv) {
 341                dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local);
 342                sin.sin_family = AF_INET;
 343                sin.sin_addr.s_addr = ifa->ifa_local;
 344                svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin);
 345        }
 346
 347out:
 348        return NOTIFY_DONE;
 349}
 350
 351static struct notifier_block nfsd_inetaddr_notifier = {
 352        .notifier_call = nfsd_inetaddr_event,
 353};
 354
 355#if IS_ENABLED(CONFIG_IPV6)
 356static int nfsd_inet6addr_event(struct notifier_block *this,
 357        unsigned long event, void *ptr)
 358{
 359        struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
 360        struct net_device *dev = ifa->idev->dev;
 361        struct net *net = dev_net(dev);
 362        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 363        struct sockaddr_in6 sin6;
 364
 365        if (event != NETDEV_DOWN)
 366                goto out;
 367
 368        if (nn->nfsd_serv) {
 369                dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr);
 370                sin6.sin6_family = AF_INET6;
 371                sin6.sin6_addr = ifa->addr;
 372                if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
 373                        sin6.sin6_scope_id = ifa->idev->dev->ifindex;
 374                svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6);
 375        }
 376
 377out:
 378        return NOTIFY_DONE;
 379}
 380
 381static struct notifier_block nfsd_inet6addr_notifier = {
 382        .notifier_call = nfsd_inet6addr_event,
 383};
 384#endif
 385
 386/* Only used under nfsd_mutex, so this atomic may be overkill: */
 387static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0);
 388
 389static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
 390{
 391        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 392
 393        /* check if the notifier still has clients */
 394        if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
 395                unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
 396#if IS_ENABLED(CONFIG_IPV6)
 397                unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
 398#endif
 399        }
 400
 401        /*
 402         * write_ports can create the server without actually starting
 403         * any threads--if we get shut down before any threads are
 404         * started, then nfsd_last_thread will be run before any of this
 405         * other initialization has been done except the rpcb information.
 406         */
 407        svc_rpcb_cleanup(serv, net);
 408        if (!nn->nfsd_net_up)
 409                return;
 410
 411        nfsd_shutdown_net(net);
 412        printk(KERN_WARNING "nfsd: last server has exited, flushing export "
 413                            "cache\n");
 414        nfsd_export_flush(net);
 415}
 416
 417void nfsd_reset_versions(void)
 418{
 419        int i;
 420
 421        for (i = 0; i < NFSD_NRVERS; i++)
 422                if (nfsd_vers(i, NFSD_TEST))
 423                        return;
 424
 425        for (i = 0; i < NFSD_NRVERS; i++)
 426                if (i != 4)
 427                        nfsd_vers(i, NFSD_SET);
 428                else {
 429                        int minor = 0;
 430                        while (nfsd_minorversion(minor, NFSD_SET) >= 0)
 431                                minor++;
 432                }
 433}
 434
 435/*
 436 * Each session guarantees a negotiated per slot memory cache for replies
 437 * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
 438 * NFSv4.1 server might want to use more memory for a DRC than a machine
 439 * with mutiple services.
 440 *
 441 * Impose a hard limit on the number of pages for the DRC which varies
 442 * according to the machines free pages. This is of course only a default.
 443 *
 444 * For now this is a #defined shift which could be under admin control
 445 * in the future.
 446 */
 447static void set_max_drc(void)
 448{
 449        #define NFSD_DRC_SIZE_SHIFT     10
 450        nfsd_drc_max_mem = (nr_free_buffer_pages()
 451                                        >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE;
 452        nfsd_drc_mem_used = 0;
 453        spin_lock_init(&nfsd_drc_lock);
 454        dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem);
 455}
 456
 457static int nfsd_get_default_max_blksize(void)
 458{
 459        struct sysinfo i;
 460        unsigned long long target;
 461        unsigned long ret;
 462
 463        si_meminfo(&i);
 464        target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
 465        /*
 466         * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig
 467         * machines, but only uses 32K on 128M machines.  Bottom out at
 468         * 8K on 32M and smaller.  Of course, this is only a default.
 469         */
 470        target >>= 12;
 471
 472        ret = NFSSVC_MAXBLKSIZE;
 473        while (ret > target && ret >= 8*1024*2)
 474                ret /= 2;
 475        return ret;
 476}
 477
 478static struct svc_serv_ops nfsd_thread_sv_ops = {
 479        .svo_shutdown           = nfsd_last_thread,
 480        .svo_function           = nfsd,
 481        .svo_enqueue_xprt       = svc_xprt_do_enqueue,
 482        .svo_setup              = svc_set_num_threads,
 483        .svo_module             = THIS_MODULE,
 484};
 485
 486int nfsd_create_serv(struct net *net)
 487{
 488        int error;
 489        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 490
 491        WARN_ON(!mutex_is_locked(&nfsd_mutex));
 492        if (nn->nfsd_serv) {
 493                svc_get(nn->nfsd_serv);
 494                return 0;
 495        }
 496        if (nfsd_max_blksize == 0)
 497                nfsd_max_blksize = nfsd_get_default_max_blksize();
 498        nfsd_reset_versions();
 499        nn->nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
 500                                                &nfsd_thread_sv_ops);
 501        if (nn->nfsd_serv == NULL)
 502                return -ENOMEM;
 503
 504        nn->nfsd_serv->sv_maxconn = nn->max_connections;
 505        error = svc_bind(nn->nfsd_serv, net);
 506        if (error < 0) {
 507                svc_destroy(nn->nfsd_serv);
 508                return error;
 509        }
 510
 511        set_max_drc();
 512        /* check if the notifier is already set */
 513        if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
 514                register_inetaddr_notifier(&nfsd_inetaddr_notifier);
 515#if IS_ENABLED(CONFIG_IPV6)
 516                register_inet6addr_notifier(&nfsd_inet6addr_notifier);
 517#endif
 518        }
 519        do_gettimeofday(&nn->nfssvc_boot);              /* record boot time */
 520        return 0;
 521}
 522
 523int nfsd_nrpools(struct net *net)
 524{
 525        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 526
 527        if (nn->nfsd_serv == NULL)
 528                return 0;
 529        else
 530                return nn->nfsd_serv->sv_nrpools;
 531}
 532
 533int nfsd_get_nrthreads(int n, int *nthreads, struct net *net)
 534{
 535        int i = 0;
 536        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 537
 538        if (nn->nfsd_serv != NULL) {
 539                for (i = 0; i < nn->nfsd_serv->sv_nrpools && i < n; i++)
 540                        nthreads[i] = nn->nfsd_serv->sv_pools[i].sp_nrthreads;
 541        }
 542
 543        return 0;
 544}
 545
 546void nfsd_destroy(struct net *net)
 547{
 548        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 549        int destroy = (nn->nfsd_serv->sv_nrthreads == 1);
 550
 551        if (destroy)
 552                svc_shutdown_net(nn->nfsd_serv, net);
 553        svc_destroy(nn->nfsd_serv);
 554        if (destroy)
 555                nn->nfsd_serv = NULL;
 556}
 557
 558int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
 559{
 560        int i = 0;
 561        int tot = 0;
 562        int err = 0;
 563        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 564
 565        WARN_ON(!mutex_is_locked(&nfsd_mutex));
 566
 567        if (nn->nfsd_serv == NULL || n <= 0)
 568                return 0;
 569
 570        if (n > nn->nfsd_serv->sv_nrpools)
 571                n = nn->nfsd_serv->sv_nrpools;
 572
 573        /* enforce a global maximum number of threads */
 574        tot = 0;
 575        for (i = 0; i < n; i++) {
 576                nthreads[i] = min(nthreads[i], NFSD_MAXSERVS);
 577                tot += nthreads[i];
 578        }
 579        if (tot > NFSD_MAXSERVS) {
 580                /* total too large: scale down requested numbers */
 581                for (i = 0; i < n && tot > 0; i++) {
 582                        int new = nthreads[i] * NFSD_MAXSERVS / tot;
 583                        tot -= (nthreads[i] - new);
 584                        nthreads[i] = new;
 585                }
 586                for (i = 0; i < n && tot > 0; i++) {
 587                        nthreads[i]--;
 588                        tot--;
 589                }
 590        }
 591
 592        /*
 593         * There must always be a thread in pool 0; the admin
 594         * can't shut down NFS completely using pool_threads.
 595         */
 596        if (nthreads[0] == 0)
 597                nthreads[0] = 1;
 598
 599        /* apply the new numbers */
 600        svc_get(nn->nfsd_serv);
 601        for (i = 0; i < n; i++) {
 602                err = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
 603                                &nn->nfsd_serv->sv_pools[i], nthreads[i]);
 604                if (err)
 605                        break;
 606        }
 607        nfsd_destroy(net);
 608        return err;
 609}
 610
 611/*
 612 * Adjust the number of threads and return the new number of threads.
 613 * This is also the function that starts the server if necessary, if
 614 * this is the first time nrservs is nonzero.
 615 */
 616int
 617nfsd_svc(int nrservs, struct net *net)
 618{
 619        int     error;
 620        bool    nfsd_up_before;
 621        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 622
 623        mutex_lock(&nfsd_mutex);
 624        dprintk("nfsd: creating service\n");
 625
 626        nrservs = max(nrservs, 0);
 627        nrservs = min(nrservs, NFSD_MAXSERVS);
 628        error = 0;
 629
 630        if (nrservs == 0 && nn->nfsd_serv == NULL)
 631                goto out;
 632
 633        error = nfsd_create_serv(net);
 634        if (error)
 635                goto out;
 636
 637        nfsd_up_before = nn->nfsd_net_up;
 638
 639        error = nfsd_startup_net(nrservs, net);
 640        if (error)
 641                goto out_destroy;
 642        error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
 643                        NULL, nrservs);
 644        if (error)
 645                goto out_shutdown;
 646        /* We are holding a reference to nn->nfsd_serv which
 647         * we don't want to count in the return value,
 648         * so subtract 1
 649         */
 650        error = nn->nfsd_serv->sv_nrthreads - 1;
 651out_shutdown:
 652        if (error < 0 && !nfsd_up_before)
 653                nfsd_shutdown_net(net);
 654out_destroy:
 655        nfsd_destroy(net);              /* Release server */
 656out:
 657        mutex_unlock(&nfsd_mutex);
 658        return error;
 659}
 660
 661
 662/*
 663 * This is the NFS server kernel thread
 664 */
 665static int
 666nfsd(void *vrqstp)
 667{
 668        struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
 669        struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
 670        struct net *net = perm_sock->xpt_net;
 671        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 672        int err;
 673
 674        /* Lock module and set up kernel thread */
 675        mutex_lock(&nfsd_mutex);
 676
 677        /* At this point, the thread shares current->fs
 678         * with the init process. We need to create files with the
 679         * umask as defined by the client instead of init's umask. */
 680        if (unshare_fs_struct() < 0) {
 681                printk("Unable to start nfsd thread: out of memory\n");
 682                goto out;
 683        }
 684
 685        current->fs->umask = 0;
 686
 687        /*
 688         * thread is spawned with all signals set to SIG_IGN, re-enable
 689         * the ones that will bring down the thread
 690         */
 691        allow_signal(SIGKILL);
 692        allow_signal(SIGHUP);
 693        allow_signal(SIGINT);
 694        allow_signal(SIGQUIT);
 695
 696        nfsdstats.th_cnt++;
 697        mutex_unlock(&nfsd_mutex);
 698
 699        set_freezable();
 700
 701        /*
 702         * The main request loop
 703         */
 704        for (;;) {
 705                /* Update sv_maxconn if it has changed */
 706                rqstp->rq_server->sv_maxconn = nn->max_connections;
 707
 708                /*
 709                 * Find a socket with data available and call its
 710                 * recvfrom routine.
 711                 */
 712                while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
 713                        ;
 714                if (err == -EINTR)
 715                        break;
 716                validate_process_creds();
 717                svc_process(rqstp);
 718                validate_process_creds();
 719        }
 720
 721        /* Clear signals before calling svc_exit_thread() */
 722        flush_signals(current);
 723
 724        mutex_lock(&nfsd_mutex);
 725        nfsdstats.th_cnt --;
 726
 727out:
 728        rqstp->rq_server = NULL;
 729
 730        /* Release the thread */
 731        svc_exit_thread(rqstp);
 732
 733        nfsd_destroy(net);
 734
 735        /* Release module */
 736        mutex_unlock(&nfsd_mutex);
 737        module_put_and_exit(0);
 738        return 0;
 739}
 740
 741static __be32 map_new_errors(u32 vers, __be32 nfserr)
 742{
 743        if (nfserr == nfserr_jukebox && vers == 2)
 744                return nfserr_dropit;
 745        if (nfserr == nfserr_wrongsec && vers < 4)
 746                return nfserr_acces;
 747        return nfserr;
 748}
 749
 750/*
 751 * A write procedure can have a large argument, and a read procedure can
 752 * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
 753 * reply that can both be larger than a page.  The xdr code has taken
 754 * advantage of this assumption to be a sloppy about bounds checking in
 755 * some cases.  Pending a rewrite of the NFSv2/v3 xdr code to fix that
 756 * problem, we enforce these assumptions here:
 757 */
 758static bool nfs_request_too_big(struct svc_rqst *rqstp,
 759                                const struct svc_procedure *proc)
 760{
 761        /*
 762         * The ACL code has more careful bounds-checking and is not
 763         * susceptible to this problem:
 764         */
 765        if (rqstp->rq_prog != NFS_PROGRAM)
 766                return false;
 767        /*
 768         * Ditto NFSv4 (which can in theory have argument and reply both
 769         * more than a page):
 770         */
 771        if (rqstp->rq_vers >= 4)
 772                return false;
 773        /* The reply will be small, we're OK: */
 774        if (proc->pc_xdrressize > 0 &&
 775            proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
 776                return false;
 777
 778        return rqstp->rq_arg.len > PAGE_SIZE;
 779}
 780
 781int
 782nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 783{
 784        const struct svc_procedure *proc;
 785        __be32                  nfserr;
 786        __be32                  *nfserrp;
 787
 788        dprintk("nfsd_dispatch: vers %d proc %d\n",
 789                                rqstp->rq_vers, rqstp->rq_proc);
 790        proc = rqstp->rq_procinfo;
 791
 792        if (nfs_request_too_big(rqstp, proc)) {
 793                dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
 794                *statp = rpc_garbage_args;
 795                return 1;
 796        }
 797        /*
 798         * Give the xdr decoder a chance to change this if it wants
 799         * (necessary in the NFSv4.0 compound case)
 800         */
 801        rqstp->rq_cachetype = proc->pc_cachetype;
 802        /* Decode arguments */
 803        if (proc->pc_decode &&
 804            !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) {
 805                dprintk("nfsd: failed to decode arguments!\n");
 806                *statp = rpc_garbage_args;
 807                return 1;
 808        }
 809
 810        /* Check whether we have this call in the cache. */
 811        switch (nfsd_cache_lookup(rqstp)) {
 812        case RC_DROPIT:
 813                return 0;
 814        case RC_REPLY:
 815                return 1;
 816        case RC_DOIT:;
 817                /* do it */
 818        }
 819
 820        /* need to grab the location to store the status, as
 821         * nfsv4 does some encoding while processing 
 822         */
 823        nfserrp = rqstp->rq_res.head[0].iov_base
 824                + rqstp->rq_res.head[0].iov_len;
 825        rqstp->rq_res.head[0].iov_len += sizeof(__be32);
 826
 827        /* Now call the procedure handler, and encode NFS status. */
 828        nfserr = proc->pc_func(rqstp);
 829        nfserr = map_new_errors(rqstp->rq_vers, nfserr);
 830        if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) {
 831                dprintk("nfsd: Dropping request; may be revisited later\n");
 832                nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
 833                return 0;
 834        }
 835
 836        if (rqstp->rq_proc != 0)
 837                *nfserrp++ = nfserr;
 838
 839        /* Encode result.
 840         * For NFSv2, additional info is never returned in case of an error.
 841         */
 842        if (!(nfserr && rqstp->rq_vers == 2)) {
 843                if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) {
 844                        /* Failed to encode result. Release cache entry */
 845                        dprintk("nfsd: failed to encode result!\n");
 846                        nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
 847                        *statp = rpc_system_err;
 848                        return 1;
 849                }
 850        }
 851
 852        /* Store reply in cache. */
 853        nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
 854        return 1;
 855}
 856
 857int nfsd_pool_stats_open(struct inode *inode, struct file *file)
 858{
 859        int ret;
 860        struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
 861
 862        mutex_lock(&nfsd_mutex);
 863        if (nn->nfsd_serv == NULL) {
 864                mutex_unlock(&nfsd_mutex);
 865                return -ENODEV;
 866        }
 867        /* bump up the psudo refcount while traversing */
 868        svc_get(nn->nfsd_serv);
 869        ret = svc_pool_stats_open(nn->nfsd_serv, file);
 870        mutex_unlock(&nfsd_mutex);
 871        return ret;
 872}
 873
 874int nfsd_pool_stats_release(struct inode *inode, struct file *file)
 875{
 876        int ret = seq_release(inode, file);
 877        struct net *net = inode->i_sb->s_fs_info;
 878
 879        mutex_lock(&nfsd_mutex);
 880        /* this function really, really should have been called svc_put() */
 881        nfsd_destroy(net);
 882        mutex_unlock(&nfsd_mutex);
 883        return ret;
 884}
 885