aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 17:42:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 17:42:28 -0400
commit08843b79fb35d33859e0f8f11a7318341076e4d1 (patch)
treee56e122146985b359d50787e3d1df640c4582dfa /fs/nfsd
parentcc8362b1f6d724e46f515121d442779924b19fec (diff)
parent2c142baa7b237584bae7dc28630851701497e1ef (diff)
Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from J. Bruce Fields: "This has been an unusually quiet cycle--mostly bugfixes and cleanup. The one large piece is Stanislav's work to containerize the server's grace period--but that in itself is just one more step in a not-yet-complete project to allow fully containerized nfs service. There are a number of outstanding delegation, container, v4 state, and gss patches that aren't quite ready yet; 3.7 may be wilder." * 'nfsd-next' of git://linux-nfs.org/~bfields/linux: (35 commits) NFSd: make boot_time variable per network namespace NFSd: make grace end flag per network namespace Lockd: move grace period management from lockd() to per-net functions LockD: pass actual network namespace to grace period management functions LockD: manage grace list per network namespace SUNRPC: service request network namespace helper introduced NFSd: make nfsd4_manager allocated per network namespace context. LockD: make lockd manager allocated per network namespace LockD: manage grace period per network namespace Lockd: add more debug to host shutdown functions Lockd: host complaining function introduced LockD: manage used host count per networks namespace LockD: manage garbage collection timeout per networks namespace LockD: make garbage collector network namespace aware. LockD: mark host per network namespace on garbage collect nfsd4: fix missing fault_inject.h include locks: move lease-specific code out of locks_delete_lock locks: prevent side-effects of locks_release_private before file_lock is initialized NFSd: set nfsd_serv to NULL after service destruction NFSd: introduce nfsd_destroy() helper ...
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/export.c10
-rw-r--r--fs/nfsd/netns.h4
-rw-r--r--fs/nfsd/nfs4callback.c1
-rw-r--r--fs/nfsd/nfs4idmap.c4
-rw-r--r--fs/nfsd/nfs4proc.c18
-rw-r--r--fs/nfsd/nfs4state.c201
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsctl.c8
-rw-r--r--fs/nfsd/nfsd.h13
-rw-r--r--fs/nfsd/nfssvc.c24
-rw-r--r--fs/nfsd/state.h5
-rw-r--r--fs/nfsd/vfs.c10
12 files changed, 175 insertions, 125 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index ba233499b9a5..a3946cf13fc8 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -398,7 +398,7 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
398 int migrated, i, err; 398 int migrated, i, err;
399 399
400 /* listsize */ 400 /* listsize */
401 err = get_int(mesg, &fsloc->locations_count); 401 err = get_uint(mesg, &fsloc->locations_count);
402 if (err) 402 if (err)
403 return err; 403 return err;
404 if (fsloc->locations_count > MAX_FS_LOCATIONS) 404 if (fsloc->locations_count > MAX_FS_LOCATIONS)
@@ -456,7 +456,7 @@ static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
456 return -EINVAL; 456 return -EINVAL;
457 457
458 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) { 458 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
459 err = get_int(mesg, &f->pseudoflavor); 459 err = get_uint(mesg, &f->pseudoflavor);
460 if (err) 460 if (err)
461 return err; 461 return err;
462 /* 462 /*
@@ -465,7 +465,7 @@ static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
465 * problem at export time instead of when a client fails 465 * problem at export time instead of when a client fails
466 * to authenticate. 466 * to authenticate.
467 */ 467 */
468 err = get_int(mesg, &f->flags); 468 err = get_uint(mesg, &f->flags);
469 if (err) 469 if (err)
470 return err; 470 return err;
471 /* Only some flags are allowed to differ between flavors: */ 471 /* Only some flags are allowed to differ between flavors: */
@@ -929,7 +929,7 @@ struct svc_export *
929rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) 929rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
930{ 930{
931 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 931 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
932 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); 932 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
933 struct cache_detail *cd = nn->svc_export_cache; 933 struct cache_detail *cd = nn->svc_export_cache;
934 934
935 if (rqstp->rq_client == NULL) 935 if (rqstp->rq_client == NULL)
@@ -960,7 +960,7 @@ struct svc_export *
960rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) 960rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
961{ 961{
962 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 962 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
963 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); 963 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
964 struct cache_detail *cd = nn->svc_export_cache; 964 struct cache_detail *cd = nn->svc_export_cache;
965 965
966 if (rqstp->rq_client == NULL) 966 if (rqstp->rq_client == NULL)
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 39365636b244..65c2431ea32f 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -34,6 +34,10 @@ struct nfsd_net {
34 34
35 struct cache_detail *idtoname_cache; 35 struct cache_detail *idtoname_cache;
36 struct cache_detail *nametoid_cache; 36 struct cache_detail *nametoid_cache;
37
38 struct lock_manager nfsd4_manager;
39 bool grace_ended;
40 time_t boot_time;
37}; 41};
38 42
39extern int nfsd_net_id; 43extern int nfsd_net_id;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index a5fd6b982f27..cbaf4f8bb7b7 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -756,7 +756,6 @@ static void do_probe_callback(struct nfs4_client *clp)
756 */ 756 */
757void nfsd4_probe_callback(struct nfs4_client *clp) 757void nfsd4_probe_callback(struct nfs4_client *clp)
758{ 758{
759 /* XXX: atomicity? Also, should we be using cl_flags? */
760 clp->cl_cb_state = NFSD4_CB_UNKNOWN; 759 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
761 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags); 760 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
762 do_probe_callback(clp); 761 do_probe_callback(clp);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index dae36f1dee95..fdc91a6fc9c4 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -546,7 +546,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
546 .type = type, 546 .type = type,
547 }; 547 };
548 int ret; 548 int ret;
549 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); 549 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
550 550
551 if (namelen + 1 > sizeof(key.name)) 551 if (namelen + 1 > sizeof(key.name))
552 return nfserr_badowner; 552 return nfserr_badowner;
@@ -571,7 +571,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
571 .type = type, 571 .type = type,
572 }; 572 };
573 int ret; 573 int ret;
574 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); 574 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
575 575
576 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 576 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
577 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); 577 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 987e719fbae8..c9c1c0a25417 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -354,10 +354,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
354 /* Openowner is now set, so sequence id will get bumped. Now we need 354 /* Openowner is now set, so sequence id will get bumped. Now we need
355 * these checks before we do any creates: */ 355 * these checks before we do any creates: */
356 status = nfserr_grace; 356 status = nfserr_grace;
357 if (locks_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 357 if (locks_in_grace(SVC_NET(rqstp)) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
358 goto out; 358 goto out;
359 status = nfserr_no_grace; 359 status = nfserr_no_grace;
360 if (!locks_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 360 if (!locks_in_grace(SVC_NET(rqstp)) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
361 goto out; 361 goto out;
362 362
363 switch (open->op_claim_type) { 363 switch (open->op_claim_type) {
@@ -686,7 +686,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
686 686
687 nfs4_lock_state(); 687 nfs4_lock_state();
688 /* check stateid */ 688 /* check stateid */
689 if ((status = nfs4_preprocess_stateid_op(cstate, &read->rd_stateid, 689 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
690 cstate, &read->rd_stateid,
690 RD_STATE, &read->rd_filp))) { 691 RD_STATE, &read->rd_filp))) {
691 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 692 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
692 goto out; 693 goto out;
@@ -741,7 +742,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
741{ 742{
742 __be32 status; 743 __be32 status;
743 744
744 if (locks_in_grace()) 745 if (locks_in_grace(SVC_NET(rqstp)))
745 return nfserr_grace; 746 return nfserr_grace;
746 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 747 status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
747 remove->rm_name, remove->rm_namelen); 748 remove->rm_name, remove->rm_namelen);
@@ -760,8 +761,8 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
760 761
761 if (!cstate->save_fh.fh_dentry) 762 if (!cstate->save_fh.fh_dentry)
762 return status; 763 return status;
763 if (locks_in_grace() && !(cstate->save_fh.fh_export->ex_flags 764 if (locks_in_grace(SVC_NET(rqstp)) &&
764 & NFSEXP_NOSUBTREECHECK)) 765 !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
765 return nfserr_grace; 766 return nfserr_grace;
766 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 767 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
767 rename->rn_snamelen, &cstate->current_fh, 768 rename->rn_snamelen, &cstate->current_fh,
@@ -845,7 +846,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
845 846
846 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 847 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
847 nfs4_lock_state(); 848 nfs4_lock_state();
848 status = nfs4_preprocess_stateid_op(cstate, 849 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
849 &setattr->sa_stateid, WR_STATE, NULL); 850 &setattr->sa_stateid, WR_STATE, NULL);
850 nfs4_unlock_state(); 851 nfs4_unlock_state();
851 if (status) { 852 if (status) {
@@ -890,7 +891,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
890 return nfserr_inval; 891 return nfserr_inval;
891 892
892 nfs4_lock_state(); 893 nfs4_lock_state();
893 status = nfs4_preprocess_stateid_op(cstate, stateid, WR_STATE, &filp); 894 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
895 cstate, stateid, WR_STATE, &filp);
894 if (filp) 896 if (filp)
895 get_file(filp); 897 get_file(filp);
896 nfs4_unlock_state(); 898 nfs4_unlock_state();
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 94effd5bc4a1..cc894eda385a 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -38,18 +38,21 @@
38#include <linux/namei.h> 38#include <linux/namei.h>
39#include <linux/swap.h> 39#include <linux/swap.h>
40#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/ratelimit.h>
41#include <linux/sunrpc/svcauth_gss.h> 42#include <linux/sunrpc/svcauth_gss.h>
42#include <linux/sunrpc/clnt.h> 43#include <linux/sunrpc/clnt.h>
43#include "xdr4.h" 44#include "xdr4.h"
44#include "vfs.h" 45#include "vfs.h"
45#include "current_stateid.h" 46#include "current_stateid.h"
47#include "fault_inject.h"
48
49#include "netns.h"
46 50
47#define NFSDDBG_FACILITY NFSDDBG_PROC 51#define NFSDDBG_FACILITY NFSDDBG_PROC
48 52
49/* Globals */ 53/* Globals */
50time_t nfsd4_lease = 90; /* default lease time */ 54time_t nfsd4_lease = 90; /* default lease time */
51time_t nfsd4_grace = 90; 55time_t nfsd4_grace = 90;
52static time_t boot_time;
53 56
54#define all_ones {{~0,~0},~0} 57#define all_ones {{~0,~0},~0}
55static const stateid_t one_stateid = { 58static const stateid_t one_stateid = {
@@ -862,6 +865,11 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses,
862 if (ret) 865 if (ret)
863 /* oops; xprt is already down: */ 866 /* oops; xprt is already down: */
864 nfsd4_conn_lost(&conn->cn_xpt_user); 867 nfsd4_conn_lost(&conn->cn_xpt_user);
868 if (ses->se_client->cl_cb_state == NFSD4_CB_DOWN &&
869 dir & NFS4_CDFC4_BACK) {
870 /* callback channel may be back up */
871 nfsd4_probe_callback(ses->se_client);
872 }
865 return nfs_ok; 873 return nfs_ok;
866} 874}
867 875
@@ -1047,12 +1055,12 @@ renew_client(struct nfs4_client *clp)
1047 1055
1048/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */ 1056/* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
1049static int 1057static int
1050STALE_CLIENTID(clientid_t *clid) 1058STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
1051{ 1059{
1052 if (clid->cl_boot == boot_time) 1060 if (clid->cl_boot == nn->boot_time)
1053 return 0; 1061 return 0;
1054 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n", 1062 dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
1055 clid->cl_boot, clid->cl_id, boot_time); 1063 clid->cl_boot, clid->cl_id, nn->boot_time);
1056 return 1; 1064 return 1;
1057} 1065}
1058 1066
@@ -1215,7 +1223,7 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
1215 return true; 1223 return true;
1216} 1224}
1217 1225
1218static int 1226static bool
1219same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1227same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1220{ 1228{
1221 if ((cr1->cr_flavor != cr2->cr_flavor) 1229 if ((cr1->cr_flavor != cr2->cr_flavor)
@@ -1227,14 +1235,15 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1227 return true; 1235 return true;
1228 if (!cr1->cr_principal || !cr2->cr_principal) 1236 if (!cr1->cr_principal || !cr2->cr_principal)
1229 return false; 1237 return false;
1230 return 0 == strcmp(cr1->cr_principal, cr1->cr_principal); 1238 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
1231} 1239}
1232 1240
1233static void gen_clid(struct nfs4_client *clp) 1241static void gen_clid(struct nfs4_client *clp)
1234{ 1242{
1235 static u32 current_clientid = 1; 1243 static u32 current_clientid = 1;
1244 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
1236 1245
1237 clp->cl_clientid.cl_boot = boot_time; 1246 clp->cl_clientid.cl_boot = nn->boot_time;
1238 clp->cl_clientid.cl_id = current_clientid++; 1247 clp->cl_clientid.cl_id = current_clientid++;
1239} 1248}
1240 1249
@@ -2217,8 +2226,9 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2217 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 2226 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
2218 clientid_t * clid = &setclientid_confirm->sc_clientid; 2227 clientid_t * clid = &setclientid_confirm->sc_clientid;
2219 __be32 status; 2228 __be32 status;
2229 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
2220 2230
2221 if (STALE_CLIENTID(clid)) 2231 if (STALE_CLIENTID(clid, nn))
2222 return nfserr_stale_clientid; 2232 return nfserr_stale_clientid;
2223 nfs4_lock_state(); 2233 nfs4_lock_state();
2224 2234
@@ -2577,8 +2587,9 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2577 unsigned int strhashval; 2587 unsigned int strhashval;
2578 struct nfs4_openowner *oo = NULL; 2588 struct nfs4_openowner *oo = NULL;
2579 __be32 status; 2589 __be32 status;
2590 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
2580 2591
2581 if (STALE_CLIENTID(&open->op_clientid)) 2592 if (STALE_CLIENTID(&open->op_clientid, nn))
2582 return nfserr_stale_clientid; 2593 return nfserr_stale_clientid;
2583 /* 2594 /*
2584 * In case we need it later, after we've already created the 2595 * In case we need it later, after we've already created the
@@ -2876,7 +2887,8 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
2876 * Attempt to hand out a delegation. 2887 * Attempt to hand out a delegation.
2877 */ 2888 */
2878static void 2889static void
2879nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_stateid *stp) 2890nfs4_open_delegation(struct net *net, struct svc_fh *fh,
2891 struct nfsd4_open *open, struct nfs4_ol_stateid *stp)
2880{ 2892{
2881 struct nfs4_delegation *dp; 2893 struct nfs4_delegation *dp;
2882 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 2894 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
@@ -2897,7 +2909,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_
2897 case NFS4_OPEN_CLAIM_NULL: 2909 case NFS4_OPEN_CLAIM_NULL:
2898 /* Let's not give out any delegations till everyone's 2910 /* Let's not give out any delegations till everyone's
2899 * had the chance to reclaim theirs.... */ 2911 * had the chance to reclaim theirs.... */
2900 if (locks_in_grace()) 2912 if (locks_in_grace(net))
2901 goto out; 2913 goto out;
2902 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) 2914 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
2903 goto out; 2915 goto out;
@@ -3007,14 +3019,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
3007 status = nfs4_get_vfs_file(rqstp, fp, current_fh, open); 3019 status = nfs4_get_vfs_file(rqstp, fp, current_fh, open);
3008 if (status) 3020 if (status)
3009 goto out; 3021 goto out;
3022 status = nfsd4_truncate(rqstp, current_fh, open);
3023 if (status)
3024 goto out;
3010 stp = open->op_stp; 3025 stp = open->op_stp;
3011 open->op_stp = NULL; 3026 open->op_stp = NULL;
3012 init_open_stateid(stp, fp, open); 3027 init_open_stateid(stp, fp, open);
3013 status = nfsd4_truncate(rqstp, current_fh, open);
3014 if (status) {
3015 release_open_stateid(stp);
3016 goto out;
3017 }
3018 } 3028 }
3019 update_stateid(&stp->st_stid.sc_stateid); 3029 update_stateid(&stp->st_stid.sc_stateid);
3020 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3030 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
@@ -3033,7 +3043,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
3033 * Attempt to hand out a delegation. No error return, because the 3043 * Attempt to hand out a delegation. No error return, because the
3034 * OPEN succeeds even if we fail. 3044 * OPEN succeeds even if we fail.
3035 */ 3045 */
3036 nfs4_open_delegation(current_fh, open, stp); 3046 nfs4_open_delegation(SVC_NET(rqstp), current_fh, open, stp);
3037nodeleg: 3047nodeleg:
3038 status = nfs_ok; 3048 status = nfs_ok;
3039 3049
@@ -3087,12 +3097,13 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3087{ 3097{
3088 struct nfs4_client *clp; 3098 struct nfs4_client *clp;
3089 __be32 status; 3099 __be32 status;
3100 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
3090 3101
3091 nfs4_lock_state(); 3102 nfs4_lock_state();
3092 dprintk("process_renew(%08x/%08x): starting\n", 3103 dprintk("process_renew(%08x/%08x): starting\n",
3093 clid->cl_boot, clid->cl_id); 3104 clid->cl_boot, clid->cl_id);
3094 status = nfserr_stale_clientid; 3105 status = nfserr_stale_clientid;
3095 if (STALE_CLIENTID(clid)) 3106 if (STALE_CLIENTID(clid, nn))
3096 goto out; 3107 goto out;
3097 clp = find_confirmed_client(clid); 3108 clp = find_confirmed_client(clid);
3098 status = nfserr_expired; 3109 status = nfserr_expired;
@@ -3111,22 +3122,19 @@ out:
3111 return status; 3122 return status;
3112} 3123}
3113 3124
3114static struct lock_manager nfsd4_manager = {
3115};
3116
3117static bool grace_ended;
3118
3119static void 3125static void
3120nfsd4_end_grace(void) 3126nfsd4_end_grace(struct net *net)
3121{ 3127{
3128 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3129
3122 /* do nothing if grace period already ended */ 3130 /* do nothing if grace period already ended */
3123 if (grace_ended) 3131 if (nn->grace_ended)
3124 return; 3132 return;
3125 3133
3126 dprintk("NFSD: end of grace period\n"); 3134 dprintk("NFSD: end of grace period\n");
3127 grace_ended = true; 3135 nn->grace_ended = true;
3128 nfsd4_record_grace_done(&init_net, boot_time); 3136 nfsd4_record_grace_done(net, nn->boot_time);
3129 locks_end_grace(&nfsd4_manager); 3137 locks_end_grace(&nn->nfsd4_manager);
3130 /* 3138 /*
3131 * Now that every NFSv4 client has had the chance to recover and 3139 * Now that every NFSv4 client has had the chance to recover and
3132 * to see the (possibly new, possibly shorter) lease time, we 3140 * to see the (possibly new, possibly shorter) lease time, we
@@ -3149,7 +3157,7 @@ nfs4_laundromat(void)
3149 nfs4_lock_state(); 3157 nfs4_lock_state();
3150 3158
3151 dprintk("NFSD: laundromat service - starting\n"); 3159 dprintk("NFSD: laundromat service - starting\n");
3152 nfsd4_end_grace(); 3160 nfsd4_end_grace(&init_net);
3153 INIT_LIST_HEAD(&reaplist); 3161 INIT_LIST_HEAD(&reaplist);
3154 spin_lock(&client_lock); 3162 spin_lock(&client_lock);
3155 list_for_each_safe(pos, next, &client_lru) { 3163 list_for_each_safe(pos, next, &client_lru) {
@@ -3231,9 +3239,9 @@ static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *s
3231} 3239}
3232 3240
3233static int 3241static int
3234STALE_STATEID(stateid_t *stateid) 3242STALE_STATEID(stateid_t *stateid, struct nfsd_net *nn)
3235{ 3243{
3236 if (stateid->si_opaque.so_clid.cl_boot == boot_time) 3244 if (stateid->si_opaque.so_clid.cl_boot == nn->boot_time)
3237 return 0; 3245 return 0;
3238 dprintk("NFSD: stale stateid " STATEID_FMT "!\n", 3246 dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
3239 STATEID_VAL(stateid)); 3247 STATEID_VAL(stateid));
@@ -3273,11 +3281,11 @@ out:
3273} 3281}
3274 3282
3275static inline __be32 3283static inline __be32
3276check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) 3284check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid, int flags)
3277{ 3285{
3278 if (ONE_STATEID(stateid) && (flags & RD_STATE)) 3286 if (ONE_STATEID(stateid) && (flags & RD_STATE))
3279 return nfs_ok; 3287 return nfs_ok;
3280 else if (locks_in_grace()) { 3288 else if (locks_in_grace(net)) {
3281 /* Answer in remaining cases depends on existence of 3289 /* Answer in remaining cases depends on existence of
3282 * conflicting state; so we must wait out the grace period. */ 3290 * conflicting state; so we must wait out the grace period. */
3283 return nfserr_grace; 3291 return nfserr_grace;
@@ -3294,9 +3302,9 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
3294 * that are not able to provide mandatory locking. 3302 * that are not able to provide mandatory locking.
3295 */ 3303 */
3296static inline int 3304static inline int
3297grace_disallows_io(struct inode *inode) 3305grace_disallows_io(struct net *net, struct inode *inode)
3298{ 3306{
3299 return locks_in_grace() && mandatory_lock(inode); 3307 return locks_in_grace(net) && mandatory_lock(inode);
3300} 3308}
3301 3309
3302/* Returns true iff a is later than b: */ 3310/* Returns true iff a is later than b: */
@@ -3333,18 +3341,26 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s
3333 return nfserr_old_stateid; 3341 return nfserr_old_stateid;
3334} 3342}
3335 3343
3336__be32 nfs4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) 3344static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
3337{ 3345{
3338 struct nfs4_stid *s; 3346 struct nfs4_stid *s;
3339 struct nfs4_ol_stateid *ols; 3347 struct nfs4_ol_stateid *ols;
3340 __be32 status; 3348 __be32 status;
3341 3349
3342 if (STALE_STATEID(stateid)) 3350 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3343 return nfserr_stale_stateid; 3351 return nfserr_bad_stateid;
3344 3352 /* Client debugging aid. */
3353 if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) {
3354 char addr_str[INET6_ADDRSTRLEN];
3355 rpc_ntop((struct sockaddr *)&cl->cl_addr, addr_str,
3356 sizeof(addr_str));
3357 pr_warn_ratelimited("NFSD: client %s testing state ID "
3358 "with incorrect client ID\n", addr_str);
3359 return nfserr_bad_stateid;
3360 }
3345 s = find_stateid(cl, stateid); 3361 s = find_stateid(cl, stateid);
3346 if (!s) 3362 if (!s)
3347 return nfserr_stale_stateid; 3363 return nfserr_bad_stateid;
3348 status = check_stateid_generation(stateid, &s->sc_stateid, 1); 3364 status = check_stateid_generation(stateid, &s->sc_stateid, 1);
3349 if (status) 3365 if (status)
3350 return status; 3366 return status;
@@ -3360,10 +3376,11 @@ __be32 nfs4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
3360static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s) 3376static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s)
3361{ 3377{
3362 struct nfs4_client *cl; 3378 struct nfs4_client *cl;
3379 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
3363 3380
3364 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3381 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3365 return nfserr_bad_stateid; 3382 return nfserr_bad_stateid;
3366 if (STALE_STATEID(stateid)) 3383 if (STALE_STATEID(stateid, nn))
3367 return nfserr_stale_stateid; 3384 return nfserr_stale_stateid;
3368 cl = find_confirmed_client(&stateid->si_opaque.so_clid); 3385 cl = find_confirmed_client(&stateid->si_opaque.so_clid);
3369 if (!cl) 3386 if (!cl)
@@ -3379,7 +3396,7 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, s
3379* Checks for stateid operations 3396* Checks for stateid operations
3380*/ 3397*/
3381__be32 3398__be32
3382nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, 3399nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3383 stateid_t *stateid, int flags, struct file **filpp) 3400 stateid_t *stateid, int flags, struct file **filpp)
3384{ 3401{
3385 struct nfs4_stid *s; 3402 struct nfs4_stid *s;
@@ -3392,11 +3409,11 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3392 if (filpp) 3409 if (filpp)
3393 *filpp = NULL; 3410 *filpp = NULL;
3394 3411
3395 if (grace_disallows_io(ino)) 3412 if (grace_disallows_io(net, ino))
3396 return nfserr_grace; 3413 return nfserr_grace;
3397 3414
3398 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3415 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3399 return check_special_stateids(current_fh, stateid, flags); 3416 return check_special_stateids(net, current_fh, stateid, flags);
3400 3417
3401 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s); 3418 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s);
3402 if (status) 3419 if (status)
@@ -3463,7 +3480,8 @@ nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3463 3480
3464 nfs4_lock_state(); 3481 nfs4_lock_state();
3465 list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list) 3482 list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
3466 stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid); 3483 stateid->ts_id_status =
3484 nfsd4_validate_stateid(cl, &stateid->ts_id_stateid);
3467 nfs4_unlock_state(); 3485 nfs4_unlock_state();
3468 3486
3469 return nfs_ok; 3487 return nfs_ok;
@@ -3750,12 +3768,19 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3750 nfsd4_close_open_stateid(stp); 3768 nfsd4_close_open_stateid(stp);
3751 oo->oo_last_closed_stid = stp; 3769 oo->oo_last_closed_stid = stp;
3752 3770
3753 /* place unused nfs4_stateowners on so_close_lru list to be 3771 if (list_empty(&oo->oo_owner.so_stateids)) {
3754 * released by the laundromat service after the lease period 3772 if (cstate->minorversion) {
3755 * to enable us to handle CLOSE replay 3773 release_openowner(oo);
3756 */ 3774 cstate->replay_owner = NULL;
3757 if (list_empty(&oo->oo_owner.so_stateids)) 3775 } else {
3758 move_to_close_lru(oo); 3776 /*
3777 * In the 4.0 case we need to keep the owners around a
3778 * little while to handle CLOSE replay.
3779 */
3780 if (list_empty(&oo->oo_owner.so_stateids))
3781 move_to_close_lru(oo);
3782 }
3783 }
3759out: 3784out:
3760 if (!cstate->replay_owner) 3785 if (!cstate->replay_owner)
3761 nfs4_unlock_state(); 3786 nfs4_unlock_state();
@@ -4027,6 +4052,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4027 bool new_state = false; 4052 bool new_state = false;
4028 int lkflg; 4053 int lkflg;
4029 int err; 4054 int err;
4055 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
4030 4056
4031 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 4057 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
4032 (long long) lock->lk_offset, 4058 (long long) lock->lk_offset,
@@ -4044,11 +4070,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4044 nfs4_lock_state(); 4070 nfs4_lock_state();
4045 4071
4046 if (lock->lk_is_new) { 4072 if (lock->lk_is_new) {
4047 /*
4048 * Client indicates that this is a new lockowner.
4049 * Use open owner and open stateid to create lock owner and
4050 * lock stateid.
4051 */
4052 struct nfs4_ol_stateid *open_stp = NULL; 4073 struct nfs4_ol_stateid *open_stp = NULL;
4053 4074
4054 if (nfsd4_has_session(cstate)) 4075 if (nfsd4_has_session(cstate))
@@ -4058,7 +4079,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4058 sizeof(clientid_t)); 4079 sizeof(clientid_t));
4059 4080
4060 status = nfserr_stale_clientid; 4081 status = nfserr_stale_clientid;
4061 if (STALE_CLIENTID(&lock->lk_new_clientid)) 4082 if (STALE_CLIENTID(&lock->lk_new_clientid, nn))
4062 goto out; 4083 goto out;
4063 4084
4064 /* validate and update open stateid and open seqid */ 4085 /* validate and update open stateid and open seqid */
@@ -4075,17 +4096,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4075 goto out; 4096 goto out;
4076 status = lookup_or_create_lock_state(cstate, open_stp, lock, 4097 status = lookup_or_create_lock_state(cstate, open_stp, lock,
4077 &lock_stp, &new_state); 4098 &lock_stp, &new_state);
4078 if (status) 4099 } else
4079 goto out;
4080 } else {
4081 /* lock (lock owner + lock stateid) already exists */
4082 status = nfs4_preprocess_seqid_op(cstate, 4100 status = nfs4_preprocess_seqid_op(cstate,
4083 lock->lk_old_lock_seqid, 4101 lock->lk_old_lock_seqid,
4084 &lock->lk_old_lock_stateid, 4102 &lock->lk_old_lock_stateid,
4085 NFS4_LOCK_STID, &lock_stp); 4103 NFS4_LOCK_STID, &lock_stp);
4086 if (status) 4104 if (status)
4087 goto out; 4105 goto out;
4088 }
4089 lock_sop = lockowner(lock_stp->st_stateowner); 4106 lock_sop = lockowner(lock_stp->st_stateowner);
4090 4107
4091 lkflg = setlkflg(lock->lk_type); 4108 lkflg = setlkflg(lock->lk_type);
@@ -4094,10 +4111,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4094 goto out; 4111 goto out;
4095 4112
4096 status = nfserr_grace; 4113 status = nfserr_grace;
4097 if (locks_in_grace() && !lock->lk_reclaim) 4114 if (locks_in_grace(SVC_NET(rqstp)) && !lock->lk_reclaim)
4098 goto out; 4115 goto out;
4099 status = nfserr_no_grace; 4116 status = nfserr_no_grace;
4100 if (!locks_in_grace() && lock->lk_reclaim) 4117 if (!locks_in_grace(SVC_NET(rqstp)) && lock->lk_reclaim)
4101 goto out; 4118 goto out;
4102 4119
4103 locks_init_lock(&file_lock); 4120 locks_init_lock(&file_lock);
@@ -4196,8 +4213,9 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4196 struct file_lock file_lock; 4213 struct file_lock file_lock;
4197 struct nfs4_lockowner *lo; 4214 struct nfs4_lockowner *lo;
4198 __be32 status; 4215 __be32 status;
4216 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
4199 4217
4200 if (locks_in_grace()) 4218 if (locks_in_grace(SVC_NET(rqstp)))
4201 return nfserr_grace; 4219 return nfserr_grace;
4202 4220
4203 if (check_lock_length(lockt->lt_offset, lockt->lt_length)) 4221 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
@@ -4206,7 +4224,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4206 nfs4_lock_state(); 4224 nfs4_lock_state();
4207 4225
4208 status = nfserr_stale_clientid; 4226 status = nfserr_stale_clientid;
4209 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid)) 4227 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid, nn))
4210 goto out; 4228 goto out;
4211 4229
4212 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 4230 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
@@ -4355,6 +4373,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4355 struct list_head matches; 4373 struct list_head matches;
4356 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner); 4374 unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
4357 __be32 status; 4375 __be32 status;
4376 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
4358 4377
4359 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 4378 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
4360 clid->cl_boot, clid->cl_id); 4379 clid->cl_boot, clid->cl_id);
@@ -4362,7 +4381,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4362 /* XXX check for lease expiration */ 4381 /* XXX check for lease expiration */
4363 4382
4364 status = nfserr_stale_clientid; 4383 status = nfserr_stale_clientid;
4365 if (STALE_CLIENTID(clid)) 4384 if (STALE_CLIENTID(clid, nn))
4366 return status; 4385 return status;
4367 4386
4368 nfs4_lock_state(); 4387 nfs4_lock_state();
@@ -4564,7 +4583,7 @@ void nfsd_forget_openowners(u64 num)
4564 printk(KERN_INFO "NFSD: Forgot %d open owners", count); 4583 printk(KERN_INFO "NFSD: Forgot %d open owners", count);
4565} 4584}
4566 4585
4567int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *)) 4586int nfsd_process_n_delegations(u64 num, struct list_head *list)
4568{ 4587{
4569 int i, count = 0; 4588 int i, count = 0;
4570 struct nfs4_file *fp, *fnext; 4589 struct nfs4_file *fp, *fnext;
@@ -4573,7 +4592,7 @@ int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegatio
4573 for (i = 0; i < FILE_HASH_SIZE; i++) { 4592 for (i = 0; i < FILE_HASH_SIZE; i++) {
4574 list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) { 4593 list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) {
4575 list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) { 4594 list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) {
4576 deleg_func(dp); 4595 list_move(&dp->dl_recall_lru, list);
4577 if (++count == num) 4596 if (++count == num)
4578 return count; 4597 return count;
4579 } 4598 }
@@ -4586,9 +4605,16 @@ int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegatio
4586void nfsd_forget_delegations(u64 num) 4605void nfsd_forget_delegations(u64 num)
4587{ 4606{
4588 unsigned int count; 4607 unsigned int count;
4608 LIST_HEAD(victims);
4609 struct nfs4_delegation *dp, *dnext;
4610
4611 spin_lock(&recall_lock);
4612 count = nfsd_process_n_delegations(num, &victims);
4613 spin_unlock(&recall_lock);
4589 4614
4590 nfs4_lock_state(); 4615 nfs4_lock_state();
4591 count = nfsd_process_n_delegations(num, unhash_delegation); 4616 list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru)
4617 unhash_delegation(dp);
4592 nfs4_unlock_state(); 4618 nfs4_unlock_state();
4593 4619
4594 printk(KERN_INFO "NFSD: Forgot %d delegations", count); 4620 printk(KERN_INFO "NFSD: Forgot %d delegations", count);
@@ -4597,12 +4623,16 @@ void nfsd_forget_delegations(u64 num)
4597void nfsd_recall_delegations(u64 num) 4623void nfsd_recall_delegations(u64 num)
4598{ 4624{
4599 unsigned int count; 4625 unsigned int count;
4626 LIST_HEAD(victims);
4627 struct nfs4_delegation *dp, *dnext;
4600 4628
4601 nfs4_lock_state();
4602 spin_lock(&recall_lock); 4629 spin_lock(&recall_lock);
4603 count = nfsd_process_n_delegations(num, nfsd_break_one_deleg); 4630 count = nfsd_process_n_delegations(num, &victims);
4631 list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru) {
4632 list_del(&dp->dl_recall_lru);
4633 nfsd_break_one_deleg(dp);
4634 }
4604 spin_unlock(&recall_lock); 4635 spin_unlock(&recall_lock);
4605 nfs4_unlock_state();
4606 4636
4607 printk(KERN_INFO "NFSD: Recalled %d delegations", count); 4637 printk(KERN_INFO "NFSD: Recalled %d delegations", count);
4608} 4638}
@@ -4665,6 +4695,8 @@ set_max_delegations(void)
4665int 4695int
4666nfs4_state_start(void) 4696nfs4_state_start(void)
4667{ 4697{
4698 struct net *net = &init_net;
4699 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4668 int ret; 4700 int ret;
4669 4701
4670 /* 4702 /*
@@ -4674,11 +4706,11 @@ nfs4_state_start(void)
4674 * to that instead and then do most of the rest of this on a per-net 4706 * to that instead and then do most of the rest of this on a per-net
4675 * basis. 4707 * basis.
4676 */ 4708 */
4677 get_net(&init_net); 4709 get_net(net);
4678 nfsd4_client_tracking_init(&init_net); 4710 nfsd4_client_tracking_init(net);
4679 boot_time = get_seconds(); 4711 nn->boot_time = get_seconds();
4680 locks_start_grace(&nfsd4_manager); 4712 locks_start_grace(net, &nn->nfsd4_manager);
4681 grace_ended = false; 4713 nn->grace_ended = false;
4682 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4714 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4683 nfsd4_grace); 4715 nfsd4_grace);
4684 ret = set_callback_cred(); 4716 ret = set_callback_cred();
@@ -4700,8 +4732,8 @@ nfs4_state_start(void)
4700out_free_laundry: 4732out_free_laundry:
4701 destroy_workqueue(laundry_wq); 4733 destroy_workqueue(laundry_wq);
4702out_recovery: 4734out_recovery:
4703 nfsd4_client_tracking_exit(&init_net); 4735 nfsd4_client_tracking_exit(net);
4704 put_net(&init_net); 4736 put_net(net);
4705 return ret; 4737 return ret;
4706} 4738}
4707 4739
@@ -4742,9 +4774,12 @@ __nfs4_state_shutdown(void)
4742void 4774void
4743nfs4_state_shutdown(void) 4775nfs4_state_shutdown(void)
4744{ 4776{
4777 struct net *net = &init_net;
4778 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4779
4745 cancel_delayed_work_sync(&laundromat_work); 4780 cancel_delayed_work_sync(&laundromat_work);
4746 destroy_workqueue(laundry_wq); 4781 destroy_workqueue(laundry_wq);
4747 locks_end_grace(&nfsd4_manager); 4782 locks_end_grace(&nn->nfsd4_manager);
4748 nfs4_lock_state(); 4783 nfs4_lock_state();
4749 __nfs4_state_shutdown(); 4784 __nfs4_state_shutdown();
4750 nfs4_unlock_state(); 4785 nfs4_unlock_state();
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4949667c84ea..6322df36031f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2259,7 +2259,7 @@ out_acl:
2259 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { 2259 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2260 if ((buflen -= 4) < 0) 2260 if ((buflen -= 4) < 0)
2261 goto out_resource; 2261 goto out_resource;
2262 WRITE32(1); 2262 WRITE32(0);
2263 } 2263 }
2264 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { 2264 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2265 if ((buflen -= 4) < 0) 2265 if ((buflen -= 4) < 0)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index c55298ed5772..fa49cff5ee65 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -673,9 +673,7 @@ static ssize_t __write_ports_addfd(char *buf)
673 673
674 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 674 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
675 if (err < 0) { 675 if (err < 0) {
676 if (nfsd_serv->sv_nrthreads == 1) 676 nfsd_destroy(net);
677 svc_shutdown_net(nfsd_serv, net);
678 svc_destroy(nfsd_serv);
679 return err; 677 return err;
680 } 678 }
681 679
@@ -744,9 +742,7 @@ out_close:
744 svc_xprt_put(xprt); 742 svc_xprt_put(xprt);
745 } 743 }
746out_err: 744out_err:
747 if (nfsd_serv->sv_nrthreads == 1) 745 nfsd_destroy(net);
748 svc_shutdown_net(nfsd_serv, net);
749 svc_destroy(nfsd_serv);
750 return err; 746 return err;
751} 747}
752 748
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 1671429ffa66..2244222368ab 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -72,6 +72,19 @@ int nfsd_nrthreads(void);
72int nfsd_nrpools(void); 72int nfsd_nrpools(void);
73int nfsd_get_nrthreads(int n, int *); 73int nfsd_get_nrthreads(int n, int *);
74int nfsd_set_nrthreads(int n, int *); 74int nfsd_set_nrthreads(int n, int *);
75int nfsd_pool_stats_open(struct inode *, struct file *);
76int nfsd_pool_stats_release(struct inode *, struct file *);
77
78static inline void nfsd_destroy(struct net *net)
79{
80 int destroy = (nfsd_serv->sv_nrthreads == 1);
81
82 if (destroy)
83 svc_shutdown_net(nfsd_serv, net);
84 svc_destroy(nfsd_serv);
85 if (destroy)
86 nfsd_serv = NULL;
87}
75 88
76#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 89#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
77#ifdef CONFIG_NFSD_V2_ACL 90#ifdef CONFIG_NFSD_V2_ACL
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ee709fc8f58b..240473cb708f 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -254,8 +254,6 @@ static void nfsd_shutdown(void)
254 254
255static void nfsd_last_thread(struct svc_serv *serv, struct net *net) 255static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
256{ 256{
257 /* When last nfsd thread exits we need to do some clean-up */
258 nfsd_serv = NULL;
259 nfsd_shutdown(); 257 nfsd_shutdown();
260 258
261 svc_rpcb_cleanup(serv, net); 259 svc_rpcb_cleanup(serv, net);
@@ -332,6 +330,7 @@ static int nfsd_get_default_max_blksize(void)
332int nfsd_create_serv(void) 330int nfsd_create_serv(void)
333{ 331{
334 int error; 332 int error;
333 struct net *net = current->nsproxy->net_ns;
335 334
336 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 335 WARN_ON(!mutex_is_locked(&nfsd_mutex));
337 if (nfsd_serv) { 336 if (nfsd_serv) {
@@ -346,7 +345,7 @@ int nfsd_create_serv(void)
346 if (nfsd_serv == NULL) 345 if (nfsd_serv == NULL)
347 return -ENOMEM; 346 return -ENOMEM;
348 347
349 error = svc_bind(nfsd_serv, current->nsproxy->net_ns); 348 error = svc_bind(nfsd_serv, net);
350 if (error < 0) { 349 if (error < 0) {
351 svc_destroy(nfsd_serv); 350 svc_destroy(nfsd_serv);
352 return error; 351 return error;
@@ -427,11 +426,7 @@ int nfsd_set_nrthreads(int n, int *nthreads)
427 if (err) 426 if (err)
428 break; 427 break;
429 } 428 }
430 429 nfsd_destroy(net);
431 if (nfsd_serv->sv_nrthreads == 1)
432 svc_shutdown_net(nfsd_serv, net);
433 svc_destroy(nfsd_serv);
434
435 return err; 430 return err;
436} 431}
437 432
@@ -478,9 +473,7 @@ out_shutdown:
478 if (error < 0 && !nfsd_up_before) 473 if (error < 0 && !nfsd_up_before)
479 nfsd_shutdown(); 474 nfsd_shutdown();
480out_destroy: 475out_destroy:
481 if (nfsd_serv->sv_nrthreads == 1) 476 nfsd_destroy(net); /* Release server */
482 svc_shutdown_net(nfsd_serv, net);
483 svc_destroy(nfsd_serv); /* Release server */
484out: 477out:
485 mutex_unlock(&nfsd_mutex); 478 mutex_unlock(&nfsd_mutex);
486 return error; 479 return error;
@@ -563,12 +556,13 @@ nfsd(void *vrqstp)
563 nfsdstats.th_cnt --; 556 nfsdstats.th_cnt --;
564 557
565out: 558out:
566 if (rqstp->rq_server->sv_nrthreads == 1) 559 rqstp->rq_server = NULL;
567 svc_shutdown_net(rqstp->rq_server, &init_net);
568 560
569 /* Release the thread */ 561 /* Release the thread */
570 svc_exit_thread(rqstp); 562 svc_exit_thread(rqstp);
571 563
564 nfsd_destroy(&init_net);
565
572 /* Release module */ 566 /* Release module */
573 mutex_unlock(&nfsd_mutex); 567 mutex_unlock(&nfsd_mutex);
574 module_put_and_exit(0); 568 module_put_and_exit(0);
@@ -682,9 +676,7 @@ int nfsd_pool_stats_release(struct inode *inode, struct file *file)
682 676
683 mutex_lock(&nfsd_mutex); 677 mutex_lock(&nfsd_mutex);
684 /* this function really, really should have been called svc_put() */ 678 /* this function really, really should have been called svc_put() */
685 if (nfsd_serv->sv_nrthreads == 1) 679 nfsd_destroy(net);
686 svc_shutdown_net(nfsd_serv, net);
687 svc_destroy(nfsd_serv);
688 mutex_unlock(&nfsd_mutex); 680 mutex_unlock(&nfsd_mutex);
689 return ret; 681 return ret;
690} 682}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 849091e16ea6..e6173147f982 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -450,8 +450,10 @@ static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
450#define WR_STATE 0x00000020 450#define WR_STATE 0x00000020
451 451
452struct nfsd4_compound_state; 452struct nfsd4_compound_state;
453struct nfsd_net;
453 454
454extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, 455extern __be32 nfs4_preprocess_stateid_op(struct net *net,
456 struct nfsd4_compound_state *cstate,
455 stateid_t *stateid, int flags, struct file **filp); 457 stateid_t *stateid, int flags, struct file **filp);
456extern void nfs4_lock_state(void); 458extern void nfs4_lock_state(void);
457extern void nfs4_unlock_state(void); 459extern void nfs4_unlock_state(void);
@@ -475,7 +477,6 @@ extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
475extern int nfs4_client_to_reclaim(const char *name); 477extern int nfs4_client_to_reclaim(const char *name);
476extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); 478extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id);
477extern void release_session_client(struct nfsd4_session *); 479extern void release_session_client(struct nfsd4_session *);
478extern __be32 nfs4_validate_stateid(struct nfs4_client *, stateid_t *);
479extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); 480extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *);
480 481
481/* nfs4recover operations */ 482/* nfs4recover operations */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4700a0a929d7..702f64e820c3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -757,8 +757,16 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
757 * If we get here, then the client has already done an "open", 757 * If we get here, then the client has already done an "open",
758 * and (hopefully) checked permission - so allow OWNER_OVERRIDE 758 * and (hopefully) checked permission - so allow OWNER_OVERRIDE
759 * in case a chmod has now revoked permission. 759 * in case a chmod has now revoked permission.
760 *
761 * Arguably we should also allow the owner override for
762 * directories, but we never have and it doesn't seem to have
763 * caused anyone a problem. If we were to change this, note
764 * also that our filldir callbacks would need a variant of
765 * lookup_one_len that doesn't check permissions.
760 */ 766 */
761 err = fh_verify(rqstp, fhp, type, may_flags | NFSD_MAY_OWNER_OVERRIDE); 767 if (type == S_IFREG)
768 may_flags |= NFSD_MAY_OWNER_OVERRIDE;
769 err = fh_verify(rqstp, fhp, type, may_flags);
762 if (err) 770 if (err)
763 goto out; 771 goto out;
764 772