aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 13:18:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 13:18:43 -0500
commitd9894c228b11273e720bb63ba120d1d326fe9d94 (patch)
treec9b91b716f281f5accf8860dfadb1ac95abf0090 /fs
parentdfa19426160046770b3a38985042df9c9760a25a (diff)
parented47b062ce9546fbe1eebf9da6937df4c5035372 (diff)
Merge branch 'for-3.14' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: - Handle some loose ends from the vfs read delegation support. (For example nfsd can stop breaking leases on its own in a fewer places where it can now depend on the vfs to.) - Make life a little easier for NFSv4-only configurations (thanks to Kinglong Mee). - Fix some gss-proxy problems (thanks Jeff Layton). - miscellaneous bug fixes and cleanup * 'for-3.14' of git://linux-nfs.org/~bfields/linux: (38 commits) nfsd: consider CLAIM_FH when handing out delegation nfsd4: fix delegation-unlink/rename race nfsd4: delay setting current_fh in open nfsd4: minor nfs4_setlease cleanup gss_krb5: use lcm from kernel lib nfsd4: decrease nfsd4_encode_fattr stack usage nfsd: fix encode_entryplus_baggage stack usage nfsd4: simplify xdr encoding of nfsv4 names nfsd4: encode_rdattr_error cleanup nfsd4: nfsd4_encode_fattr cleanup minor svcauth_gss.c cleanup nfsd4: better VERIFY comment nfsd4: break only delegations when appropriate NFSD: Fix a memory leak in nfsd4_create_session sunrpc: get rid of use_gssp_lock sunrpc: fix potential race between setting use_gss_proxy and the upcall rpc_clnt sunrpc: don't wait for write before allowing reads from use-gss-proxy file nfsd: get rid of unused function definition Define op_iattr for nfsd4_open instead using macro NFSD: fix compile warning without CONFIG_NFSD_V3 ...
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/acl.h2
-rw-r--r--fs/nfsd/cache.h8
-rw-r--r--fs/nfsd/idmap.h4
-rw-r--r--fs/nfsd/netns.h1
-rw-r--r--fs/nfsd/nfs3xdr.c14
-rw-r--r--fs/nfsd/nfs4acl.c20
-rw-r--r--fs/nfsd/nfs4idmap.c50
-rw-r--r--fs/nfsd/nfs4proc.c57
-rw-r--r--fs/nfsd/nfs4state.c40
-rw-r--r--fs/nfsd/nfs4xdr.c178
-rw-r--r--fs/nfsd/nfscache.c36
-rw-r--r--fs/nfsd/nfssvc.c30
-rw-r--r--fs/nfsd/nfsxdr.c2
-rw-r--r--fs/nfsd/vfs.c40
-rw-r--r--fs/nfsd/vfs.h2
-rw-r--r--fs/nfsd/xdr3.h3
-rw-r--r--fs/nfsd/xdr4.h4
17 files changed, 219 insertions, 272 deletions
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index 8b68218e2c1c..a812fd1b92a4 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -45,7 +45,7 @@ struct svc_rqst;
45 45
46struct nfs4_acl *nfs4_acl_new(int); 46struct nfs4_acl *nfs4_acl_new(int);
47int nfs4_acl_get_whotype(char *, u32); 47int nfs4_acl_get_whotype(char *, u32);
48int nfs4_acl_write_who(int who, char *p); 48__be32 nfs4_acl_write_who(int who, __be32 **p, int *len);
49 49
50int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, 50int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
51 struct nfs4_acl **acl); 51 struct nfs4_acl **acl);
diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h
index d5c5b3e00266..b582f9ab6b2a 100644
--- a/fs/nfsd/cache.h
+++ b/fs/nfsd/cache.h
@@ -84,12 +84,4 @@ int nfsd_cache_lookup(struct svc_rqst *);
84void nfsd_cache_update(struct svc_rqst *, int, __be32 *); 84void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
85int nfsd_reply_cache_stats_open(struct inode *, struct file *); 85int nfsd_reply_cache_stats_open(struct inode *, struct file *);
86 86
87#ifdef CONFIG_NFSD_V4
88void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp);
89#else /* CONFIG_NFSD_V4 */
90static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp)
91{
92}
93#endif /* CONFIG_NFSD_V4 */
94
95#endif /* NFSCACHE_H */ 87#endif /* NFSCACHE_H */
diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h
index bf95f6b817a4..66e58db01936 100644
--- a/fs/nfsd/idmap.h
+++ b/fs/nfsd/idmap.h
@@ -56,7 +56,7 @@ static inline void nfsd_idmap_shutdown(struct net *net)
56 56
57__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *); 57__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *);
58__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *); 58__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *);
59int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *); 59__be32 nfsd4_encode_user(struct svc_rqst *, kuid_t, __be32 **, int *);
60int nfsd_map_gid_to_name(struct svc_rqst *, kgid_t, char *); 60__be32 nfsd4_encode_group(struct svc_rqst *, kgid_t, __be32 **, int *);
61 61
62#endif /* LINUX_NFSD_IDMAP_H */ 62#endif /* LINUX_NFSD_IDMAP_H */
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 849a7c3ced22..d32b3aa6600d 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -95,6 +95,7 @@ struct nfsd_net {
95 time_t nfsd4_grace; 95 time_t nfsd4_grace;
96 96
97 bool nfsd_net_up; 97 bool nfsd_net_up;
98 bool lockd_up;
98 99
99 /* 100 /*
100 * Time of server startup 101 * Time of server startup
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 14d9ecb96cff..de6e39e12cb3 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -168,7 +168,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
168 struct kstat *stat) 168 struct kstat *stat)
169{ 169{
170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 170 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
171 *p++ = htonl((u32) stat->mode); 171 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
172 *p++ = htonl((u32) stat->nlink); 172 *p++ = htonl((u32) stat->nlink);
173 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 173 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
174 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 174 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
@@ -842,21 +842,21 @@ out:
842 842
843static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) 843static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
844{ 844{
845 struct svc_fh fh; 845 struct svc_fh *fh = &cd->scratch;
846 __be32 err; 846 __be32 err;
847 847
848 fh_init(&fh, NFS3_FHSIZE); 848 fh_init(fh, NFS3_FHSIZE);
849 err = compose_entry_fh(cd, &fh, name, namlen); 849 err = compose_entry_fh(cd, fh, name, namlen);
850 if (err) { 850 if (err) {
851 *p++ = 0; 851 *p++ = 0;
852 *p++ = 0; 852 *p++ = 0;
853 goto out; 853 goto out;
854 } 854 }
855 p = encode_post_op_attr(cd->rqstp, p, &fh); 855 p = encode_post_op_attr(cd->rqstp, p, fh);
856 *p++ = xdr_one; /* yes, a file handle follows */ 856 *p++ = xdr_one; /* yes, a file handle follows */
857 p = encode_fh(p, &fh); 857 p = encode_fh(p, fh);
858out: 858out:
859 fh_put(&fh); 859 fh_put(fh);
860 return p; 860 return p;
861} 861}
862 862
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 649ad7cf2204..d3a587144222 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -38,6 +38,7 @@
38#include <linux/nfs_fs.h> 38#include <linux/nfs_fs.h>
39#include <linux/export.h> 39#include <linux/export.h>
40#include "nfsfh.h" 40#include "nfsfh.h"
41#include "nfsd.h"
41#include "acl.h" 42#include "acl.h"
42#include "vfs.h" 43#include "vfs.h"
43 44
@@ -916,17 +917,22 @@ nfs4_acl_get_whotype(char *p, u32 len)
916 return NFS4_ACL_WHO_NAMED; 917 return NFS4_ACL_WHO_NAMED;
917} 918}
918 919
919int 920__be32 nfs4_acl_write_who(int who, __be32 **p, int *len)
920nfs4_acl_write_who(int who, char *p)
921{ 921{
922 int i; 922 int i;
923 int bytes;
923 924
924 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 925 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
925 if (s2t_map[i].type == who) { 926 if (s2t_map[i].type != who)
926 memcpy(p, s2t_map[i].string, s2t_map[i].stringlen); 927 continue;
927 return s2t_map[i].stringlen; 928 bytes = 4 + (XDR_QUADLEN(s2t_map[i].stringlen) << 2);
928 } 929 if (bytes > *len)
930 return nfserr_resource;
931 *p = xdr_encode_opaque(*p, s2t_map[i].string,
932 s2t_map[i].stringlen);
933 *len -= bytes;
934 return 0;
929 } 935 }
930 BUG(); 936 WARN_ON_ONCE(1);
931 return -1; 937 return -1;
932} 938}
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 4832fd819f88..c0dfde68742e 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -551,27 +551,46 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
551 return 0; 551 return 0;
552} 552}
553 553
554static int 554static __be32 encode_ascii_id(u32 id, __be32 **p, int *buflen)
555idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) 555{
556 char buf[11];
557 int len;
558 int bytes;
559
560 len = sprintf(buf, "%u", id);
561 bytes = 4 + (XDR_QUADLEN(len) << 2);
562 if (bytes > *buflen)
563 return nfserr_resource;
564 *p = xdr_encode_opaque(*p, buf, len);
565 *buflen -= bytes;
566 return 0;
567}
568
569static __be32 idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen)
556{ 570{
557 struct ent *item, key = { 571 struct ent *item, key = {
558 .id = id, 572 .id = id,
559 .type = type, 573 .type = type,
560 }; 574 };
561 int ret; 575 int ret;
576 int bytes;
562 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 577 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
563 578
564 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 579 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
565 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); 580 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
566 if (ret == -ENOENT) 581 if (ret == -ENOENT)
567 return sprintf(name, "%u", id); 582 return encode_ascii_id(id, p, buflen);
568 if (ret) 583 if (ret)
569 return ret; 584 return nfserrno(ret);
570 ret = strlen(item->name); 585 ret = strlen(item->name);
571 BUG_ON(ret > IDMAP_NAMESZ); 586 WARN_ON_ONCE(ret > IDMAP_NAMESZ);
572 memcpy(name, item->name, ret); 587 bytes = 4 + (XDR_QUADLEN(ret) << 2);
588 if (bytes > *buflen)
589 return nfserr_resource;
590 *p = xdr_encode_opaque(*p, item->name, ret);
591 *buflen -= bytes;
573 cache_put(&item->h, nn->idtoname_cache); 592 cache_put(&item->h, nn->idtoname_cache);
574 return ret; 593 return 0;
575} 594}
576 595
577static bool 596static bool
@@ -603,12 +622,11 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
603 return idmap_name_to_id(rqstp, type, name, namelen, id); 622 return idmap_name_to_id(rqstp, type, name, namelen, id);
604} 623}
605 624
606static int 625static __be32 encode_name_from_id(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen)
607do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
608{ 626{
609 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 627 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
610 return sprintf(name, "%u", id); 628 return encode_ascii_id(id, p, buflen);
611 return idmap_id_to_name(rqstp, type, id, name); 629 return idmap_id_to_name(rqstp, type, id, p, buflen);
612} 630}
613 631
614__be32 632__be32
@@ -637,16 +655,14 @@ nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
637 return status; 655 return status;
638} 656}
639 657
640int 658__be32 nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t uid, __be32 **p, int *buflen)
641nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name)
642{ 659{
643 u32 id = from_kuid(&init_user_ns, uid); 660 u32 id = from_kuid(&init_user_ns, uid);
644 return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 661 return encode_name_from_id(rqstp, IDMAP_TYPE_USER, id, p, buflen);
645} 662}
646 663
647int 664__be32 nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t gid, __be32 **p, int *buflen)
648nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name)
649{ 665{
650 u32 id = from_kgid(&init_user_ns, gid); 666 u32 id = from_kgid(&init_user_ns, gid);
651 return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 667 return encode_name_from_id(rqstp, IDMAP_TYPE_GROUP, id, p, buflen);
652} 668}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 825b8a99b99b..82189b208af3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -231,17 +231,16 @@ static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate
231} 231}
232 232
233static __be32 233static __be32
234do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 234do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh)
235{ 235{
236 struct svc_fh *current_fh = &cstate->current_fh; 236 struct svc_fh *current_fh = &cstate->current_fh;
237 struct svc_fh *resfh;
238 int accmode; 237 int accmode;
239 __be32 status; 238 __be32 status;
240 239
241 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); 240 *resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
242 if (!resfh) 241 if (!*resfh)
243 return nfserr_jukebox; 242 return nfserr_jukebox;
244 fh_init(resfh, NFS4_FHSIZE); 243 fh_init(*resfh, NFS4_FHSIZE);
245 open->op_truncate = 0; 244 open->op_truncate = 0;
246 245
247 if (open->op_create) { 246 if (open->op_create) {
@@ -266,12 +265,12 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
266 */ 265 */
267 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 266 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
268 open->op_fname.len, &open->op_iattr, 267 open->op_fname.len, &open->op_iattr,
269 resfh, open->op_createmode, 268 *resfh, open->op_createmode,
270 (u32 *)open->op_verf.data, 269 (u32 *)open->op_verf.data,
271 &open->op_truncate, &open->op_created); 270 &open->op_truncate, &open->op_created);
272 271
273 if (!status && open->op_label.len) 272 if (!status && open->op_label.len)
274 nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval); 273 nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
275 274
276 /* 275 /*
277 * Following rfc 3530 14.2.16, use the returned bitmask 276 * Following rfc 3530 14.2.16, use the returned bitmask
@@ -281,31 +280,32 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
281 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) 280 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
282 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | 281 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
283 FATTR4_WORD1_TIME_MODIFY); 282 FATTR4_WORD1_TIME_MODIFY);
284 } else { 283 } else
284 /*
285 * Note this may exit with the parent still locked.
286 * We will hold the lock until nfsd4_open's final
287 * lookup, to prevent renames or unlinks until we've had
288 * a chance to an acquire a delegation if appropriate.
289 */
285 status = nfsd_lookup(rqstp, current_fh, 290 status = nfsd_lookup(rqstp, current_fh,
286 open->op_fname.data, open->op_fname.len, resfh); 291 open->op_fname.data, open->op_fname.len, *resfh);
287 fh_unlock(current_fh);
288 }
289 if (status) 292 if (status)
290 goto out; 293 goto out;
291 status = nfsd_check_obj_isreg(resfh); 294 status = nfsd_check_obj_isreg(*resfh);
292 if (status) 295 if (status)
293 goto out; 296 goto out;
294 297
295 if (is_create_with_attrs(open) && open->op_acl != NULL) 298 if (is_create_with_attrs(open) && open->op_acl != NULL)
296 do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval); 299 do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval);
297 300
298 nfsd4_set_open_owner_reply_cache(cstate, open, resfh); 301 nfsd4_set_open_owner_reply_cache(cstate, open, *resfh);
299 accmode = NFSD_MAY_NOP; 302 accmode = NFSD_MAY_NOP;
300 if (open->op_created || 303 if (open->op_created ||
301 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 304 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
302 accmode |= NFSD_MAY_OWNER_OVERRIDE; 305 accmode |= NFSD_MAY_OWNER_OVERRIDE;
303 status = do_open_permission(rqstp, resfh, open, accmode); 306 status = do_open_permission(rqstp, *resfh, open, accmode);
304 set_change_info(&open->op_cinfo, current_fh); 307 set_change_info(&open->op_cinfo, current_fh);
305 fh_dup2(current_fh, resfh);
306out: 308out:
307 fh_put(resfh);
308 kfree(resfh);
309 return status; 309 return status;
310} 310}
311 311
@@ -358,6 +358,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
358 struct nfsd4_open *open) 358 struct nfsd4_open *open)
359{ 359{
360 __be32 status; 360 __be32 status;
361 struct svc_fh *resfh = NULL;
361 struct nfsd4_compoundres *resp; 362 struct nfsd4_compoundres *resp;
362 struct net *net = SVC_NET(rqstp); 363 struct net *net = SVC_NET(rqstp);
363 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 364 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
@@ -424,7 +425,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
424 switch (open->op_claim_type) { 425 switch (open->op_claim_type) {
425 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 426 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
426 case NFS4_OPEN_CLAIM_NULL: 427 case NFS4_OPEN_CLAIM_NULL:
427 status = do_open_lookup(rqstp, cstate, open); 428 status = do_open_lookup(rqstp, cstate, open, &resfh);
428 if (status) 429 if (status)
429 goto out; 430 goto out;
430 break; 431 break;
@@ -440,6 +441,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
440 status = do_open_fhandle(rqstp, cstate, open); 441 status = do_open_fhandle(rqstp, cstate, open);
441 if (status) 442 if (status)
442 goto out; 443 goto out;
444 resfh = &cstate->current_fh;
443 break; 445 break;
444 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 446 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
445 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 447 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
@@ -459,9 +461,14 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
459 * successful, it (1) truncates the file if open->op_truncate was 461 * successful, it (1) truncates the file if open->op_truncate was
460 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 462 * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
461 */ 463 */
462 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 464 status = nfsd4_process_open2(rqstp, resfh, open);
463 WARN_ON(status && open->op_created); 465 WARN_ON(status && open->op_created);
464out: 466out:
467 if (resfh && resfh != &cstate->current_fh) {
468 fh_dup2(&cstate->current_fh, resfh);
469 fh_put(resfh);
470 kfree(resfh);
471 }
465 nfsd4_cleanup_open_state(open, status); 472 nfsd4_cleanup_open_state(open, status);
466 if (open->op_openowner && !nfsd4_has_session(cstate)) 473 if (open->op_openowner && !nfsd4_has_session(cstate))
467 cstate->replay_owner = &open->op_openowner->oo_owner; 474 cstate->replay_owner = &open->op_openowner->oo_owner;
@@ -1070,8 +1077,10 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1070 cstate->current_fh.fh_dentry, &p, 1077 cstate->current_fh.fh_dentry, &p,
1071 count, verify->ve_bmval, 1078 count, verify->ve_bmval,
1072 rqstp, 0); 1079 rqstp, 0);
1073 1080 /*
1074 /* this means that nfsd4_encode_fattr() ran out of space */ 1081 * If nfsd4_encode_fattr() ran out of space, assume that's because
1082 * the attributes are longer (hence different) than those given:
1083 */
1075 if (status == nfserr_resource) 1084 if (status == nfserr_resource)
1076 status = nfserr_not_same; 1085 status = nfserr_not_same;
1077 if (status) 1086 if (status)
@@ -1525,7 +1534,8 @@ static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1525static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1534static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1526{ 1535{
1527 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1536 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1528 1 + 1 + 2 + /* eir_flags, spr_how, spo_must_enforce & _allow */\ 1537 1 + 1 + /* eir_flags, spr_how */\
1538 4 + /* spo_must_enforce & _allow with bitmap */\
1529 2 + /*eir_server_owner.so_minor_id */\ 1539 2 + /*eir_server_owner.so_minor_id */\
1530 /* eir_server_owner.so_major_id<> */\ 1540 /* eir_server_owner.so_major_id<> */\
1531 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1541 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
@@ -1882,6 +1892,7 @@ struct svc_version nfsd_version4 = {
1882 .vs_proc = nfsd_procedures4, 1892 .vs_proc = nfsd_procedures4,
1883 .vs_dispatch = nfsd_dispatch, 1893 .vs_dispatch = nfsd_dispatch,
1884 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1894 .vs_xdrsize = NFS4_SVC_XDRSIZE,
1895 .vs_rpcb_optnl = 1,
1885}; 1896};
1886 1897
1887/* 1898/*
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 105d6fa7c514..d5d070fbeb35 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -832,10 +832,11 @@ static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
832 spin_unlock(&nfsd_drc_lock); 832 spin_unlock(&nfsd_drc_lock);
833} 833}
834 834
835static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs) 835static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs,
836 struct nfsd4_channel_attrs *battrs)
836{ 837{
837 int numslots = attrs->maxreqs; 838 int numslots = fattrs->maxreqs;
838 int slotsize = slot_bytes(attrs); 839 int slotsize = slot_bytes(fattrs);
839 struct nfsd4_session *new; 840 struct nfsd4_session *new;
840 int mem, i; 841 int mem, i;
841 842
@@ -852,6 +853,10 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs)
852 if (!new->se_slots[i]) 853 if (!new->se_slots[i])
853 goto out_free; 854 goto out_free;
854 } 855 }
856
857 memcpy(&new->se_fchannel, fattrs, sizeof(struct nfsd4_channel_attrs));
858 memcpy(&new->se_bchannel, battrs, sizeof(struct nfsd4_channel_attrs));
859
855 return new; 860 return new;
856out_free: 861out_free:
857 while (i--) 862 while (i--)
@@ -997,8 +1002,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru
997 list_add(&new->se_perclnt, &clp->cl_sessions); 1002 list_add(&new->se_perclnt, &clp->cl_sessions);
998 spin_unlock(&clp->cl_lock); 1003 spin_unlock(&clp->cl_lock);
999 spin_unlock(&nn->client_lock); 1004 spin_unlock(&nn->client_lock);
1000 memcpy(&new->se_fchannel, &cses->fore_channel, 1005
1001 sizeof(struct nfsd4_channel_attrs));
1002 if (cses->flags & SESSION4_BACK_CHAN) { 1006 if (cses->flags & SESSION4_BACK_CHAN) {
1003 struct sockaddr *sa = svc_addr(rqstp); 1007 struct sockaddr *sa = svc_addr(rqstp);
1004 /* 1008 /*
@@ -1851,6 +1855,11 @@ static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfs
1851 return nfs_ok; 1855 return nfs_ok;
1852} 1856}
1853 1857
1858#define NFSD_CB_MAX_REQ_SZ ((NFS4_enc_cb_recall_sz + \
1859 RPC_MAX_HEADER_WITH_AUTH) * sizeof(__be32))
1860#define NFSD_CB_MAX_RESP_SZ ((NFS4_dec_cb_recall_sz + \
1861 RPC_MAX_REPHEADER_WITH_AUTH) * sizeof(__be32))
1862
1854static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca) 1863static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
1855{ 1864{
1856 ca->headerpadsz = 0; 1865 ca->headerpadsz = 0;
@@ -1861,9 +1870,9 @@ static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
1861 * less than 1k. Tighten up this estimate in the unlikely event 1870 * less than 1k. Tighten up this estimate in the unlikely event
1862 * it turns out to be a problem for some client: 1871 * it turns out to be a problem for some client:
1863 */ 1872 */
1864 if (ca->maxreq_sz < NFS4_enc_cb_recall_sz + RPC_MAX_HEADER_WITH_AUTH) 1873 if (ca->maxreq_sz < NFSD_CB_MAX_REQ_SZ)
1865 return nfserr_toosmall; 1874 return nfserr_toosmall;
1866 if (ca->maxresp_sz < NFS4_dec_cb_recall_sz + RPC_MAX_REPHEADER_WITH_AUTH) 1875 if (ca->maxresp_sz < NFSD_CB_MAX_RESP_SZ)
1867 return nfserr_toosmall; 1876 return nfserr_toosmall;
1868 ca->maxresp_cached = 0; 1877 ca->maxresp_cached = 0;
1869 if (ca->maxops < 2) 1878 if (ca->maxops < 2)
@@ -1913,9 +1922,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1913 return status; 1922 return status;
1914 status = check_backchannel_attrs(&cr_ses->back_channel); 1923 status = check_backchannel_attrs(&cr_ses->back_channel);
1915 if (status) 1924 if (status)
1916 return status; 1925 goto out_release_drc_mem;
1917 status = nfserr_jukebox; 1926 status = nfserr_jukebox;
1918 new = alloc_session(&cr_ses->fore_channel); 1927 new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel);
1919 if (!new) 1928 if (!new)
1920 goto out_release_drc_mem; 1929 goto out_release_drc_mem;
1921 conn = alloc_conn_from_crses(rqstp, cr_ses); 1930 conn = alloc_conn_from_crses(rqstp, cr_ses);
@@ -3034,18 +3043,18 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
3034 if (!fl) 3043 if (!fl)
3035 return -ENOMEM; 3044 return -ENOMEM;
3036 fl->fl_file = find_readable_file(fp); 3045 fl->fl_file = find_readable_file(fp);
3037 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
3038 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); 3046 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
3039 if (status) { 3047 if (status)
3040 list_del_init(&dp->dl_perclnt); 3048 goto out_free;
3041 locks_free_lock(fl); 3049 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
3042 return status;
3043 }
3044 fp->fi_lease = fl; 3050 fp->fi_lease = fl;
3045 fp->fi_deleg_file = get_file(fl->fl_file); 3051 fp->fi_deleg_file = get_file(fl->fl_file);
3046 atomic_set(&fp->fi_delegees, 1); 3052 atomic_set(&fp->fi_delegees, 1);
3047 list_add(&dp->dl_perfile, &fp->fi_delegations); 3053 list_add(&dp->dl_perfile, &fp->fi_delegations);
3048 return 0; 3054 return 0;
3055out_free:
3056 locks_free_lock(fl);
3057 return status;
3049} 3058}
3050 3059
3051static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp) 3060static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp)
@@ -3125,6 +3134,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3125 goto out_no_deleg; 3134 goto out_no_deleg;
3126 break; 3135 break;
3127 case NFS4_OPEN_CLAIM_NULL: 3136 case NFS4_OPEN_CLAIM_NULL:
3137 case NFS4_OPEN_CLAIM_FH:
3128 /* 3138 /*
3129 * Let's not give out any delegations till everyone's 3139 * Let's not give out any delegations till everyone's
3130 * had the chance to reclaim theirs.... 3140 * had the chance to reclaim theirs....
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ee7237f99f54..63f2395c57ed 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -103,11 +103,6 @@ xdr_error: \
103 (x) = (u64)ntohl(*p++) << 32; \ 103 (x) = (u64)ntohl(*p++) << 32; \
104 (x) |= ntohl(*p++); \ 104 (x) |= ntohl(*p++); \
105} while (0) 105} while (0)
106#define READTIME(x) do { \
107 p++; \
108 (x) = ntohl(*p++); \
109 p++; \
110} while (0)
111#define READMEM(x,nbytes) do { \ 106#define READMEM(x,nbytes) do { \
112 x = (char *)p; \ 107 x = (char *)p; \
113 p += XDR_QUADLEN(nbytes); \ 108 p += XDR_QUADLEN(nbytes); \
@@ -190,6 +185,15 @@ static int zero_clientid(clientid_t *clid)
190 return (clid->cl_boot == 0) && (clid->cl_id == 0); 185 return (clid->cl_boot == 0) && (clid->cl_id == 0);
191} 186}
192 187
188/**
189 * defer_free - mark an allocation as deferred freed
190 * @argp: NFSv4 compound argument structure to be freed with
191 * @release: release callback to free @p, typically kfree()
192 * @p: pointer to be freed
193 *
194 * Marks @p to be freed when processing the compound operation
195 * described in @argp finishes.
196 */
193static int 197static int
194defer_free(struct nfsd4_compoundargs *argp, 198defer_free(struct nfsd4_compoundargs *argp,
195 void (*release)(const void *), void *p) 199 void (*release)(const void *), void *p)
@@ -206,6 +210,16 @@ defer_free(struct nfsd4_compoundargs *argp,
206 return 0; 210 return 0;
207} 211}
208 212
213/**
214 * savemem - duplicate a chunk of memory for later processing
215 * @argp: NFSv4 compound argument structure to be freed with
216 * @p: pointer to be duplicated
217 * @nbytes: length to be duplicated
218 *
219 * Returns a pointer to a copy of @nbytes bytes of memory at @p
220 * that are preserved until processing of the NFSv4 compound
221 * operation described by @argp finishes.
222 */
209static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) 223static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
210{ 224{
211 if (p == argp->tmp) { 225 if (p == argp->tmp) {
@@ -257,7 +271,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
257 int expected_len, len = 0; 271 int expected_len, len = 0;
258 u32 dummy32; 272 u32 dummy32;
259 char *buf; 273 char *buf;
260 int host_err;
261 274
262 DECODE_HEAD; 275 DECODE_HEAD;
263 iattr->ia_valid = 0; 276 iattr->ia_valid = 0;
@@ -284,10 +297,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
284 return nfserr_resource; 297 return nfserr_resource;
285 298
286 *acl = nfs4_acl_new(nace); 299 *acl = nfs4_acl_new(nace);
287 if (*acl == NULL) { 300 if (*acl == NULL)
288 host_err = -ENOMEM; 301 return nfserr_jukebox;
289 goto out_nfserr; 302
290 }
291 defer_free(argp, kfree, *acl); 303 defer_free(argp, kfree, *acl);
292 304
293 (*acl)->naces = nace; 305 (*acl)->naces = nace;
@@ -425,10 +437,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
425 goto xdr_error; 437 goto xdr_error;
426 438
427 DECODE_TAIL; 439 DECODE_TAIL;
428
429out_nfserr:
430 status = nfserrno(host_err);
431 goto out;
432} 440}
433 441
434static __be32 442static __be32
@@ -1957,56 +1965,16 @@ static u32 nfs4_file_type(umode_t mode)
1957 }; 1965 };
1958} 1966}
1959 1967
1960static __be32
1961nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid,
1962 __be32 **p, int *buflen)
1963{
1964 int status;
1965
1966 if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1967 return nfserr_resource;
1968 if (whotype != NFS4_ACL_WHO_NAMED)
1969 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1970 else if (gid_valid(gid))
1971 status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1));
1972 else
1973 status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1));
1974 if (status < 0)
1975 return nfserrno(status);
1976 *p = xdr_encode_opaque(*p, NULL, status);
1977 *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1978 BUG_ON(*buflen < 0);
1979 return 0;
1980}
1981
1982static inline __be32
1983nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen)
1984{
1985 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID,
1986 p, buflen);
1987}
1988
1989static inline __be32
1990nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen)
1991{
1992 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group,
1993 p, buflen);
1994}
1995
1996static inline __be32 1968static inline __be32
1997nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace, 1969nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
1998 __be32 **p, int *buflen) 1970 __be32 **p, int *buflen)
1999{ 1971{
2000 kuid_t uid = INVALID_UID; 1972 if (ace->whotype != NFS4_ACL_WHO_NAMED)
2001 kgid_t gid = INVALID_GID; 1973 return nfs4_acl_write_who(ace->whotype, p, buflen);
2002 1974 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
2003 if (ace->whotype == NFS4_ACL_WHO_NAMED) { 1975 return nfsd4_encode_group(rqstp, ace->who_gid, p, buflen);
2004 if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 1976 else
2005 gid = ace->who_gid; 1977 return nfsd4_encode_user(rqstp, ace->who_uid, p, buflen);
2006 else
2007 uid = ace->who_uid;
2008 }
2009 return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen);
2010} 1978}
2011 1979
2012#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ 1980#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
@@ -2090,7 +2058,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2090 u32 bmval1 = bmval[1]; 2058 u32 bmval1 = bmval[1];
2091 u32 bmval2 = bmval[2]; 2059 u32 bmval2 = bmval[2];
2092 struct kstat stat; 2060 struct kstat stat;
2093 struct svc_fh tempfh; 2061 struct svc_fh *tempfh = NULL;
2094 struct kstatfs statfs; 2062 struct kstatfs statfs;
2095 int buflen = count << 2; 2063 int buflen = count << 2;
2096 __be32 *attrlenp; 2064 __be32 *attrlenp;
@@ -2137,11 +2105,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2137 goto out_nfserr; 2105 goto out_nfserr;
2138 } 2106 }
2139 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { 2107 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2140 fh_init(&tempfh, NFS4_FHSIZE); 2108 tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
2141 status = fh_compose(&tempfh, exp, dentry, NULL); 2109 status = nfserr_jukebox;
2110 if (!tempfh)
2111 goto out;
2112 fh_init(tempfh, NFS4_FHSIZE);
2113 status = fh_compose(tempfh, exp, dentry, NULL);
2142 if (status) 2114 if (status)
2143 goto out; 2115 goto out;
2144 fhp = &tempfh; 2116 fhp = tempfh;
2145 } 2117 }
2146 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT 2118 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
2147 | FATTR4_WORD0_SUPPORTED_ATTRS)) { 2119 | FATTR4_WORD0_SUPPORTED_ATTRS)) {
@@ -2222,8 +2194,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2222 if ((buflen -= 4) < 0) 2194 if ((buflen -= 4) < 0)
2223 goto out_resource; 2195 goto out_resource;
2224 dummy = nfs4_file_type(stat.mode); 2196 dummy = nfs4_file_type(stat.mode);
2225 if (dummy == NF4BAD) 2197 if (dummy == NF4BAD) {
2226 goto out_serverfault; 2198 status = nfserr_serverfault;
2199 goto out;
2200 }
2227 WRITE32(dummy); 2201 WRITE32(dummy);
2228 } 2202 }
2229 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { 2203 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
@@ -2317,8 +2291,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2317 WRITE32(ace->flag); 2291 WRITE32(ace->flag);
2318 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 2292 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2319 status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen); 2293 status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen);
2320 if (status == nfserr_resource)
2321 goto out_resource;
2322 if (status) 2294 if (status)
2323 goto out; 2295 goto out;
2324 } 2296 }
@@ -2379,8 +2351,6 @@ out_acl:
2379 } 2351 }
2380 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 2352 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2381 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); 2353 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2382 if (status == nfserr_resource)
2383 goto out_resource;
2384 if (status) 2354 if (status)
2385 goto out; 2355 goto out;
2386 } 2356 }
@@ -2431,15 +2401,11 @@ out_acl:
2431 } 2401 }
2432 if (bmval1 & FATTR4_WORD1_OWNER) { 2402 if (bmval1 & FATTR4_WORD1_OWNER) {
2433 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); 2403 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
2434 if (status == nfserr_resource)
2435 goto out_resource;
2436 if (status) 2404 if (status)
2437 goto out; 2405 goto out;
2438 } 2406 }
2439 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { 2407 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2440 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); 2408 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
2441 if (status == nfserr_resource)
2442 goto out_resource;
2443 if (status) 2409 if (status)
2444 goto out; 2410 goto out;
2445 } 2411 }
@@ -2533,8 +2499,8 @@ out:
2533 security_release_secctx(context, contextlen); 2499 security_release_secctx(context, contextlen);
2534#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ 2500#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2535 kfree(acl); 2501 kfree(acl);
2536 if (fhp == &tempfh) 2502 if (tempfh)
2537 fh_put(&tempfh); 2503 fh_put(tempfh);
2538 return status; 2504 return status;
2539out_nfserr: 2505out_nfserr:
2540 status = nfserrno(err); 2506 status = nfserrno(err);
@@ -2542,9 +2508,6 @@ out_nfserr:
2542out_resource: 2508out_resource:
2543 status = nfserr_resource; 2509 status = nfserr_resource;
2544 goto out; 2510 goto out;
2545out_serverfault:
2546 status = nfserr_serverfault;
2547 goto out;
2548} 2511}
2549 2512
2550static inline int attributes_need_mount(u32 *bmval) 2513static inline int attributes_need_mount(u32 *bmval)
@@ -2621,17 +2584,14 @@ out_put:
2621static __be32 * 2584static __be32 *
2622nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) 2585nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2623{ 2586{
2624 __be32 *attrlenp;
2625
2626 if (buflen < 6) 2587 if (buflen < 6)
2627 return NULL; 2588 return NULL;
2628 *p++ = htonl(2); 2589 *p++ = htonl(2);
2629 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */ 2590 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2630 *p++ = htonl(0); /* bmval1 */ 2591 *p++ = htonl(0); /* bmval1 */
2631 2592
2632 attrlenp = p++; 2593 *p++ = htonl(4); /* attribute length */
2633 *p++ = nfserr; /* no htonl */ 2594 *p++ = nfserr; /* no htonl */
2634 *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2635 return p; 2595 return p;
2636} 2596}
2637 2597
@@ -3244,7 +3204,7 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3244 3204
3245 if (rpcauth_get_gssinfo(pf, &info) == 0) { 3205 if (rpcauth_get_gssinfo(pf, &info) == 0) {
3246 supported++; 3206 supported++;
3247 RESERVE_SPACE(4 + 4 + info.oid.len + 4 + 4); 3207 RESERVE_SPACE(4 + 4 + XDR_LEN(info.oid.len) + 4 + 4);
3248 WRITE32(RPC_AUTH_GSS); 3208 WRITE32(RPC_AUTH_GSS);
3249 WRITE32(info.oid.len); 3209 WRITE32(info.oid.len);
3250 WRITEMEM(info.oid.data, info.oid.len); 3210 WRITEMEM(info.oid.data, info.oid.len);
@@ -3379,35 +3339,43 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3379 8 /* eir_clientid */ + 3339 8 /* eir_clientid */ +
3380 4 /* eir_sequenceid */ + 3340 4 /* eir_sequenceid */ +
3381 4 /* eir_flags */ + 3341 4 /* eir_flags */ +
3382 4 /* spr_how */ + 3342 4 /* spr_how */);
3383 8 /* spo_must_enforce, spo_must_allow */ +
3384 8 /* so_minor_id */ +
3385 4 /* so_major_id.len */ +
3386 (XDR_QUADLEN(major_id_sz) * 4) +
3387 4 /* eir_server_scope.len */ +
3388 (XDR_QUADLEN(server_scope_sz) * 4) +
3389 4 /* eir_server_impl_id.count (0) */);
3390 3343
3391 WRITEMEM(&exid->clientid, 8); 3344 WRITEMEM(&exid->clientid, 8);
3392 WRITE32(exid->seqid); 3345 WRITE32(exid->seqid);
3393 WRITE32(exid->flags); 3346 WRITE32(exid->flags);
3394 3347
3395 WRITE32(exid->spa_how); 3348 WRITE32(exid->spa_how);
3349 ADJUST_ARGS();
3350
3396 switch (exid->spa_how) { 3351 switch (exid->spa_how) {
3397 case SP4_NONE: 3352 case SP4_NONE:
3398 break; 3353 break;
3399 case SP4_MACH_CRED: 3354 case SP4_MACH_CRED:
3355 /* spo_must_enforce, spo_must_allow */
3356 RESERVE_SPACE(16);
3357
3400 /* spo_must_enforce bitmap: */ 3358 /* spo_must_enforce bitmap: */
3401 WRITE32(2); 3359 WRITE32(2);
3402 WRITE32(nfs4_minimal_spo_must_enforce[0]); 3360 WRITE32(nfs4_minimal_spo_must_enforce[0]);
3403 WRITE32(nfs4_minimal_spo_must_enforce[1]); 3361 WRITE32(nfs4_minimal_spo_must_enforce[1]);
3404 /* empty spo_must_allow bitmap: */ 3362 /* empty spo_must_allow bitmap: */
3405 WRITE32(0); 3363 WRITE32(0);
3364
3365 ADJUST_ARGS();
3406 break; 3366 break;
3407 default: 3367 default:
3408 WARN_ON_ONCE(1); 3368 WARN_ON_ONCE(1);
3409 } 3369 }
3410 3370
3371 RESERVE_SPACE(
3372 8 /* so_minor_id */ +
3373 4 /* so_major_id.len */ +
3374 (XDR_QUADLEN(major_id_sz) * 4) +
3375 4 /* eir_server_scope.len */ +
3376 (XDR_QUADLEN(server_scope_sz) * 4) +
3377 4 /* eir_server_impl_id.count (0) */);
3378
3411 /* The server_owner struct */ 3379 /* The server_owner struct */
3412 WRITE64(minor_id); /* Minor id */ 3380 WRITE64(minor_id); /* Minor id */
3413 /* major id */ 3381 /* major id */
@@ -3474,28 +3442,6 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3474} 3442}
3475 3443
3476static __be32 3444static __be32
3477nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3478 struct nfsd4_destroy_session *destroy_session)
3479{
3480 return nfserr;
3481}
3482
3483static __be32
3484nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3485 struct nfsd4_free_stateid *free_stateid)
3486{
3487 __be32 *p;
3488
3489 if (nfserr)
3490 return nfserr;
3491
3492 RESERVE_SPACE(4);
3493 *p++ = nfserr;
3494 ADJUST_ARGS();
3495 return nfserr;
3496}
3497
3498static __be32
3499nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, 3445nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3500 struct nfsd4_sequence *seq) 3446 struct nfsd4_sequence *seq)
3501{ 3447{
@@ -3593,8 +3539,8 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3593 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session, 3539 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3594 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3540 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
3595 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3541 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
3596 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3542 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
3597 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_free_stateid, 3543 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
3598 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3544 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
3599 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, 3545 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop,
3600 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, 3546 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index b6af150c96b8..f8f060ffbf4f 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -132,13 +132,6 @@ nfsd_reply_cache_alloc(void)
132} 132}
133 133
134static void 134static void
135nfsd_reply_cache_unhash(struct svc_cacherep *rp)
136{
137 hlist_del_init(&rp->c_hash);
138 list_del_init(&rp->c_lru);
139}
140
141static void
142nfsd_reply_cache_free_locked(struct svc_cacherep *rp) 135nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
143{ 136{
144 if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) { 137 if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) {
@@ -416,22 +409,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
416 409
417 /* 410 /*
418 * Since the common case is a cache miss followed by an insert, 411 * Since the common case is a cache miss followed by an insert,
419 * preallocate an entry. First, try to reuse the first entry on the LRU 412 * preallocate an entry.
420 * if it works, then go ahead and prune the LRU list.
421 */ 413 */
422 spin_lock(&cache_lock);
423 if (!list_empty(&lru_head)) {
424 rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
425 if (nfsd_cache_entry_expired(rp) ||
426 num_drc_entries >= max_drc_entries) {
427 nfsd_reply_cache_unhash(rp);
428 prune_cache_entries();
429 goto search_cache;
430 }
431 }
432
433 /* No expired ones available, allocate a new one. */
434 spin_unlock(&cache_lock);
435 rp = nfsd_reply_cache_alloc(); 414 rp = nfsd_reply_cache_alloc();
436 spin_lock(&cache_lock); 415 spin_lock(&cache_lock);
437 if (likely(rp)) { 416 if (likely(rp)) {
@@ -439,7 +418,9 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
439 drc_mem_usage += sizeof(*rp); 418 drc_mem_usage += sizeof(*rp);
440 } 419 }
441 420
442search_cache: 421 /* go ahead and prune the cache */
422 prune_cache_entries();
423
443 found = nfsd_cache_search(rqstp, csum); 424 found = nfsd_cache_search(rqstp, csum);
444 if (found) { 425 if (found) {
445 if (likely(rp)) 426 if (likely(rp))
@@ -453,15 +434,6 @@ search_cache:
453 goto out; 434 goto out;
454 } 435 }
455 436
456 /*
457 * We're keeping the one we just allocated. Are we now over the
458 * limit? Prune one off the tip of the LRU in trade for the one we
459 * just allocated if so.
460 */
461 if (num_drc_entries >= max_drc_entries)
462 nfsd_reply_cache_free_locked(list_first_entry(&lru_head,
463 struct svc_cacherep, c_lru));
464
465 nfsdstats.rcmisses++; 437 nfsdstats.rcmisses++;
466 rqstp->rq_cacherep = rp; 438 rqstp->rq_cacherep = rp;
467 rp->c_state = RC_INPROG; 439 rp->c_state = RC_INPROG;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 760c85a6f534..9a4a5f9e7468 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -241,6 +241,15 @@ static void nfsd_shutdown_generic(void)
241 nfsd_racache_shutdown(); 241 nfsd_racache_shutdown();
242} 242}
243 243
244static bool nfsd_needs_lockd(void)
245{
246#if defined(CONFIG_NFSD_V3)
247 return (nfsd_versions[2] != NULL) || (nfsd_versions[3] != NULL);
248#else
249 return (nfsd_versions[2] != NULL);
250#endif
251}
252
244static int nfsd_startup_net(int nrservs, struct net *net) 253static int nfsd_startup_net(int nrservs, struct net *net)
245{ 254{
246 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 255 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
@@ -255,9 +264,14 @@ static int nfsd_startup_net(int nrservs, struct net *net)
255 ret = nfsd_init_socks(net); 264 ret = nfsd_init_socks(net);
256 if (ret) 265 if (ret)
257 goto out_socks; 266 goto out_socks;
258 ret = lockd_up(net); 267
259 if (ret) 268 if (nfsd_needs_lockd() && !nn->lockd_up) {
260 goto out_socks; 269 ret = lockd_up(net);
270 if (ret)
271 goto out_socks;
272 nn->lockd_up = 1;
273 }
274
261 ret = nfs4_state_start_net(net); 275 ret = nfs4_state_start_net(net);
262 if (ret) 276 if (ret)
263 goto out_lockd; 277 goto out_lockd;
@@ -266,7 +280,10 @@ static int nfsd_startup_net(int nrservs, struct net *net)
266 return 0; 280 return 0;
267 281
268out_lockd: 282out_lockd:
269 lockd_down(net); 283 if (nn->lockd_up) {
284 lockd_down(net);
285 nn->lockd_up = 0;
286 }
270out_socks: 287out_socks:
271 nfsd_shutdown_generic(); 288 nfsd_shutdown_generic();
272 return ret; 289 return ret;
@@ -277,7 +294,10 @@ static void nfsd_shutdown_net(struct net *net)
277 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 294 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
278 295
279 nfs4_state_shutdown_net(net); 296 nfs4_state_shutdown_net(net);
280 lockd_down(net); 297 if (nn->lockd_up) {
298 lockd_down(net);
299 nn->lockd_up = 0;
300 }
281 nn->nfsd_net_up = false; 301 nn->nfsd_net_up = false;
282 nfsd_shutdown_generic(); 302 nfsd_shutdown_generic();
283} 303}
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 9c769a47ac5a..b17d93214d01 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -152,7 +152,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
152 type = (stat->mode & S_IFMT); 152 type = (stat->mode & S_IFMT);
153 153
154 *p++ = htonl(nfs_ftypes[type >> 12]); 154 *p++ = htonl(nfs_ftypes[type >> 12]);
155 *p++ = htonl((u32) stat->mode); 155 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
156 *p++ = htonl((u32) stat->nlink); 156 *p++ = htonl((u32) stat->nlink);
157 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 157 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
158 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 158 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 1426eb66c8c6..017d3cb5e99b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -207,7 +207,12 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
207 goto out_nfserr; 207 goto out_nfserr;
208 } 208 }
209 } else { 209 } else {
210 fh_lock(fhp); 210 /*
211 * In the nfsd4_open() case, this may be held across
212 * subsequent open and delegation acquisition which may
213 * need to take the child's i_mutex:
214 */
215 fh_lock_nested(fhp, I_MUTEX_PARENT);
211 dentry = lookup_one_len(name, dparent, len); 216 dentry = lookup_one_len(name, dparent, len);
212 host_err = PTR_ERR(dentry); 217 host_err = PTR_ERR(dentry);
213 if (IS_ERR(dentry)) 218 if (IS_ERR(dentry))
@@ -273,13 +278,6 @@ out:
273 return err; 278 return err;
274} 279}
275 280
276static int nfsd_break_lease(struct inode *inode)
277{
278 if (!S_ISREG(inode->i_mode))
279 return 0;
280 return break_lease(inode, O_WRONLY | O_NONBLOCK);
281}
282
283/* 281/*
284 * Commit metadata changes to stable storage. 282 * Commit metadata changes to stable storage.
285 */ 283 */
@@ -348,8 +346,7 @@ nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap)
348 346
349 /* Revoke setuid/setgid on chown */ 347 /* Revoke setuid/setgid on chown */
350 if (!S_ISDIR(inode->i_mode) && 348 if (!S_ISDIR(inode->i_mode) &&
351 (((iap->ia_valid & ATTR_UID) && !uid_eq(iap->ia_uid, inode->i_uid)) || 349 ((iap->ia_valid & ATTR_UID) || (iap->ia_valid & ATTR_GID))) {
352 ((iap->ia_valid & ATTR_GID) && !gid_eq(iap->ia_gid, inode->i_gid)))) {
353 iap->ia_valid |= ATTR_KILL_PRIV; 350 iap->ia_valid |= ATTR_KILL_PRIV;
354 if (iap->ia_valid & ATTR_MODE) { 351 if (iap->ia_valid & ATTR_MODE) {
355 /* we're setting mode too, just clear the s*id bits */ 352 /* we're setting mode too, just clear the s*id bits */
@@ -449,16 +446,10 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
449 goto out_put_write_access; 446 goto out_put_write_access;
450 } 447 }
451 448
452 host_err = nfsd_break_lease(inode);
453 if (host_err)
454 goto out_put_write_access_nfserror;
455
456 fh_lock(fhp); 449 fh_lock(fhp);
457 host_err = notify_change(dentry, iap, NULL); 450 host_err = notify_change(dentry, iap, NULL);
458 fh_unlock(fhp); 451 fh_unlock(fhp);
459 452
460out_put_write_access_nfserror:
461 err = nfserrno(host_err);
462out_put_write_access: 453out_put_write_access:
463 if (size_change) 454 if (size_change)
464 put_write_access(inode); 455 put_write_access(inode);
@@ -1609,11 +1600,6 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1609 err = nfserr_noent; 1600 err = nfserr_noent;
1610 if (!dold->d_inode) 1601 if (!dold->d_inode)
1611 goto out_dput; 1602 goto out_dput;
1612 host_err = nfsd_break_lease(dold->d_inode);
1613 if (host_err) {
1614 err = nfserrno(host_err);
1615 goto out_dput;
1616 }
1617 host_err = vfs_link(dold, dirp, dnew, NULL); 1603 host_err = vfs_link(dold, dirp, dnew, NULL);
1618 if (!host_err) { 1604 if (!host_err) {
1619 err = nfserrno(commit_metadata(ffhp)); 1605 err = nfserrno(commit_metadata(ffhp));
@@ -1707,14 +1693,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1707 if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) 1693 if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry)
1708 goto out_dput_new; 1694 goto out_dput_new;
1709 1695
1710 host_err = nfsd_break_lease(odentry->d_inode);
1711 if (host_err)
1712 goto out_dput_new;
1713 if (ndentry->d_inode) {
1714 host_err = nfsd_break_lease(ndentry->d_inode);
1715 if (host_err)
1716 goto out_dput_new;
1717 }
1718 host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); 1696 host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
1719 if (!host_err) { 1697 if (!host_err) {
1720 host_err = commit_metadata(tfhp); 1698 host_err = commit_metadata(tfhp);
@@ -1784,16 +1762,12 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1784 if (!type) 1762 if (!type)
1785 type = rdentry->d_inode->i_mode & S_IFMT; 1763 type = rdentry->d_inode->i_mode & S_IFMT;
1786 1764
1787 host_err = nfsd_break_lease(rdentry->d_inode);
1788 if (host_err)
1789 goto out_put;
1790 if (type != S_IFDIR) 1765 if (type != S_IFDIR)
1791 host_err = vfs_unlink(dirp, rdentry, NULL); 1766 host_err = vfs_unlink(dirp, rdentry, NULL);
1792 else 1767 else
1793 host_err = vfs_rmdir(dirp, rdentry); 1768 host_err = vfs_rmdir(dirp, rdentry);
1794 if (!host_err) 1769 if (!host_err)
1795 host_err = commit_metadata(fhp); 1770 host_err = commit_metadata(fhp);
1796out_put:
1797 dput(rdentry); 1771 dput(rdentry);
1798 1772
1799out_nfserr: 1773out_nfserr:
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 1bc1d440a1a5..fbe90bdb2214 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -86,8 +86,6 @@ __be32 nfsd_link(struct svc_rqst *, struct svc_fh *,
86__be32 nfsd_rename(struct svc_rqst *, 86__be32 nfsd_rename(struct svc_rqst *,
87 struct svc_fh *, char *, int, 87 struct svc_fh *, char *, int,
88 struct svc_fh *, char *, int); 88 struct svc_fh *, char *, int);
89__be32 nfsd_remove(struct svc_rqst *,
90 struct svc_fh *, char *, int);
91__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, 89__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
92 char *name, int len); 90 char *name, int len);
93__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, 91__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index b6d5542a4ac8..335e04aaf7db 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -174,6 +174,9 @@ struct nfsd3_linkres {
174struct nfsd3_readdirres { 174struct nfsd3_readdirres {
175 __be32 status; 175 __be32 status;
176 struct svc_fh fh; 176 struct svc_fh fh;
177 /* Just to save kmalloc on every readdirplus entry (svc_fh is a
178 * little large for the stack): */
179 struct svc_fh scratch;
177 int count; 180 int count;
178 __be32 verf[2]; 181 __be32 verf[2];
179 182
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index b3ed6446ed8e..d278a0d03496 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -228,7 +228,7 @@ struct nfsd4_open {
228 u32 op_create; /* request */ 228 u32 op_create; /* request */
229 u32 op_createmode; /* request */ 229 u32 op_createmode; /* request */
230 u32 op_bmval[3]; /* request */ 230 u32 op_bmval[3]; /* request */
231 struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ 231 struct iattr op_iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
232 nfs4_verifier op_verf __attribute__((aligned(32))); 232 nfs4_verifier op_verf __attribute__((aligned(32)));
233 /* EXCLUSIVE4 */ 233 /* EXCLUSIVE4 */
234 clientid_t op_clientid; /* request */ 234 clientid_t op_clientid; /* request */
@@ -250,7 +250,6 @@ struct nfsd4_open {
250 struct nfs4_acl *op_acl; 250 struct nfs4_acl *op_acl;
251 struct xdr_netobj op_label; 251 struct xdr_netobj op_label;
252}; 252};
253#define op_iattr iattr
254 253
255struct nfsd4_open_confirm { 254struct nfsd4_open_confirm {
256 stateid_t oc_req_stateid /* request */; 255 stateid_t oc_req_stateid /* request */;
@@ -374,7 +373,6 @@ struct nfsd4_test_stateid {
374 373
375struct nfsd4_free_stateid { 374struct nfsd4_free_stateid {
376 stateid_t fr_stateid; /* request */ 375 stateid_t fr_stateid; /* request */
377 __be32 fr_status; /* response */
378}; 376};
379 377
380/* also used for NVERIFY */ 378/* also used for NVERIFY */