aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/nfs/nfs41-server.txt2
-rw-r--r--fs/lockd/clnt4xdr.c2
-rw-r--r--fs/lockd/clntxdr.c2
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/lockd/svcsubs.c3
-rw-r--r--fs/lockd/xdr.c2
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfsd/acl.h2
-rw-r--r--fs/nfsd/auth.c5
-rw-r--r--fs/nfsd/export.c88
-rw-r--r--fs/nfsd/export.h (renamed from include/linux/nfsd/export.h)14
-rw-r--r--fs/nfsd/fault_inject.c15
-rw-r--r--fs/nfsd/idmap.h4
-rw-r--r--fs/nfsd/nfs2acl.c12
-rw-r--r--fs/nfsd/nfs3acl.c6
-rw-r--r--fs/nfsd/nfs3xdr.c27
-rw-r--r--fs/nfsd/nfs4acl.c12
-rw-r--r--fs/nfsd/nfs4idmap.c42
-rw-r--r--fs/nfsd/nfs4proc.c180
-rw-r--r--fs/nfsd/nfs4state.c271
-rw-r--r--fs/nfsd/nfs4xdr.c1933
-rw-r--r--fs/nfsd/nfscache.c17
-rw-r--r--fs/nfsd/nfsctl.c1
-rw-r--r--fs/nfsd/nfsd.h17
-rw-r--r--fs/nfsd/nfsfh.c25
-rw-r--r--fs/nfsd/nfsfh.h59
-rw-r--r--fs/nfsd/nfssvc.c6
-rw-r--r--fs/nfsd/nfsxdr.c15
-rw-r--r--fs/nfsd/state.h5
-rw-r--r--fs/nfsd/stats.c1
-rw-r--r--fs/nfsd/stats.h (renamed from include/linux/nfsd/stats.h)8
-rw-r--r--fs/nfsd/vfs.c155
-rw-r--r--fs/nfsd/vfs.h10
-rw-r--r--fs/nfsd/xdr4.h23
-rw-r--r--include/linux/lockd/lockd.h2
-rw-r--r--include/linux/nfs4.h2
-rw-r--r--include/linux/nfsd/debug.h19
-rw-r--r--include/linux/nfsd/nfsfh.h63
-rw-r--r--include/linux/sunrpc/svc.h13
-rw-r--r--include/linux/sunrpc/svc_rdma.h3
-rw-r--r--include/linux/sunrpc/svc_xprt.h2
-rw-r--r--include/linux/sunrpc/xdr.h3
-rw-r--r--include/uapi/linux/nfsd/nfsfh.h32
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/cache.c2
-rw-r--r--net/sunrpc/sunrpc.h13
-rw-r--r--net/sunrpc/svc_xprt.c5
-rw-r--r--net/sunrpc/svcauth.c2
-rw-r--r--net/sunrpc/svcsock.c17
-rw-r--r--net/sunrpc/xdr.c174
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c643
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c230
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c69
53 files changed, 2265 insertions, 1999 deletions
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt
index b930ad087780..c49cd7e796e7 100644
--- a/Documentation/filesystems/nfs/nfs41-server.txt
+++ b/Documentation/filesystems/nfs/nfs41-server.txt
@@ -176,7 +176,5 @@ Nonstandard compound limitations:
176 ca_maxrequestsize request and a ca_maxresponsesize reply, so we may 176 ca_maxrequestsize request and a ca_maxresponsesize reply, so we may
177 fail to live up to the promise we made in CREATE_SESSION fore channel 177 fail to live up to the promise we made in CREATE_SESSION fore channel
178 negotiation. 178 negotiation.
179* No more than one read-like operation allowed per compound; encoding
180 replies that cross page boundaries (except for read data) not handled.
181 179
182See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues. 180See also http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues.
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
index 00ec0b9c94d1..d3e40db28930 100644
--- a/fs/lockd/clnt4xdr.c
+++ b/fs/lockd/clnt4xdr.c
@@ -14,6 +14,8 @@
14#include <linux/sunrpc/stats.h> 14#include <linux/sunrpc/stats.h>
15#include <linux/lockd/lockd.h> 15#include <linux/lockd/lockd.h>
16 16
17#include <uapi/linux/nfs3.h>
18
17#define NLMDBG_FACILITY NLMDBG_XDR 19#define NLMDBG_FACILITY NLMDBG_XDR
18 20
19#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) 21#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
index 9a55797a1cd4..3e9f7874b975 100644
--- a/fs/lockd/clntxdr.c
+++ b/fs/lockd/clntxdr.c
@@ -15,6 +15,8 @@
15#include <linux/sunrpc/stats.h> 15#include <linux/sunrpc/stats.h>
16#include <linux/lockd/lockd.h> 16#include <linux/lockd/lockd.h>
17 17
18#include <uapi/linux/nfs2.h>
19
18#define NLMDBG_FACILITY NLMDBG_XDR 20#define NLMDBG_FACILITY NLMDBG_XDR
19 21
20#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) 22#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index de051cb1f553..8f27c93f8d2e 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -622,8 +622,8 @@ static int __init init_nlm(void)
622err_pernet: 622err_pernet:
623#ifdef CONFIG_SYSCTL 623#ifdef CONFIG_SYSCTL
624 unregister_sysctl_table(nlm_sysctl_table); 624 unregister_sysctl_table(nlm_sysctl_table);
625#endif
626err_sysctl: 625err_sysctl:
626#endif
627 return err; 627 return err;
628} 628}
629 629
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index dc5c75930f0f..b6f3b84b6e99 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -14,12 +14,11 @@
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/sunrpc/svc.h> 15#include <linux/sunrpc/svc.h>
16#include <linux/sunrpc/addr.h> 16#include <linux/sunrpc/addr.h>
17#include <linux/nfsd/nfsfh.h>
18#include <linux/nfsd/export.h>
19#include <linux/lockd/lockd.h> 17#include <linux/lockd/lockd.h>
20#include <linux/lockd/share.h> 18#include <linux/lockd/share.h>
21#include <linux/module.h> 19#include <linux/module.h>
22#include <linux/mount.h> 20#include <linux/mount.h>
21#include <uapi/linux/nfs2.h>
23 22
24#define NLMDBG_FACILITY NLMDBG_SVCSUBS 23#define NLMDBG_FACILITY NLMDBG_SVCSUBS
25 24
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 964666c68a86..9340e7e10ef6 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -16,6 +16,8 @@
16#include <linux/sunrpc/stats.h> 16#include <linux/sunrpc/stats.h>
17#include <linux/lockd/lockd.h> 17#include <linux/lockd/lockd.h>
18 18
19#include <uapi/linux/nfs2.h>
20
19#define NLMDBG_FACILITY NLMDBG_XDR 21#define NLMDBG_FACILITY NLMDBG_XDR
20 22
21 23
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 397be39c6dc8..7f55fed8dc64 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2750,7 +2750,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
2750 2750
2751#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) 2751#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
2752#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) 2752#define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
2753#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL) 2753#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_SECURITY_LABEL - 1UL)
2754 2754
2755static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 2755static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
2756{ 2756{
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index b481e1f5eecc..a986ceb6fd0d 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -49,7 +49,7 @@ struct svc_rqst;
49 49
50struct nfs4_acl *nfs4_acl_new(int); 50struct nfs4_acl *nfs4_acl_new(int);
51int nfs4_acl_get_whotype(char *, u32); 51int nfs4_acl_get_whotype(char *, u32);
52__be32 nfs4_acl_write_who(int who, __be32 **p, int *len); 52__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who);
53 53
54int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, 54int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
55 struct nfs4_acl **acl); 55 struct nfs4_acl **acl);
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 2645be435e75..72f44823adbb 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -1,7 +1,6 @@
1/* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */ 1/* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2 2
3#include <linux/sched.h> 3#include <linux/sched.h>
4#include <linux/user_namespace.h>
5#include "nfsd.h" 4#include "nfsd.h"
6#include "auth.h" 5#include "auth.h"
7 6
@@ -25,7 +24,6 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
25 struct cred *new; 24 struct cred *new;
26 int i; 25 int i;
27 int flags = nfsexp_flags(rqstp, exp); 26 int flags = nfsexp_flags(rqstp, exp);
28 int ret;
29 27
30 validate_process_creds(); 28 validate_process_creds();
31 29
@@ -86,8 +84,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
86 return 0; 84 return 0;
87 85
88oom: 86oom:
89 ret = -ENOMEM;
90 abort_creds(new); 87 abort_creds(new);
91 return ret; 88 return -ENOMEM;
92} 89}
93 90
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 8513c598fabf..13b85f94d9e2 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -17,17 +17,12 @@
17#include <linux/exportfs.h> 17#include <linux/exportfs.h>
18#include <linux/sunrpc/svc_xprt.h> 18#include <linux/sunrpc/svc_xprt.h>
19 19
20#include <net/ipv6.h>
21
22#include "nfsd.h" 20#include "nfsd.h"
23#include "nfsfh.h" 21#include "nfsfh.h"
24#include "netns.h" 22#include "netns.h"
25 23
26#define NFSDDBG_FACILITY NFSDDBG_EXPORT 24#define NFSDDBG_FACILITY NFSDDBG_EXPORT
27 25
28typedef struct auth_domain svc_client;
29typedef struct svc_export svc_export;
30
31/* 26/*
32 * We have two caches. 27 * We have two caches.
33 * One maps client+vfsmnt+dentry to export options - the export map 28 * One maps client+vfsmnt+dentry to export options - the export map
@@ -73,7 +68,7 @@ static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_
73 68
74static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) 69static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
75{ 70{
76 /* client fsidtype fsid [path] */ 71 /* client fsidtype fsid expiry [path] */
77 char *buf; 72 char *buf;
78 int len; 73 int len;
79 struct auth_domain *dom = NULL; 74 struct auth_domain *dom = NULL;
@@ -295,13 +290,19 @@ svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
295 290
296static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) 291static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
297{ 292{
293 struct nfsd4_fs_location *locations = fsloc->locations;
298 int i; 294 int i;
299 295
296 if (!locations)
297 return;
298
300 for (i = 0; i < fsloc->locations_count; i++) { 299 for (i = 0; i < fsloc->locations_count; i++) {
301 kfree(fsloc->locations[i].path); 300 kfree(locations[i].path);
302 kfree(fsloc->locations[i].hosts); 301 kfree(locations[i].hosts);
303 } 302 }
304 kfree(fsloc->locations); 303
304 kfree(locations);
305 fsloc->locations = NULL;
305} 306}
306 307
307static void svc_export_put(struct kref *ref) 308static void svc_export_put(struct kref *ref)
@@ -388,6 +389,10 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
388 int len; 389 int len;
389 int migrated, i, err; 390 int migrated, i, err;
390 391
392 /* more than one fsloc */
393 if (fsloc->locations)
394 return -EINVAL;
395
391 /* listsize */ 396 /* listsize */
392 err = get_uint(mesg, &fsloc->locations_count); 397 err = get_uint(mesg, &fsloc->locations_count);
393 if (err) 398 if (err)
@@ -437,13 +442,18 @@ out_free_all:
437 442
438static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp) 443static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
439{ 444{
440 int listsize, err;
441 struct exp_flavor_info *f; 445 struct exp_flavor_info *f;
446 u32 listsize;
447 int err;
448
449 /* more than one secinfo */
450 if (exp->ex_nflavors)
451 return -EINVAL;
442 452
443 err = get_int(mesg, &listsize); 453 err = get_uint(mesg, &listsize);
444 if (err) 454 if (err)
445 return err; 455 return err;
446 if (listsize < 0 || listsize > MAX_SECINFO_LIST) 456 if (listsize > MAX_SECINFO_LIST)
447 return -EINVAL; 457 return -EINVAL;
448 458
449 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) { 459 for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
@@ -474,6 +484,27 @@ static inline int
474secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; } 484secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
475#endif 485#endif
476 486
487static inline int
488uuid_parse(char **mesg, char *buf, unsigned char **puuid)
489{
490 int len;
491
492 /* more than one uuid */
493 if (*puuid)
494 return -EINVAL;
495
496 /* expect a 16 byte uuid encoded as \xXXXX... */
497 len = qword_get(mesg, buf, PAGE_SIZE);
498 if (len != EX_UUID_LEN)
499 return -EINVAL;
500
501 *puuid = kmemdup(buf, EX_UUID_LEN, GFP_KERNEL);
502 if (*puuid == NULL)
503 return -ENOMEM;
504
505 return 0;
506}
507
477static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) 508static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
478{ 509{
479 /* client path expiry [flags anonuid anongid fsid] */ 510 /* client path expiry [flags anonuid anongid fsid] */
@@ -552,18 +583,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
552 while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) { 583 while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
553 if (strcmp(buf, "fsloc") == 0) 584 if (strcmp(buf, "fsloc") == 0)
554 err = fsloc_parse(&mesg, buf, &exp.ex_fslocs); 585 err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
555 else if (strcmp(buf, "uuid") == 0) { 586 else if (strcmp(buf, "uuid") == 0)
556 /* expect a 16 byte uuid encoded as \xXXXX... */ 587 err = uuid_parse(&mesg, buf, &exp.ex_uuid);
557 len = qword_get(&mesg, buf, PAGE_SIZE); 588 else if (strcmp(buf, "secinfo") == 0)
558 if (len != 16)
559 err = -EINVAL;
560 else {
561 exp.ex_uuid =
562 kmemdup(buf, 16, GFP_KERNEL);
563 if (exp.ex_uuid == NULL)
564 err = -ENOMEM;
565 }
566 } else if (strcmp(buf, "secinfo") == 0)
567 err = secinfo_parse(&mesg, buf, &exp); 589 err = secinfo_parse(&mesg, buf, &exp);
568 else 590 else
569 /* quietly ignore unknown words and anything 591 /* quietly ignore unknown words and anything
@@ -649,7 +671,7 @@ static int svc_export_show(struct seq_file *m,
649 if (exp->ex_uuid) { 671 if (exp->ex_uuid) {
650 int i; 672 int i;
651 seq_puts(m, ",uuid="); 673 seq_puts(m, ",uuid=");
652 for (i=0; i<16; i++) { 674 for (i = 0; i < EX_UUID_LEN; i++) {
653 if ((i&3) == 0 && i) 675 if ((i&3) == 0 && i)
654 seq_putc(m, ':'); 676 seq_putc(m, ':');
655 seq_printf(m, "%02x", exp->ex_uuid[i]); 677 seq_printf(m, "%02x", exp->ex_uuid[i]);
@@ -771,7 +793,7 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
771 793
772 794
773static struct svc_expkey * 795static struct svc_expkey *
774exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type, 796exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
775 u32 *fsidv, struct cache_req *reqp) 797 u32 *fsidv, struct cache_req *reqp)
776{ 798{
777 struct svc_expkey key, *ek; 799 struct svc_expkey key, *ek;
@@ -793,9 +815,9 @@ exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
793 return ek; 815 return ek;
794} 816}
795 817
796 818static struct svc_export *
797static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp, 819exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
798 const struct path *path, struct cache_req *reqp) 820 const struct path *path, struct cache_req *reqp)
799{ 821{
800 struct svc_export *exp, key; 822 struct svc_export *exp, key;
801 int err; 823 int err;
@@ -819,11 +841,11 @@ static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
819/* 841/*
820 * Find the export entry for a given dentry. 842 * Find the export entry for a given dentry.
821 */ 843 */
822static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp, 844static struct svc_export *
823 struct path *path) 845exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
824{ 846{
825 struct dentry *saved = dget(path->dentry); 847 struct dentry *saved = dget(path->dentry);
826 svc_export *exp = exp_get_by_name(cd, clp, path, NULL); 848 struct svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
827 849
828 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { 850 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
829 struct dentry *parent = dget_parent(path->dentry); 851 struct dentry *parent = dget_parent(path->dentry);
@@ -844,7 +866,7 @@ static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
844 * since its harder to fool a kernel module than a user space program. 866 * since its harder to fool a kernel module than a user space program.
845 */ 867 */
846int 868int
847exp_rootfh(struct net *net, svc_client *clp, char *name, 869exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
848 struct knfsd_fh *f, int maxsize) 870 struct knfsd_fh *f, int maxsize)
849{ 871{
850 struct svc_export *exp; 872 struct svc_export *exp;
diff --git a/include/linux/nfsd/export.h b/fs/nfsd/export.h
index 7898c997dfea..cfeea85c5bed 100644
--- a/include/linux/nfsd/export.h
+++ b/fs/nfsd/export.h
@@ -1,17 +1,16 @@
1/* 1/*
2 * include/linux/nfsd/export.h
3 *
4 * Public declarations for NFS exports. The definitions for the
5 * syscall interface are in nfsctl.h
6 *
7 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> 2 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
8 */ 3 */
9#ifndef NFSD_EXPORT_H 4#ifndef NFSD_EXPORT_H
10#define NFSD_EXPORT_H 5#define NFSD_EXPORT_H
11 6
12# include <linux/nfsd/nfsfh.h> 7#include <linux/sunrpc/cache.h>
13#include <uapi/linux/nfsd/export.h> 8#include <uapi/linux/nfsd/export.h>
14 9
10struct knfsd_fh;
11struct svc_fh;
12struct svc_rqst;
13
15/* 14/*
16 * FS Locations 15 * FS Locations
17 */ 16 */
@@ -38,6 +37,7 @@ struct nfsd4_fs_locations {
38 * spkm3i, and spkm3p (and using all 8 at once should be rare). 37 * spkm3i, and spkm3p (and using all 8 at once should be rare).
39 */ 38 */
40#define MAX_SECINFO_LIST 8 39#define MAX_SECINFO_LIST 8
40#define EX_UUID_LEN 16
41 41
42struct exp_flavor_info { 42struct exp_flavor_info {
43 u32 pseudoflavor; 43 u32 pseudoflavor;
@@ -54,7 +54,7 @@ struct svc_export {
54 int ex_fsid; 54 int ex_fsid;
55 unsigned char * ex_uuid; /* 16 byte fsid */ 55 unsigned char * ex_uuid; /* 16 byte fsid */
56 struct nfsd4_fs_locations ex_fslocs; 56 struct nfsd4_fs_locations ex_fslocs;
57 int ex_nflavors; 57 uint32_t ex_nflavors;
58 struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST]; 58 struct exp_flavor_info ex_flavors[MAX_SECINFO_LIST];
59 struct cache_detail *cd; 59 struct cache_detail *cd;
60}; 60};
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index d620e7f81429..2ed05c3cd43d 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -97,25 +97,14 @@ static ssize_t fault_inject_read(struct file *file, char __user *buf,
97{ 97{
98 static u64 val; 98 static u64 val;
99 char read_buf[25]; 99 char read_buf[25];
100 size_t size, ret; 100 size_t size;
101 loff_t pos = *ppos; 101 loff_t pos = *ppos;
102 102
103 if (!pos) 103 if (!pos)
104 nfsd_inject_get(file_inode(file)->i_private, &val); 104 nfsd_inject_get(file_inode(file)->i_private, &val);
105 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val); 105 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);
106 106
107 if (pos < 0) 107 return simple_read_from_buffer(buf, len, ppos, read_buf, size);
108 return -EINVAL;
109 if (pos >= size || !len)
110 return 0;
111 if (len > size - pos)
112 len = size - pos;
113 ret = copy_to_user(buf, read_buf + pos, len);
114 if (ret == len)
115 return -EFAULT;
116 len -= ret;
117 *ppos = pos + len;
118 return len;
119} 108}
120 109
121static ssize_t fault_inject_write(struct file *file, const char __user *buf, 110static ssize_t fault_inject_write(struct file *file, const char __user *buf,
diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h
index 66e58db01936..a3f34900091f 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 *);
59__be32 nfsd4_encode_user(struct svc_rqst *, kuid_t, __be32 **, int *); 59__be32 nfsd4_encode_user(struct xdr_stream *, struct svc_rqst *, kuid_t);
60__be32 nfsd4_encode_group(struct svc_rqst *, kgid_t, __be32 **, int *); 60__be32 nfsd4_encode_group(struct xdr_stream *, struct svc_rqst *, kgid_t);
61 61
62#endif /* LINUX_NFSD_IDMAP_H */ 62#endif /* LINUX_NFSD_IDMAP_H */
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 11c1fba29312..12b023a7ab7d 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -182,7 +182,8 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessarg
182static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, 182static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
183 struct nfsd3_getaclargs *argp) 183 struct nfsd3_getaclargs *argp)
184{ 184{
185 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 185 p = nfs2svc_decode_fh(p, &argp->fh);
186 if (!p)
186 return 0; 187 return 0;
187 argp->mask = ntohl(*p); p++; 188 argp->mask = ntohl(*p); p++;
188 189
@@ -197,7 +198,8 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
197 unsigned int base; 198 unsigned int base;
198 int n; 199 int n;
199 200
200 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 201 p = nfs2svc_decode_fh(p, &argp->fh);
202 if (!p)
201 return 0; 203 return 0;
202 argp->mask = ntohl(*p++); 204 argp->mask = ntohl(*p++);
203 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) || 205 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
@@ -218,7 +220,8 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
218static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p, 220static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p,
219 struct nfsd_fhandle *argp) 221 struct nfsd_fhandle *argp)
220{ 222{
221 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 223 p = nfs2svc_decode_fh(p, &argp->fh);
224 if (!p)
222 return 0; 225 return 0;
223 return xdr_argsize_check(rqstp, p); 226 return xdr_argsize_check(rqstp, p);
224} 227}
@@ -226,7 +229,8 @@ static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p,
226static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, 229static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
227 struct nfsd3_accessargs *argp) 230 struct nfsd3_accessargs *argp)
228{ 231{
229 if (!(p = nfs2svc_decode_fh(p, &argp->fh))) 232 p = nfs2svc_decode_fh(p, &argp->fh);
233 if (!p)
230 return 0; 234 return 0;
231 argp->access = ntohl(*p++); 235 argp->access = ntohl(*p++);
232 236
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index adc5f1b1dc26..2a514e21dc74 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -128,7 +128,8 @@ out:
128static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, 128static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
129 struct nfsd3_getaclargs *args) 129 struct nfsd3_getaclargs *args)
130{ 130{
131 if (!(p = nfs3svc_decode_fh(p, &args->fh))) 131 p = nfs3svc_decode_fh(p, &args->fh);
132 if (!p)
132 return 0; 133 return 0;
133 args->mask = ntohl(*p); p++; 134 args->mask = ntohl(*p); p++;
134 135
@@ -143,7 +144,8 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
143 unsigned int base; 144 unsigned int base;
144 int n; 145 int n;
145 146
146 if (!(p = nfs3svc_decode_fh(p, &args->fh))) 147 p = nfs3svc_decode_fh(p, &args->fh);
148 if (!p)
147 return 0; 149 return 0;
148 args->mask = ntohl(*p++); 150 args->mask = ntohl(*p++);
149 if (args->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) || 151 if (args->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index de6e39e12cb3..e6c01e80325e 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -278,7 +278,8 @@ void fill_post_wcc(struct svc_fh *fhp)
278int 278int
279nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) 279nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
280{ 280{
281 if (!(p = decode_fh(p, &args->fh))) 281 p = decode_fh(p, &args->fh);
282 if (!p)
282 return 0; 283 return 0;
283 return xdr_argsize_check(rqstp, p); 284 return xdr_argsize_check(rqstp, p);
284} 285}
@@ -287,7 +288,8 @@ int
287nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, 288nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
288 struct nfsd3_sattrargs *args) 289 struct nfsd3_sattrargs *args)
289{ 290{
290 if (!(p = decode_fh(p, &args->fh))) 291 p = decode_fh(p, &args->fh);
292 if (!p)
291 return 0; 293 return 0;
292 p = decode_sattr3(p, &args->attrs); 294 p = decode_sattr3(p, &args->attrs);
293 295
@@ -315,7 +317,8 @@ int
315nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, 317nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
316 struct nfsd3_accessargs *args) 318 struct nfsd3_accessargs *args)
317{ 319{
318 if (!(p = decode_fh(p, &args->fh))) 320 p = decode_fh(p, &args->fh);
321 if (!p)
319 return 0; 322 return 0;
320 args->access = ntohl(*p++); 323 args->access = ntohl(*p++);
321 324
@@ -330,7 +333,8 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
330 int v; 333 int v;
331 u32 max_blocksize = svc_max_payload(rqstp); 334 u32 max_blocksize = svc_max_payload(rqstp);
332 335
333 if (!(p = decode_fh(p, &args->fh))) 336 p = decode_fh(p, &args->fh);
337 if (!p)
334 return 0; 338 return 0;
335 p = xdr_decode_hyper(p, &args->offset); 339 p = xdr_decode_hyper(p, &args->offset);
336 340
@@ -360,7 +364,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
360 unsigned int len, v, hdr, dlen; 364 unsigned int len, v, hdr, dlen;
361 u32 max_blocksize = svc_max_payload(rqstp); 365 u32 max_blocksize = svc_max_payload(rqstp);
362 366
363 if (!(p = decode_fh(p, &args->fh))) 367 p = decode_fh(p, &args->fh);
368 if (!p)
364 return 0; 369 return 0;
365 p = xdr_decode_hyper(p, &args->offset); 370 p = xdr_decode_hyper(p, &args->offset);
366 371
@@ -535,7 +540,8 @@ int
535nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, 540nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
536 struct nfsd3_readlinkargs *args) 541 struct nfsd3_readlinkargs *args)
537{ 542{
538 if (!(p = decode_fh(p, &args->fh))) 543 p = decode_fh(p, &args->fh);
544 if (!p)
539 return 0; 545 return 0;
540 args->buffer = page_address(*(rqstp->rq_next_page++)); 546 args->buffer = page_address(*(rqstp->rq_next_page++));
541 547
@@ -558,7 +564,8 @@ int
558nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, 564nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
559 struct nfsd3_readdirargs *args) 565 struct nfsd3_readdirargs *args)
560{ 566{
561 if (!(p = decode_fh(p, &args->fh))) 567 p = decode_fh(p, &args->fh);
568 if (!p)
562 return 0; 569 return 0;
563 p = xdr_decode_hyper(p, &args->cookie); 570 p = xdr_decode_hyper(p, &args->cookie);
564 args->verf = p; p += 2; 571 args->verf = p; p += 2;
@@ -580,7 +587,8 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
580 int len; 587 int len;
581 u32 max_blocksize = svc_max_payload(rqstp); 588 u32 max_blocksize = svc_max_payload(rqstp);
582 589
583 if (!(p = decode_fh(p, &args->fh))) 590 p = decode_fh(p, &args->fh);
591 if (!p)
584 return 0; 592 return 0;
585 p = xdr_decode_hyper(p, &args->cookie); 593 p = xdr_decode_hyper(p, &args->cookie);
586 args->verf = p; p += 2; 594 args->verf = p; p += 2;
@@ -605,7 +613,8 @@ int
605nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p, 613nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p,
606 struct nfsd3_commitargs *args) 614 struct nfsd3_commitargs *args)
607{ 615{
608 if (!(p = decode_fh(p, &args->fh))) 616 p = decode_fh(p, &args->fh);
617 if (!p)
609 return 0; 618 return 0;
610 p = xdr_decode_hyper(p, &args->offset); 619 p = xdr_decode_hyper(p, &args->offset);
611 args->count = ntohl(*p++); 620 args->count = ntohl(*p++);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index f66c66b9f182..d714156a19fd 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -36,7 +36,6 @@
36 36
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/nfs_fs.h> 38#include <linux/nfs_fs.h>
39#include <linux/export.h>
40#include "nfsfh.h" 39#include "nfsfh.h"
41#include "nfsd.h" 40#include "nfsd.h"
42#include "acl.h" 41#include "acl.h"
@@ -920,20 +919,19 @@ nfs4_acl_get_whotype(char *p, u32 len)
920 return NFS4_ACL_WHO_NAMED; 919 return NFS4_ACL_WHO_NAMED;
921} 920}
922 921
923__be32 nfs4_acl_write_who(int who, __be32 **p, int *len) 922__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who)
924{ 923{
924 __be32 *p;
925 int i; 925 int i;
926 int bytes;
927 926
928 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 927 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
929 if (s2t_map[i].type != who) 928 if (s2t_map[i].type != who)
930 continue; 929 continue;
931 bytes = 4 + (XDR_QUADLEN(s2t_map[i].stringlen) << 2); 930 p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4);
932 if (bytes > *len) 931 if (!p)
933 return nfserr_resource; 932 return nfserr_resource;
934 *p = xdr_encode_opaque(*p, s2t_map[i].string, 933 p = xdr_encode_opaque(p, s2t_map[i].string,
935 s2t_map[i].stringlen); 934 s2t_map[i].stringlen);
936 *len -= bytes;
937 return 0; 935 return 0;
938 } 936 }
939 WARN_ON_ONCE(1); 937 WARN_ON_ONCE(1);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index c0dfde68742e..a0ab0a847d69 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -551,44 +551,43 @@ 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 __be32 encode_ascii_id(u32 id, __be32 **p, int *buflen) 554static __be32 encode_ascii_id(struct xdr_stream *xdr, u32 id)
555{ 555{
556 char buf[11]; 556 char buf[11];
557 int len; 557 int len;
558 int bytes; 558 __be32 *p;
559 559
560 len = sprintf(buf, "%u", id); 560 len = sprintf(buf, "%u", id);
561 bytes = 4 + (XDR_QUADLEN(len) << 2); 561 p = xdr_reserve_space(xdr, len + 4);
562 if (bytes > *buflen) 562 if (!p)
563 return nfserr_resource; 563 return nfserr_resource;
564 *p = xdr_encode_opaque(*p, buf, len); 564 p = xdr_encode_opaque(p, buf, len);
565 *buflen -= bytes;
566 return 0; 565 return 0;
567} 566}
568 567
569static __be32 idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) 568static __be32 idmap_id_to_name(struct xdr_stream *xdr,
569 struct svc_rqst *rqstp, int type, u32 id)
570{ 570{
571 struct ent *item, key = { 571 struct ent *item, key = {
572 .id = id, 572 .id = id,
573 .type = type, 573 .type = type,
574 }; 574 };
575 __be32 *p;
575 int ret; 576 int ret;
576 int bytes;
577 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);
578 578
579 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 579 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
580 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item); 580 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
581 if (ret == -ENOENT) 581 if (ret == -ENOENT)
582 return encode_ascii_id(id, p, buflen); 582 return encode_ascii_id(xdr, id);
583 if (ret) 583 if (ret)
584 return nfserrno(ret); 584 return nfserrno(ret);
585 ret = strlen(item->name); 585 ret = strlen(item->name);
586 WARN_ON_ONCE(ret > IDMAP_NAMESZ); 586 WARN_ON_ONCE(ret > IDMAP_NAMESZ);
587 bytes = 4 + (XDR_QUADLEN(ret) << 2); 587 p = xdr_reserve_space(xdr, ret + 4);
588 if (bytes > *buflen) 588 if (!p)
589 return nfserr_resource; 589 return nfserr_resource;
590 *p = xdr_encode_opaque(*p, item->name, ret); 590 p = xdr_encode_opaque(p, item->name, ret);
591 *buflen -= bytes;
592 cache_put(&item->h, nn->idtoname_cache); 591 cache_put(&item->h, nn->idtoname_cache);
593 return 0; 592 return 0;
594} 593}
@@ -622,11 +621,12 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
622 return idmap_name_to_id(rqstp, type, name, namelen, id); 621 return idmap_name_to_id(rqstp, type, name, namelen, id);
623} 622}
624 623
625static __be32 encode_name_from_id(struct svc_rqst *rqstp, int type, u32 id, __be32 **p, int *buflen) 624static __be32 encode_name_from_id(struct xdr_stream *xdr,
625 struct svc_rqst *rqstp, int type, u32 id)
626{ 626{
627 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)
628 return encode_ascii_id(id, p, buflen); 628 return encode_ascii_id(xdr, id);
629 return idmap_id_to_name(rqstp, type, id, p, buflen); 629 return idmap_id_to_name(xdr, rqstp, type, id);
630} 630}
631 631
632__be32 632__be32
@@ -655,14 +655,16 @@ nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
655 return status; 655 return status;
656} 656}
657 657
658__be32 nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t uid, __be32 **p, int *buflen) 658__be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp,
659 kuid_t uid)
659{ 660{
660 u32 id = from_kuid(&init_user_ns, uid); 661 u32 id = from_kuid(&init_user_ns, uid);
661 return encode_name_from_id(rqstp, IDMAP_TYPE_USER, id, p, buflen); 662 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id);
662} 663}
663 664
664__be32 nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t gid, __be32 **p, int *buflen) 665__be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp,
666 kgid_t gid)
665{ 667{
666 u32 id = from_kgid(&init_user_ns, gid); 668 u32 id = from_kgid(&init_user_ns, gid);
667 return encode_name_from_id(rqstp, IDMAP_TYPE_GROUP, id, p, buflen); 669 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id);
668} 670}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index d543222babf3..6851b003f2a4 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -430,12 +430,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
430 goto out; 430 goto out;
431 break; 431 break;
432 case NFS4_OPEN_CLAIM_PREVIOUS: 432 case NFS4_OPEN_CLAIM_PREVIOUS:
433 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
434 status = nfs4_check_open_reclaim(&open->op_clientid, 433 status = nfs4_check_open_reclaim(&open->op_clientid,
435 cstate->minorversion, 434 cstate->minorversion,
436 nn); 435 nn);
437 if (status) 436 if (status)
438 goto out; 437 goto out;
438 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
439 case NFS4_OPEN_CLAIM_FH: 439 case NFS4_OPEN_CLAIM_FH:
440 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 440 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
441 status = do_open_fhandle(rqstp, cstate, open); 441 status = do_open_fhandle(rqstp, cstate, open);
@@ -445,7 +445,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
445 break; 445 break;
446 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 446 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
447 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 447 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
448 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
449 dprintk("NFSD: unsupported OPEN claim type %d\n", 448 dprintk("NFSD: unsupported OPEN claim type %d\n",
450 open->op_claim_type); 449 open->op_claim_type);
451 status = nfserr_notsupp; 450 status = nfserr_notsupp;
@@ -786,7 +785,6 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
786 if (!nfsd4_last_compound_op(rqstp)) 785 if (!nfsd4_last_compound_op(rqstp))
787 rqstp->rq_splice_ok = false; 786 rqstp->rq_splice_ok = false;
788 787
789 nfs4_lock_state();
790 /* check stateid */ 788 /* check stateid */
791 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), 789 if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
792 cstate, &read->rd_stateid, 790 cstate, &read->rd_stateid,
@@ -794,11 +792,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
794 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 792 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
795 goto out; 793 goto out;
796 } 794 }
797 if (read->rd_filp)
798 get_file(read->rd_filp);
799 status = nfs_ok; 795 status = nfs_ok;
800out: 796out:
801 nfs4_unlock_state();
802 read->rd_rqstp = rqstp; 797 read->rd_rqstp = rqstp;
803 read->rd_fhp = &cstate->current_fh; 798 read->rd_fhp = &cstate->current_fh;
804 return status; 799 return status;
@@ -937,10 +932,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
937 int err; 932 int err;
938 933
939 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 934 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
940 nfs4_lock_state();
941 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate, 935 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
942 &setattr->sa_stateid, WR_STATE, NULL); 936 &setattr->sa_stateid, WR_STATE, NULL);
943 nfs4_unlock_state();
944 if (status) { 937 if (status) {
945 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); 938 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
946 return status; 939 return status;
@@ -1006,17 +999,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1006 if (write->wr_offset >= OFFSET_MAX) 999 if (write->wr_offset >= OFFSET_MAX)
1007 return nfserr_inval; 1000 return nfserr_inval;
1008 1001
1009 nfs4_lock_state();
1010 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), 1002 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
1011 cstate, stateid, WR_STATE, &filp); 1003 cstate, stateid, WR_STATE, &filp);
1012 if (status) { 1004 if (status) {
1013 nfs4_unlock_state();
1014 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); 1005 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
1015 return status; 1006 return status;
1016 } 1007 }
1017 if (filp)
1018 get_file(filp);
1019 nfs4_unlock_state();
1020 1008
1021 cnt = write->wr_buflen; 1009 cnt = write->wr_buflen;
1022 write->wr_how_written = write->wr_stable_how; 1010 write->wr_how_written = write->wr_stable_how;
@@ -1072,10 +1060,10 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1072 return nfserr_jukebox; 1060 return nfserr_jukebox;
1073 1061
1074 p = buf; 1062 p = buf;
1075 status = nfsd4_encode_fattr(&cstate->current_fh, 1063 status = nfsd4_encode_fattr_to_buf(&p, count, &cstate->current_fh,
1076 cstate->current_fh.fh_export, 1064 cstate->current_fh.fh_export,
1077 cstate->current_fh.fh_dentry, &p, 1065 cstate->current_fh.fh_dentry,
1078 count, verify->ve_bmval, 1066 verify->ve_bmval,
1079 rqstp, 0); 1067 rqstp, 0);
1080 /* 1068 /*
1081 * If nfsd4_encode_fattr() ran out of space, assume that's because 1069 * If nfsd4_encode_fattr() ran out of space, assume that's because
@@ -1182,9 +1170,7 @@ struct nfsd4_operation {
1182 1170
1183static struct nfsd4_operation nfsd4_ops[]; 1171static struct nfsd4_operation nfsd4_ops[];
1184 1172
1185#ifdef NFSD_DEBUG
1186static const char *nfsd4_op_name(unsigned opnum); 1173static const char *nfsd4_op_name(unsigned opnum);
1187#endif
1188 1174
1189/* 1175/*
1190 * Enforce NFSv4.1 COMPOUND ordering rules: 1176 * Enforce NFSv4.1 COMPOUND ordering rules:
@@ -1226,6 +1212,8 @@ static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
1226 1212
1227bool nfsd4_cache_this_op(struct nfsd4_op *op) 1213bool nfsd4_cache_this_op(struct nfsd4_op *op)
1228{ 1214{
1215 if (op->opnum == OP_ILLEGAL)
1216 return false;
1229 return OPDESC(op)->op_flags & OP_CACHEME; 1217 return OPDESC(op)->op_flags & OP_CACHEME;
1230} 1218}
1231 1219
@@ -1262,6 +1250,25 @@ static bool need_wrongsec_check(struct svc_rqst *rqstp)
1262 return !(nextd->op_flags & OP_HANDLES_WRONGSEC); 1250 return !(nextd->op_flags & OP_HANDLES_WRONGSEC);
1263} 1251}
1264 1252
1253static void svcxdr_init_encode(struct svc_rqst *rqstp,
1254 struct nfsd4_compoundres *resp)
1255{
1256 struct xdr_stream *xdr = &resp->xdr;
1257 struct xdr_buf *buf = &rqstp->rq_res;
1258 struct kvec *head = buf->head;
1259
1260 xdr->buf = buf;
1261 xdr->iov = head;
1262 xdr->p = head->iov_base + head->iov_len;
1263 xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
1264 /* Tail and page_len should be zero at this point: */
1265 buf->len = buf->head[0].iov_len;
1266 xdr->scratch.iov_len = 0;
1267 xdr->page_ptr = buf->pages - 1;
1268 buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
1269 - rqstp->rq_auth_slack;
1270}
1271
1265/* 1272/*
1266 * COMPOUND call. 1273 * COMPOUND call.
1267 */ 1274 */
@@ -1275,24 +1282,16 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1275 struct nfsd4_compound_state *cstate = &resp->cstate; 1282 struct nfsd4_compound_state *cstate = &resp->cstate;
1276 struct svc_fh *current_fh = &cstate->current_fh; 1283 struct svc_fh *current_fh = &cstate->current_fh;
1277 struct svc_fh *save_fh = &cstate->save_fh; 1284 struct svc_fh *save_fh = &cstate->save_fh;
1278 int slack_bytes;
1279 u32 plen = 0;
1280 __be32 status; 1285 __be32 status;
1281 1286
1282 resp->xbuf = &rqstp->rq_res; 1287 svcxdr_init_encode(rqstp, resp);
1283 resp->p = rqstp->rq_res.head[0].iov_base + 1288 resp->tagp = resp->xdr.p;
1284 rqstp->rq_res.head[0].iov_len;
1285 resp->tagp = resp->p;
1286 /* reserve space for: taglen, tag, and opcnt */ 1289 /* reserve space for: taglen, tag, and opcnt */
1287 resp->p += 2 + XDR_QUADLEN(args->taglen); 1290 xdr_reserve_space(&resp->xdr, 8 + args->taglen);
1288 resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE;
1289 resp->taglen = args->taglen; 1291 resp->taglen = args->taglen;
1290 resp->tag = args->tag; 1292 resp->tag = args->tag;
1291 resp->opcnt = 0;
1292 resp->rqstp = rqstp; 1293 resp->rqstp = rqstp;
1293 cstate->minorversion = args->minorversion; 1294 cstate->minorversion = args->minorversion;
1294 cstate->replay_owner = NULL;
1295 cstate->session = NULL;
1296 fh_init(current_fh, NFS4_FHSIZE); 1295 fh_init(current_fh, NFS4_FHSIZE);
1297 fh_init(save_fh, NFS4_FHSIZE); 1296 fh_init(save_fh, NFS4_FHSIZE);
1298 /* 1297 /*
@@ -1332,19 +1331,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1332 goto encode_op; 1331 goto encode_op;
1333 } 1332 }
1334 1333
1335 /* We must be able to encode a successful response to
1336 * this operation, with enough room left over to encode a
1337 * failed response to the next operation. If we don't
1338 * have enough room, fail with ERR_RESOURCE.
1339 */
1340 slack_bytes = (char *)resp->end - (char *)resp->p;
1341 if (slack_bytes < COMPOUND_SLACK_SPACE
1342 + COMPOUND_ERR_SLACK_SPACE) {
1343 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE);
1344 op->status = nfserr_resource;
1345 goto encode_op;
1346 }
1347
1348 opdesc = OPDESC(op); 1334 opdesc = OPDESC(op);
1349 1335
1350 if (!current_fh->fh_dentry) { 1336 if (!current_fh->fh_dentry) {
@@ -1362,9 +1348,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1362 1348
1363 /* If op is non-idempotent */ 1349 /* If op is non-idempotent */
1364 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1350 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
1365 plen = opdesc->op_rsize_bop(rqstp, op);
1366 /* 1351 /*
1367 * If there's still another operation, make sure 1352 * Don't execute this op if we couldn't encode a
1353 * succesful reply:
1354 */
1355 u32 plen = opdesc->op_rsize_bop(rqstp, op);
1356 /*
1357 * Plus if there's another operation, make sure
1368 * we'll have space to at least encode an error: 1358 * we'll have space to at least encode an error:
1369 */ 1359 */
1370 if (resp->opcnt < args->opcnt) 1360 if (resp->opcnt < args->opcnt)
@@ -1399,7 +1389,7 @@ encode_op:
1399 } 1389 }
1400 if (op->status == nfserr_replay_me) { 1390 if (op->status == nfserr_replay_me) {
1401 op->replay = &cstate->replay_owner->so_replay; 1391 op->replay = &cstate->replay_owner->so_replay;
1402 nfsd4_encode_replay(resp, op); 1392 nfsd4_encode_replay(&resp->xdr, op);
1403 status = op->status = op->replay->rp_status; 1393 status = op->status = op->replay->rp_status;
1404 } else { 1394 } else {
1405 nfsd4_encode_operation(resp, op); 1395 nfsd4_encode_operation(resp, op);
@@ -1438,7 +1428,8 @@ out:
1438#define op_encode_change_info_maxsz (5) 1428#define op_encode_change_info_maxsz (5)
1439#define nfs4_fattr_bitmap_maxsz (4) 1429#define nfs4_fattr_bitmap_maxsz (4)
1440 1430
1441#define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1431/* We'll fall back on returning no lockowner if run out of space: */
1432#define op_encode_lockowner_maxsz (0)
1442#define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz) 1433#define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz)
1443 1434
1444#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1435#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
@@ -1470,6 +1461,49 @@ static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op
1470 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1461 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1471} 1462}
1472 1463
1464/*
1465 * Note since this is an idempotent operation we won't insist on failing
1466 * the op prematurely if the estimate is too large. We may turn off splice
1467 * reads unnecessarily.
1468 */
1469static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
1470 struct nfsd4_op *op)
1471{
1472 u32 *bmap = op->u.getattr.ga_bmval;
1473 u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2];
1474 u32 ret = 0;
1475
1476 if (bmap0 & FATTR4_WORD0_ACL)
1477 return svc_max_payload(rqstp);
1478 if (bmap0 & FATTR4_WORD0_FS_LOCATIONS)
1479 return svc_max_payload(rqstp);
1480
1481 if (bmap1 & FATTR4_WORD1_OWNER) {
1482 ret += IDMAP_NAMESZ + 4;
1483 bmap1 &= ~FATTR4_WORD1_OWNER;
1484 }
1485 if (bmap1 & FATTR4_WORD1_OWNER_GROUP) {
1486 ret += IDMAP_NAMESZ + 4;
1487 bmap1 &= ~FATTR4_WORD1_OWNER_GROUP;
1488 }
1489 if (bmap0 & FATTR4_WORD0_FILEHANDLE) {
1490 ret += NFS4_FHSIZE + 4;
1491 bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
1492 }
1493 if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
1494 ret += NFSD4_MAX_SEC_LABEL_LEN + 12;
1495 bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
1496 }
1497 /*
1498 * Largest of remaining attributes are 16 bytes (e.g.,
1499 * supported_attributes)
1500 */
1501 ret += 16 * (hweight32(bmap0) + hweight32(bmap1) + hweight32(bmap2));
1502 /* bitmask, length */
1503 ret += 20;
1504 return ret;
1505}
1506
1473static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1507static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1474{ 1508{
1475 return (op_encode_hdr_size + op_encode_change_info_maxsz) 1509 return (op_encode_hdr_size + op_encode_change_info_maxsz)
@@ -1500,18 +1534,19 @@ static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1500 if (rlen > maxcount) 1534 if (rlen > maxcount)
1501 rlen = maxcount; 1535 rlen = maxcount;
1502 1536
1503 return (op_encode_hdr_size + 2) * sizeof(__be32) + rlen; 1537 return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32);
1504} 1538}
1505 1539
1506static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1540static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1507{ 1541{
1542 u32 maxcount = svc_max_payload(rqstp);
1508 u32 rlen = op->u.readdir.rd_maxcount; 1543 u32 rlen = op->u.readdir.rd_maxcount;
1509 1544
1510 if (rlen > PAGE_SIZE) 1545 if (rlen > maxcount)
1511 rlen = PAGE_SIZE; 1546 rlen = maxcount;
1512 1547
1513 return (op_encode_hdr_size + op_encode_verifier_maxsz) 1548 return (op_encode_hdr_size + op_encode_verifier_maxsz +
1514 * sizeof(__be32) + rlen; 1549 XDR_QUADLEN(rlen)) * sizeof(__be32);
1515} 1550}
1516 1551
1517static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1552static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
@@ -1526,6 +1561,12 @@ static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op
1526 + op_encode_change_info_maxsz) * sizeof(__be32); 1561 + op_encode_change_info_maxsz) * sizeof(__be32);
1527} 1562}
1528 1563
1564static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
1565 struct nfsd4_op *op)
1566{
1567 return NFS4_MAX_SESSIONID_LEN + 20;
1568}
1569
1529static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1570static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1530{ 1571{
1531 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1572 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
@@ -1539,7 +1580,7 @@ static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_o
1539 1580
1540static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1581static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1541{ 1582{
1542 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 1583 return (op_encode_hdr_size + 2 + op_encode_verifier_maxsz) * sizeof(__be32);
1543} 1584}
1544 1585
1545static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1586static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
@@ -1607,6 +1648,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1607 [OP_GETATTR] = { 1648 [OP_GETATTR] = {
1608 .op_func = (nfsd4op_func)nfsd4_getattr, 1649 .op_func = (nfsd4op_func)nfsd4_getattr,
1609 .op_flags = ALLOWED_ON_ABSENT_FS, 1650 .op_flags = ALLOWED_ON_ABSENT_FS,
1651 .op_rsize_bop = nfsd4_getattr_rsize,
1610 .op_name = "OP_GETATTR", 1652 .op_name = "OP_GETATTR",
1611 }, 1653 },
1612 [OP_GETFH] = { 1654 [OP_GETFH] = {
@@ -1676,37 +1718,32 @@ static struct nfsd4_operation nfsd4_ops[] = {
1676 [OP_PUTFH] = { 1718 [OP_PUTFH] = {
1677 .op_func = (nfsd4op_func)nfsd4_putfh, 1719 .op_func = (nfsd4op_func)nfsd4_putfh,
1678 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1720 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1679 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1721 | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
1680 | OP_CLEAR_STATEID,
1681 .op_name = "OP_PUTFH", 1722 .op_name = "OP_PUTFH",
1682 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1723 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1683 }, 1724 },
1684 [OP_PUTPUBFH] = { 1725 [OP_PUTPUBFH] = {
1685 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1726 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1686 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1727 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1687 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1728 | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
1688 | OP_CLEAR_STATEID,
1689 .op_name = "OP_PUTPUBFH", 1729 .op_name = "OP_PUTPUBFH",
1690 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1730 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1691 }, 1731 },
1692 [OP_PUTROOTFH] = { 1732 [OP_PUTROOTFH] = {
1693 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1733 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1694 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1734 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1695 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING 1735 | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
1696 | OP_CLEAR_STATEID,
1697 .op_name = "OP_PUTROOTFH", 1736 .op_name = "OP_PUTROOTFH",
1698 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1737 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1699 }, 1738 },
1700 [OP_READ] = { 1739 [OP_READ] = {
1701 .op_func = (nfsd4op_func)nfsd4_read, 1740 .op_func = (nfsd4op_func)nfsd4_read,
1702 .op_flags = OP_MODIFIES_SOMETHING,
1703 .op_name = "OP_READ", 1741 .op_name = "OP_READ",
1704 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, 1742 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
1705 .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid, 1743 .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid,
1706 }, 1744 },
1707 [OP_READDIR] = { 1745 [OP_READDIR] = {
1708 .op_func = (nfsd4op_func)nfsd4_readdir, 1746 .op_func = (nfsd4op_func)nfsd4_readdir,
1709 .op_flags = OP_MODIFIES_SOMETHING,
1710 .op_name = "OP_READDIR", 1747 .op_name = "OP_READDIR",
1711 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize, 1748 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize,
1712 }, 1749 },
@@ -1864,14 +1901,33 @@ static struct nfsd4_operation nfsd4_ops[] = {
1864 }, 1901 },
1865}; 1902};
1866 1903
1867#ifdef NFSD_DEBUG 1904int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
1905{
1906 struct nfsd4_operation *opdesc;
1907 nfsd4op_rsize estimator;
1908
1909 if (op->opnum == OP_ILLEGAL)
1910 return op_encode_hdr_size * sizeof(__be32);
1911 opdesc = OPDESC(op);
1912 estimator = opdesc->op_rsize_bop;
1913 return estimator ? estimator(rqstp, op) : PAGE_SIZE;
1914}
1915
1916void warn_on_nonidempotent_op(struct nfsd4_op *op)
1917{
1918 if (OPDESC(op)->op_flags & OP_MODIFIES_SOMETHING) {
1919 pr_err("unable to encode reply to nonidempotent op %d (%s)\n",
1920 op->opnum, nfsd4_op_name(op->opnum));
1921 WARN_ON_ONCE(1);
1922 }
1923}
1924
1868static const char *nfsd4_op_name(unsigned opnum) 1925static const char *nfsd4_op_name(unsigned opnum)
1869{ 1926{
1870 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1927 if (opnum < ARRAY_SIZE(nfsd4_ops))
1871 return nfsd4_ops[opnum].op_name; 1928 return nfsd4_ops[opnum].op_name;
1872 return "unknown_operation"; 1929 return "unknown_operation";
1873} 1930}
1874#endif
1875 1931
1876#define nfsd4_voidres nfsd4_voidargs 1932#define nfsd4_voidres nfsd4_voidargs
1877struct nfsd4_voidargs { int dummy; }; 1933struct nfsd4_voidargs { int dummy; };
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9a77a5a21557..c0d45cec9958 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -81,13 +81,13 @@ static DEFINE_MUTEX(client_mutex);
81 * effort to decrease the scope of the client_mutex, this spinlock may 81 * effort to decrease the scope of the client_mutex, this spinlock may
82 * eventually cover more: 82 * eventually cover more:
83 */ 83 */
84static DEFINE_SPINLOCK(recall_lock); 84static DEFINE_SPINLOCK(state_lock);
85 85
86static struct kmem_cache *openowner_slab = NULL; 86static struct kmem_cache *openowner_slab;
87static struct kmem_cache *lockowner_slab = NULL; 87static struct kmem_cache *lockowner_slab;
88static struct kmem_cache *file_slab = NULL; 88static struct kmem_cache *file_slab;
89static struct kmem_cache *stateid_slab = NULL; 89static struct kmem_cache *stateid_slab;
90static struct kmem_cache *deleg_slab = NULL; 90static struct kmem_cache *deleg_slab;
91 91
92void 92void
93nfs4_lock_state(void) 93nfs4_lock_state(void)
@@ -235,9 +235,9 @@ static void nfsd4_free_file(struct nfs4_file *f)
235static inline void 235static inline void
236put_nfs4_file(struct nfs4_file *fi) 236put_nfs4_file(struct nfs4_file *fi)
237{ 237{
238 if (atomic_dec_and_lock(&fi->fi_ref, &recall_lock)) { 238 if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
239 hlist_del(&fi->fi_hash); 239 hlist_del(&fi->fi_hash);
240 spin_unlock(&recall_lock); 240 spin_unlock(&state_lock);
241 iput(fi->fi_inode); 241 iput(fi->fi_inode);
242 nfsd4_free_file(fi); 242 nfsd4_free_file(fi);
243 } 243 }
@@ -375,7 +375,6 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
375 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab)); 375 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
376 if (dp == NULL) 376 if (dp == NULL)
377 return dp; 377 return dp;
378 dp->dl_stid.sc_type = NFS4_DELEG_STID;
379 /* 378 /*
380 * delegation seqid's are never incremented. The 4.1 special 379 * delegation seqid's are never incremented. The 4.1 special
381 * meaning of seqid 0 isn't meaningful, really, but let's avoid 380 * meaning of seqid 0 isn't meaningful, really, but let's avoid
@@ -418,6 +417,8 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
418 417
419static void nfs4_put_deleg_lease(struct nfs4_file *fp) 418static void nfs4_put_deleg_lease(struct nfs4_file *fp)
420{ 419{
420 if (!fp->fi_lease)
421 return;
421 if (atomic_dec_and_test(&fp->fi_delegees)) { 422 if (atomic_dec_and_test(&fp->fi_delegees)) {
422 vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); 423 vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease);
423 fp->fi_lease = NULL; 424 fp->fi_lease = NULL;
@@ -431,18 +432,30 @@ static void unhash_stid(struct nfs4_stid *s)
431 s->sc_type = 0; 432 s->sc_type = 0;
432} 433}
433 434
435static void
436hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
437{
438 lockdep_assert_held(&state_lock);
439
440 dp->dl_stid.sc_type = NFS4_DELEG_STID;
441 list_add(&dp->dl_perfile, &fp->fi_delegations);
442 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
443}
444
434/* Called under the state lock. */ 445/* Called under the state lock. */
435static void 446static void
436unhash_delegation(struct nfs4_delegation *dp) 447unhash_delegation(struct nfs4_delegation *dp)
437{ 448{
449 spin_lock(&state_lock);
438 list_del_init(&dp->dl_perclnt); 450 list_del_init(&dp->dl_perclnt);
439 spin_lock(&recall_lock);
440 list_del_init(&dp->dl_perfile); 451 list_del_init(&dp->dl_perfile);
441 list_del_init(&dp->dl_recall_lru); 452 list_del_init(&dp->dl_recall_lru);
442 spin_unlock(&recall_lock); 453 spin_unlock(&state_lock);
443 nfs4_put_deleg_lease(dp->dl_file); 454 if (dp->dl_file) {
444 put_nfs4_file(dp->dl_file); 455 nfs4_put_deleg_lease(dp->dl_file);
445 dp->dl_file = NULL; 456 put_nfs4_file(dp->dl_file);
457 dp->dl_file = NULL;
458 }
446} 459}
447 460
448 461
@@ -645,6 +658,12 @@ static void unhash_lockowner(struct nfs4_lockowner *lo)
645 } 658 }
646} 659}
647 660
661static void nfs4_free_lockowner(struct nfs4_lockowner *lo)
662{
663 kfree(lo->lo_owner.so_owner.data);
664 kmem_cache_free(lockowner_slab, lo);
665}
666
648static void release_lockowner(struct nfs4_lockowner *lo) 667static void release_lockowner(struct nfs4_lockowner *lo)
649{ 668{
650 unhash_lockowner(lo); 669 unhash_lockowner(lo);
@@ -699,6 +718,12 @@ static void release_last_closed_stateid(struct nfs4_openowner *oo)
699 } 718 }
700} 719}
701 720
721static void nfs4_free_openowner(struct nfs4_openowner *oo)
722{
723 kfree(oo->oo_owner.so_owner.data);
724 kmem_cache_free(openowner_slab, oo);
725}
726
702static void release_openowner(struct nfs4_openowner *oo) 727static void release_openowner(struct nfs4_openowner *oo)
703{ 728{
704 unhash_openowner(oo); 729 unhash_openowner(oo);
@@ -1093,7 +1118,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1093 return clp; 1118 return clp;
1094} 1119}
1095 1120
1096static inline void 1121static void
1097free_client(struct nfs4_client *clp) 1122free_client(struct nfs4_client *clp)
1098{ 1123{
1099 struct nfsd_net __maybe_unused *nn = net_generic(clp->net, nfsd_net_id); 1124 struct nfsd_net __maybe_unused *nn = net_generic(clp->net, nfsd_net_id);
@@ -1136,13 +1161,13 @@ destroy_client(struct nfs4_client *clp)
1136 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); 1161 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1137 1162
1138 INIT_LIST_HEAD(&reaplist); 1163 INIT_LIST_HEAD(&reaplist);
1139 spin_lock(&recall_lock); 1164 spin_lock(&state_lock);
1140 while (!list_empty(&clp->cl_delegations)) { 1165 while (!list_empty(&clp->cl_delegations)) {
1141 dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt); 1166 dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
1142 list_del_init(&dp->dl_perclnt); 1167 list_del_init(&dp->dl_perclnt);
1143 list_move(&dp->dl_recall_lru, &reaplist); 1168 list_move(&dp->dl_recall_lru, &reaplist);
1144 } 1169 }
1145 spin_unlock(&recall_lock); 1170 spin_unlock(&state_lock);
1146 while (!list_empty(&reaplist)) { 1171 while (!list_empty(&reaplist)) {
1147 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); 1172 dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
1148 destroy_delegation(dp); 1173 destroy_delegation(dp);
@@ -1544,6 +1569,7 @@ out_err:
1544void 1569void
1545nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) 1570nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1546{ 1571{
1572 struct xdr_buf *buf = resp->xdr.buf;
1547 struct nfsd4_slot *slot = resp->cstate.slot; 1573 struct nfsd4_slot *slot = resp->cstate.slot;
1548 unsigned int base; 1574 unsigned int base;
1549 1575
@@ -1557,11 +1583,9 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1557 slot->sl_datalen = 0; 1583 slot->sl_datalen = 0;
1558 return; 1584 return;
1559 } 1585 }
1560 slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap; 1586 base = resp->cstate.data_offset;
1561 base = (char *)resp->cstate.datap - 1587 slot->sl_datalen = buf->len - base;
1562 (char *)resp->xbuf->head[0].iov_base; 1588 if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
1563 if (read_bytes_from_xdr_buf(resp->xbuf, base, slot->sl_data,
1564 slot->sl_datalen))
1565 WARN("%s: sessions DRC could not cache compound\n", __func__); 1589 WARN("%s: sessions DRC could not cache compound\n", __func__);
1566 return; 1590 return;
1567} 1591}
@@ -1602,6 +1626,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1602 struct nfsd4_sequence *seq) 1626 struct nfsd4_sequence *seq)
1603{ 1627{
1604 struct nfsd4_slot *slot = resp->cstate.slot; 1628 struct nfsd4_slot *slot = resp->cstate.slot;
1629 struct xdr_stream *xdr = &resp->xdr;
1630 __be32 *p;
1605 __be32 status; 1631 __be32 status;
1606 1632
1607 dprintk("--> %s slot %p\n", __func__, slot); 1633 dprintk("--> %s slot %p\n", __func__, slot);
@@ -1610,14 +1636,16 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1610 if (status) 1636 if (status)
1611 return status; 1637 return status;
1612 1638
1613 /* The sequence operation has been encoded, cstate->datap set. */ 1639 p = xdr_reserve_space(xdr, slot->sl_datalen);
1614 memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen); 1640 if (!p) {
1641 WARN_ON_ONCE(1);
1642 return nfserr_serverfault;
1643 }
1644 xdr_encode_opaque_fixed(p, slot->sl_data, slot->sl_datalen);
1645 xdr_commit_encode(xdr);
1615 1646
1616 resp->opcnt = slot->sl_opcnt; 1647 resp->opcnt = slot->sl_opcnt;
1617 resp->p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen); 1648 return slot->sl_status;
1618 status = slot->sl_status;
1619
1620 return status;
1621} 1649}
1622 1650
1623/* 1651/*
@@ -2189,11 +2217,13 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2189 struct nfsd4_sequence *seq) 2217 struct nfsd4_sequence *seq)
2190{ 2218{
2191 struct nfsd4_compoundres *resp = rqstp->rq_resp; 2219 struct nfsd4_compoundres *resp = rqstp->rq_resp;
2220 struct xdr_stream *xdr = &resp->xdr;
2192 struct nfsd4_session *session; 2221 struct nfsd4_session *session;
2193 struct nfs4_client *clp; 2222 struct nfs4_client *clp;
2194 struct nfsd4_slot *slot; 2223 struct nfsd4_slot *slot;
2195 struct nfsd4_conn *conn; 2224 struct nfsd4_conn *conn;
2196 __be32 status; 2225 __be32 status;
2226 int buflen;
2197 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 2227 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2198 2228
2199 if (resp->opcnt != 1) 2229 if (resp->opcnt != 1)
@@ -2262,6 +2292,16 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2262 if (status) 2292 if (status)
2263 goto out_put_session; 2293 goto out_put_session;
2264 2294
2295 buflen = (seq->cachethis) ?
2296 session->se_fchannel.maxresp_cached :
2297 session->se_fchannel.maxresp_sz;
2298 status = (seq->cachethis) ? nfserr_rep_too_big_to_cache :
2299 nfserr_rep_too_big;
2300 if (xdr_restrict_buflen(xdr, buflen - rqstp->rq_auth_slack))
2301 goto out_put_session;
2302 svc_reserve(rqstp, buflen);
2303
2304 status = nfs_ok;
2265 /* Success! bump slot seqid */ 2305 /* Success! bump slot seqid */
2266 slot->sl_seqid = seq->seqid; 2306 slot->sl_seqid = seq->seqid;
2267 slot->sl_flags |= NFSD4_SLOT_INUSE; 2307 slot->sl_flags |= NFSD4_SLOT_INUSE;
@@ -2499,28 +2539,19 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
2499 fp->fi_lease = NULL; 2539 fp->fi_lease = NULL;
2500 memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); 2540 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
2501 memset(fp->fi_access, 0, sizeof(fp->fi_access)); 2541 memset(fp->fi_access, 0, sizeof(fp->fi_access));
2502 spin_lock(&recall_lock); 2542 spin_lock(&state_lock);
2503 hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]); 2543 hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
2504 spin_unlock(&recall_lock); 2544 spin_unlock(&state_lock);
2505}
2506
2507static void
2508nfsd4_free_slab(struct kmem_cache **slab)
2509{
2510 if (*slab == NULL)
2511 return;
2512 kmem_cache_destroy(*slab);
2513 *slab = NULL;
2514} 2545}
2515 2546
2516void 2547void
2517nfsd4_free_slabs(void) 2548nfsd4_free_slabs(void)
2518{ 2549{
2519 nfsd4_free_slab(&openowner_slab); 2550 kmem_cache_destroy(openowner_slab);
2520 nfsd4_free_slab(&lockowner_slab); 2551 kmem_cache_destroy(lockowner_slab);
2521 nfsd4_free_slab(&file_slab); 2552 kmem_cache_destroy(file_slab);
2522 nfsd4_free_slab(&stateid_slab); 2553 kmem_cache_destroy(stateid_slab);
2523 nfsd4_free_slab(&deleg_slab); 2554 kmem_cache_destroy(deleg_slab);
2524} 2555}
2525 2556
2526int 2557int
@@ -2529,42 +2560,38 @@ nfsd4_init_slabs(void)
2529 openowner_slab = kmem_cache_create("nfsd4_openowners", 2560 openowner_slab = kmem_cache_create("nfsd4_openowners",
2530 sizeof(struct nfs4_openowner), 0, 0, NULL); 2561 sizeof(struct nfs4_openowner), 0, 0, NULL);
2531 if (openowner_slab == NULL) 2562 if (openowner_slab == NULL)
2532 goto out_nomem; 2563 goto out;
2533 lockowner_slab = kmem_cache_create("nfsd4_lockowners", 2564 lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2534 sizeof(struct nfs4_lockowner), 0, 0, NULL); 2565 sizeof(struct nfs4_lockowner), 0, 0, NULL);
2535 if (lockowner_slab == NULL) 2566 if (lockowner_slab == NULL)
2536 goto out_nomem; 2567 goto out_free_openowner_slab;
2537 file_slab = kmem_cache_create("nfsd4_files", 2568 file_slab = kmem_cache_create("nfsd4_files",
2538 sizeof(struct nfs4_file), 0, 0, NULL); 2569 sizeof(struct nfs4_file), 0, 0, NULL);
2539 if (file_slab == NULL) 2570 if (file_slab == NULL)
2540 goto out_nomem; 2571 goto out_free_lockowner_slab;
2541 stateid_slab = kmem_cache_create("nfsd4_stateids", 2572 stateid_slab = kmem_cache_create("nfsd4_stateids",
2542 sizeof(struct nfs4_ol_stateid), 0, 0, NULL); 2573 sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
2543 if (stateid_slab == NULL) 2574 if (stateid_slab == NULL)
2544 goto out_nomem; 2575 goto out_free_file_slab;
2545 deleg_slab = kmem_cache_create("nfsd4_delegations", 2576 deleg_slab = kmem_cache_create("nfsd4_delegations",
2546 sizeof(struct nfs4_delegation), 0, 0, NULL); 2577 sizeof(struct nfs4_delegation), 0, 0, NULL);
2547 if (deleg_slab == NULL) 2578 if (deleg_slab == NULL)
2548 goto out_nomem; 2579 goto out_free_stateid_slab;
2549 return 0; 2580 return 0;
2550out_nomem: 2581
2551 nfsd4_free_slabs(); 2582out_free_stateid_slab:
2583 kmem_cache_destroy(stateid_slab);
2584out_free_file_slab:
2585 kmem_cache_destroy(file_slab);
2586out_free_lockowner_slab:
2587 kmem_cache_destroy(lockowner_slab);
2588out_free_openowner_slab:
2589 kmem_cache_destroy(openowner_slab);
2590out:
2552 dprintk("nfsd4: out of memory while initializing nfsv4\n"); 2591 dprintk("nfsd4: out of memory while initializing nfsv4\n");
2553 return -ENOMEM; 2592 return -ENOMEM;
2554} 2593}
2555 2594
2556void nfs4_free_openowner(struct nfs4_openowner *oo)
2557{
2558 kfree(oo->oo_owner.so_owner.data);
2559 kmem_cache_free(openowner_slab, oo);
2560}
2561
2562void nfs4_free_lockowner(struct nfs4_lockowner *lo)
2563{
2564 kfree(lo->lo_owner.so_owner.data);
2565 kmem_cache_free(lockowner_slab, lo);
2566}
2567
2568static void init_nfs4_replay(struct nfs4_replay *rp) 2595static void init_nfs4_replay(struct nfs4_replay *rp)
2569{ 2596{
2570 rp->rp_status = nfserr_serverfault; 2597 rp->rp_status = nfserr_serverfault;
@@ -2685,15 +2712,15 @@ find_file(struct inode *ino)
2685 unsigned int hashval = file_hashval(ino); 2712 unsigned int hashval = file_hashval(ino);
2686 struct nfs4_file *fp; 2713 struct nfs4_file *fp;
2687 2714
2688 spin_lock(&recall_lock); 2715 spin_lock(&state_lock);
2689 hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) { 2716 hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
2690 if (fp->fi_inode == ino) { 2717 if (fp->fi_inode == ino) {
2691 get_nfs4_file(fp); 2718 get_nfs4_file(fp);
2692 spin_unlock(&recall_lock); 2719 spin_unlock(&state_lock);
2693 return fp; 2720 return fp;
2694 } 2721 }
2695 } 2722 }
2696 spin_unlock(&recall_lock); 2723 spin_unlock(&state_lock);
2697 return NULL; 2724 return NULL;
2698} 2725}
2699 2726
@@ -2730,6 +2757,7 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
2730 struct nfs4_client *clp = dp->dl_stid.sc_client; 2757 struct nfs4_client *clp = dp->dl_stid.sc_client;
2731 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); 2758 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
2732 2759
2760 lockdep_assert_held(&state_lock);
2733 /* We're assuming the state code never drops its reference 2761 /* We're assuming the state code never drops its reference
2734 * without first removing the lease. Since we're in this lease 2762 * without first removing the lease. Since we're in this lease
2735 * callback (and since the lease code is serialized by the kernel 2763 * callback (and since the lease code is serialized by the kernel
@@ -2766,11 +2794,11 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
2766 */ 2794 */
2767 fl->fl_break_time = 0; 2795 fl->fl_break_time = 0;
2768 2796
2769 spin_lock(&recall_lock); 2797 spin_lock(&state_lock);
2770 fp->fi_had_conflict = true; 2798 fp->fi_had_conflict = true;
2771 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) 2799 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
2772 nfsd_break_one_deleg(dp); 2800 nfsd_break_one_deleg(dp);
2773 spin_unlock(&recall_lock); 2801 spin_unlock(&state_lock);
2774} 2802}
2775 2803
2776static 2804static
@@ -3047,11 +3075,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
3047 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); 3075 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
3048 if (status) 3076 if (status)
3049 goto out_free; 3077 goto out_free;
3050 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
3051 fp->fi_lease = fl; 3078 fp->fi_lease = fl;
3052 fp->fi_deleg_file = get_file(fl->fl_file); 3079 fp->fi_deleg_file = get_file(fl->fl_file);
3053 atomic_set(&fp->fi_delegees, 1); 3080 atomic_set(&fp->fi_delegees, 1);
3054 list_add(&dp->dl_perfile, &fp->fi_delegations); 3081 spin_lock(&state_lock);
3082 hash_delegation_locked(dp, fp);
3083 spin_unlock(&state_lock);
3055 return 0; 3084 return 0;
3056out_free: 3085out_free:
3057 locks_free_lock(fl); 3086 locks_free_lock(fl);
@@ -3060,33 +3089,21 @@ out_free:
3060 3089
3061static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp) 3090static int nfs4_set_delegation(struct nfs4_delegation *dp, struct nfs4_file *fp)
3062{ 3091{
3063 int status;
3064
3065 if (fp->fi_had_conflict) 3092 if (fp->fi_had_conflict)
3066 return -EAGAIN; 3093 return -EAGAIN;
3067 get_nfs4_file(fp); 3094 get_nfs4_file(fp);
3068 dp->dl_file = fp; 3095 dp->dl_file = fp;
3069 if (!fp->fi_lease) { 3096 if (!fp->fi_lease)
3070 status = nfs4_setlease(dp); 3097 return nfs4_setlease(dp);
3071 if (status) 3098 spin_lock(&state_lock);
3072 goto out_free; 3099 atomic_inc(&fp->fi_delegees);
3073 return 0;
3074 }
3075 spin_lock(&recall_lock);
3076 if (fp->fi_had_conflict) { 3100 if (fp->fi_had_conflict) {
3077 spin_unlock(&recall_lock); 3101 spin_unlock(&state_lock);
3078 status = -EAGAIN; 3102 return -EAGAIN;
3079 goto out_free;
3080 } 3103 }
3081 atomic_inc(&fp->fi_delegees); 3104 hash_delegation_locked(dp, fp);
3082 list_add(&dp->dl_perfile, &fp->fi_delegations); 3105 spin_unlock(&state_lock);
3083 spin_unlock(&recall_lock);
3084 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
3085 return 0; 3106 return 0;
3086out_free:
3087 put_nfs4_file(fp);
3088 dp->dl_file = fp;
3089 return status;
3090} 3107}
3091 3108
3092static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status) 3109static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
@@ -3173,8 +3190,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3173 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ; 3190 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3174 return; 3191 return;
3175out_free: 3192out_free:
3176 remove_stid(&dp->dl_stid); 3193 destroy_delegation(dp);
3177 nfs4_put_delegation(dp);
3178out_no_deleg: 3194out_no_deleg:
3179 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; 3195 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
3180 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS && 3196 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
@@ -3391,8 +3407,7 @@ nfs4_laundromat(struct nfsd_net *nn)
3391 struct nfs4_delegation *dp; 3407 struct nfs4_delegation *dp;
3392 struct list_head *pos, *next, reaplist; 3408 struct list_head *pos, *next, reaplist;
3393 time_t cutoff = get_seconds() - nn->nfsd4_lease; 3409 time_t cutoff = get_seconds() - nn->nfsd4_lease;
3394 time_t t, clientid_val = nn->nfsd4_lease; 3410 time_t t, new_timeo = nn->nfsd4_lease;
3395 time_t u, test_val = nn->nfsd4_lease;
3396 3411
3397 nfs4_lock_state(); 3412 nfs4_lock_state();
3398 3413
@@ -3404,8 +3419,7 @@ nfs4_laundromat(struct nfsd_net *nn)
3404 clp = list_entry(pos, struct nfs4_client, cl_lru); 3419 clp = list_entry(pos, struct nfs4_client, cl_lru);
3405 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 3420 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
3406 t = clp->cl_time - cutoff; 3421 t = clp->cl_time - cutoff;
3407 if (clientid_val > t) 3422 new_timeo = min(new_timeo, t);
3408 clientid_val = t;
3409 break; 3423 break;
3410 } 3424 }
3411 if (mark_client_expired_locked(clp)) { 3425 if (mark_client_expired_locked(clp)) {
@@ -3422,39 +3436,35 @@ nfs4_laundromat(struct nfsd_net *nn)
3422 clp->cl_clientid.cl_id); 3436 clp->cl_clientid.cl_id);
3423 expire_client(clp); 3437 expire_client(clp);
3424 } 3438 }
3425 spin_lock(&recall_lock); 3439 spin_lock(&state_lock);
3426 list_for_each_safe(pos, next, &nn->del_recall_lru) { 3440 list_for_each_safe(pos, next, &nn->del_recall_lru) {
3427 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3441 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3428 if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn) 3442 if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
3429 continue; 3443 continue;
3430 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) { 3444 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
3431 u = dp->dl_time - cutoff; 3445 t = dp->dl_time - cutoff;
3432 if (test_val > u) 3446 new_timeo = min(new_timeo, t);
3433 test_val = u;
3434 break; 3447 break;
3435 } 3448 }
3436 list_move(&dp->dl_recall_lru, &reaplist); 3449 list_move(&dp->dl_recall_lru, &reaplist);
3437 } 3450 }
3438 spin_unlock(&recall_lock); 3451 spin_unlock(&state_lock);
3439 list_for_each_safe(pos, next, &reaplist) { 3452 list_for_each_safe(pos, next, &reaplist) {
3440 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 3453 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3441 revoke_delegation(dp); 3454 revoke_delegation(dp);
3442 } 3455 }
3443 test_val = nn->nfsd4_lease;
3444 list_for_each_safe(pos, next, &nn->close_lru) { 3456 list_for_each_safe(pos, next, &nn->close_lru) {
3445 oo = container_of(pos, struct nfs4_openowner, oo_close_lru); 3457 oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
3446 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { 3458 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3447 u = oo->oo_time - cutoff; 3459 t = oo->oo_time - cutoff;
3448 if (test_val > u) 3460 new_timeo = min(new_timeo, t);
3449 test_val = u;
3450 break; 3461 break;
3451 } 3462 }
3452 release_openowner(oo); 3463 release_openowner(oo);
3453 } 3464 }
3454 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) 3465 new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
3455 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
3456 nfs4_unlock_state(); 3466 nfs4_unlock_state();
3457 return clientid_val; 3467 return new_timeo;
3458} 3468}
3459 3469
3460static struct workqueue_struct *laundry_wq; 3470static struct workqueue_struct *laundry_wq;
@@ -3654,6 +3664,7 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3654 struct svc_fh *current_fh = &cstate->current_fh; 3664 struct svc_fh *current_fh = &cstate->current_fh;
3655 struct inode *ino = current_fh->fh_dentry->d_inode; 3665 struct inode *ino = current_fh->fh_dentry->d_inode;
3656 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 3666 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
3667 struct file *file = NULL;
3657 __be32 status; 3668 __be32 status;
3658 3669
3659 if (filpp) 3670 if (filpp)
@@ -3665,10 +3676,12 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3665 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3676 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3666 return check_special_stateids(net, current_fh, stateid, flags); 3677 return check_special_stateids(net, current_fh, stateid, flags);
3667 3678
3679 nfs4_lock_state();
3680
3668 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, 3681 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
3669 &s, cstate->minorversion, nn); 3682 &s, cstate->minorversion, nn);
3670 if (status) 3683 if (status)
3671 return status; 3684 goto out;
3672 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate)); 3685 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
3673 if (status) 3686 if (status)
3674 goto out; 3687 goto out;
@@ -3679,8 +3692,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3679 if (status) 3692 if (status)
3680 goto out; 3693 goto out;
3681 if (filpp) { 3694 if (filpp) {
3682 *filpp = dp->dl_file->fi_deleg_file; 3695 file = dp->dl_file->fi_deleg_file;
3683 if (!*filpp) { 3696 if (!file) {
3684 WARN_ON_ONCE(1); 3697 WARN_ON_ONCE(1);
3685 status = nfserr_serverfault; 3698 status = nfserr_serverfault;
3686 goto out; 3699 goto out;
@@ -3701,16 +3714,20 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
3701 goto out; 3714 goto out;
3702 if (filpp) { 3715 if (filpp) {
3703 if (flags & RD_STATE) 3716 if (flags & RD_STATE)
3704 *filpp = find_readable_file(stp->st_file); 3717 file = find_readable_file(stp->st_file);
3705 else 3718 else
3706 *filpp = find_writeable_file(stp->st_file); 3719 file = find_writeable_file(stp->st_file);
3707 } 3720 }
3708 break; 3721 break;
3709 default: 3722 default:
3710 return nfserr_bad_stateid; 3723 status = nfserr_bad_stateid;
3724 goto out;
3711 } 3725 }
3712 status = nfs_ok; 3726 status = nfs_ok;
3727 if (file)
3728 *filpp = get_file(file);
3713out: 3729out:
3730 nfs4_unlock_state();
3714 return status; 3731 return status;
3715} 3732}
3716 3733
@@ -3726,7 +3743,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
3726 * correspondance, and we have to delete the lockowner when we 3743 * correspondance, and we have to delete the lockowner when we
3727 * delete the lock stateid: 3744 * delete the lock stateid:
3728 */ 3745 */
3729 unhash_lockowner(lo); 3746 release_lockowner(lo);
3730 return nfs_ok; 3747 return nfs_ok;
3731} 3748}
3732 3749
@@ -4896,6 +4913,7 @@ static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max,
4896 struct nfs4_delegation *dp, *next; 4913 struct nfs4_delegation *dp, *next;
4897 u64 count = 0; 4914 u64 count = 0;
4898 4915
4916 lockdep_assert_held(&state_lock);
4899 list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) { 4917 list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) {
4900 if (victims) 4918 if (victims)
4901 list_move(&dp->dl_recall_lru, victims); 4919 list_move(&dp->dl_recall_lru, victims);
@@ -4911,9 +4929,9 @@ u64 nfsd_forget_client_delegations(struct nfs4_client *clp, u64 max)
4911 LIST_HEAD(victims); 4929 LIST_HEAD(victims);
4912 u64 count; 4930 u64 count;
4913 4931
4914 spin_lock(&recall_lock); 4932 spin_lock(&state_lock);
4915 count = nfsd_find_all_delegations(clp, max, &victims); 4933 count = nfsd_find_all_delegations(clp, max, &victims);
4916 spin_unlock(&recall_lock); 4934 spin_unlock(&state_lock);
4917 4935
4918 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) 4936 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
4919 revoke_delegation(dp); 4937 revoke_delegation(dp);
@@ -4927,11 +4945,11 @@ u64 nfsd_recall_client_delegations(struct nfs4_client *clp, u64 max)
4927 LIST_HEAD(victims); 4945 LIST_HEAD(victims);
4928 u64 count; 4946 u64 count;
4929 4947
4930 spin_lock(&recall_lock); 4948 spin_lock(&state_lock);
4931 count = nfsd_find_all_delegations(clp, max, &victims); 4949 count = nfsd_find_all_delegations(clp, max, &victims);
4932 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) 4950 list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
4933 nfsd_break_one_deleg(dp); 4951 nfsd_break_one_deleg(dp);
4934 spin_unlock(&recall_lock); 4952 spin_unlock(&state_lock);
4935 4953
4936 return count; 4954 return count;
4937} 4955}
@@ -4940,9 +4958,9 @@ u64 nfsd_print_client_delegations(struct nfs4_client *clp, u64 max)
4940{ 4958{
4941 u64 count = 0; 4959 u64 count = 0;
4942 4960
4943 spin_lock(&recall_lock); 4961 spin_lock(&state_lock);
4944 count = nfsd_find_all_delegations(clp, max, NULL); 4962 count = nfsd_find_all_delegations(clp, max, NULL);
4945 spin_unlock(&recall_lock); 4963 spin_unlock(&state_lock);
4946 4964
4947 nfsd_print_count(clp, count, "delegations"); 4965 nfsd_print_count(clp, count, "delegations");
4948 return count; 4966 return count;
@@ -4983,13 +5001,6 @@ struct nfs4_client *nfsd_find_client(struct sockaddr_storage *addr, size_t addr_
4983 5001
4984#endif /* CONFIG_NFSD_FAULT_INJECTION */ 5002#endif /* CONFIG_NFSD_FAULT_INJECTION */
4985 5003
4986/* initialization to perform at module load time: */
4987
4988void
4989nfs4_state_init(void)
4990{
4991}
4992
4993/* 5004/*
4994 * Since the lifetime of a delegation isn't limited to that of an open, a 5005 * Since the lifetime of a delegation isn't limited to that of an open, a
4995 * client may quite reasonably hang on to a delegation as long as it has 5006 * client may quite reasonably hang on to a delegation as long as it has
@@ -5160,12 +5171,12 @@ nfs4_state_shutdown_net(struct net *net)
5160 5171
5161 nfs4_lock_state(); 5172 nfs4_lock_state();
5162 INIT_LIST_HEAD(&reaplist); 5173 INIT_LIST_HEAD(&reaplist);
5163 spin_lock(&recall_lock); 5174 spin_lock(&state_lock);
5164 list_for_each_safe(pos, next, &nn->del_recall_lru) { 5175 list_for_each_safe(pos, next, &nn->del_recall_lru) {
5165 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 5176 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5166 list_move(&dp->dl_recall_lru, &reaplist); 5177 list_move(&dp->dl_recall_lru, &reaplist);
5167 } 5178 }
5168 spin_unlock(&recall_lock); 5179 spin_unlock(&state_lock);
5169 list_for_each_safe(pos, next, &reaplist) { 5180 list_for_each_safe(pos, next, &reaplist) {
5170 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); 5181 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
5171 destroy_delegation(dp); 5182 destroy_delegation(dp);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 18881f34737a..2d305a121f37 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -98,11 +98,6 @@ xdr_error: \
98 status = nfserr_bad_xdr; \ 98 status = nfserr_bad_xdr; \
99 goto out 99 goto out
100 100
101#define READ32(x) (x) = ntohl(*p++)
102#define READ64(x) do { \
103 (x) = (u64)ntohl(*p++) << 32; \
104 (x) |= ntohl(*p++); \
105} while (0)
106#define READMEM(x,nbytes) do { \ 101#define READMEM(x,nbytes) do { \
107 x = (char *)p; \ 102 x = (char *)p; \
108 p += XDR_QUADLEN(nbytes); \ 103 p += XDR_QUADLEN(nbytes); \
@@ -248,17 +243,17 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
248 bmval[2] = 0; 243 bmval[2] = 0;
249 244
250 READ_BUF(4); 245 READ_BUF(4);
251 READ32(bmlen); 246 bmlen = be32_to_cpup(p++);
252 if (bmlen > 1000) 247 if (bmlen > 1000)
253 goto xdr_error; 248 goto xdr_error;
254 249
255 READ_BUF(bmlen << 2); 250 READ_BUF(bmlen << 2);
256 if (bmlen > 0) 251 if (bmlen > 0)
257 READ32(bmval[0]); 252 bmval[0] = be32_to_cpup(p++);
258 if (bmlen > 1) 253 if (bmlen > 1)
259 READ32(bmval[1]); 254 bmval[1] = be32_to_cpup(p++);
260 if (bmlen > 2) 255 if (bmlen > 2)
261 READ32(bmval[2]); 256 bmval[2] = be32_to_cpup(p++);
262 257
263 DECODE_TAIL; 258 DECODE_TAIL;
264} 259}
@@ -270,6 +265,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
270{ 265{
271 int expected_len, len = 0; 266 int expected_len, len = 0;
272 u32 dummy32; 267 u32 dummy32;
268 u64 sec;
273 char *buf; 269 char *buf;
274 270
275 DECODE_HEAD; 271 DECODE_HEAD;
@@ -278,12 +274,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
278 return status; 274 return status;
279 275
280 READ_BUF(4); 276 READ_BUF(4);
281 READ32(expected_len); 277 expected_len = be32_to_cpup(p++);
282 278
283 if (bmval[0] & FATTR4_WORD0_SIZE) { 279 if (bmval[0] & FATTR4_WORD0_SIZE) {
284 READ_BUF(8); 280 READ_BUF(8);
285 len += 8; 281 len += 8;
286 READ64(iattr->ia_size); 282 p = xdr_decode_hyper(p, &iattr->ia_size);
287 iattr->ia_valid |= ATTR_SIZE; 283 iattr->ia_valid |= ATTR_SIZE;
288 } 284 }
289 if (bmval[0] & FATTR4_WORD0_ACL) { 285 if (bmval[0] & FATTR4_WORD0_ACL) {
@@ -291,7 +287,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
291 struct nfs4_ace *ace; 287 struct nfs4_ace *ace;
292 288
293 READ_BUF(4); len += 4; 289 READ_BUF(4); len += 4;
294 READ32(nace); 290 nace = be32_to_cpup(p++);
295 291
296 if (nace > NFS4_ACL_MAX) 292 if (nace > NFS4_ACL_MAX)
297 return nfserr_fbig; 293 return nfserr_fbig;
@@ -305,10 +301,10 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
305 (*acl)->naces = nace; 301 (*acl)->naces = nace;
306 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { 302 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
307 READ_BUF(16); len += 16; 303 READ_BUF(16); len += 16;
308 READ32(ace->type); 304 ace->type = be32_to_cpup(p++);
309 READ32(ace->flag); 305 ace->flag = be32_to_cpup(p++);
310 READ32(ace->access_mask); 306 ace->access_mask = be32_to_cpup(p++);
311 READ32(dummy32); 307 dummy32 = be32_to_cpup(p++);
312 READ_BUF(dummy32); 308 READ_BUF(dummy32);
313 len += XDR_QUADLEN(dummy32) << 2; 309 len += XDR_QUADLEN(dummy32) << 2;
314 READMEM(buf, dummy32); 310 READMEM(buf, dummy32);
@@ -330,14 +326,14 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
330 if (bmval[1] & FATTR4_WORD1_MODE) { 326 if (bmval[1] & FATTR4_WORD1_MODE) {
331 READ_BUF(4); 327 READ_BUF(4);
332 len += 4; 328 len += 4;
333 READ32(iattr->ia_mode); 329 iattr->ia_mode = be32_to_cpup(p++);
334 iattr->ia_mode &= (S_IFMT | S_IALLUGO); 330 iattr->ia_mode &= (S_IFMT | S_IALLUGO);
335 iattr->ia_valid |= ATTR_MODE; 331 iattr->ia_valid |= ATTR_MODE;
336 } 332 }
337 if (bmval[1] & FATTR4_WORD1_OWNER) { 333 if (bmval[1] & FATTR4_WORD1_OWNER) {
338 READ_BUF(4); 334 READ_BUF(4);
339 len += 4; 335 len += 4;
340 READ32(dummy32); 336 dummy32 = be32_to_cpup(p++);
341 READ_BUF(dummy32); 337 READ_BUF(dummy32);
342 len += (XDR_QUADLEN(dummy32) << 2); 338 len += (XDR_QUADLEN(dummy32) << 2);
343 READMEM(buf, dummy32); 339 READMEM(buf, dummy32);
@@ -348,7 +344,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
348 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { 344 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
349 READ_BUF(4); 345 READ_BUF(4);
350 len += 4; 346 len += 4;
351 READ32(dummy32); 347 dummy32 = be32_to_cpup(p++);
352 READ_BUF(dummy32); 348 READ_BUF(dummy32);
353 len += (XDR_QUADLEN(dummy32) << 2); 349 len += (XDR_QUADLEN(dummy32) << 2);
354 READMEM(buf, dummy32); 350 READMEM(buf, dummy32);
@@ -359,15 +355,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
359 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 355 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
360 READ_BUF(4); 356 READ_BUF(4);
361 len += 4; 357 len += 4;
362 READ32(dummy32); 358 dummy32 = be32_to_cpup(p++);
363 switch (dummy32) { 359 switch (dummy32) {
364 case NFS4_SET_TO_CLIENT_TIME: 360 case NFS4_SET_TO_CLIENT_TIME:
365 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 361 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
366 all 32 bits of 'nseconds'. */ 362 all 32 bits of 'nseconds'. */
367 READ_BUF(12); 363 READ_BUF(12);
368 len += 12; 364 len += 12;
369 READ64(iattr->ia_atime.tv_sec); 365 p = xdr_decode_hyper(p, &sec);
370 READ32(iattr->ia_atime.tv_nsec); 366 iattr->ia_atime.tv_sec = (time_t)sec;
367 iattr->ia_atime.tv_nsec = be32_to_cpup(p++);
371 if (iattr->ia_atime.tv_nsec >= (u32)1000000000) 368 if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
372 return nfserr_inval; 369 return nfserr_inval;
373 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); 370 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
@@ -382,15 +379,16 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
382 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 379 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
383 READ_BUF(4); 380 READ_BUF(4);
384 len += 4; 381 len += 4;
385 READ32(dummy32); 382 dummy32 = be32_to_cpup(p++);
386 switch (dummy32) { 383 switch (dummy32) {
387 case NFS4_SET_TO_CLIENT_TIME: 384 case NFS4_SET_TO_CLIENT_TIME:
388 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 385 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
389 all 32 bits of 'nseconds'. */ 386 all 32 bits of 'nseconds'. */
390 READ_BUF(12); 387 READ_BUF(12);
391 len += 12; 388 len += 12;
392 READ64(iattr->ia_mtime.tv_sec); 389 p = xdr_decode_hyper(p, &sec);
393 READ32(iattr->ia_mtime.tv_nsec); 390 iattr->ia_mtime.tv_sec = sec;
391 iattr->ia_mtime.tv_nsec = be32_to_cpup(p++);
394 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000) 392 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
395 return nfserr_inval; 393 return nfserr_inval;
396 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); 394 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
@@ -408,13 +406,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
408 if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) { 406 if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
409 READ_BUF(4); 407 READ_BUF(4);
410 len += 4; 408 len += 4;
411 READ32(dummy32); /* lfs: we don't use it */ 409 dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
412 READ_BUF(4); 410 READ_BUF(4);
413 len += 4; 411 len += 4;
414 READ32(dummy32); /* pi: we don't use it either */ 412 dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
415 READ_BUF(4); 413 READ_BUF(4);
416 len += 4; 414 len += 4;
417 READ32(dummy32); 415 dummy32 = be32_to_cpup(p++);
418 READ_BUF(dummy32); 416 READ_BUF(dummy32);
419 if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN) 417 if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN)
420 return nfserr_badlabel; 418 return nfserr_badlabel;
@@ -445,7 +443,7 @@ nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
445 DECODE_HEAD; 443 DECODE_HEAD;
446 444
447 READ_BUF(sizeof(stateid_t)); 445 READ_BUF(sizeof(stateid_t));
448 READ32(sid->si_generation); 446 sid->si_generation = be32_to_cpup(p++);
449 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 447 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
450 448
451 DECODE_TAIL; 449 DECODE_TAIL;
@@ -457,7 +455,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
457 DECODE_HEAD; 455 DECODE_HEAD;
458 456
459 READ_BUF(4); 457 READ_BUF(4);
460 READ32(access->ac_req_access); 458 access->ac_req_access = be32_to_cpup(p++);
461 459
462 DECODE_TAIL; 460 DECODE_TAIL;
463} 461}
@@ -472,7 +470,7 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
472 470
473 /* callback_sec_params4 */ 471 /* callback_sec_params4 */
474 READ_BUF(4); 472 READ_BUF(4);
475 READ32(nr_secflavs); 473 nr_secflavs = be32_to_cpup(p++);
476 if (nr_secflavs) 474 if (nr_secflavs)
477 cbs->flavor = (u32)(-1); 475 cbs->flavor = (u32)(-1);
478 else 476 else
@@ -480,7 +478,7 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
480 cbs->flavor = 0; 478 cbs->flavor = 0;
481 for (i = 0; i < nr_secflavs; ++i) { 479 for (i = 0; i < nr_secflavs; ++i) {
482 READ_BUF(4); 480 READ_BUF(4);
483 READ32(dummy); 481 dummy = be32_to_cpup(p++);
484 switch (dummy) { 482 switch (dummy) {
485 case RPC_AUTH_NULL: 483 case RPC_AUTH_NULL:
486 /* Nothing to read */ 484 /* Nothing to read */
@@ -490,21 +488,21 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
490 case RPC_AUTH_UNIX: 488 case RPC_AUTH_UNIX:
491 READ_BUF(8); 489 READ_BUF(8);
492 /* stamp */ 490 /* stamp */
493 READ32(dummy); 491 dummy = be32_to_cpup(p++);
494 492
495 /* machine name */ 493 /* machine name */
496 READ32(dummy); 494 dummy = be32_to_cpup(p++);
497 READ_BUF(dummy); 495 READ_BUF(dummy);
498 SAVEMEM(machine_name, dummy); 496 SAVEMEM(machine_name, dummy);
499 497
500 /* uid, gid */ 498 /* uid, gid */
501 READ_BUF(8); 499 READ_BUF(8);
502 READ32(uid); 500 uid = be32_to_cpup(p++);
503 READ32(gid); 501 gid = be32_to_cpup(p++);
504 502
505 /* more gids */ 503 /* more gids */
506 READ_BUF(4); 504 READ_BUF(4);
507 READ32(dummy); 505 dummy = be32_to_cpup(p++);
508 READ_BUF(dummy * 4); 506 READ_BUF(dummy * 4);
509 if (cbs->flavor == (u32)(-1)) { 507 if (cbs->flavor == (u32)(-1)) {
510 kuid_t kuid = make_kuid(&init_user_ns, uid); 508 kuid_t kuid = make_kuid(&init_user_ns, uid);
@@ -524,14 +522,14 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
524 "not supported!\n"); 522 "not supported!\n");
525 READ_BUF(8); 523 READ_BUF(8);
526 /* gcbp_service */ 524 /* gcbp_service */
527 READ32(dummy); 525 dummy = be32_to_cpup(p++);
528 /* gcbp_handle_from_server */ 526 /* gcbp_handle_from_server */
529 READ32(dummy); 527 dummy = be32_to_cpup(p++);
530 READ_BUF(dummy); 528 READ_BUF(dummy);
531 p += XDR_QUADLEN(dummy); 529 p += XDR_QUADLEN(dummy);
532 /* gcbp_handle_from_client */ 530 /* gcbp_handle_from_client */
533 READ_BUF(4); 531 READ_BUF(4);
534 READ32(dummy); 532 dummy = be32_to_cpup(p++);
535 READ_BUF(dummy); 533 READ_BUF(dummy);
536 break; 534 break;
537 default: 535 default:
@@ -547,7 +545,7 @@ static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, stru
547 DECODE_HEAD; 545 DECODE_HEAD;
548 546
549 READ_BUF(4); 547 READ_BUF(4);
550 READ32(bc->bc_cb_program); 548 bc->bc_cb_program = be32_to_cpup(p++);
551 nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec); 549 nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
552 550
553 DECODE_TAIL; 551 DECODE_TAIL;
@@ -559,7 +557,7 @@ static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp,
559 557
560 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); 558 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
561 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); 559 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
562 READ32(bcts->dir); 560 bcts->dir = be32_to_cpup(p++);
563 /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker 561 /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker
564 * could help us figure out we should be using it. */ 562 * could help us figure out we should be using it. */
565 DECODE_TAIL; 563 DECODE_TAIL;
@@ -571,7 +569,7 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
571 DECODE_HEAD; 569 DECODE_HEAD;
572 570
573 READ_BUF(4); 571 READ_BUF(4);
574 READ32(close->cl_seqid); 572 close->cl_seqid = be32_to_cpup(p++);
575 return nfsd4_decode_stateid(argp, &close->cl_stateid); 573 return nfsd4_decode_stateid(argp, &close->cl_stateid);
576 574
577 DECODE_TAIL; 575 DECODE_TAIL;
@@ -584,8 +582,8 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
584 DECODE_HEAD; 582 DECODE_HEAD;
585 583
586 READ_BUF(12); 584 READ_BUF(12);
587 READ64(commit->co_offset); 585 p = xdr_decode_hyper(p, &commit->co_offset);
588 READ32(commit->co_count); 586 commit->co_count = be32_to_cpup(p++);
589 587
590 DECODE_TAIL; 588 DECODE_TAIL;
591} 589}
@@ -596,19 +594,19 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
596 DECODE_HEAD; 594 DECODE_HEAD;
597 595
598 READ_BUF(4); 596 READ_BUF(4);
599 READ32(create->cr_type); 597 create->cr_type = be32_to_cpup(p++);
600 switch (create->cr_type) { 598 switch (create->cr_type) {
601 case NF4LNK: 599 case NF4LNK:
602 READ_BUF(4); 600 READ_BUF(4);
603 READ32(create->cr_linklen); 601 create->cr_linklen = be32_to_cpup(p++);
604 READ_BUF(create->cr_linklen); 602 READ_BUF(create->cr_linklen);
605 SAVEMEM(create->cr_linkname, create->cr_linklen); 603 SAVEMEM(create->cr_linkname, create->cr_linklen);
606 break; 604 break;
607 case NF4BLK: 605 case NF4BLK:
608 case NF4CHR: 606 case NF4CHR:
609 READ_BUF(8); 607 READ_BUF(8);
610 READ32(create->cr_specdata1); 608 create->cr_specdata1 = be32_to_cpup(p++);
611 READ32(create->cr_specdata2); 609 create->cr_specdata2 = be32_to_cpup(p++);
612 break; 610 break;
613 case NF4SOCK: 611 case NF4SOCK:
614 case NF4FIFO: 612 case NF4FIFO:
@@ -618,7 +616,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
618 } 616 }
619 617
620 READ_BUF(4); 618 READ_BUF(4);
621 READ32(create->cr_namelen); 619 create->cr_namelen = be32_to_cpup(p++);
622 READ_BUF(create->cr_namelen); 620 READ_BUF(create->cr_namelen);
623 SAVEMEM(create->cr_name, create->cr_namelen); 621 SAVEMEM(create->cr_name, create->cr_namelen);
624 if ((status = check_filename(create->cr_name, create->cr_namelen))) 622 if ((status = check_filename(create->cr_name, create->cr_namelen)))
@@ -650,7 +648,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
650 DECODE_HEAD; 648 DECODE_HEAD;
651 649
652 READ_BUF(4); 650 READ_BUF(4);
653 READ32(link->li_namelen); 651 link->li_namelen = be32_to_cpup(p++);
654 READ_BUF(link->li_namelen); 652 READ_BUF(link->li_namelen);
655 SAVEMEM(link->li_name, link->li_namelen); 653 SAVEMEM(link->li_name, link->li_namelen);
656 if ((status = check_filename(link->li_name, link->li_namelen))) 654 if ((status = check_filename(link->li_name, link->li_namelen)))
@@ -668,24 +666,24 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
668 * type, reclaim(boolean), offset, length, new_lock_owner(boolean) 666 * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
669 */ 667 */
670 READ_BUF(28); 668 READ_BUF(28);
671 READ32(lock->lk_type); 669 lock->lk_type = be32_to_cpup(p++);
672 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT)) 670 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
673 goto xdr_error; 671 goto xdr_error;
674 READ32(lock->lk_reclaim); 672 lock->lk_reclaim = be32_to_cpup(p++);
675 READ64(lock->lk_offset); 673 p = xdr_decode_hyper(p, &lock->lk_offset);
676 READ64(lock->lk_length); 674 p = xdr_decode_hyper(p, &lock->lk_length);
677 READ32(lock->lk_is_new); 675 lock->lk_is_new = be32_to_cpup(p++);
678 676
679 if (lock->lk_is_new) { 677 if (lock->lk_is_new) {
680 READ_BUF(4); 678 READ_BUF(4);
681 READ32(lock->lk_new_open_seqid); 679 lock->lk_new_open_seqid = be32_to_cpup(p++);
682 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid); 680 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
683 if (status) 681 if (status)
684 return status; 682 return status;
685 READ_BUF(8 + sizeof(clientid_t)); 683 READ_BUF(8 + sizeof(clientid_t));
686 READ32(lock->lk_new_lock_seqid); 684 lock->lk_new_lock_seqid = be32_to_cpup(p++);
687 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t)); 685 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
688 READ32(lock->lk_new_owner.len); 686 lock->lk_new_owner.len = be32_to_cpup(p++);
689 READ_BUF(lock->lk_new_owner.len); 687 READ_BUF(lock->lk_new_owner.len);
690 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len); 688 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
691 } else { 689 } else {
@@ -693,7 +691,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
693 if (status) 691 if (status)
694 return status; 692 return status;
695 READ_BUF(4); 693 READ_BUF(4);
696 READ32(lock->lk_old_lock_seqid); 694 lock->lk_old_lock_seqid = be32_to_cpup(p++);
697 } 695 }
698 696
699 DECODE_TAIL; 697 DECODE_TAIL;
@@ -705,13 +703,13 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
705 DECODE_HEAD; 703 DECODE_HEAD;
706 704
707 READ_BUF(32); 705 READ_BUF(32);
708 READ32(lockt->lt_type); 706 lockt->lt_type = be32_to_cpup(p++);
709 if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT)) 707 if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
710 goto xdr_error; 708 goto xdr_error;
711 READ64(lockt->lt_offset); 709 p = xdr_decode_hyper(p, &lockt->lt_offset);
712 READ64(lockt->lt_length); 710 p = xdr_decode_hyper(p, &lockt->lt_length);
713 COPYMEM(&lockt->lt_clientid, 8); 711 COPYMEM(&lockt->lt_clientid, 8);
714 READ32(lockt->lt_owner.len); 712 lockt->lt_owner.len = be32_to_cpup(p++);
715 READ_BUF(lockt->lt_owner.len); 713 READ_BUF(lockt->lt_owner.len);
716 READMEM(lockt->lt_owner.data, lockt->lt_owner.len); 714 READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
717 715
@@ -724,16 +722,16 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
724 DECODE_HEAD; 722 DECODE_HEAD;
725 723
726 READ_BUF(8); 724 READ_BUF(8);
727 READ32(locku->lu_type); 725 locku->lu_type = be32_to_cpup(p++);
728 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) 726 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
729 goto xdr_error; 727 goto xdr_error;
730 READ32(locku->lu_seqid); 728 locku->lu_seqid = be32_to_cpup(p++);
731 status = nfsd4_decode_stateid(argp, &locku->lu_stateid); 729 status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
732 if (status) 730 if (status)
733 return status; 731 return status;
734 READ_BUF(16); 732 READ_BUF(16);
735 READ64(locku->lu_offset); 733 p = xdr_decode_hyper(p, &locku->lu_offset);
736 READ64(locku->lu_length); 734 p = xdr_decode_hyper(p, &locku->lu_length);
737 735
738 DECODE_TAIL; 736 DECODE_TAIL;
739} 737}
@@ -744,7 +742,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
744 DECODE_HEAD; 742 DECODE_HEAD;
745 743
746 READ_BUF(4); 744 READ_BUF(4);
747 READ32(lookup->lo_len); 745 lookup->lo_len = be32_to_cpup(p++);
748 READ_BUF(lookup->lo_len); 746 READ_BUF(lookup->lo_len);
749 SAVEMEM(lookup->lo_name, lookup->lo_len); 747 SAVEMEM(lookup->lo_name, lookup->lo_len);
750 if ((status = check_filename(lookup->lo_name, lookup->lo_len))) 748 if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
@@ -759,7 +757,7 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *sh
759 u32 w; 757 u32 w;
760 758
761 READ_BUF(4); 759 READ_BUF(4);
762 READ32(w); 760 w = be32_to_cpup(p++);
763 *share_access = w & NFS4_SHARE_ACCESS_MASK; 761 *share_access = w & NFS4_SHARE_ACCESS_MASK;
764 *deleg_want = w & NFS4_SHARE_WANT_MASK; 762 *deleg_want = w & NFS4_SHARE_WANT_MASK;
765 if (deleg_when) 763 if (deleg_when)
@@ -811,7 +809,7 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
811 __be32 *p; 809 __be32 *p;
812 810
813 READ_BUF(4); 811 READ_BUF(4);
814 READ32(*x); 812 *x = be32_to_cpup(p++);
815 /* Note: unlinke access bits, deny bits may be zero. */ 813 /* Note: unlinke access bits, deny bits may be zero. */
816 if (*x & ~NFS4_SHARE_DENY_BOTH) 814 if (*x & ~NFS4_SHARE_DENY_BOTH)
817 return nfserr_bad_xdr; 815 return nfserr_bad_xdr;
@@ -825,7 +823,7 @@ static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_ne
825 __be32 *p; 823 __be32 *p;
826 824
827 READ_BUF(4); 825 READ_BUF(4);
828 READ32(o->len); 826 o->len = be32_to_cpup(p++);
829 827
830 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT) 828 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
831 return nfserr_bad_xdr; 829 return nfserr_bad_xdr;
@@ -850,7 +848,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
850 open->op_xdr_error = 0; 848 open->op_xdr_error = 0;
851 /* seqid, share_access, share_deny, clientid, ownerlen */ 849 /* seqid, share_access, share_deny, clientid, ownerlen */
852 READ_BUF(4); 850 READ_BUF(4);
853 READ32(open->op_seqid); 851 open->op_seqid = be32_to_cpup(p++);
854 /* decode, yet ignore deleg_when until supported */ 852 /* decode, yet ignore deleg_when until supported */
855 status = nfsd4_decode_share_access(argp, &open->op_share_access, 853 status = nfsd4_decode_share_access(argp, &open->op_share_access,
856 &open->op_deleg_want, &dummy); 854 &open->op_deleg_want, &dummy);
@@ -865,13 +863,13 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
865 if (status) 863 if (status)
866 goto xdr_error; 864 goto xdr_error;
867 READ_BUF(4); 865 READ_BUF(4);
868 READ32(open->op_create); 866 open->op_create = be32_to_cpup(p++);
869 switch (open->op_create) { 867 switch (open->op_create) {
870 case NFS4_OPEN_NOCREATE: 868 case NFS4_OPEN_NOCREATE:
871 break; 869 break;
872 case NFS4_OPEN_CREATE: 870 case NFS4_OPEN_CREATE:
873 READ_BUF(4); 871 READ_BUF(4);
874 READ32(open->op_createmode); 872 open->op_createmode = be32_to_cpup(p++);
875 switch (open->op_createmode) { 873 switch (open->op_createmode) {
876 case NFS4_CREATE_UNCHECKED: 874 case NFS4_CREATE_UNCHECKED:
877 case NFS4_CREATE_GUARDED: 875 case NFS4_CREATE_GUARDED:
@@ -904,12 +902,12 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
904 902
905 /* open_claim */ 903 /* open_claim */
906 READ_BUF(4); 904 READ_BUF(4);
907 READ32(open->op_claim_type); 905 open->op_claim_type = be32_to_cpup(p++);
908 switch (open->op_claim_type) { 906 switch (open->op_claim_type) {
909 case NFS4_OPEN_CLAIM_NULL: 907 case NFS4_OPEN_CLAIM_NULL:
910 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 908 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
911 READ_BUF(4); 909 READ_BUF(4);
912 READ32(open->op_fname.len); 910 open->op_fname.len = be32_to_cpup(p++);
913 READ_BUF(open->op_fname.len); 911 READ_BUF(open->op_fname.len);
914 SAVEMEM(open->op_fname.data, open->op_fname.len); 912 SAVEMEM(open->op_fname.data, open->op_fname.len);
915 if ((status = check_filename(open->op_fname.data, open->op_fname.len))) 913 if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
@@ -917,14 +915,14 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
917 break; 915 break;
918 case NFS4_OPEN_CLAIM_PREVIOUS: 916 case NFS4_OPEN_CLAIM_PREVIOUS:
919 READ_BUF(4); 917 READ_BUF(4);
920 READ32(open->op_delegate_type); 918 open->op_delegate_type = be32_to_cpup(p++);
921 break; 919 break;
922 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 920 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
923 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid); 921 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
924 if (status) 922 if (status)
925 return status; 923 return status;
926 READ_BUF(4); 924 READ_BUF(4);
927 READ32(open->op_fname.len); 925 open->op_fname.len = be32_to_cpup(p++);
928 READ_BUF(open->op_fname.len); 926 READ_BUF(open->op_fname.len);
929 SAVEMEM(open->op_fname.data, open->op_fname.len); 927 SAVEMEM(open->op_fname.data, open->op_fname.len);
930 if ((status = check_filename(open->op_fname.data, open->op_fname.len))) 928 if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
@@ -962,7 +960,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
962 if (status) 960 if (status)
963 return status; 961 return status;
964 READ_BUF(4); 962 READ_BUF(4);
965 READ32(open_conf->oc_seqid); 963 open_conf->oc_seqid = be32_to_cpup(p++);
966 964
967 DECODE_TAIL; 965 DECODE_TAIL;
968} 966}
@@ -976,7 +974,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
976 if (status) 974 if (status)
977 return status; 975 return status;
978 READ_BUF(4); 976 READ_BUF(4);
979 READ32(open_down->od_seqid); 977 open_down->od_seqid = be32_to_cpup(p++);
980 status = nfsd4_decode_share_access(argp, &open_down->od_share_access, 978 status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
981 &open_down->od_deleg_want, NULL); 979 &open_down->od_deleg_want, NULL);
982 if (status) 980 if (status)
@@ -993,7 +991,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
993 DECODE_HEAD; 991 DECODE_HEAD;
994 992
995 READ_BUF(4); 993 READ_BUF(4);
996 READ32(putfh->pf_fhlen); 994 putfh->pf_fhlen = be32_to_cpup(p++);
997 if (putfh->pf_fhlen > NFS4_FHSIZE) 995 if (putfh->pf_fhlen > NFS4_FHSIZE)
998 goto xdr_error; 996 goto xdr_error;
999 READ_BUF(putfh->pf_fhlen); 997 READ_BUF(putfh->pf_fhlen);
@@ -1019,8 +1017,8 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
1019 if (status) 1017 if (status)
1020 return status; 1018 return status;
1021 READ_BUF(12); 1019 READ_BUF(12);
1022 READ64(read->rd_offset); 1020 p = xdr_decode_hyper(p, &read->rd_offset);
1023 READ32(read->rd_length); 1021 read->rd_length = be32_to_cpup(p++);
1024 1022
1025 DECODE_TAIL; 1023 DECODE_TAIL;
1026} 1024}
@@ -1031,10 +1029,10 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
1031 DECODE_HEAD; 1029 DECODE_HEAD;
1032 1030
1033 READ_BUF(24); 1031 READ_BUF(24);
1034 READ64(readdir->rd_cookie); 1032 p = xdr_decode_hyper(p, &readdir->rd_cookie);
1035 COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data)); 1033 COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
1036 READ32(readdir->rd_dircount); /* just in case you needed a useless field... */ 1034 readdir->rd_dircount = be32_to_cpup(p++);
1037 READ32(readdir->rd_maxcount); 1035 readdir->rd_maxcount = be32_to_cpup(p++);
1038 if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval))) 1036 if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
1039 goto out; 1037 goto out;
1040 1038
@@ -1047,7 +1045,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
1047 DECODE_HEAD; 1045 DECODE_HEAD;
1048 1046
1049 READ_BUF(4); 1047 READ_BUF(4);
1050 READ32(remove->rm_namelen); 1048 remove->rm_namelen = be32_to_cpup(p++);
1051 READ_BUF(remove->rm_namelen); 1049 READ_BUF(remove->rm_namelen);
1052 SAVEMEM(remove->rm_name, remove->rm_namelen); 1050 SAVEMEM(remove->rm_name, remove->rm_namelen);
1053 if ((status = check_filename(remove->rm_name, remove->rm_namelen))) 1051 if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
@@ -1062,10 +1060,10 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
1062 DECODE_HEAD; 1060 DECODE_HEAD;
1063 1061
1064 READ_BUF(4); 1062 READ_BUF(4);
1065 READ32(rename->rn_snamelen); 1063 rename->rn_snamelen = be32_to_cpup(p++);
1066 READ_BUF(rename->rn_snamelen + 4); 1064 READ_BUF(rename->rn_snamelen + 4);
1067 SAVEMEM(rename->rn_sname, rename->rn_snamelen); 1065 SAVEMEM(rename->rn_sname, rename->rn_snamelen);
1068 READ32(rename->rn_tnamelen); 1066 rename->rn_tnamelen = be32_to_cpup(p++);
1069 READ_BUF(rename->rn_tnamelen); 1067 READ_BUF(rename->rn_tnamelen);
1070 SAVEMEM(rename->rn_tname, rename->rn_tnamelen); 1068 SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
1071 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen))) 1069 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
@@ -1097,7 +1095,7 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
1097 DECODE_HEAD; 1095 DECODE_HEAD;
1098 1096
1099 READ_BUF(4); 1097 READ_BUF(4);
1100 READ32(secinfo->si_namelen); 1098 secinfo->si_namelen = be32_to_cpup(p++);
1101 READ_BUF(secinfo->si_namelen); 1099 READ_BUF(secinfo->si_namelen);
1102 SAVEMEM(secinfo->si_name, secinfo->si_namelen); 1100 SAVEMEM(secinfo->si_name, secinfo->si_namelen);
1103 status = check_filename(secinfo->si_name, secinfo->si_namelen); 1101 status = check_filename(secinfo->si_name, secinfo->si_namelen);
@@ -1113,7 +1111,7 @@ nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
1113 DECODE_HEAD; 1111 DECODE_HEAD;
1114 1112
1115 READ_BUF(4); 1113 READ_BUF(4);
1116 READ32(sin->sin_style); 1114 sin->sin_style = be32_to_cpup(p++);
1117 DECODE_TAIL; 1115 DECODE_TAIL;
1118} 1116}
1119 1117
@@ -1144,16 +1142,16 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
1144 if (status) 1142 if (status)
1145 return nfserr_bad_xdr; 1143 return nfserr_bad_xdr;
1146 READ_BUF(8); 1144 READ_BUF(8);
1147 READ32(setclientid->se_callback_prog); 1145 setclientid->se_callback_prog = be32_to_cpup(p++);
1148 READ32(setclientid->se_callback_netid_len); 1146 setclientid->se_callback_netid_len = be32_to_cpup(p++);
1149 1147
1150 READ_BUF(setclientid->se_callback_netid_len + 4); 1148 READ_BUF(setclientid->se_callback_netid_len + 4);
1151 SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len); 1149 SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
1152 READ32(setclientid->se_callback_addr_len); 1150 setclientid->se_callback_addr_len = be32_to_cpup(p++);
1153 1151
1154 READ_BUF(setclientid->se_callback_addr_len + 4); 1152 READ_BUF(setclientid->se_callback_addr_len + 4);
1155 SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len); 1153 SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
1156 READ32(setclientid->se_callback_ident); 1154 setclientid->se_callback_ident = be32_to_cpup(p++);
1157 1155
1158 DECODE_TAIL; 1156 DECODE_TAIL;
1159} 1157}
@@ -1186,7 +1184,7 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
1186 * nfsd4_proc_verify */ 1184 * nfsd4_proc_verify */
1187 1185
1188 READ_BUF(4); 1186 READ_BUF(4);
1189 READ32(verify->ve_attrlen); 1187 verify->ve_attrlen = be32_to_cpup(p++);
1190 READ_BUF(verify->ve_attrlen); 1188 READ_BUF(verify->ve_attrlen);
1191 SAVEMEM(verify->ve_attrval, verify->ve_attrlen); 1189 SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
1192 1190
@@ -1204,11 +1202,11 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1204 if (status) 1202 if (status)
1205 return status; 1203 return status;
1206 READ_BUF(16); 1204 READ_BUF(16);
1207 READ64(write->wr_offset); 1205 p = xdr_decode_hyper(p, &write->wr_offset);
1208 READ32(write->wr_stable_how); 1206 write->wr_stable_how = be32_to_cpup(p++);
1209 if (write->wr_stable_how > 2) 1207 if (write->wr_stable_how > 2)
1210 goto xdr_error; 1208 goto xdr_error;
1211 READ32(write->wr_buflen); 1209 write->wr_buflen = be32_to_cpup(p++);
1212 1210
1213 /* Sorry .. no magic macros for this.. * 1211 /* Sorry .. no magic macros for this.. *
1214 * READ_BUF(write->wr_buflen); 1212 * READ_BUF(write->wr_buflen);
@@ -1254,7 +1252,7 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
1254 1252
1255 READ_BUF(12); 1253 READ_BUF(12);
1256 COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); 1254 COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1257 READ32(rlockowner->rl_owner.len); 1255 rlockowner->rl_owner.len = be32_to_cpup(p++);
1258 READ_BUF(rlockowner->rl_owner.len); 1256 READ_BUF(rlockowner->rl_owner.len);
1259 READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len); 1257 READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1260 1258
@@ -1278,63 +1276,63 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1278 return nfserr_bad_xdr; 1276 return nfserr_bad_xdr;
1279 1277
1280 READ_BUF(4); 1278 READ_BUF(4);
1281 READ32(exid->flags); 1279 exid->flags = be32_to_cpup(p++);
1282 1280
1283 /* Ignore state_protect4_a */ 1281 /* Ignore state_protect4_a */
1284 READ_BUF(4); 1282 READ_BUF(4);
1285 READ32(exid->spa_how); 1283 exid->spa_how = be32_to_cpup(p++);
1286 switch (exid->spa_how) { 1284 switch (exid->spa_how) {
1287 case SP4_NONE: 1285 case SP4_NONE:
1288 break; 1286 break;
1289 case SP4_MACH_CRED: 1287 case SP4_MACH_CRED:
1290 /* spo_must_enforce */ 1288 /* spo_must_enforce */
1291 READ_BUF(4); 1289 READ_BUF(4);
1292 READ32(dummy); 1290 dummy = be32_to_cpup(p++);
1293 READ_BUF(dummy * 4); 1291 READ_BUF(dummy * 4);
1294 p += dummy; 1292 p += dummy;
1295 1293
1296 /* spo_must_allow */ 1294 /* spo_must_allow */
1297 READ_BUF(4); 1295 READ_BUF(4);
1298 READ32(dummy); 1296 dummy = be32_to_cpup(p++);
1299 READ_BUF(dummy * 4); 1297 READ_BUF(dummy * 4);
1300 p += dummy; 1298 p += dummy;
1301 break; 1299 break;
1302 case SP4_SSV: 1300 case SP4_SSV:
1303 /* ssp_ops */ 1301 /* ssp_ops */
1304 READ_BUF(4); 1302 READ_BUF(4);
1305 READ32(dummy); 1303 dummy = be32_to_cpup(p++);
1306 READ_BUF(dummy * 4); 1304 READ_BUF(dummy * 4);
1307 p += dummy; 1305 p += dummy;
1308 1306
1309 READ_BUF(4); 1307 READ_BUF(4);
1310 READ32(dummy); 1308 dummy = be32_to_cpup(p++);
1311 READ_BUF(dummy * 4); 1309 READ_BUF(dummy * 4);
1312 p += dummy; 1310 p += dummy;
1313 1311
1314 /* ssp_hash_algs<> */ 1312 /* ssp_hash_algs<> */
1315 READ_BUF(4); 1313 READ_BUF(4);
1316 READ32(tmp); 1314 tmp = be32_to_cpup(p++);
1317 while (tmp--) { 1315 while (tmp--) {
1318 READ_BUF(4); 1316 READ_BUF(4);
1319 READ32(dummy); 1317 dummy = be32_to_cpup(p++);
1320 READ_BUF(dummy); 1318 READ_BUF(dummy);
1321 p += XDR_QUADLEN(dummy); 1319 p += XDR_QUADLEN(dummy);
1322 } 1320 }
1323 1321
1324 /* ssp_encr_algs<> */ 1322 /* ssp_encr_algs<> */
1325 READ_BUF(4); 1323 READ_BUF(4);
1326 READ32(tmp); 1324 tmp = be32_to_cpup(p++);
1327 while (tmp--) { 1325 while (tmp--) {
1328 READ_BUF(4); 1326 READ_BUF(4);
1329 READ32(dummy); 1327 dummy = be32_to_cpup(p++);
1330 READ_BUF(dummy); 1328 READ_BUF(dummy);
1331 p += XDR_QUADLEN(dummy); 1329 p += XDR_QUADLEN(dummy);
1332 } 1330 }
1333 1331
1334 /* ssp_window and ssp_num_gss_handles */ 1332 /* ssp_window and ssp_num_gss_handles */
1335 READ_BUF(8); 1333 READ_BUF(8);
1336 READ32(dummy); 1334 dummy = be32_to_cpup(p++);
1337 READ32(dummy); 1335 dummy = be32_to_cpup(p++);
1338 break; 1336 break;
1339 default: 1337 default:
1340 goto xdr_error; 1338 goto xdr_error;
@@ -1342,7 +1340,7 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1342 1340
1343 /* Ignore Implementation ID */ 1341 /* Ignore Implementation ID */
1344 READ_BUF(4); /* nfs_impl_id4 array length */ 1342 READ_BUF(4); /* nfs_impl_id4 array length */
1345 READ32(dummy); 1343 dummy = be32_to_cpup(p++);
1346 1344
1347 if (dummy > 1) 1345 if (dummy > 1)
1348 goto xdr_error; 1346 goto xdr_error;
@@ -1350,13 +1348,13 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1350 if (dummy == 1) { 1348 if (dummy == 1) {
1351 /* nii_domain */ 1349 /* nii_domain */
1352 READ_BUF(4); 1350 READ_BUF(4);
1353 READ32(dummy); 1351 dummy = be32_to_cpup(p++);
1354 READ_BUF(dummy); 1352 READ_BUF(dummy);
1355 p += XDR_QUADLEN(dummy); 1353 p += XDR_QUADLEN(dummy);
1356 1354
1357 /* nii_name */ 1355 /* nii_name */
1358 READ_BUF(4); 1356 READ_BUF(4);
1359 READ32(dummy); 1357 dummy = be32_to_cpup(p++);
1360 READ_BUF(dummy); 1358 READ_BUF(dummy);
1361 p += XDR_QUADLEN(dummy); 1359 p += XDR_QUADLEN(dummy);
1362 1360
@@ -1376,21 +1374,21 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1376 1374
1377 READ_BUF(16); 1375 READ_BUF(16);
1378 COPYMEM(&sess->clientid, 8); 1376 COPYMEM(&sess->clientid, 8);
1379 READ32(sess->seqid); 1377 sess->seqid = be32_to_cpup(p++);
1380 READ32(sess->flags); 1378 sess->flags = be32_to_cpup(p++);
1381 1379
1382 /* Fore channel attrs */ 1380 /* Fore channel attrs */
1383 READ_BUF(28); 1381 READ_BUF(28);
1384 READ32(dummy); /* headerpadsz is always 0 */ 1382 dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
1385 READ32(sess->fore_channel.maxreq_sz); 1383 sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
1386 READ32(sess->fore_channel.maxresp_sz); 1384 sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
1387 READ32(sess->fore_channel.maxresp_cached); 1385 sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
1388 READ32(sess->fore_channel.maxops); 1386 sess->fore_channel.maxops = be32_to_cpup(p++);
1389 READ32(sess->fore_channel.maxreqs); 1387 sess->fore_channel.maxreqs = be32_to_cpup(p++);
1390 READ32(sess->fore_channel.nr_rdma_attrs); 1388 sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
1391 if (sess->fore_channel.nr_rdma_attrs == 1) { 1389 if (sess->fore_channel.nr_rdma_attrs == 1) {
1392 READ_BUF(4); 1390 READ_BUF(4);
1393 READ32(sess->fore_channel.rdma_attrs); 1391 sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
1394 } else if (sess->fore_channel.nr_rdma_attrs > 1) { 1392 } else if (sess->fore_channel.nr_rdma_attrs > 1) {
1395 dprintk("Too many fore channel attr bitmaps!\n"); 1393 dprintk("Too many fore channel attr bitmaps!\n");
1396 goto xdr_error; 1394 goto xdr_error;
@@ -1398,23 +1396,23 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1398 1396
1399 /* Back channel attrs */ 1397 /* Back channel attrs */
1400 READ_BUF(28); 1398 READ_BUF(28);
1401 READ32(dummy); /* headerpadsz is always 0 */ 1399 dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
1402 READ32(sess->back_channel.maxreq_sz); 1400 sess->back_channel.maxreq_sz = be32_to_cpup(p++);
1403 READ32(sess->back_channel.maxresp_sz); 1401 sess->back_channel.maxresp_sz = be32_to_cpup(p++);
1404 READ32(sess->back_channel.maxresp_cached); 1402 sess->back_channel.maxresp_cached = be32_to_cpup(p++);
1405 READ32(sess->back_channel.maxops); 1403 sess->back_channel.maxops = be32_to_cpup(p++);
1406 READ32(sess->back_channel.maxreqs); 1404 sess->back_channel.maxreqs = be32_to_cpup(p++);
1407 READ32(sess->back_channel.nr_rdma_attrs); 1405 sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
1408 if (sess->back_channel.nr_rdma_attrs == 1) { 1406 if (sess->back_channel.nr_rdma_attrs == 1) {
1409 READ_BUF(4); 1407 READ_BUF(4);
1410 READ32(sess->back_channel.rdma_attrs); 1408 sess->back_channel.rdma_attrs = be32_to_cpup(p++);
1411 } else if (sess->back_channel.nr_rdma_attrs > 1) { 1409 } else if (sess->back_channel.nr_rdma_attrs > 1) {
1412 dprintk("Too many back channel attr bitmaps!\n"); 1410 dprintk("Too many back channel attr bitmaps!\n");
1413 goto xdr_error; 1411 goto xdr_error;
1414 } 1412 }
1415 1413
1416 READ_BUF(4); 1414 READ_BUF(4);
1417 READ32(sess->callback_prog); 1415 sess->callback_prog = be32_to_cpup(p++);
1418 nfsd4_decode_cb_sec(argp, &sess->cb_sec); 1416 nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1419 DECODE_TAIL; 1417 DECODE_TAIL;
1420} 1418}
@@ -1437,7 +1435,7 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1437 DECODE_HEAD; 1435 DECODE_HEAD;
1438 1436
1439 READ_BUF(sizeof(stateid_t)); 1437 READ_BUF(sizeof(stateid_t));
1440 READ32(free_stateid->fr_stateid.si_generation); 1438 free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
1441 COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t)); 1439 COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
1442 1440
1443 DECODE_TAIL; 1441 DECODE_TAIL;
@@ -1451,10 +1449,10 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1451 1449
1452 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16); 1450 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1453 COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1451 COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1454 READ32(seq->seqid); 1452 seq->seqid = be32_to_cpup(p++);
1455 READ32(seq->slotid); 1453 seq->slotid = be32_to_cpup(p++);
1456 READ32(seq->maxslots); 1454 seq->maxslots = be32_to_cpup(p++);
1457 READ32(seq->cachethis); 1455 seq->cachethis = be32_to_cpup(p++);
1458 1456
1459 DECODE_TAIL; 1457 DECODE_TAIL;
1460} 1458}
@@ -1511,7 +1509,7 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
1511 DECODE_HEAD; 1509 DECODE_HEAD;
1512 1510
1513 READ_BUF(4); 1511 READ_BUF(4);
1514 READ32(rc->rca_one_fs); 1512 rc->rca_one_fs = be32_to_cpup(p++);
1515 1513
1516 DECODE_TAIL; 1514 DECODE_TAIL;
1517} 1515}
@@ -1605,47 +1603,25 @@ nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
1605 return true; 1603 return true;
1606} 1604}
1607 1605
1608/*
1609 * Return a rough estimate of the maximum possible reply size. Note the
1610 * estimate includes rpc headers so is meant to be passed to
1611 * svc_reserve, not svc_reserve_auth.
1612 *
1613 * Also note the current compound encoding permits only one operation to
1614 * use pages beyond the first one, so the maximum possible length is the
1615 * maximum over these values, not the sum.
1616 */
1617static int nfsd4_max_reply(u32 opnum)
1618{
1619 switch (opnum) {
1620 case OP_READLINK:
1621 case OP_READDIR:
1622 /*
1623 * Both of these ops take a single page for data and put
1624 * the head and tail in another page:
1625 */
1626 return 2 * PAGE_SIZE;
1627 case OP_READ:
1628 return INT_MAX;
1629 default:
1630 return PAGE_SIZE;
1631 }
1632}
1633
1634static __be32 1606static __be32
1635nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 1607nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1636{ 1608{
1637 DECODE_HEAD; 1609 DECODE_HEAD;
1638 struct nfsd4_op *op; 1610 struct nfsd4_op *op;
1639 bool cachethis = false; 1611 bool cachethis = false;
1640 int max_reply = PAGE_SIZE; 1612 int auth_slack= argp->rqstp->rq_auth_slack;
1613 int max_reply = auth_slack + 8; /* opcnt, status */
1614 int readcount = 0;
1615 int readbytes = 0;
1641 int i; 1616 int i;
1642 1617
1643 READ_BUF(4); 1618 READ_BUF(4);
1644 READ32(argp->taglen); 1619 argp->taglen = be32_to_cpup(p++);
1645 READ_BUF(argp->taglen + 8); 1620 READ_BUF(argp->taglen + 8);
1646 SAVEMEM(argp->tag, argp->taglen); 1621 SAVEMEM(argp->tag, argp->taglen);
1647 READ32(argp->minorversion); 1622 argp->minorversion = be32_to_cpup(p++);
1648 READ32(argp->opcnt); 1623 argp->opcnt = be32_to_cpup(p++);
1624 max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
1649 1625
1650 if (argp->taglen > NFSD4_MAX_TAGLEN) 1626 if (argp->taglen > NFSD4_MAX_TAGLEN)
1651 goto xdr_error; 1627 goto xdr_error;
@@ -1669,7 +1645,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1669 op->replay = NULL; 1645 op->replay = NULL;
1670 1646
1671 READ_BUF(4); 1647 READ_BUF(4);
1672 READ32(op->opnum); 1648 op->opnum = be32_to_cpup(p++);
1673 1649
1674 if (nfsd4_opnum_in_range(argp, op)) 1650 if (nfsd4_opnum_in_range(argp, op))
1675 op->status = nfsd4_dec_ops[op->opnum](argp, &op->u); 1651 op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
@@ -1677,97 +1653,82 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1677 op->opnum = OP_ILLEGAL; 1653 op->opnum = OP_ILLEGAL;
1678 op->status = nfserr_op_illegal; 1654 op->status = nfserr_op_illegal;
1679 } 1655 }
1680
1681 if (op->status) {
1682 argp->opcnt = i+1;
1683 break;
1684 }
1685 /* 1656 /*
1686 * We'll try to cache the result in the DRC if any one 1657 * We'll try to cache the result in the DRC if any one
1687 * op in the compound wants to be cached: 1658 * op in the compound wants to be cached:
1688 */ 1659 */
1689 cachethis |= nfsd4_cache_this_op(op); 1660 cachethis |= nfsd4_cache_this_op(op);
1690 1661
1691 max_reply = max(max_reply, nfsd4_max_reply(op->opnum)); 1662 if (op->opnum == OP_READ) {
1663 readcount++;
1664 readbytes += nfsd4_max_reply(argp->rqstp, op);
1665 } else
1666 max_reply += nfsd4_max_reply(argp->rqstp, op);
1667
1668 if (op->status) {
1669 argp->opcnt = i+1;
1670 break;
1671 }
1692 } 1672 }
1693 /* Sessions make the DRC unnecessary: */ 1673 /* Sessions make the DRC unnecessary: */
1694 if (argp->minorversion) 1674 if (argp->minorversion)
1695 cachethis = false; 1675 cachethis = false;
1696 if (max_reply != INT_MAX) 1676 svc_reserve(argp->rqstp, max_reply + readbytes);
1697 svc_reserve(argp->rqstp, max_reply);
1698 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 1677 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
1699 1678
1700 DECODE_TAIL; 1679 if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
1701} 1680 argp->rqstp->rq_splice_ok = false;
1702
1703#define WRITE32(n) *p++ = htonl(n)
1704#define WRITE64(n) do { \
1705 *p++ = htonl((u32)((n) >> 32)); \
1706 *p++ = htonl((u32)(n)); \
1707} while (0)
1708#define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \
1709 *(p + XDR_QUADLEN(nbytes) -1) = 0; \
1710 memcpy(p, ptr, nbytes); \
1711 p += XDR_QUADLEN(nbytes); \
1712}} while (0)
1713
1714static void write32(__be32 **p, u32 n)
1715{
1716 *(*p)++ = htonl(n);
1717}
1718 1681
1719static void write64(__be32 **p, u64 n) 1682 DECODE_TAIL;
1720{
1721 write32(p, (n >> 32));
1722 write32(p, (u32)n);
1723} 1683}
1724 1684
1725static void write_change(__be32 **p, struct kstat *stat, struct inode *inode) 1685static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode)
1726{ 1686{
1727 if (IS_I_VERSION(inode)) { 1687 if (IS_I_VERSION(inode)) {
1728 write64(p, inode->i_version); 1688 p = xdr_encode_hyper(p, inode->i_version);
1729 } else { 1689 } else {
1730 write32(p, stat->ctime.tv_sec); 1690 *p++ = cpu_to_be32(stat->ctime.tv_sec);
1731 write32(p, stat->ctime.tv_nsec); 1691 *p++ = cpu_to_be32(stat->ctime.tv_nsec);
1732 } 1692 }
1693 return p;
1733} 1694}
1734 1695
1735static void write_cinfo(__be32 **p, struct nfsd4_change_info *c) 1696static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
1736{ 1697{
1737 write32(p, c->atomic); 1698 *p++ = cpu_to_be32(c->atomic);
1738 if (c->change_supported) { 1699 if (c->change_supported) {
1739 write64(p, c->before_change); 1700 p = xdr_encode_hyper(p, c->before_change);
1740 write64(p, c->after_change); 1701 p = xdr_encode_hyper(p, c->after_change);
1741 } else { 1702 } else {
1742 write32(p, c->before_ctime_sec); 1703 *p++ = cpu_to_be32(c->before_ctime_sec);
1743 write32(p, c->before_ctime_nsec); 1704 *p++ = cpu_to_be32(c->before_ctime_nsec);
1744 write32(p, c->after_ctime_sec); 1705 *p++ = cpu_to_be32(c->after_ctime_sec);
1745 write32(p, c->after_ctime_nsec); 1706 *p++ = cpu_to_be32(c->after_ctime_nsec);
1746 } 1707 }
1708 return p;
1747} 1709}
1748 1710
1749#define RESERVE_SPACE(nbytes) do { \
1750 p = resp->p; \
1751 BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end); \
1752} while (0)
1753#define ADJUST_ARGS() resp->p = p
1754
1755/* Encode as an array of strings the string given with components 1711/* Encode as an array of strings the string given with components
1756 * separated @sep, escaped with esc_enter and esc_exit. 1712 * separated @sep, escaped with esc_enter and esc_exit.
1757 */ 1713 */
1758static __be32 nfsd4_encode_components_esc(char sep, char *components, 1714static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
1759 __be32 **pp, int *buflen, 1715 char *components, char esc_enter,
1760 char esc_enter, char esc_exit) 1716 char esc_exit)
1761{ 1717{
1762 __be32 *p = *pp; 1718 __be32 *p;
1763 __be32 *countp = p; 1719 __be32 pathlen;
1720 int pathlen_offset;
1764 int strlen, count=0; 1721 int strlen, count=0;
1765 char *str, *end, *next; 1722 char *str, *end, *next;
1766 1723
1767 dprintk("nfsd4_encode_components(%s)\n", components); 1724 dprintk("nfsd4_encode_components(%s)\n", components);
1768 if ((*buflen -= 4) < 0) 1725
1726 pathlen_offset = xdr->buf->len;
1727 p = xdr_reserve_space(xdr, 4);
1728 if (!p)
1769 return nfserr_resource; 1729 return nfserr_resource;
1770 WRITE32(0); /* We will fill this in with @count later */ 1730 p++; /* We will fill this in with @count later */
1731
1771 end = str = components; 1732 end = str = components;
1772 while (*end) { 1733 while (*end) {
1773 bool found_esc = false; 1734 bool found_esc = false;
@@ -1789,59 +1750,57 @@ static __be32 nfsd4_encode_components_esc(char sep, char *components,
1789 1750
1790 strlen = end - str; 1751 strlen = end - str;
1791 if (strlen) { 1752 if (strlen) {
1792 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) 1753 p = xdr_reserve_space(xdr, strlen + 4);
1754 if (!p)
1793 return nfserr_resource; 1755 return nfserr_resource;
1794 WRITE32(strlen); 1756 p = xdr_encode_opaque(p, str, strlen);
1795 WRITEMEM(str, strlen);
1796 count++; 1757 count++;
1797 } 1758 }
1798 else 1759 else
1799 end++; 1760 end++;
1800 str = end; 1761 str = end;
1801 } 1762 }
1802 *pp = p; 1763 pathlen = htonl(xdr->buf->len - pathlen_offset);
1803 p = countp; 1764 write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
1804 WRITE32(count);
1805 return 0; 1765 return 0;
1806} 1766}
1807 1767
1808/* Encode as an array of strings the string given with components 1768/* Encode as an array of strings the string given with components
1809 * separated @sep. 1769 * separated @sep.
1810 */ 1770 */
1811static __be32 nfsd4_encode_components(char sep, char *components, 1771static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
1812 __be32 **pp, int *buflen) 1772 char *components)
1813{ 1773{
1814 return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0); 1774 return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
1815} 1775}
1816 1776
1817/* 1777/*
1818 * encode a location element of a fs_locations structure 1778 * encode a location element of a fs_locations structure
1819 */ 1779 */
1820static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, 1780static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
1821 __be32 **pp, int *buflen) 1781 struct nfsd4_fs_location *location)
1822{ 1782{
1823 __be32 status; 1783 __be32 status;
1824 __be32 *p = *pp;
1825 1784
1826 status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen, 1785 status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
1827 '[', ']'); 1786 '[', ']');
1828 if (status) 1787 if (status)
1829 return status; 1788 return status;
1830 status = nfsd4_encode_components('/', location->path, &p, buflen); 1789 status = nfsd4_encode_components(xdr, '/', location->path);
1831 if (status) 1790 if (status)
1832 return status; 1791 return status;
1833 *pp = p;
1834 return 0; 1792 return 0;
1835} 1793}
1836 1794
1837/* 1795/*
1838 * Encode a path in RFC3530 'pathname4' format 1796 * Encode a path in RFC3530 'pathname4' format
1839 */ 1797 */
1840static __be32 nfsd4_encode_path(const struct path *root, 1798static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
1841 const struct path *path, __be32 **pp, int *buflen) 1799 const struct path *root,
1800 const struct path *path)
1842{ 1801{
1843 struct path cur = *path; 1802 struct path cur = *path;
1844 __be32 *p = *pp; 1803 __be32 *p;
1845 struct dentry **components = NULL; 1804 struct dentry **components = NULL;
1846 unsigned int ncomponents = 0; 1805 unsigned int ncomponents = 0;
1847 __be32 err = nfserr_jukebox; 1806 __be32 err = nfserr_jukebox;
@@ -1872,11 +1831,11 @@ static __be32 nfsd4_encode_path(const struct path *root,
1872 components[ncomponents++] = cur.dentry; 1831 components[ncomponents++] = cur.dentry;
1873 cur.dentry = dget_parent(cur.dentry); 1832 cur.dentry = dget_parent(cur.dentry);
1874 } 1833 }
1875 1834 err = nfserr_resource;
1876 *buflen -= 4; 1835 p = xdr_reserve_space(xdr, 4);
1877 if (*buflen < 0) 1836 if (!p)
1878 goto out_free; 1837 goto out_free;
1879 WRITE32(ncomponents); 1838 *p++ = cpu_to_be32(ncomponents);
1880 1839
1881 while (ncomponents) { 1840 while (ncomponents) {
1882 struct dentry *dentry = components[ncomponents - 1]; 1841 struct dentry *dentry = components[ncomponents - 1];
@@ -1884,20 +1843,18 @@ static __be32 nfsd4_encode_path(const struct path *root,
1884 1843
1885 spin_lock(&dentry->d_lock); 1844 spin_lock(&dentry->d_lock);
1886 len = dentry->d_name.len; 1845 len = dentry->d_name.len;
1887 *buflen -= 4 + (XDR_QUADLEN(len) << 2); 1846 p = xdr_reserve_space(xdr, len + 4);
1888 if (*buflen < 0) { 1847 if (!p) {
1889 spin_unlock(&dentry->d_lock); 1848 spin_unlock(&dentry->d_lock);
1890 goto out_free; 1849 goto out_free;
1891 } 1850 }
1892 WRITE32(len); 1851 p = xdr_encode_opaque(p, dentry->d_name.name, len);
1893 WRITEMEM(dentry->d_name.name, len);
1894 dprintk("/%s", dentry->d_name.name); 1852 dprintk("/%s", dentry->d_name.name);
1895 spin_unlock(&dentry->d_lock); 1853 spin_unlock(&dentry->d_lock);
1896 dput(dentry); 1854 dput(dentry);
1897 ncomponents--; 1855 ncomponents--;
1898 } 1856 }
1899 1857
1900 *pp = p;
1901 err = 0; 1858 err = 0;
1902out_free: 1859out_free:
1903 dprintk(")\n"); 1860 dprintk(")\n");
@@ -1908,8 +1865,8 @@ out_free:
1908 return err; 1865 return err;
1909} 1866}
1910 1867
1911static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp, 1868static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
1912 const struct path *path, __be32 **pp, int *buflen) 1869 struct svc_rqst *rqstp, const struct path *path)
1913{ 1870{
1914 struct svc_export *exp_ps; 1871 struct svc_export *exp_ps;
1915 __be32 res; 1872 __be32 res;
@@ -1917,7 +1874,7 @@ static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
1917 exp_ps = rqst_find_fsidzero_export(rqstp); 1874 exp_ps = rqst_find_fsidzero_export(rqstp);
1918 if (IS_ERR(exp_ps)) 1875 if (IS_ERR(exp_ps))
1919 return nfserrno(PTR_ERR(exp_ps)); 1876 return nfserrno(PTR_ERR(exp_ps));
1920 res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen); 1877 res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
1921 exp_put(exp_ps); 1878 exp_put(exp_ps);
1922 return res; 1879 return res;
1923} 1880}
@@ -1925,28 +1882,26 @@ static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
1925/* 1882/*
1926 * encode a fs_locations structure 1883 * encode a fs_locations structure
1927 */ 1884 */
1928static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, 1885static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
1929 struct svc_export *exp, 1886 struct svc_rqst *rqstp, struct svc_export *exp)
1930 __be32 **pp, int *buflen)
1931{ 1887{
1932 __be32 status; 1888 __be32 status;
1933 int i; 1889 int i;
1934 __be32 *p = *pp; 1890 __be32 *p;
1935 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; 1891 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1936 1892
1937 status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen); 1893 status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
1938 if (status) 1894 if (status)
1939 return status; 1895 return status;
1940 if ((*buflen -= 4) < 0) 1896 p = xdr_reserve_space(xdr, 4);
1897 if (!p)
1941 return nfserr_resource; 1898 return nfserr_resource;
1942 WRITE32(fslocs->locations_count); 1899 *p++ = cpu_to_be32(fslocs->locations_count);
1943 for (i=0; i<fslocs->locations_count; i++) { 1900 for (i=0; i<fslocs->locations_count; i++) {
1944 status = nfsd4_encode_fs_location4(&fslocs->locations[i], 1901 status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
1945 &p, buflen);
1946 if (status) 1902 if (status)
1947 return status; 1903 return status;
1948 } 1904 }
1949 *pp = p;
1950 return 0; 1905 return 0;
1951} 1906}
1952 1907
@@ -1965,15 +1920,15 @@ static u32 nfs4_file_type(umode_t mode)
1965} 1920}
1966 1921
1967static inline __be32 1922static inline __be32
1968nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace, 1923nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
1969 __be32 **p, int *buflen) 1924 struct nfs4_ace *ace)
1970{ 1925{
1971 if (ace->whotype != NFS4_ACL_WHO_NAMED) 1926 if (ace->whotype != NFS4_ACL_WHO_NAMED)
1972 return nfs4_acl_write_who(ace->whotype, p, buflen); 1927 return nfs4_acl_write_who(xdr, ace->whotype);
1973 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 1928 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
1974 return nfsd4_encode_group(rqstp, ace->who_gid, p, buflen); 1929 return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
1975 else 1930 else
1976 return nfsd4_encode_user(rqstp, ace->who_uid, p, buflen); 1931 return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
1977} 1932}
1978 1933
1979#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ 1934#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
@@ -1982,31 +1937,28 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
1982 1937
1983#ifdef CONFIG_NFSD_V4_SECURITY_LABEL 1938#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
1984static inline __be32 1939static inline __be32
1985nfsd4_encode_security_label(struct svc_rqst *rqstp, void *context, int len, __be32 **pp, int *buflen) 1940nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
1941 void *context, int len)
1986{ 1942{
1987 __be32 *p = *pp; 1943 __be32 *p;
1988 1944
1989 if (*buflen < ((XDR_QUADLEN(len) << 2) + 4 + 4 + 4)) 1945 p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
1946 if (!p)
1990 return nfserr_resource; 1947 return nfserr_resource;
1991 1948
1992 /* 1949 /*
1993 * For now we use a 0 here to indicate the null translation; in 1950 * For now we use a 0 here to indicate the null translation; in
1994 * the future we may place a call to translation code here. 1951 * the future we may place a call to translation code here.
1995 */ 1952 */
1996 if ((*buflen -= 8) < 0) 1953 *p++ = cpu_to_be32(0); /* lfs */
1997 return nfserr_resource; 1954 *p++ = cpu_to_be32(0); /* pi */
1998
1999 WRITE32(0); /* lfs */
2000 WRITE32(0); /* pi */
2001 p = xdr_encode_opaque(p, context, len); 1955 p = xdr_encode_opaque(p, context, len);
2002 *buflen -= (XDR_QUADLEN(len) << 2) + 4;
2003
2004 *pp = p;
2005 return 0; 1956 return 0;
2006} 1957}
2007#else 1958#else
2008static inline __be32 1959static inline __be32
2009nfsd4_encode_security_label(struct svc_rqst *rqstp, void *context, int len, __be32 **pp, int *buflen) 1960nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
1961 void *context, int len)
2010{ return 0; } 1962{ return 0; }
2011#endif 1963#endif
2012 1964
@@ -2045,12 +1997,11 @@ static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2045/* 1997/*
2046 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 1998 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2047 * ourselves. 1999 * ourselves.
2048 *
2049 * countp is the buffer size in _words_
2050 */ 2000 */
2051__be32 2001static __be32
2052nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 2002nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
2053 struct dentry *dentry, __be32 **buffer, int count, u32 *bmval, 2003 struct svc_export *exp,
2004 struct dentry *dentry, u32 *bmval,
2054 struct svc_rqst *rqstp, int ignore_crossmnt) 2005 struct svc_rqst *rqstp, int ignore_crossmnt)
2055{ 2006{
2056 u32 bmval0 = bmval[0]; 2007 u32 bmval0 = bmval[0];
@@ -2059,12 +2010,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2059 struct kstat stat; 2010 struct kstat stat;
2060 struct svc_fh *tempfh = NULL; 2011 struct svc_fh *tempfh = NULL;
2061 struct kstatfs statfs; 2012 struct kstatfs statfs;
2062 int buflen = count << 2; 2013 __be32 *p;
2063 __be32 *attrlenp; 2014 int starting_len = xdr->buf->len;
2015 int attrlen_offset;
2016 __be32 attrlen;
2064 u32 dummy; 2017 u32 dummy;
2065 u64 dummy64; 2018 u64 dummy64;
2066 u32 rdattr_err = 0; 2019 u32 rdattr_err = 0;
2067 __be32 *p = *buffer;
2068 __be32 status; 2020 __be32 status;
2069 int err; 2021 int err;
2070 int aclsupport = 0; 2022 int aclsupport = 0;
@@ -2095,8 +2047,8 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2095 err = vfs_getattr(&path, &stat); 2047 err = vfs_getattr(&path, &stat);
2096 if (err) 2048 if (err)
2097 goto out_nfserr; 2049 goto out_nfserr;
2098 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | 2050 if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2099 FATTR4_WORD0_MAXNAME)) || 2051 FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2100 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | 2052 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2101 FATTR4_WORD1_SPACE_TOTAL))) { 2053 FATTR4_WORD1_SPACE_TOTAL))) {
2102 err = vfs_statfs(&path, &statfs); 2054 err = vfs_statfs(&path, &statfs);
@@ -2145,25 +2097,33 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2145#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ 2097#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2146 2098
2147 if (bmval2) { 2099 if (bmval2) {
2148 if ((buflen -= 16) < 0) 2100 p = xdr_reserve_space(xdr, 16);
2101 if (!p)
2149 goto out_resource; 2102 goto out_resource;
2150 WRITE32(3); 2103 *p++ = cpu_to_be32(3);
2151 WRITE32(bmval0); 2104 *p++ = cpu_to_be32(bmval0);
2152 WRITE32(bmval1); 2105 *p++ = cpu_to_be32(bmval1);
2153 WRITE32(bmval2); 2106 *p++ = cpu_to_be32(bmval2);
2154 } else if (bmval1) { 2107 } else if (bmval1) {
2155 if ((buflen -= 12) < 0) 2108 p = xdr_reserve_space(xdr, 12);
2109 if (!p)
2156 goto out_resource; 2110 goto out_resource;
2157 WRITE32(2); 2111 *p++ = cpu_to_be32(2);
2158 WRITE32(bmval0); 2112 *p++ = cpu_to_be32(bmval0);
2159 WRITE32(bmval1); 2113 *p++ = cpu_to_be32(bmval1);
2160 } else { 2114 } else {
2161 if ((buflen -= 8) < 0) 2115 p = xdr_reserve_space(xdr, 8);
2116 if (!p)
2162 goto out_resource; 2117 goto out_resource;
2163 WRITE32(1); 2118 *p++ = cpu_to_be32(1);
2164 WRITE32(bmval0); 2119 *p++ = cpu_to_be32(bmval0);
2165 } 2120 }
2166 attrlenp = p++; /* to be backfilled later */ 2121
2122 attrlen_offset = xdr->buf->len;
2123 p = xdr_reserve_space(xdr, 4);
2124 if (!p)
2125 goto out_resource;
2126 p++; /* to be backfilled later */
2167 2127
2168 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { 2128 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2169 u32 word0 = nfsd_suppattrs0(minorversion); 2129 u32 word0 = nfsd_suppattrs0(minorversion);
@@ -2175,296 +2135,343 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2175 if (!contextsupport) 2135 if (!contextsupport)
2176 word2 &= ~FATTR4_WORD2_SECURITY_LABEL; 2136 word2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2177 if (!word2) { 2137 if (!word2) {
2178 if ((buflen -= 12) < 0) 2138 p = xdr_reserve_space(xdr, 12);
2139 if (!p)
2179 goto out_resource; 2140 goto out_resource;
2180 WRITE32(2); 2141 *p++ = cpu_to_be32(2);
2181 WRITE32(word0); 2142 *p++ = cpu_to_be32(word0);
2182 WRITE32(word1); 2143 *p++ = cpu_to_be32(word1);
2183 } else { 2144 } else {
2184 if ((buflen -= 16) < 0) 2145 p = xdr_reserve_space(xdr, 16);
2146 if (!p)
2185 goto out_resource; 2147 goto out_resource;
2186 WRITE32(3); 2148 *p++ = cpu_to_be32(3);
2187 WRITE32(word0); 2149 *p++ = cpu_to_be32(word0);
2188 WRITE32(word1); 2150 *p++ = cpu_to_be32(word1);
2189 WRITE32(word2); 2151 *p++ = cpu_to_be32(word2);
2190 } 2152 }
2191 } 2153 }
2192 if (bmval0 & FATTR4_WORD0_TYPE) { 2154 if (bmval0 & FATTR4_WORD0_TYPE) {
2193 if ((buflen -= 4) < 0) 2155 p = xdr_reserve_space(xdr, 4);
2156 if (!p)
2194 goto out_resource; 2157 goto out_resource;
2195 dummy = nfs4_file_type(stat.mode); 2158 dummy = nfs4_file_type(stat.mode);
2196 if (dummy == NF4BAD) { 2159 if (dummy == NF4BAD) {
2197 status = nfserr_serverfault; 2160 status = nfserr_serverfault;
2198 goto out; 2161 goto out;
2199 } 2162 }
2200 WRITE32(dummy); 2163 *p++ = cpu_to_be32(dummy);
2201 } 2164 }
2202 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { 2165 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2203 if ((buflen -= 4) < 0) 2166 p = xdr_reserve_space(xdr, 4);
2167 if (!p)
2204 goto out_resource; 2168 goto out_resource;
2205 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 2169 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2206 WRITE32(NFS4_FH_PERSISTENT); 2170 *p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
2207 else 2171 else
2208 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME); 2172 *p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
2173 NFS4_FH_VOL_RENAME);
2209 } 2174 }
2210 if (bmval0 & FATTR4_WORD0_CHANGE) { 2175 if (bmval0 & FATTR4_WORD0_CHANGE) {
2211 if ((buflen -= 8) < 0) 2176 p = xdr_reserve_space(xdr, 8);
2177 if (!p)
2212 goto out_resource; 2178 goto out_resource;
2213 write_change(&p, &stat, dentry->d_inode); 2179 p = encode_change(p, &stat, dentry->d_inode);
2214 } 2180 }
2215 if (bmval0 & FATTR4_WORD0_SIZE) { 2181 if (bmval0 & FATTR4_WORD0_SIZE) {
2216 if ((buflen -= 8) < 0) 2182 p = xdr_reserve_space(xdr, 8);
2183 if (!p)
2217 goto out_resource; 2184 goto out_resource;
2218 WRITE64(stat.size); 2185 p = xdr_encode_hyper(p, stat.size);
2219 } 2186 }
2220 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) { 2187 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2221 if ((buflen -= 4) < 0) 2188 p = xdr_reserve_space(xdr, 4);
2189 if (!p)
2222 goto out_resource; 2190 goto out_resource;
2223 WRITE32(1); 2191 *p++ = cpu_to_be32(1);
2224 } 2192 }
2225 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) { 2193 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2226 if ((buflen -= 4) < 0) 2194 p = xdr_reserve_space(xdr, 4);
2195 if (!p)
2227 goto out_resource; 2196 goto out_resource;
2228 WRITE32(1); 2197 *p++ = cpu_to_be32(1);
2229 } 2198 }
2230 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) { 2199 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
2231 if ((buflen -= 4) < 0) 2200 p = xdr_reserve_space(xdr, 4);
2201 if (!p)
2232 goto out_resource; 2202 goto out_resource;
2233 WRITE32(0); 2203 *p++ = cpu_to_be32(0);
2234 } 2204 }
2235 if (bmval0 & FATTR4_WORD0_FSID) { 2205 if (bmval0 & FATTR4_WORD0_FSID) {
2236 if ((buflen -= 16) < 0) 2206 p = xdr_reserve_space(xdr, 16);
2207 if (!p)
2237 goto out_resource; 2208 goto out_resource;
2238 if (exp->ex_fslocs.migrated) { 2209 if (exp->ex_fslocs.migrated) {
2239 WRITE64(NFS4_REFERRAL_FSID_MAJOR); 2210 p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
2240 WRITE64(NFS4_REFERRAL_FSID_MINOR); 2211 p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
2241 } else switch(fsid_source(fhp)) { 2212 } else switch(fsid_source(fhp)) {
2242 case FSIDSOURCE_FSID: 2213 case FSIDSOURCE_FSID:
2243 WRITE64((u64)exp->ex_fsid); 2214 p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
2244 WRITE64((u64)0); 2215 p = xdr_encode_hyper(p, (u64)0);
2245 break; 2216 break;
2246 case FSIDSOURCE_DEV: 2217 case FSIDSOURCE_DEV:
2247 WRITE32(0); 2218 *p++ = cpu_to_be32(0);
2248 WRITE32(MAJOR(stat.dev)); 2219 *p++ = cpu_to_be32(MAJOR(stat.dev));
2249 WRITE32(0); 2220 *p++ = cpu_to_be32(0);
2250 WRITE32(MINOR(stat.dev)); 2221 *p++ = cpu_to_be32(MINOR(stat.dev));
2251 break; 2222 break;
2252 case FSIDSOURCE_UUID: 2223 case FSIDSOURCE_UUID:
2253 WRITEMEM(exp->ex_uuid, 16); 2224 p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
2225 EX_UUID_LEN);
2254 break; 2226 break;
2255 } 2227 }
2256 } 2228 }
2257 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) { 2229 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2258 if ((buflen -= 4) < 0) 2230 p = xdr_reserve_space(xdr, 4);
2231 if (!p)
2259 goto out_resource; 2232 goto out_resource;
2260 WRITE32(0); 2233 *p++ = cpu_to_be32(0);
2261 } 2234 }
2262 if (bmval0 & FATTR4_WORD0_LEASE_TIME) { 2235 if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2263 if ((buflen -= 4) < 0) 2236 p = xdr_reserve_space(xdr, 4);
2237 if (!p)
2264 goto out_resource; 2238 goto out_resource;
2265 WRITE32(nn->nfsd4_lease); 2239 *p++ = cpu_to_be32(nn->nfsd4_lease);
2266 } 2240 }
2267 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 2241 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2268 if ((buflen -= 4) < 0) 2242 p = xdr_reserve_space(xdr, 4);
2243 if (!p)
2269 goto out_resource; 2244 goto out_resource;
2270 WRITE32(rdattr_err); 2245 *p++ = cpu_to_be32(rdattr_err);
2271 } 2246 }
2272 if (bmval0 & FATTR4_WORD0_ACL) { 2247 if (bmval0 & FATTR4_WORD0_ACL) {
2273 struct nfs4_ace *ace; 2248 struct nfs4_ace *ace;
2274 2249
2275 if (acl == NULL) { 2250 if (acl == NULL) {
2276 if ((buflen -= 4) < 0) 2251 p = xdr_reserve_space(xdr, 4);
2252 if (!p)
2277 goto out_resource; 2253 goto out_resource;
2278 2254
2279 WRITE32(0); 2255 *p++ = cpu_to_be32(0);
2280 goto out_acl; 2256 goto out_acl;
2281 } 2257 }
2282 if ((buflen -= 4) < 0) 2258 p = xdr_reserve_space(xdr, 4);
2259 if (!p)
2283 goto out_resource; 2260 goto out_resource;
2284 WRITE32(acl->naces); 2261 *p++ = cpu_to_be32(acl->naces);
2285 2262
2286 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { 2263 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2287 if ((buflen -= 4*3) < 0) 2264 p = xdr_reserve_space(xdr, 4*3);
2265 if (!p)
2288 goto out_resource; 2266 goto out_resource;
2289 WRITE32(ace->type); 2267 *p++ = cpu_to_be32(ace->type);
2290 WRITE32(ace->flag); 2268 *p++ = cpu_to_be32(ace->flag);
2291 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 2269 *p++ = cpu_to_be32(ace->access_mask &
2292 status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen); 2270 NFS4_ACE_MASK_ALL);
2271 status = nfsd4_encode_aclname(xdr, rqstp, ace);
2293 if (status) 2272 if (status)
2294 goto out; 2273 goto out;
2295 } 2274 }
2296 } 2275 }
2297out_acl: 2276out_acl:
2298 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { 2277 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2299 if ((buflen -= 4) < 0) 2278 p = xdr_reserve_space(xdr, 4);
2279 if (!p)
2300 goto out_resource; 2280 goto out_resource;
2301 WRITE32(aclsupport ? 2281 *p++ = cpu_to_be32(aclsupport ?
2302 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); 2282 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2303 } 2283 }
2304 if (bmval0 & FATTR4_WORD0_CANSETTIME) { 2284 if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2305 if ((buflen -= 4) < 0) 2285 p = xdr_reserve_space(xdr, 4);
2286 if (!p)
2306 goto out_resource; 2287 goto out_resource;
2307 WRITE32(1); 2288 *p++ = cpu_to_be32(1);
2308 } 2289 }
2309 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { 2290 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2310 if ((buflen -= 4) < 0) 2291 p = xdr_reserve_space(xdr, 4);
2292 if (!p)
2311 goto out_resource; 2293 goto out_resource;
2312 WRITE32(0); 2294 *p++ = cpu_to_be32(0);
2313 } 2295 }
2314 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { 2296 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2315 if ((buflen -= 4) < 0) 2297 p = xdr_reserve_space(xdr, 4);
2298 if (!p)
2316 goto out_resource; 2299 goto out_resource;
2317 WRITE32(1); 2300 *p++ = cpu_to_be32(1);
2318 } 2301 }
2319 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) { 2302 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2320 if ((buflen -= 4) < 0) 2303 p = xdr_reserve_space(xdr, 4);
2304 if (!p)
2321 goto out_resource; 2305 goto out_resource;
2322 WRITE32(1); 2306 *p++ = cpu_to_be32(1);
2323 } 2307 }
2324 if (bmval0 & FATTR4_WORD0_FILEHANDLE) { 2308 if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2325 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4; 2309 p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
2326 if (buflen < 0) 2310 if (!p)
2327 goto out_resource; 2311 goto out_resource;
2328 WRITE32(fhp->fh_handle.fh_size); 2312 p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
2329 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size); 2313 fhp->fh_handle.fh_size);
2330 } 2314 }
2331 if (bmval0 & FATTR4_WORD0_FILEID) { 2315 if (bmval0 & FATTR4_WORD0_FILEID) {
2332 if ((buflen -= 8) < 0) 2316 p = xdr_reserve_space(xdr, 8);
2317 if (!p)
2333 goto out_resource; 2318 goto out_resource;
2334 WRITE64(stat.ino); 2319 p = xdr_encode_hyper(p, stat.ino);
2335 } 2320 }
2336 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) { 2321 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2337 if ((buflen -= 8) < 0) 2322 p = xdr_reserve_space(xdr, 8);
2323 if (!p)
2338 goto out_resource; 2324 goto out_resource;
2339 WRITE64((u64) statfs.f_ffree); 2325 p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2340 } 2326 }
2341 if (bmval0 & FATTR4_WORD0_FILES_FREE) { 2327 if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2342 if ((buflen -= 8) < 0) 2328 p = xdr_reserve_space(xdr, 8);
2329 if (!p)
2343 goto out_resource; 2330 goto out_resource;
2344 WRITE64((u64) statfs.f_ffree); 2331 p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2345 } 2332 }
2346 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) { 2333 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2347 if ((buflen -= 8) < 0) 2334 p = xdr_reserve_space(xdr, 8);
2335 if (!p)
2348 goto out_resource; 2336 goto out_resource;
2349 WRITE64((u64) statfs.f_files); 2337 p = xdr_encode_hyper(p, (u64) statfs.f_files);
2350 } 2338 }
2351 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 2339 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2352 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); 2340 status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
2353 if (status) 2341 if (status)
2354 goto out; 2342 goto out;
2355 } 2343 }
2356 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { 2344 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2357 if ((buflen -= 4) < 0) 2345 p = xdr_reserve_space(xdr, 4);
2346 if (!p)
2358 goto out_resource; 2347 goto out_resource;
2359 WRITE32(1); 2348 *p++ = cpu_to_be32(1);
2360 } 2349 }
2361 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { 2350 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2362 if ((buflen -= 8) < 0) 2351 p = xdr_reserve_space(xdr, 8);
2352 if (!p)
2363 goto out_resource; 2353 goto out_resource;
2364 WRITE64(exp->ex_path.mnt->mnt_sb->s_maxbytes); 2354 p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
2365 } 2355 }
2366 if (bmval0 & FATTR4_WORD0_MAXLINK) { 2356 if (bmval0 & FATTR4_WORD0_MAXLINK) {
2367 if ((buflen -= 4) < 0) 2357 p = xdr_reserve_space(xdr, 4);
2358 if (!p)
2368 goto out_resource; 2359 goto out_resource;
2369 WRITE32(255); 2360 *p++ = cpu_to_be32(255);
2370 } 2361 }
2371 if (bmval0 & FATTR4_WORD0_MAXNAME) { 2362 if (bmval0 & FATTR4_WORD0_MAXNAME) {
2372 if ((buflen -= 4) < 0) 2363 p = xdr_reserve_space(xdr, 4);
2364 if (!p)
2373 goto out_resource; 2365 goto out_resource;
2374 WRITE32(statfs.f_namelen); 2366 *p++ = cpu_to_be32(statfs.f_namelen);
2375 } 2367 }
2376 if (bmval0 & FATTR4_WORD0_MAXREAD) { 2368 if (bmval0 & FATTR4_WORD0_MAXREAD) {
2377 if ((buflen -= 8) < 0) 2369 p = xdr_reserve_space(xdr, 8);
2370 if (!p)
2378 goto out_resource; 2371 goto out_resource;
2379 WRITE64((u64) svc_max_payload(rqstp)); 2372 p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2380 } 2373 }
2381 if (bmval0 & FATTR4_WORD0_MAXWRITE) { 2374 if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2382 if ((buflen -= 8) < 0) 2375 p = xdr_reserve_space(xdr, 8);
2376 if (!p)
2383 goto out_resource; 2377 goto out_resource;
2384 WRITE64((u64) svc_max_payload(rqstp)); 2378 p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2385 } 2379 }
2386 if (bmval1 & FATTR4_WORD1_MODE) { 2380 if (bmval1 & FATTR4_WORD1_MODE) {
2387 if ((buflen -= 4) < 0) 2381 p = xdr_reserve_space(xdr, 4);
2382 if (!p)
2388 goto out_resource; 2383 goto out_resource;
2389 WRITE32(stat.mode & S_IALLUGO); 2384 *p++ = cpu_to_be32(stat.mode & S_IALLUGO);
2390 } 2385 }
2391 if (bmval1 & FATTR4_WORD1_NO_TRUNC) { 2386 if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2392 if ((buflen -= 4) < 0) 2387 p = xdr_reserve_space(xdr, 4);
2388 if (!p)
2393 goto out_resource; 2389 goto out_resource;
2394 WRITE32(1); 2390 *p++ = cpu_to_be32(1);
2395 } 2391 }
2396 if (bmval1 & FATTR4_WORD1_NUMLINKS) { 2392 if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2397 if ((buflen -= 4) < 0) 2393 p = xdr_reserve_space(xdr, 4);
2394 if (!p)
2398 goto out_resource; 2395 goto out_resource;
2399 WRITE32(stat.nlink); 2396 *p++ = cpu_to_be32(stat.nlink);
2400 } 2397 }
2401 if (bmval1 & FATTR4_WORD1_OWNER) { 2398 if (bmval1 & FATTR4_WORD1_OWNER) {
2402 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); 2399 status = nfsd4_encode_user(xdr, rqstp, stat.uid);
2403 if (status) 2400 if (status)
2404 goto out; 2401 goto out;
2405 } 2402 }
2406 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { 2403 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2407 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); 2404 status = nfsd4_encode_group(xdr, rqstp, stat.gid);
2408 if (status) 2405 if (status)
2409 goto out; 2406 goto out;
2410 } 2407 }
2411 if (bmval1 & FATTR4_WORD1_RAWDEV) { 2408 if (bmval1 & FATTR4_WORD1_RAWDEV) {
2412 if ((buflen -= 8) < 0) 2409 p = xdr_reserve_space(xdr, 8);
2410 if (!p)
2413 goto out_resource; 2411 goto out_resource;
2414 WRITE32((u32) MAJOR(stat.rdev)); 2412 *p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
2415 WRITE32((u32) MINOR(stat.rdev)); 2413 *p++ = cpu_to_be32((u32) MINOR(stat.rdev));
2416 } 2414 }
2417 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) { 2415 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2418 if ((buflen -= 8) < 0) 2416 p = xdr_reserve_space(xdr, 8);
2417 if (!p)
2419 goto out_resource; 2418 goto out_resource;
2420 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize; 2419 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2421 WRITE64(dummy64); 2420 p = xdr_encode_hyper(p, dummy64);
2422 } 2421 }
2423 if (bmval1 & FATTR4_WORD1_SPACE_FREE) { 2422 if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2424 if ((buflen -= 8) < 0) 2423 p = xdr_reserve_space(xdr, 8);
2424 if (!p)
2425 goto out_resource; 2425 goto out_resource;
2426 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize; 2426 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2427 WRITE64(dummy64); 2427 p = xdr_encode_hyper(p, dummy64);
2428 } 2428 }
2429 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) { 2429 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2430 if ((buflen -= 8) < 0) 2430 p = xdr_reserve_space(xdr, 8);
2431 if (!p)
2431 goto out_resource; 2432 goto out_resource;
2432 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize; 2433 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2433 WRITE64(dummy64); 2434 p = xdr_encode_hyper(p, dummy64);
2434 } 2435 }
2435 if (bmval1 & FATTR4_WORD1_SPACE_USED) { 2436 if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2436 if ((buflen -= 8) < 0) 2437 p = xdr_reserve_space(xdr, 8);
2438 if (!p)
2437 goto out_resource; 2439 goto out_resource;
2438 dummy64 = (u64)stat.blocks << 9; 2440 dummy64 = (u64)stat.blocks << 9;
2439 WRITE64(dummy64); 2441 p = xdr_encode_hyper(p, dummy64);
2440 } 2442 }
2441 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { 2443 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2442 if ((buflen -= 12) < 0) 2444 p = xdr_reserve_space(xdr, 12);
2445 if (!p)
2443 goto out_resource; 2446 goto out_resource;
2444 WRITE64((s64)stat.atime.tv_sec); 2447 p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
2445 WRITE32(stat.atime.tv_nsec); 2448 *p++ = cpu_to_be32(stat.atime.tv_nsec);
2446 } 2449 }
2447 if (bmval1 & FATTR4_WORD1_TIME_DELTA) { 2450 if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2448 if ((buflen -= 12) < 0) 2451 p = xdr_reserve_space(xdr, 12);
2452 if (!p)
2449 goto out_resource; 2453 goto out_resource;
2450 WRITE32(0); 2454 *p++ = cpu_to_be32(0);
2451 WRITE32(1); 2455 *p++ = cpu_to_be32(1);
2452 WRITE32(0); 2456 *p++ = cpu_to_be32(0);
2453 } 2457 }
2454 if (bmval1 & FATTR4_WORD1_TIME_METADATA) { 2458 if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2455 if ((buflen -= 12) < 0) 2459 p = xdr_reserve_space(xdr, 12);
2460 if (!p)
2456 goto out_resource; 2461 goto out_resource;
2457 WRITE64((s64)stat.ctime.tv_sec); 2462 p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
2458 WRITE32(stat.ctime.tv_nsec); 2463 *p++ = cpu_to_be32(stat.ctime.tv_nsec);
2459 } 2464 }
2460 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { 2465 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2461 if ((buflen -= 12) < 0) 2466 p = xdr_reserve_space(xdr, 12);
2467 if (!p)
2462 goto out_resource; 2468 goto out_resource;
2463 WRITE64((s64)stat.mtime.tv_sec); 2469 p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
2464 WRITE32(stat.mtime.tv_nsec); 2470 *p++ = cpu_to_be32(stat.mtime.tv_nsec);
2465 } 2471 }
2466 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { 2472 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2467 if ((buflen -= 8) < 0) 2473 p = xdr_reserve_space(xdr, 8);
2474 if (!p)
2468 goto out_resource; 2475 goto out_resource;
2469 /* 2476 /*
2470 * Get parent's attributes if not ignoring crossmount 2477 * Get parent's attributes if not ignoring crossmount
@@ -2473,25 +2480,26 @@ out_acl:
2473 if (ignore_crossmnt == 0 && 2480 if (ignore_crossmnt == 0 &&
2474 dentry == exp->ex_path.mnt->mnt_root) 2481 dentry == exp->ex_path.mnt->mnt_root)
2475 get_parent_attributes(exp, &stat); 2482 get_parent_attributes(exp, &stat);
2476 WRITE64(stat.ino); 2483 p = xdr_encode_hyper(p, stat.ino);
2477 } 2484 }
2478 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) { 2485 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2479 status = nfsd4_encode_security_label(rqstp, context, 2486 status = nfsd4_encode_security_label(xdr, rqstp, context,
2480 contextlen, &p, &buflen); 2487 contextlen);
2481 if (status) 2488 if (status)
2482 goto out; 2489 goto out;
2483 } 2490 }
2484 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2491 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2485 if ((buflen -= 16) < 0) 2492 p = xdr_reserve_space(xdr, 16);
2493 if (!p)
2486 goto out_resource; 2494 goto out_resource;
2487 WRITE32(3); 2495 *p++ = cpu_to_be32(3);
2488 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); 2496 *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2489 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1); 2497 *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2490 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2); 2498 *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2491 } 2499 }
2492 2500
2493 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2501 attrlen = htonl(xdr->buf->len - attrlen_offset - 4);
2494 *buffer = p; 2502 write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4);
2495 status = nfs_ok; 2503 status = nfs_ok;
2496 2504
2497out: 2505out:
@@ -2504,6 +2512,8 @@ out:
2504 fh_put(tempfh); 2512 fh_put(tempfh);
2505 kfree(tempfh); 2513 kfree(tempfh);
2506 } 2514 }
2515 if (status)
2516 xdr_truncate_encode(xdr, starting_len);
2507 return status; 2517 return status;
2508out_nfserr: 2518out_nfserr:
2509 status = nfserrno(err); 2519 status = nfserrno(err);
@@ -2513,6 +2523,37 @@ out_resource:
2513 goto out; 2523 goto out;
2514} 2524}
2515 2525
2526static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
2527 struct xdr_buf *buf, __be32 *p, int bytes)
2528{
2529 xdr->scratch.iov_len = 0;
2530 memset(buf, 0, sizeof(struct xdr_buf));
2531 buf->head[0].iov_base = p;
2532 buf->head[0].iov_len = 0;
2533 buf->len = 0;
2534 xdr->buf = buf;
2535 xdr->iov = buf->head;
2536 xdr->p = p;
2537 xdr->end = (void *)p + bytes;
2538 buf->buflen = bytes;
2539}
2540
2541__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
2542 struct svc_fh *fhp, struct svc_export *exp,
2543 struct dentry *dentry, u32 *bmval,
2544 struct svc_rqst *rqstp, int ignore_crossmnt)
2545{
2546 struct xdr_buf dummy;
2547 struct xdr_stream xdr;
2548 __be32 ret;
2549
2550 svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
2551 ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
2552 ignore_crossmnt);
2553 *p = xdr.p;
2554 return ret;
2555}
2556
2516static inline int attributes_need_mount(u32 *bmval) 2557static inline int attributes_need_mount(u32 *bmval)
2517{ 2558{
2518 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME)) 2559 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
@@ -2523,8 +2564,8 @@ static inline int attributes_need_mount(u32 *bmval)
2523} 2564}
2524 2565
2525static __be32 2566static __be32
2526nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 2567nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
2527 const char *name, int namlen, __be32 **p, int buflen) 2568 const char *name, int namlen)
2528{ 2569{
2529 struct svc_export *exp = cd->rd_fhp->fh_export; 2570 struct svc_export *exp = cd->rd_fhp->fh_export;
2530 struct dentry *dentry; 2571 struct dentry *dentry;
@@ -2576,7 +2617,7 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2576 2617
2577 } 2618 }
2578out_encode: 2619out_encode:
2579 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, 2620 nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
2580 cd->rd_rqstp, ignore_crossmnt); 2621 cd->rd_rqstp, ignore_crossmnt);
2581out_put: 2622out_put:
2582 dput(dentry); 2623 dput(dentry);
@@ -2585,9 +2626,12 @@ out_put:
2585} 2626}
2586 2627
2587static __be32 * 2628static __be32 *
2588nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) 2629nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
2589{ 2630{
2590 if (buflen < 6) 2631 __be32 *p;
2632
2633 p = xdr_reserve_space(xdr, 6);
2634 if (!p)
2591 return NULL; 2635 return NULL;
2592 *p++ = htonl(2); 2636 *p++ = htonl(2);
2593 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */ 2637 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
@@ -2604,10 +2648,13 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2604{ 2648{
2605 struct readdir_cd *ccd = ccdv; 2649 struct readdir_cd *ccd = ccdv;
2606 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 2650 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2607 int buflen; 2651 struct xdr_stream *xdr = cd->xdr;
2608 __be32 *p = cd->buffer; 2652 int start_offset = xdr->buf->len;
2609 __be32 *cookiep; 2653 int cookie_offset;
2654 int entry_bytes;
2610 __be32 nfserr = nfserr_toosmall; 2655 __be32 nfserr = nfserr_toosmall;
2656 __be64 wire_offset;
2657 __be32 *p;
2611 2658
2612 /* In nfsv4, "." and ".." never make it onto the wire.. */ 2659 /* In nfsv4, "." and ".." never make it onto the wire.. */
2613 if (name && isdotent(name, namlen)) { 2660 if (name && isdotent(name, namlen)) {
@@ -2615,19 +2662,24 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2615 return 0; 2662 return 0;
2616 } 2663 }
2617 2664
2618 if (cd->offset) 2665 if (cd->cookie_offset) {
2619 xdr_encode_hyper(cd->offset, (u64) offset); 2666 wire_offset = cpu_to_be64(offset);
2667 write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
2668 &wire_offset, 8);
2669 }
2620 2670
2621 buflen = cd->buflen - 4 - XDR_QUADLEN(namlen); 2671 p = xdr_reserve_space(xdr, 4);
2622 if (buflen < 0) 2672 if (!p)
2623 goto fail; 2673 goto fail;
2624
2625 *p++ = xdr_one; /* mark entry present */ 2674 *p++ = xdr_one; /* mark entry present */
2626 cookiep = p; 2675 cookie_offset = xdr->buf->len;
2676 p = xdr_reserve_space(xdr, 3*4 + namlen);
2677 if (!p)
2678 goto fail;
2627 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ 2679 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
2628 p = xdr_encode_array(p, name, namlen); /* name length & name */ 2680 p = xdr_encode_array(p, name, namlen); /* name length & name */
2629 2681
2630 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, &p, buflen); 2682 nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
2631 switch (nfserr) { 2683 switch (nfserr) {
2632 case nfs_ok: 2684 case nfs_ok:
2633 break; 2685 break;
@@ -2646,59 +2698,74 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2646 */ 2698 */
2647 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)) 2699 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2648 goto fail; 2700 goto fail;
2649 p = nfsd4_encode_rdattr_error(p, buflen, nfserr); 2701 p = nfsd4_encode_rdattr_error(xdr, nfserr);
2650 if (p == NULL) { 2702 if (p == NULL) {
2651 nfserr = nfserr_toosmall; 2703 nfserr = nfserr_toosmall;
2652 goto fail; 2704 goto fail;
2653 } 2705 }
2654 } 2706 }
2655 cd->buflen -= (p - cd->buffer); 2707 nfserr = nfserr_toosmall;
2656 cd->buffer = p; 2708 entry_bytes = xdr->buf->len - start_offset;
2657 cd->offset = cookiep; 2709 if (entry_bytes > cd->rd_maxcount)
2710 goto fail;
2711 cd->rd_maxcount -= entry_bytes;
2712 if (!cd->rd_dircount)
2713 goto fail;
2714 cd->rd_dircount--;
2715 cd->cookie_offset = cookie_offset;
2658skip_entry: 2716skip_entry:
2659 cd->common.err = nfs_ok; 2717 cd->common.err = nfs_ok;
2660 return 0; 2718 return 0;
2661fail: 2719fail:
2720 xdr_truncate_encode(xdr, start_offset);
2662 cd->common.err = nfserr; 2721 cd->common.err = nfserr;
2663 return -EINVAL; 2722 return -EINVAL;
2664} 2723}
2665 2724
2666static void 2725static __be32
2667nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid) 2726nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
2668{ 2727{
2669 __be32 *p; 2728 __be32 *p;
2670 2729
2671 RESERVE_SPACE(sizeof(stateid_t)); 2730 p = xdr_reserve_space(xdr, sizeof(stateid_t));
2672 WRITE32(sid->si_generation); 2731 if (!p)
2673 WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 2732 return nfserr_resource;
2674 ADJUST_ARGS(); 2733 *p++ = cpu_to_be32(sid->si_generation);
2734 p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
2735 sizeof(stateid_opaque_t));
2736 return 0;
2675} 2737}
2676 2738
2677static __be32 2739static __be32
2678nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) 2740nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2679{ 2741{
2742 struct xdr_stream *xdr = &resp->xdr;
2680 __be32 *p; 2743 __be32 *p;
2681 2744
2682 if (!nfserr) { 2745 if (!nfserr) {
2683 RESERVE_SPACE(8); 2746 p = xdr_reserve_space(xdr, 8);
2684 WRITE32(access->ac_supported); 2747 if (!p)
2685 WRITE32(access->ac_resp_access); 2748 return nfserr_resource;
2686 ADJUST_ARGS(); 2749 *p++ = cpu_to_be32(access->ac_supported);
2750 *p++ = cpu_to_be32(access->ac_resp_access);
2687 } 2751 }
2688 return nfserr; 2752 return nfserr;
2689} 2753}
2690 2754
2691static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts) 2755static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2692{ 2756{
2757 struct xdr_stream *xdr = &resp->xdr;
2693 __be32 *p; 2758 __be32 *p;
2694 2759
2695 if (!nfserr) { 2760 if (!nfserr) {
2696 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8); 2761 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
2697 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); 2762 if (!p)
2698 WRITE32(bcts->dir); 2763 return nfserr_resource;
2764 p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
2765 NFS4_MAX_SESSIONID_LEN);
2766 *p++ = cpu_to_be32(bcts->dir);
2699 /* Sorry, we do not yet support RDMA over 4.1: */ 2767 /* Sorry, we do not yet support RDMA over 4.1: */
2700 WRITE32(0); 2768 *p++ = cpu_to_be32(0);
2701 ADJUST_ARGS();
2702 } 2769 }
2703 return nfserr; 2770 return nfserr;
2704} 2771}
@@ -2706,8 +2773,10 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
2706static __be32 2773static __be32
2707nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 2774nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2708{ 2775{
2776 struct xdr_stream *xdr = &resp->xdr;
2777
2709 if (!nfserr) 2778 if (!nfserr)
2710 nfsd4_encode_stateid(resp, &close->cl_stateid); 2779 nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid);
2711 2780
2712 return nfserr; 2781 return nfserr;
2713} 2782}
@@ -2716,12 +2785,15 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
2716static __be32 2785static __be32
2717nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) 2786nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2718{ 2787{
2788 struct xdr_stream *xdr = &resp->xdr;
2719 __be32 *p; 2789 __be32 *p;
2720 2790
2721 if (!nfserr) { 2791 if (!nfserr) {
2722 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 2792 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
2723 WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE); 2793 if (!p)
2724 ADJUST_ARGS(); 2794 return nfserr_resource;
2795 p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
2796 NFS4_VERIFIER_SIZE);
2725 } 2797 }
2726 return nfserr; 2798 return nfserr;
2727} 2799}
@@ -2729,15 +2801,17 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2729static __be32 2801static __be32
2730nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) 2802nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2731{ 2803{
2804 struct xdr_stream *xdr = &resp->xdr;
2732 __be32 *p; 2805 __be32 *p;
2733 2806
2734 if (!nfserr) { 2807 if (!nfserr) {
2735 RESERVE_SPACE(32); 2808 p = xdr_reserve_space(xdr, 32);
2736 write_cinfo(&p, &create->cr_cinfo); 2809 if (!p)
2737 WRITE32(2); 2810 return nfserr_resource;
2738 WRITE32(create->cr_bmval[0]); 2811 p = encode_cinfo(p, &create->cr_cinfo);
2739 WRITE32(create->cr_bmval[1]); 2812 *p++ = cpu_to_be32(2);
2740 ADJUST_ARGS(); 2813 *p++ = cpu_to_be32(create->cr_bmval[0]);
2814 *p++ = cpu_to_be32(create->cr_bmval[1]);
2741 } 2815 }
2742 return nfserr; 2816 return nfserr;
2743} 2817}
@@ -2746,14 +2820,13 @@ static __be32
2746nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) 2820nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2747{ 2821{
2748 struct svc_fh *fhp = getattr->ga_fhp; 2822 struct svc_fh *fhp = getattr->ga_fhp;
2749 int buflen; 2823 struct xdr_stream *xdr = &resp->xdr;
2750 2824
2751 if (nfserr) 2825 if (nfserr)
2752 return nfserr; 2826 return nfserr;
2753 2827
2754 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); 2828 nfserr = nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
2755 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, 2829 getattr->ga_bmval,
2756 &resp->p, buflen, getattr->ga_bmval,
2757 resp->rqstp, 0); 2830 resp->rqstp, 0);
2758 return nfserr; 2831 return nfserr;
2759} 2832}
@@ -2761,16 +2834,17 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
2761static __be32 2834static __be32
2762nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp) 2835nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2763{ 2836{
2837 struct xdr_stream *xdr = &resp->xdr;
2764 struct svc_fh *fhp = *fhpp; 2838 struct svc_fh *fhp = *fhpp;
2765 unsigned int len; 2839 unsigned int len;
2766 __be32 *p; 2840 __be32 *p;
2767 2841
2768 if (!nfserr) { 2842 if (!nfserr) {
2769 len = fhp->fh_handle.fh_size; 2843 len = fhp->fh_handle.fh_size;
2770 RESERVE_SPACE(len + 4); 2844 p = xdr_reserve_space(xdr, len + 4);
2771 WRITE32(len); 2845 if (!p)
2772 WRITEMEM(&fhp->fh_handle.fh_base, len); 2846 return nfserr_resource;
2773 ADJUST_ARGS(); 2847 p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
2774 } 2848 }
2775 return nfserr; 2849 return nfserr;
2776} 2850}
@@ -2779,52 +2853,69 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
2779* Including all fields other than the name, a LOCK4denied structure requires 2853* Including all fields other than the name, a LOCK4denied structure requires
2780* 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes. 2854* 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2781*/ 2855*/
2782static void 2856static __be32
2783nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld) 2857nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
2784{ 2858{
2785 struct xdr_netobj *conf = &ld->ld_owner; 2859 struct xdr_netobj *conf = &ld->ld_owner;
2786 __be32 *p; 2860 __be32 *p;
2787 2861
2788 RESERVE_SPACE(32 + XDR_LEN(conf->len)); 2862again:
2789 WRITE64(ld->ld_start); 2863 p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
2790 WRITE64(ld->ld_length); 2864 if (!p) {
2791 WRITE32(ld->ld_type); 2865 /*
2866 * Don't fail to return the result just because we can't
2867 * return the conflicting open:
2868 */
2869 if (conf->len) {
2870 conf->len = 0;
2871 conf->data = NULL;
2872 goto again;
2873 }
2874 return nfserr_resource;
2875 }
2876 p = xdr_encode_hyper(p, ld->ld_start);
2877 p = xdr_encode_hyper(p, ld->ld_length);
2878 *p++ = cpu_to_be32(ld->ld_type);
2792 if (conf->len) { 2879 if (conf->len) {
2793 WRITEMEM(&ld->ld_clientid, 8); 2880 p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
2794 WRITE32(conf->len); 2881 p = xdr_encode_opaque(p, conf->data, conf->len);
2795 WRITEMEM(conf->data, conf->len);
2796 kfree(conf->data);
2797 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */ 2882 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
2798 WRITE64((u64)0); /* clientid */ 2883 p = xdr_encode_hyper(p, (u64)0); /* clientid */
2799 WRITE32(0); /* length of owner name */ 2884 *p++ = cpu_to_be32(0); /* length of owner name */
2800 } 2885 }
2801 ADJUST_ARGS(); 2886 return nfserr_denied;
2802} 2887}
2803 2888
2804static __be32 2889static __be32
2805nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) 2890nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2806{ 2891{
2892 struct xdr_stream *xdr = &resp->xdr;
2893
2807 if (!nfserr) 2894 if (!nfserr)
2808 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid); 2895 nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
2809 else if (nfserr == nfserr_denied) 2896 else if (nfserr == nfserr_denied)
2810 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2897 nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
2811 2898 kfree(lock->lk_denied.ld_owner.data);
2812 return nfserr; 2899 return nfserr;
2813} 2900}
2814 2901
2815static __be32 2902static __be32
2816nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) 2903nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2817{ 2904{
2905 struct xdr_stream *xdr = &resp->xdr;
2906
2818 if (nfserr == nfserr_denied) 2907 if (nfserr == nfserr_denied)
2819 nfsd4_encode_lock_denied(resp, &lockt->lt_denied); 2908 nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
2820 return nfserr; 2909 return nfserr;
2821} 2910}
2822 2911
2823static __be32 2912static __be32
2824nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) 2913nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2825{ 2914{
2915 struct xdr_stream *xdr = &resp->xdr;
2916
2826 if (!nfserr) 2917 if (!nfserr)
2827 nfsd4_encode_stateid(resp, &locku->lu_stateid); 2918 nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid);
2828 2919
2829 return nfserr; 2920 return nfserr;
2830} 2921}
@@ -2833,12 +2924,14 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
2833static __be32 2924static __be32
2834nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) 2925nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2835{ 2926{
2927 struct xdr_stream *xdr = &resp->xdr;
2836 __be32 *p; 2928 __be32 *p;
2837 2929
2838 if (!nfserr) { 2930 if (!nfserr) {
2839 RESERVE_SPACE(20); 2931 p = xdr_reserve_space(xdr, 20);
2840 write_cinfo(&p, &link->li_cinfo); 2932 if (!p)
2841 ADJUST_ARGS(); 2933 return nfserr_resource;
2934 p = encode_cinfo(p, &link->li_cinfo);
2842 } 2935 }
2843 return nfserr; 2936 return nfserr;
2844} 2937}
@@ -2847,72 +2940,86 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
2847static __be32 2940static __be32
2848nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) 2941nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2849{ 2942{
2943 struct xdr_stream *xdr = &resp->xdr;
2850 __be32 *p; 2944 __be32 *p;
2851 2945
2852 if (nfserr) 2946 if (nfserr)
2853 goto out; 2947 goto out;
2854 2948
2855 nfsd4_encode_stateid(resp, &open->op_stateid); 2949 nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
2856 RESERVE_SPACE(40); 2950 if (nfserr)
2857 write_cinfo(&p, &open->op_cinfo); 2951 goto out;
2858 WRITE32(open->op_rflags); 2952 p = xdr_reserve_space(xdr, 40);
2859 WRITE32(2); 2953 if (!p)
2860 WRITE32(open->op_bmval[0]); 2954 return nfserr_resource;
2861 WRITE32(open->op_bmval[1]); 2955 p = encode_cinfo(p, &open->op_cinfo);
2862 WRITE32(open->op_delegate_type); 2956 *p++ = cpu_to_be32(open->op_rflags);
2863 ADJUST_ARGS(); 2957 *p++ = cpu_to_be32(2);
2958 *p++ = cpu_to_be32(open->op_bmval[0]);
2959 *p++ = cpu_to_be32(open->op_bmval[1]);
2960 *p++ = cpu_to_be32(open->op_delegate_type);
2864 2961
2865 switch (open->op_delegate_type) { 2962 switch (open->op_delegate_type) {
2866 case NFS4_OPEN_DELEGATE_NONE: 2963 case NFS4_OPEN_DELEGATE_NONE:
2867 break; 2964 break;
2868 case NFS4_OPEN_DELEGATE_READ: 2965 case NFS4_OPEN_DELEGATE_READ:
2869 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2966 nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
2870 RESERVE_SPACE(20); 2967 if (nfserr)
2871 WRITE32(open->op_recall); 2968 return nfserr;
2969 p = xdr_reserve_space(xdr, 20);
2970 if (!p)
2971 return nfserr_resource;
2972 *p++ = cpu_to_be32(open->op_recall);
2872 2973
2873 /* 2974 /*
2874 * TODO: ACE's in delegations 2975 * TODO: ACE's in delegations
2875 */ 2976 */
2876 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 2977 *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2877 WRITE32(0); 2978 *p++ = cpu_to_be32(0);
2878 WRITE32(0); 2979 *p++ = cpu_to_be32(0);
2879 WRITE32(0); /* XXX: is NULL principal ok? */ 2980 *p++ = cpu_to_be32(0); /* XXX: is NULL principal ok? */
2880 ADJUST_ARGS();
2881 break; 2981 break;
2882 case NFS4_OPEN_DELEGATE_WRITE: 2982 case NFS4_OPEN_DELEGATE_WRITE:
2883 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2983 nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
2884 RESERVE_SPACE(32); 2984 if (nfserr)
2885 WRITE32(0); 2985 return nfserr;
2986 p = xdr_reserve_space(xdr, 32);
2987 if (!p)
2988 return nfserr_resource;
2989 *p++ = cpu_to_be32(0);
2886 2990
2887 /* 2991 /*
2888 * TODO: space_limit's in delegations 2992 * TODO: space_limit's in delegations
2889 */ 2993 */
2890 WRITE32(NFS4_LIMIT_SIZE); 2994 *p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
2891 WRITE32(~(u32)0); 2995 *p++ = cpu_to_be32(~(u32)0);
2892 WRITE32(~(u32)0); 2996 *p++ = cpu_to_be32(~(u32)0);
2893 2997
2894 /* 2998 /*
2895 * TODO: ACE's in delegations 2999 * TODO: ACE's in delegations
2896 */ 3000 */
2897 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 3001 *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2898 WRITE32(0); 3002 *p++ = cpu_to_be32(0);
2899 WRITE32(0); 3003 *p++ = cpu_to_be32(0);
2900 WRITE32(0); /* XXX: is NULL principal ok? */ 3004 *p++ = cpu_to_be32(0); /* XXX: is NULL principal ok? */
2901 ADJUST_ARGS();
2902 break; 3005 break;
2903 case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */ 3006 case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
2904 switch (open->op_why_no_deleg) { 3007 switch (open->op_why_no_deleg) {
2905 case WND4_CONTENTION: 3008 case WND4_CONTENTION:
2906 case WND4_RESOURCE: 3009 case WND4_RESOURCE:
2907 RESERVE_SPACE(8); 3010 p = xdr_reserve_space(xdr, 8);
2908 WRITE32(open->op_why_no_deleg); 3011 if (!p)
2909 WRITE32(0); /* deleg signaling not supported yet */ 3012 return nfserr_resource;
3013 *p++ = cpu_to_be32(open->op_why_no_deleg);
3014 /* deleg signaling not supported yet: */
3015 *p++ = cpu_to_be32(0);
2910 break; 3016 break;
2911 default: 3017 default:
2912 RESERVE_SPACE(4); 3018 p = xdr_reserve_space(xdr, 4);
2913 WRITE32(open->op_why_no_deleg); 3019 if (!p)
3020 return nfserr_resource;
3021 *p++ = cpu_to_be32(open->op_why_no_deleg);
2914 } 3022 }
2915 ADJUST_ARGS();
2916 break; 3023 break;
2917 default: 3024 default:
2918 BUG(); 3025 BUG();
@@ -2925,8 +3032,10 @@ out:
2925static __be32 3032static __be32
2926nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) 3033nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2927{ 3034{
3035 struct xdr_stream *xdr = &resp->xdr;
3036
2928 if (!nfserr) 3037 if (!nfserr)
2929 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid); 3038 nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
2930 3039
2931 return nfserr; 3040 return nfserr;
2932} 3041}
@@ -2934,127 +3043,233 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
2934static __be32 3043static __be32
2935nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) 3044nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2936{ 3045{
3046 struct xdr_stream *xdr = &resp->xdr;
3047
2937 if (!nfserr) 3048 if (!nfserr)
2938 nfsd4_encode_stateid(resp, &od->od_stateid); 3049 nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid);
2939 3050
2940 return nfserr; 3051 return nfserr;
2941} 3052}
2942 3053
2943static __be32 3054static __be32 nfsd4_encode_splice_read(
2944nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, 3055 struct nfsd4_compoundres *resp,
2945 struct nfsd4_read *read) 3056 struct nfsd4_read *read,
3057 struct file *file, unsigned long maxcount)
2946{ 3058{
3059 struct xdr_stream *xdr = &resp->xdr;
3060 struct xdr_buf *buf = xdr->buf;
2947 u32 eof; 3061 u32 eof;
2948 int v; 3062 int space_left;
2949 struct page *page; 3063 __be32 nfserr;
2950 unsigned long maxcount; 3064 __be32 *p = xdr->p - 2;
2951 long len;
2952 __be32 *p;
2953 3065
2954 if (nfserr) 3066 /*
2955 return nfserr; 3067 * Don't inline pages unless we know there's room for eof,
2956 if (resp->xbuf->page_len) 3068 * count, and possible padding:
3069 */
3070 if (xdr->end - xdr->p < 3)
2957 return nfserr_resource; 3071 return nfserr_resource;
2958 3072
2959 RESERVE_SPACE(8); /* eof flag and byte count */ 3073 nfserr = nfsd_splice_read(read->rd_rqstp, file,
3074 read->rd_offset, &maxcount);
3075 if (nfserr) {
3076 /*
3077 * nfsd_splice_actor may have already messed with the
3078 * page length; reset it so as not to confuse
3079 * xdr_truncate_encode:
3080 */
3081 buf->page_len = 0;
3082 return nfserr;
3083 }
2960 3084
2961 maxcount = svc_max_payload(resp->rqstp); 3085 eof = (read->rd_offset + maxcount >=
2962 if (maxcount > read->rd_length) 3086 read->rd_fhp->fh_dentry->d_inode->i_size);
2963 maxcount = read->rd_length; 3087
3088 *(p++) = htonl(eof);
3089 *(p++) = htonl(maxcount);
3090
3091 buf->page_len = maxcount;
3092 buf->len += maxcount;
3093 xdr->page_ptr += (maxcount + PAGE_SIZE - 1) / PAGE_SIZE;
3094
3095 /* Use rest of head for padding and remaining ops: */
3096 buf->tail[0].iov_base = xdr->p;
3097 buf->tail[0].iov_len = 0;
3098 xdr->iov = buf->tail;
3099 if (maxcount&3) {
3100 int pad = 4 - (maxcount&3);
3101
3102 *(xdr->p++) = 0;
3103
3104 buf->tail[0].iov_base += maxcount&3;
3105 buf->tail[0].iov_len = pad;
3106 buf->len += pad;
3107 }
3108
3109 space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
3110 buf->buflen - buf->len);
3111 buf->buflen = buf->len + space_left;
3112 xdr->end = (__be32 *)((void *)xdr->end + space_left);
3113
3114 return 0;
3115}
3116
3117static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3118 struct nfsd4_read *read,
3119 struct file *file, unsigned long maxcount)
3120{
3121 struct xdr_stream *xdr = &resp->xdr;
3122 u32 eof;
3123 int v;
3124 int starting_len = xdr->buf->len - 8;
3125 long len;
3126 int thislen;
3127 __be32 nfserr;
3128 __be32 tmp;
3129 __be32 *p;
3130 u32 zzz = 0;
3131 int pad;
2964 3132
2965 len = maxcount; 3133 len = maxcount;
2966 v = 0; 3134 v = 0;
2967 while (len > 0) { 3135
2968 page = *(resp->rqstp->rq_next_page); 3136 thislen = (void *)xdr->end - (void *)xdr->p;
2969 if (!page) { /* ran out of pages */ 3137 if (len < thislen)
2970 maxcount -= len; 3138 thislen = len;
2971 break; 3139 p = xdr_reserve_space(xdr, (thislen+3)&~3);
2972 } 3140 WARN_ON_ONCE(!p);
2973 resp->rqstp->rq_vec[v].iov_base = page_address(page); 3141 resp->rqstp->rq_vec[v].iov_base = p;
2974 resp->rqstp->rq_vec[v].iov_len = 3142 resp->rqstp->rq_vec[v].iov_len = thislen;
2975 len < PAGE_SIZE ? len : PAGE_SIZE; 3143 v++;
2976 resp->rqstp->rq_next_page++; 3144 len -= thislen;
3145
3146 while (len) {
3147 thislen = min_t(long, len, PAGE_SIZE);
3148 p = xdr_reserve_space(xdr, (thislen+3)&~3);
3149 WARN_ON_ONCE(!p);
3150 resp->rqstp->rq_vec[v].iov_base = p;
3151 resp->rqstp->rq_vec[v].iov_len = thislen;
2977 v++; 3152 v++;
2978 len -= PAGE_SIZE; 3153 len -= thislen;
2979 } 3154 }
2980 read->rd_vlen = v; 3155 read->rd_vlen = v;
2981 3156
2982 nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp, 3157 nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec,
2983 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, 3158 read->rd_vlen, &maxcount);
2984 &maxcount);
2985
2986 if (nfserr) 3159 if (nfserr)
2987 return nfserr; 3160 return nfserr;
3161 xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
3162
2988 eof = (read->rd_offset + maxcount >= 3163 eof = (read->rd_offset + maxcount >=
2989 read->rd_fhp->fh_dentry->d_inode->i_size); 3164 read->rd_fhp->fh_dentry->d_inode->i_size);
2990 3165
2991 WRITE32(eof); 3166 tmp = htonl(eof);
2992 WRITE32(maxcount); 3167 write_bytes_to_xdr_buf(xdr->buf, starting_len , &tmp, 4);
2993 ADJUST_ARGS(); 3168 tmp = htonl(maxcount);
2994 resp->xbuf->head[0].iov_len = (char*)p 3169 write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
2995 - (char*)resp->xbuf->head[0].iov_base;
2996 resp->xbuf->page_len = maxcount;
2997 3170
2998 /* Use rest of head for padding and remaining ops: */ 3171 pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
2999 resp->xbuf->tail[0].iov_base = p; 3172 write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
3000 resp->xbuf->tail[0].iov_len = 0; 3173 &zzz, pad);
3001 if (maxcount&3) {
3002 RESERVE_SPACE(4);
3003 WRITE32(0);
3004 resp->xbuf->tail[0].iov_base += maxcount&3;
3005 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
3006 ADJUST_ARGS();
3007 }
3008 return 0; 3174 return 0;
3175
3009} 3176}
3010 3177
3011static __be32 3178static __be32
3012nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) 3179nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3180 struct nfsd4_read *read)
3013{ 3181{
3014 int maxcount; 3182 unsigned long maxcount;
3015 char *page; 3183 struct xdr_stream *xdr = &resp->xdr;
3184 struct file *file = read->rd_filp;
3185 int starting_len = xdr->buf->len;
3186 struct raparms *ra;
3016 __be32 *p; 3187 __be32 *p;
3188 __be32 err;
3017 3189
3018 if (nfserr) 3190 if (nfserr)
3019 return nfserr; 3191 return nfserr;
3020 if (resp->xbuf->page_len) 3192
3193 p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
3194 if (!p) {
3195 WARN_ON_ONCE(resp->rqstp->rq_splice_ok);
3021 return nfserr_resource; 3196 return nfserr_resource;
3022 if (!*resp->rqstp->rq_next_page) 3197 }
3198 if (resp->xdr.buf->page_len && resp->rqstp->rq_splice_ok) {
3199 WARN_ON_ONCE(1);
3023 return nfserr_resource; 3200 return nfserr_resource;
3201 }
3202 xdr_commit_encode(xdr);
3203
3204 maxcount = svc_max_payload(resp->rqstp);
3205 if (maxcount > xdr->buf->buflen - xdr->buf->len)
3206 maxcount = xdr->buf->buflen - xdr->buf->len;
3207 if (maxcount > read->rd_length)
3208 maxcount = read->rd_length;
3209
3210 if (!read->rd_filp) {
3211 err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
3212 &file, &ra);
3213 if (err)
3214 goto err_truncate;
3215 }
3216
3217 if (file->f_op->splice_read && resp->rqstp->rq_splice_ok)
3218 err = nfsd4_encode_splice_read(resp, read, file, maxcount);
3219 else
3220 err = nfsd4_encode_readv(resp, read, file, maxcount);
3221
3222 if (!read->rd_filp)
3223 nfsd_put_tmp_read_open(file, ra);
3224
3225err_truncate:
3226 if (err)
3227 xdr_truncate_encode(xdr, starting_len);
3228 return err;
3229}
3230
3231static __be32
3232nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
3233{
3234 int maxcount;
3235 __be32 wire_count;
3236 int zero = 0;
3237 struct xdr_stream *xdr = &resp->xdr;
3238 int length_offset = xdr->buf->len;
3239 __be32 *p;
3024 3240
3025 page = page_address(*(resp->rqstp->rq_next_page++)); 3241 if (nfserr)
3242 return nfserr;
3026 3243
3244 p = xdr_reserve_space(xdr, 4);
3245 if (!p)
3246 return nfserr_resource;
3027 maxcount = PAGE_SIZE; 3247 maxcount = PAGE_SIZE;
3028 RESERVE_SPACE(4);
3029 3248
3249 p = xdr_reserve_space(xdr, maxcount);
3250 if (!p)
3251 return nfserr_resource;
3030 /* 3252 /*
3031 * XXX: By default, the ->readlink() VFS op will truncate symlinks 3253 * XXX: By default, the ->readlink() VFS op will truncate symlinks
3032 * if they would overflow the buffer. Is this kosher in NFSv4? If 3254 * if they would overflow the buffer. Is this kosher in NFSv4? If
3033 * not, one easy fix is: if ->readlink() precisely fills the buffer, 3255 * not, one easy fix is: if ->readlink() precisely fills the buffer,
3034 * assume that truncation occurred, and return NFS4ERR_RESOURCE. 3256 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
3035 */ 3257 */
3036 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount); 3258 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
3259 (char *)p, &maxcount);
3037 if (nfserr == nfserr_isdir) 3260 if (nfserr == nfserr_isdir)
3038 return nfserr_inval; 3261 nfserr = nfserr_inval;
3039 if (nfserr) 3262 if (nfserr) {
3263 xdr_truncate_encode(xdr, length_offset);
3040 return nfserr; 3264 return nfserr;
3041
3042 WRITE32(maxcount);
3043 ADJUST_ARGS();
3044 resp->xbuf->head[0].iov_len = (char*)p
3045 - (char*)resp->xbuf->head[0].iov_base;
3046 resp->xbuf->page_len = maxcount;
3047
3048 /* Use rest of head for padding and remaining ops: */
3049 resp->xbuf->tail[0].iov_base = p;
3050 resp->xbuf->tail[0].iov_len = 0;
3051 if (maxcount&3) {
3052 RESERVE_SPACE(4);
3053 WRITE32(0);
3054 resp->xbuf->tail[0].iov_base += maxcount&3;
3055 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
3056 ADJUST_ARGS();
3057 } 3265 }
3266
3267 wire_count = htonl(maxcount);
3268 write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
3269 xdr_truncate_encode(xdr, length_offset + 4 + maxcount);
3270 if (maxcount & 3)
3271 write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
3272 &zero, 4 - (maxcount&3));
3058 return 0; 3273 return 0;
3059} 3274}
3060 3275
@@ -3062,47 +3277,52 @@ static __be32
3062nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) 3277nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
3063{ 3278{
3064 int maxcount; 3279 int maxcount;
3280 int bytes_left;
3065 loff_t offset; 3281 loff_t offset;
3066 __be32 *page, *savep, *tailbase; 3282 __be64 wire_offset;
3283 struct xdr_stream *xdr = &resp->xdr;
3284 int starting_len = xdr->buf->len;
3067 __be32 *p; 3285 __be32 *p;
3068 3286
3069 if (nfserr) 3287 if (nfserr)
3070 return nfserr; 3288 return nfserr;
3071 if (resp->xbuf->page_len)
3072 return nfserr_resource;
3073 if (!*resp->rqstp->rq_next_page)
3074 return nfserr_resource;
3075 3289
3076 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 3290 p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3077 savep = p; 3291 if (!p)
3292 return nfserr_resource;
3078 3293
3079 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */ 3294 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
3080 WRITE32(0); 3295 *p++ = cpu_to_be32(0);
3081 WRITE32(0); 3296 *p++ = cpu_to_be32(0);
3082 ADJUST_ARGS(); 3297 resp->xdr.buf->head[0].iov_len = ((char *)resp->xdr.p)
3083 resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; 3298 - (char *)resp->xdr.buf->head[0].iov_base;
3084 tailbase = p;
3085
3086 maxcount = PAGE_SIZE;
3087 if (maxcount > readdir->rd_maxcount)
3088 maxcount = readdir->rd_maxcount;
3089 3299
3090 /* 3300 /*
3091 * Convert from bytes to words, account for the two words already 3301 * Number of bytes left for directory entries allowing for the
3092 * written, make sure to leave two words at the end for the next 3302 * final 8 bytes of the readdir and a following failed op:
3093 * pointer and eof field. 3303 */
3304 bytes_left = xdr->buf->buflen - xdr->buf->len
3305 - COMPOUND_ERR_SLACK_SPACE - 8;
3306 if (bytes_left < 0) {
3307 nfserr = nfserr_resource;
3308 goto err_no_verf;
3309 }
3310 maxcount = min_t(u32, readdir->rd_maxcount, INT_MAX);
3311 /*
3312 * Note the rfc defines rd_maxcount as the size of the
3313 * READDIR4resok structure, which includes the verifier above
3314 * and the 8 bytes encoded at the end of this function:
3094 */ 3315 */
3095 maxcount = (maxcount >> 2) - 4; 3316 if (maxcount < 16) {
3096 if (maxcount < 0) { 3317 nfserr = nfserr_toosmall;
3097 nfserr = nfserr_toosmall;
3098 goto err_no_verf; 3318 goto err_no_verf;
3099 } 3319 }
3320 maxcount = min_t(int, maxcount-16, bytes_left);
3100 3321
3101 page = page_address(*(resp->rqstp->rq_next_page++)); 3322 readdir->xdr = xdr;
3323 readdir->rd_maxcount = maxcount;
3102 readdir->common.err = 0; 3324 readdir->common.err = 0;
3103 readdir->buflen = maxcount; 3325 readdir->cookie_offset = 0;
3104 readdir->buffer = page;
3105 readdir->offset = NULL;
3106 3326
3107 offset = readdir->rd_cookie; 3327 offset = readdir->rd_cookie;
3108 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp, 3328 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
@@ -3110,42 +3330,49 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3110 &readdir->common, nfsd4_encode_dirent); 3330 &readdir->common, nfsd4_encode_dirent);
3111 if (nfserr == nfs_ok && 3331 if (nfserr == nfs_ok &&
3112 readdir->common.err == nfserr_toosmall && 3332 readdir->common.err == nfserr_toosmall &&
3113 readdir->buffer == page) 3333 xdr->buf->len == starting_len + 8) {
3114 nfserr = nfserr_toosmall; 3334 /* nothing encoded; which limit did we hit?: */
3335 if (maxcount - 16 < bytes_left)
3336 /* It was the fault of rd_maxcount: */
3337 nfserr = nfserr_toosmall;
3338 else
3339 /* We ran out of buffer space: */
3340 nfserr = nfserr_resource;
3341 }
3115 if (nfserr) 3342 if (nfserr)
3116 goto err_no_verf; 3343 goto err_no_verf;
3117 3344
3118 if (readdir->offset) 3345 if (readdir->cookie_offset) {
3119 xdr_encode_hyper(readdir->offset, offset); 3346 wire_offset = cpu_to_be64(offset);
3347 write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
3348 &wire_offset, 8);
3349 }
3120 3350
3121 p = readdir->buffer; 3351 p = xdr_reserve_space(xdr, 8);
3352 if (!p) {
3353 WARN_ON_ONCE(1);
3354 goto err_no_verf;
3355 }
3122 *p++ = 0; /* no more entries */ 3356 *p++ = 0; /* no more entries */
3123 *p++ = htonl(readdir->common.err == nfserr_eof); 3357 *p++ = htonl(readdir->common.err == nfserr_eof);
3124 resp->xbuf->page_len = ((char*)p) -
3125 (char*)page_address(*(resp->rqstp->rq_next_page-1));
3126
3127 /* Use rest of head for padding and remaining ops: */
3128 resp->xbuf->tail[0].iov_base = tailbase;
3129 resp->xbuf->tail[0].iov_len = 0;
3130 resp->p = resp->xbuf->tail[0].iov_base;
3131 resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
3132 3358
3133 return 0; 3359 return 0;
3134err_no_verf: 3360err_no_verf:
3135 p = savep; 3361 xdr_truncate_encode(xdr, starting_len);
3136 ADJUST_ARGS();
3137 return nfserr; 3362 return nfserr;
3138} 3363}
3139 3364
3140static __be32 3365static __be32
3141nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) 3366nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
3142{ 3367{
3368 struct xdr_stream *xdr = &resp->xdr;
3143 __be32 *p; 3369 __be32 *p;
3144 3370
3145 if (!nfserr) { 3371 if (!nfserr) {
3146 RESERVE_SPACE(20); 3372 p = xdr_reserve_space(xdr, 20);
3147 write_cinfo(&p, &remove->rm_cinfo); 3373 if (!p)
3148 ADJUST_ARGS(); 3374 return nfserr_resource;
3375 p = encode_cinfo(p, &remove->rm_cinfo);
3149 } 3376 }
3150 return nfserr; 3377 return nfserr;
3151} 3378}
@@ -3153,19 +3380,21 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
3153static __be32 3380static __be32
3154nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) 3381nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
3155{ 3382{
3383 struct xdr_stream *xdr = &resp->xdr;
3156 __be32 *p; 3384 __be32 *p;
3157 3385
3158 if (!nfserr) { 3386 if (!nfserr) {
3159 RESERVE_SPACE(40); 3387 p = xdr_reserve_space(xdr, 40);
3160 write_cinfo(&p, &rename->rn_sinfo); 3388 if (!p)
3161 write_cinfo(&p, &rename->rn_tinfo); 3389 return nfserr_resource;
3162 ADJUST_ARGS(); 3390 p = encode_cinfo(p, &rename->rn_sinfo);
3391 p = encode_cinfo(p, &rename->rn_tinfo);
3163 } 3392 }
3164 return nfserr; 3393 return nfserr;
3165} 3394}
3166 3395
3167static __be32 3396static __be32
3168nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, 3397nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
3169 __be32 nfserr, struct svc_export *exp) 3398 __be32 nfserr, struct svc_export *exp)
3170{ 3399{
3171 u32 i, nflavs, supported; 3400 u32 i, nflavs, supported;
@@ -3176,6 +3405,7 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3176 3405
3177 if (nfserr) 3406 if (nfserr)
3178 goto out; 3407 goto out;
3408 nfserr = nfserr_resource;
3179 if (exp->ex_nflavors) { 3409 if (exp->ex_nflavors) {
3180 flavs = exp->ex_flavors; 3410 flavs = exp->ex_flavors;
3181 nflavs = exp->ex_nflavors; 3411 nflavs = exp->ex_nflavors;
@@ -3197,9 +3427,10 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3197 } 3427 }
3198 3428
3199 supported = 0; 3429 supported = 0;
3200 RESERVE_SPACE(4); 3430 p = xdr_reserve_space(xdr, 4);
3431 if (!p)
3432 goto out;
3201 flavorsp = p++; /* to be backfilled later */ 3433 flavorsp = p++; /* to be backfilled later */
3202 ADJUST_ARGS();
3203 3434
3204 for (i = 0; i < nflavs; i++) { 3435 for (i = 0; i < nflavs; i++) {
3205 rpc_authflavor_t pf = flavs[i].pseudoflavor; 3436 rpc_authflavor_t pf = flavs[i].pseudoflavor;
@@ -3207,18 +3438,20 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3207 3438
3208 if (rpcauth_get_gssinfo(pf, &info) == 0) { 3439 if (rpcauth_get_gssinfo(pf, &info) == 0) {
3209 supported++; 3440 supported++;
3210 RESERVE_SPACE(4 + 4 + XDR_LEN(info.oid.len) + 4 + 4); 3441 p = xdr_reserve_space(xdr, 4 + 4 +
3211 WRITE32(RPC_AUTH_GSS); 3442 XDR_LEN(info.oid.len) + 4 + 4);
3212 WRITE32(info.oid.len); 3443 if (!p)
3213 WRITEMEM(info.oid.data, info.oid.len); 3444 goto out;
3214 WRITE32(info.qop); 3445 *p++ = cpu_to_be32(RPC_AUTH_GSS);
3215 WRITE32(info.service); 3446 p = xdr_encode_opaque(p, info.oid.data, info.oid.len);
3216 ADJUST_ARGS(); 3447 *p++ = cpu_to_be32(info.qop);
3448 *p++ = cpu_to_be32(info.service);
3217 } else if (pf < RPC_AUTH_MAXFLAVOR) { 3449 } else if (pf < RPC_AUTH_MAXFLAVOR) {
3218 supported++; 3450 supported++;
3219 RESERVE_SPACE(4); 3451 p = xdr_reserve_space(xdr, 4);
3220 WRITE32(pf); 3452 if (!p)
3221 ADJUST_ARGS(); 3453 goto out;
3454 *p++ = cpu_to_be32(pf);
3222 } else { 3455 } else {
3223 if (report) 3456 if (report)
3224 pr_warn("NFS: SECINFO: security flavor %u " 3457 pr_warn("NFS: SECINFO: security flavor %u "
@@ -3229,7 +3462,7 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3229 if (nflavs != supported) 3462 if (nflavs != supported)
3230 report = false; 3463 report = false;
3231 *flavorsp = htonl(supported); 3464 *flavorsp = htonl(supported);
3232 3465 nfserr = 0;
3233out: 3466out:
3234 if (exp) 3467 if (exp)
3235 exp_put(exp); 3468 exp_put(exp);
@@ -3240,14 +3473,18 @@ static __be32
3240nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 3473nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3241 struct nfsd4_secinfo *secinfo) 3474 struct nfsd4_secinfo *secinfo)
3242{ 3475{
3243 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp); 3476 struct xdr_stream *xdr = &resp->xdr;
3477
3478 return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp);
3244} 3479}
3245 3480
3246static __be32 3481static __be32
3247nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, 3482nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3248 struct nfsd4_secinfo_no_name *secinfo) 3483 struct nfsd4_secinfo_no_name *secinfo)
3249{ 3484{
3250 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp); 3485 struct xdr_stream *xdr = &resp->xdr;
3486
3487 return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp);
3251} 3488}
3252 3489
3253/* 3490/*
@@ -3257,41 +3494,47 @@ nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3257static __be32 3494static __be32
3258nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) 3495nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3259{ 3496{
3497 struct xdr_stream *xdr = &resp->xdr;
3260 __be32 *p; 3498 __be32 *p;
3261 3499
3262 RESERVE_SPACE(16); 3500 p = xdr_reserve_space(xdr, 16);
3501 if (!p)
3502 return nfserr_resource;
3263 if (nfserr) { 3503 if (nfserr) {
3264 WRITE32(3); 3504 *p++ = cpu_to_be32(3);
3265 WRITE32(0); 3505 *p++ = cpu_to_be32(0);
3266 WRITE32(0); 3506 *p++ = cpu_to_be32(0);
3267 WRITE32(0); 3507 *p++ = cpu_to_be32(0);
3268 } 3508 }
3269 else { 3509 else {
3270 WRITE32(3); 3510 *p++ = cpu_to_be32(3);
3271 WRITE32(setattr->sa_bmval[0]); 3511 *p++ = cpu_to_be32(setattr->sa_bmval[0]);
3272 WRITE32(setattr->sa_bmval[1]); 3512 *p++ = cpu_to_be32(setattr->sa_bmval[1]);
3273 WRITE32(setattr->sa_bmval[2]); 3513 *p++ = cpu_to_be32(setattr->sa_bmval[2]);
3274 } 3514 }
3275 ADJUST_ARGS();
3276 return nfserr; 3515 return nfserr;
3277} 3516}
3278 3517
3279static __be32 3518static __be32
3280nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) 3519nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3281{ 3520{
3521 struct xdr_stream *xdr = &resp->xdr;
3282 __be32 *p; 3522 __be32 *p;
3283 3523
3284 if (!nfserr) { 3524 if (!nfserr) {
3285 RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE); 3525 p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
3286 WRITEMEM(&scd->se_clientid, 8); 3526 if (!p)
3287 WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE); 3527 return nfserr_resource;
3288 ADJUST_ARGS(); 3528 p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
3529 p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
3530 NFS4_VERIFIER_SIZE);
3289 } 3531 }
3290 else if (nfserr == nfserr_clid_inuse) { 3532 else if (nfserr == nfserr_clid_inuse) {
3291 RESERVE_SPACE(8); 3533 p = xdr_reserve_space(xdr, 8);
3292 WRITE32(0); 3534 if (!p)
3293 WRITE32(0); 3535 return nfserr_resource;
3294 ADJUST_ARGS(); 3536 *p++ = cpu_to_be32(0);
3537 *p++ = cpu_to_be32(0);
3295 } 3538 }
3296 return nfserr; 3539 return nfserr;
3297} 3540}
@@ -3299,14 +3542,17 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
3299static __be32 3542static __be32
3300nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) 3543nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3301{ 3544{
3545 struct xdr_stream *xdr = &resp->xdr;
3302 __be32 *p; 3546 __be32 *p;
3303 3547
3304 if (!nfserr) { 3548 if (!nfserr) {
3305 RESERVE_SPACE(16); 3549 p = xdr_reserve_space(xdr, 16);
3306 WRITE32(write->wr_bytes_written); 3550 if (!p)
3307 WRITE32(write->wr_how_written); 3551 return nfserr_resource;
3308 WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE); 3552 *p++ = cpu_to_be32(write->wr_bytes_written);
3309 ADJUST_ARGS(); 3553 *p++ = cpu_to_be32(write->wr_how_written);
3554 p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
3555 NFS4_VERIFIER_SIZE);
3310 } 3556 }
3311 return nfserr; 3557 return nfserr;
3312} 3558}
@@ -3323,6 +3569,7 @@ static __be32
3323nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, 3569nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3324 struct nfsd4_exchange_id *exid) 3570 struct nfsd4_exchange_id *exid)
3325{ 3571{
3572 struct xdr_stream *xdr = &resp->xdr;
3326 __be32 *p; 3573 __be32 *p;
3327 char *major_id; 3574 char *major_id;
3328 char *server_scope; 3575 char *server_scope;
@@ -3338,60 +3585,61 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3338 server_scope = utsname()->nodename; 3585 server_scope = utsname()->nodename;
3339 server_scope_sz = strlen(server_scope); 3586 server_scope_sz = strlen(server_scope);
3340 3587
3341 RESERVE_SPACE( 3588 p = xdr_reserve_space(xdr,
3342 8 /* eir_clientid */ + 3589 8 /* eir_clientid */ +
3343 4 /* eir_sequenceid */ + 3590 4 /* eir_sequenceid */ +
3344 4 /* eir_flags */ + 3591 4 /* eir_flags */ +
3345 4 /* spr_how */); 3592 4 /* spr_how */);
3593 if (!p)
3594 return nfserr_resource;
3346 3595
3347 WRITEMEM(&exid->clientid, 8); 3596 p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
3348 WRITE32(exid->seqid); 3597 *p++ = cpu_to_be32(exid->seqid);
3349 WRITE32(exid->flags); 3598 *p++ = cpu_to_be32(exid->flags);
3350 3599
3351 WRITE32(exid->spa_how); 3600 *p++ = cpu_to_be32(exid->spa_how);
3352 ADJUST_ARGS();
3353 3601
3354 switch (exid->spa_how) { 3602 switch (exid->spa_how) {
3355 case SP4_NONE: 3603 case SP4_NONE:
3356 break; 3604 break;
3357 case SP4_MACH_CRED: 3605 case SP4_MACH_CRED:
3358 /* spo_must_enforce, spo_must_allow */ 3606 /* spo_must_enforce, spo_must_allow */
3359 RESERVE_SPACE(16); 3607 p = xdr_reserve_space(xdr, 16);
3608 if (!p)
3609 return nfserr_resource;
3360 3610
3361 /* spo_must_enforce bitmap: */ 3611 /* spo_must_enforce bitmap: */
3362 WRITE32(2); 3612 *p++ = cpu_to_be32(2);
3363 WRITE32(nfs4_minimal_spo_must_enforce[0]); 3613 *p++ = cpu_to_be32(nfs4_minimal_spo_must_enforce[0]);
3364 WRITE32(nfs4_minimal_spo_must_enforce[1]); 3614 *p++ = cpu_to_be32(nfs4_minimal_spo_must_enforce[1]);
3365 /* empty spo_must_allow bitmap: */ 3615 /* empty spo_must_allow bitmap: */
3366 WRITE32(0); 3616 *p++ = cpu_to_be32(0);
3367 3617
3368 ADJUST_ARGS();
3369 break; 3618 break;
3370 default: 3619 default:
3371 WARN_ON_ONCE(1); 3620 WARN_ON_ONCE(1);
3372 } 3621 }
3373 3622
3374 RESERVE_SPACE( 3623 p = xdr_reserve_space(xdr,
3375 8 /* so_minor_id */ + 3624 8 /* so_minor_id */ +
3376 4 /* so_major_id.len */ + 3625 4 /* so_major_id.len */ +
3377 (XDR_QUADLEN(major_id_sz) * 4) + 3626 (XDR_QUADLEN(major_id_sz) * 4) +
3378 4 /* eir_server_scope.len */ + 3627 4 /* eir_server_scope.len */ +
3379 (XDR_QUADLEN(server_scope_sz) * 4) + 3628 (XDR_QUADLEN(server_scope_sz) * 4) +
3380 4 /* eir_server_impl_id.count (0) */); 3629 4 /* eir_server_impl_id.count (0) */);
3630 if (!p)
3631 return nfserr_resource;
3381 3632
3382 /* The server_owner struct */ 3633 /* The server_owner struct */
3383 WRITE64(minor_id); /* Minor id */ 3634 p = xdr_encode_hyper(p, minor_id); /* Minor id */
3384 /* major id */ 3635 /* major id */
3385 WRITE32(major_id_sz); 3636 p = xdr_encode_opaque(p, major_id, major_id_sz);
3386 WRITEMEM(major_id, major_id_sz);
3387 3637
3388 /* Server scope */ 3638 /* Server scope */
3389 WRITE32(server_scope_sz); 3639 p = xdr_encode_opaque(p, server_scope, server_scope_sz);
3390 WRITEMEM(server_scope, server_scope_sz);
3391 3640
3392 /* Implementation id */ 3641 /* Implementation id */
3393 WRITE32(0); /* zero length nfs_impl_id4 array */ 3642 *p++ = cpu_to_be32(0); /* zero length nfs_impl_id4 array */
3394 ADJUST_ARGS();
3395 return 0; 3643 return 0;
3396} 3644}
3397 3645
@@ -3399,47 +3647,54 @@ static __be32
3399nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr, 3647nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3400 struct nfsd4_create_session *sess) 3648 struct nfsd4_create_session *sess)
3401{ 3649{
3650 struct xdr_stream *xdr = &resp->xdr;
3402 __be32 *p; 3651 __be32 *p;
3403 3652
3404 if (nfserr) 3653 if (nfserr)
3405 return nfserr; 3654 return nfserr;
3406 3655
3407 RESERVE_SPACE(24); 3656 p = xdr_reserve_space(xdr, 24);
3408 WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3657 if (!p)
3409 WRITE32(sess->seqid); 3658 return nfserr_resource;
3410 WRITE32(sess->flags); 3659 p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
3411 ADJUST_ARGS(); 3660 NFS4_MAX_SESSIONID_LEN);
3412 3661 *p++ = cpu_to_be32(sess->seqid);
3413 RESERVE_SPACE(28); 3662 *p++ = cpu_to_be32(sess->flags);
3414 WRITE32(0); /* headerpadsz */ 3663
3415 WRITE32(sess->fore_channel.maxreq_sz); 3664 p = xdr_reserve_space(xdr, 28);
3416 WRITE32(sess->fore_channel.maxresp_sz); 3665 if (!p)
3417 WRITE32(sess->fore_channel.maxresp_cached); 3666 return nfserr_resource;
3418 WRITE32(sess->fore_channel.maxops); 3667 *p++ = cpu_to_be32(0); /* headerpadsz */
3419 WRITE32(sess->fore_channel.maxreqs); 3668 *p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
3420 WRITE32(sess->fore_channel.nr_rdma_attrs); 3669 *p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
3421 ADJUST_ARGS(); 3670 *p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
3671 *p++ = cpu_to_be32(sess->fore_channel.maxops);
3672 *p++ = cpu_to_be32(sess->fore_channel.maxreqs);
3673 *p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
3422 3674
3423 if (sess->fore_channel.nr_rdma_attrs) { 3675 if (sess->fore_channel.nr_rdma_attrs) {
3424 RESERVE_SPACE(4); 3676 p = xdr_reserve_space(xdr, 4);
3425 WRITE32(sess->fore_channel.rdma_attrs); 3677 if (!p)
3426 ADJUST_ARGS(); 3678 return nfserr_resource;
3679 *p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
3427 } 3680 }
3428 3681
3429 RESERVE_SPACE(28); 3682 p = xdr_reserve_space(xdr, 28);
3430 WRITE32(0); /* headerpadsz */ 3683 if (!p)
3431 WRITE32(sess->back_channel.maxreq_sz); 3684 return nfserr_resource;
3432 WRITE32(sess->back_channel.maxresp_sz); 3685 *p++ = cpu_to_be32(0); /* headerpadsz */
3433 WRITE32(sess->back_channel.maxresp_cached); 3686 *p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
3434 WRITE32(sess->back_channel.maxops); 3687 *p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
3435 WRITE32(sess->back_channel.maxreqs); 3688 *p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
3436 WRITE32(sess->back_channel.nr_rdma_attrs); 3689 *p++ = cpu_to_be32(sess->back_channel.maxops);
3437 ADJUST_ARGS(); 3690 *p++ = cpu_to_be32(sess->back_channel.maxreqs);
3691 *p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
3438 3692
3439 if (sess->back_channel.nr_rdma_attrs) { 3693 if (sess->back_channel.nr_rdma_attrs) {
3440 RESERVE_SPACE(4); 3694 p = xdr_reserve_space(xdr, 4);
3441 WRITE32(sess->back_channel.rdma_attrs); 3695 if (!p)
3442 ADJUST_ARGS(); 3696 return nfserr_resource;
3697 *p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
3443 } 3698 }
3444 return 0; 3699 return 0;
3445} 3700}
@@ -3448,22 +3703,25 @@ static __be32
3448nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, 3703nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3449 struct nfsd4_sequence *seq) 3704 struct nfsd4_sequence *seq)
3450{ 3705{
3706 struct xdr_stream *xdr = &resp->xdr;
3451 __be32 *p; 3707 __be32 *p;
3452 3708
3453 if (nfserr) 3709 if (nfserr)
3454 return nfserr; 3710 return nfserr;
3455 3711
3456 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20); 3712 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
3457 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3713 if (!p)
3458 WRITE32(seq->seqid); 3714 return nfserr_resource;
3459 WRITE32(seq->slotid); 3715 p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
3716 NFS4_MAX_SESSIONID_LEN);
3717 *p++ = cpu_to_be32(seq->seqid);
3718 *p++ = cpu_to_be32(seq->slotid);
3460 /* Note slotid's are numbered from zero: */ 3719 /* Note slotid's are numbered from zero: */
3461 WRITE32(seq->maxslots - 1); /* sr_highest_slotid */ 3720 *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
3462 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */ 3721 *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
3463 WRITE32(seq->status_flags); 3722 *p++ = cpu_to_be32(seq->status_flags);
3464 3723
3465 ADJUST_ARGS(); 3724 resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
3466 resp->cstate.datap = p; /* DRC cache data pointer */
3467 return 0; 3725 return 0;
3468} 3726}
3469 3727
@@ -3471,20 +3729,22 @@ static __be32
3471nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, 3729nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3472 struct nfsd4_test_stateid *test_stateid) 3730 struct nfsd4_test_stateid *test_stateid)
3473{ 3731{
3732 struct xdr_stream *xdr = &resp->xdr;
3474 struct nfsd4_test_stateid_id *stateid, *next; 3733 struct nfsd4_test_stateid_id *stateid, *next;
3475 __be32 *p; 3734 __be32 *p;
3476 3735
3477 if (nfserr) 3736 if (nfserr)
3478 return nfserr; 3737 return nfserr;
3479 3738
3480 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids)); 3739 p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
3740 if (!p)
3741 return nfserr_resource;
3481 *p++ = htonl(test_stateid->ts_num_ids); 3742 *p++ = htonl(test_stateid->ts_num_ids);
3482 3743
3483 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { 3744 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
3484 *p++ = stateid->ts_id_status; 3745 *p++ = stateid->ts_id_status;
3485 } 3746 }
3486 3747
3487 ADJUST_ARGS();
3488 return nfserr; 3748 return nfserr;
3489} 3749}
3490 3750
@@ -3563,81 +3823,99 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3563}; 3823};
3564 3824
3565/* 3825/*
3566 * Calculate the total amount of memory that the compound response has taken 3826 * Calculate whether we still have space to encode repsize bytes.
3567 * after encoding the current operation with pad. 3827 * There are two considerations:
3568 * 3828 * - For NFS versions >=4.1, the size of the reply must stay within
3569 * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop() 3829 * session limits
3570 * which was specified at nfsd4_operation, else pad is zero. 3830 * - For all NFS versions, we must stay within limited preallocated
3571 * 3831 * buffer space.
3572 * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached.
3573 * 3832 *
3574 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3833 * This is called before the operation is processed, so can only provide
3575 * will be at least a page and will therefore hold the xdr_buf head. 3834 * an upper estimate. For some nonidempotent operations (such as
3835 * getattr), it's not necessarily a problem if that estimate is wrong,
3836 * as we can fail it after processing without significant side effects.
3576 */ 3837 */
3577__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3838__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
3578{ 3839{
3579 struct xdr_buf *xb = &resp->rqstp->rq_res; 3840 struct xdr_buf *buf = &resp->rqstp->rq_res;
3580 struct nfsd4_session *session = NULL;
3581 struct nfsd4_slot *slot = resp->cstate.slot; 3841 struct nfsd4_slot *slot = resp->cstate.slot;
3582 u32 length, tlen = 0;
3583 3842
3843 if (buf->len + respsize <= buf->buflen)
3844 return nfs_ok;
3584 if (!nfsd4_has_session(&resp->cstate)) 3845 if (!nfsd4_has_session(&resp->cstate))
3585 return 0; 3846 return nfserr_resource;
3586 3847 if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
3587 session = resp->cstate.session; 3848 WARN_ON_ONCE(1);
3588
3589 if (xb->page_len == 0) {
3590 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3591 } else {
3592 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3593 tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3594
3595 length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3596 }
3597 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3598 length, xb->page_len, tlen, pad);
3599
3600 if (length > session->se_fchannel.maxresp_sz)
3601 return nfserr_rep_too_big;
3602
3603 if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
3604 length > session->se_fchannel.maxresp_cached)
3605 return nfserr_rep_too_big_to_cache; 3849 return nfserr_rep_too_big_to_cache;
3606 3850 }
3607 return 0; 3851 return nfserr_rep_too_big;
3608} 3852}
3609 3853
3610void 3854void
3611nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3855nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3612{ 3856{
3857 struct xdr_stream *xdr = &resp->xdr;
3613 struct nfs4_stateowner *so = resp->cstate.replay_owner; 3858 struct nfs4_stateowner *so = resp->cstate.replay_owner;
3614 __be32 *statp; 3859 struct svc_rqst *rqstp = resp->rqstp;
3860 int post_err_offset;
3861 nfsd4_enc encoder;
3615 __be32 *p; 3862 __be32 *p;
3616 3863
3617 RESERVE_SPACE(8); 3864 p = xdr_reserve_space(xdr, 8);
3618 WRITE32(op->opnum); 3865 if (!p) {
3619 statp = p++; /* to be backfilled at the end */ 3866 WARN_ON_ONCE(1);
3620 ADJUST_ARGS(); 3867 return;
3868 }
3869 *p++ = cpu_to_be32(op->opnum);
3870 post_err_offset = xdr->buf->len;
3621 3871
3622 if (op->opnum == OP_ILLEGAL) 3872 if (op->opnum == OP_ILLEGAL)
3623 goto status; 3873 goto status;
3624 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || 3874 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3625 !nfsd4_enc_ops[op->opnum]); 3875 !nfsd4_enc_ops[op->opnum]);
3626 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); 3876 encoder = nfsd4_enc_ops[op->opnum];
3877 op->status = encoder(resp, op->status, &op->u);
3878 xdr_commit_encode(xdr);
3879
3627 /* nfsd4_check_resp_size guarantees enough room for error status */ 3880 /* nfsd4_check_resp_size guarantees enough room for error status */
3628 if (!op->status) 3881 if (!op->status) {
3629 op->status = nfsd4_check_resp_size(resp, 0); 3882 int space_needed = 0;
3883 if (!nfsd4_last_compound_op(rqstp))
3884 space_needed = COMPOUND_ERR_SLACK_SPACE;
3885 op->status = nfsd4_check_resp_size(resp, space_needed);
3886 }
3887 if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
3888 struct nfsd4_slot *slot = resp->cstate.slot;
3889
3890 if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
3891 op->status = nfserr_rep_too_big_to_cache;
3892 else
3893 op->status = nfserr_rep_too_big;
3894 }
3895 if (op->status == nfserr_resource ||
3896 op->status == nfserr_rep_too_big ||
3897 op->status == nfserr_rep_too_big_to_cache) {
3898 /*
3899 * The operation may have already been encoded or
3900 * partially encoded. No op returns anything additional
3901 * in the case of one of these three errors, so we can
3902 * just truncate back to after the status. But it's a
3903 * bug if we had to do this on a non-idempotent op:
3904 */
3905 warn_on_nonidempotent_op(op);
3906 xdr_truncate_encode(xdr, post_err_offset);
3907 }
3630 if (so) { 3908 if (so) {
3909 int len = xdr->buf->len - post_err_offset;
3910
3631 so->so_replay.rp_status = op->status; 3911 so->so_replay.rp_status = op->status;
3632 so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1); 3912 so->so_replay.rp_buflen = len;
3633 memcpy(so->so_replay.rp_buf, statp+1, so->so_replay.rp_buflen); 3913 read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
3914 so->so_replay.rp_buf, len);
3634 } 3915 }
3635status: 3916status:
3636 /* 3917 /* Note that op->status is already in network byte order: */
3637 * Note: We write the status directly, instead of using WRITE32(), 3918 write_bytes_to_xdr_buf(xdr->buf, post_err_offset - 4, &op->status, 4);
3638 * since it is already in network byte order.
3639 */
3640 *statp = op->status;
3641} 3919}
3642 3920
3643/* 3921/*
@@ -3649,21 +3927,22 @@ status:
3649 * called with nfs4_lock_state() held 3927 * called with nfs4_lock_state() held
3650 */ 3928 */
3651void 3929void
3652nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3930nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
3653{ 3931{
3654 __be32 *p; 3932 __be32 *p;
3655 struct nfs4_replay *rp = op->replay; 3933 struct nfs4_replay *rp = op->replay;
3656 3934
3657 BUG_ON(!rp); 3935 BUG_ON(!rp);
3658 3936
3659 RESERVE_SPACE(8); 3937 p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
3660 WRITE32(op->opnum); 3938 if (!p) {
3939 WARN_ON_ONCE(1);
3940 return;
3941 }
3942 *p++ = cpu_to_be32(op->opnum);
3661 *p++ = rp->rp_status; /* already xdr'ed */ 3943 *p++ = rp->rp_status; /* already xdr'ed */
3662 ADJUST_ARGS();
3663 3944
3664 RESERVE_SPACE(rp->rp_buflen); 3945 p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
3665 WRITEMEM(rp->rp_buf, rp->rp_buflen);
3666 ADJUST_ARGS();
3667} 3946}
3668 3947
3669int 3948int
@@ -3720,19 +3999,19 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
3720 * All that remains is to write the tag and operation count... 3999 * All that remains is to write the tag and operation count...
3721 */ 4000 */
3722 struct nfsd4_compound_state *cs = &resp->cstate; 4001 struct nfsd4_compound_state *cs = &resp->cstate;
3723 struct kvec *iov; 4002 struct xdr_buf *buf = resp->xdr.buf;
4003
4004 WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
4005 buf->tail[0].iov_len);
4006
4007 rqstp->rq_next_page = resp->xdr.page_ptr + 1;
4008
3724 p = resp->tagp; 4009 p = resp->tagp;
3725 *p++ = htonl(resp->taglen); 4010 *p++ = htonl(resp->taglen);
3726 memcpy(p, resp->tag, resp->taglen); 4011 memcpy(p, resp->tag, resp->taglen);
3727 p += XDR_QUADLEN(resp->taglen); 4012 p += XDR_QUADLEN(resp->taglen);
3728 *p++ = htonl(resp->opcnt); 4013 *p++ = htonl(resp->opcnt);
3729 4014
3730 if (rqstp->rq_res.page_len)
3731 iov = &rqstp->rq_res.tail[0];
3732 else
3733 iov = &rqstp->rq_res.head[0];
3734 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3735 BUG_ON(iov->iov_len > PAGE_SIZE);
3736 if (nfsd4_has_session(cs)) { 4015 if (nfsd4_has_session(cs)) {
3737 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 4016 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3738 struct nfs4_client *clp = cs->session->se_client; 4017 struct nfs4_client *clp = cs->session->se_client;
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index f8f060ffbf4f..6040da8830ff 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -224,13 +224,6 @@ hash_refile(struct svc_cacherep *rp)
224 hlist_add_head(&rp->c_hash, cache_hash + hash_32(rp->c_xid, maskbits)); 224 hlist_add_head(&rp->c_hash, cache_hash + hash_32(rp->c_xid, maskbits));
225} 225}
226 226
227static inline bool
228nfsd_cache_entry_expired(struct svc_cacherep *rp)
229{
230 return rp->c_state != RC_INPROG &&
231 time_after(jiffies, rp->c_timestamp + RC_EXPIRE);
232}
233
234/* 227/*
235 * Walk the LRU list and prune off entries that are older than RC_EXPIRE. 228 * Walk the LRU list and prune off entries that are older than RC_EXPIRE.
236 * Also prune the oldest ones when the total exceeds the max number of entries. 229 * Also prune the oldest ones when the total exceeds the max number of entries.
@@ -242,8 +235,14 @@ prune_cache_entries(void)
242 long freed = 0; 235 long freed = 0;
243 236
244 list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) { 237 list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) {
245 if (!nfsd_cache_entry_expired(rp) && 238 /*
246 num_drc_entries <= max_drc_entries) 239 * Don't free entries attached to calls that are still
240 * in-progress, but do keep scanning the list.
241 */
242 if (rp->c_state == RC_INPROG)
243 continue;
244 if (num_drc_entries <= max_drc_entries &&
245 time_before(jiffies, rp->c_timestamp + RC_EXPIRE))
247 break; 246 break;
248 nfsd_reply_cache_free_locked(rp); 247 nfsd_reply_cache_free_locked(rp);
249 freed++; 248 freed++;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index f34d9de802ab..51844048937f 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1179,7 +1179,6 @@ static int __init init_nfsd(void)
1179 retval = nfsd4_init_slabs(); 1179 retval = nfsd4_init_slabs();
1180 if (retval) 1180 if (retval)
1181 goto out_unregister_pernet; 1181 goto out_unregister_pernet;
1182 nfs4_state_init();
1183 retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ 1182 retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */
1184 if (retval) 1183 if (retval)
1185 goto out_free_slabs; 1184 goto out_free_slabs;
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 479eb681c27c..847daf37e566 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -15,11 +15,20 @@
15#include <linux/nfs2.h> 15#include <linux/nfs2.h>
16#include <linux/nfs3.h> 16#include <linux/nfs3.h>
17#include <linux/nfs4.h> 17#include <linux/nfs4.h>
18#include <linux/sunrpc/svc.h>
18#include <linux/sunrpc/msg_prot.h> 19#include <linux/sunrpc/msg_prot.h>
19 20
20#include <linux/nfsd/debug.h> 21#include <uapi/linux/nfsd/debug.h>
21#include <linux/nfsd/export.h> 22
22#include <linux/nfsd/stats.h> 23#include "stats.h"
24#include "export.h"
25
26#undef ifdebug
27#ifdef NFSD_DEBUG
28# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
29#else
30# define ifdebug(flag) if (0)
31#endif
23 32
24/* 33/*
25 * nfsd version 34 * nfsd version
@@ -106,7 +115,6 @@ static inline int nfsd_v4client(struct svc_rqst *rq)
106 */ 115 */
107#ifdef CONFIG_NFSD_V4 116#ifdef CONFIG_NFSD_V4
108extern unsigned long max_delegations; 117extern unsigned long max_delegations;
109void nfs4_state_init(void);
110int nfsd4_init_slabs(void); 118int nfsd4_init_slabs(void);
111void nfsd4_free_slabs(void); 119void nfsd4_free_slabs(void);
112int nfs4_state_start(void); 120int nfs4_state_start(void);
@@ -117,7 +125,6 @@ void nfs4_reset_lease(time_t leasetime);
117int nfs4_reset_recoverydir(char *recdir); 125int nfs4_reset_recoverydir(char *recdir);
118char * nfs4_recoverydir(void); 126char * nfs4_recoverydir(void);
119#else 127#else
120static inline void nfs4_state_init(void) { }
121static inline int nfsd4_init_slabs(void) { return 0; } 128static inline int nfsd4_init_slabs(void) { return 0; }
122static inline void nfsd4_free_slabs(void) { } 129static inline void nfsd4_free_slabs(void) { }
123static inline int nfs4_state_start(void) { return 0; } 130static inline int nfs4_state_start(void) { return 0; }
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 3c37b160dcad..ec8393418154 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -88,9 +88,8 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
88 /* Check if the request originated from a secure port. */ 88 /* Check if the request originated from a secure port. */
89 if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) { 89 if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) {
90 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 90 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
91 dprintk(KERN_WARNING 91 dprintk("nfsd: request from insecure port %s!\n",
92 "nfsd: request from insecure port %s!\n", 92 svc_print_addr(rqstp, buf, sizeof(buf)));
93 svc_print_addr(rqstp, buf, sizeof(buf)));
94 return nfserr_perm; 93 return nfserr_perm;
95 } 94 }
96 95
@@ -169,8 +168,8 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
169 data_left -= len; 168 data_left -= len;
170 if (data_left < 0) 169 if (data_left < 0)
171 return error; 170 return error;
172 exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_auth); 171 exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid);
173 fid = (struct fid *)(fh->fh_auth + len); 172 fid = (struct fid *)(fh->fh_fsid + len);
174 } else { 173 } else {
175 __u32 tfh[2]; 174 __u32 tfh[2];
176 dev_t xdev; 175 dev_t xdev;
@@ -385,7 +384,7 @@ static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
385{ 384{
386 if (dentry != exp->ex_path.dentry) { 385 if (dentry != exp->ex_path.dentry) {
387 struct fid *fid = (struct fid *) 386 struct fid *fid = (struct fid *)
388 (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1); 387 (fhp->fh_handle.fh_fsid + fhp->fh_handle.fh_size/4 - 1);
389 int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; 388 int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
390 int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK); 389 int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
391 390
@@ -513,7 +512,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
513 */ 512 */
514 513
515 struct inode * inode = dentry->d_inode; 514 struct inode * inode = dentry->d_inode;
516 __u32 *datap;
517 dev_t ex_dev = exp_sb(exp)->s_dev; 515 dev_t ex_dev = exp_sb(exp)->s_dev;
518 516
519 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %pd2, ino=%ld)\n", 517 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %pd2, ino=%ld)\n",
@@ -557,17 +555,16 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
557 if (inode) 555 if (inode)
558 _fh_update_old(dentry, exp, &fhp->fh_handle); 556 _fh_update_old(dentry, exp, &fhp->fh_handle);
559 } else { 557 } else {
560 int len; 558 fhp->fh_handle.fh_size =
559 key_len(fhp->fh_handle.fh_fsid_type) + 4;
561 fhp->fh_handle.fh_auth_type = 0; 560 fhp->fh_handle.fh_auth_type = 0;
562 datap = fhp->fh_handle.fh_auth+0; 561
563 mk_fsid(fhp->fh_handle.fh_fsid_type, datap, ex_dev, 562 mk_fsid(fhp->fh_handle.fh_fsid_type,
563 fhp->fh_handle.fh_fsid,
564 ex_dev,
564 exp->ex_path.dentry->d_inode->i_ino, 565 exp->ex_path.dentry->d_inode->i_ino,
565 exp->ex_fsid, exp->ex_uuid); 566 exp->ex_fsid, exp->ex_uuid);
566 567
567 len = key_len(fhp->fh_handle.fh_fsid_type);
568 datap += len/4;
569 fhp->fh_handle.fh_size = 4 + len;
570
571 if (inode) 568 if (inode)
572 _fh_update(fhp, exp, dentry); 569 _fh_update(fhp, exp, dentry);
573 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { 570 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
index ad67964d0bb1..2e89e70ac15c 100644
--- a/fs/nfsd/nfsfh.h
+++ b/fs/nfsd/nfsfh.h
@@ -1,9 +1,58 @@
1/* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> */ 1/*
2 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
3 *
4 * This file describes the layout of the file handles as passed
5 * over the wire.
6 */
7#ifndef _LINUX_NFSD_NFSFH_H
8#define _LINUX_NFSD_NFSFH_H
9
10#include <linux/sunrpc/svc.h>
11#include <uapi/linux/nfsd/nfsfh.h>
12
13static inline __u32 ino_t_to_u32(ino_t ino)
14{
15 return (__u32) ino;
16}
17
18static inline ino_t u32_to_ino_t(__u32 uino)
19{
20 return (ino_t) uino;
21}
2 22
3#ifndef _LINUX_NFSD_FH_INT_H 23/*
4#define _LINUX_NFSD_FH_INT_H 24 * This is the internal representation of an NFS handle used in knfsd.
25 * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
26 */
27typedef struct svc_fh {
28 struct knfsd_fh fh_handle; /* FH data */
29 struct dentry * fh_dentry; /* validated dentry */
30 struct svc_export * fh_export; /* export pointer */
31 int fh_maxsize; /* max size for fh_handle */
32
33 unsigned char fh_locked; /* inode locked by us */
34 unsigned char fh_want_write; /* remount protection taken */
35
36#ifdef CONFIG_NFSD_V3
37 unsigned char fh_post_saved; /* post-op attrs saved */
38 unsigned char fh_pre_saved; /* pre-op attrs saved */
39
40 /* Pre-op attributes saved during fh_lock */
41 __u64 fh_pre_size; /* size before operation */
42 struct timespec fh_pre_mtime; /* mtime before oper */
43 struct timespec fh_pre_ctime; /* ctime before oper */
44 /*
45 * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
46 * to find out if it is valid.
47 */
48 u64 fh_pre_change;
49
50 /* Post-op attributes saved in fh_unlock */
51 struct kstat fh_post_attr; /* full attrs after operation */
52 u64 fh_post_change; /* nfsv4 change; see above */
53#endif /* CONFIG_NFSD_V3 */
5 54
6#include <linux/nfsd/nfsfh.h> 55} svc_fh;
7 56
8enum nfsd_fsid { 57enum nfsd_fsid {
9 FSID_DEV = 0, 58 FSID_DEV = 0,
@@ -215,4 +264,4 @@ fh_unlock(struct svc_fh *fhp)
215 } 264 }
216} 265}
217 266
218#endif /* _LINUX_NFSD_FH_INT_H */ 267#endif /* _LINUX_NFSD_NFSFH_H */
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 9a4a5f9e7468..1879e43f2868 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -591,12 +591,6 @@ nfsd(void *vrqstp)
591 nfsdstats.th_cnt++; 591 nfsdstats.th_cnt++;
592 mutex_unlock(&nfsd_mutex); 592 mutex_unlock(&nfsd_mutex);
593 593
594 /*
595 * We want less throttling in balance_dirty_pages() so that nfs to
596 * localhost doesn't cause nfsd to lock up due to all the client's
597 * dirty pages.
598 */
599 current->flags |= PF_LESS_THROTTLE;
600 set_freezable(); 594 set_freezable();
601 595
602 /* 596 /*
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 9c769a47ac5a..1ac306b769df 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -214,7 +214,8 @@ nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
214int 214int
215nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) 215nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
216{ 216{
217 if (!(p = decode_fh(p, &args->fh))) 217 p = decode_fh(p, &args->fh);
218 if (!p)
218 return 0; 219 return 0;
219 return xdr_argsize_check(rqstp, p); 220 return xdr_argsize_check(rqstp, p);
220} 221}
@@ -248,7 +249,8 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
248{ 249{
249 unsigned int len; 250 unsigned int len;
250 int v; 251 int v;
251 if (!(p = decode_fh(p, &args->fh))) 252 p = decode_fh(p, &args->fh);
253 if (!p)
252 return 0; 254 return 0;
253 255
254 args->offset = ntohl(*p++); 256 args->offset = ntohl(*p++);
@@ -281,7 +283,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
281 unsigned int len, hdr, dlen; 283 unsigned int len, hdr, dlen;
282 int v; 284 int v;
283 285
284 if (!(p = decode_fh(p, &args->fh))) 286 p = decode_fh(p, &args->fh);
287 if (!p)
285 return 0; 288 return 0;
286 289
287 p++; /* beginoffset */ 290 p++; /* beginoffset */
@@ -355,7 +358,8 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
355int 358int
356nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args) 359nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args)
357{ 360{
358 if (!(p = decode_fh(p, &args->fh))) 361 p = decode_fh(p, &args->fh);
362 if (!p)
359 return 0; 363 return 0;
360 args->buffer = page_address(*(rqstp->rq_next_page++)); 364 args->buffer = page_address(*(rqstp->rq_next_page++));
361 365
@@ -391,7 +395,8 @@ int
391nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, 395nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
392 struct nfsd_readdirargs *args) 396 struct nfsd_readdirargs *args)
393{ 397{
394 if (!(p = decode_fh(p, &args->fh))) 398 p = decode_fh(p, &args->fh);
399 if (!p)
395 return 0; 400 return 0;
396 args->cookie = ntohl(*p++); 401 args->cookie = ntohl(*p++);
397 args->count = ntohl(*p++); 402 args->count = ntohl(*p++);
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 424d8f5f2317..374c66283ac5 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -37,7 +37,6 @@
37 37
38#include <linux/idr.h> 38#include <linux/idr.h>
39#include <linux/sunrpc/svc_xprt.h> 39#include <linux/sunrpc/svc_xprt.h>
40#include <linux/nfsd/nfsfh.h>
41#include "nfsfh.h" 40#include "nfsfh.h"
42 41
43typedef struct { 42typedef struct {
@@ -123,7 +122,7 @@ static inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
123/* Maximum number of operations per session compound */ 122/* Maximum number of operations per session compound */
124#define NFSD_MAX_OPS_PER_COMPOUND 16 123#define NFSD_MAX_OPS_PER_COMPOUND 16
125/* Maximum session per slot cache size */ 124/* Maximum session per slot cache size */
126#define NFSD_SLOT_CACHE_SIZE 1024 125#define NFSD_SLOT_CACHE_SIZE 2048
127/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */ 126/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */
128#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32 127#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32
129#define NFSD_MAX_MEM_PER_SESSION \ 128#define NFSD_MAX_MEM_PER_SESSION \
@@ -464,8 +463,6 @@ extern void nfs4_release_reclaim(struct nfsd_net *);
464extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, 463extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
465 struct nfsd_net *nn); 464 struct nfsd_net *nn);
466extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions, struct nfsd_net *nn); 465extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions, struct nfsd_net *nn);
467extern void nfs4_free_openowner(struct nfs4_openowner *);
468extern void nfs4_free_lockowner(struct nfs4_lockowner *);
469extern int set_callback_cred(void); 466extern int set_callback_cred(void);
470extern void nfsd4_init_callback(struct nfsd4_callback *); 467extern void nfsd4_init_callback(struct nfsd4_callback *);
471extern void nfsd4_probe_callback(struct nfs4_client *clp); 468extern void nfsd4_probe_callback(struct nfs4_client *clp);
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
index 6d4521feb6e3..cd90878a76aa 100644
--- a/fs/nfsd/stats.c
+++ b/fs/nfsd/stats.c
@@ -24,7 +24,6 @@
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/sunrpc/stats.h> 26#include <linux/sunrpc/stats.h>
27#include <linux/nfsd/stats.h>
28#include <net/net_namespace.h> 27#include <net/net_namespace.h>
29 28
30#include "nfsd.h" 29#include "nfsd.h"
diff --git a/include/linux/nfsd/stats.h b/fs/nfsd/stats.h
index e75b2544ff12..a5c944b771c6 100644
--- a/include/linux/nfsd/stats.h
+++ b/fs/nfsd/stats.h
@@ -1,12 +1,10 @@
1/* 1/*
2 * linux/include/linux/nfsd/stats.h
3 *
4 * Statistics for NFS server. 2 * Statistics for NFS server.
5 * 3 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 4 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */ 5 */
8#ifndef LINUX_NFSD_STATS_H 6#ifndef _NFSD_STATS_H
9#define LINUX_NFSD_STATS_H 7#define _NFSD_STATS_H
10 8
11#include <uapi/linux/nfsd/stats.h> 9#include <uapi/linux/nfsd/stats.h>
12 10
@@ -42,4 +40,4 @@ extern struct svc_stat nfsd_svcstats;
42void nfsd_stat_init(void); 40void nfsd_stat_init(void);
43void nfsd_stat_shutdown(void); 41void nfsd_stat_shutdown(void);
44 42
45#endif /* LINUX_NFSD_STATS_H */ 43#endif /* _NFSD_STATS_H */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 16f0673a423c..140c496f612c 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -820,55 +820,54 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
820 return __splice_from_pipe(pipe, sd, nfsd_splice_actor); 820 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
821} 821}
822 822
823static __be32 823__be32 nfsd_finish_read(struct file *file, unsigned long *count, int host_err)
824nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
825 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
826{ 824{
827 mm_segment_t oldfs;
828 __be32 err;
829 int host_err;
830
831 err = nfserr_perm;
832
833 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
834 struct splice_desc sd = {
835 .len = 0,
836 .total_len = *count,
837 .pos = offset,
838 .u.data = rqstp,
839 };
840
841 rqstp->rq_next_page = rqstp->rq_respages + 1;
842 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
843 } else {
844 oldfs = get_fs();
845 set_fs(KERNEL_DS);
846 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
847 set_fs(oldfs);
848 }
849
850 if (host_err >= 0) { 825 if (host_err >= 0) {
851 nfsdstats.io_read += host_err; 826 nfsdstats.io_read += host_err;
852 *count = host_err; 827 *count = host_err;
853 err = 0;
854 fsnotify_access(file); 828 fsnotify_access(file);
829 return 0;
855 } else 830 } else
856 err = nfserrno(host_err); 831 return nfserrno(host_err);
857 return err; 832}
833
834int nfsd_splice_read(struct svc_rqst *rqstp,
835 struct file *file, loff_t offset, unsigned long *count)
836{
837 struct splice_desc sd = {
838 .len = 0,
839 .total_len = *count,
840 .pos = offset,
841 .u.data = rqstp,
842 };
843 int host_err;
844
845 rqstp->rq_next_page = rqstp->rq_respages + 1;
846 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
847 return nfsd_finish_read(file, count, host_err);
858} 848}
859 849
860static void kill_suid(struct dentry *dentry) 850int nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen,
851 unsigned long *count)
861{ 852{
862 struct iattr ia; 853 mm_segment_t oldfs;
863 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; 854 int host_err;
864 855
865 mutex_lock(&dentry->d_inode->i_mutex); 856 oldfs = get_fs();
866 /* 857 set_fs(KERNEL_DS);
867 * Note we call this on write, so notify_change will not 858 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
868 * encounter any conflicting delegations: 859 set_fs(oldfs);
869 */ 860 return nfsd_finish_read(file, count, host_err);
870 notify_change(dentry, &ia, NULL); 861}
871 mutex_unlock(&dentry->d_inode->i_mutex); 862
863static __be32
864nfsd_vfs_read(struct svc_rqst *rqstp, struct file *file,
865 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
866{
867 if (file->f_op->splice_read && rqstp->rq_splice_ok)
868 return nfsd_splice_read(rqstp, file, offset, count);
869 else
870 return nfsd_readv(file, offset, vec, vlen, count);
872} 871}
873 872
874/* 873/*
@@ -922,6 +921,16 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
922 int stable = *stablep; 921 int stable = *stablep;
923 int use_wgather; 922 int use_wgather;
924 loff_t pos = offset; 923 loff_t pos = offset;
924 unsigned int pflags = current->flags;
925
926 if (rqstp->rq_local)
927 /*
928 * We want less throttling in balance_dirty_pages()
929 * and shrink_inactive_list() so that nfs to
930 * localhost doesn't cause nfsd to lock up due to all
931 * the client's dirty pages or its congested queue.
932 */
933 current->flags |= PF_LESS_THROTTLE;
925 934
926 dentry = file->f_path.dentry; 935 dentry = file->f_path.dentry;
927 inode = dentry->d_inode; 936 inode = dentry->d_inode;
@@ -942,10 +951,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
942 nfsdstats.io_write += host_err; 951 nfsdstats.io_write += host_err;
943 fsnotify_modify(file); 952 fsnotify_modify(file);
944 953
945 /* clear setuid/setgid flag after write */
946 if (inode->i_mode & (S_ISUID | S_ISGID))
947 kill_suid(dentry);
948
949 if (stable) { 954 if (stable) {
950 if (use_wgather) 955 if (use_wgather)
951 host_err = wait_for_concurrent_writes(file); 956 host_err = wait_for_concurrent_writes(file);
@@ -959,36 +964,33 @@ out_nfserr:
959 err = 0; 964 err = 0;
960 else 965 else
961 err = nfserrno(host_err); 966 err = nfserrno(host_err);
967 if (rqstp->rq_local)
968 tsk_restore_flags(current, pflags, PF_LESS_THROTTLE);
962 return err; 969 return err;
963} 970}
964 971
965/* 972__be32 nfsd_get_tmp_read_open(struct svc_rqst *rqstp, struct svc_fh *fhp,
966 * Read data from a file. count must contain the requested read count 973 struct file **file, struct raparms **ra)
967 * on entry. On return, *count contains the number of bytes actually read.
968 * N.B. After this call fhp needs an fh_put
969 */
970__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
971 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
972{ 974{
973 struct file *file;
974 struct inode *inode; 975 struct inode *inode;
975 struct raparms *ra;
976 __be32 err; 976 __be32 err;
977 977
978 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); 978 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, file);
979 if (err) 979 if (err)
980 return err; 980 return err;
981 981
982 inode = file_inode(file); 982 inode = file_inode(*file);
983 983
984 /* Get readahead parameters */ 984 /* Get readahead parameters */
985 ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); 985 *ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
986 986
987 if (ra && ra->p_set) 987 if (*ra && (*ra)->p_set)
988 file->f_ra = ra->p_ra; 988 (*file)->f_ra = (*ra)->p_ra;
989 989 return nfs_ok;
990 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); 990}
991 991
992void nfsd_put_tmp_read_open(struct file *file, struct raparms *ra)
993{
992 /* Write back readahead params */ 994 /* Write back readahead params */
993 if (ra) { 995 if (ra) {
994 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex]; 996 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
@@ -998,28 +1000,29 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
998 ra->p_count--; 1000 ra->p_count--;
999 spin_unlock(&rab->pb_lock); 1001 spin_unlock(&rab->pb_lock);
1000 } 1002 }
1001
1002 nfsd_close(file); 1003 nfsd_close(file);
1003 return err;
1004} 1004}
1005 1005
1006/* As above, but use the provided file descriptor. */ 1006/*
1007__be32 1007 * Read data from a file. count must contain the requested read count
1008nfsd_read_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 1008 * on entry. On return, *count contains the number of bytes actually read.
1009 loff_t offset, struct kvec *vec, int vlen, 1009 * N.B. After this call fhp needs an fh_put
1010 unsigned long *count) 1010 */
1011__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1012 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
1011{ 1013{
1012 __be32 err; 1014 struct file *file;
1015 struct raparms *ra;
1016 __be32 err;
1017
1018 err = nfsd_get_tmp_read_open(rqstp, fhp, &file, &ra);
1019 if (err)
1020 return err;
1021
1022 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
1023
1024 nfsd_put_tmp_read_open(file, ra);
1013 1025
1014 if (file) {
1015 err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
1016 NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
1017 if (err)
1018 goto out;
1019 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1020 } else /* Note file may still be NULL in NFSv4 special stateid case: */
1021 err = nfsd_read(rqstp, fhp, offset, vec, vlen, count);
1022out:
1023 return err; 1026 return err;
1024} 1027}
1025 1028
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index fbe90bdb2214..91b6ae3f658b 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -70,10 +70,16 @@ __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
70__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, 70__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
71 int, struct file **); 71 int, struct file **);
72void nfsd_close(struct file *); 72void nfsd_close(struct file *);
73struct raparms;
74__be32 nfsd_get_tmp_read_open(struct svc_rqst *, struct svc_fh *,
75 struct file **, struct raparms **);
76void nfsd_put_tmp_read_open(struct file *, struct raparms *);
77int nfsd_splice_read(struct svc_rqst *,
78 struct file *, loff_t, unsigned long *);
79int nfsd_readv(struct file *, loff_t, struct kvec *, int,
80 unsigned long *);
73__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, 81__be32 nfsd_read(struct svc_rqst *, struct svc_fh *,
74 loff_t, struct kvec *, int, unsigned long *); 82 loff_t, struct kvec *, int, unsigned long *);
75__be32 nfsd_read_file(struct svc_rqst *, struct svc_fh *, struct file *,
76 loff_t, struct kvec *, int, unsigned long *);
77__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, 83__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
78 loff_t, struct kvec *,int, unsigned long *, int *); 84 loff_t, struct kvec *,int, unsigned long *, int *);
79__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, 85__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 5ea7df305083..18cbb6d9c8a9 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -58,7 +58,7 @@ struct nfsd4_compound_state {
58 /* For sessions DRC */ 58 /* For sessions DRC */
59 struct nfsd4_session *session; 59 struct nfsd4_session *session;
60 struct nfsd4_slot *slot; 60 struct nfsd4_slot *slot;
61 __be32 *datap; 61 int data_offset;
62 size_t iovlen; 62 size_t iovlen;
63 u32 minorversion; 63 u32 minorversion;
64 __be32 status; 64 __be32 status;
@@ -287,9 +287,8 @@ struct nfsd4_readdir {
287 struct svc_fh * rd_fhp; /* response */ 287 struct svc_fh * rd_fhp; /* response */
288 288
289 struct readdir_cd common; 289 struct readdir_cd common;
290 __be32 * buffer; 290 struct xdr_stream *xdr;
291 int buflen; 291 int cookie_offset;
292 __be32 * offset;
293}; 292};
294 293
295struct nfsd4_release_lockowner { 294struct nfsd4_release_lockowner {
@@ -506,9 +505,7 @@ struct nfsd4_compoundargs {
506 505
507struct nfsd4_compoundres { 506struct nfsd4_compoundres {
508 /* scratch variables for XDR encode */ 507 /* scratch variables for XDR encode */
509 __be32 * p; 508 struct xdr_stream xdr;
510 __be32 * end;
511 struct xdr_buf * xbuf;
512 struct svc_rqst * rqstp; 509 struct svc_rqst * rqstp;
513 510
514 u32 taglen; 511 u32 taglen;
@@ -538,6 +535,9 @@ static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
538 return argp->opcnt == resp->opcnt; 535 return argp->opcnt == resp->opcnt;
539} 536}
540 537
538int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op);
539void warn_on_nonidempotent_op(struct nfsd4_op *op);
540
541#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) 541#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
542 542
543static inline void 543static inline void
@@ -563,10 +563,11 @@ int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
563 struct nfsd4_compoundres *); 563 struct nfsd4_compoundres *);
564__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); 564__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
565void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 565void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
566void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 566void nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op);
567__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 567__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
568 struct dentry *dentry, __be32 **buffer, int countp, 568 struct svc_fh *fhp, struct svc_export *exp,
569 u32 *bmval, struct svc_rqst *, int ignore_crossmnt); 569 struct dentry *dentry,
570 u32 *bmval, struct svc_rqst *, int ignore_crossmnt);
570extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, 571extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
571 struct nfsd4_compound_state *, 572 struct nfsd4_compound_state *,
572 struct nfsd4_setclientid *setclid); 573 struct nfsd4_setclientid *setclid);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index dcaad79f54ed..219d79627c05 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -17,13 +17,13 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/kref.h> 18#include <linux/kref.h>
19#include <linux/utsname.h> 19#include <linux/utsname.h>
20#include <linux/nfsd/nfsfh.h>
21#include <linux/lockd/bind.h> 20#include <linux/lockd/bind.h>
22#include <linux/lockd/xdr.h> 21#include <linux/lockd/xdr.h>
23#ifdef CONFIG_LOCKD_V4 22#ifdef CONFIG_LOCKD_V4
24#include <linux/lockd/xdr4.h> 23#include <linux/lockd/xdr4.h>
25#endif 24#endif
26#include <linux/lockd/debug.h> 25#include <linux/lockd/debug.h>
26#include <linux/sunrpc/svc.h>
27 27
28/* 28/*
29 * Version string 29 * Version string
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 12c2cb947df5..a1e3064a8d99 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -399,8 +399,6 @@ enum lock_type4 {
399#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) 399#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1)
400#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) 400#define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4)
401#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) 401#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
402#define FATTR4_WORD2_CHANGE_SECURITY_LABEL \
403 (1UL << 17)
404 402
405/* MDS threshold bitmap bits */ 403/* MDS threshold bitmap bits */
406#define THRESHOLD_RD (1UL << 0) 404#define THRESHOLD_RD (1UL << 0)
diff --git a/include/linux/nfsd/debug.h b/include/linux/nfsd/debug.h
deleted file mode 100644
index 19ef8375b577..000000000000
--- a/include/linux/nfsd/debug.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/include/linux/nfsd/debug.h
3 *
4 * Debugging-related stuff for nfsd
5 *
6 * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
7 */
8#ifndef LINUX_NFSD_DEBUG_H
9#define LINUX_NFSD_DEBUG_H
10
11#include <uapi/linux/nfsd/debug.h>
12
13# undef ifdebug
14# ifdef NFSD_DEBUG
15# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
16# else
17# define ifdebug(flag) if (0)
18# endif
19#endif /* LINUX_NFSD_DEBUG_H */
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
deleted file mode 100644
index a93593f1fa4e..000000000000
--- a/include/linux/nfsd/nfsfh.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * include/linux/nfsd/nfsfh.h
3 *
4 * This file describes the layout of the file handles as passed
5 * over the wire.
6 *
7 * Earlier versions of knfsd used to sign file handles using keyed MD5
8 * or SHA. I've removed this code, because it doesn't give you more
9 * security than blocking external access to port 2049 on your firewall.
10 *
11 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
12 */
13#ifndef _LINUX_NFSD_FH_H
14#define _LINUX_NFSD_FH_H
15
16# include <linux/sunrpc/svc.h>
17#include <uapi/linux/nfsd/nfsfh.h>
18
19static inline __u32 ino_t_to_u32(ino_t ino)
20{
21 return (__u32) ino;
22}
23
24static inline ino_t u32_to_ino_t(__u32 uino)
25{
26 return (ino_t) uino;
27}
28
29/*
30 * This is the internal representation of an NFS handle used in knfsd.
31 * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
32 */
33typedef struct svc_fh {
34 struct knfsd_fh fh_handle; /* FH data */
35 struct dentry * fh_dentry; /* validated dentry */
36 struct svc_export * fh_export; /* export pointer */
37 int fh_maxsize; /* max size for fh_handle */
38
39 unsigned char fh_locked; /* inode locked by us */
40 unsigned char fh_want_write; /* remount protection taken */
41
42#ifdef CONFIG_NFSD_V3
43 unsigned char fh_post_saved; /* post-op attrs saved */
44 unsigned char fh_pre_saved; /* pre-op attrs saved */
45
46 /* Pre-op attributes saved during fh_lock */
47 __u64 fh_pre_size; /* size before operation */
48 struct timespec fh_pre_mtime; /* mtime before oper */
49 struct timespec fh_pre_ctime; /* ctime before oper */
50 /*
51 * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
52 * to find out if it is valid.
53 */
54 u64 fh_pre_change;
55
56 /* Post-op attributes saved in fh_unlock */
57 struct kstat fh_post_attr; /* full attrs after operation */
58 u64 fh_post_change; /* nfsv4 change; see above */
59#endif /* CONFIG_NFSD_V3 */
60
61} svc_fh;
62
63#endif /* _LINUX_NFSD_FH_H */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 04e763221246..1bc7cd05b22e 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -244,6 +244,7 @@ struct svc_rqst {
244 struct page * rq_pages[RPCSVC_MAXPAGES]; 244 struct page * rq_pages[RPCSVC_MAXPAGES];
245 struct page * *rq_respages; /* points into rq_pages */ 245 struct page * *rq_respages; /* points into rq_pages */
246 struct page * *rq_next_page; /* next reply page to use */ 246 struct page * *rq_next_page; /* next reply page to use */
247 struct page * *rq_page_end; /* one past the last page */
247 248
248 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ 249 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
249 250
@@ -254,11 +255,15 @@ struct svc_rqst {
254 u32 rq_prot; /* IP protocol */ 255 u32 rq_prot; /* IP protocol */
255 unsigned short 256 unsigned short
256 rq_secure : 1; /* secure port */ 257 rq_secure : 1; /* secure port */
258 unsigned short rq_local : 1; /* local request */
257 259
258 void * rq_argp; /* decoded arguments */ 260 void * rq_argp; /* decoded arguments */
259 void * rq_resp; /* xdr'd results */ 261 void * rq_resp; /* xdr'd results */
260 void * rq_auth_data; /* flavor-specific data */ 262 void * rq_auth_data; /* flavor-specific data */
261 263 int rq_auth_slack; /* extra space xdr code
264 * should leave in head
265 * for krb5i, krb5p.
266 */
262 int rq_reserved; /* space on socket outq 267 int rq_reserved; /* space on socket outq
263 * reserved for this request 268 * reserved for this request
264 */ 269 */
@@ -454,11 +459,7 @@ char * svc_print_addr(struct svc_rqst *, char *, size_t);
454 */ 459 */
455static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) 460static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
456{ 461{
457 int added_space = 0; 462 svc_reserve(rqstp, space + rqstp->rq_auth_slack);
458
459 if (rqstp->rq_authop->flavour)
460 added_space = RPC_MAX_AUTH_SIZE;
461 svc_reserve(rqstp, space + added_space);
462} 463}
463 464
464#endif /* SUNRPC_SVC_H */ 465#endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 0b8e3e6bdacf..5cf99a016368 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -115,14 +115,13 @@ struct svc_rdma_fastreg_mr {
115 struct list_head frmr_list; 115 struct list_head frmr_list;
116}; 116};
117struct svc_rdma_req_map { 117struct svc_rdma_req_map {
118 struct svc_rdma_fastreg_mr *frmr;
119 unsigned long count; 118 unsigned long count;
120 union { 119 union {
121 struct kvec sge[RPCSVC_MAXPAGES]; 120 struct kvec sge[RPCSVC_MAXPAGES];
122 struct svc_rdma_chunk_sge ch[RPCSVC_MAXPAGES]; 121 struct svc_rdma_chunk_sge ch[RPCSVC_MAXPAGES];
122 unsigned long lkey[RPCSVC_MAXPAGES];
123 }; 123 };
124}; 124};
125#define RDMACTXT_F_FAST_UNREG 1
126#define RDMACTXT_F_LAST_CTXT 2 125#define RDMACTXT_F_LAST_CTXT 2
127 126
128#define SVCRDMA_DEVCAP_FAST_REG 1 /* fast mr registration */ 127#define SVCRDMA_DEVCAP_FAST_REG 1 /* fast mr registration */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index b05963f09ebf..7235040a19b2 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -24,6 +24,7 @@ struct svc_xprt_ops {
24 void (*xpo_release_rqst)(struct svc_rqst *); 24 void (*xpo_release_rqst)(struct svc_rqst *);
25 void (*xpo_detach)(struct svc_xprt *); 25 void (*xpo_detach)(struct svc_xprt *);
26 void (*xpo_free)(struct svc_xprt *); 26 void (*xpo_free)(struct svc_xprt *);
27 int (*xpo_secure_port)(struct svc_rqst *);
27}; 28};
28 29
29struct svc_xprt_class { 30struct svc_xprt_class {
@@ -63,6 +64,7 @@ struct svc_xprt {
63#define XPT_DETACHED 10 /* detached from tempsocks list */ 64#define XPT_DETACHED 10 /* detached from tempsocks list */
64#define XPT_LISTENER 11 /* listening endpoint */ 65#define XPT_LISTENER 11 /* listening endpoint */
65#define XPT_CACHE_AUTH 12 /* cache auth info */ 66#define XPT_CACHE_AUTH 12 /* cache auth info */
67#define XPT_LOCAL 13 /* connection from loopback interface */
66 68
67 struct svc_serv *xpt_server; /* service for transport */ 69 struct svc_serv *xpt_server; /* service for transport */
68 atomic_t xpt_reserved; /* space on outq that is rsvd */ 70 atomic_t xpt_reserved; /* space on outq that is rsvd */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 15f9204ee70b..70c6b92e15a7 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -215,6 +215,9 @@ typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj);
215 215
216extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); 216extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p);
217extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); 217extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
218extern void xdr_commit_encode(struct xdr_stream *xdr);
219extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
220extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
218extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, 221extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
219 unsigned int base, unsigned int len); 222 unsigned int base, unsigned int len);
220extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr); 223extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr);
diff --git a/include/uapi/linux/nfsd/nfsfh.h b/include/uapi/linux/nfsd/nfsfh.h
index 616e3b396476..20391235d088 100644
--- a/include/uapi/linux/nfsd/nfsfh.h
+++ b/include/uapi/linux/nfsd/nfsfh.h
@@ -1,13 +1,7 @@
1/* 1/*
2 * include/linux/nfsd/nfsfh.h
3 *
4 * This file describes the layout of the file handles as passed 2 * This file describes the layout of the file handles as passed
5 * over the wire. 3 * over the wire.
6 * 4 *
7 * Earlier versions of knfsd used to sign file handles using keyed MD5
8 * or SHA. I've removed this code, because it doesn't give you more
9 * security than blocking external access to port 2049 on your firewall.
10 *
11 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> 5 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
12 */ 6 */
13 7
@@ -37,7 +31,7 @@ struct nfs_fhbase_old {
37}; 31};
38 32
39/* 33/*
40 * This is the new flexible, extensible style NFSv2/v3 file handle. 34 * This is the new flexible, extensible style NFSv2/v3/v4 file handle.
41 * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000 35 * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000
42 * 36 *
43 * The file handle starts with a sequence of four-byte words. 37 * The file handle starts with a sequence of four-byte words.
@@ -47,14 +41,7 @@ struct nfs_fhbase_old {
47 * 41 *
48 * All four-byte values are in host-byte-order. 42 * All four-byte values are in host-byte-order.
49 * 43 *
50 * The auth_type field specifies how the filehandle can be authenticated 44 * The auth_type field is deprecated and must be set to 0.
51 * This might allow a file to be confirmed to be in a writable part of a
52 * filetree without checking the path from it up to the root.
53 * Current values:
54 * 0 - No authentication. fb_auth is 0 bytes long
55 * Possible future values:
56 * 1 - 4 bytes taken from MD5 hash of the remainer of the file handle
57 * prefixed by a secret and with the important export flags.
58 * 45 *
59 * The fsid_type identifies how the filesystem (or export point) is 46 * The fsid_type identifies how the filesystem (or export point) is
60 * encoded. 47 * encoded.
@@ -71,14 +58,9 @@ struct nfs_fhbase_old {
71 * 7 - 8 byte inode number and 16 byte uuid 58 * 7 - 8 byte inode number and 16 byte uuid
72 * 59 *
73 * The fileid_type identified how the file within the filesystem is encoded. 60 * The fileid_type identified how the file within the filesystem is encoded.
74 * This is (will be) passed to, and set by, the underlying filesystem if it supports 61 * The values for this field are filesystem specific, exccept that
75 * filehandle operations. The filesystem must not use the value '0' or '0xff' and may 62 * filesystems must not use the values '0' or '0xff'. 'See enum fid_type'
76 * only use the values 1 and 2 as defined below: 63 * in include/linux/exportfs.h for currently registered values.
77 * Current values:
78 * 0 - The root, or export point, of the filesystem. fb_fileid is 0 bytes.
79 * 1 - 32bit inode number, 32 bit generation number.
80 * 2 - 32bit inode number, 32 bit generation number, 32 bit parent directory inode number.
81 *
82 */ 64 */
83struct nfs_fhbase_new { 65struct nfs_fhbase_new {
84 __u8 fb_version; /* == 1, even => nfs_fhbase_old */ 66 __u8 fb_version; /* == 1, even => nfs_fhbase_old */
@@ -114,9 +96,9 @@ struct knfsd_fh {
114#define fh_fsid_type fh_base.fh_new.fb_fsid_type 96#define fh_fsid_type fh_base.fh_new.fb_fsid_type
115#define fh_auth_type fh_base.fh_new.fb_auth_type 97#define fh_auth_type fh_base.fh_new.fb_auth_type
116#define fh_fileid_type fh_base.fh_new.fb_fileid_type 98#define fh_fileid_type fh_base.fh_new.fb_fileid_type
117#define fh_auth fh_base.fh_new.fb_auth
118#define fh_fsid fh_base.fh_new.fb_auth 99#define fh_fsid fh_base.fh_new.fb_auth
119 100
120 101/* Do not use, provided for userspace compatiblity. */
102#define fh_auth fh_base.fh_new.fb_auth
121 103
122#endif /* _UAPI_LINUX_NFSD_FH_H */ 104#endif /* _UAPI_LINUX_NFSD_FH_H */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 0f73f4507746..4ce5eccec1f6 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1503,6 +1503,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1503 if (unwrap_integ_data(rqstp, &rqstp->rq_arg, 1503 if (unwrap_integ_data(rqstp, &rqstp->rq_arg,
1504 gc->gc_seq, rsci->mechctx)) 1504 gc->gc_seq, rsci->mechctx))
1505 goto garbage_args; 1505 goto garbage_args;
1506 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE;
1506 break; 1507 break;
1507 case RPC_GSS_SVC_PRIVACY: 1508 case RPC_GSS_SVC_PRIVACY:
1508 /* placeholders for length and seq. number: */ 1509 /* placeholders for length and seq. number: */
@@ -1511,6 +1512,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1511 if (unwrap_priv_data(rqstp, &rqstp->rq_arg, 1512 if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
1512 gc->gc_seq, rsci->mechctx)) 1513 gc->gc_seq, rsci->mechctx))
1513 goto garbage_args; 1514 goto garbage_args;
1515 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2;
1514 break; 1516 break;
1515 default: 1517 default:
1516 goto auth_err; 1518 goto auth_err;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index ae333c1845bb..066362141133 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -374,7 +374,7 @@ void sunrpc_destroy_cache_detail(struct cache_detail *cd)
374 } 374 }
375 return; 375 return;
376out: 376out:
377 printk(KERN_ERR "nfsd: failed to unregister %s cache\n", cd->name); 377 printk(KERN_ERR "RPC: failed to unregister %s cache\n", cd->name);
378} 378}
379EXPORT_SYMBOL_GPL(sunrpc_destroy_cache_detail); 379EXPORT_SYMBOL_GPL(sunrpc_destroy_cache_detail);
380 380
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
index 14c9f6d1c5ff..f2b7cb540e61 100644
--- a/net/sunrpc/sunrpc.h
+++ b/net/sunrpc/sunrpc.h
@@ -43,6 +43,19 @@ static inline int rpc_reply_expected(struct rpc_task *task)
43 (task->tk_msg.rpc_proc->p_decode != NULL); 43 (task->tk_msg.rpc_proc->p_decode != NULL);
44} 44}
45 45
46static inline int sock_is_loopback(struct sock *sk)
47{
48 struct dst_entry *dst;
49 int loopback = 0;
50 rcu_read_lock();
51 dst = rcu_dereference(sk->sk_dst_cache);
52 if (dst && dst->dev &&
53 (dst->dev->features & NETIF_F_LOOPBACK))
54 loopback = 1;
55 rcu_read_unlock();
56 return loopback;
57}
58
46int svc_send_common(struct socket *sock, struct xdr_buf *xdr, 59int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
47 struct page *headpage, unsigned long headoffset, 60 struct page *headpage, unsigned long headoffset,
48 struct page *tailpage, unsigned long tailoffset); 61 struct page *tailpage, unsigned long tailoffset);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 06c6ff0cb911..b4737fbdec13 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -597,6 +597,7 @@ static int svc_alloc_arg(struct svc_rqst *rqstp)
597 } 597 }
598 rqstp->rq_pages[i] = p; 598 rqstp->rq_pages[i] = p;
599 } 599 }
600 rqstp->rq_page_end = &rqstp->rq_pages[i];
600 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ 601 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */
601 602
602 /* Make arg->head point to first page and arg->pages point to rest */ 603 /* Make arg->head point to first page and arg->pages point to rest */
@@ -730,6 +731,8 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
730 newxpt = xprt->xpt_ops->xpo_accept(xprt); 731 newxpt = xprt->xpt_ops->xpo_accept(xprt);
731 if (newxpt) 732 if (newxpt)
732 svc_add_new_temp_xprt(serv, newxpt); 733 svc_add_new_temp_xprt(serv, newxpt);
734 else
735 module_put(xprt->xpt_class->xcl_owner);
733 } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { 736 } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
734 /* XPT_DATA|XPT_DEFERRED case: */ 737 /* XPT_DATA|XPT_DEFERRED case: */
735 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", 738 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
@@ -793,7 +796,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
793 796
794 clear_bit(XPT_OLD, &xprt->xpt_flags); 797 clear_bit(XPT_OLD, &xprt->xpt_flags);
795 798
796 rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); 799 rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp);
797 rqstp->rq_chandle.defer = svc_defer; 800 rqstp->rq_chandle.defer = svc_defer;
798 801
799 if (serv->sv_stats) 802 if (serv->sv_stats)
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 2af7b0cba43a..79c0f3459b5c 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -54,6 +54,8 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
54 } 54 }
55 spin_unlock(&authtab_lock); 55 spin_unlock(&authtab_lock);
56 56
57 rqstp->rq_auth_slack = 0;
58
57 rqstp->rq_authop = aops; 59 rqstp->rq_authop = aops;
58 return aops->accept(rqstp, authp); 60 return aops->accept(rqstp, authp);
59} 61}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 43bcb4699d69..b507cd327d9b 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -400,6 +400,12 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
400 release_sock(sock->sk); 400 release_sock(sock->sk);
401#endif 401#endif
402} 402}
403
404static int svc_sock_secure_port(struct svc_rqst *rqstp)
405{
406 return svc_port_is_privileged(svc_addr(rqstp));
407}
408
403/* 409/*
404 * INET callback when data has been received on the socket. 410 * INET callback when data has been received on the socket.
405 */ 411 */
@@ -678,6 +684,7 @@ static struct svc_xprt_ops svc_udp_ops = {
678 .xpo_prep_reply_hdr = svc_udp_prep_reply_hdr, 684 .xpo_prep_reply_hdr = svc_udp_prep_reply_hdr,
679 .xpo_has_wspace = svc_udp_has_wspace, 685 .xpo_has_wspace = svc_udp_has_wspace,
680 .xpo_accept = svc_udp_accept, 686 .xpo_accept = svc_udp_accept,
687 .xpo_secure_port = svc_sock_secure_port,
681}; 688};
682 689
683static struct svc_xprt_class svc_udp_class = { 690static struct svc_xprt_class svc_udp_class = {
@@ -842,8 +849,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
842 * tell us anything. For now just warn about unpriv connections. 849 * tell us anything. For now just warn about unpriv connections.
843 */ 850 */
844 if (!svc_port_is_privileged(sin)) { 851 if (!svc_port_is_privileged(sin)) {
845 dprintk(KERN_WARNING 852 dprintk("%s: connect from unprivileged port: %s\n",
846 "%s: connect from unprivileged port: %s\n",
847 serv->sv_name, 853 serv->sv_name,
848 __svc_print_addr(sin, buf, sizeof(buf))); 854 __svc_print_addr(sin, buf, sizeof(buf)));
849 } 855 }
@@ -867,6 +873,10 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
867 } 873 }
868 svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen); 874 svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen);
869 875
876 if (sock_is_loopback(newsock->sk))
877 set_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
878 else
879 clear_bit(XPT_LOCAL, &newsvsk->sk_xprt.xpt_flags);
870 if (serv->sv_stats) 880 if (serv->sv_stats)
871 serv->sv_stats->nettcpconn++; 881 serv->sv_stats->nettcpconn++;
872 882
@@ -1112,6 +1122,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1112 1122
1113 rqstp->rq_xprt_ctxt = NULL; 1123 rqstp->rq_xprt_ctxt = NULL;
1114 rqstp->rq_prot = IPPROTO_TCP; 1124 rqstp->rq_prot = IPPROTO_TCP;
1125 rqstp->rq_local = !!test_bit(XPT_LOCAL, &svsk->sk_xprt.xpt_flags);
1115 1126
1116 p = (__be32 *)rqstp->rq_arg.head[0].iov_base; 1127 p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
1117 calldir = p[1]; 1128 calldir = p[1];
@@ -1234,6 +1245,7 @@ static struct svc_xprt_ops svc_tcp_bc_ops = {
1234 .xpo_detach = svc_bc_tcp_sock_detach, 1245 .xpo_detach = svc_bc_tcp_sock_detach,
1235 .xpo_free = svc_bc_sock_free, 1246 .xpo_free = svc_bc_sock_free,
1236 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, 1247 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
1248 .xpo_secure_port = svc_sock_secure_port,
1237}; 1249};
1238 1250
1239static struct svc_xprt_class svc_tcp_bc_class = { 1251static struct svc_xprt_class svc_tcp_bc_class = {
@@ -1272,6 +1284,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
1272 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, 1284 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
1273 .xpo_has_wspace = svc_tcp_has_wspace, 1285 .xpo_has_wspace = svc_tcp_has_wspace,
1274 .xpo_accept = svc_tcp_accept, 1286 .xpo_accept = svc_tcp_accept,
1287 .xpo_secure_port = svc_sock_secure_port,
1275}; 1288};
1276 1289
1277static struct svc_xprt_class svc_tcp_class = { 1290static struct svc_xprt_class svc_tcp_class = {
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index dd97ba3c4456..23fb4e75e245 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -462,6 +462,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
462 struct kvec *iov = buf->head; 462 struct kvec *iov = buf->head;
463 int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len; 463 int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
464 464
465 xdr_set_scratch_buffer(xdr, NULL, 0);
465 BUG_ON(scratch_len < 0); 466 BUG_ON(scratch_len < 0);
466 xdr->buf = buf; 467 xdr->buf = buf;
467 xdr->iov = iov; 468 xdr->iov = iov;
@@ -482,6 +483,73 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
482EXPORT_SYMBOL_GPL(xdr_init_encode); 483EXPORT_SYMBOL_GPL(xdr_init_encode);
483 484
484/** 485/**
486 * xdr_commit_encode - Ensure all data is written to buffer
487 * @xdr: pointer to xdr_stream
488 *
489 * We handle encoding across page boundaries by giving the caller a
490 * temporary location to write to, then later copying the data into
491 * place; xdr_commit_encode does that copying.
492 *
493 * Normally the caller doesn't need to call this directly, as the
494 * following xdr_reserve_space will do it. But an explicit call may be
495 * required at the end of encoding, or any other time when the xdr_buf
496 * data might be read.
497 */
498void xdr_commit_encode(struct xdr_stream *xdr)
499{
500 int shift = xdr->scratch.iov_len;
501 void *page;
502
503 if (shift == 0)
504 return;
505 page = page_address(*xdr->page_ptr);
506 memcpy(xdr->scratch.iov_base, page, shift);
507 memmove(page, page + shift, (void *)xdr->p - page);
508 xdr->scratch.iov_len = 0;
509}
510EXPORT_SYMBOL_GPL(xdr_commit_encode);
511
512__be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, size_t nbytes)
513{
514 static __be32 *p;
515 int space_left;
516 int frag1bytes, frag2bytes;
517
518 if (nbytes > PAGE_SIZE)
519 return NULL; /* Bigger buffers require special handling */
520 if (xdr->buf->len + nbytes > xdr->buf->buflen)
521 return NULL; /* Sorry, we're totally out of space */
522 frag1bytes = (xdr->end - xdr->p) << 2;
523 frag2bytes = nbytes - frag1bytes;
524 if (xdr->iov)
525 xdr->iov->iov_len += frag1bytes;
526 else
527 xdr->buf->page_len += frag1bytes;
528 xdr->page_ptr++;
529 xdr->iov = NULL;
530 /*
531 * If the last encode didn't end exactly on a page boundary, the
532 * next one will straddle boundaries. Encode into the next
533 * page, then copy it back later in xdr_commit_encode. We use
534 * the "scratch" iov to track any temporarily unused fragment of
535 * space at the end of the previous buffer:
536 */
537 xdr->scratch.iov_base = xdr->p;
538 xdr->scratch.iov_len = frag1bytes;
539 p = page_address(*xdr->page_ptr);
540 /*
541 * Note this is where the next encode will start after we've
542 * shifted this one back:
543 */
544 xdr->p = (void *)p + frag2bytes;
545 space_left = xdr->buf->buflen - xdr->buf->len;
546 xdr->end = (void *)p + min_t(int, space_left, PAGE_SIZE);
547 xdr->buf->page_len += frag2bytes;
548 xdr->buf->len += nbytes;
549 return p;
550}
551
552/**
485 * xdr_reserve_space - Reserve buffer space for sending 553 * xdr_reserve_space - Reserve buffer space for sending
486 * @xdr: pointer to xdr_stream 554 * @xdr: pointer to xdr_stream
487 * @nbytes: number of bytes to reserve 555 * @nbytes: number of bytes to reserve
@@ -495,20 +563,122 @@ __be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
495 __be32 *p = xdr->p; 563 __be32 *p = xdr->p;
496 __be32 *q; 564 __be32 *q;
497 565
566 xdr_commit_encode(xdr);
498 /* align nbytes on the next 32-bit boundary */ 567 /* align nbytes on the next 32-bit boundary */
499 nbytes += 3; 568 nbytes += 3;
500 nbytes &= ~3; 569 nbytes &= ~3;
501 q = p + (nbytes >> 2); 570 q = p + (nbytes >> 2);
502 if (unlikely(q > xdr->end || q < p)) 571 if (unlikely(q > xdr->end || q < p))
503 return NULL; 572 return xdr_get_next_encode_buffer(xdr, nbytes);
504 xdr->p = q; 573 xdr->p = q;
505 xdr->iov->iov_len += nbytes; 574 if (xdr->iov)
575 xdr->iov->iov_len += nbytes;
576 else
577 xdr->buf->page_len += nbytes;
506 xdr->buf->len += nbytes; 578 xdr->buf->len += nbytes;
507 return p; 579 return p;
508} 580}
509EXPORT_SYMBOL_GPL(xdr_reserve_space); 581EXPORT_SYMBOL_GPL(xdr_reserve_space);
510 582
511/** 583/**
584 * xdr_truncate_encode - truncate an encode buffer
585 * @xdr: pointer to xdr_stream
586 * @len: new length of buffer
587 *
588 * Truncates the xdr stream, so that xdr->buf->len == len,
589 * and xdr->p points at offset len from the start of the buffer, and
590 * head, tail, and page lengths are adjusted to correspond.
591 *
592 * If this means moving xdr->p to a different buffer, we assume that
593 * that the end pointer should be set to the end of the current page,
594 * except in the case of the head buffer when we assume the head
595 * buffer's current length represents the end of the available buffer.
596 *
597 * This is *not* safe to use on a buffer that already has inlined page
598 * cache pages (as in a zero-copy server read reply), except for the
599 * simple case of truncating from one position in the tail to another.
600 *
601 */
602void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
603{
604 struct xdr_buf *buf = xdr->buf;
605 struct kvec *head = buf->head;
606 struct kvec *tail = buf->tail;
607 int fraglen;
608 int new, old;
609
610 if (len > buf->len) {
611 WARN_ON_ONCE(1);
612 return;
613 }
614 xdr_commit_encode(xdr);
615
616 fraglen = min_t(int, buf->len - len, tail->iov_len);
617 tail->iov_len -= fraglen;
618 buf->len -= fraglen;
619 if (tail->iov_len && buf->len == len) {
620 xdr->p = tail->iov_base + tail->iov_len;
621 /* xdr->end, xdr->iov should be set already */
622 return;
623 }
624 WARN_ON_ONCE(fraglen);
625 fraglen = min_t(int, buf->len - len, buf->page_len);
626 buf->page_len -= fraglen;
627 buf->len -= fraglen;
628
629 new = buf->page_base + buf->page_len;
630 old = new + fraglen;
631 xdr->page_ptr -= (old >> PAGE_SHIFT) - (new >> PAGE_SHIFT);
632
633 if (buf->page_len && buf->len == len) {
634 xdr->p = page_address(*xdr->page_ptr);
635 xdr->end = (void *)xdr->p + PAGE_SIZE;
636 xdr->p = (void *)xdr->p + (new % PAGE_SIZE);
637 /* xdr->iov should already be NULL */
638 return;
639 }
640 if (fraglen) {
641 xdr->end = head->iov_base + head->iov_len;
642 xdr->page_ptr--;
643 }
644 /* (otherwise assume xdr->end is already set) */
645 head->iov_len = len;
646 buf->len = len;
647 xdr->p = head->iov_base + head->iov_len;
648 xdr->iov = buf->head;
649}
650EXPORT_SYMBOL(xdr_truncate_encode);
651
652/**
653 * xdr_restrict_buflen - decrease available buffer space
654 * @xdr: pointer to xdr_stream
655 * @newbuflen: new maximum number of bytes available
656 *
657 * Adjust our idea of how much space is available in the buffer.
658 * If we've already used too much space in the buffer, returns -1.
659 * If the available space is already smaller than newbuflen, returns 0
660 * and does nothing. Otherwise, adjusts xdr->buf->buflen to newbuflen
661 * and ensures xdr->end is set at most offset newbuflen from the start
662 * of the buffer.
663 */
664int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen)
665{
666 struct xdr_buf *buf = xdr->buf;
667 int left_in_this_buf = (void *)xdr->end - (void *)xdr->p;
668 int end_offset = buf->len + left_in_this_buf;
669
670 if (newbuflen < 0 || newbuflen < buf->len)
671 return -1;
672 if (newbuflen > buf->buflen)
673 return 0;
674 if (newbuflen < end_offset)
675 xdr->end = (void *)xdr->end + newbuflen - end_offset;
676 buf->buflen = newbuflen;
677 return 0;
678}
679EXPORT_SYMBOL(xdr_restrict_buflen);
680
681/**
512 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending 682 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending
513 * @xdr: pointer to xdr_stream 683 * @xdr: pointer to xdr_stream
514 * @pages: list of pages 684 * @pages: list of pages
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 8d904e4eef15..8f92a61ee2df 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved.
2 * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. 3 * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
@@ -69,7 +70,8 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
69 70
70 /* Set up the XDR head */ 71 /* Set up the XDR head */
71 rqstp->rq_arg.head[0].iov_base = page_address(page); 72 rqstp->rq_arg.head[0].iov_base = page_address(page);
72 rqstp->rq_arg.head[0].iov_len = min(byte_count, ctxt->sge[0].length); 73 rqstp->rq_arg.head[0].iov_len =
74 min_t(size_t, byte_count, ctxt->sge[0].length);
73 rqstp->rq_arg.len = byte_count; 75 rqstp->rq_arg.len = byte_count;
74 rqstp->rq_arg.buflen = byte_count; 76 rqstp->rq_arg.buflen = byte_count;
75 77
@@ -85,7 +87,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
85 page = ctxt->pages[sge_no]; 87 page = ctxt->pages[sge_no];
86 put_page(rqstp->rq_pages[sge_no]); 88 put_page(rqstp->rq_pages[sge_no]);
87 rqstp->rq_pages[sge_no] = page; 89 rqstp->rq_pages[sge_no] = page;
88 bc -= min(bc, ctxt->sge[sge_no].length); 90 bc -= min_t(u32, bc, ctxt->sge[sge_no].length);
89 rqstp->rq_arg.buflen += ctxt->sge[sge_no].length; 91 rqstp->rq_arg.buflen += ctxt->sge[sge_no].length;
90 sge_no++; 92 sge_no++;
91 } 93 }
@@ -113,291 +115,265 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
113 rqstp->rq_arg.tail[0].iov_len = 0; 115 rqstp->rq_arg.tail[0].iov_len = 0;
114} 116}
115 117
116/* Encode a read-chunk-list as an array of IB SGE 118static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
117 *
118 * Assumptions:
119 * - chunk[0]->position points to pages[0] at an offset of 0
120 * - pages[] is not physically or virtually contiguous and consists of
121 * PAGE_SIZE elements.
122 *
123 * Output:
124 * - sge array pointing into pages[] array.
125 * - chunk_sge array specifying sge index and count for each
126 * chunk in the read list
127 *
128 */
129static int map_read_chunks(struct svcxprt_rdma *xprt,
130 struct svc_rqst *rqstp,
131 struct svc_rdma_op_ctxt *head,
132 struct rpcrdma_msg *rmsgp,
133 struct svc_rdma_req_map *rpl_map,
134 struct svc_rdma_req_map *chl_map,
135 int ch_count,
136 int byte_count)
137{ 119{
138 int sge_no; 120 if (rdma_node_get_transport(xprt->sc_cm_id->device->node_type) ==
139 int sge_bytes; 121 RDMA_TRANSPORT_IWARP)
140 int page_off; 122 return 1;
141 int page_no; 123 else
142 int ch_bytes; 124 return min_t(int, sge_count, xprt->sc_max_sge);
143 int ch_no; 125}
144 struct rpcrdma_read_chunk *ch;
145 126
146 sge_no = 0; 127typedef int (*rdma_reader_fn)(struct svcxprt_rdma *xprt,
147 page_no = 0; 128 struct svc_rqst *rqstp,
148 page_off = 0; 129 struct svc_rdma_op_ctxt *head,
149 ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; 130 int *page_no,
150 ch_no = 0; 131 u32 *page_offset,
151 ch_bytes = ntohl(ch->rc_target.rs_length); 132 u32 rs_handle,
152 head->arg.head[0] = rqstp->rq_arg.head[0]; 133 u32 rs_length,
153 head->arg.tail[0] = rqstp->rq_arg.tail[0]; 134 u64 rs_offset,
154 head->arg.pages = &head->pages[head->count]; 135 int last);
155 head->hdr_count = head->count; /* save count of hdr pages */ 136
156 head->arg.page_base = 0; 137/* Issue an RDMA_READ using the local lkey to map the data sink */
157 head->arg.page_len = ch_bytes; 138static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
158 head->arg.len = rqstp->rq_arg.len + ch_bytes; 139 struct svc_rqst *rqstp,
159 head->arg.buflen = rqstp->rq_arg.buflen + ch_bytes; 140 struct svc_rdma_op_ctxt *head,
160 head->count++; 141 int *page_no,
161 chl_map->ch[0].start = 0; 142 u32 *page_offset,
162 while (byte_count) { 143 u32 rs_handle,
163 rpl_map->sge[sge_no].iov_base = 144 u32 rs_length,
164 page_address(rqstp->rq_arg.pages[page_no]) + page_off; 145 u64 rs_offset,
165 sge_bytes = min_t(int, PAGE_SIZE-page_off, ch_bytes); 146 int last)
166 rpl_map->sge[sge_no].iov_len = sge_bytes; 147{
167 /* 148 struct ib_send_wr read_wr;
168 * Don't bump head->count here because the same page 149 int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT;
169 * may be used by multiple SGE. 150 struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt);
170 */ 151 int ret, read, pno;
171 head->arg.pages[page_no] = rqstp->rq_arg.pages[page_no]; 152 u32 pg_off = *page_offset;
172 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no+1]; 153 u32 pg_no = *page_no;
154
155 ctxt->direction = DMA_FROM_DEVICE;
156 ctxt->read_hdr = head;
157 pages_needed =
158 min_t(int, pages_needed, rdma_read_max_sge(xprt, pages_needed));
159 read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
160
161 for (pno = 0; pno < pages_needed; pno++) {
162 int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
163
164 head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no];
165 head->arg.page_len += len;
166 head->arg.len += len;
167 if (!pg_off)
168 head->count++;
169 rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1];
173 rqstp->rq_next_page = rqstp->rq_respages + 1; 170 rqstp->rq_next_page = rqstp->rq_respages + 1;
171 ctxt->sge[pno].addr =
172 ib_dma_map_page(xprt->sc_cm_id->device,
173 head->arg.pages[pg_no], pg_off,
174 PAGE_SIZE - pg_off,
175 DMA_FROM_DEVICE);
176 ret = ib_dma_mapping_error(xprt->sc_cm_id->device,
177 ctxt->sge[pno].addr);
178 if (ret)
179 goto err;
180 atomic_inc(&xprt->sc_dma_used);
174 181
175 byte_count -= sge_bytes; 182 /* The lkey here is either a local dma lkey or a dma_mr lkey */
176 ch_bytes -= sge_bytes; 183 ctxt->sge[pno].lkey = xprt->sc_dma_lkey;
177 sge_no++; 184 ctxt->sge[pno].length = len;
178 /* 185 ctxt->count++;
179 * If all bytes for this chunk have been mapped to an 186
180 * SGE, move to the next SGE 187 /* adjust offset and wrap to next page if needed */
181 */ 188 pg_off += len;
182 if (ch_bytes == 0) { 189 if (pg_off == PAGE_SIZE) {
183 chl_map->ch[ch_no].count = 190 pg_off = 0;
184 sge_no - chl_map->ch[ch_no].start; 191 pg_no++;
185 ch_no++;
186 ch++;
187 chl_map->ch[ch_no].start = sge_no;
188 ch_bytes = ntohl(ch->rc_target.rs_length);
189 /* If bytes remaining account for next chunk */
190 if (byte_count) {
191 head->arg.page_len += ch_bytes;
192 head->arg.len += ch_bytes;
193 head->arg.buflen += ch_bytes;
194 }
195 } 192 }
196 /* 193 rs_length -= len;
197 * If this SGE consumed all of the page, move to the
198 * next page
199 */
200 if ((sge_bytes + page_off) == PAGE_SIZE) {
201 page_no++;
202 page_off = 0;
203 /*
204 * If there are still bytes left to map, bump
205 * the page count
206 */
207 if (byte_count)
208 head->count++;
209 } else
210 page_off += sge_bytes;
211 } 194 }
212 BUG_ON(byte_count != 0); 195
213 return sge_no; 196 if (last && rs_length == 0)
197 set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
198 else
199 clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
200
201 memset(&read_wr, 0, sizeof(read_wr));
202 read_wr.wr_id = (unsigned long)ctxt;
203 read_wr.opcode = IB_WR_RDMA_READ;
204 ctxt->wr_op = read_wr.opcode;
205 read_wr.send_flags = IB_SEND_SIGNALED;
206 read_wr.wr.rdma.rkey = rs_handle;
207 read_wr.wr.rdma.remote_addr = rs_offset;
208 read_wr.sg_list = ctxt->sge;
209 read_wr.num_sge = pages_needed;
210
211 ret = svc_rdma_send(xprt, &read_wr);
212 if (ret) {
213 pr_err("svcrdma: Error %d posting RDMA_READ\n", ret);
214 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
215 goto err;
216 }
217
218 /* return current location in page array */
219 *page_no = pg_no;
220 *page_offset = pg_off;
221 ret = read;
222 atomic_inc(&rdma_stat_read);
223 return ret;
224 err:
225 svc_rdma_unmap_dma(ctxt);
226 svc_rdma_put_context(ctxt, 0);
227 return ret;
214} 228}
215 229
216/* Map a read-chunk-list to an XDR and fast register the page-list. 230/* Issue an RDMA_READ using an FRMR to map the data sink */
217 * 231static int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
218 * Assumptions:
219 * - chunk[0] position points to pages[0] at an offset of 0
220 * - pages[] will be made physically contiguous by creating a one-off memory
221 * region using the fastreg verb.
222 * - byte_count is # of bytes in read-chunk-list
223 * - ch_count is # of chunks in read-chunk-list
224 *
225 * Output:
226 * - sge array pointing into pages[] array.
227 * - chunk_sge array specifying sge index and count for each
228 * chunk in the read list
229 */
230static int fast_reg_read_chunks(struct svcxprt_rdma *xprt,
231 struct svc_rqst *rqstp, 232 struct svc_rqst *rqstp,
232 struct svc_rdma_op_ctxt *head, 233 struct svc_rdma_op_ctxt *head,
233 struct rpcrdma_msg *rmsgp, 234 int *page_no,
234 struct svc_rdma_req_map *rpl_map, 235 u32 *page_offset,
235 struct svc_rdma_req_map *chl_map, 236 u32 rs_handle,
236 int ch_count, 237 u32 rs_length,
237 int byte_count) 238 u64 rs_offset,
239 int last)
238{ 240{
239 int page_no; 241 struct ib_send_wr read_wr;
240 int ch_no; 242 struct ib_send_wr inv_wr;
241 u32 offset; 243 struct ib_send_wr fastreg_wr;
242 struct rpcrdma_read_chunk *ch; 244 u8 key;
243 struct svc_rdma_fastreg_mr *frmr; 245 int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT;
244 int ret = 0; 246 struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt);
247 struct svc_rdma_fastreg_mr *frmr = svc_rdma_get_frmr(xprt);
248 int ret, read, pno;
249 u32 pg_off = *page_offset;
250 u32 pg_no = *page_no;
245 251
246 frmr = svc_rdma_get_frmr(xprt);
247 if (IS_ERR(frmr)) 252 if (IS_ERR(frmr))
248 return -ENOMEM; 253 return -ENOMEM;
249 254
250 head->frmr = frmr; 255 ctxt->direction = DMA_FROM_DEVICE;
251 head->arg.head[0] = rqstp->rq_arg.head[0]; 256 ctxt->frmr = frmr;
252 head->arg.tail[0] = rqstp->rq_arg.tail[0]; 257 pages_needed = min_t(int, pages_needed, xprt->sc_frmr_pg_list_len);
253 head->arg.pages = &head->pages[head->count]; 258 read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
254 head->hdr_count = head->count; /* save count of hdr pages */
255 head->arg.page_base = 0;
256 head->arg.page_len = byte_count;
257 head->arg.len = rqstp->rq_arg.len + byte_count;
258 head->arg.buflen = rqstp->rq_arg.buflen + byte_count;
259 259
260 /* Fast register the page list */ 260 frmr->kva = page_address(rqstp->rq_arg.pages[pg_no]);
261 frmr->kva = page_address(rqstp->rq_arg.pages[0]);
262 frmr->direction = DMA_FROM_DEVICE; 261 frmr->direction = DMA_FROM_DEVICE;
263 frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE); 262 frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE);
264 frmr->map_len = byte_count; 263 frmr->map_len = pages_needed << PAGE_SHIFT;
265 frmr->page_list_len = PAGE_ALIGN(byte_count) >> PAGE_SHIFT; 264 frmr->page_list_len = pages_needed;
266 for (page_no = 0; page_no < frmr->page_list_len; page_no++) { 265
267 frmr->page_list->page_list[page_no] = 266 for (pno = 0; pno < pages_needed; pno++) {
267 int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
268
269 head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no];
270 head->arg.page_len += len;
271 head->arg.len += len;
272 if (!pg_off)
273 head->count++;
274 rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1];
275 rqstp->rq_next_page = rqstp->rq_respages + 1;
276 frmr->page_list->page_list[pno] =
268 ib_dma_map_page(xprt->sc_cm_id->device, 277 ib_dma_map_page(xprt->sc_cm_id->device,
269 rqstp->rq_arg.pages[page_no], 0, 278 head->arg.pages[pg_no], 0,
270 PAGE_SIZE, DMA_FROM_DEVICE); 279 PAGE_SIZE, DMA_FROM_DEVICE);
271 if (ib_dma_mapping_error(xprt->sc_cm_id->device, 280 ret = ib_dma_mapping_error(xprt->sc_cm_id->device,
272 frmr->page_list->page_list[page_no])) 281 frmr->page_list->page_list[pno]);
273 goto fatal_err; 282 if (ret)
283 goto err;
274 atomic_inc(&xprt->sc_dma_used); 284 atomic_inc(&xprt->sc_dma_used);
275 head->arg.pages[page_no] = rqstp->rq_arg.pages[page_no];
276 }
277 head->count += page_no;
278
279 /* rq_respages points one past arg pages */
280 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
281 rqstp->rq_next_page = rqstp->rq_respages + 1;
282 285
283 /* Create the reply and chunk maps */ 286 /* adjust offset and wrap to next page if needed */
284 offset = 0; 287 pg_off += len;
285 ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; 288 if (pg_off == PAGE_SIZE) {
286 for (ch_no = 0; ch_no < ch_count; ch_no++) { 289 pg_off = 0;
287 int len = ntohl(ch->rc_target.rs_length); 290 pg_no++;
288 rpl_map->sge[ch_no].iov_base = frmr->kva + offset; 291 }
289 rpl_map->sge[ch_no].iov_len = len; 292 rs_length -= len;
290 chl_map->ch[ch_no].count = 1;
291 chl_map->ch[ch_no].start = ch_no;
292 offset += len;
293 ch++;
294 } 293 }
295 294
296 ret = svc_rdma_fastreg(xprt, frmr); 295 if (last && rs_length == 0)
297 if (ret) 296 set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
298 goto fatal_err; 297 else
299 298 clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
300 return ch_no;
301
302 fatal_err:
303 printk("svcrdma: error fast registering xdr for xprt %p", xprt);
304 svc_rdma_put_frmr(xprt, frmr);
305 return -EIO;
306}
307
308static int rdma_set_ctxt_sge(struct svcxprt_rdma *xprt,
309 struct svc_rdma_op_ctxt *ctxt,
310 struct svc_rdma_fastreg_mr *frmr,
311 struct kvec *vec,
312 u64 *sgl_offset,
313 int count)
314{
315 int i;
316 unsigned long off;
317 299
318 ctxt->count = count; 300 /* Bump the key */
319 ctxt->direction = DMA_FROM_DEVICE; 301 key = (u8)(frmr->mr->lkey & 0x000000FF);
320 for (i = 0; i < count; i++) { 302 ib_update_fast_reg_key(frmr->mr, ++key);
321 ctxt->sge[i].length = 0; /* in case map fails */ 303
322 if (!frmr) { 304 ctxt->sge[0].addr = (unsigned long)frmr->kva + *page_offset;
323 BUG_ON(!virt_to_page(vec[i].iov_base)); 305 ctxt->sge[0].lkey = frmr->mr->lkey;
324 off = (unsigned long)vec[i].iov_base & ~PAGE_MASK; 306 ctxt->sge[0].length = read;
325 ctxt->sge[i].addr = 307 ctxt->count = 1;
326 ib_dma_map_page(xprt->sc_cm_id->device, 308 ctxt->read_hdr = head;
327 virt_to_page(vec[i].iov_base), 309
328 off, 310 /* Prepare FASTREG WR */
329 vec[i].iov_len, 311 memset(&fastreg_wr, 0, sizeof(fastreg_wr));
330 DMA_FROM_DEVICE); 312 fastreg_wr.opcode = IB_WR_FAST_REG_MR;
331 if (ib_dma_mapping_error(xprt->sc_cm_id->device, 313 fastreg_wr.send_flags = IB_SEND_SIGNALED;
332 ctxt->sge[i].addr)) 314 fastreg_wr.wr.fast_reg.iova_start = (unsigned long)frmr->kva;
333 return -EINVAL; 315 fastreg_wr.wr.fast_reg.page_list = frmr->page_list;
334 ctxt->sge[i].lkey = xprt->sc_dma_lkey; 316 fastreg_wr.wr.fast_reg.page_list_len = frmr->page_list_len;
335 atomic_inc(&xprt->sc_dma_used); 317 fastreg_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
336 } else { 318 fastreg_wr.wr.fast_reg.length = frmr->map_len;
337 ctxt->sge[i].addr = (unsigned long)vec[i].iov_base; 319 fastreg_wr.wr.fast_reg.access_flags = frmr->access_flags;
338 ctxt->sge[i].lkey = frmr->mr->lkey; 320 fastreg_wr.wr.fast_reg.rkey = frmr->mr->lkey;
339 } 321 fastreg_wr.next = &read_wr;
340 ctxt->sge[i].length = vec[i].iov_len; 322
341 *sgl_offset = *sgl_offset + vec[i].iov_len; 323 /* Prepare RDMA_READ */
324 memset(&read_wr, 0, sizeof(read_wr));
325 read_wr.send_flags = IB_SEND_SIGNALED;
326 read_wr.wr.rdma.rkey = rs_handle;
327 read_wr.wr.rdma.remote_addr = rs_offset;
328 read_wr.sg_list = ctxt->sge;
329 read_wr.num_sge = 1;
330 if (xprt->sc_dev_caps & SVCRDMA_DEVCAP_READ_W_INV) {
331 read_wr.opcode = IB_WR_RDMA_READ_WITH_INV;
332 read_wr.wr_id = (unsigned long)ctxt;
333 read_wr.ex.invalidate_rkey = ctxt->frmr->mr->lkey;
334 } else {
335 read_wr.opcode = IB_WR_RDMA_READ;
336 read_wr.next = &inv_wr;
337 /* Prepare invalidate */
338 memset(&inv_wr, 0, sizeof(inv_wr));
339 inv_wr.wr_id = (unsigned long)ctxt;
340 inv_wr.opcode = IB_WR_LOCAL_INV;
341 inv_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_FENCE;
342 inv_wr.ex.invalidate_rkey = frmr->mr->lkey;
343 }
344 ctxt->wr_op = read_wr.opcode;
345
346 /* Post the chain */
347 ret = svc_rdma_send(xprt, &fastreg_wr);
348 if (ret) {
349 pr_err("svcrdma: Error %d posting RDMA_READ\n", ret);
350 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
351 goto err;
342 } 352 }
343 return 0;
344}
345 353
346static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) 354 /* return current location in page array */
347{ 355 *page_no = pg_no;
348 if ((rdma_node_get_transport(xprt->sc_cm_id->device->node_type) == 356 *page_offset = pg_off;
349 RDMA_TRANSPORT_IWARP) && 357 ret = read;
350 sge_count > 1) 358 atomic_inc(&rdma_stat_read);
351 return 1; 359 return ret;
352 else 360 err:
353 return min_t(int, sge_count, xprt->sc_max_sge); 361 svc_rdma_unmap_dma(ctxt);
362 svc_rdma_put_context(ctxt, 0);
363 svc_rdma_put_frmr(xprt, frmr);
364 return ret;
354} 365}
355 366
356/* 367static int rdma_read_chunks(struct svcxprt_rdma *xprt,
357 * Use RDMA_READ to read data from the advertised client buffer into the 368 struct rpcrdma_msg *rmsgp,
358 * XDR stream starting at rq_arg.head[0].iov_base. 369 struct svc_rqst *rqstp,
359 * Each chunk in the array 370 struct svc_rdma_op_ctxt *head)
360 * contains the following fields:
361 * discrim - '1', This isn't used for data placement
362 * position - The xdr stream offset (the same for every chunk)
363 * handle - RMR for client memory region
364 * length - data transfer length
365 * offset - 64 bit tagged offset in remote memory region
366 *
367 * On our side, we need to read into a pagelist. The first page immediately
368 * follows the RPC header.
369 *
370 * This function returns:
371 * 0 - No error and no read-list found.
372 *
373 * 1 - Successful read-list processing. The data is not yet in
374 * the pagelist and therefore the RPC request must be deferred. The
375 * I/O completion will enqueue the transport again and
376 * svc_rdma_recvfrom will complete the request.
377 *
378 * <0 - Error processing/posting read-list.
379 *
380 * NOTE: The ctxt must not be touched after the last WR has been posted
381 * because the I/O completion processing may occur on another
382 * processor and free / modify the context. Ne touche pas!
383 */
384static int rdma_read_xdr(struct svcxprt_rdma *xprt,
385 struct rpcrdma_msg *rmsgp,
386 struct svc_rqst *rqstp,
387 struct svc_rdma_op_ctxt *hdr_ctxt)
388{ 371{
389 struct ib_send_wr read_wr; 372 int page_no, ch_count, ret;
390 struct ib_send_wr inv_wr;
391 int err = 0;
392 int ch_no;
393 int ch_count;
394 int byte_count;
395 int sge_count;
396 u64 sgl_offset;
397 struct rpcrdma_read_chunk *ch; 373 struct rpcrdma_read_chunk *ch;
398 struct svc_rdma_op_ctxt *ctxt = NULL; 374 u32 page_offset, byte_count;
399 struct svc_rdma_req_map *rpl_map; 375 u64 rs_offset;
400 struct svc_rdma_req_map *chl_map; 376 rdma_reader_fn reader;
401 377
402 /* If no read list is present, return 0 */ 378 /* If no read list is present, return 0 */
403 ch = svc_rdma_get_read_chunk(rmsgp); 379 ch = svc_rdma_get_read_chunk(rmsgp);
@@ -408,122 +384,55 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
408 if (ch_count > RPCSVC_MAXPAGES) 384 if (ch_count > RPCSVC_MAXPAGES)
409 return -EINVAL; 385 return -EINVAL;
410 386
411 /* Allocate temporary reply and chunk maps */ 387 /* The request is completed when the RDMA_READs complete. The
412 rpl_map = svc_rdma_get_req_map(); 388 * head context keeps all the pages that comprise the
413 chl_map = svc_rdma_get_req_map(); 389 * request.
390 */
391 head->arg.head[0] = rqstp->rq_arg.head[0];
392 head->arg.tail[0] = rqstp->rq_arg.tail[0];
393 head->arg.pages = &head->pages[head->count];
394 head->hdr_count = head->count;
395 head->arg.page_base = 0;
396 head->arg.page_len = 0;
397 head->arg.len = rqstp->rq_arg.len;
398 head->arg.buflen = rqstp->rq_arg.buflen;
414 399
415 if (!xprt->sc_frmr_pg_list_len) 400 /* Use FRMR if supported */
416 sge_count = map_read_chunks(xprt, rqstp, hdr_ctxt, rmsgp, 401 if (xprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)
417 rpl_map, chl_map, ch_count, 402 reader = rdma_read_chunk_frmr;
418 byte_count);
419 else 403 else
420 sge_count = fast_reg_read_chunks(xprt, rqstp, hdr_ctxt, rmsgp, 404 reader = rdma_read_chunk_lcl;
421 rpl_map, chl_map, ch_count,
422 byte_count);
423 if (sge_count < 0) {
424 err = -EIO;
425 goto out;
426 }
427
428 sgl_offset = 0;
429 ch_no = 0;
430 405
406 page_no = 0; page_offset = 0;
431 for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; 407 for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
432 ch->rc_discrim != 0; ch++, ch_no++) { 408 ch->rc_discrim != 0; ch++) {
433 u64 rs_offset;
434next_sge:
435 ctxt = svc_rdma_get_context(xprt);
436 ctxt->direction = DMA_FROM_DEVICE;
437 ctxt->frmr = hdr_ctxt->frmr;
438 ctxt->read_hdr = NULL;
439 clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
440 clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
441 409
442 /* Prepare READ WR */
443 memset(&read_wr, 0, sizeof read_wr);
444 read_wr.wr_id = (unsigned long)ctxt;
445 read_wr.opcode = IB_WR_RDMA_READ;
446 ctxt->wr_op = read_wr.opcode;
447 read_wr.send_flags = IB_SEND_SIGNALED;
448 read_wr.wr.rdma.rkey = ntohl(ch->rc_target.rs_handle);
449 xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset, 410 xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset,
450 &rs_offset); 411 &rs_offset);
451 read_wr.wr.rdma.remote_addr = rs_offset + sgl_offset; 412 byte_count = ntohl(ch->rc_target.rs_length);
452 read_wr.sg_list = ctxt->sge; 413
453 read_wr.num_sge = 414 while (byte_count > 0) {
454 rdma_read_max_sge(xprt, chl_map->ch[ch_no].count); 415 ret = reader(xprt, rqstp, head,
455 err = rdma_set_ctxt_sge(xprt, ctxt, hdr_ctxt->frmr, 416 &page_no, &page_offset,
456 &rpl_map->sge[chl_map->ch[ch_no].start], 417 ntohl(ch->rc_target.rs_handle),
457 &sgl_offset, 418 byte_count, rs_offset,
458 read_wr.num_sge); 419 ((ch+1)->rc_discrim == 0) /* last */
459 if (err) { 420 );
460 svc_rdma_unmap_dma(ctxt); 421 if (ret < 0)
461 svc_rdma_put_context(ctxt, 0); 422 goto err;
462 goto out; 423 byte_count -= ret;
463 } 424 rs_offset += ret;
464 if (((ch+1)->rc_discrim == 0) && 425 head->arg.buflen += ret;
465 (read_wr.num_sge == chl_map->ch[ch_no].count)) {
466 /*
467 * Mark the last RDMA_READ with a bit to
468 * indicate all RPC data has been fetched from
469 * the client and the RPC needs to be enqueued.
470 */
471 set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
472 if (hdr_ctxt->frmr) {
473 set_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
474 /*
475 * Invalidate the local MR used to map the data
476 * sink.
477 */
478 if (xprt->sc_dev_caps &
479 SVCRDMA_DEVCAP_READ_W_INV) {
480 read_wr.opcode =
481 IB_WR_RDMA_READ_WITH_INV;
482 ctxt->wr_op = read_wr.opcode;
483 read_wr.ex.invalidate_rkey =
484 ctxt->frmr->mr->lkey;
485 } else {
486 /* Prepare INVALIDATE WR */
487 memset(&inv_wr, 0, sizeof inv_wr);
488 inv_wr.opcode = IB_WR_LOCAL_INV;
489 inv_wr.send_flags = IB_SEND_SIGNALED;
490 inv_wr.ex.invalidate_rkey =
491 hdr_ctxt->frmr->mr->lkey;
492 read_wr.next = &inv_wr;
493 }
494 }
495 ctxt->read_hdr = hdr_ctxt;
496 }
497 /* Post the read */
498 err = svc_rdma_send(xprt, &read_wr);
499 if (err) {
500 printk(KERN_ERR "svcrdma: Error %d posting RDMA_READ\n",
501 err);
502 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
503 svc_rdma_unmap_dma(ctxt);
504 svc_rdma_put_context(ctxt, 0);
505 goto out;
506 } 426 }
507 atomic_inc(&rdma_stat_read);
508
509 if (read_wr.num_sge < chl_map->ch[ch_no].count) {
510 chl_map->ch[ch_no].count -= read_wr.num_sge;
511 chl_map->ch[ch_no].start += read_wr.num_sge;
512 goto next_sge;
513 }
514 sgl_offset = 0;
515 err = 1;
516 } 427 }
517 428 ret = 1;
518 out: 429 err:
519 svc_rdma_put_req_map(rpl_map);
520 svc_rdma_put_req_map(chl_map);
521
522 /* Detach arg pages. svc_recv will replenish them */ 430 /* Detach arg pages. svc_recv will replenish them */
523 for (ch_no = 0; &rqstp->rq_pages[ch_no] < rqstp->rq_respages; ch_no++) 431 for (page_no = 0;
524 rqstp->rq_pages[ch_no] = NULL; 432 &rqstp->rq_pages[page_no] < rqstp->rq_respages; page_no++)
433 rqstp->rq_pages[page_no] = NULL;
525 434
526 return err; 435 return ret;
527} 436}
528 437
529static int rdma_read_complete(struct svc_rqst *rqstp, 438static int rdma_read_complete(struct svc_rqst *rqstp,
@@ -595,13 +504,9 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
595 struct svc_rdma_op_ctxt, 504 struct svc_rdma_op_ctxt,
596 dto_q); 505 dto_q);
597 list_del_init(&ctxt->dto_q); 506 list_del_init(&ctxt->dto_q);
598 }
599 if (ctxt) {
600 spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock); 507 spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock);
601 return rdma_read_complete(rqstp, ctxt); 508 return rdma_read_complete(rqstp, ctxt);
602 } 509 } else if (!list_empty(&rdma_xprt->sc_rq_dto_q)) {
603
604 if (!list_empty(&rdma_xprt->sc_rq_dto_q)) {
605 ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next, 510 ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next,
606 struct svc_rdma_op_ctxt, 511 struct svc_rdma_op_ctxt,
607 dto_q); 512 dto_q);
@@ -621,7 +526,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
621 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) 526 if (test_bit(XPT_CLOSE, &xprt->xpt_flags))
622 goto close_out; 527 goto close_out;
623 528
624 BUG_ON(ret);
625 goto out; 529 goto out;
626 } 530 }
627 dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p, status=%d\n", 531 dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p, status=%d\n",
@@ -644,12 +548,11 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
644 } 548 }
645 549
646 /* Read read-list data. */ 550 /* Read read-list data. */
647 ret = rdma_read_xdr(rdma_xprt, rmsgp, rqstp, ctxt); 551 ret = rdma_read_chunks(rdma_xprt, rmsgp, rqstp, ctxt);
648 if (ret > 0) { 552 if (ret > 0) {
649 /* read-list posted, defer until data received from client. */ 553 /* read-list posted, defer until data received from client. */
650 goto defer; 554 goto defer;
651 } 555 } else if (ret < 0) {
652 if (ret < 0) {
653 /* Post of read-list failed, free context. */ 556 /* Post of read-list failed, free context. */
654 svc_rdma_put_context(ctxt, 1); 557 svc_rdma_put_context(ctxt, 1);
655 return 0; 558 return 0;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 7e024a51617e..49fd21a5c215 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved.
2 * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. 3 * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
@@ -49,152 +50,6 @@
49 50
50#define RPCDBG_FACILITY RPCDBG_SVCXPRT 51#define RPCDBG_FACILITY RPCDBG_SVCXPRT
51 52
52/* Encode an XDR as an array of IB SGE
53 *
54 * Assumptions:
55 * - head[0] is physically contiguous.
56 * - tail[0] is physically contiguous.
57 * - pages[] is not physically or virtually contiguous and consists of
58 * PAGE_SIZE elements.
59 *
60 * Output:
61 * SGE[0] reserved for RCPRDMA header
62 * SGE[1] data from xdr->head[]
63 * SGE[2..sge_count-2] data from xdr->pages[]
64 * SGE[sge_count-1] data from xdr->tail.
65 *
66 * The max SGE we need is the length of the XDR / pagesize + one for
67 * head + one for tail + one for RPCRDMA header. Since RPCSVC_MAXPAGES
68 * reserves a page for both the request and the reply header, and this
69 * array is only concerned with the reply we are assured that we have
70 * on extra page for the RPCRMDA header.
71 */
72static int fast_reg_xdr(struct svcxprt_rdma *xprt,
73 struct xdr_buf *xdr,
74 struct svc_rdma_req_map *vec)
75{
76 int sge_no;
77 u32 sge_bytes;
78 u32 page_bytes;
79 u32 page_off;
80 int page_no = 0;
81 u8 *frva;
82 struct svc_rdma_fastreg_mr *frmr;
83
84 frmr = svc_rdma_get_frmr(xprt);
85 if (IS_ERR(frmr))
86 return -ENOMEM;
87 vec->frmr = frmr;
88
89 /* Skip the RPCRDMA header */
90 sge_no = 1;
91
92 /* Map the head. */
93 frva = (void *)((unsigned long)(xdr->head[0].iov_base) & PAGE_MASK);
94 vec->sge[sge_no].iov_base = xdr->head[0].iov_base;
95 vec->sge[sge_no].iov_len = xdr->head[0].iov_len;
96 vec->count = 2;
97 sge_no++;
98
99 /* Map the XDR head */
100 frmr->kva = frva;
101 frmr->direction = DMA_TO_DEVICE;
102 frmr->access_flags = 0;
103 frmr->map_len = PAGE_SIZE;
104 frmr->page_list_len = 1;
105 page_off = (unsigned long)xdr->head[0].iov_base & ~PAGE_MASK;
106 frmr->page_list->page_list[page_no] =
107 ib_dma_map_page(xprt->sc_cm_id->device,
108 virt_to_page(xdr->head[0].iov_base),
109 page_off,
110 PAGE_SIZE - page_off,
111 DMA_TO_DEVICE);
112 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
113 frmr->page_list->page_list[page_no]))
114 goto fatal_err;
115 atomic_inc(&xprt->sc_dma_used);
116
117 /* Map the XDR page list */
118 page_off = xdr->page_base;
119 page_bytes = xdr->page_len + page_off;
120 if (!page_bytes)
121 goto encode_tail;
122
123 /* Map the pages */
124 vec->sge[sge_no].iov_base = frva + frmr->map_len + page_off;
125 vec->sge[sge_no].iov_len = page_bytes;
126 sge_no++;
127 while (page_bytes) {
128 struct page *page;
129
130 page = xdr->pages[page_no++];
131 sge_bytes = min_t(u32, page_bytes, (PAGE_SIZE - page_off));
132 page_bytes -= sge_bytes;
133
134 frmr->page_list->page_list[page_no] =
135 ib_dma_map_page(xprt->sc_cm_id->device,
136 page, page_off,
137 sge_bytes, DMA_TO_DEVICE);
138 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
139 frmr->page_list->page_list[page_no]))
140 goto fatal_err;
141
142 atomic_inc(&xprt->sc_dma_used);
143 page_off = 0; /* reset for next time through loop */
144 frmr->map_len += PAGE_SIZE;
145 frmr->page_list_len++;
146 }
147 vec->count++;
148
149 encode_tail:
150 /* Map tail */
151 if (0 == xdr->tail[0].iov_len)
152 goto done;
153
154 vec->count++;
155 vec->sge[sge_no].iov_len = xdr->tail[0].iov_len;
156
157 if (((unsigned long)xdr->tail[0].iov_base & PAGE_MASK) ==
158 ((unsigned long)xdr->head[0].iov_base & PAGE_MASK)) {
159 /*
160 * If head and tail use the same page, we don't need
161 * to map it again.
162 */
163 vec->sge[sge_no].iov_base = xdr->tail[0].iov_base;
164 } else {
165 void *va;
166
167 /* Map another page for the tail */
168 page_off = (unsigned long)xdr->tail[0].iov_base & ~PAGE_MASK;
169 va = (void *)((unsigned long)xdr->tail[0].iov_base & PAGE_MASK);
170 vec->sge[sge_no].iov_base = frva + frmr->map_len + page_off;
171
172 frmr->page_list->page_list[page_no] =
173 ib_dma_map_page(xprt->sc_cm_id->device, virt_to_page(va),
174 page_off,
175 PAGE_SIZE,
176 DMA_TO_DEVICE);
177 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
178 frmr->page_list->page_list[page_no]))
179 goto fatal_err;
180 atomic_inc(&xprt->sc_dma_used);
181 frmr->map_len += PAGE_SIZE;
182 frmr->page_list_len++;
183 }
184
185 done:
186 if (svc_rdma_fastreg(xprt, frmr))
187 goto fatal_err;
188
189 return 0;
190
191 fatal_err:
192 printk("svcrdma: Error fast registering memory for xprt %p\n", xprt);
193 vec->frmr = NULL;
194 svc_rdma_put_frmr(xprt, frmr);
195 return -EIO;
196}
197
198static int map_xdr(struct svcxprt_rdma *xprt, 53static int map_xdr(struct svcxprt_rdma *xprt,
199 struct xdr_buf *xdr, 54 struct xdr_buf *xdr,
200 struct svc_rdma_req_map *vec) 55 struct svc_rdma_req_map *vec)
@@ -208,9 +63,6 @@ static int map_xdr(struct svcxprt_rdma *xprt,
208 BUG_ON(xdr->len != 63 BUG_ON(xdr->len !=
209 (xdr->head[0].iov_len + xdr->page_len + xdr->tail[0].iov_len)); 64 (xdr->head[0].iov_len + xdr->page_len + xdr->tail[0].iov_len));
210 65
211 if (xprt->sc_frmr_pg_list_len)
212 return fast_reg_xdr(xprt, xdr, vec);
213
214 /* Skip the first sge, this is for the RPCRDMA header */ 66 /* Skip the first sge, this is for the RPCRDMA header */
215 sge_no = 1; 67 sge_no = 1;
216 68
@@ -282,8 +134,6 @@ static dma_addr_t dma_map_xdr(struct svcxprt_rdma *xprt,
282} 134}
283 135
284/* Assumptions: 136/* Assumptions:
285 * - We are using FRMR
286 * - or -
287 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE 137 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE
288 */ 138 */
289static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, 139static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
@@ -327,23 +177,16 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
327 sge_bytes = min_t(size_t, 177 sge_bytes = min_t(size_t,
328 bc, vec->sge[xdr_sge_no].iov_len-sge_off); 178 bc, vec->sge[xdr_sge_no].iov_len-sge_off);
329 sge[sge_no].length = sge_bytes; 179 sge[sge_no].length = sge_bytes;
330 if (!vec->frmr) { 180 sge[sge_no].addr =
331 sge[sge_no].addr = 181 dma_map_xdr(xprt, &rqstp->rq_res, xdr_off,
332 dma_map_xdr(xprt, &rqstp->rq_res, xdr_off, 182 sge_bytes, DMA_TO_DEVICE);
333 sge_bytes, DMA_TO_DEVICE); 183 xdr_off += sge_bytes;
334 xdr_off += sge_bytes; 184 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
335 if (ib_dma_mapping_error(xprt->sc_cm_id->device, 185 sge[sge_no].addr))
336 sge[sge_no].addr)) 186 goto err;
337 goto err; 187 atomic_inc(&xprt->sc_dma_used);
338 atomic_inc(&xprt->sc_dma_used); 188 sge[sge_no].lkey = xprt->sc_dma_lkey;
339 sge[sge_no].lkey = xprt->sc_dma_lkey;
340 } else {
341 sge[sge_no].addr = (unsigned long)
342 vec->sge[xdr_sge_no].iov_base + sge_off;
343 sge[sge_no].lkey = vec->frmr->mr->lkey;
344 }
345 ctxt->count++; 189 ctxt->count++;
346 ctxt->frmr = vec->frmr;
347 sge_off = 0; 190 sge_off = 0;
348 sge_no++; 191 sge_no++;
349 xdr_sge_no++; 192 xdr_sge_no++;
@@ -369,7 +212,6 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
369 return 0; 212 return 0;
370 err: 213 err:
371 svc_rdma_unmap_dma(ctxt); 214 svc_rdma_unmap_dma(ctxt);
372 svc_rdma_put_frmr(xprt, vec->frmr);
373 svc_rdma_put_context(ctxt, 0); 215 svc_rdma_put_context(ctxt, 0);
374 /* Fatal error, close transport */ 216 /* Fatal error, close transport */
375 return -EIO; 217 return -EIO;
@@ -397,10 +239,7 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
397 res_ary = (struct rpcrdma_write_array *) 239 res_ary = (struct rpcrdma_write_array *)
398 &rdma_resp->rm_body.rm_chunks[1]; 240 &rdma_resp->rm_body.rm_chunks[1];
399 241
400 if (vec->frmr) 242 max_write = xprt->sc_max_sge * PAGE_SIZE;
401 max_write = vec->frmr->map_len;
402 else
403 max_write = xprt->sc_max_sge * PAGE_SIZE;
404 243
405 /* Write chunks start at the pagelist */ 244 /* Write chunks start at the pagelist */
406 for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0; 245 for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0;
@@ -472,10 +311,7 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
472 res_ary = (struct rpcrdma_write_array *) 311 res_ary = (struct rpcrdma_write_array *)
473 &rdma_resp->rm_body.rm_chunks[2]; 312 &rdma_resp->rm_body.rm_chunks[2];
474 313
475 if (vec->frmr) 314 max_write = xprt->sc_max_sge * PAGE_SIZE;
476 max_write = vec->frmr->map_len;
477 else
478 max_write = xprt->sc_max_sge * PAGE_SIZE;
479 315
480 /* xdr offset starts at RPC message */ 316 /* xdr offset starts at RPC message */
481 nchunks = ntohl(arg_ary->wc_nchunks); 317 nchunks = ntohl(arg_ary->wc_nchunks);
@@ -545,7 +381,6 @@ static int send_reply(struct svcxprt_rdma *rdma,
545 int byte_count) 381 int byte_count)
546{ 382{
547 struct ib_send_wr send_wr; 383 struct ib_send_wr send_wr;
548 struct ib_send_wr inv_wr;
549 int sge_no; 384 int sge_no;
550 int sge_bytes; 385 int sge_bytes;
551 int page_no; 386 int page_no;
@@ -559,7 +394,6 @@ static int send_reply(struct svcxprt_rdma *rdma,
559 "svcrdma: could not post a receive buffer, err=%d." 394 "svcrdma: could not post a receive buffer, err=%d."
560 "Closing transport %p.\n", ret, rdma); 395 "Closing transport %p.\n", ret, rdma);
561 set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); 396 set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
562 svc_rdma_put_frmr(rdma, vec->frmr);
563 svc_rdma_put_context(ctxt, 0); 397 svc_rdma_put_context(ctxt, 0);
564 return -ENOTCONN; 398 return -ENOTCONN;
565 } 399 }
@@ -567,11 +401,6 @@ static int send_reply(struct svcxprt_rdma *rdma,
567 /* Prepare the context */ 401 /* Prepare the context */
568 ctxt->pages[0] = page; 402 ctxt->pages[0] = page;
569 ctxt->count = 1; 403 ctxt->count = 1;
570 ctxt->frmr = vec->frmr;
571 if (vec->frmr)
572 set_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
573 else
574 clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
575 404
576 /* Prepare the SGE for the RPCRDMA Header */ 405 /* Prepare the SGE for the RPCRDMA Header */
577 ctxt->sge[0].lkey = rdma->sc_dma_lkey; 406 ctxt->sge[0].lkey = rdma->sc_dma_lkey;
@@ -590,21 +419,15 @@ static int send_reply(struct svcxprt_rdma *rdma,
590 int xdr_off = 0; 419 int xdr_off = 0;
591 sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count); 420 sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count);
592 byte_count -= sge_bytes; 421 byte_count -= sge_bytes;
593 if (!vec->frmr) { 422 ctxt->sge[sge_no].addr =
594 ctxt->sge[sge_no].addr = 423 dma_map_xdr(rdma, &rqstp->rq_res, xdr_off,
595 dma_map_xdr(rdma, &rqstp->rq_res, xdr_off, 424 sge_bytes, DMA_TO_DEVICE);
596 sge_bytes, DMA_TO_DEVICE); 425 xdr_off += sge_bytes;
597 xdr_off += sge_bytes; 426 if (ib_dma_mapping_error(rdma->sc_cm_id->device,
598 if (ib_dma_mapping_error(rdma->sc_cm_id->device, 427 ctxt->sge[sge_no].addr))
599 ctxt->sge[sge_no].addr)) 428 goto err;
600 goto err; 429 atomic_inc(&rdma->sc_dma_used);
601 atomic_inc(&rdma->sc_dma_used); 430 ctxt->sge[sge_no].lkey = rdma->sc_dma_lkey;
602 ctxt->sge[sge_no].lkey = rdma->sc_dma_lkey;
603 } else {
604 ctxt->sge[sge_no].addr = (unsigned long)
605 vec->sge[sge_no].iov_base;
606 ctxt->sge[sge_no].lkey = vec->frmr->mr->lkey;
607 }
608 ctxt->sge[sge_no].length = sge_bytes; 431 ctxt->sge[sge_no].length = sge_bytes;
609 } 432 }
610 BUG_ON(byte_count != 0); 433 BUG_ON(byte_count != 0);
@@ -627,6 +450,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
627 ctxt->sge[page_no+1].length = 0; 450 ctxt->sge[page_no+1].length = 0;
628 } 451 }
629 rqstp->rq_next_page = rqstp->rq_respages + 1; 452 rqstp->rq_next_page = rqstp->rq_respages + 1;
453
630 BUG_ON(sge_no > rdma->sc_max_sge); 454 BUG_ON(sge_no > rdma->sc_max_sge);
631 memset(&send_wr, 0, sizeof send_wr); 455 memset(&send_wr, 0, sizeof send_wr);
632 ctxt->wr_op = IB_WR_SEND; 456 ctxt->wr_op = IB_WR_SEND;
@@ -635,15 +459,6 @@ static int send_reply(struct svcxprt_rdma *rdma,
635 send_wr.num_sge = sge_no; 459 send_wr.num_sge = sge_no;
636 send_wr.opcode = IB_WR_SEND; 460 send_wr.opcode = IB_WR_SEND;
637 send_wr.send_flags = IB_SEND_SIGNALED; 461 send_wr.send_flags = IB_SEND_SIGNALED;
638 if (vec->frmr) {
639 /* Prepare INVALIDATE WR */
640 memset(&inv_wr, 0, sizeof inv_wr);
641 inv_wr.opcode = IB_WR_LOCAL_INV;
642 inv_wr.send_flags = IB_SEND_SIGNALED;
643 inv_wr.ex.invalidate_rkey =
644 vec->frmr->mr->lkey;
645 send_wr.next = &inv_wr;
646 }
647 462
648 ret = svc_rdma_send(rdma, &send_wr); 463 ret = svc_rdma_send(rdma, &send_wr);
649 if (ret) 464 if (ret)
@@ -653,7 +468,6 @@ static int send_reply(struct svcxprt_rdma *rdma,
653 468
654 err: 469 err:
655 svc_rdma_unmap_dma(ctxt); 470 svc_rdma_unmap_dma(ctxt);
656 svc_rdma_put_frmr(rdma, vec->frmr);
657 svc_rdma_put_context(ctxt, 1); 471 svc_rdma_put_context(ctxt, 1);
658 return -EIO; 472 return -EIO;
659} 473}
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 25688fa2207f..e7323fbbd348 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved.
2 * Copyright (c) 2005-2007 Network Appliance, Inc. All rights reserved. 3 * Copyright (c) 2005-2007 Network Appliance, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
@@ -65,6 +66,7 @@ static void dto_tasklet_func(unsigned long data);
65static void svc_rdma_detach(struct svc_xprt *xprt); 66static void svc_rdma_detach(struct svc_xprt *xprt);
66static void svc_rdma_free(struct svc_xprt *xprt); 67static void svc_rdma_free(struct svc_xprt *xprt);
67static int svc_rdma_has_wspace(struct svc_xprt *xprt); 68static int svc_rdma_has_wspace(struct svc_xprt *xprt);
69static int svc_rdma_secure_port(struct svc_rqst *);
68static void rq_cq_reap(struct svcxprt_rdma *xprt); 70static void rq_cq_reap(struct svcxprt_rdma *xprt);
69static void sq_cq_reap(struct svcxprt_rdma *xprt); 71static void sq_cq_reap(struct svcxprt_rdma *xprt);
70 72
@@ -82,6 +84,7 @@ static struct svc_xprt_ops svc_rdma_ops = {
82 .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr, 84 .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
83 .xpo_has_wspace = svc_rdma_has_wspace, 85 .xpo_has_wspace = svc_rdma_has_wspace,
84 .xpo_accept = svc_rdma_accept, 86 .xpo_accept = svc_rdma_accept,
87 .xpo_secure_port = svc_rdma_secure_port,
85}; 88};
86 89
87struct svc_xprt_class svc_rdma_class = { 90struct svc_xprt_class svc_rdma_class = {
@@ -160,7 +163,6 @@ struct svc_rdma_req_map *svc_rdma_get_req_map(void)
160 schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 163 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
161 } 164 }
162 map->count = 0; 165 map->count = 0;
163 map->frmr = NULL;
164 return map; 166 return map;
165} 167}
166 168
@@ -336,22 +338,21 @@ static void process_context(struct svcxprt_rdma *xprt,
336 338
337 switch (ctxt->wr_op) { 339 switch (ctxt->wr_op) {
338 case IB_WR_SEND: 340 case IB_WR_SEND:
339 if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags)) 341 BUG_ON(ctxt->frmr);
340 svc_rdma_put_frmr(xprt, ctxt->frmr);
341 svc_rdma_put_context(ctxt, 1); 342 svc_rdma_put_context(ctxt, 1);
342 break; 343 break;
343 344
344 case IB_WR_RDMA_WRITE: 345 case IB_WR_RDMA_WRITE:
346 BUG_ON(ctxt->frmr);
345 svc_rdma_put_context(ctxt, 0); 347 svc_rdma_put_context(ctxt, 0);
346 break; 348 break;
347 349
348 case IB_WR_RDMA_READ: 350 case IB_WR_RDMA_READ:
349 case IB_WR_RDMA_READ_WITH_INV: 351 case IB_WR_RDMA_READ_WITH_INV:
352 svc_rdma_put_frmr(xprt, ctxt->frmr);
350 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) { 353 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
351 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr; 354 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
352 BUG_ON(!read_hdr); 355 BUG_ON(!read_hdr);
353 if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags))
354 svc_rdma_put_frmr(xprt, ctxt->frmr);
355 spin_lock_bh(&xprt->sc_rq_dto_lock); 356 spin_lock_bh(&xprt->sc_rq_dto_lock);
356 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); 357 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
357 list_add_tail(&read_hdr->dto_q, 358 list_add_tail(&read_hdr->dto_q,
@@ -363,6 +364,7 @@ static void process_context(struct svcxprt_rdma *xprt,
363 break; 364 break;
364 365
365 default: 366 default:
367 BUG_ON(1);
366 printk(KERN_ERR "svcrdma: unexpected completion type, " 368 printk(KERN_ERR "svcrdma: unexpected completion type, "
367 "opcode=%d\n", 369 "opcode=%d\n",
368 ctxt->wr_op); 370 ctxt->wr_op);
@@ -378,29 +380,42 @@ static void process_context(struct svcxprt_rdma *xprt,
378static void sq_cq_reap(struct svcxprt_rdma *xprt) 380static void sq_cq_reap(struct svcxprt_rdma *xprt)
379{ 381{
380 struct svc_rdma_op_ctxt *ctxt = NULL; 382 struct svc_rdma_op_ctxt *ctxt = NULL;
381 struct ib_wc wc; 383 struct ib_wc wc_a[6];
384 struct ib_wc *wc;
382 struct ib_cq *cq = xprt->sc_sq_cq; 385 struct ib_cq *cq = xprt->sc_sq_cq;
383 int ret; 386 int ret;
384 387
388 memset(wc_a, 0, sizeof(wc_a));
389
385 if (!test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags)) 390 if (!test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags))
386 return; 391 return;
387 392
388 ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP); 393 ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP);
389 atomic_inc(&rdma_stat_sq_poll); 394 atomic_inc(&rdma_stat_sq_poll);
390 while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) { 395 while ((ret = ib_poll_cq(cq, ARRAY_SIZE(wc_a), wc_a)) > 0) {
391 if (wc.status != IB_WC_SUCCESS) 396 int i;
392 /* Close the transport */
393 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
394 397
395 /* Decrement used SQ WR count */ 398 for (i = 0; i < ret; i++) {
396 atomic_dec(&xprt->sc_sq_count); 399 wc = &wc_a[i];
397 wake_up(&xprt->sc_send_wait); 400 if (wc->status != IB_WC_SUCCESS) {
401 dprintk("svcrdma: sq wc err status %d\n",
402 wc->status);
398 403
399 ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id; 404 /* Close the transport */
400 if (ctxt) 405 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
401 process_context(xprt, ctxt); 406 }
402 407
403 svc_xprt_put(&xprt->sc_xprt); 408 /* Decrement used SQ WR count */
409 atomic_dec(&xprt->sc_sq_count);
410 wake_up(&xprt->sc_send_wait);
411
412 ctxt = (struct svc_rdma_op_ctxt *)
413 (unsigned long)wc->wr_id;
414 if (ctxt)
415 process_context(xprt, ctxt);
416
417 svc_xprt_put(&xprt->sc_xprt);
418 }
404 } 419 }
405 420
406 if (ctxt) 421 if (ctxt)
@@ -993,7 +1008,11 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
993 need_dma_mr = 0; 1008 need_dma_mr = 0;
994 break; 1009 break;
995 case RDMA_TRANSPORT_IB: 1010 case RDMA_TRANSPORT_IB:
996 if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) { 1011 if (!(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)) {
1012 need_dma_mr = 1;
1013 dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
1014 } else if (!(devattr.device_cap_flags &
1015 IB_DEVICE_LOCAL_DMA_LKEY)) {
997 need_dma_mr = 1; 1016 need_dma_mr = 1;
998 dma_mr_acc = IB_ACCESS_LOCAL_WRITE; 1017 dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
999 } else 1018 } else
@@ -1190,14 +1209,7 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
1190 container_of(xprt, struct svcxprt_rdma, sc_xprt); 1209 container_of(xprt, struct svcxprt_rdma, sc_xprt);
1191 1210
1192 /* 1211 /*
1193 * If there are fewer SQ WR available than required to send a 1212 * If there are already waiters on the SQ,
1194 * simple response, return false.
1195 */
1196 if ((rdma->sc_sq_depth - atomic_read(&rdma->sc_sq_count) < 3))
1197 return 0;
1198
1199 /*
1200 * ...or there are already waiters on the SQ,
1201 * return false. 1213 * return false.
1202 */ 1214 */
1203 if (waitqueue_active(&rdma->sc_send_wait)) 1215 if (waitqueue_active(&rdma->sc_send_wait))
@@ -1207,6 +1219,11 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
1207 return 1; 1219 return 1;
1208} 1220}
1209 1221
1222static int svc_rdma_secure_port(struct svc_rqst *rqstp)
1223{
1224 return 1;
1225}
1226
1210/* 1227/*
1211 * Attempt to register the kvec representing the RPC memory with the 1228 * Attempt to register the kvec representing the RPC memory with the
1212 * device. 1229 * device.