aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 15:53:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 15:53:06 -0400
commitdf36b439c5fedefe013d4449cb6a50d15e2f4d70 (patch)
tree537c58db778cbf11b74e28091f89d1b8139fb84d
parenta9b011f5ac57cbaedb32a8149f3d39d7b2c1f0e0 (diff)
parente9f029855865e917821ef6034b31e340a4cfc815 (diff)
Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (128 commits) nfs41: sunrpc: xprt_alloc_bc_request() should not use spin_lock_bh() nfs41: Move initialization of nfs4_opendata seq_res to nfs4_init_opendata_res nfs: remove unnecessary NFS_INO_INVALID_ACL checks NFS: More "sloppy" parsing problems NFS: Invalid mount option values should always fail, even with "sloppy" NFS: Remove unused XDR decoder functions NFS: Update MNT and MNT3 reply decoding functions NFS: add XDR decoder for mountd version 3 auth-flavor lists NFS: add new file handle decoders to in-kernel mountd client NFS: Add separate mountd status code decoders for each mountd version NFS: remove unused function in fs/nfs/mount_clnt.c NFS: Use xdr_stream-based XDR encoder for MNT's dirpath argument NFS: Clean up MNT program definitions lockd: Don't bother with RPC ping for NSM upcalls lockd: Update NSM state from SM_MON replies NFS: Fix false error return from nfs_callback_up() if ipv6.ko is not available NFS: Return error code from nfs_callback_up() to user space NFS: Do not display the setting of the "intr" mount option NFS: add support for splice writes nfs41: Backchannel: CB_SEQUENCE validation ...
-rw-r--r--fs/lockd/clntproc.c4
-rw-r--r--fs/lockd/mon.c19
-rw-r--r--fs/nfs/Kconfig9
-rw-r--r--fs/nfs/callback.c218
-rw-r--r--fs/nfs/callback.h68
-rw-r--r--fs/nfs/callback_proc.c127
-rw-r--r--fs/nfs/callback_xdr.c280
-rw-r--r--fs/nfs/client.c191
-rw-r--r--fs/nfs/delegation.c32
-rw-r--r--fs/nfs/direct.c9
-rw-r--r--fs/nfs/file.c37
-rw-r--r--fs/nfs/internal.h70
-rw-r--r--fs/nfs/mount_clnt.c337
-rw-r--r--fs/nfs/nfs3acl.c2
-rw-r--r--fs/nfs/nfs4_fs.h37
-rw-r--r--fs/nfs/nfs4proc.c1348
-rw-r--r--fs/nfs/nfs4renewd.c6
-rw-r--r--fs/nfs/nfs4state.c190
-rw-r--r--fs/nfs/nfs4xdr.c1072
-rw-r--r--fs/nfs/nfsroot.c5
-rw-r--r--fs/nfs/read.c33
-rw-r--r--fs/nfs/super.c295
-rw-r--r--fs/nfs/unlink.c20
-rw-r--r--fs/nfs/write.c31
-rw-r--r--include/linux/lockd/lockd.h2
-rw-r--r--include/linux/nfs.h5
-rw-r--r--include/linux/nfs2.h7
-rw-r--r--include/linux/nfs3.h5
-rw-r--r--include/linux/nfs4.h18
-rw-r--r--include/linux/nfs_fs_sb.h67
-rw-r--r--include/linux/nfs_xdr.h171
-rw-r--r--include/linux/nfsd/state.h1
-rw-r--r--include/linux/sunrpc/bc_xprt.h49
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--include/linux/sunrpc/sched.h3
-rw-r--r--include/linux/sunrpc/svc.h11
-rw-r--r--include/linux/sunrpc/svcsock.h2
-rw-r--r--include/linux/sunrpc/xprt.h38
-rw-r--r--net/sunrpc/Makefile1
-rw-r--r--net/sunrpc/backchannel_rqst.c281
-rw-r--r--net/sunrpc/bc_svc.c81
-rw-r--r--net/sunrpc/clnt.c143
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/stats.c8
-rw-r--r--net/sunrpc/sunrpc.h37
-rw-r--r--net/sunrpc/svc.c134
-rw-r--r--net/sunrpc/svcsock.c39
-rw-r--r--net/sunrpc/xprt.c60
-rw-r--r--net/sunrpc/xprtsock.c217
49 files changed, 5220 insertions, 603 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index dd7957064a8c..f2fdcbce143e 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -126,7 +126,6 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
126 struct nlm_lock *lock = &argp->lock; 126 struct nlm_lock *lock = &argp->lock;
127 127
128 nlmclnt_next_cookie(&argp->cookie); 128 nlmclnt_next_cookie(&argp->cookie);
129 argp->state = nsm_local_state;
130 memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh)); 129 memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh));
131 lock->caller = utsname()->nodename; 130 lock->caller = utsname()->nodename;
132 lock->oh.data = req->a_owner; 131 lock->oh.data = req->a_owner;
@@ -165,6 +164,7 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
165 /* Set up the argument struct */ 164 /* Set up the argument struct */
166 nlmclnt_setlockargs(call, fl); 165 nlmclnt_setlockargs(call, fl);
167 166
167 lock_kernel();
168 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { 168 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) {
169 if (fl->fl_type != F_UNLCK) { 169 if (fl->fl_type != F_UNLCK) {
170 call->a_args.block = IS_SETLKW(cmd) ? 1 : 0; 170 call->a_args.block = IS_SETLKW(cmd) ? 1 : 0;
@@ -178,6 +178,7 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
178 178
179 fl->fl_ops->fl_release_private(fl); 179 fl->fl_ops->fl_release_private(fl);
180 fl->fl_ops = NULL; 180 fl->fl_ops = NULL;
181 unlock_kernel();
181 182
182 dprintk("lockd: clnt proc returns %d\n", status); 183 dprintk("lockd: clnt proc returns %d\n", status);
183 return status; 184 return status;
@@ -519,6 +520,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
519 520
520 if (nsm_monitor(host) < 0) 521 if (nsm_monitor(host) < 0)
521 goto out; 522 goto out;
523 req->a_args.state = nsm_local_state;
522 524
523 fl->fl_flags |= FL_ACCESS; 525 fl->fl_flags |= FL_ACCESS;
524 status = do_vfs_lock(fl); 526 status = do_vfs_lock(fl);
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 6d5d4a4169e5..7fce1b525849 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -53,7 +53,7 @@ static DEFINE_SPINLOCK(nsm_lock);
53/* 53/*
54 * Local NSM state 54 * Local NSM state
55 */ 55 */
56int __read_mostly nsm_local_state; 56u32 __read_mostly nsm_local_state;
57int __read_mostly nsm_use_hostnames; 57int __read_mostly nsm_use_hostnames;
58 58
59static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm) 59static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm)
@@ -112,6 +112,7 @@ static struct rpc_clnt *nsm_create(void)
112 .program = &nsm_program, 112 .program = &nsm_program,
113 .version = NSM_VERSION, 113 .version = NSM_VERSION,
114 .authflavor = RPC_AUTH_NULL, 114 .authflavor = RPC_AUTH_NULL,
115 .flags = RPC_CLNT_CREATE_NOPING,
115 }; 116 };
116 117
117 return rpc_create(&args); 118 return rpc_create(&args);
@@ -184,13 +185,19 @@ int nsm_monitor(const struct nlm_host *host)
184 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; 185 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
185 186
186 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res); 187 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res);
187 if (res.status != 0) 188 if (unlikely(res.status != 0))
188 status = -EIO; 189 status = -EIO;
189 if (status < 0) 190 if (unlikely(status < 0)) {
190 printk(KERN_NOTICE "lockd: cannot monitor %s\n", nsm->sm_name); 191 printk(KERN_NOTICE "lockd: cannot monitor %s\n", nsm->sm_name);
191 else 192 return status;
192 nsm->sm_monitored = 1; 193 }
193 return status; 194
195 nsm->sm_monitored = 1;
196 if (unlikely(nsm_local_state != res.state)) {
197 nsm_local_state = res.state;
198 dprintk("lockd: NSM state changed to %d\n", nsm_local_state);
199 }
200 return 0;
194} 201}
195 202
196/** 203/**
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index e67f3ec07736..5d6d6f415935 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -74,6 +74,15 @@ config NFS_V4
74 74
75 If unsure, say N. 75 If unsure, say N.
76 76
77config NFS_V4_1
78 bool "NFS client support for NFSv4.1 (DEVELOPER ONLY)"
79 depends on NFS_V4 && EXPERIMENTAL
80 help
81 This option enables support for minor version 1 of the NFSv4 protocol
82 (draft-ietf-nfsv4-minorversion1) in the kernel's NFS client.
83
84 Unless you're an NFS developer, say N.
85
77config ROOT_NFS 86config ROOT_NFS
78 bool "Root file system on NFS" 87 bool "Root file system on NFS"
79 depends on NFS_FS=y && IP_PNP 88 depends on NFS_FS=y && IP_PNP
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a886e692ddd0..7f604c7941fb 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -17,6 +17,9 @@
17#include <linux/freezer.h> 17#include <linux/freezer.h>
18#include <linux/kthread.h> 18#include <linux/kthread.h>
19#include <linux/sunrpc/svcauth_gss.h> 19#include <linux/sunrpc/svcauth_gss.h>
20#if defined(CONFIG_NFS_V4_1)
21#include <linux/sunrpc/bc_xprt.h>
22#endif
20 23
21#include <net/inet_sock.h> 24#include <net/inet_sock.h>
22 25
@@ -28,11 +31,12 @@
28 31
29struct nfs_callback_data { 32struct nfs_callback_data {
30 unsigned int users; 33 unsigned int users;
34 struct svc_serv *serv;
31 struct svc_rqst *rqst; 35 struct svc_rqst *rqst;
32 struct task_struct *task; 36 struct task_struct *task;
33}; 37};
34 38
35static struct nfs_callback_data nfs_callback_info; 39static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
36static DEFINE_MUTEX(nfs_callback_mutex); 40static DEFINE_MUTEX(nfs_callback_mutex);
37static struct svc_program nfs4_callback_program; 41static struct svc_program nfs4_callback_program;
38 42
@@ -56,10 +60,10 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
56 &nfs_callback_set_tcpport, 0644); 60 &nfs_callback_set_tcpport, 0644);
57 61
58/* 62/*
59 * This is the callback kernel thread. 63 * This is the NFSv4 callback kernel thread.
60 */ 64 */
61static int 65static int
62nfs_callback_svc(void *vrqstp) 66nfs4_callback_svc(void *vrqstp)
63{ 67{
64 int err, preverr = 0; 68 int err, preverr = 0;
65 struct svc_rqst *rqstp = vrqstp; 69 struct svc_rqst *rqstp = vrqstp;
@@ -97,20 +101,12 @@ nfs_callback_svc(void *vrqstp)
97} 101}
98 102
99/* 103/*
100 * Bring up the callback thread if it is not already up. 104 * Prepare to bring up the NFSv4 callback service
101 */ 105 */
102int nfs_callback_up(void) 106struct svc_rqst *
107nfs4_callback_up(struct svc_serv *serv)
103{ 108{
104 struct svc_serv *serv = NULL; 109 int ret;
105 int ret = 0;
106
107 mutex_lock(&nfs_callback_mutex);
108 if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
109 goto out;
110 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
111 ret = -ENOMEM;
112 if (!serv)
113 goto out_err;
114 110
115 ret = svc_create_xprt(serv, "tcp", PF_INET, 111 ret = svc_create_xprt(serv, "tcp", PF_INET,
116 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 112 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
@@ -127,27 +123,174 @@ int nfs_callback_up(void)
127 nfs_callback_tcpport6 = ret; 123 nfs_callback_tcpport6 = ret;
128 dprintk("NFS: Callback listener port = %u (af %u)\n", 124 dprintk("NFS: Callback listener port = %u (af %u)\n",
129 nfs_callback_tcpport6, PF_INET6); 125 nfs_callback_tcpport6, PF_INET6);
130 } else if (ret != -EAFNOSUPPORT) 126 } else if (ret == -EAFNOSUPPORT)
127 ret = 0;
128 else
131 goto out_err; 129 goto out_err;
132#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ 130#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
133 131
134 nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); 132 return svc_prepare_thread(serv, &serv->sv_pools[0]);
135 if (IS_ERR(nfs_callback_info.rqst)) { 133
136 ret = PTR_ERR(nfs_callback_info.rqst); 134out_err:
137 nfs_callback_info.rqst = NULL; 135 if (ret == 0)
136 ret = -ENOMEM;
137 return ERR_PTR(ret);
138}
139
140#if defined(CONFIG_NFS_V4_1)
141/*
142 * The callback service for NFSv4.1 callbacks
143 */
144static int
145nfs41_callback_svc(void *vrqstp)
146{
147 struct svc_rqst *rqstp = vrqstp;
148 struct svc_serv *serv = rqstp->rq_server;
149 struct rpc_rqst *req;
150 int error;
151 DEFINE_WAIT(wq);
152
153 set_freezable();
154
155 /*
156 * FIXME: do we really need to run this under the BKL? If so, please
157 * add a comment about what it's intended to protect.
158 */
159 lock_kernel();
160 while (!kthread_should_stop()) {
161 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
162 spin_lock_bh(&serv->sv_cb_lock);
163 if (!list_empty(&serv->sv_cb_list)) {
164 req = list_first_entry(&serv->sv_cb_list,
165 struct rpc_rqst, rq_bc_list);
166 list_del(&req->rq_bc_list);
167 spin_unlock_bh(&serv->sv_cb_lock);
168 dprintk("Invoking bc_svc_process()\n");
169 error = bc_svc_process(serv, req, rqstp);
170 dprintk("bc_svc_process() returned w/ error code= %d\n",
171 error);
172 } else {
173 spin_unlock_bh(&serv->sv_cb_lock);
174 schedule();
175 }
176 finish_wait(&serv->sv_cb_waitq, &wq);
177 }
178 unlock_kernel();
179 return 0;
180}
181
182/*
183 * Bring up the NFSv4.1 callback service
184 */
185struct svc_rqst *
186nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
187{
188 struct svc_xprt *bc_xprt;
189 struct svc_rqst *rqstp = ERR_PTR(-ENOMEM);
190
191 dprintk("--> %s\n", __func__);
192 /* Create a svc_sock for the service */
193 bc_xprt = svc_sock_create(serv, xprt->prot);
194 if (!bc_xprt)
195 goto out;
196
197 /*
198 * Save the svc_serv in the transport so that it can
199 * be referenced when the session backchannel is initialized
200 */
201 serv->bc_xprt = bc_xprt;
202 xprt->bc_serv = serv;
203
204 INIT_LIST_HEAD(&serv->sv_cb_list);
205 spin_lock_init(&serv->sv_cb_lock);
206 init_waitqueue_head(&serv->sv_cb_waitq);
207 rqstp = svc_prepare_thread(serv, &serv->sv_pools[0]);
208 if (IS_ERR(rqstp))
209 svc_sock_destroy(bc_xprt);
210out:
211 dprintk("--> %s return %p\n", __func__, rqstp);
212 return rqstp;
213}
214
215static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
216 struct svc_serv *serv, struct rpc_xprt *xprt,
217 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
218{
219 if (minorversion) {
220 *rqstpp = nfs41_callback_up(serv, xprt);
221 *callback_svc = nfs41_callback_svc;
222 }
223 return minorversion;
224}
225
226static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
227 struct nfs_callback_data *cb_info)
228{
229 if (minorversion)
230 xprt->bc_serv = cb_info->serv;
231}
232#else
233static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
234 struct svc_serv *serv, struct rpc_xprt *xprt,
235 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
236{
237 return 0;
238}
239
240static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
241 struct nfs_callback_data *cb_info)
242{
243}
244#endif /* CONFIG_NFS_V4_1 */
245
246/*
247 * Bring up the callback thread if it is not already up.
248 */
249int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
250{
251 struct svc_serv *serv = NULL;
252 struct svc_rqst *rqstp;
253 int (*callback_svc)(void *vrqstp);
254 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
255 char svc_name[12];
256 int ret = 0;
257 int minorversion_setup;
258
259 mutex_lock(&nfs_callback_mutex);
260 if (cb_info->users++ || cb_info->task != NULL) {
261 nfs_callback_bc_serv(minorversion, xprt, cb_info);
262 goto out;
263 }
264 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
265 if (!serv) {
266 ret = -ENOMEM;
267 goto out_err;
268 }
269
270 minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion,
271 serv, xprt, &rqstp, &callback_svc);
272 if (!minorversion_setup) {
273 /* v4.0 callback setup */
274 rqstp = nfs4_callback_up(serv);
275 callback_svc = nfs4_callback_svc;
276 }
277
278 if (IS_ERR(rqstp)) {
279 ret = PTR_ERR(rqstp);
138 goto out_err; 280 goto out_err;
139 } 281 }
140 282
141 svc_sock_update_bufs(serv); 283 svc_sock_update_bufs(serv);
142 284
143 nfs_callback_info.task = kthread_run(nfs_callback_svc, 285 sprintf(svc_name, "nfsv4.%u-svc", minorversion);
144 nfs_callback_info.rqst, 286 cb_info->serv = serv;
145 "nfsv4-svc"); 287 cb_info->rqst = rqstp;
146 if (IS_ERR(nfs_callback_info.task)) { 288 cb_info->task = kthread_run(callback_svc, cb_info->rqst, svc_name);
147 ret = PTR_ERR(nfs_callback_info.task); 289 if (IS_ERR(cb_info->task)) {
148 svc_exit_thread(nfs_callback_info.rqst); 290 ret = PTR_ERR(cb_info->task);
149 nfs_callback_info.rqst = NULL; 291 svc_exit_thread(cb_info->rqst);
150 nfs_callback_info.task = NULL; 292 cb_info->rqst = NULL;
293 cb_info->task = NULL;
151 goto out_err; 294 goto out_err;
152 } 295 }
153out: 296out:
@@ -164,22 +307,25 @@ out:
164out_err: 307out_err:
165 dprintk("NFS: Couldn't create callback socket or server thread; " 308 dprintk("NFS: Couldn't create callback socket or server thread; "
166 "err = %d\n", ret); 309 "err = %d\n", ret);
167 nfs_callback_info.users--; 310 cb_info->users--;
168 goto out; 311 goto out;
169} 312}
170 313
171/* 314/*
172 * Kill the callback thread if it's no longer being used. 315 * Kill the callback thread if it's no longer being used.
173 */ 316 */
174void nfs_callback_down(void) 317void nfs_callback_down(int minorversion)
175{ 318{
319 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
320
176 mutex_lock(&nfs_callback_mutex); 321 mutex_lock(&nfs_callback_mutex);
177 nfs_callback_info.users--; 322 cb_info->users--;
178 if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL) { 323 if (cb_info->users == 0 && cb_info->task != NULL) {
179 kthread_stop(nfs_callback_info.task); 324 kthread_stop(cb_info->task);
180 svc_exit_thread(nfs_callback_info.rqst); 325 svc_exit_thread(cb_info->rqst);
181 nfs_callback_info.rqst = NULL; 326 cb_info->serv = NULL;
182 nfs_callback_info.task = NULL; 327 cb_info->rqst = NULL;
328 cb_info->task = NULL;
183 } 329 }
184 mutex_unlock(&nfs_callback_mutex); 330 mutex_unlock(&nfs_callback_mutex);
185} 331}
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index e110e286a262..07baa8254ca1 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -20,13 +20,24 @@ enum nfs4_callback_procnum {
20enum nfs4_callback_opnum { 20enum nfs4_callback_opnum {
21 OP_CB_GETATTR = 3, 21 OP_CB_GETATTR = 3,
22 OP_CB_RECALL = 4, 22 OP_CB_RECALL = 4,
23/* Callback operations new to NFSv4.1 */
24 OP_CB_LAYOUTRECALL = 5,
25 OP_CB_NOTIFY = 6,
26 OP_CB_PUSH_DELEG = 7,
27 OP_CB_RECALL_ANY = 8,
28 OP_CB_RECALLABLE_OBJ_AVAIL = 9,
29 OP_CB_RECALL_SLOT = 10,
30 OP_CB_SEQUENCE = 11,
31 OP_CB_WANTS_CANCELLED = 12,
32 OP_CB_NOTIFY_LOCK = 13,
33 OP_CB_NOTIFY_DEVICEID = 14,
23 OP_CB_ILLEGAL = 10044, 34 OP_CB_ILLEGAL = 10044,
24}; 35};
25 36
26struct cb_compound_hdr_arg { 37struct cb_compound_hdr_arg {
27 unsigned int taglen; 38 unsigned int taglen;
28 const char *tag; 39 const char *tag;
29 unsigned int callback_ident; 40 unsigned int minorversion;
30 unsigned nops; 41 unsigned nops;
31}; 42};
32 43
@@ -59,16 +70,59 @@ struct cb_recallargs {
59 uint32_t truncate; 70 uint32_t truncate;
60}; 71};
61 72
73#if defined(CONFIG_NFS_V4_1)
74
75struct referring_call {
76 uint32_t rc_sequenceid;
77 uint32_t rc_slotid;
78};
79
80struct referring_call_list {
81 struct nfs4_sessionid rcl_sessionid;
82 uint32_t rcl_nrefcalls;
83 struct referring_call *rcl_refcalls;
84};
85
86struct cb_sequenceargs {
87 struct sockaddr *csa_addr;
88 struct nfs4_sessionid csa_sessionid;
89 uint32_t csa_sequenceid;
90 uint32_t csa_slotid;
91 uint32_t csa_highestslotid;
92 uint32_t csa_cachethis;
93 uint32_t csa_nrclists;
94 struct referring_call_list *csa_rclists;
95};
96
97struct cb_sequenceres {
98 __be32 csr_status;
99 struct nfs4_sessionid csr_sessionid;
100 uint32_t csr_sequenceid;
101 uint32_t csr_slotid;
102 uint32_t csr_highestslotid;
103 uint32_t csr_target_highestslotid;
104};
105
106extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
107 struct cb_sequenceres *res);
108
109#endif /* CONFIG_NFS_V4_1 */
110
62extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); 111extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
63extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy); 112extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
64 113
65#ifdef CONFIG_NFS_V4 114#ifdef CONFIG_NFS_V4
66extern int nfs_callback_up(void); 115extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
67extern void nfs_callback_down(void); 116extern void nfs_callback_down(int minorversion);
68#else 117#endif /* CONFIG_NFS_V4 */
69#define nfs_callback_up() (0) 118
70#define nfs_callback_down() do {} while(0) 119/*
71#endif 120 * nfs41: Callbacks are expected to not cause substantial latency,
121 * so we limit their concurrency to 1 by setting up the maximum number
122 * of slots for the backchannel.
123 */
124#define NFS41_BC_MIN_CALLBACKS 1
125#define NFS41_BC_MAX_CALLBACKS 1
72 126
73extern unsigned int nfs_callback_set_tcpport; 127extern unsigned int nfs_callback_set_tcpport;
74extern unsigned short nfs_callback_tcpport; 128extern unsigned short nfs_callback_tcpport;
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index f7e83e23cf9f..b7da1f54da68 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -101,3 +101,130 @@ out:
101 dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); 101 dprintk("%s: exit with status = %d\n", __func__, ntohl(res));
102 return res; 102 return res;
103} 103}
104
105#if defined(CONFIG_NFS_V4_1)
106
107/*
108 * Validate the sequenceID sent by the server.
109 * Return success if the sequenceID is one more than what we last saw on
110 * this slot, accounting for wraparound. Increments the slot's sequence.
111 *
112 * We don't yet implement a duplicate request cache, so at this time
113 * we will log replays, and process them as if we had not seen them before,
114 * but we don't bump the sequence in the slot. Not too worried about it,
115 * since we only currently implement idempotent callbacks anyway.
116 *
117 * We have a single slot backchannel at this time, so we don't bother
118 * checking the used_slots bit array on the table. The lower layer guarantees
119 * a single outstanding callback request at a time.
120 */
121static int
122validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid)
123{
124 struct nfs4_slot *slot;
125
126 dprintk("%s enter. slotid %d seqid %d\n",
127 __func__, slotid, seqid);
128
129 if (slotid > NFS41_BC_MAX_CALLBACKS)
130 return htonl(NFS4ERR_BADSLOT);
131
132 slot = tbl->slots + slotid;
133 dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr);
134
135 /* Normal */
136 if (likely(seqid == slot->seq_nr + 1)) {
137 slot->seq_nr++;
138 return htonl(NFS4_OK);
139 }
140
141 /* Replay */
142 if (seqid == slot->seq_nr) {
143 dprintk("%s seqid %d is a replay - no DRC available\n",
144 __func__, seqid);
145 return htonl(NFS4_OK);
146 }
147
148 /* Wraparound */
149 if (seqid == 1 && (slot->seq_nr + 1) == 0) {
150 slot->seq_nr = 1;
151 return htonl(NFS4_OK);
152 }
153
154 /* Misordered request */
155 return htonl(NFS4ERR_SEQ_MISORDERED);
156}
157
158/*
159 * Returns a pointer to a held 'struct nfs_client' that matches the server's
160 * address, major version number, and session ID. It is the caller's
161 * responsibility to release the returned reference.
162 *
163 * Returns NULL if there are no connections with sessions, or if no session
164 * matches the one of interest.
165 */
166 static struct nfs_client *find_client_with_session(
167 const struct sockaddr *addr, u32 nfsversion,
168 struct nfs4_sessionid *sessionid)
169{
170 struct nfs_client *clp;
171
172 clp = nfs_find_client(addr, 4);
173 if (clp == NULL)
174 return NULL;
175
176 do {
177 struct nfs_client *prev = clp;
178
179 if (clp->cl_session != NULL) {
180 if (memcmp(clp->cl_session->sess_id.data,
181 sessionid->data,
182 NFS4_MAX_SESSIONID_LEN) == 0) {
183 /* Returns a held reference to clp */
184 return clp;
185 }
186 }
187 clp = nfs_find_client_next(prev);
188 nfs_put_client(prev);
189 } while (clp != NULL);
190
191 return NULL;
192}
193
194/* FIXME: referring calls should be processed */
195unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
196 struct cb_sequenceres *res)
197{
198 struct nfs_client *clp;
199 int i, status;
200
201 for (i = 0; i < args->csa_nrclists; i++)
202 kfree(args->csa_rclists[i].rcl_refcalls);
203 kfree(args->csa_rclists);
204
205 status = htonl(NFS4ERR_BADSESSION);
206 clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid);
207 if (clp == NULL)
208 goto out;
209
210 status = validate_seqid(&clp->cl_session->bc_slot_table,
211 args->csa_slotid, args->csa_sequenceid);
212 if (status)
213 goto out_putclient;
214
215 memcpy(&res->csr_sessionid, &args->csa_sessionid,
216 sizeof(res->csr_sessionid));
217 res->csr_sequenceid = args->csa_sequenceid;
218 res->csr_slotid = args->csa_slotid;
219 res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
220 res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
221
222out_putclient:
223 nfs_put_client(clp);
224out:
225 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
226 res->csr_status = status;
227 return res->csr_status;
228}
229
230#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index dd0ef34b5845..e5a2dac5f715 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -20,6 +20,11 @@
20 2 + 2 + 3 + 3) 20 2 + 2 + 3 + 3)
21#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 21#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
22 22
23#if defined(CONFIG_NFS_V4_1)
24#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
25 4 + 1 + 3)
26#endif /* CONFIG_NFS_V4_1 */
27
23#define NFSDBG_FACILITY NFSDBG_CALLBACK 28#define NFSDBG_FACILITY NFSDBG_CALLBACK
24 29
25typedef __be32 (*callback_process_op_t)(void *, void *); 30typedef __be32 (*callback_process_op_t)(void *, void *);
@@ -132,7 +137,6 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
132static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) 137static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
133{ 138{
134 __be32 *p; 139 __be32 *p;
135 unsigned int minor_version;
136 __be32 status; 140 __be32 status;
137 141
138 status = decode_string(xdr, &hdr->taglen, &hdr->tag); 142 status = decode_string(xdr, &hdr->taglen, &hdr->tag);
@@ -147,15 +151,19 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
147 p = read_buf(xdr, 12); 151 p = read_buf(xdr, 12);
148 if (unlikely(p == NULL)) 152 if (unlikely(p == NULL))
149 return htonl(NFS4ERR_RESOURCE); 153 return htonl(NFS4ERR_RESOURCE);
150 minor_version = ntohl(*p++); 154 hdr->minorversion = ntohl(*p++);
151 /* Check minor version is zero. */ 155 /* Check minor version is zero or one. */
152 if (minor_version != 0) { 156 if (hdr->minorversion <= 1) {
153 printk(KERN_WARNING "%s: NFSv4 server callback with illegal minor version %u!\n", 157 p++; /* skip callback_ident */
154 __func__, minor_version); 158 } else {
159 printk(KERN_WARNING "%s: NFSv4 server callback with "
160 "illegal minor version %u!\n",
161 __func__, hdr->minorversion);
155 return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 162 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
156 } 163 }
157 hdr->callback_ident = ntohl(*p++);
158 hdr->nops = ntohl(*p); 164 hdr->nops = ntohl(*p);
165 dprintk("%s: minorversion %d nops %d\n", __func__,
166 hdr->minorversion, hdr->nops);
159 return 0; 167 return 0;
160} 168}
161 169
@@ -204,6 +212,122 @@ out:
204 return status; 212 return status;
205} 213}
206 214
215#if defined(CONFIG_NFS_V4_1)
216
217static unsigned decode_sessionid(struct xdr_stream *xdr,
218 struct nfs4_sessionid *sid)
219{
220 uint32_t *p;
221 int len = NFS4_MAX_SESSIONID_LEN;
222
223 p = read_buf(xdr, len);
224 if (unlikely(p == NULL))
225 return htonl(NFS4ERR_RESOURCE);;
226
227 memcpy(sid->data, p, len);
228 return 0;
229}
230
231static unsigned decode_rc_list(struct xdr_stream *xdr,
232 struct referring_call_list *rc_list)
233{
234 uint32_t *p;
235 int i;
236 unsigned status;
237
238 status = decode_sessionid(xdr, &rc_list->rcl_sessionid);
239 if (status)
240 goto out;
241
242 status = htonl(NFS4ERR_RESOURCE);
243 p = read_buf(xdr, sizeof(uint32_t));
244 if (unlikely(p == NULL))
245 goto out;
246
247 rc_list->rcl_nrefcalls = ntohl(*p++);
248 if (rc_list->rcl_nrefcalls) {
249 p = read_buf(xdr,
250 rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
251 if (unlikely(p == NULL))
252 goto out;
253 rc_list->rcl_refcalls = kmalloc(rc_list->rcl_nrefcalls *
254 sizeof(*rc_list->rcl_refcalls),
255 GFP_KERNEL);
256 if (unlikely(rc_list->rcl_refcalls == NULL))
257 goto out;
258 for (i = 0; i < rc_list->rcl_nrefcalls; i++) {
259 rc_list->rcl_refcalls[i].rc_sequenceid = ntohl(*p++);
260 rc_list->rcl_refcalls[i].rc_slotid = ntohl(*p++);
261 }
262 }
263 status = 0;
264
265out:
266 return status;
267}
268
269static unsigned decode_cb_sequence_args(struct svc_rqst *rqstp,
270 struct xdr_stream *xdr,
271 struct cb_sequenceargs *args)
272{
273 uint32_t *p;
274 int i;
275 unsigned status;
276
277 status = decode_sessionid(xdr, &args->csa_sessionid);
278 if (status)
279 goto out;
280
281 status = htonl(NFS4ERR_RESOURCE);
282 p = read_buf(xdr, 5 * sizeof(uint32_t));
283 if (unlikely(p == NULL))
284 goto out;
285
286 args->csa_addr = svc_addr(rqstp);
287 args->csa_sequenceid = ntohl(*p++);
288 args->csa_slotid = ntohl(*p++);
289 args->csa_highestslotid = ntohl(*p++);
290 args->csa_cachethis = ntohl(*p++);
291 args->csa_nrclists = ntohl(*p++);
292 args->csa_rclists = NULL;
293 if (args->csa_nrclists) {
294 args->csa_rclists = kmalloc(args->csa_nrclists *
295 sizeof(*args->csa_rclists),
296 GFP_KERNEL);
297 if (unlikely(args->csa_rclists == NULL))
298 goto out;
299
300 for (i = 0; i < args->csa_nrclists; i++) {
301 status = decode_rc_list(xdr, &args->csa_rclists[i]);
302 if (status)
303 goto out_free;
304 }
305 }
306 status = 0;
307
308 dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u slotid %u "
309 "highestslotid %u cachethis %d nrclists %u\n",
310 __func__,
311 ((u32 *)&args->csa_sessionid)[0],
312 ((u32 *)&args->csa_sessionid)[1],
313 ((u32 *)&args->csa_sessionid)[2],
314 ((u32 *)&args->csa_sessionid)[3],
315 args->csa_sequenceid, args->csa_slotid,
316 args->csa_highestslotid, args->csa_cachethis,
317 args->csa_nrclists);
318out:
319 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
320 return status;
321
322out_free:
323 for (i = 0; i < args->csa_nrclists; i++)
324 kfree(args->csa_rclists[i].rcl_refcalls);
325 kfree(args->csa_rclists);
326 goto out;
327}
328
329#endif /* CONFIG_NFS_V4_1 */
330
207static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 331static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
208{ 332{
209 __be32 *p; 333 __be32 *p;
@@ -353,31 +477,134 @@ out:
353 return status; 477 return status;
354} 478}
355 479
356static __be32 process_op(struct svc_rqst *rqstp, 480#if defined(CONFIG_NFS_V4_1)
481
482static unsigned encode_sessionid(struct xdr_stream *xdr,
483 const struct nfs4_sessionid *sid)
484{
485 uint32_t *p;
486 int len = NFS4_MAX_SESSIONID_LEN;
487
488 p = xdr_reserve_space(xdr, len);
489 if (unlikely(p == NULL))
490 return htonl(NFS4ERR_RESOURCE);
491
492 memcpy(p, sid, len);
493 return 0;
494}
495
496static unsigned encode_cb_sequence_res(struct svc_rqst *rqstp,
497 struct xdr_stream *xdr,
498 const struct cb_sequenceres *res)
499{
500 uint32_t *p;
501 unsigned status = res->csr_status;
502
503 if (unlikely(status != 0))
504 goto out;
505
506 encode_sessionid(xdr, &res->csr_sessionid);
507
508 p = xdr_reserve_space(xdr, 4 * sizeof(uint32_t));
509 if (unlikely(p == NULL))
510 return htonl(NFS4ERR_RESOURCE);
511
512 *p++ = htonl(res->csr_sequenceid);
513 *p++ = htonl(res->csr_slotid);
514 *p++ = htonl(res->csr_highestslotid);
515 *p++ = htonl(res->csr_target_highestslotid);
516out:
517 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
518 return status;
519}
520
521static __be32
522preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
523{
524 if (op_nr == OP_CB_SEQUENCE) {
525 if (nop != 0)
526 return htonl(NFS4ERR_SEQUENCE_POS);
527 } else {
528 if (nop == 0)
529 return htonl(NFS4ERR_OP_NOT_IN_SESSION);
530 }
531
532 switch (op_nr) {
533 case OP_CB_GETATTR:
534 case OP_CB_RECALL:
535 case OP_CB_SEQUENCE:
536 *op = &callback_ops[op_nr];
537 break;
538
539 case OP_CB_LAYOUTRECALL:
540 case OP_CB_NOTIFY_DEVICEID:
541 case OP_CB_NOTIFY:
542 case OP_CB_PUSH_DELEG:
543 case OP_CB_RECALL_ANY:
544 case OP_CB_RECALLABLE_OBJ_AVAIL:
545 case OP_CB_RECALL_SLOT:
546 case OP_CB_WANTS_CANCELLED:
547 case OP_CB_NOTIFY_LOCK:
548 return htonl(NFS4ERR_NOTSUPP);
549
550 default:
551 return htonl(NFS4ERR_OP_ILLEGAL);
552 }
553
554 return htonl(NFS_OK);
555}
556
557#else /* CONFIG_NFS_V4_1 */
558
559static __be32
560preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
561{
562 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
563}
564
565#endif /* CONFIG_NFS_V4_1 */
566
567static __be32
568preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
569{
570 switch (op_nr) {
571 case OP_CB_GETATTR:
572 case OP_CB_RECALL:
573 *op = &callback_ops[op_nr];
574 break;
575 default:
576 return htonl(NFS4ERR_OP_ILLEGAL);
577 }
578
579 return htonl(NFS_OK);
580}
581
582static __be32 process_op(uint32_t minorversion, int nop,
583 struct svc_rqst *rqstp,
357 struct xdr_stream *xdr_in, void *argp, 584 struct xdr_stream *xdr_in, void *argp,
358 struct xdr_stream *xdr_out, void *resp) 585 struct xdr_stream *xdr_out, void *resp)
359{ 586{
360 struct callback_op *op = &callback_ops[0]; 587 struct callback_op *op = &callback_ops[0];
361 unsigned int op_nr = OP_CB_ILLEGAL; 588 unsigned int op_nr = OP_CB_ILLEGAL;
362 __be32 status = 0; 589 __be32 status;
363 long maxlen; 590 long maxlen;
364 __be32 res; 591 __be32 res;
365 592
366 dprintk("%s: start\n", __func__); 593 dprintk("%s: start\n", __func__);
367 status = decode_op_hdr(xdr_in, &op_nr); 594 status = decode_op_hdr(xdr_in, &op_nr);
368 if (likely(status == 0)) { 595 if (unlikely(status)) {
369 switch (op_nr) { 596 status = htonl(NFS4ERR_OP_ILLEGAL);
370 case OP_CB_GETATTR: 597 goto out;
371 case OP_CB_RECALL:
372 op = &callback_ops[op_nr];
373 break;
374 default:
375 op_nr = OP_CB_ILLEGAL;
376 op = &callback_ops[0];
377 status = htonl(NFS4ERR_OP_ILLEGAL);
378 }
379 } 598 }
380 599
600 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
601 __func__, minorversion, nop, op_nr);
602
603 status = minorversion ? preprocess_nfs41_op(nop, op_nr, &op) :
604 preprocess_nfs4_op(op_nr, &op);
605 if (status == htonl(NFS4ERR_OP_ILLEGAL))
606 op_nr = OP_CB_ILLEGAL;
607out:
381 maxlen = xdr_out->end - xdr_out->p; 608 maxlen = xdr_out->end - xdr_out->p;
382 if (maxlen > 0 && maxlen < PAGE_SIZE) { 609 if (maxlen > 0 && maxlen < PAGE_SIZE) {
383 if (likely(status == 0 && op->decode_args != NULL)) 610 if (likely(status == 0 && op->decode_args != NULL))
@@ -425,7 +652,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
425 return rpc_system_err; 652 return rpc_system_err;
426 653
427 while (status == 0 && nops != hdr_arg.nops) { 654 while (status == 0 && nops != hdr_arg.nops) {
428 status = process_op(rqstp, &xdr_in, argp, &xdr_out, resp); 655 status = process_op(hdr_arg.minorversion, nops,
656 rqstp, &xdr_in, argp, &xdr_out, resp);
429 nops++; 657 nops++;
430 } 658 }
431 659
@@ -452,7 +680,15 @@ static struct callback_op callback_ops[] = {
452 .process_op = (callback_process_op_t)nfs4_callback_recall, 680 .process_op = (callback_process_op_t)nfs4_callback_recall,
453 .decode_args = (callback_decode_arg_t)decode_recall_args, 681 .decode_args = (callback_decode_arg_t)decode_recall_args,
454 .res_maxsize = CB_OP_RECALL_RES_MAXSZ, 682 .res_maxsize = CB_OP_RECALL_RES_MAXSZ,
455 } 683 },
684#if defined(CONFIG_NFS_V4_1)
685 [OP_CB_SEQUENCE] = {
686 .process_op = (callback_process_op_t)nfs4_callback_sequence,
687 .decode_args = (callback_decode_arg_t)decode_cb_sequence_args,
688 .encode_res = (callback_encode_res_t)encode_cb_sequence_res,
689 .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ,
690 },
691#endif /* CONFIG_NFS_V4_1 */
456}; 692};
457 693
458/* 694/*
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 75c9cd2aa119..c2d061675d80 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -37,6 +37,7 @@
37#include <linux/in6.h> 37#include <linux/in6.h>
38#include <net/ipv6.h> 38#include <net/ipv6.h>
39#include <linux/nfs_xdr.h> 39#include <linux/nfs_xdr.h>
40#include <linux/sunrpc/bc_xprt.h>
40 41
41#include <asm/system.h> 42#include <asm/system.h>
42 43
@@ -102,6 +103,7 @@ struct nfs_client_initdata {
102 size_t addrlen; 103 size_t addrlen;
103 const struct nfs_rpc_ops *rpc_ops; 104 const struct nfs_rpc_ops *rpc_ops;
104 int proto; 105 int proto;
106 u32 minorversion;
105}; 107};
106 108
107/* 109/*
@@ -114,18 +116,13 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
114{ 116{
115 struct nfs_client *clp; 117 struct nfs_client *clp;
116 struct rpc_cred *cred; 118 struct rpc_cred *cred;
119 int err = -ENOMEM;
117 120
118 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) 121 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
119 goto error_0; 122 goto error_0;
120 123
121 clp->rpc_ops = cl_init->rpc_ops; 124 clp->rpc_ops = cl_init->rpc_ops;
122 125
123 if (cl_init->rpc_ops->version == 4) {
124 if (nfs_callback_up() < 0)
125 goto error_2;
126 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
127 }
128
129 atomic_set(&clp->cl_count, 1); 126 atomic_set(&clp->cl_count, 1);
130 clp->cl_cons_state = NFS_CS_INITING; 127 clp->cl_cons_state = NFS_CS_INITING;
131 128
@@ -133,9 +130,10 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
133 clp->cl_addrlen = cl_init->addrlen; 130 clp->cl_addrlen = cl_init->addrlen;
134 131
135 if (cl_init->hostname) { 132 if (cl_init->hostname) {
133 err = -ENOMEM;
136 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL); 134 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
137 if (!clp->cl_hostname) 135 if (!clp->cl_hostname)
138 goto error_3; 136 goto error_cleanup;
139 } 137 }
140 138
141 INIT_LIST_HEAD(&clp->cl_superblocks); 139 INIT_LIST_HEAD(&clp->cl_superblocks);
@@ -150,6 +148,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
150 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); 148 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
151 clp->cl_boot_time = CURRENT_TIME; 149 clp->cl_boot_time = CURRENT_TIME;
152 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 150 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
151 clp->cl_minorversion = cl_init->minorversion;
153#endif 152#endif
154 cred = rpc_lookup_machine_cred(); 153 cred = rpc_lookup_machine_cred();
155 if (!IS_ERR(cred)) 154 if (!IS_ERR(cred))
@@ -159,13 +158,10 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
159 158
160 return clp; 159 return clp;
161 160
162error_3: 161error_cleanup:
163 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
164 nfs_callback_down();
165error_2:
166 kfree(clp); 162 kfree(clp);
167error_0: 163error_0:
168 return NULL; 164 return ERR_PTR(err);
169} 165}
170 166
171static void nfs4_shutdown_client(struct nfs_client *clp) 167static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -182,12 +178,42 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
182} 178}
183 179
184/* 180/*
181 * Destroy the NFS4 callback service
182 */
183static void nfs4_destroy_callback(struct nfs_client *clp)
184{
185#ifdef CONFIG_NFS_V4
186 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
187 nfs_callback_down(clp->cl_minorversion);
188#endif /* CONFIG_NFS_V4 */
189}
190
191/*
192 * Clears/puts all minor version specific parts from an nfs_client struct
193 * reverting it to minorversion 0.
194 */
195static void nfs4_clear_client_minor_version(struct nfs_client *clp)
196{
197#ifdef CONFIG_NFS_V4_1
198 if (nfs4_has_session(clp)) {
199 nfs4_destroy_session(clp->cl_session);
200 clp->cl_session = NULL;
201 }
202
203 clp->cl_call_sync = _nfs4_call_sync;
204#endif /* CONFIG_NFS_V4_1 */
205
206 nfs4_destroy_callback(clp);
207}
208
209/*
185 * Destroy a shared client record 210 * Destroy a shared client record
186 */ 211 */
187static void nfs_free_client(struct nfs_client *clp) 212static void nfs_free_client(struct nfs_client *clp)
188{ 213{
189 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); 214 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
190 215
216 nfs4_clear_client_minor_version(clp);
191 nfs4_shutdown_client(clp); 217 nfs4_shutdown_client(clp);
192 218
193 nfs_fscache_release_client_cookie(clp); 219 nfs_fscache_release_client_cookie(clp);
@@ -196,9 +222,6 @@ static void nfs_free_client(struct nfs_client *clp)
196 if (!IS_ERR(clp->cl_rpcclient)) 222 if (!IS_ERR(clp->cl_rpcclient))
197 rpc_shutdown_client(clp->cl_rpcclient); 223 rpc_shutdown_client(clp->cl_rpcclient);
198 224
199 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
200 nfs_callback_down();
201
202 if (clp->cl_machine_cred != NULL) 225 if (clp->cl_machine_cred != NULL)
203 put_rpccred(clp->cl_machine_cred); 226 put_rpccred(clp->cl_machine_cred);
204 227
@@ -347,7 +370,8 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
347 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; 370 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
348 371
349 /* Don't match clients that failed to initialise properly */ 372 /* Don't match clients that failed to initialise properly */
350 if (clp->cl_cons_state != NFS_CS_READY) 373 if (!(clp->cl_cons_state == NFS_CS_READY ||
374 clp->cl_cons_state == NFS_CS_SESSION_INITING))
351 continue; 375 continue;
352 376
353 /* Different NFS versions cannot share the same nfs_client */ 377 /* Different NFS versions cannot share the same nfs_client */
@@ -420,7 +444,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
420 444
421 if (clp->cl_proto != data->proto) 445 if (clp->cl_proto != data->proto)
422 continue; 446 continue;
423 447 /* Match nfsv4 minorversion */
448 if (clp->cl_minorversion != data->minorversion)
449 continue;
424 /* Match the full socket address */ 450 /* Match the full socket address */
425 if (!nfs_sockaddr_cmp(sap, clap)) 451 if (!nfs_sockaddr_cmp(sap, clap))
426 continue; 452 continue;
@@ -456,9 +482,10 @@ static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_in
456 spin_unlock(&nfs_client_lock); 482 spin_unlock(&nfs_client_lock);
457 483
458 new = nfs_alloc_client(cl_init); 484 new = nfs_alloc_client(cl_init);
459 } while (new); 485 } while (!IS_ERR(new));
460 486
461 return ERR_PTR(-ENOMEM); 487 dprintk("--> nfs_get_client() = %ld [failed]\n", PTR_ERR(new));
488 return new;
462 489
463 /* install a new client and return with it unready */ 490 /* install a new client and return with it unready */
464install_client: 491install_client:
@@ -478,7 +505,7 @@ found_client:
478 nfs_free_client(new); 505 nfs_free_client(new);
479 506
480 error = wait_event_killable(nfs_client_active_wq, 507 error = wait_event_killable(nfs_client_active_wq,
481 clp->cl_cons_state != NFS_CS_INITING); 508 clp->cl_cons_state < NFS_CS_INITING);
482 if (error < 0) { 509 if (error < 0) {
483 nfs_put_client(clp); 510 nfs_put_client(clp);
484 return ERR_PTR(-ERESTARTSYS); 511 return ERR_PTR(-ERESTARTSYS);
@@ -499,13 +526,29 @@ found_client:
499/* 526/*
500 * Mark a server as ready or failed 527 * Mark a server as ready or failed
501 */ 528 */
502static void nfs_mark_client_ready(struct nfs_client *clp, int state) 529void nfs_mark_client_ready(struct nfs_client *clp, int state)
503{ 530{
504 clp->cl_cons_state = state; 531 clp->cl_cons_state = state;
505 wake_up_all(&nfs_client_active_wq); 532 wake_up_all(&nfs_client_active_wq);
506} 533}
507 534
508/* 535/*
536 * With sessions, the client is not marked ready until after a
537 * successful EXCHANGE_ID and CREATE_SESSION.
538 *
539 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
540 * other versions of NFS can be tried.
541 */
542int nfs4_check_client_ready(struct nfs_client *clp)
543{
544 if (!nfs4_has_session(clp))
545 return 0;
546 if (clp->cl_cons_state < NFS_CS_READY)
547 return -EPROTONOSUPPORT;
548 return 0;
549}
550
551/*
509 * Initialise the timeout values for a connection 552 * Initialise the timeout values for a connection
510 */ 553 */
511static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, 554static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
@@ -1050,6 +1093,61 @@ error:
1050 1093
1051#ifdef CONFIG_NFS_V4 1094#ifdef CONFIG_NFS_V4
1052/* 1095/*
1096 * Initialize the NFS4 callback service
1097 */
1098static int nfs4_init_callback(struct nfs_client *clp)
1099{
1100 int error;
1101
1102 if (clp->rpc_ops->version == 4) {
1103 if (nfs4_has_session(clp)) {
1104 error = xprt_setup_backchannel(
1105 clp->cl_rpcclient->cl_xprt,
1106 NFS41_BC_MIN_CALLBACKS);
1107 if (error < 0)
1108 return error;
1109 }
1110
1111 error = nfs_callback_up(clp->cl_minorversion,
1112 clp->cl_rpcclient->cl_xprt);
1113 if (error < 0) {
1114 dprintk("%s: failed to start callback. Error = %d\n",
1115 __func__, error);
1116 return error;
1117 }
1118 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
1119 }
1120 return 0;
1121}
1122
1123/*
1124 * Initialize the minor version specific parts of an NFS4 client record
1125 */
1126static int nfs4_init_client_minor_version(struct nfs_client *clp)
1127{
1128 clp->cl_call_sync = _nfs4_call_sync;
1129
1130#if defined(CONFIG_NFS_V4_1)
1131 if (clp->cl_minorversion) {
1132 struct nfs4_session *session = NULL;
1133 /*
1134 * Create the session and mark it expired.
1135 * When a SEQUENCE operation encounters the expired session
1136 * it will do session recovery to initialize it.
1137 */
1138 session = nfs4_alloc_session(clp);
1139 if (!session)
1140 return -ENOMEM;
1141
1142 clp->cl_session = session;
1143 clp->cl_call_sync = _nfs4_call_sync_session;
1144 }
1145#endif /* CONFIG_NFS_V4_1 */
1146
1147 return nfs4_init_callback(clp);
1148}
1149
1150/*
1053 * Initialise an NFS4 client record 1151 * Initialise an NFS4 client record
1054 */ 1152 */
1055static int nfs4_init_client(struct nfs_client *clp, 1153static int nfs4_init_client(struct nfs_client *clp,
@@ -1083,7 +1181,12 @@ static int nfs4_init_client(struct nfs_client *clp,
1083 } 1181 }
1084 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); 1182 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
1085 1183
1086 nfs_mark_client_ready(clp, NFS_CS_READY); 1184 error = nfs4_init_client_minor_version(clp);
1185 if (error < 0)
1186 goto error;
1187
1188 if (!nfs4_has_session(clp))
1189 nfs_mark_client_ready(clp, NFS_CS_READY);
1087 return 0; 1190 return 0;
1088 1191
1089error: 1192error:
@@ -1101,7 +1204,8 @@ static int nfs4_set_client(struct nfs_server *server,
1101 const size_t addrlen, 1204 const size_t addrlen,
1102 const char *ip_addr, 1205 const char *ip_addr,
1103 rpc_authflavor_t authflavour, 1206 rpc_authflavor_t authflavour,
1104 int proto, const struct rpc_timeout *timeparms) 1207 int proto, const struct rpc_timeout *timeparms,
1208 u32 minorversion)
1105{ 1209{
1106 struct nfs_client_initdata cl_init = { 1210 struct nfs_client_initdata cl_init = {
1107 .hostname = hostname, 1211 .hostname = hostname,
@@ -1109,6 +1213,7 @@ static int nfs4_set_client(struct nfs_server *server,
1109 .addrlen = addrlen, 1213 .addrlen = addrlen,
1110 .rpc_ops = &nfs_v4_clientops, 1214 .rpc_ops = &nfs_v4_clientops,
1111 .proto = proto, 1215 .proto = proto,
1216 .minorversion = minorversion,
1112 }; 1217 };
1113 struct nfs_client *clp; 1218 struct nfs_client *clp;
1114 int error; 1219 int error;
@@ -1138,6 +1243,36 @@ error:
1138} 1243}
1139 1244
1140/* 1245/*
1246 * Initialize a session.
1247 * Note: save the mount rsize and wsize for create_server negotiation.
1248 */
1249static void nfs4_init_session(struct nfs_client *clp,
1250 unsigned int wsize, unsigned int rsize)
1251{
1252#if defined(CONFIG_NFS_V4_1)
1253 if (nfs4_has_session(clp)) {
1254 clp->cl_session->fc_attrs.max_rqst_sz = wsize;
1255 clp->cl_session->fc_attrs.max_resp_sz = rsize;
1256 }
1257#endif /* CONFIG_NFS_V4_1 */
1258}
1259
1260/*
1261 * Session has been established, and the client marked ready.
1262 * Set the mount rsize and wsize with negotiated fore channel
1263 * attributes which will be bound checked in nfs_server_set_fsinfo.
1264 */
1265static void nfs4_session_set_rwsize(struct nfs_server *server)
1266{
1267#ifdef CONFIG_NFS_V4_1
1268 if (!nfs4_has_session(server->nfs_client))
1269 return;
1270 server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
1271 server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
1272#endif /* CONFIG_NFS_V4_1 */
1273}
1274
1275/*
1141 * Create a version 4 volume record 1276 * Create a version 4 volume record
1142 */ 1277 */
1143static int nfs4_init_server(struct nfs_server *server, 1278static int nfs4_init_server(struct nfs_server *server,
@@ -1164,7 +1299,8 @@ static int nfs4_init_server(struct nfs_server *server,
1164 data->client_address, 1299 data->client_address,
1165 data->auth_flavors[0], 1300 data->auth_flavors[0],
1166 data->nfs_server.protocol, 1301 data->nfs_server.protocol,
1167 &timeparms); 1302 &timeparms,
1303 data->minorversion);
1168 if (error < 0) 1304 if (error < 0)
1169 goto error; 1305 goto error;
1170 1306
@@ -1214,6 +1350,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1214 BUG_ON(!server->nfs_client->rpc_ops); 1350 BUG_ON(!server->nfs_client->rpc_ops);
1215 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1351 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1216 1352
1353 nfs4_init_session(server->nfs_client, server->wsize, server->rsize);
1354
1217 /* Probe the root fh to retrieve its FSID */ 1355 /* Probe the root fh to retrieve its FSID */
1218 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); 1356 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
1219 if (error < 0) 1357 if (error < 0)
@@ -1224,6 +1362,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1224 (unsigned long long) server->fsid.minor); 1362 (unsigned long long) server->fsid.minor);
1225 dprintk("Mount FH: %d\n", mntfh->size); 1363 dprintk("Mount FH: %d\n", mntfh->size);
1226 1364
1365 nfs4_session_set_rwsize(server);
1366
1227 error = nfs_probe_fsinfo(server, mntfh, &fattr); 1367 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1228 if (error < 0) 1368 if (error < 0)
1229 goto error; 1369 goto error;
@@ -1282,7 +1422,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1282 parent_client->cl_ipaddr, 1422 parent_client->cl_ipaddr,
1283 data->authflavor, 1423 data->authflavor,
1284 parent_server->client->cl_xprt->prot, 1424 parent_server->client->cl_xprt->prot,
1285 parent_server->client->cl_timeout); 1425 parent_server->client->cl_timeout,
1426 parent_client->cl_minorversion);
1286 if (error < 0) 1427 if (error < 0)
1287 goto error; 1428 goto error;
1288 1429
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 968225a88015..af05b918cb5b 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -68,29 +68,26 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
68{ 68{
69 struct inode *inode = state->inode; 69 struct inode *inode = state->inode;
70 struct file_lock *fl; 70 struct file_lock *fl;
71 int status; 71 int status = 0;
72
73 if (inode->i_flock == NULL)
74 goto out;
72 75
76 /* Protect inode->i_flock using the BKL */
77 lock_kernel();
73 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 78 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
74 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 79 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
75 continue; 80 continue;
76 if (nfs_file_open_context(fl->fl_file) != ctx) 81 if (nfs_file_open_context(fl->fl_file) != ctx)
77 continue; 82 continue;
83 unlock_kernel();
78 status = nfs4_lock_delegation_recall(state, fl); 84 status = nfs4_lock_delegation_recall(state, fl);
79 if (status >= 0) 85 if (status < 0)
80 continue; 86 goto out;
81 switch (status) { 87 lock_kernel();
82 default:
83 printk(KERN_ERR "%s: unhandled error %d.\n",
84 __func__, status);
85 case -NFS4ERR_EXPIRED:
86 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
87 case -NFS4ERR_STALE_CLIENTID:
88 nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs_client);
89 goto out_err;
90 }
91 } 88 }
92 return 0; 89 unlock_kernel();
93out_err: 90out:
94 return status; 91 return status;
95} 92}
96 93
@@ -268,7 +265,10 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
268 struct nfs_inode *nfsi = NFS_I(inode); 265 struct nfs_inode *nfsi = NFS_I(inode);
269 266
270 nfs_msync_inode(inode); 267 nfs_msync_inode(inode);
271 /* Guard against new delegated open calls */ 268 /*
269 * Guard against new delegated open/lock/unlock calls and against
270 * state recovery
271 */
272 down_write(&nfsi->rwsem); 272 down_write(&nfsi->rwsem);
273 nfs_delegation_claim_opens(inode, &delegation->stateid); 273 nfs_delegation_claim_opens(inode, &delegation->stateid);
274 up_write(&nfsi->rwsem); 274 up_write(&nfsi->rwsem);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 08f6b040d289..489fc01a3204 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -259,6 +259,9 @@ static void nfs_direct_read_release(void *calldata)
259} 259}
260 260
261static const struct rpc_call_ops nfs_read_direct_ops = { 261static const struct rpc_call_ops nfs_read_direct_ops = {
262#if defined(CONFIG_NFS_V4_1)
263 .rpc_call_prepare = nfs_read_prepare,
264#endif /* CONFIG_NFS_V4_1 */
262 .rpc_call_done = nfs_direct_read_result, 265 .rpc_call_done = nfs_direct_read_result,
263 .rpc_release = nfs_direct_read_release, 266 .rpc_release = nfs_direct_read_release,
264}; 267};
@@ -535,6 +538,9 @@ static void nfs_direct_commit_release(void *calldata)
535} 538}
536 539
537static const struct rpc_call_ops nfs_commit_direct_ops = { 540static const struct rpc_call_ops nfs_commit_direct_ops = {
541#if defined(CONFIG_NFS_V4_1)
542 .rpc_call_prepare = nfs_write_prepare,
543#endif /* CONFIG_NFS_V4_1 */
538 .rpc_call_done = nfs_direct_commit_result, 544 .rpc_call_done = nfs_direct_commit_result,
539 .rpc_release = nfs_direct_commit_release, 545 .rpc_release = nfs_direct_commit_release,
540}; 546};
@@ -673,6 +679,9 @@ out_unlock:
673} 679}
674 680
675static const struct rpc_call_ops nfs_write_direct_ops = { 681static const struct rpc_call_ops nfs_write_direct_ops = {
682#if defined(CONFIG_NFS_V4_1)
683 .rpc_call_prepare = nfs_write_prepare,
684#endif /* CONFIG_NFS_V4_1 */
676 .rpc_call_done = nfs_direct_write_result, 685 .rpc_call_done = nfs_direct_write_result,
677 .rpc_release = nfs_direct_write_release, 686 .rpc_release = nfs_direct_write_release,
678}; 687};
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index ec7e27d00bc6..0055b813ec2c 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -48,6 +48,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
48 size_t count, unsigned int flags); 48 size_t count, unsigned int flags);
49static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, 49static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
50 unsigned long nr_segs, loff_t pos); 50 unsigned long nr_segs, loff_t pos);
51static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
52 struct file *filp, loff_t *ppos,
53 size_t count, unsigned int flags);
51static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 54static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
52 unsigned long nr_segs, loff_t pos); 55 unsigned long nr_segs, loff_t pos);
53static int nfs_file_flush(struct file *, fl_owner_t id); 56static int nfs_file_flush(struct file *, fl_owner_t id);
@@ -73,6 +76,7 @@ const struct file_operations nfs_file_operations = {
73 .lock = nfs_lock, 76 .lock = nfs_lock,
74 .flock = nfs_flock, 77 .flock = nfs_flock,
75 .splice_read = nfs_file_splice_read, 78 .splice_read = nfs_file_splice_read,
79 .splice_write = nfs_file_splice_write,
76 .check_flags = nfs_check_flags, 80 .check_flags = nfs_check_flags,
77 .setlease = nfs_setlease, 81 .setlease = nfs_setlease,
78}; 82};
@@ -587,12 +591,38 @@ out_swapfile:
587 goto out; 591 goto out;
588} 592}
589 593
594static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
595 struct file *filp, loff_t *ppos,
596 size_t count, unsigned int flags)
597{
598 struct dentry *dentry = filp->f_path.dentry;
599 struct inode *inode = dentry->d_inode;
600 ssize_t ret;
601
602 dprintk("NFS splice_write(%s/%s, %lu@%llu)\n",
603 dentry->d_parent->d_name.name, dentry->d_name.name,
604 (unsigned long) count, (unsigned long long) *ppos);
605
606 /*
607 * The combination of splice and an O_APPEND destination is disallowed.
608 */
609
610 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
611
612 ret = generic_file_splice_write(pipe, filp, ppos, count, flags);
613 if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
614 int err = nfs_do_fsync(nfs_file_open_context(filp), inode);
615 if (err < 0)
616 ret = err;
617 }
618 return ret;
619}
620
590static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) 621static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
591{ 622{
592 struct inode *inode = filp->f_mapping->host; 623 struct inode *inode = filp->f_mapping->host;
593 int status = 0; 624 int status = 0;
594 625
595 lock_kernel();
596 /* Try local locking first */ 626 /* Try local locking first */
597 posix_test_lock(filp, fl); 627 posix_test_lock(filp, fl);
598 if (fl->fl_type != F_UNLCK) { 628 if (fl->fl_type != F_UNLCK) {
@@ -608,7 +638,6 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
608 638
609 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 639 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
610out: 640out:
611 unlock_kernel();
612 return status; 641 return status;
613out_noconflict: 642out_noconflict:
614 fl->fl_type = F_UNLCK; 643 fl->fl_type = F_UNLCK;
@@ -650,13 +679,11 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
650 * If we're signalled while cleaning up locks on process exit, we 679 * If we're signalled while cleaning up locks on process exit, we
651 * still need to complete the unlock. 680 * still need to complete the unlock.
652 */ 681 */
653 lock_kernel();
654 /* Use local locking if mounted with "-onolock" */ 682 /* Use local locking if mounted with "-onolock" */
655 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 683 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
656 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 684 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
657 else 685 else
658 status = do_vfs_lock(filp, fl); 686 status = do_vfs_lock(filp, fl);
659 unlock_kernel();
660 return status; 687 return status;
661} 688}
662 689
@@ -673,13 +700,11 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
673 if (status != 0) 700 if (status != 0)
674 goto out; 701 goto out;
675 702
676 lock_kernel();
677 /* Use local locking if mounted with "-onolock" */ 703 /* Use local locking if mounted with "-onolock" */
678 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 704 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
679 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 705 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
680 else 706 else
681 status = do_vfs_lock(filp, fl); 707 status = do_vfs_lock(filp, fl);
682 unlock_kernel();
683 if (status < 0) 708 if (status < 0)
684 goto out; 709 goto out;
685 /* 710 /*
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e4d6a8348adf..7dd90a6769d0 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -2,6 +2,7 @@
2 * NFS internal definitions 2 * NFS internal definitions
3 */ 3 */
4 4
5#include "nfs4_fs.h"
5#include <linux/mount.h> 6#include <linux/mount.h>
6#include <linux/security.h> 7#include <linux/security.h>
7 8
@@ -17,6 +18,18 @@ struct nfs_string;
17 */ 18 */
18#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 19#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
19 20
21/*
22 * Determine if sessions are in use.
23 */
24static inline int nfs4_has_session(const struct nfs_client *clp)
25{
26#ifdef CONFIG_NFS_V4_1
27 if (clp->cl_session)
28 return 1;
29#endif /* CONFIG_NFS_V4_1 */
30 return 0;
31}
32
20struct nfs_clone_mount { 33struct nfs_clone_mount {
21 const struct super_block *sb; 34 const struct super_block *sb;
22 const struct dentry *dentry; 35 const struct dentry *dentry;
@@ -30,6 +43,12 @@ struct nfs_clone_mount {
30}; 43};
31 44
32/* 45/*
46 * Note: RFC 1813 doesn't limit the number of auth flavors that
47 * a server can return, so make something up.
48 */
49#define NFS_MAX_SECFLAVORS (12)
50
51/*
33 * In-kernel mount arguments 52 * In-kernel mount arguments
34 */ 53 */
35struct nfs_parsed_mount_data { 54struct nfs_parsed_mount_data {
@@ -44,6 +63,7 @@ struct nfs_parsed_mount_data {
44 unsigned int auth_flavor_len; 63 unsigned int auth_flavor_len;
45 rpc_authflavor_t auth_flavors[1]; 64 rpc_authflavor_t auth_flavors[1];
46 char *client_address; 65 char *client_address;
66 unsigned int minorversion;
47 char *fscache_uniq; 67 char *fscache_uniq;
48 68
49 struct { 69 struct {
@@ -77,6 +97,8 @@ struct nfs_mount_request {
77 unsigned short protocol; 97 unsigned short protocol;
78 struct nfs_fh *fh; 98 struct nfs_fh *fh;
79 int noresvport; 99 int noresvport;
100 unsigned int *auth_flav_len;
101 rpc_authflavor_t *auth_flavs;
80}; 102};
81 103
82extern int nfs_mount(struct nfs_mount_request *info); 104extern int nfs_mount(struct nfs_mount_request *info);
@@ -99,6 +121,8 @@ extern void nfs_free_server(struct nfs_server *server);
99extern struct nfs_server *nfs_clone_server(struct nfs_server *, 121extern struct nfs_server *nfs_clone_server(struct nfs_server *,
100 struct nfs_fh *, 122 struct nfs_fh *,
101 struct nfs_fattr *); 123 struct nfs_fattr *);
124extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
125extern int nfs4_check_client_ready(struct nfs_client *clp);
102#ifdef CONFIG_PROC_FS 126#ifdef CONFIG_PROC_FS
103extern int __init nfs_fs_proc_init(void); 127extern int __init nfs_fs_proc_init(void);
104extern void nfs_fs_proc_exit(void); 128extern void nfs_fs_proc_exit(void);
@@ -146,6 +170,20 @@ extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
146extern struct rpc_procinfo nfs3_procedures[]; 170extern struct rpc_procinfo nfs3_procedures[];
147extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int); 171extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
148 172
173/* nfs4proc.c */
174static inline void nfs4_restart_rpc(struct rpc_task *task,
175 const struct nfs_client *clp)
176{
177#ifdef CONFIG_NFS_V4_1
178 if (nfs4_has_session(clp) &&
179 test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
180 rpc_restart_call_prepare(task);
181 return;
182 }
183#endif /* CONFIG_NFS_V4_1 */
184 rpc_restart_call(task);
185}
186
149/* nfs4xdr.c */ 187/* nfs4xdr.c */
150#ifdef CONFIG_NFS_V4 188#ifdef CONFIG_NFS_V4
151extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); 189extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
@@ -205,6 +243,38 @@ extern int nfs4_path_walk(struct nfs_server *server,
205 const char *path); 243 const char *path);
206#endif 244#endif
207 245
246/* read.c */
247extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
248
249/* write.c */
250extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
251
252/* nfs4proc.c */
253extern int _nfs4_call_sync(struct nfs_server *server,
254 struct rpc_message *msg,
255 struct nfs4_sequence_args *args,
256 struct nfs4_sequence_res *res,
257 int cache_reply);
258extern int _nfs4_call_sync_session(struct nfs_server *server,
259 struct rpc_message *msg,
260 struct nfs4_sequence_args *args,
261 struct nfs4_sequence_res *res,
262 int cache_reply);
263
264#ifdef CONFIG_NFS_V4_1
265extern void nfs41_sequence_free_slot(const struct nfs_client *,
266 struct nfs4_sequence_res *res);
267#endif /* CONFIG_NFS_V4_1 */
268
269static inline void nfs4_sequence_free_slot(const struct nfs_client *clp,
270 struct nfs4_sequence_res *res)
271{
272#ifdef CONFIG_NFS_V4_1
273 if (nfs4_has_session(clp))
274 nfs41_sequence_free_slot(clp, res);
275#endif /* CONFIG_NFS_V4_1 */
276}
277
208/* 278/*
209 * Determine the device name as a string 279 * Determine the device name as a string
210 */ 280 */
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index ca905a5bb1ba..38ef9eaec407 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -20,8 +20,116 @@
20# define NFSDBG_FACILITY NFSDBG_MOUNT 20# define NFSDBG_FACILITY NFSDBG_MOUNT
21#endif 21#endif
22 22
23/*
24 * Defined by RFC 1094, section A.3; and RFC 1813, section 5.1.4
25 */
26#define MNTPATHLEN (1024)
27
28/*
29 * XDR data type sizes
30 */
31#define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN))
32#define MNT_status_sz (1)
33#define MNT_fhs_status_sz (1)
34#define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE)
35#define MNT_fhandle3_sz (1 + XDR_QUADLEN(NFS3_FHSIZE))
36#define MNT_authflav3_sz (1 + NFS_MAX_SECFLAVORS)
37
38/*
39 * XDR argument and result sizes
40 */
41#define MNT_enc_dirpath_sz encode_dirpath_sz
42#define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz)
43#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandle_sz + \
44 MNT_authflav3_sz)
45
46/*
47 * Defined by RFC 1094, section A.5
48 */
49enum {
50 MOUNTPROC_NULL = 0,
51 MOUNTPROC_MNT = 1,
52 MOUNTPROC_DUMP = 2,
53 MOUNTPROC_UMNT = 3,
54 MOUNTPROC_UMNTALL = 4,
55 MOUNTPROC_EXPORT = 5,
56};
57
58/*
59 * Defined by RFC 1813, section 5.2
60 */
61enum {
62 MOUNTPROC3_NULL = 0,
63 MOUNTPROC3_MNT = 1,
64 MOUNTPROC3_DUMP = 2,
65 MOUNTPROC3_UMNT = 3,
66 MOUNTPROC3_UMNTALL = 4,
67 MOUNTPROC3_EXPORT = 5,
68};
69
23static struct rpc_program mnt_program; 70static struct rpc_program mnt_program;
24 71
72/*
73 * Defined by OpenGroup XNFS Version 3W, chapter 8
74 */
75enum mountstat {
76 MNT_OK = 0,
77 MNT_EPERM = 1,
78 MNT_ENOENT = 2,
79 MNT_EACCES = 13,
80 MNT_EINVAL = 22,
81};
82
83static struct {
84 u32 status;
85 int errno;
86} mnt_errtbl[] = {
87 { .status = MNT_OK, .errno = 0, },
88 { .status = MNT_EPERM, .errno = -EPERM, },
89 { .status = MNT_ENOENT, .errno = -ENOENT, },
90 { .status = MNT_EACCES, .errno = -EACCES, },
91 { .status = MNT_EINVAL, .errno = -EINVAL, },
92};
93
94/*
95 * Defined by RFC 1813, section 5.1.5
96 */
97enum mountstat3 {
98 MNT3_OK = 0, /* no error */
99 MNT3ERR_PERM = 1, /* Not owner */
100 MNT3ERR_NOENT = 2, /* No such file or directory */
101 MNT3ERR_IO = 5, /* I/O error */
102 MNT3ERR_ACCES = 13, /* Permission denied */
103 MNT3ERR_NOTDIR = 20, /* Not a directory */
104 MNT3ERR_INVAL = 22, /* Invalid argument */
105 MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
106 MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
107 MNT3ERR_SERVERFAULT = 10006, /* A failure on the server */
108};
109
110static struct {
111 u32 status;
112 int errno;
113} mnt3_errtbl[] = {
114 { .status = MNT3_OK, .errno = 0, },
115 { .status = MNT3ERR_PERM, .errno = -EPERM, },
116 { .status = MNT3ERR_NOENT, .errno = -ENOENT, },
117 { .status = MNT3ERR_IO, .errno = -EIO, },
118 { .status = MNT3ERR_ACCES, .errno = -EACCES, },
119 { .status = MNT3ERR_NOTDIR, .errno = -ENOTDIR, },
120 { .status = MNT3ERR_INVAL, .errno = -EINVAL, },
121 { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, },
122 { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, },
123 { .status = MNT3ERR_SERVERFAULT, .errno = -ESERVERFAULT, },
124};
125
126struct mountres {
127 int errno;
128 struct nfs_fh *fh;
129 unsigned int *auth_count;
130 rpc_authflavor_t *auth_flavors;
131};
132
25struct mnt_fhstatus { 133struct mnt_fhstatus {
26 u32 status; 134 u32 status;
27 struct nfs_fh *fh; 135 struct nfs_fh *fh;
@@ -35,8 +143,10 @@ struct mnt_fhstatus {
35 */ 143 */
36int nfs_mount(struct nfs_mount_request *info) 144int nfs_mount(struct nfs_mount_request *info)
37{ 145{
38 struct mnt_fhstatus result = { 146 struct mountres result = {
39 .fh = info->fh 147 .fh = info->fh,
148 .auth_count = info->auth_flav_len,
149 .auth_flavors = info->auth_flavs,
40 }; 150 };
41 struct rpc_message msg = { 151 struct rpc_message msg = {
42 .rpc_argp = info->dirpath, 152 .rpc_argp = info->dirpath,
@@ -68,14 +178,14 @@ int nfs_mount(struct nfs_mount_request *info)
68 if (info->version == NFS_MNT3_VERSION) 178 if (info->version == NFS_MNT3_VERSION)
69 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT]; 179 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
70 else 180 else
71 msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT]; 181 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
72 182
73 status = rpc_call_sync(mnt_clnt, &msg, 0); 183 status = rpc_call_sync(mnt_clnt, &msg, 0);
74 rpc_shutdown_client(mnt_clnt); 184 rpc_shutdown_client(mnt_clnt);
75 185
76 if (status < 0) 186 if (status < 0)
77 goto out_call_err; 187 goto out_call_err;
78 if (result.status != 0) 188 if (result.errno != 0)
79 goto out_mnt_err; 189 goto out_mnt_err;
80 190
81 dprintk("NFS: MNT request succeeded\n"); 191 dprintk("NFS: MNT request succeeded\n");
@@ -86,72 +196,215 @@ out:
86 196
87out_clnt_err: 197out_clnt_err:
88 status = PTR_ERR(mnt_clnt); 198 status = PTR_ERR(mnt_clnt);
89 dprintk("NFS: failed to create RPC client, status=%d\n", status); 199 dprintk("NFS: failed to create MNT RPC client, status=%d\n", status);
90 goto out; 200 goto out;
91 201
92out_call_err: 202out_call_err:
93 dprintk("NFS: failed to start MNT request, status=%d\n", status); 203 dprintk("NFS: MNT request failed, status=%d\n", status);
94 goto out; 204 goto out;
95 205
96out_mnt_err: 206out_mnt_err:
97 dprintk("NFS: MNT server returned result %d\n", result.status); 207 dprintk("NFS: MNT server returned result %d\n", result.errno);
98 status = nfs_stat_to_errno(result.status); 208 status = result.errno;
99 goto out; 209 goto out;
100} 210}
101 211
102/* 212/*
103 * XDR encode/decode functions for MOUNT 213 * XDR encode/decode functions for MOUNT
104 */ 214 */
105static int xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, 215
106 const char *path) 216static int encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
217{
218 const u32 pathname_len = strlen(pathname);
219 __be32 *p;
220
221 if (unlikely(pathname_len > MNTPATHLEN))
222 return -EIO;
223
224 p = xdr_reserve_space(xdr, sizeof(u32) + pathname_len);
225 if (unlikely(p == NULL))
226 return -EIO;
227 xdr_encode_opaque(p, pathname, pathname_len);
228
229 return 0;
230}
231
232static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p,
233 const char *dirpath)
234{
235 struct xdr_stream xdr;
236
237 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
238 return encode_mntdirpath(&xdr, dirpath);
239}
240
241/*
242 * RFC 1094: "A non-zero status indicates some sort of error. In this
243 * case, the status is a UNIX error number." This can be problematic
244 * if the server and client use different errno values for the same
245 * error.
246 *
247 * However, the OpenGroup XNFS spec provides a simple mapping that is
248 * independent of local errno values on the server and the client.
249 */
250static int decode_status(struct xdr_stream *xdr, struct mountres *res)
107{ 251{
108 p = xdr_encode_string(p, path); 252 unsigned int i;
253 u32 status;
254 __be32 *p;
255
256 p = xdr_inline_decode(xdr, sizeof(status));
257 if (unlikely(p == NULL))
258 return -EIO;
259 status = ntohl(*p);
109 260
110 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); 261 for (i = 0; i <= ARRAY_SIZE(mnt_errtbl); i++) {
262 if (mnt_errtbl[i].status == status) {
263 res->errno = mnt_errtbl[i].errno;
264 return 0;
265 }
266 }
267
268 dprintk("NFS: unrecognized MNT status code: %u\n", status);
269 res->errno = -EACCES;
111 return 0; 270 return 0;
112} 271}
113 272
114static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, 273static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
115 struct mnt_fhstatus *res)
116{ 274{
117 struct nfs_fh *fh = res->fh; 275 struct nfs_fh *fh = res->fh;
276 __be32 *p;
277
278 p = xdr_inline_decode(xdr, NFS2_FHSIZE);
279 if (unlikely(p == NULL))
280 return -EIO;
281
282 fh->size = NFS2_FHSIZE;
283 memcpy(fh->data, p, NFS2_FHSIZE);
284 return 0;
285}
286
287static int mnt_dec_mountres(struct rpc_rqst *req, __be32 *p,
288 struct mountres *res)
289{
290 struct xdr_stream xdr;
291 int status;
292
293 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
294
295 status = decode_status(&xdr, res);
296 if (unlikely(status != 0 || res->errno != 0))
297 return status;
298 return decode_fhandle(&xdr, res);
299}
300
301static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
302{
303 unsigned int i;
304 u32 status;
305 __be32 *p;
118 306
119 if ((res->status = ntohl(*p++)) == 0) { 307 p = xdr_inline_decode(xdr, sizeof(status));
120 fh->size = NFS2_FHSIZE; 308 if (unlikely(p == NULL))
121 memcpy(fh->data, p, NFS2_FHSIZE); 309 return -EIO;
310 status = ntohl(*p);
311
312 for (i = 0; i <= ARRAY_SIZE(mnt3_errtbl); i++) {
313 if (mnt3_errtbl[i].status == status) {
314 res->errno = mnt3_errtbl[i].errno;
315 return 0;
316 }
122 } 317 }
318
319 dprintk("NFS: unrecognized MNT3 status code: %u\n", status);
320 res->errno = -EACCES;
123 return 0; 321 return 0;
124} 322}
125 323
126static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, 324static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res)
127 struct mnt_fhstatus *res)
128{ 325{
129 struct nfs_fh *fh = res->fh; 326 struct nfs_fh *fh = res->fh;
130 unsigned size; 327 u32 size;
131 328 __be32 *p;
132 if ((res->status = ntohl(*p++)) == 0) { 329
133 size = ntohl(*p++); 330 p = xdr_inline_decode(xdr, sizeof(size));
134 if (size <= NFS3_FHSIZE && size != 0) { 331 if (unlikely(p == NULL))
135 fh->size = size; 332 return -EIO;
136 memcpy(fh->data, p, size); 333
137 } else 334 size = ntohl(*p++);
138 res->status = -EBADHANDLE; 335 if (size > NFS3_FHSIZE || size == 0)
336 return -EIO;
337
338 p = xdr_inline_decode(xdr, size);
339 if (unlikely(p == NULL))
340 return -EIO;
341
342 fh->size = size;
343 memcpy(fh->data, p, size);
344 return 0;
345}
346
347static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
348{
349 rpc_authflavor_t *flavors = res->auth_flavors;
350 unsigned int *count = res->auth_count;
351 u32 entries, i;
352 __be32 *p;
353
354 if (*count == 0)
355 return 0;
356
357 p = xdr_inline_decode(xdr, sizeof(entries));
358 if (unlikely(p == NULL))
359 return -EIO;
360 entries = ntohl(*p);
361 dprintk("NFS: received %u auth flavors\n", entries);
362 if (entries > NFS_MAX_SECFLAVORS)
363 entries = NFS_MAX_SECFLAVORS;
364
365 p = xdr_inline_decode(xdr, sizeof(u32) * entries);
366 if (unlikely(p == NULL))
367 return -EIO;
368
369 if (entries > *count)
370 entries = *count;
371
372 for (i = 0; i < entries; i++) {
373 flavors[i] = ntohl(*p++);
374 dprintk("NFS:\tflavor %u: %d\n", i, flavors[i]);
139 } 375 }
376 *count = i;
377
140 return 0; 378 return 0;
141} 379}
142 380
143#define MNT_dirpath_sz (1 + 256) 381static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p,
144#define MNT_fhstatus_sz (1 + 8) 382 struct mountres *res)
145#define MNT_fhstatus3_sz (1 + 16) 383{
384 struct xdr_stream xdr;
385 int status;
386
387 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
388
389 status = decode_fhs_status(&xdr, res);
390 if (unlikely(status != 0 || res->errno != 0))
391 return status;
392 status = decode_fhandle3(&xdr, res);
393 if (unlikely(status != 0)) {
394 res->errno = -EBADHANDLE;
395 return 0;
396 }
397 return decode_auth_flavors(&xdr, res);
398}
146 399
147static struct rpc_procinfo mnt_procedures[] = { 400static struct rpc_procinfo mnt_procedures[] = {
148 [MNTPROC_MNT] = { 401 [MOUNTPROC_MNT] = {
149 .p_proc = MNTPROC_MNT, 402 .p_proc = MOUNTPROC_MNT,
150 .p_encode = (kxdrproc_t) xdr_encode_dirpath, 403 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
151 .p_decode = (kxdrproc_t) xdr_decode_fhstatus, 404 .p_decode = (kxdrproc_t)mnt_dec_mountres,
152 .p_arglen = MNT_dirpath_sz, 405 .p_arglen = MNT_enc_dirpath_sz,
153 .p_replen = MNT_fhstatus_sz, 406 .p_replen = MNT_dec_mountres_sz,
154 .p_statidx = MNTPROC_MNT, 407 .p_statidx = MOUNTPROC_MNT,
155 .p_name = "MOUNT", 408 .p_name = "MOUNT",
156 }, 409 },
157}; 410};
@@ -159,10 +412,10 @@ static struct rpc_procinfo mnt_procedures[] = {
159static struct rpc_procinfo mnt3_procedures[] = { 412static struct rpc_procinfo mnt3_procedures[] = {
160 [MOUNTPROC3_MNT] = { 413 [MOUNTPROC3_MNT] = {
161 .p_proc = MOUNTPROC3_MNT, 414 .p_proc = MOUNTPROC3_MNT,
162 .p_encode = (kxdrproc_t) xdr_encode_dirpath, 415 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
163 .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, 416 .p_decode = (kxdrproc_t)mnt_dec_mountres3,
164 .p_arglen = MNT_dirpath_sz, 417 .p_arglen = MNT_enc_dirpath_sz,
165 .p_replen = MNT_fhstatus3_sz, 418 .p_replen = MNT_dec_mountres3_sz,
166 .p_statidx = MOUNTPROC3_MNT, 419 .p_statidx = MOUNTPROC3_MNT,
167 .p_name = "MOUNT", 420 .p_name = "MOUNT",
168 }, 421 },
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 6bbf0e6daad2..bac60515a4b3 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -207,8 +207,6 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
207 status = nfs_revalidate_inode(server, inode); 207 status = nfs_revalidate_inode(server, inode);
208 if (status < 0) 208 if (status < 0)
209 return ERR_PTR(status); 209 return ERR_PTR(status);
210 if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
211 nfs_zap_acl_cache(inode);
212 acl = nfs3_get_cached_acl(inode, type); 210 acl = nfs3_get_cached_acl(inode, type);
213 if (acl != ERR_PTR(-EAGAIN)) 211 if (acl != ERR_PTR(-EAGAIN))
214 return acl; 212 return acl;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 84345deab26f..61bc3a32e1e2 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -44,6 +44,7 @@ enum nfs4_client_state {
44 NFS4CLNT_RECLAIM_REBOOT, 44 NFS4CLNT_RECLAIM_REBOOT,
45 NFS4CLNT_RECLAIM_NOGRACE, 45 NFS4CLNT_RECLAIM_NOGRACE,
46 NFS4CLNT_DELEGRETURN, 46 NFS4CLNT_DELEGRETURN,
47 NFS4CLNT_SESSION_SETUP,
47}; 48};
48 49
49/* 50/*
@@ -177,6 +178,14 @@ struct nfs4_state_recovery_ops {
177 int state_flag_bit; 178 int state_flag_bit;
178 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); 179 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
179 int (*recover_lock)(struct nfs4_state *, struct file_lock *); 180 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
181 int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
182 struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
183};
184
185struct nfs4_state_maintenance_ops {
186 int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *);
187 struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);
188 int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
180}; 189};
181 190
182extern const struct dentry_operations nfs4_dentry_operations; 191extern const struct dentry_operations nfs4_dentry_operations;
@@ -193,6 +202,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
193extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); 202extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
194extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); 203extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
195extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); 204extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
205extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
196extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait); 206extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
197extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 207extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
198extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 208extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -200,8 +210,26 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fh
200extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, 210extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
201 struct nfs4_fs_locations *fs_locations, struct page *page); 211 struct nfs4_fs_locations *fs_locations, struct page *page);
202 212
203extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; 213extern struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[];
204extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops; 214extern struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[];
215#if defined(CONFIG_NFS_V4_1)
216extern int nfs4_setup_sequence(struct nfs_client *clp,
217 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
218 int cache_reply, struct rpc_task *task);
219extern void nfs4_destroy_session(struct nfs4_session *session);
220extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
221extern int nfs4_proc_create_session(struct nfs_client *, int reset);
222extern int nfs4_proc_destroy_session(struct nfs4_session *);
223#else /* CONFIG_NFS_v4_1 */
224static inline int nfs4_setup_sequence(struct nfs_client *clp,
225 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
226 int cache_reply, struct rpc_task *task)
227{
228 return 0;
229}
230#endif /* CONFIG_NFS_V4_1 */
231
232extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[];
205 233
206extern const u32 nfs4_fattr_bitmap[2]; 234extern const u32 nfs4_fattr_bitmap[2];
207extern const u32 nfs4_statfs_bitmap[2]; 235extern const u32 nfs4_statfs_bitmap[2];
@@ -216,7 +244,12 @@ extern void nfs4_kill_renewd(struct nfs_client *);
216extern void nfs4_renew_state(struct work_struct *); 244extern void nfs4_renew_state(struct work_struct *);
217 245
218/* nfs4state.c */ 246/* nfs4state.c */
247struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
219struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); 248struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
249#if defined(CONFIG_NFS_V4_1)
250struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
251struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
252#endif /* CONFIG_NFS_V4_1 */
220 253
221extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); 254extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
222extern void nfs4_put_state_owner(struct nfs4_state_owner *); 255extern void nfs4_put_state_owner(struct nfs4_state_owner *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4674f8092da8..92ce43517814 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -48,11 +48,14 @@
48#include <linux/smp_lock.h> 48#include <linux/smp_lock.h>
49#include <linux/namei.h> 49#include <linux/namei.h>
50#include <linux/mount.h> 50#include <linux/mount.h>
51#include <linux/module.h>
52#include <linux/sunrpc/bc_xprt.h>
51 53
52#include "nfs4_fs.h" 54#include "nfs4_fs.h"
53#include "delegation.h" 55#include "delegation.h"
54#include "internal.h" 56#include "internal.h"
55#include "iostat.h" 57#include "iostat.h"
58#include "callback.h"
56 59
57#define NFSDBG_FACILITY NFSDBG_PROC 60#define NFSDBG_FACILITY NFSDBG_PROC
58 61
@@ -247,7 +250,25 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
247 ret = nfs4_wait_clnt_recover(clp); 250 ret = nfs4_wait_clnt_recover(clp);
248 if (ret == 0) 251 if (ret == 0)
249 exception->retry = 1; 252 exception->retry = 1;
253#if !defined(CONFIG_NFS_V4_1)
250 break; 254 break;
255#else /* !defined(CONFIG_NFS_V4_1) */
256 if (!nfs4_has_session(server->nfs_client))
257 break;
258 /* FALLTHROUGH */
259 case -NFS4ERR_BADSESSION:
260 case -NFS4ERR_BADSLOT:
261 case -NFS4ERR_BAD_HIGH_SLOT:
262 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
263 case -NFS4ERR_DEADSESSION:
264 case -NFS4ERR_SEQ_FALSE_RETRY:
265 case -NFS4ERR_SEQ_MISORDERED:
266 dprintk("%s ERROR: %d Reset session\n", __func__,
267 errorcode);
268 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
269 exception->retry = 1;
270 /* FALLTHROUGH */
271#endif /* !defined(CONFIG_NFS_V4_1) */
251 case -NFS4ERR_FILE_OPEN: 272 case -NFS4ERR_FILE_OPEN:
252 case -NFS4ERR_GRACE: 273 case -NFS4ERR_GRACE:
253 case -NFS4ERR_DELAY: 274 case -NFS4ERR_DELAY:
@@ -271,6 +292,353 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
271 spin_unlock(&clp->cl_lock); 292 spin_unlock(&clp->cl_lock);
272} 293}
273 294
295#if defined(CONFIG_NFS_V4_1)
296
297/*
298 * nfs4_free_slot - free a slot and efficiently update slot table.
299 *
300 * freeing a slot is trivially done by clearing its respective bit
301 * in the bitmap.
302 * If the freed slotid equals highest_used_slotid we want to update it
303 * so that the server would be able to size down the slot table if needed,
304 * otherwise we know that the highest_used_slotid is still in use.
305 * When updating highest_used_slotid there may be "holes" in the bitmap
306 * so we need to scan down from highest_used_slotid to 0 looking for the now
307 * highest slotid in use.
308 * If none found, highest_used_slotid is set to -1.
309 */
310static void
311nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
312{
313 int slotid = free_slotid;
314
315 spin_lock(&tbl->slot_tbl_lock);
316 /* clear used bit in bitmap */
317 __clear_bit(slotid, tbl->used_slots);
318
319 /* update highest_used_slotid when it is freed */
320 if (slotid == tbl->highest_used_slotid) {
321 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
322 if (slotid >= 0 && slotid < tbl->max_slots)
323 tbl->highest_used_slotid = slotid;
324 else
325 tbl->highest_used_slotid = -1;
326 }
327 rpc_wake_up_next(&tbl->slot_tbl_waitq);
328 spin_unlock(&tbl->slot_tbl_lock);
329 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
330 free_slotid, tbl->highest_used_slotid);
331}
332
333void nfs41_sequence_free_slot(const struct nfs_client *clp,
334 struct nfs4_sequence_res *res)
335{
336 struct nfs4_slot_table *tbl;
337
338 if (!nfs4_has_session(clp)) {
339 dprintk("%s: No session\n", __func__);
340 return;
341 }
342 tbl = &clp->cl_session->fc_slot_table;
343 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
344 dprintk("%s: No slot\n", __func__);
345 /* just wake up the next guy waiting since
346 * we may have not consumed a slot after all */
347 rpc_wake_up_next(&tbl->slot_tbl_waitq);
348 return;
349 }
350 nfs4_free_slot(tbl, res->sr_slotid);
351 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
352}
353
354static void nfs41_sequence_done(struct nfs_client *clp,
355 struct nfs4_sequence_res *res,
356 int rpc_status)
357{
358 unsigned long timestamp;
359 struct nfs4_slot_table *tbl;
360 struct nfs4_slot *slot;
361
362 /*
363 * sr_status remains 1 if an RPC level error occurred. The server
364 * may or may not have processed the sequence operation..
365 * Proceed as if the server received and processed the sequence
366 * operation.
367 */
368 if (res->sr_status == 1)
369 res->sr_status = NFS_OK;
370
371 /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
372 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
373 goto out;
374
375 tbl = &clp->cl_session->fc_slot_table;
376 slot = tbl->slots + res->sr_slotid;
377
378 if (res->sr_status == 0) {
379 /* Update the slot's sequence and clientid lease timer */
380 ++slot->seq_nr;
381 timestamp = res->sr_renewal_time;
382 spin_lock(&clp->cl_lock);
383 if (time_before(clp->cl_last_renewal, timestamp))
384 clp->cl_last_renewal = timestamp;
385 spin_unlock(&clp->cl_lock);
386 return;
387 }
388out:
389 /* The session may be reset by one of the error handlers. */
390 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
391 nfs41_sequence_free_slot(clp, res);
392}
393
394/*
395 * nfs4_find_slot - efficiently look for a free slot
396 *
397 * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
398 * If found, we mark the slot as used, update the highest_used_slotid,
399 * and respectively set up the sequence operation args.
400 * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
401 *
402 * Note: must be called with under the slot_tbl_lock.
403 */
404static u8
405nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
406{
407 int slotid;
408 u8 ret_id = NFS4_MAX_SLOT_TABLE;
409 BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
410
411 dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
412 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
413 tbl->max_slots);
414 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
415 if (slotid >= tbl->max_slots)
416 goto out;
417 __set_bit(slotid, tbl->used_slots);
418 if (slotid > tbl->highest_used_slotid)
419 tbl->highest_used_slotid = slotid;
420 ret_id = slotid;
421out:
422 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
423 __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
424 return ret_id;
425}
426
427static int nfs4_recover_session(struct nfs4_session *session)
428{
429 struct nfs_client *clp = session->clp;
430 int ret;
431
432 for (;;) {
433 ret = nfs4_wait_clnt_recover(clp);
434 if (ret != 0)
435 return ret;
436 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
437 break;
438 nfs4_schedule_state_manager(clp);
439 }
440 return 0;
441}
442
443static int nfs41_setup_sequence(struct nfs4_session *session,
444 struct nfs4_sequence_args *args,
445 struct nfs4_sequence_res *res,
446 int cache_reply,
447 struct rpc_task *task)
448{
449 struct nfs4_slot *slot;
450 struct nfs4_slot_table *tbl;
451 int status = 0;
452 u8 slotid;
453
454 dprintk("--> %s\n", __func__);
455 /* slot already allocated? */
456 if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
457 return 0;
458
459 memset(res, 0, sizeof(*res));
460 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
461 tbl = &session->fc_slot_table;
462
463 spin_lock(&tbl->slot_tbl_lock);
464 if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) {
465 if (tbl->highest_used_slotid != -1) {
466 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
467 spin_unlock(&tbl->slot_tbl_lock);
468 dprintk("<-- %s: Session reset: draining\n", __func__);
469 return -EAGAIN;
470 }
471
472 /* The slot table is empty; start the reset thread */
473 dprintk("%s Session Reset\n", __func__);
474 spin_unlock(&tbl->slot_tbl_lock);
475 status = nfs4_recover_session(session);
476 if (status)
477 return status;
478 spin_lock(&tbl->slot_tbl_lock);
479 }
480
481 slotid = nfs4_find_slot(tbl, task);
482 if (slotid == NFS4_MAX_SLOT_TABLE) {
483 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
484 spin_unlock(&tbl->slot_tbl_lock);
485 dprintk("<-- %s: no free slots\n", __func__);
486 return -EAGAIN;
487 }
488 spin_unlock(&tbl->slot_tbl_lock);
489
490 slot = tbl->slots + slotid;
491 args->sa_session = session;
492 args->sa_slotid = slotid;
493 args->sa_cache_this = cache_reply;
494
495 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
496
497 res->sr_session = session;
498 res->sr_slotid = slotid;
499 res->sr_renewal_time = jiffies;
500 /*
501 * sr_status is only set in decode_sequence, and so will remain
502 * set to 1 if an rpc level failure occurs.
503 */
504 res->sr_status = 1;
505 return 0;
506}
507
508int nfs4_setup_sequence(struct nfs_client *clp,
509 struct nfs4_sequence_args *args,
510 struct nfs4_sequence_res *res,
511 int cache_reply,
512 struct rpc_task *task)
513{
514 int ret = 0;
515
516 dprintk("--> %s clp %p session %p sr_slotid %d\n",
517 __func__, clp, clp->cl_session, res->sr_slotid);
518
519 if (!nfs4_has_session(clp))
520 goto out;
521 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
522 task);
523 if (ret != -EAGAIN) {
524 /* terminate rpc task */
525 task->tk_status = ret;
526 task->tk_action = NULL;
527 }
528out:
529 dprintk("<-- %s status=%d\n", __func__, ret);
530 return ret;
531}
532
533struct nfs41_call_sync_data {
534 struct nfs_client *clp;
535 struct nfs4_sequence_args *seq_args;
536 struct nfs4_sequence_res *seq_res;
537 int cache_reply;
538};
539
540static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
541{
542 struct nfs41_call_sync_data *data = calldata;
543
544 dprintk("--> %s data->clp->cl_session %p\n", __func__,
545 data->clp->cl_session);
546 if (nfs4_setup_sequence(data->clp, data->seq_args,
547 data->seq_res, data->cache_reply, task))
548 return;
549 rpc_call_start(task);
550}
551
552static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
553{
554 struct nfs41_call_sync_data *data = calldata;
555
556 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
557 nfs41_sequence_free_slot(data->clp, data->seq_res);
558}
559
560struct rpc_call_ops nfs41_call_sync_ops = {
561 .rpc_call_prepare = nfs41_call_sync_prepare,
562 .rpc_call_done = nfs41_call_sync_done,
563};
564
565static int nfs4_call_sync_sequence(struct nfs_client *clp,
566 struct rpc_clnt *clnt,
567 struct rpc_message *msg,
568 struct nfs4_sequence_args *args,
569 struct nfs4_sequence_res *res,
570 int cache_reply)
571{
572 int ret;
573 struct rpc_task *task;
574 struct nfs41_call_sync_data data = {
575 .clp = clp,
576 .seq_args = args,
577 .seq_res = res,
578 .cache_reply = cache_reply,
579 };
580 struct rpc_task_setup task_setup = {
581 .rpc_client = clnt,
582 .rpc_message = msg,
583 .callback_ops = &nfs41_call_sync_ops,
584 .callback_data = &data
585 };
586
587 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
588 task = rpc_run_task(&task_setup);
589 if (IS_ERR(task))
590 ret = PTR_ERR(task);
591 else {
592 ret = task->tk_status;
593 rpc_put_task(task);
594 }
595 return ret;
596}
597
598int _nfs4_call_sync_session(struct nfs_server *server,
599 struct rpc_message *msg,
600 struct nfs4_sequence_args *args,
601 struct nfs4_sequence_res *res,
602 int cache_reply)
603{
604 return nfs4_call_sync_sequence(server->nfs_client, server->client,
605 msg, args, res, cache_reply);
606}
607
608#endif /* CONFIG_NFS_V4_1 */
609
610int _nfs4_call_sync(struct nfs_server *server,
611 struct rpc_message *msg,
612 struct nfs4_sequence_args *args,
613 struct nfs4_sequence_res *res,
614 int cache_reply)
615{
616 args->sa_session = res->sr_session = NULL;
617 return rpc_call_sync(server->client, msg, 0);
618}
619
620#define nfs4_call_sync(server, msg, args, res, cache_reply) \
621 (server)->nfs_client->cl_call_sync((server), (msg), &(args)->seq_args, \
622 &(res)->seq_res, (cache_reply))
623
624static void nfs4_sequence_done(const struct nfs_server *server,
625 struct nfs4_sequence_res *res, int rpc_status)
626{
627#ifdef CONFIG_NFS_V4_1
628 if (nfs4_has_session(server->nfs_client))
629 nfs41_sequence_done(server->nfs_client, res, rpc_status);
630#endif /* CONFIG_NFS_V4_1 */
631}
632
633/* no restart, therefore free slot here */
634static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
635 struct nfs4_sequence_res *res,
636 int rpc_status)
637{
638 nfs4_sequence_done(server, res, rpc_status);
639 nfs4_sequence_free_slot(server->nfs_client, res);
640}
641
274static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 642static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
275{ 643{
276 struct nfs_inode *nfsi = NFS_I(dir); 644 struct nfs_inode *nfsi = NFS_I(dir);
@@ -312,6 +680,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
312 p->o_res.server = p->o_arg.server; 680 p->o_res.server = p->o_arg.server;
313 nfs_fattr_init(&p->f_attr); 681 nfs_fattr_init(&p->f_attr);
314 nfs_fattr_init(&p->dir_attr); 682 nfs_fattr_init(&p->dir_attr);
683 p->o_res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
315} 684}
316 685
317static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, 686static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
@@ -804,16 +1173,30 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
804 err = _nfs4_open_delegation_recall(ctx, state, stateid); 1173 err = _nfs4_open_delegation_recall(ctx, state, stateid);
805 switch (err) { 1174 switch (err) {
806 case 0: 1175 case 0:
807 return err; 1176 case -ENOENT:
1177 case -ESTALE:
1178 goto out;
808 case -NFS4ERR_STALE_CLIENTID: 1179 case -NFS4ERR_STALE_CLIENTID:
809 case -NFS4ERR_STALE_STATEID: 1180 case -NFS4ERR_STALE_STATEID:
810 case -NFS4ERR_EXPIRED: 1181 case -NFS4ERR_EXPIRED:
811 /* Don't recall a delegation if it was lost */ 1182 /* Don't recall a delegation if it was lost */
812 nfs4_schedule_state_recovery(server->nfs_client); 1183 nfs4_schedule_state_recovery(server->nfs_client);
813 return err; 1184 goto out;
1185 case -ERESTARTSYS:
1186 /*
1187 * The show must go on: exit, but mark the
1188 * stateid as needing recovery.
1189 */
1190 case -NFS4ERR_ADMIN_REVOKED:
1191 case -NFS4ERR_BAD_STATEID:
1192 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);
1193 case -ENOMEM:
1194 err = 0;
1195 goto out;
814 } 1196 }
815 err = nfs4_handle_exception(server, err, &exception); 1197 err = nfs4_handle_exception(server, err, &exception);
816 } while (exception.retry); 1198 } while (exception.retry);
1199out:
817 return err; 1200 return err;
818} 1201}
819 1202
@@ -929,6 +1312,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
929 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); 1312 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
930 } 1313 }
931 data->timestamp = jiffies; 1314 data->timestamp = jiffies;
1315 if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
1316 &data->o_arg.seq_args,
1317 &data->o_res.seq_res, 1, task))
1318 return;
932 rpc_call_start(task); 1319 rpc_call_start(task);
933 return; 1320 return;
934out_no_action: 1321out_no_action:
@@ -941,6 +1328,10 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
941 struct nfs4_opendata *data = calldata; 1328 struct nfs4_opendata *data = calldata;
942 1329
943 data->rpc_status = task->tk_status; 1330 data->rpc_status = task->tk_status;
1331
1332 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res,
1333 task->tk_status);
1334
944 if (RPC_ASSASSINATED(task)) 1335 if (RPC_ASSASSINATED(task))
945 return; 1336 return;
946 if (task->tk_status == 0) { 1337 if (task->tk_status == 0) {
@@ -1269,7 +1660,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
1269 } else 1660 } else
1270 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); 1661 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
1271 1662
1272 status = rpc_call_sync(server->client, &msg, 0); 1663 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
1273 if (status == 0 && state != NULL) 1664 if (status == 0 && state != NULL)
1274 renew_lease(server, timestamp); 1665 renew_lease(server, timestamp);
1275 return status; 1666 return status;
@@ -1318,6 +1709,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1318 struct nfs4_state *state = calldata->state; 1709 struct nfs4_state *state = calldata->state;
1319 struct nfs_server *server = NFS_SERVER(calldata->inode); 1710 struct nfs_server *server = NFS_SERVER(calldata->inode);
1320 1711
1712 nfs4_sequence_done(server, &calldata->res.seq_res, task->tk_status);
1321 if (RPC_ASSASSINATED(task)) 1713 if (RPC_ASSASSINATED(task))
1322 return; 1714 return;
1323 /* hmm. we are done with the inode, and in the process of freeing 1715 /* hmm. we are done with the inode, and in the process of freeing
@@ -1336,10 +1728,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1336 break; 1728 break;
1337 default: 1729 default:
1338 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1730 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
1339 rpc_restart_call(task); 1731 nfs4_restart_rpc(task, server->nfs_client);
1340 return; 1732 return;
1341 } 1733 }
1342 } 1734 }
1735 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res);
1343 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1736 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1344} 1737}
1345 1738
@@ -1380,6 +1773,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1380 calldata->arg.fmode = FMODE_WRITE; 1773 calldata->arg.fmode = FMODE_WRITE;
1381 } 1774 }
1382 calldata->timestamp = jiffies; 1775 calldata->timestamp = jiffies;
1776 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1777 &calldata->arg.seq_args, &calldata->res.seq_res,
1778 1, task))
1779 return;
1383 rpc_call_start(task); 1780 rpc_call_start(task);
1384} 1781}
1385 1782
@@ -1419,13 +1816,15 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1419 }; 1816 };
1420 int status = -ENOMEM; 1817 int status = -ENOMEM;
1421 1818
1422 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); 1819 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
1423 if (calldata == NULL) 1820 if (calldata == NULL)
1424 goto out; 1821 goto out;
1425 calldata->inode = state->inode; 1822 calldata->inode = state->inode;
1426 calldata->state = state; 1823 calldata->state = state;
1427 calldata->arg.fh = NFS_FH(state->inode); 1824 calldata->arg.fh = NFS_FH(state->inode);
1428 calldata->arg.stateid = &state->open_stateid; 1825 calldata->arg.stateid = &state->open_stateid;
1826 if (nfs4_has_session(server->nfs_client))
1827 memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
1429 /* Serialization for the sequence id */ 1828 /* Serialization for the sequence id */
1430 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1829 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1431 if (calldata->arg.seqid == NULL) 1830 if (calldata->arg.seqid == NULL)
@@ -1435,6 +1834,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1435 calldata->res.fattr = &calldata->fattr; 1834 calldata->res.fattr = &calldata->fattr;
1436 calldata->res.seqid = calldata->arg.seqid; 1835 calldata->res.seqid = calldata->arg.seqid;
1437 calldata->res.server = server; 1836 calldata->res.server = server;
1837 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
1438 calldata->path.mnt = mntget(path->mnt); 1838 calldata->path.mnt = mntget(path->mnt);
1439 calldata->path.dentry = dget(path->dentry); 1839 calldata->path.dentry = dget(path->dentry);
1440 1840
@@ -1584,15 +1984,18 @@ void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1584 1984
1585static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 1985static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
1586{ 1986{
1987 struct nfs4_server_caps_arg args = {
1988 .fhandle = fhandle,
1989 };
1587 struct nfs4_server_caps_res res = {}; 1990 struct nfs4_server_caps_res res = {};
1588 struct rpc_message msg = { 1991 struct rpc_message msg = {
1589 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS], 1992 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS],
1590 .rpc_argp = fhandle, 1993 .rpc_argp = &args,
1591 .rpc_resp = &res, 1994 .rpc_resp = &res,
1592 }; 1995 };
1593 int status; 1996 int status;
1594 1997
1595 status = rpc_call_sync(server->client, &msg, 0); 1998 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1596 if (status == 0) { 1999 if (status == 0) {
1597 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 2000 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
1598 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 2001 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
@@ -1606,6 +2009,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
1606 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 2009 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1607 server->acl_bitmask = res.acl_bitmask; 2010 server->acl_bitmask = res.acl_bitmask;
1608 } 2011 }
2012
1609 return status; 2013 return status;
1610} 2014}
1611 2015
@@ -1637,8 +2041,15 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
1637 .rpc_argp = &args, 2041 .rpc_argp = &args,
1638 .rpc_resp = &res, 2042 .rpc_resp = &res,
1639 }; 2043 };
2044 int status;
2045
1640 nfs_fattr_init(info->fattr); 2046 nfs_fattr_init(info->fattr);
1641 return rpc_call_sync(server->client, &msg, 0); 2047 status = nfs4_recover_expired_lease(server);
2048 if (!status)
2049 status = nfs4_check_client_ready(server->nfs_client);
2050 if (!status)
2051 status = nfs4_call_sync(server, &msg, &args, &res, 0);
2052 return status;
1642} 2053}
1643 2054
1644static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, 2055static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -1728,7 +2139,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
1728 }; 2139 };
1729 2140
1730 nfs_fattr_init(fattr); 2141 nfs_fattr_init(fattr);
1731 return rpc_call_sync(server->client, &msg, 0); 2142 return nfs4_call_sync(server, &msg, &args, &res, 0);
1732} 2143}
1733 2144
1734static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2145static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
@@ -1812,7 +2223,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
1812 nfs_fattr_init(fattr); 2223 nfs_fattr_init(fattr);
1813 2224
1814 dprintk("NFS call lookupfh %s\n", name->name); 2225 dprintk("NFS call lookupfh %s\n", name->name);
1815 status = rpc_call_sync(server->client, &msg, 0); 2226 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1816 dprintk("NFS reply lookupfh: %d\n", status); 2227 dprintk("NFS reply lookupfh: %d\n", status);
1817 return status; 2228 return status;
1818} 2229}
@@ -1898,7 +2309,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
1898 args.access |= NFS4_ACCESS_EXECUTE; 2309 args.access |= NFS4_ACCESS_EXECUTE;
1899 } 2310 }
1900 nfs_fattr_init(&fattr); 2311 nfs_fattr_init(&fattr);
1901 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 2312 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1902 if (!status) { 2313 if (!status) {
1903 entry->mask = 0; 2314 entry->mask = 0;
1904 if (res.access & NFS4_ACCESS_READ) 2315 if (res.access & NFS4_ACCESS_READ)
@@ -1957,13 +2368,14 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
1957 .pglen = pglen, 2368 .pglen = pglen,
1958 .pages = &page, 2369 .pages = &page,
1959 }; 2370 };
2371 struct nfs4_readlink_res res;
1960 struct rpc_message msg = { 2372 struct rpc_message msg = {
1961 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK], 2373 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
1962 .rpc_argp = &args, 2374 .rpc_argp = &args,
1963 .rpc_resp = NULL, 2375 .rpc_resp = &res,
1964 }; 2376 };
1965 2377
1966 return rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 2378 return nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
1967} 2379}
1968 2380
1969static int nfs4_proc_readlink(struct inode *inode, struct page *page, 2381static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2057,7 +2469,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
2057 int status; 2469 int status;
2058 2470
2059 nfs_fattr_init(&res.dir_attr); 2471 nfs_fattr_init(&res.dir_attr);
2060 status = rpc_call_sync(server->client, &msg, 0); 2472 status = nfs4_call_sync(server, &msg, &args, &res, 1);
2061 if (status == 0) { 2473 if (status == 0) {
2062 update_changeattr(dir, &res.cinfo); 2474 update_changeattr(dir, &res.cinfo);
2063 nfs_post_op_update_inode(dir, &res.dir_attr); 2475 nfs_post_op_update_inode(dir, &res.dir_attr);
@@ -2092,8 +2504,10 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2092{ 2504{
2093 struct nfs_removeres *res = task->tk_msg.rpc_resp; 2505 struct nfs_removeres *res = task->tk_msg.rpc_resp;
2094 2506
2507 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2095 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2508 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2096 return 0; 2509 return 0;
2510 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2097 update_changeattr(dir, &res->cinfo); 2511 update_changeattr(dir, &res->cinfo);
2098 nfs_post_op_update_inode(dir, &res->dir_attr); 2512 nfs_post_op_update_inode(dir, &res->dir_attr);
2099 return 1; 2513 return 1;
@@ -2125,7 +2539,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2125 2539
2126 nfs_fattr_init(res.old_fattr); 2540 nfs_fattr_init(res.old_fattr);
2127 nfs_fattr_init(res.new_fattr); 2541 nfs_fattr_init(res.new_fattr);
2128 status = rpc_call_sync(server->client, &msg, 0); 2542 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
2129 2543
2130 if (!status) { 2544 if (!status) {
2131 update_changeattr(old_dir, &res.old_cinfo); 2545 update_changeattr(old_dir, &res.old_cinfo);
@@ -2174,7 +2588,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
2174 2588
2175 nfs_fattr_init(res.fattr); 2589 nfs_fattr_init(res.fattr);
2176 nfs_fattr_init(res.dir_attr); 2590 nfs_fattr_init(res.dir_attr);
2177 status = rpc_call_sync(server->client, &msg, 0); 2591 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
2178 if (!status) { 2592 if (!status) {
2179 update_changeattr(dir, &res.cinfo); 2593 update_changeattr(dir, &res.cinfo);
2180 nfs_post_op_update_inode(dir, res.dir_attr); 2594 nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2235,7 +2649,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
2235 2649
2236static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) 2650static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
2237{ 2651{
2238 int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); 2652 int status = nfs4_call_sync(NFS_SERVER(dir), &data->msg,
2653 &data->arg, &data->res, 1);
2239 if (status == 0) { 2654 if (status == 0) {
2240 update_changeattr(dir, &data->res.dir_cinfo); 2655 update_changeattr(dir, &data->res.dir_cinfo);
2241 nfs_post_op_update_inode(dir, data->res.dir_fattr); 2656 nfs_post_op_update_inode(dir, data->res.dir_fattr);
@@ -2344,7 +2759,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2344 (unsigned long long)cookie); 2759 (unsigned long long)cookie);
2345 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 2760 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
2346 res.pgbase = args.pgbase; 2761 res.pgbase = args.pgbase;
2347 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 2762 status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
2348 if (status == 0) 2763 if (status == 0)
2349 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 2764 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
2350 2765
@@ -2422,14 +2837,17 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
2422 .fh = fhandle, 2837 .fh = fhandle,
2423 .bitmask = server->attr_bitmask, 2838 .bitmask = server->attr_bitmask,
2424 }; 2839 };
2840 struct nfs4_statfs_res res = {
2841 .fsstat = fsstat,
2842 };
2425 struct rpc_message msg = { 2843 struct rpc_message msg = {
2426 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS], 2844 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS],
2427 .rpc_argp = &args, 2845 .rpc_argp = &args,
2428 .rpc_resp = fsstat, 2846 .rpc_resp = &res,
2429 }; 2847 };
2430 2848
2431 nfs_fattr_init(fsstat->fattr); 2849 nfs_fattr_init(fsstat->fattr);
2432 return rpc_call_sync(server->client, &msg, 0); 2850 return nfs4_call_sync(server, &msg, &args, &res, 0);
2433} 2851}
2434 2852
2435static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) 2853static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
@@ -2451,13 +2869,16 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
2451 .fh = fhandle, 2869 .fh = fhandle,
2452 .bitmask = server->attr_bitmask, 2870 .bitmask = server->attr_bitmask,
2453 }; 2871 };
2872 struct nfs4_fsinfo_res res = {
2873 .fsinfo = fsinfo,
2874 };
2454 struct rpc_message msg = { 2875 struct rpc_message msg = {
2455 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO], 2876 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
2456 .rpc_argp = &args, 2877 .rpc_argp = &args,
2457 .rpc_resp = fsinfo, 2878 .rpc_resp = &res,
2458 }; 2879 };
2459 2880
2460 return rpc_call_sync(server->client, &msg, 0); 2881 return nfs4_call_sync(server, &msg, &args, &res, 0);
2461} 2882}
2462 2883
2463static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) 2884static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
@@ -2486,10 +2907,13 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
2486 .fh = fhandle, 2907 .fh = fhandle,
2487 .bitmask = server->attr_bitmask, 2908 .bitmask = server->attr_bitmask,
2488 }; 2909 };
2910 struct nfs4_pathconf_res res = {
2911 .pathconf = pathconf,
2912 };
2489 struct rpc_message msg = { 2913 struct rpc_message msg = {
2490 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF], 2914 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF],
2491 .rpc_argp = &args, 2915 .rpc_argp = &args,
2492 .rpc_resp = pathconf, 2916 .rpc_resp = &res,
2493 }; 2917 };
2494 2918
2495 /* None of the pathconf attributes are mandatory to implement */ 2919 /* None of the pathconf attributes are mandatory to implement */
@@ -2499,7 +2923,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
2499 } 2923 }
2500 2924
2501 nfs_fattr_init(pathconf->fattr); 2925 nfs_fattr_init(pathconf->fattr);
2502 return rpc_call_sync(server->client, &msg, 0); 2926 return nfs4_call_sync(server, &msg, &args, &res, 0);
2503} 2927}
2504 2928
2505static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, 2929static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2520,8 +2944,13 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2520{ 2944{
2521 struct nfs_server *server = NFS_SERVER(data->inode); 2945 struct nfs_server *server = NFS_SERVER(data->inode);
2522 2946
2947 dprintk("--> %s\n", __func__);
2948
2949 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2950 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2951
2523 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 2952 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2524 rpc_restart_call(task); 2953 nfs4_restart_rpc(task, server->nfs_client);
2525 return -EAGAIN; 2954 return -EAGAIN;
2526 } 2955 }
2527 2956
@@ -2541,8 +2970,12 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2541{ 2970{
2542 struct inode *inode = data->inode; 2971 struct inode *inode = data->inode;
2543 2972
2973 /* slot is freed in nfs_writeback_done */
2974 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
2975 task->tk_status);
2976
2544 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 2977 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
2545 rpc_restart_call(task); 2978 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
2546 return -EAGAIN; 2979 return -EAGAIN;
2547 } 2980 }
2548 if (task->tk_status >= 0) { 2981 if (task->tk_status >= 0) {
@@ -2567,10 +3000,14 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2567{ 3000{
2568 struct inode *inode = data->inode; 3001 struct inode *inode = data->inode;
2569 3002
3003 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3004 task->tk_status);
2570 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3005 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
2571 rpc_restart_call(task); 3006 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
2572 return -EAGAIN; 3007 return -EAGAIN;
2573 } 3008 }
3009 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
3010 &data->res.seq_res);
2574 nfs_refresh_inode(inode, data->res.fattr); 3011 nfs_refresh_inode(inode, data->res.fattr);
2575 return 0; 3012 return 0;
2576} 3013}
@@ -2603,6 +3040,9 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
2603 if (time_before(clp->cl_last_renewal,timestamp)) 3040 if (time_before(clp->cl_last_renewal,timestamp))
2604 clp->cl_last_renewal = timestamp; 3041 clp->cl_last_renewal = timestamp;
2605 spin_unlock(&clp->cl_lock); 3042 spin_unlock(&clp->cl_lock);
3043 dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
3044 task->tk_msg.rpc_cred);
3045 put_rpccred(task->tk_msg.rpc_cred);
2606} 3046}
2607 3047
2608static const struct rpc_call_ops nfs4_renew_ops = { 3048static const struct rpc_call_ops nfs4_renew_ops = {
@@ -2742,12 +3182,14 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
2742 .acl_pages = pages, 3182 .acl_pages = pages,
2743 .acl_len = buflen, 3183 .acl_len = buflen,
2744 }; 3184 };
2745 size_t resp_len = buflen; 3185 struct nfs_getaclres res = {
3186 .acl_len = buflen,
3187 };
2746 void *resp_buf; 3188 void *resp_buf;
2747 struct rpc_message msg = { 3189 struct rpc_message msg = {
2748 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], 3190 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
2749 .rpc_argp = &args, 3191 .rpc_argp = &args,
2750 .rpc_resp = &resp_len, 3192 .rpc_resp = &res,
2751 }; 3193 };
2752 struct page *localpage = NULL; 3194 struct page *localpage = NULL;
2753 int ret; 3195 int ret;
@@ -2761,26 +3203,26 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
2761 return -ENOMEM; 3203 return -ENOMEM;
2762 args.acl_pages[0] = localpage; 3204 args.acl_pages[0] = localpage;
2763 args.acl_pgbase = 0; 3205 args.acl_pgbase = 0;
2764 resp_len = args.acl_len = PAGE_SIZE; 3206 args.acl_len = PAGE_SIZE;
2765 } else { 3207 } else {
2766 resp_buf = buf; 3208 resp_buf = buf;
2767 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase); 3209 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
2768 } 3210 }
2769 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 3211 ret = nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
2770 if (ret) 3212 if (ret)
2771 goto out_free; 3213 goto out_free;
2772 if (resp_len > args.acl_len) 3214 if (res.acl_len > args.acl_len)
2773 nfs4_write_cached_acl(inode, NULL, resp_len); 3215 nfs4_write_cached_acl(inode, NULL, res.acl_len);
2774 else 3216 else
2775 nfs4_write_cached_acl(inode, resp_buf, resp_len); 3217 nfs4_write_cached_acl(inode, resp_buf, res.acl_len);
2776 if (buf) { 3218 if (buf) {
2777 ret = -ERANGE; 3219 ret = -ERANGE;
2778 if (resp_len > buflen) 3220 if (res.acl_len > buflen)
2779 goto out_free; 3221 goto out_free;
2780 if (localpage) 3222 if (localpage)
2781 memcpy(buf, resp_buf, resp_len); 3223 memcpy(buf, resp_buf, res.acl_len);
2782 } 3224 }
2783 ret = resp_len; 3225 ret = res.acl_len;
2784out_free: 3226out_free:
2785 if (localpage) 3227 if (localpage)
2786 __free_page(localpage); 3228 __free_page(localpage);
@@ -2810,8 +3252,6 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
2810 ret = nfs_revalidate_inode(server, inode); 3252 ret = nfs_revalidate_inode(server, inode);
2811 if (ret < 0) 3253 if (ret < 0)
2812 return ret; 3254 return ret;
2813 if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
2814 nfs_zap_acl_cache(inode);
2815 ret = nfs4_read_cached_acl(inode, buf, buflen); 3255 ret = nfs4_read_cached_acl(inode, buf, buflen);
2816 if (ret != -ENOENT) 3256 if (ret != -ENOENT)
2817 return ret; 3257 return ret;
@@ -2827,10 +3267,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
2827 .acl_pages = pages, 3267 .acl_pages = pages,
2828 .acl_len = buflen, 3268 .acl_len = buflen,
2829 }; 3269 };
3270 struct nfs_setaclres res;
2830 struct rpc_message msg = { 3271 struct rpc_message msg = {
2831 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL], 3272 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
2832 .rpc_argp = &arg, 3273 .rpc_argp = &arg,
2833 .rpc_resp = NULL, 3274 .rpc_resp = &res,
2834 }; 3275 };
2835 int ret; 3276 int ret;
2836 3277
@@ -2838,7 +3279,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
2838 return -EOPNOTSUPP; 3279 return -EOPNOTSUPP;
2839 nfs_inode_return_delegation(inode); 3280 nfs_inode_return_delegation(inode);
2840 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 3281 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
2841 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 3282 ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
2842 nfs_access_zap_cache(inode); 3283 nfs_access_zap_cache(inode);
2843 nfs_zap_acl_cache(inode); 3284 nfs_zap_acl_cache(inode);
2844 return ret; 3285 return ret;
@@ -2857,10 +3298,8 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
2857} 3298}
2858 3299
2859static int 3300static int
2860nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state) 3301_nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs_client *clp, struct nfs4_state *state)
2861{ 3302{
2862 struct nfs_client *clp = server->nfs_client;
2863
2864 if (!clp || task->tk_status >= 0) 3303 if (!clp || task->tk_status >= 0)
2865 return 0; 3304 return 0;
2866 switch(task->tk_status) { 3305 switch(task->tk_status) {
@@ -2879,8 +3318,23 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
2879 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 3318 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
2880 task->tk_status = 0; 3319 task->tk_status = 0;
2881 return -EAGAIN; 3320 return -EAGAIN;
3321#if defined(CONFIG_NFS_V4_1)
3322 case -NFS4ERR_BADSESSION:
3323 case -NFS4ERR_BADSLOT:
3324 case -NFS4ERR_BAD_HIGH_SLOT:
3325 case -NFS4ERR_DEADSESSION:
3326 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
3327 case -NFS4ERR_SEQ_FALSE_RETRY:
3328 case -NFS4ERR_SEQ_MISORDERED:
3329 dprintk("%s ERROR %d, Reset session\n", __func__,
3330 task->tk_status);
3331 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
3332 task->tk_status = 0;
3333 return -EAGAIN;
3334#endif /* CONFIG_NFS_V4_1 */
2882 case -NFS4ERR_DELAY: 3335 case -NFS4ERR_DELAY:
2883 nfs_inc_server_stats(server, NFSIOS_DELAY); 3336 if (server)
3337 nfs_inc_server_stats(server, NFSIOS_DELAY);
2884 case -NFS4ERR_GRACE: 3338 case -NFS4ERR_GRACE:
2885 rpc_delay(task, NFS4_POLL_RETRY_MAX); 3339 rpc_delay(task, NFS4_POLL_RETRY_MAX);
2886 task->tk_status = 0; 3340 task->tk_status = 0;
@@ -2893,6 +3347,12 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
2893 return 0; 3347 return 0;
2894} 3348}
2895 3349
3350static int
3351nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
3352{
3353 return _nfs4_async_handle_error(task, server, server->nfs_client, state);
3354}
3355
2896int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 3356int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2897{ 3357{
2898 nfs4_verifier sc_verifier; 3358 nfs4_verifier sc_verifier;
@@ -3000,6 +3460,10 @@ struct nfs4_delegreturndata {
3000static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) 3460static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3001{ 3461{
3002 struct nfs4_delegreturndata *data = calldata; 3462 struct nfs4_delegreturndata *data = calldata;
3463
3464 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res,
3465 task->tk_status);
3466
3003 data->rpc_status = task->tk_status; 3467 data->rpc_status = task->tk_status;
3004 if (data->rpc_status == 0) 3468 if (data->rpc_status == 0)
3005 renew_lease(data->res.server, data->timestamp); 3469 renew_lease(data->res.server, data->timestamp);
@@ -3010,7 +3474,25 @@ static void nfs4_delegreturn_release(void *calldata)
3010 kfree(calldata); 3474 kfree(calldata);
3011} 3475}
3012 3476
3477#if defined(CONFIG_NFS_V4_1)
3478static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
3479{
3480 struct nfs4_delegreturndata *d_data;
3481
3482 d_data = (struct nfs4_delegreturndata *)data;
3483
3484 if (nfs4_setup_sequence(d_data->res.server->nfs_client,
3485 &d_data->args.seq_args,
3486 &d_data->res.seq_res, 1, task))
3487 return;
3488 rpc_call_start(task);
3489}
3490#endif /* CONFIG_NFS_V4_1 */
3491
3013static const struct rpc_call_ops nfs4_delegreturn_ops = { 3492static const struct rpc_call_ops nfs4_delegreturn_ops = {
3493#if defined(CONFIG_NFS_V4_1)
3494 .rpc_call_prepare = nfs4_delegreturn_prepare,
3495#endif /* CONFIG_NFS_V4_1 */
3014 .rpc_call_done = nfs4_delegreturn_done, 3496 .rpc_call_done = nfs4_delegreturn_done,
3015 .rpc_release = nfs4_delegreturn_release, 3497 .rpc_release = nfs4_delegreturn_release,
3016}; 3498};
@@ -3032,7 +3514,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3032 }; 3514 };
3033 int status = 0; 3515 int status = 0;
3034 3516
3035 data = kmalloc(sizeof(*data), GFP_KERNEL); 3517 data = kzalloc(sizeof(*data), GFP_KERNEL);
3036 if (data == NULL) 3518 if (data == NULL)
3037 return -ENOMEM; 3519 return -ENOMEM;
3038 data->args.fhandle = &data->fh; 3520 data->args.fhandle = &data->fh;
@@ -3042,6 +3524,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3042 memcpy(&data->stateid, stateid, sizeof(data->stateid)); 3524 memcpy(&data->stateid, stateid, sizeof(data->stateid));
3043 data->res.fattr = &data->fattr; 3525 data->res.fattr = &data->fattr;
3044 data->res.server = server; 3526 data->res.server = server;
3527 data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3045 nfs_fattr_init(data->res.fattr); 3528 nfs_fattr_init(data->res.fattr);
3046 data->timestamp = jiffies; 3529 data->timestamp = jiffies;
3047 data->rpc_status = 0; 3530 data->rpc_status = 0;
@@ -3127,7 +3610,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3127 goto out; 3610 goto out;
3128 lsp = request->fl_u.nfs4_fl.owner; 3611 lsp = request->fl_u.nfs4_fl.owner;
3129 arg.lock_owner.id = lsp->ls_id.id; 3612 arg.lock_owner.id = lsp->ls_id.id;
3130 status = rpc_call_sync(server->client, &msg, 0); 3613 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
3131 switch (status) { 3614 switch (status) {
3132 case 0: 3615 case 0:
3133 request->fl_type = F_UNLCK; 3616 request->fl_type = F_UNLCK;
@@ -3187,13 +3670,14 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3187 struct nfs4_unlockdata *p; 3670 struct nfs4_unlockdata *p;
3188 struct inode *inode = lsp->ls_state->inode; 3671 struct inode *inode = lsp->ls_state->inode;
3189 3672
3190 p = kmalloc(sizeof(*p), GFP_KERNEL); 3673 p = kzalloc(sizeof(*p), GFP_KERNEL);
3191 if (p == NULL) 3674 if (p == NULL)
3192 return NULL; 3675 return NULL;
3193 p->arg.fh = NFS_FH(inode); 3676 p->arg.fh = NFS_FH(inode);
3194 p->arg.fl = &p->fl; 3677 p->arg.fl = &p->fl;
3195 p->arg.seqid = seqid; 3678 p->arg.seqid = seqid;
3196 p->res.seqid = seqid; 3679 p->res.seqid = seqid;
3680 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3197 p->arg.stateid = &lsp->ls_stateid; 3681 p->arg.stateid = &lsp->ls_stateid;
3198 p->lsp = lsp; 3682 p->lsp = lsp;
3199 atomic_inc(&lsp->ls_count); 3683 atomic_inc(&lsp->ls_count);
@@ -3217,6 +3701,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3217{ 3701{
3218 struct nfs4_unlockdata *calldata = data; 3702 struct nfs4_unlockdata *calldata = data;
3219 3703
3704 nfs4_sequence_done(calldata->server, &calldata->res.seq_res,
3705 task->tk_status);
3220 if (RPC_ASSASSINATED(task)) 3706 if (RPC_ASSASSINATED(task))
3221 return; 3707 return;
3222 switch (task->tk_status) { 3708 switch (task->tk_status) {
@@ -3233,8 +3719,11 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3233 break; 3719 break;
3234 default: 3720 default:
3235 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3721 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3236 rpc_restart_call(task); 3722 nfs4_restart_rpc(task,
3723 calldata->server->nfs_client);
3237 } 3724 }
3725 nfs4_sequence_free_slot(calldata->server->nfs_client,
3726 &calldata->res.seq_res);
3238} 3727}
3239 3728
3240static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3729static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3249,6 +3738,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
3249 return; 3738 return;
3250 } 3739 }
3251 calldata->timestamp = jiffies; 3740 calldata->timestamp = jiffies;
3741 if (nfs4_setup_sequence(calldata->server->nfs_client,
3742 &calldata->arg.seq_args,
3743 &calldata->res.seq_res, 1, task))
3744 return;
3252 rpc_call_start(task); 3745 rpc_call_start(task);
3253} 3746}
3254 3747
@@ -3341,6 +3834,7 @@ struct nfs4_lockdata {
3341 unsigned long timestamp; 3834 unsigned long timestamp;
3342 int rpc_status; 3835 int rpc_status;
3343 int cancelled; 3836 int cancelled;
3837 struct nfs_server *server;
3344}; 3838};
3345 3839
3346static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, 3840static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
@@ -3366,7 +3860,9 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3366 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 3860 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3367 p->arg.lock_owner.id = lsp->ls_id.id; 3861 p->arg.lock_owner.id = lsp->ls_id.id;
3368 p->res.lock_seqid = p->arg.lock_seqid; 3862 p->res.lock_seqid = p->arg.lock_seqid;
3863 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3369 p->lsp = lsp; 3864 p->lsp = lsp;
3865 p->server = server;
3370 atomic_inc(&lsp->ls_count); 3866 atomic_inc(&lsp->ls_count);
3371 p->ctx = get_nfs_open_context(ctx); 3867 p->ctx = get_nfs_open_context(ctx);
3372 memcpy(&p->fl, fl, sizeof(p->fl)); 3868 memcpy(&p->fl, fl, sizeof(p->fl));
@@ -3396,6 +3892,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3396 } else 3892 } else
3397 data->arg.new_lock_owner = 0; 3893 data->arg.new_lock_owner = 0;
3398 data->timestamp = jiffies; 3894 data->timestamp = jiffies;
3895 if (nfs4_setup_sequence(data->server->nfs_client, &data->arg.seq_args,
3896 &data->res.seq_res, 1, task))
3897 return;
3399 rpc_call_start(task); 3898 rpc_call_start(task);
3400 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 3899 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3401} 3900}
@@ -3406,6 +3905,9 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3406 3905
3407 dprintk("%s: begin!\n", __func__); 3906 dprintk("%s: begin!\n", __func__);
3408 3907
3908 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res,
3909 task->tk_status);
3910
3409 data->rpc_status = task->tk_status; 3911 data->rpc_status = task->tk_status;
3410 if (RPC_ASSASSINATED(task)) 3912 if (RPC_ASSASSINATED(task))
3411 goto out; 3913 goto out;
@@ -3487,8 +3989,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
3487 ret = nfs4_wait_for_completion_rpc_task(task); 3989 ret = nfs4_wait_for_completion_rpc_task(task);
3488 if (ret == 0) { 3990 if (ret == 0) {
3489 ret = data->rpc_status; 3991 ret = data->rpc_status;
3490 if (ret == -NFS4ERR_DENIED)
3491 ret = -EAGAIN;
3492 } else 3992 } else
3493 data->cancelled = 1; 3993 data->cancelled = 1;
3494 rpc_put_task(task); 3994 rpc_put_task(task);
@@ -3576,9 +4076,11 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *
3576 int err; 4076 int err;
3577 4077
3578 do { 4078 do {
4079 err = _nfs4_proc_setlk(state, cmd, request);
4080 if (err == -NFS4ERR_DENIED)
4081 err = -EAGAIN;
3579 err = nfs4_handle_exception(NFS_SERVER(state->inode), 4082 err = nfs4_handle_exception(NFS_SERVER(state->inode),
3580 _nfs4_proc_setlk(state, cmd, request), 4083 err, &exception);
3581 &exception);
3582 } while (exception.retry); 4084 } while (exception.retry);
3583 return err; 4085 return err;
3584} 4086}
@@ -3630,8 +4132,37 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
3630 goto out; 4132 goto out;
3631 do { 4133 do {
3632 err = _nfs4_do_setlk(state, F_SETLK, fl, 0); 4134 err = _nfs4_do_setlk(state, F_SETLK, fl, 0);
3633 if (err != -NFS4ERR_DELAY) 4135 switch (err) {
3634 break; 4136 default:
4137 printk(KERN_ERR "%s: unhandled error %d.\n",
4138 __func__, err);
4139 case 0:
4140 case -ESTALE:
4141 goto out;
4142 case -NFS4ERR_EXPIRED:
4143 case -NFS4ERR_STALE_CLIENTID:
4144 case -NFS4ERR_STALE_STATEID:
4145 nfs4_schedule_state_recovery(server->nfs_client);
4146 goto out;
4147 case -ERESTARTSYS:
4148 /*
4149 * The show must go on: exit, but mark the
4150 * stateid as needing recovery.
4151 */
4152 case -NFS4ERR_ADMIN_REVOKED:
4153 case -NFS4ERR_BAD_STATEID:
4154 case -NFS4ERR_OPENMODE:
4155 nfs4_state_mark_reclaim_nograce(server->nfs_client, state);
4156 err = 0;
4157 goto out;
4158 case -ENOMEM:
4159 case -NFS4ERR_DENIED:
4160 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
4161 err = 0;
4162 goto out;
4163 case -NFS4ERR_DELAY:
4164 break;
4165 }
3635 err = nfs4_handle_exception(server, err, &exception); 4166 err = nfs4_handle_exception(server, err, &exception);
3636 } while (exception.retry); 4167 } while (exception.retry);
3637out: 4168out:
@@ -3706,10 +4237,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
3706 .page = page, 4237 .page = page,
3707 .bitmask = bitmask, 4238 .bitmask = bitmask,
3708 }; 4239 };
4240 struct nfs4_fs_locations_res res = {
4241 .fs_locations = fs_locations,
4242 };
3709 struct rpc_message msg = { 4243 struct rpc_message msg = {
3710 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], 4244 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
3711 .rpc_argp = &args, 4245 .rpc_argp = &args,
3712 .rpc_resp = fs_locations, 4246 .rpc_resp = &res,
3713 }; 4247 };
3714 int status; 4248 int status;
3715 4249
@@ -3717,24 +4251,720 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
3717 nfs_fattr_init(&fs_locations->fattr); 4251 nfs_fattr_init(&fs_locations->fattr);
3718 fs_locations->server = server; 4252 fs_locations->server = server;
3719 fs_locations->nlocations = 0; 4253 fs_locations->nlocations = 0;
3720 status = rpc_call_sync(server->client, &msg, 0); 4254 status = nfs4_call_sync(server, &msg, &args, &res, 0);
3721 nfs_fixup_referral_attributes(&fs_locations->fattr); 4255 nfs_fixup_referral_attributes(&fs_locations->fattr);
3722 dprintk("%s: returned status = %d\n", __func__, status); 4256 dprintk("%s: returned status = %d\n", __func__, status);
3723 return status; 4257 return status;
3724} 4258}
3725 4259
3726struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { 4260#ifdef CONFIG_NFS_V4_1
4261/*
4262 * nfs4_proc_exchange_id()
4263 *
4264 * Since the clientid has expired, all compounds using sessions
4265 * associated with the stale clientid will be returning
4266 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4267 * be in some phase of session reset.
4268 */
4269static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4270{
4271 nfs4_verifier verifier;
4272 struct nfs41_exchange_id_args args = {
4273 .client = clp,
4274 .flags = clp->cl_exchange_flags,
4275 };
4276 struct nfs41_exchange_id_res res = {
4277 .client = clp,
4278 };
4279 int status;
4280 struct rpc_message msg = {
4281 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
4282 .rpc_argp = &args,
4283 .rpc_resp = &res,
4284 .rpc_cred = cred,
4285 };
4286 __be32 *p;
4287
4288 dprintk("--> %s\n", __func__);
4289 BUG_ON(clp == NULL);
4290
4291 p = (u32 *)verifier.data;
4292 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4293 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
4294 args.verifier = &verifier;
4295
4296 while (1) {
4297 args.id_len = scnprintf(args.id, sizeof(args.id),
4298 "%s/%s %u",
4299 clp->cl_ipaddr,
4300 rpc_peeraddr2str(clp->cl_rpcclient,
4301 RPC_DISPLAY_ADDR),
4302 clp->cl_id_uniquifier);
4303
4304 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4305
4306 if (status != NFS4ERR_CLID_INUSE)
4307 break;
4308
4309 if (signalled())
4310 break;
4311
4312 if (++clp->cl_id_uniquifier == 0)
4313 break;
4314 }
4315
4316 dprintk("<-- %s status= %d\n", __func__, status);
4317 return status;
4318}
4319
4320struct nfs4_get_lease_time_data {
4321 struct nfs4_get_lease_time_args *args;
4322 struct nfs4_get_lease_time_res *res;
4323 struct nfs_client *clp;
4324};
4325
4326static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4327 void *calldata)
4328{
4329 int ret;
4330 struct nfs4_get_lease_time_data *data =
4331 (struct nfs4_get_lease_time_data *)calldata;
4332
4333 dprintk("--> %s\n", __func__);
4334 /* just setup sequence, do not trigger session recovery
4335 since we're invoked within one */
4336 ret = nfs41_setup_sequence(data->clp->cl_session,
4337 &data->args->la_seq_args,
4338 &data->res->lr_seq_res, 0, task);
4339
4340 BUG_ON(ret == -EAGAIN);
4341 rpc_call_start(task);
4342 dprintk("<-- %s\n", __func__);
4343}
4344
4345/*
4346 * Called from nfs4_state_manager thread for session setup, so don't recover
4347 * from sequence operation or clientid errors.
4348 */
4349static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4350{
4351 struct nfs4_get_lease_time_data *data =
4352 (struct nfs4_get_lease_time_data *)calldata;
4353
4354 dprintk("--> %s\n", __func__);
4355 nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status);
4356 switch (task->tk_status) {
4357 case -NFS4ERR_DELAY:
4358 case -NFS4ERR_GRACE:
4359 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4360 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4361 task->tk_status = 0;
4362 nfs4_restart_rpc(task, data->clp);
4363 return;
4364 }
4365 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4366 dprintk("<-- %s\n", __func__);
4367}
4368
4369struct rpc_call_ops nfs4_get_lease_time_ops = {
4370 .rpc_call_prepare = nfs4_get_lease_time_prepare,
4371 .rpc_call_done = nfs4_get_lease_time_done,
4372};
4373
4374int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4375{
4376 struct rpc_task *task;
4377 struct nfs4_get_lease_time_args args;
4378 struct nfs4_get_lease_time_res res = {
4379 .lr_fsinfo = fsinfo,
4380 };
4381 struct nfs4_get_lease_time_data data = {
4382 .args = &args,
4383 .res = &res,
4384 .clp = clp,
4385 };
4386 struct rpc_message msg = {
4387 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME],
4388 .rpc_argp = &args,
4389 .rpc_resp = &res,
4390 };
4391 struct rpc_task_setup task_setup = {
4392 .rpc_client = clp->cl_rpcclient,
4393 .rpc_message = &msg,
4394 .callback_ops = &nfs4_get_lease_time_ops,
4395 .callback_data = &data
4396 };
4397 int status;
4398
4399 res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
4400 dprintk("--> %s\n", __func__);
4401 task = rpc_run_task(&task_setup);
4402
4403 if (IS_ERR(task))
4404 status = PTR_ERR(task);
4405 else {
4406 status = task->tk_status;
4407 rpc_put_task(task);
4408 }
4409 dprintk("<-- %s return %d\n", __func__, status);
4410
4411 return status;
4412}
4413
4414/*
4415 * Reset a slot table
4416 */
4417static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
4418 int old_max_slots, int ivalue)
4419{
4420 int i;
4421 int ret = 0;
4422
4423 dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__, max_slots, tbl);
4424
4425 /*
4426 * Until we have dynamic slot table adjustment, insist
4427 * upon the same slot table size
4428 */
4429 if (max_slots != old_max_slots) {
4430 dprintk("%s reset slot table does't match old\n",
4431 __func__);
4432 ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */
4433 goto out;
4434 }
4435 spin_lock(&tbl->slot_tbl_lock);
4436 for (i = 0; i < max_slots; ++i)
4437 tbl->slots[i].seq_nr = ivalue;
4438 tbl->highest_used_slotid = -1;
4439 spin_unlock(&tbl->slot_tbl_lock);
4440 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4441 tbl, tbl->slots, tbl->max_slots);
4442out:
4443 dprintk("<-- %s: return %d\n", __func__, ret);
4444 return ret;
4445}
4446
4447/*
4448 * Reset the forechannel and backchannel slot tables
4449 */
4450static int nfs4_reset_slot_tables(struct nfs4_session *session)
4451{
4452 int status;
4453
4454 status = nfs4_reset_slot_table(&session->fc_slot_table,
4455 session->fc_attrs.max_reqs,
4456 session->fc_slot_table.max_slots,
4457 1);
4458 if (status)
4459 return status;
4460
4461 status = nfs4_reset_slot_table(&session->bc_slot_table,
4462 session->bc_attrs.max_reqs,
4463 session->bc_slot_table.max_slots,
4464 0);
4465 return status;
4466}
4467
4468/* Destroy the slot table */
4469static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4470{
4471 if (session->fc_slot_table.slots != NULL) {
4472 kfree(session->fc_slot_table.slots);
4473 session->fc_slot_table.slots = NULL;
4474 }
4475 if (session->bc_slot_table.slots != NULL) {
4476 kfree(session->bc_slot_table.slots);
4477 session->bc_slot_table.slots = NULL;
4478 }
4479 return;
4480}
4481
4482/*
4483 * Initialize slot table
4484 */
4485static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4486 int max_slots, int ivalue)
4487{
4488 int i;
4489 struct nfs4_slot *slot;
4490 int ret = -ENOMEM;
4491
4492 BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
4493
4494 dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
4495
4496 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4497 if (!slot)
4498 goto out;
4499 for (i = 0; i < max_slots; ++i)
4500 slot[i].seq_nr = ivalue;
4501 ret = 0;
4502
4503 spin_lock(&tbl->slot_tbl_lock);
4504 if (tbl->slots != NULL) {
4505 spin_unlock(&tbl->slot_tbl_lock);
4506 dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
4507 __func__, tbl, tbl->slots);
4508 WARN_ON(1);
4509 goto out_free;
4510 }
4511 tbl->max_slots = max_slots;
4512 tbl->slots = slot;
4513 tbl->highest_used_slotid = -1; /* no slot is currently used */
4514 spin_unlock(&tbl->slot_tbl_lock);
4515 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4516 tbl, tbl->slots, tbl->max_slots);
4517out:
4518 dprintk("<-- %s: return %d\n", __func__, ret);
4519 return ret;
4520
4521out_free:
4522 kfree(slot);
4523 goto out;
4524}
4525
4526/*
4527 * Initialize the forechannel and backchannel tables
4528 */
4529static int nfs4_init_slot_tables(struct nfs4_session *session)
4530{
4531 int status;
4532
4533 status = nfs4_init_slot_table(&session->fc_slot_table,
4534 session->fc_attrs.max_reqs, 1);
4535 if (status)
4536 return status;
4537
4538 status = nfs4_init_slot_table(&session->bc_slot_table,
4539 session->bc_attrs.max_reqs, 0);
4540 if (status)
4541 nfs4_destroy_slot_tables(session);
4542
4543 return status;
4544}
4545
4546struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4547{
4548 struct nfs4_session *session;
4549 struct nfs4_slot_table *tbl;
4550
4551 session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL);
4552 if (!session)
4553 return NULL;
4554
4555 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4556 /*
4557 * The create session reply races with the server back
4558 * channel probe. Mark the client NFS_CS_SESSION_INITING
4559 * so that the client back channel can find the
4560 * nfs_client struct
4561 */
4562 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4563
4564 tbl = &session->fc_slot_table;
4565 spin_lock_init(&tbl->slot_tbl_lock);
4566 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4567
4568 tbl = &session->bc_slot_table;
4569 spin_lock_init(&tbl->slot_tbl_lock);
4570 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4571
4572 session->clp = clp;
4573 return session;
4574}
4575
4576void nfs4_destroy_session(struct nfs4_session *session)
4577{
4578 nfs4_proc_destroy_session(session);
4579 dprintk("%s Destroy backchannel for xprt %p\n",
4580 __func__, session->clp->cl_rpcclient->cl_xprt);
4581 xprt_destroy_backchannel(session->clp->cl_rpcclient->cl_xprt,
4582 NFS41_BC_MIN_CALLBACKS);
4583 nfs4_destroy_slot_tables(session);
4584 kfree(session);
4585}
4586
4587/*
4588 * Initialize the values to be used by the client in CREATE_SESSION
4589 * If nfs4_init_session set the fore channel request and response sizes,
4590 * use them.
4591 *
4592 * Set the back channel max_resp_sz_cached to zero to force the client to
4593 * always set csa_cachethis to FALSE because the current implementation
4594 * of the back channel DRC only supports caching the CB_SEQUENCE operation.
4595 */
4596static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
4597{
4598 struct nfs4_session *session = args->client->cl_session;
4599 unsigned int mxrqst_sz = session->fc_attrs.max_rqst_sz,
4600 mxresp_sz = session->fc_attrs.max_resp_sz;
4601
4602 if (mxrqst_sz == 0)
4603 mxrqst_sz = NFS_MAX_FILE_IO_SIZE;
4604 if (mxresp_sz == 0)
4605 mxresp_sz = NFS_MAX_FILE_IO_SIZE;
4606 /* Fore channel attributes */
4607 args->fc_attrs.headerpadsz = 0;
4608 args->fc_attrs.max_rqst_sz = mxrqst_sz;
4609 args->fc_attrs.max_resp_sz = mxresp_sz;
4610 args->fc_attrs.max_resp_sz_cached = mxresp_sz;
4611 args->fc_attrs.max_ops = NFS4_MAX_OPS;
4612 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
4613
4614 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
4615 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
4616 __func__,
4617 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
4618 args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops,
4619 args->fc_attrs.max_reqs);
4620
4621 /* Back channel attributes */
4622 args->bc_attrs.headerpadsz = 0;
4623 args->bc_attrs.max_rqst_sz = PAGE_SIZE;
4624 args->bc_attrs.max_resp_sz = PAGE_SIZE;
4625 args->bc_attrs.max_resp_sz_cached = 0;
4626 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
4627 args->bc_attrs.max_reqs = 1;
4628
4629 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
4630 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
4631 __func__,
4632 args->bc_attrs.max_rqst_sz, args->bc_attrs.max_resp_sz,
4633 args->bc_attrs.max_resp_sz_cached, args->bc_attrs.max_ops,
4634 args->bc_attrs.max_reqs);
4635}
4636
4637static int _verify_channel_attr(char *chan, char *attr_name, u32 sent, u32 rcvd)
4638{
4639 if (rcvd <= sent)
4640 return 0;
4641 printk(KERN_WARNING "%s: Session INVALID: %s channel %s increased. "
4642 "sent=%u rcvd=%u\n", __func__, chan, attr_name, sent, rcvd);
4643 return -EINVAL;
4644}
4645
4646#define _verify_fore_channel_attr(_name_) \
4647 _verify_channel_attr("fore", #_name_, \
4648 args->fc_attrs._name_, \
4649 session->fc_attrs._name_)
4650
4651#define _verify_back_channel_attr(_name_) \
4652 _verify_channel_attr("back", #_name_, \
4653 args->bc_attrs._name_, \
4654 session->bc_attrs._name_)
4655
4656/*
4657 * The server is not allowed to increase the fore channel header pad size,
4658 * maximum response size, or maximum number of operations.
4659 *
4660 * The back channel attributes are only negotiatied down: We send what the
4661 * (back channel) server insists upon.
4662 */
4663static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args,
4664 struct nfs4_session *session)
4665{
4666 int ret = 0;
4667
4668 ret |= _verify_fore_channel_attr(headerpadsz);
4669 ret |= _verify_fore_channel_attr(max_resp_sz);
4670 ret |= _verify_fore_channel_attr(max_ops);
4671
4672 ret |= _verify_back_channel_attr(headerpadsz);
4673 ret |= _verify_back_channel_attr(max_rqst_sz);
4674 ret |= _verify_back_channel_attr(max_resp_sz);
4675 ret |= _verify_back_channel_attr(max_resp_sz_cached);
4676 ret |= _verify_back_channel_attr(max_ops);
4677 ret |= _verify_back_channel_attr(max_reqs);
4678
4679 return ret;
4680}
4681
4682static int _nfs4_proc_create_session(struct nfs_client *clp)
4683{
4684 struct nfs4_session *session = clp->cl_session;
4685 struct nfs41_create_session_args args = {
4686 .client = clp,
4687 .cb_program = NFS4_CALLBACK,
4688 };
4689 struct nfs41_create_session_res res = {
4690 .client = clp,
4691 };
4692 struct rpc_message msg = {
4693 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION],
4694 .rpc_argp = &args,
4695 .rpc_resp = &res,
4696 };
4697 int status;
4698
4699 nfs4_init_channel_attrs(&args);
4700 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
4701
4702 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
4703
4704 if (!status)
4705 /* Verify the session's negotiated channel_attrs values */
4706 status = nfs4_verify_channel_attrs(&args, session);
4707 if (!status) {
4708 /* Increment the clientid slot sequence id */
4709 clp->cl_seqid++;
4710 }
4711
4712 return status;
4713}
4714
4715/*
4716 * Issues a CREATE_SESSION operation to the server.
4717 * It is the responsibility of the caller to verify the session is
4718 * expired before calling this routine.
4719 */
4720int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4721{
4722 int status;
4723 unsigned *ptr;
4724 struct nfs_fsinfo fsinfo;
4725 struct nfs4_session *session = clp->cl_session;
4726
4727 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
4728
4729 status = _nfs4_proc_create_session(clp);
4730 if (status)
4731 goto out;
4732
4733 /* Init or reset the fore channel */
4734 if (reset)
4735 status = nfs4_reset_slot_tables(session);
4736 else
4737 status = nfs4_init_slot_tables(session);
4738 dprintk("fore channel slot table initialization returned %d\n", status);
4739 if (status)
4740 goto out;
4741
4742 ptr = (unsigned *)&session->sess_id.data[0];
4743 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4744 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
4745
4746 if (reset)
4747 /* Lease time is aleady set */
4748 goto out;
4749
4750 /* Get the lease time */
4751 status = nfs4_proc_get_lease_time(clp, &fsinfo);
4752 if (status == 0) {
4753 /* Update lease time and schedule renewal */
4754 spin_lock(&clp->cl_lock);
4755 clp->cl_lease_time = fsinfo.lease_time * HZ;
4756 clp->cl_last_renewal = jiffies;
4757 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
4758 spin_unlock(&clp->cl_lock);
4759
4760 nfs4_schedule_state_renewal(clp);
4761 }
4762out:
4763 dprintk("<-- %s\n", __func__);
4764 return status;
4765}
4766
4767/*
4768 * Issue the over-the-wire RPC DESTROY_SESSION.
4769 * The caller must serialize access to this routine.
4770 */
4771int nfs4_proc_destroy_session(struct nfs4_session *session)
4772{
4773 int status = 0;
4774 struct rpc_message msg;
4775
4776 dprintk("--> nfs4_proc_destroy_session\n");
4777
4778 /* session is still being setup */
4779 if (session->clp->cl_cons_state != NFS_CS_READY)
4780 return status;
4781
4782 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION];
4783 msg.rpc_argp = session;
4784 msg.rpc_resp = NULL;
4785 msg.rpc_cred = NULL;
4786 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
4787
4788 if (status)
4789 printk(KERN_WARNING
4790 "Got error %d from the server on DESTROY_SESSION. "
4791 "Session has been destroyed regardless...\n", status);
4792
4793 dprintk("<-- nfs4_proc_destroy_session\n");
4794 return status;
4795}
4796
4797/*
4798 * Renew the cl_session lease.
4799 */
4800static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4801{
4802 struct nfs4_sequence_args args;
4803 struct nfs4_sequence_res res;
4804
4805 struct rpc_message msg = {
4806 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
4807 .rpc_argp = &args,
4808 .rpc_resp = &res,
4809 .rpc_cred = cred,
4810 };
4811
4812 args.sa_cache_this = 0;
4813
4814 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4815 &res, 0);
4816}
4817
4818void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4819{
4820 struct nfs_client *clp = (struct nfs_client *)data;
4821
4822 nfs41_sequence_done(clp, task->tk_msg.rpc_resp, task->tk_status);
4823
4824 if (task->tk_status < 0) {
4825 dprintk("%s ERROR %d\n", __func__, task->tk_status);
4826
4827 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4828 == -EAGAIN) {
4829 nfs4_restart_rpc(task, clp);
4830 return;
4831 }
4832 }
4833 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4834 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4835
4836 put_rpccred(task->tk_msg.rpc_cred);
4837 kfree(task->tk_msg.rpc_argp);
4838 kfree(task->tk_msg.rpc_resp);
4839
4840 dprintk("<-- %s\n", __func__);
4841}
4842
4843static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
4844{
4845 struct nfs_client *clp;
4846 struct nfs4_sequence_args *args;
4847 struct nfs4_sequence_res *res;
4848
4849 clp = (struct nfs_client *)data;
4850 args = task->tk_msg.rpc_argp;
4851 res = task->tk_msg.rpc_resp;
4852
4853 if (nfs4_setup_sequence(clp, args, res, 0, task))
4854 return;
4855 rpc_call_start(task);
4856}
4857
4858static const struct rpc_call_ops nfs41_sequence_ops = {
4859 .rpc_call_done = nfs41_sequence_call_done,
4860 .rpc_call_prepare = nfs41_sequence_prepare,
4861};
4862
4863static int nfs41_proc_async_sequence(struct nfs_client *clp,
4864 struct rpc_cred *cred)
4865{
4866 struct nfs4_sequence_args *args;
4867 struct nfs4_sequence_res *res;
4868 struct rpc_message msg = {
4869 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
4870 .rpc_cred = cred,
4871 };
4872
4873 args = kzalloc(sizeof(*args), GFP_KERNEL);
4874 if (!args)
4875 return -ENOMEM;
4876 res = kzalloc(sizeof(*res), GFP_KERNEL);
4877 if (!res) {
4878 kfree(args);
4879 return -ENOMEM;
4880 }
4881 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
4882 msg.rpc_argp = args;
4883 msg.rpc_resp = res;
4884
4885 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
4886 &nfs41_sequence_ops, (void *)clp);
4887}
4888
4889#endif /* CONFIG_NFS_V4_1 */
4890
4891struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
3727 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, 4892 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
3728 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 4893 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
3729 .recover_open = nfs4_open_reclaim, 4894 .recover_open = nfs4_open_reclaim,
3730 .recover_lock = nfs4_lock_reclaim, 4895 .recover_lock = nfs4_lock_reclaim,
4896 .establish_clid = nfs4_init_clientid,
4897 .get_clid_cred = nfs4_get_setclientid_cred,
4898};
4899
4900#if defined(CONFIG_NFS_V4_1)
4901struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4902 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
4903 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4904 .recover_open = nfs4_open_reclaim,
4905 .recover_lock = nfs4_lock_reclaim,
4906 .establish_clid = nfs4_proc_exchange_id,
4907 .get_clid_cred = nfs4_get_exchange_id_cred,
4908};
4909#endif /* CONFIG_NFS_V4_1 */
4910
4911struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
4912 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
4913 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4914 .recover_open = nfs4_open_expired,
4915 .recover_lock = nfs4_lock_expired,
4916 .establish_clid = nfs4_init_clientid,
4917 .get_clid_cred = nfs4_get_setclientid_cred,
3731}; 4918};
3732 4919
3733struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = { 4920#if defined(CONFIG_NFS_V4_1)
4921struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
3734 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, 4922 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
3735 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 4923 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
3736 .recover_open = nfs4_open_expired, 4924 .recover_open = nfs4_open_expired,
3737 .recover_lock = nfs4_lock_expired, 4925 .recover_lock = nfs4_lock_expired,
4926 .establish_clid = nfs4_proc_exchange_id,
4927 .get_clid_cred = nfs4_get_exchange_id_cred,
4928};
4929#endif /* CONFIG_NFS_V4_1 */
4930
4931struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
4932 .sched_state_renewal = nfs4_proc_async_renew,
4933 .get_state_renewal_cred_locked = nfs4_get_renew_cred_locked,
4934 .renew_lease = nfs4_proc_renew,
4935};
4936
4937#if defined(CONFIG_NFS_V4_1)
4938struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
4939 .sched_state_renewal = nfs41_proc_async_sequence,
4940 .get_state_renewal_cred_locked = nfs4_get_machine_cred_locked,
4941 .renew_lease = nfs4_proc_sequence,
4942};
4943#endif
4944
4945/*
4946 * Per minor version reboot and network partition recovery ops
4947 */
4948
4949struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[] = {
4950 &nfs40_reboot_recovery_ops,
4951#if defined(CONFIG_NFS_V4_1)
4952 &nfs41_reboot_recovery_ops,
4953#endif
4954};
4955
4956struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[] = {
4957 &nfs40_nograce_recovery_ops,
4958#if defined(CONFIG_NFS_V4_1)
4959 &nfs41_nograce_recovery_ops,
4960#endif
4961};
4962
4963struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = {
4964 &nfs40_state_renewal_ops,
4965#if defined(CONFIG_NFS_V4_1)
4966 &nfs41_state_renewal_ops,
4967#endif
3738}; 4968};
3739 4969
3740static const struct inode_operations nfs4_file_inode_operations = { 4970static const struct inode_operations nfs4_file_inode_operations = {
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index f524e932ff7b..e27c6cef18f2 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -59,12 +59,14 @@
59void 59void
60nfs4_renew_state(struct work_struct *work) 60nfs4_renew_state(struct work_struct *work)
61{ 61{
62 struct nfs4_state_maintenance_ops *ops;
62 struct nfs_client *clp = 63 struct nfs_client *clp =
63 container_of(work, struct nfs_client, cl_renewd.work); 64 container_of(work, struct nfs_client, cl_renewd.work);
64 struct rpc_cred *cred; 65 struct rpc_cred *cred;
65 long lease, timeout; 66 long lease, timeout;
66 unsigned long last, now; 67 unsigned long last, now;
67 68
69 ops = nfs4_state_renewal_ops[clp->cl_minorversion];
68 dprintk("%s: start\n", __func__); 70 dprintk("%s: start\n", __func__);
69 /* Are there any active superblocks? */ 71 /* Are there any active superblocks? */
70 if (list_empty(&clp->cl_superblocks)) 72 if (list_empty(&clp->cl_superblocks))
@@ -76,7 +78,7 @@ nfs4_renew_state(struct work_struct *work)
76 timeout = (2 * lease) / 3 + (long)last - (long)now; 78 timeout = (2 * lease) / 3 + (long)last - (long)now;
77 /* Are we close to a lease timeout? */ 79 /* Are we close to a lease timeout? */
78 if (time_after(now, last + lease/3)) { 80 if (time_after(now, last + lease/3)) {
79 cred = nfs4_get_renew_cred_locked(clp); 81 cred = ops->get_state_renewal_cred_locked(clp);
80 spin_unlock(&clp->cl_lock); 82 spin_unlock(&clp->cl_lock);
81 if (cred == NULL) { 83 if (cred == NULL) {
82 if (list_empty(&clp->cl_delegations)) { 84 if (list_empty(&clp->cl_delegations)) {
@@ -86,7 +88,7 @@ nfs4_renew_state(struct work_struct *work)
86 nfs_expire_all_delegations(clp); 88 nfs_expire_all_delegations(clp);
87 } else { 89 } else {
88 /* Queue an asynchronous RENEW. */ 90 /* Queue an asynchronous RENEW. */
89 nfs4_proc_async_renew(clp, cred); 91 ops->sched_state_renewal(clp, cred);
90 put_rpccred(cred); 92 put_rpccred(cred);
91 } 93 }
92 timeout = (2 * lease) / 3; 94 timeout = (2 * lease) / 3;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0298e909559f..b73c5a728655 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -60,7 +60,7 @@ const nfs4_stateid zero_stateid;
60 60
61static LIST_HEAD(nfs4_clientid_list); 61static LIST_HEAD(nfs4_clientid_list);
62 62
63static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred) 63int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
64{ 64{
65 unsigned short port; 65 unsigned short port;
66 int status; 66 int status;
@@ -77,7 +77,7 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
77 return status; 77 return status;
78} 78}
79 79
80static struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) 80struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
81{ 81{
82 struct rpc_cred *cred = NULL; 82 struct rpc_cred *cred = NULL;
83 83
@@ -114,17 +114,21 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
114 return cred; 114 return cred;
115} 115}
116 116
117static struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) 117#if defined(CONFIG_NFS_V4_1)
118
119struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
118{ 120{
119 struct rpc_cred *cred; 121 struct rpc_cred *cred;
120 122
121 spin_lock(&clp->cl_lock); 123 spin_lock(&clp->cl_lock);
122 cred = nfs4_get_renew_cred_locked(clp); 124 cred = nfs4_get_machine_cred_locked(clp);
123 spin_unlock(&clp->cl_lock); 125 spin_unlock(&clp->cl_lock);
124 return cred; 126 return cred;
125} 127}
126 128
127static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) 129#endif /* CONFIG_NFS_V4_1 */
130
131struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
128{ 132{
129 struct nfs4_state_owner *sp; 133 struct nfs4_state_owner *sp;
130 struct rb_node *pos; 134 struct rb_node *pos;
@@ -738,12 +742,14 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
738 742
739void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) 743void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
740{ 744{
741 if (status == -NFS4ERR_BAD_SEQID) { 745 struct nfs4_state_owner *sp = container_of(seqid->sequence,
742 struct nfs4_state_owner *sp = container_of(seqid->sequence, 746 struct nfs4_state_owner, so_seqid);
743 struct nfs4_state_owner, so_seqid); 747 struct nfs_server *server = sp->so_server;
748
749 if (status == -NFS4ERR_BAD_SEQID)
744 nfs4_drop_state_owner(sp); 750 nfs4_drop_state_owner(sp);
745 } 751 if (!nfs4_has_session(server->nfs_client))
746 nfs_increment_seqid(status, seqid); 752 nfs_increment_seqid(status, seqid);
747} 753}
748 754
749/* 755/*
@@ -847,32 +853,45 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
847 struct file_lock *fl; 853 struct file_lock *fl;
848 int status = 0; 854 int status = 0;
849 855
856 if (inode->i_flock == NULL)
857 return 0;
858
859 /* Guard against delegation returns and new lock/unlock calls */
850 down_write(&nfsi->rwsem); 860 down_write(&nfsi->rwsem);
861 /* Protect inode->i_flock using the BKL */
862 lock_kernel();
851 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 863 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
852 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 864 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
853 continue; 865 continue;
854 if (nfs_file_open_context(fl->fl_file)->state != state) 866 if (nfs_file_open_context(fl->fl_file)->state != state)
855 continue; 867 continue;
868 unlock_kernel();
856 status = ops->recover_lock(state, fl); 869 status = ops->recover_lock(state, fl);
857 if (status >= 0)
858 continue;
859 switch (status) { 870 switch (status) {
871 case 0:
872 break;
873 case -ESTALE:
874 case -NFS4ERR_ADMIN_REVOKED:
875 case -NFS4ERR_STALE_STATEID:
876 case -NFS4ERR_BAD_STATEID:
877 case -NFS4ERR_EXPIRED:
878 case -NFS4ERR_NO_GRACE:
879 case -NFS4ERR_STALE_CLIENTID:
880 goto out;
860 default: 881 default:
861 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 882 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
862 __func__, status); 883 __func__, status);
863 case -NFS4ERR_EXPIRED: 884 case -ENOMEM:
864 case -NFS4ERR_NO_GRACE: 885 case -NFS4ERR_DENIED:
865 case -NFS4ERR_RECLAIM_BAD: 886 case -NFS4ERR_RECLAIM_BAD:
866 case -NFS4ERR_RECLAIM_CONFLICT: 887 case -NFS4ERR_RECLAIM_CONFLICT:
867 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 888 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
868 break; 889 status = 0;
869 case -NFS4ERR_STALE_CLIENTID:
870 goto out_err;
871 } 890 }
891 lock_kernel();
872 } 892 }
873 up_write(&nfsi->rwsem); 893 unlock_kernel();
874 return 0; 894out:
875out_err:
876 up_write(&nfsi->rwsem); 895 up_write(&nfsi->rwsem);
877 return status; 896 return status;
878} 897}
@@ -918,6 +937,7 @@ restart:
918 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 937 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
919 __func__, status); 938 __func__, status);
920 case -ENOENT: 939 case -ENOENT:
940 case -ENOMEM:
921 case -ESTALE: 941 case -ESTALE:
922 /* 942 /*
923 * Open state on this file cannot be recovered 943 * Open state on this file cannot be recovered
@@ -928,6 +948,9 @@ restart:
928 /* Mark the file as being 'closed' */ 948 /* Mark the file as being 'closed' */
929 state->state = 0; 949 state->state = 0;
930 break; 950 break;
951 case -NFS4ERR_ADMIN_REVOKED:
952 case -NFS4ERR_STALE_STATEID:
953 case -NFS4ERR_BAD_STATEID:
931 case -NFS4ERR_RECLAIM_BAD: 954 case -NFS4ERR_RECLAIM_BAD:
932 case -NFS4ERR_RECLAIM_CONFLICT: 955 case -NFS4ERR_RECLAIM_CONFLICT:
933 nfs4_state_mark_reclaim_nograce(sp->so_client, state); 956 nfs4_state_mark_reclaim_nograce(sp->so_client, state);
@@ -1042,6 +1065,14 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1042 case -NFS4ERR_EXPIRED: 1065 case -NFS4ERR_EXPIRED:
1043 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1066 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1044 nfs4_state_start_reclaim_nograce(clp); 1067 nfs4_state_start_reclaim_nograce(clp);
1068 case -NFS4ERR_BADSESSION:
1069 case -NFS4ERR_BADSLOT:
1070 case -NFS4ERR_BAD_HIGH_SLOT:
1071 case -NFS4ERR_DEADSESSION:
1072 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1073 case -NFS4ERR_SEQ_FALSE_RETRY:
1074 case -NFS4ERR_SEQ_MISORDERED:
1075 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1045 } 1076 }
1046} 1077}
1047 1078
@@ -1075,18 +1106,22 @@ restart:
1075static int nfs4_check_lease(struct nfs_client *clp) 1106static int nfs4_check_lease(struct nfs_client *clp)
1076{ 1107{
1077 struct rpc_cred *cred; 1108 struct rpc_cred *cred;
1109 struct nfs4_state_maintenance_ops *ops =
1110 nfs4_state_renewal_ops[clp->cl_minorversion];
1078 int status = -NFS4ERR_EXPIRED; 1111 int status = -NFS4ERR_EXPIRED;
1079 1112
1080 /* Is the client already known to have an expired lease? */ 1113 /* Is the client already known to have an expired lease? */
1081 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 1114 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1082 return 0; 1115 return 0;
1083 cred = nfs4_get_renew_cred(clp); 1116 spin_lock(&clp->cl_lock);
1117 cred = ops->get_state_renewal_cred_locked(clp);
1118 spin_unlock(&clp->cl_lock);
1084 if (cred == NULL) { 1119 if (cred == NULL) {
1085 cred = nfs4_get_setclientid_cred(clp); 1120 cred = nfs4_get_setclientid_cred(clp);
1086 if (cred == NULL) 1121 if (cred == NULL)
1087 goto out; 1122 goto out;
1088 } 1123 }
1089 status = nfs4_proc_renew(clp, cred); 1124 status = ops->renew_lease(clp, cred);
1090 put_rpccred(cred); 1125 put_rpccred(cred);
1091out: 1126out:
1092 nfs4_recovery_handle_error(clp, status); 1127 nfs4_recovery_handle_error(clp, status);
@@ -1096,21 +1131,98 @@ out:
1096static int nfs4_reclaim_lease(struct nfs_client *clp) 1131static int nfs4_reclaim_lease(struct nfs_client *clp)
1097{ 1132{
1098 struct rpc_cred *cred; 1133 struct rpc_cred *cred;
1134 struct nfs4_state_recovery_ops *ops =
1135 nfs4_reboot_recovery_ops[clp->cl_minorversion];
1099 int status = -ENOENT; 1136 int status = -ENOENT;
1100 1137
1101 cred = nfs4_get_setclientid_cred(clp); 1138 cred = ops->get_clid_cred(clp);
1102 if (cred != NULL) { 1139 if (cred != NULL) {
1103 status = nfs4_init_client(clp, cred); 1140 status = ops->establish_clid(clp, cred);
1104 put_rpccred(cred); 1141 put_rpccred(cred);
1105 /* Handle case where the user hasn't set up machine creds */ 1142 /* Handle case where the user hasn't set up machine creds */
1106 if (status == -EACCES && cred == clp->cl_machine_cred) { 1143 if (status == -EACCES && cred == clp->cl_machine_cred) {
1107 nfs4_clear_machine_cred(clp); 1144 nfs4_clear_machine_cred(clp);
1108 status = -EAGAIN; 1145 status = -EAGAIN;
1109 } 1146 }
1147 if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
1148 status = -EPROTONOSUPPORT;
1149 }
1150 return status;
1151}
1152
1153#ifdef CONFIG_NFS_V4_1
1154static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
1155{
1156 switch (err) {
1157 case -NFS4ERR_STALE_CLIENTID:
1158 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1159 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1160 }
1161}
1162
1163static int nfs4_reset_session(struct nfs_client *clp)
1164{
1165 int status;
1166
1167 status = nfs4_proc_destroy_session(clp->cl_session);
1168 if (status && status != -NFS4ERR_BADSESSION &&
1169 status != -NFS4ERR_DEADSESSION) {
1170 nfs4_session_recovery_handle_error(clp, status);
1171 goto out;
1110 } 1172 }
1173
1174 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
1175 status = nfs4_proc_create_session(clp, 1);
1176 if (status)
1177 nfs4_session_recovery_handle_error(clp, status);
1178 /* fall through*/
1179out:
1180 /* Wake up the next rpc task even on error */
1181 rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
1111 return status; 1182 return status;
1112} 1183}
1113 1184
1185static int nfs4_initialize_session(struct nfs_client *clp)
1186{
1187 int status;
1188
1189 status = nfs4_proc_create_session(clp, 0);
1190 if (!status) {
1191 nfs_mark_client_ready(clp, NFS_CS_READY);
1192 } else if (status == -NFS4ERR_STALE_CLIENTID) {
1193 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1194 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1195 } else {
1196 nfs_mark_client_ready(clp, status);
1197 }
1198 return status;
1199}
1200#else /* CONFIG_NFS_V4_1 */
1201static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1202static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
1203#endif /* CONFIG_NFS_V4_1 */
1204
1205/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
1206 * on EXCHANGE_ID for v4.1
1207 */
1208static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1209{
1210 if (nfs4_has_session(clp)) {
1211 switch (status) {
1212 case -NFS4ERR_DELAY:
1213 case -NFS4ERR_CLID_INUSE:
1214 case -EAGAIN:
1215 break;
1216
1217 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1218 * in nfs4_exchange_id */
1219 default:
1220 return;
1221 }
1222 }
1223 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1224}
1225
1114static void nfs4_state_manager(struct nfs_client *clp) 1226static void nfs4_state_manager(struct nfs_client *clp)
1115{ 1227{
1116 int status = 0; 1228 int status = 0;
@@ -1121,9 +1233,12 @@ static void nfs4_state_manager(struct nfs_client *clp)
1121 /* We're going to have to re-establish a clientid */ 1233 /* We're going to have to re-establish a clientid */
1122 status = nfs4_reclaim_lease(clp); 1234 status = nfs4_reclaim_lease(clp);
1123 if (status) { 1235 if (status) {
1124 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1236 nfs4_set_lease_expired(clp, status);
1125 if (status == -EAGAIN) 1237 if (status == -EAGAIN)
1126 continue; 1238 continue;
1239 if (clp->cl_cons_state ==
1240 NFS_CS_SESSION_INITING)
1241 nfs_mark_client_ready(clp, status);
1127 goto out_error; 1242 goto out_error;
1128 } 1243 }
1129 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1244 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
@@ -1134,25 +1249,44 @@ static void nfs4_state_manager(struct nfs_client *clp)
1134 if (status != 0) 1249 if (status != 0)
1135 continue; 1250 continue;
1136 } 1251 }
1137 1252 /* Initialize or reset the session */
1253 if (nfs4_has_session(clp) &&
1254 test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
1255 if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
1256 status = nfs4_initialize_session(clp);
1257 else
1258 status = nfs4_reset_session(clp);
1259 if (status) {
1260 if (status == -NFS4ERR_STALE_CLIENTID)
1261 continue;
1262 goto out_error;
1263 }
1264 }
1138 /* First recover reboot state... */ 1265 /* First recover reboot state... */
1139 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { 1266 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1140 status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); 1267 status = nfs4_do_reclaim(clp,
1268 nfs4_reboot_recovery_ops[clp->cl_minorversion]);
1141 if (status == -NFS4ERR_STALE_CLIENTID) 1269 if (status == -NFS4ERR_STALE_CLIENTID)
1142 continue; 1270 continue;
1271 if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
1272 continue;
1143 nfs4_state_end_reclaim_reboot(clp); 1273 nfs4_state_end_reclaim_reboot(clp);
1144 continue; 1274 continue;
1145 } 1275 }
1146 1276
1147 /* Now recover expired state... */ 1277 /* Now recover expired state... */
1148 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { 1278 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
1149 status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops); 1279 status = nfs4_do_reclaim(clp,
1280 nfs4_nograce_recovery_ops[clp->cl_minorversion]);
1150 if (status < 0) { 1281 if (status < 0) {
1151 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); 1282 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1152 if (status == -NFS4ERR_STALE_CLIENTID) 1283 if (status == -NFS4ERR_STALE_CLIENTID)
1153 continue; 1284 continue;
1154 if (status == -NFS4ERR_EXPIRED) 1285 if (status == -NFS4ERR_EXPIRED)
1155 continue; 1286 continue;
1287 if (test_bit(NFS4CLNT_SESSION_SETUP,
1288 &clp->cl_state))
1289 continue;
1156 goto out_error; 1290 goto out_error;
1157 } else 1291 } else
1158 nfs4_state_end_reclaim_nograce(clp); 1292 nfs4_state_end_reclaim_nograce(clp);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1690f0e44b91..617273e7d47f 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -192,12 +192,16 @@ static int nfs4_stat_to_errno(int);
192 decode_verifier_maxsz) 192 decode_verifier_maxsz)
193#define encode_remove_maxsz (op_encode_hdr_maxsz + \ 193#define encode_remove_maxsz (op_encode_hdr_maxsz + \
194 nfs4_name_maxsz) 194 nfs4_name_maxsz)
195#define decode_remove_maxsz (op_decode_hdr_maxsz + \
196 decode_change_info_maxsz)
195#define encode_rename_maxsz (op_encode_hdr_maxsz + \ 197#define encode_rename_maxsz (op_encode_hdr_maxsz + \
196 2 * nfs4_name_maxsz) 198 2 * nfs4_name_maxsz)
197#define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5) 199#define decode_rename_maxsz (op_decode_hdr_maxsz + \
200 decode_change_info_maxsz + \
201 decode_change_info_maxsz)
198#define encode_link_maxsz (op_encode_hdr_maxsz + \ 202#define encode_link_maxsz (op_encode_hdr_maxsz + \
199 nfs4_name_maxsz) 203 nfs4_name_maxsz)
200#define decode_link_maxsz (op_decode_hdr_maxsz + 5) 204#define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
201#define encode_lock_maxsz (op_encode_hdr_maxsz + \ 205#define encode_lock_maxsz (op_encode_hdr_maxsz + \
202 7 + \ 206 7 + \
203 1 + encode_stateid_maxsz + 8) 207 1 + encode_stateid_maxsz + 8)
@@ -240,43 +244,115 @@ static int nfs4_stat_to_errno(int);
240 (encode_getattr_maxsz) 244 (encode_getattr_maxsz)
241#define decode_fs_locations_maxsz \ 245#define decode_fs_locations_maxsz \
242 (0) 246 (0)
247
248#if defined(CONFIG_NFS_V4_1)
249#define NFS4_MAX_MACHINE_NAME_LEN (64)
250
251#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
252 encode_verifier_maxsz + \
253 1 /* co_ownerid.len */ + \
254 XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
255 1 /* flags */ + \
256 1 /* spa_how */ + \
257 0 /* SP4_NONE (for now) */ + \
258 1 /* zero implemetation id array */)
259#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
260 2 /* eir_clientid */ + \
261 1 /* eir_sequenceid */ + \
262 1 /* eir_flags */ + \
263 1 /* spr_how */ + \
264 0 /* SP4_NONE (for now) */ + \
265 2 /* eir_server_owner.so_minor_id */ + \
266 /* eir_server_owner.so_major_id<> */ \
267 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
268 /* eir_server_scope<> */ \
269 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
270 1 /* eir_server_impl_id array length */ + \
271 0 /* ignored eir_server_impl_id contents */)
272#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */)
273#define decode_channel_attrs_maxsz (6 + \
274 1 /* ca_rdma_ird.len */ + \
275 1 /* ca_rdma_ird */)
276#define encode_create_session_maxsz (op_encode_hdr_maxsz + \
277 2 /* csa_clientid */ + \
278 1 /* csa_sequence */ + \
279 1 /* csa_flags */ + \
280 encode_channel_attrs_maxsz + \
281 encode_channel_attrs_maxsz + \
282 1 /* csa_cb_program */ + \
283 1 /* csa_sec_parms.len (1) */ + \
284 1 /* cb_secflavor (AUTH_SYS) */ + \
285 1 /* stamp */ + \
286 1 /* machinename.len */ + \
287 XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \
288 1 /* uid */ + \
289 1 /* gid */ + \
290 1 /* gids.len (0) */)
291#define decode_create_session_maxsz (op_decode_hdr_maxsz + \
292 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
293 1 /* csr_sequence */ + \
294 1 /* csr_flags */ + \
295 decode_channel_attrs_maxsz + \
296 decode_channel_attrs_maxsz)
297#define encode_destroy_session_maxsz (op_encode_hdr_maxsz + 4)
298#define decode_destroy_session_maxsz (op_decode_hdr_maxsz)
299#define encode_sequence_maxsz (op_encode_hdr_maxsz + \
300 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
301#define decode_sequence_maxsz (op_decode_hdr_maxsz + \
302 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
303#else /* CONFIG_NFS_V4_1 */
304#define encode_sequence_maxsz 0
305#define decode_sequence_maxsz 0
306#endif /* CONFIG_NFS_V4_1 */
307
243#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ 308#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
244#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ 309#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
245#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ 310#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
311 encode_sequence_maxsz + \
246 encode_putfh_maxsz + \ 312 encode_putfh_maxsz + \
247 encode_read_maxsz) 313 encode_read_maxsz)
248#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ 314#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \
315 decode_sequence_maxsz + \
249 decode_putfh_maxsz + \ 316 decode_putfh_maxsz + \
250 decode_read_maxsz) 317 decode_read_maxsz)
251#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ 318#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \
319 encode_sequence_maxsz + \
252 encode_putfh_maxsz + \ 320 encode_putfh_maxsz + \
253 encode_readlink_maxsz) 321 encode_readlink_maxsz)
254#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ 322#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \
323 decode_sequence_maxsz + \
255 decode_putfh_maxsz + \ 324 decode_putfh_maxsz + \
256 decode_readlink_maxsz) 325 decode_readlink_maxsz)
257#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ 326#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \
327 encode_sequence_maxsz + \
258 encode_putfh_maxsz + \ 328 encode_putfh_maxsz + \
259 encode_readdir_maxsz) 329 encode_readdir_maxsz)
260#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ 330#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \
331 decode_sequence_maxsz + \
261 decode_putfh_maxsz + \ 332 decode_putfh_maxsz + \
262 decode_readdir_maxsz) 333 decode_readdir_maxsz)
263#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ 334#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
335 encode_sequence_maxsz + \
264 encode_putfh_maxsz + \ 336 encode_putfh_maxsz + \
265 encode_write_maxsz + \ 337 encode_write_maxsz + \
266 encode_getattr_maxsz) 338 encode_getattr_maxsz)
267#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ 339#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
340 decode_sequence_maxsz + \
268 decode_putfh_maxsz + \ 341 decode_putfh_maxsz + \
269 decode_write_maxsz + \ 342 decode_write_maxsz + \
270 decode_getattr_maxsz) 343 decode_getattr_maxsz)
271#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ 344#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
345 encode_sequence_maxsz + \
272 encode_putfh_maxsz + \ 346 encode_putfh_maxsz + \
273 encode_commit_maxsz + \ 347 encode_commit_maxsz + \
274 encode_getattr_maxsz) 348 encode_getattr_maxsz)
275#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ 349#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
350 decode_sequence_maxsz + \
276 decode_putfh_maxsz + \ 351 decode_putfh_maxsz + \
277 decode_commit_maxsz + \ 352 decode_commit_maxsz + \
278 decode_getattr_maxsz) 353 decode_getattr_maxsz)
279#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ 354#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
355 encode_sequence_maxsz + \
280 encode_putfh_maxsz + \ 356 encode_putfh_maxsz + \
281 encode_savefh_maxsz + \ 357 encode_savefh_maxsz + \
282 encode_open_maxsz + \ 358 encode_open_maxsz + \
@@ -285,6 +361,7 @@ static int nfs4_stat_to_errno(int);
285 encode_restorefh_maxsz + \ 361 encode_restorefh_maxsz + \
286 encode_getattr_maxsz) 362 encode_getattr_maxsz)
287#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ 363#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
364 decode_sequence_maxsz + \
288 decode_putfh_maxsz + \ 365 decode_putfh_maxsz + \
289 decode_savefh_maxsz + \ 366 decode_savefh_maxsz + \
290 decode_open_maxsz + \ 367 decode_open_maxsz + \
@@ -301,43 +378,53 @@ static int nfs4_stat_to_errno(int);
301 decode_putfh_maxsz + \ 378 decode_putfh_maxsz + \
302 decode_open_confirm_maxsz) 379 decode_open_confirm_maxsz)
303#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ 380#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
381 encode_sequence_maxsz + \
304 encode_putfh_maxsz + \ 382 encode_putfh_maxsz + \
305 encode_open_maxsz + \ 383 encode_open_maxsz + \
306 encode_getattr_maxsz) 384 encode_getattr_maxsz)
307#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ 385#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
386 decode_sequence_maxsz + \
308 decode_putfh_maxsz + \ 387 decode_putfh_maxsz + \
309 decode_open_maxsz + \ 388 decode_open_maxsz + \
310 decode_getattr_maxsz) 389 decode_getattr_maxsz)
311#define NFS4_enc_open_downgrade_sz \ 390#define NFS4_enc_open_downgrade_sz \
312 (compound_encode_hdr_maxsz + \ 391 (compound_encode_hdr_maxsz + \
392 encode_sequence_maxsz + \
313 encode_putfh_maxsz + \ 393 encode_putfh_maxsz + \
314 encode_open_downgrade_maxsz + \ 394 encode_open_downgrade_maxsz + \
315 encode_getattr_maxsz) 395 encode_getattr_maxsz)
316#define NFS4_dec_open_downgrade_sz \ 396#define NFS4_dec_open_downgrade_sz \
317 (compound_decode_hdr_maxsz + \ 397 (compound_decode_hdr_maxsz + \
398 decode_sequence_maxsz + \
318 decode_putfh_maxsz + \ 399 decode_putfh_maxsz + \
319 decode_open_downgrade_maxsz + \ 400 decode_open_downgrade_maxsz + \
320 decode_getattr_maxsz) 401 decode_getattr_maxsz)
321#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ 402#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
403 encode_sequence_maxsz + \
322 encode_putfh_maxsz + \ 404 encode_putfh_maxsz + \
323 encode_close_maxsz + \ 405 encode_close_maxsz + \
324 encode_getattr_maxsz) 406 encode_getattr_maxsz)
325#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ 407#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
408 decode_sequence_maxsz + \
326 decode_putfh_maxsz + \ 409 decode_putfh_maxsz + \
327 decode_close_maxsz + \ 410 decode_close_maxsz + \
328 decode_getattr_maxsz) 411 decode_getattr_maxsz)
329#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ 412#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
413 encode_sequence_maxsz + \
330 encode_putfh_maxsz + \ 414 encode_putfh_maxsz + \
331 encode_setattr_maxsz + \ 415 encode_setattr_maxsz + \
332 encode_getattr_maxsz) 416 encode_getattr_maxsz)
333#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ 417#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
418 decode_sequence_maxsz + \
334 decode_putfh_maxsz + \ 419 decode_putfh_maxsz + \
335 decode_setattr_maxsz + \ 420 decode_setattr_maxsz + \
336 decode_getattr_maxsz) 421 decode_getattr_maxsz)
337#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ 422#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
423 encode_sequence_maxsz + \
338 encode_putfh_maxsz + \ 424 encode_putfh_maxsz + \
339 encode_fsinfo_maxsz) 425 encode_fsinfo_maxsz)
340#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ 426#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \
427 decode_sequence_maxsz + \
341 decode_putfh_maxsz + \ 428 decode_putfh_maxsz + \
342 decode_fsinfo_maxsz) 429 decode_fsinfo_maxsz)
343#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \ 430#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \
@@ -359,64 +446,81 @@ static int nfs4_stat_to_errno(int);
359 decode_putrootfh_maxsz + \ 446 decode_putrootfh_maxsz + \
360 decode_fsinfo_maxsz) 447 decode_fsinfo_maxsz)
361#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ 448#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \
449 encode_sequence_maxsz + \
362 encode_putfh_maxsz + \ 450 encode_putfh_maxsz + \
363 encode_lock_maxsz) 451 encode_lock_maxsz)
364#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ 452#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \
453 decode_sequence_maxsz + \
365 decode_putfh_maxsz + \ 454 decode_putfh_maxsz + \
366 decode_lock_maxsz) 455 decode_lock_maxsz)
367#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ 456#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \
457 encode_sequence_maxsz + \
368 encode_putfh_maxsz + \ 458 encode_putfh_maxsz + \
369 encode_lockt_maxsz) 459 encode_lockt_maxsz)
370#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \ 460#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \
461 decode_sequence_maxsz + \
371 decode_putfh_maxsz + \ 462 decode_putfh_maxsz + \
372 decode_lockt_maxsz) 463 decode_lockt_maxsz)
373#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ 464#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \
465 encode_sequence_maxsz + \
374 encode_putfh_maxsz + \ 466 encode_putfh_maxsz + \
375 encode_locku_maxsz) 467 encode_locku_maxsz)
376#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ 468#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \
469 decode_sequence_maxsz + \
377 decode_putfh_maxsz + \ 470 decode_putfh_maxsz + \
378 decode_locku_maxsz) 471 decode_locku_maxsz)
379#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ 472#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
473 encode_sequence_maxsz + \
380 encode_putfh_maxsz + \ 474 encode_putfh_maxsz + \
381 encode_access_maxsz + \ 475 encode_access_maxsz + \
382 encode_getattr_maxsz) 476 encode_getattr_maxsz)
383#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ 477#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \
478 decode_sequence_maxsz + \
384 decode_putfh_maxsz + \ 479 decode_putfh_maxsz + \
385 decode_access_maxsz + \ 480 decode_access_maxsz + \
386 decode_getattr_maxsz) 481 decode_getattr_maxsz)
387#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ 482#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
483 encode_sequence_maxsz + \
388 encode_putfh_maxsz + \ 484 encode_putfh_maxsz + \
389 encode_getattr_maxsz) 485 encode_getattr_maxsz)
390#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ 486#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
487 decode_sequence_maxsz + \
391 decode_putfh_maxsz + \ 488 decode_putfh_maxsz + \
392 decode_getattr_maxsz) 489 decode_getattr_maxsz)
393#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ 490#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
491 encode_sequence_maxsz + \
394 encode_putfh_maxsz + \ 492 encode_putfh_maxsz + \
395 encode_lookup_maxsz + \ 493 encode_lookup_maxsz + \
396 encode_getattr_maxsz + \ 494 encode_getattr_maxsz + \
397 encode_getfh_maxsz) 495 encode_getfh_maxsz)
398#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \ 496#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \
497 decode_sequence_maxsz + \
399 decode_putfh_maxsz + \ 498 decode_putfh_maxsz + \
400 decode_lookup_maxsz + \ 499 decode_lookup_maxsz + \
401 decode_getattr_maxsz + \ 500 decode_getattr_maxsz + \
402 decode_getfh_maxsz) 501 decode_getfh_maxsz)
403#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ 502#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
503 encode_sequence_maxsz + \
404 encode_putrootfh_maxsz + \ 504 encode_putrootfh_maxsz + \
405 encode_getattr_maxsz + \ 505 encode_getattr_maxsz + \
406 encode_getfh_maxsz) 506 encode_getfh_maxsz)
407#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ 507#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
508 decode_sequence_maxsz + \
408 decode_putrootfh_maxsz + \ 509 decode_putrootfh_maxsz + \
409 decode_getattr_maxsz + \ 510 decode_getattr_maxsz + \
410 decode_getfh_maxsz) 511 decode_getfh_maxsz)
411#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ 512#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
513 encode_sequence_maxsz + \
412 encode_putfh_maxsz + \ 514 encode_putfh_maxsz + \
413 encode_remove_maxsz + \ 515 encode_remove_maxsz + \
414 encode_getattr_maxsz) 516 encode_getattr_maxsz)
415#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ 517#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
518 decode_sequence_maxsz + \
416 decode_putfh_maxsz + \ 519 decode_putfh_maxsz + \
417 op_decode_hdr_maxsz + 5 + \ 520 decode_remove_maxsz + \
418 decode_getattr_maxsz) 521 decode_getattr_maxsz)
419#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ 522#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
523 encode_sequence_maxsz + \
420 encode_putfh_maxsz + \ 524 encode_putfh_maxsz + \
421 encode_savefh_maxsz + \ 525 encode_savefh_maxsz + \
422 encode_putfh_maxsz + \ 526 encode_putfh_maxsz + \
@@ -425,6 +529,7 @@ static int nfs4_stat_to_errno(int);
425 encode_restorefh_maxsz + \ 529 encode_restorefh_maxsz + \
426 encode_getattr_maxsz) 530 encode_getattr_maxsz)
427#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ 531#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
532 decode_sequence_maxsz + \
428 decode_putfh_maxsz + \ 533 decode_putfh_maxsz + \
429 decode_savefh_maxsz + \ 534 decode_savefh_maxsz + \
430 decode_putfh_maxsz + \ 535 decode_putfh_maxsz + \
@@ -433,6 +538,7 @@ static int nfs4_stat_to_errno(int);
433 decode_restorefh_maxsz + \ 538 decode_restorefh_maxsz + \
434 decode_getattr_maxsz) 539 decode_getattr_maxsz)
435#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ 540#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
541 encode_sequence_maxsz + \
436 encode_putfh_maxsz + \ 542 encode_putfh_maxsz + \
437 encode_savefh_maxsz + \ 543 encode_savefh_maxsz + \
438 encode_putfh_maxsz + \ 544 encode_putfh_maxsz + \
@@ -441,6 +547,7 @@ static int nfs4_stat_to_errno(int);
441 encode_restorefh_maxsz + \ 547 encode_restorefh_maxsz + \
442 decode_getattr_maxsz) 548 decode_getattr_maxsz)
443#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ 549#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
550 decode_sequence_maxsz + \
444 decode_putfh_maxsz + \ 551 decode_putfh_maxsz + \
445 decode_savefh_maxsz + \ 552 decode_savefh_maxsz + \
446 decode_putfh_maxsz + \ 553 decode_putfh_maxsz + \
@@ -449,16 +556,19 @@ static int nfs4_stat_to_errno(int);
449 decode_restorefh_maxsz + \ 556 decode_restorefh_maxsz + \
450 decode_getattr_maxsz) 557 decode_getattr_maxsz)
451#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ 558#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
559 encode_sequence_maxsz + \
452 encode_putfh_maxsz + \ 560 encode_putfh_maxsz + \
453 encode_symlink_maxsz + \ 561 encode_symlink_maxsz + \
454 encode_getattr_maxsz + \ 562 encode_getattr_maxsz + \
455 encode_getfh_maxsz) 563 encode_getfh_maxsz)
456#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ 564#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \
565 decode_sequence_maxsz + \
457 decode_putfh_maxsz + \ 566 decode_putfh_maxsz + \
458 decode_symlink_maxsz + \ 567 decode_symlink_maxsz + \
459 decode_getattr_maxsz + \ 568 decode_getattr_maxsz + \
460 decode_getfh_maxsz) 569 decode_getfh_maxsz)
461#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ 570#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
571 encode_sequence_maxsz + \
462 encode_putfh_maxsz + \ 572 encode_putfh_maxsz + \
463 encode_savefh_maxsz + \ 573 encode_savefh_maxsz + \
464 encode_create_maxsz + \ 574 encode_create_maxsz + \
@@ -467,6 +577,7 @@ static int nfs4_stat_to_errno(int);
467 encode_restorefh_maxsz + \ 577 encode_restorefh_maxsz + \
468 encode_getattr_maxsz) 578 encode_getattr_maxsz)
469#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ 579#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
580 decode_sequence_maxsz + \
470 decode_putfh_maxsz + \ 581 decode_putfh_maxsz + \
471 decode_savefh_maxsz + \ 582 decode_savefh_maxsz + \
472 decode_create_maxsz + \ 583 decode_create_maxsz + \
@@ -475,52 +586,98 @@ static int nfs4_stat_to_errno(int);
475 decode_restorefh_maxsz + \ 586 decode_restorefh_maxsz + \
476 decode_getattr_maxsz) 587 decode_getattr_maxsz)
477#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ 588#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
589 encode_sequence_maxsz + \
478 encode_putfh_maxsz + \ 590 encode_putfh_maxsz + \
479 encode_getattr_maxsz) 591 encode_getattr_maxsz)
480#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ 592#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \
593 decode_sequence_maxsz + \
481 decode_putfh_maxsz + \ 594 decode_putfh_maxsz + \
482 decode_getattr_maxsz) 595 decode_getattr_maxsz)
483#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ 596#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \
597 encode_sequence_maxsz + \
484 encode_putfh_maxsz + \ 598 encode_putfh_maxsz + \
485 encode_statfs_maxsz) 599 encode_statfs_maxsz)
486#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ 600#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \
601 decode_sequence_maxsz + \
487 decode_putfh_maxsz + \ 602 decode_putfh_maxsz + \
488 decode_statfs_maxsz) 603 decode_statfs_maxsz)
489#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ 604#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
605 encode_sequence_maxsz + \
490 encode_putfh_maxsz + \ 606 encode_putfh_maxsz + \
491 encode_getattr_maxsz) 607 encode_getattr_maxsz)
492#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ 608#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
609 decode_sequence_maxsz + \
493 decode_putfh_maxsz + \ 610 decode_putfh_maxsz + \
494 decode_getattr_maxsz) 611 decode_getattr_maxsz)
495#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ 612#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
613 encode_sequence_maxsz + \
496 encode_putfh_maxsz + \ 614 encode_putfh_maxsz + \
497 encode_delegreturn_maxsz + \ 615 encode_delegreturn_maxsz + \
498 encode_getattr_maxsz) 616 encode_getattr_maxsz)
499#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ 617#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
618 decode_sequence_maxsz + \
500 decode_delegreturn_maxsz + \ 619 decode_delegreturn_maxsz + \
501 decode_getattr_maxsz) 620 decode_getattr_maxsz)
502#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ 621#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
622 encode_sequence_maxsz + \
503 encode_putfh_maxsz + \ 623 encode_putfh_maxsz + \
504 encode_getacl_maxsz) 624 encode_getacl_maxsz)
505#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ 625#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \
626 decode_sequence_maxsz + \
506 decode_putfh_maxsz + \ 627 decode_putfh_maxsz + \
507 decode_getacl_maxsz) 628 decode_getacl_maxsz)
508#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ 629#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \
630 encode_sequence_maxsz + \
509 encode_putfh_maxsz + \ 631 encode_putfh_maxsz + \
510 encode_setacl_maxsz) 632 encode_setacl_maxsz)
511#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ 633#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
634 decode_sequence_maxsz + \
512 decode_putfh_maxsz + \ 635 decode_putfh_maxsz + \
513 decode_setacl_maxsz) 636 decode_setacl_maxsz)
514#define NFS4_enc_fs_locations_sz \ 637#define NFS4_enc_fs_locations_sz \
515 (compound_encode_hdr_maxsz + \ 638 (compound_encode_hdr_maxsz + \
639 encode_sequence_maxsz + \
516 encode_putfh_maxsz + \ 640 encode_putfh_maxsz + \
517 encode_lookup_maxsz + \ 641 encode_lookup_maxsz + \
518 encode_fs_locations_maxsz) 642 encode_fs_locations_maxsz)
519#define NFS4_dec_fs_locations_sz \ 643#define NFS4_dec_fs_locations_sz \
520 (compound_decode_hdr_maxsz + \ 644 (compound_decode_hdr_maxsz + \
645 decode_sequence_maxsz + \
521 decode_putfh_maxsz + \ 646 decode_putfh_maxsz + \
522 decode_lookup_maxsz + \ 647 decode_lookup_maxsz + \
523 decode_fs_locations_maxsz) 648 decode_fs_locations_maxsz)
649#if defined(CONFIG_NFS_V4_1)
650#define NFS4_enc_exchange_id_sz \
651 (compound_encode_hdr_maxsz + \
652 encode_exchange_id_maxsz)
653#define NFS4_dec_exchange_id_sz \
654 (compound_decode_hdr_maxsz + \
655 decode_exchange_id_maxsz)
656#define NFS4_enc_create_session_sz \
657 (compound_encode_hdr_maxsz + \
658 encode_create_session_maxsz)
659#define NFS4_dec_create_session_sz \
660 (compound_decode_hdr_maxsz + \
661 decode_create_session_maxsz)
662#define NFS4_enc_destroy_session_sz (compound_encode_hdr_maxsz + \
663 encode_destroy_session_maxsz)
664#define NFS4_dec_destroy_session_sz (compound_decode_hdr_maxsz + \
665 decode_destroy_session_maxsz)
666#define NFS4_enc_sequence_sz \
667 (compound_decode_hdr_maxsz + \
668 encode_sequence_maxsz)
669#define NFS4_dec_sequence_sz \
670 (compound_decode_hdr_maxsz + \
671 decode_sequence_maxsz)
672#define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \
673 encode_sequence_maxsz + \
674 encode_putrootfh_maxsz + \
675 encode_fsinfo_maxsz)
676#define NFS4_dec_get_lease_time_sz (compound_decode_hdr_maxsz + \
677 decode_sequence_maxsz + \
678 decode_putrootfh_maxsz + \
679 decode_fsinfo_maxsz)
680#endif /* CONFIG_NFS_V4_1 */
524 681
525static const umode_t nfs_type2fmt[] = { 682static const umode_t nfs_type2fmt[] = {
526 [NF4BAD] = 0, 683 [NF4BAD] = 0,
@@ -541,6 +698,8 @@ struct compound_hdr {
541 __be32 * nops_p; 698 __be32 * nops_p;
542 uint32_t taglen; 699 uint32_t taglen;
543 char * tag; 700 char * tag;
701 uint32_t replen; /* expected reply words */
702 u32 minorversion;
544}; 703};
545 704
546/* 705/*
@@ -576,22 +735,31 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *
576 xdr_encode_opaque(p, str, len); 735 xdr_encode_opaque(p, str, len);
577} 736}
578 737
579static void encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) 738static void encode_compound_hdr(struct xdr_stream *xdr,
739 struct rpc_rqst *req,
740 struct compound_hdr *hdr)
580{ 741{
581 __be32 *p; 742 __be32 *p;
743 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
744
745 /* initialize running count of expected bytes in reply.
746 * NOTE: the replied tag SHOULD be the same is the one sent,
747 * but this is not required as a MUST for the server to do so. */
748 hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
582 749
583 dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); 750 dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
584 BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); 751 BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
585 RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2)); 752 RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2));
586 WRITE32(hdr->taglen); 753 WRITE32(hdr->taglen);
587 WRITEMEM(hdr->tag, hdr->taglen); 754 WRITEMEM(hdr->tag, hdr->taglen);
588 WRITE32(NFS4_MINOR_VERSION); 755 WRITE32(hdr->minorversion);
589 hdr->nops_p = p; 756 hdr->nops_p = p;
590 WRITE32(hdr->nops); 757 WRITE32(hdr->nops);
591} 758}
592 759
593static void encode_nops(struct compound_hdr *hdr) 760static void encode_nops(struct compound_hdr *hdr)
594{ 761{
762 BUG_ON(hdr->nops > NFS4_MAX_OPS);
595 *hdr->nops_p = htonl(hdr->nops); 763 *hdr->nops_p = htonl(hdr->nops);
596} 764}
597 765
@@ -736,6 +904,7 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd
736 WRITE32(OP_ACCESS); 904 WRITE32(OP_ACCESS);
737 WRITE32(access); 905 WRITE32(access);
738 hdr->nops++; 906 hdr->nops++;
907 hdr->replen += decode_access_maxsz;
739} 908}
740 909
741static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr) 910static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -747,6 +916,7 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg
747 WRITE32(arg->seqid->sequence->counter); 916 WRITE32(arg->seqid->sequence->counter);
748 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); 917 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
749 hdr->nops++; 918 hdr->nops++;
919 hdr->replen += decode_close_maxsz;
750} 920}
751 921
752static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr) 922static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -758,6 +928,7 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar
758 WRITE64(args->offset); 928 WRITE64(args->offset);
759 WRITE32(args->count); 929 WRITE32(args->count);
760 hdr->nops++; 930 hdr->nops++;
931 hdr->replen += decode_commit_maxsz;
761} 932}
762 933
763static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr) 934static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
@@ -789,6 +960,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
789 WRITE32(create->name->len); 960 WRITE32(create->name->len);
790 WRITEMEM(create->name->name, create->name->len); 961 WRITEMEM(create->name->name, create->name->len);
791 hdr->nops++; 962 hdr->nops++;
963 hdr->replen += decode_create_maxsz;
792 964
793 encode_attrs(xdr, create->attrs, create->server); 965 encode_attrs(xdr, create->attrs, create->server);
794} 966}
@@ -802,6 +974,7 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c
802 WRITE32(1); 974 WRITE32(1);
803 WRITE32(bitmap); 975 WRITE32(bitmap);
804 hdr->nops++; 976 hdr->nops++;
977 hdr->replen += decode_getattr_maxsz;
805} 978}
806 979
807static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr) 980static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
@@ -814,6 +987,7 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm
814 WRITE32(bm0); 987 WRITE32(bm0);
815 WRITE32(bm1); 988 WRITE32(bm1);
816 hdr->nops++; 989 hdr->nops++;
990 hdr->replen += decode_getattr_maxsz;
817} 991}
818 992
819static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 993static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
@@ -841,6 +1015,7 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
841 RESERVE_SPACE(4); 1015 RESERVE_SPACE(4);
842 WRITE32(OP_GETFH); 1016 WRITE32(OP_GETFH);
843 hdr->nops++; 1017 hdr->nops++;
1018 hdr->replen += decode_getfh_maxsz;
844} 1019}
845 1020
846static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 1021static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -852,6 +1027,7 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct
852 WRITE32(name->len); 1027 WRITE32(name->len);
853 WRITEMEM(name->name, name->len); 1028 WRITEMEM(name->name, name->len);
854 hdr->nops++; 1029 hdr->nops++;
1030 hdr->replen += decode_link_maxsz;
855} 1031}
856 1032
857static inline int nfs4_lock_type(struct file_lock *fl, int block) 1033static inline int nfs4_lock_type(struct file_lock *fl, int block)
@@ -899,6 +1075,7 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args
899 WRITE32(args->lock_seqid->sequence->counter); 1075 WRITE32(args->lock_seqid->sequence->counter);
900 } 1076 }
901 hdr->nops++; 1077 hdr->nops++;
1078 hdr->replen += decode_lock_maxsz;
902} 1079}
903 1080
904static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr) 1081static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
@@ -915,6 +1092,7 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar
915 WRITEMEM("lock id:", 8); 1092 WRITEMEM("lock id:", 8);
916 WRITE64(args->lock_owner.id); 1093 WRITE64(args->lock_owner.id);
917 hdr->nops++; 1094 hdr->nops++;
1095 hdr->replen += decode_lockt_maxsz;
918} 1096}
919 1097
920static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr) 1098static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
@@ -929,6 +1107,7 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar
929 WRITE64(args->fl->fl_start); 1107 WRITE64(args->fl->fl_start);
930 WRITE64(nfs4_lock_length(args->fl)); 1108 WRITE64(nfs4_lock_length(args->fl));
931 hdr->nops++; 1109 hdr->nops++;
1110 hdr->replen += decode_locku_maxsz;
932} 1111}
933 1112
934static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 1113static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -941,6 +1120,7 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
941 WRITE32(len); 1120 WRITE32(len);
942 WRITEMEM(name->name, len); 1121 WRITEMEM(name->name, len);
943 hdr->nops++; 1122 hdr->nops++;
1123 hdr->replen += decode_lookup_maxsz;
944} 1124}
945 1125
946static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode) 1126static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
@@ -1080,6 +1260,7 @@ static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg,
1080 BUG(); 1260 BUG();
1081 } 1261 }
1082 hdr->nops++; 1262 hdr->nops++;
1263 hdr->replen += decode_open_maxsz;
1083} 1264}
1084 1265
1085static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr) 1266static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
@@ -1091,6 +1272,7 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co
1091 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); 1272 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
1092 WRITE32(arg->seqid->sequence->counter); 1273 WRITE32(arg->seqid->sequence->counter);
1093 hdr->nops++; 1274 hdr->nops++;
1275 hdr->replen += decode_open_confirm_maxsz;
1094} 1276}
1095 1277
1096static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr) 1278static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -1103,6 +1285,7 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close
1103 WRITE32(arg->seqid->sequence->counter); 1285 WRITE32(arg->seqid->sequence->counter);
1104 encode_share_access(xdr, arg->fmode); 1286 encode_share_access(xdr, arg->fmode);
1105 hdr->nops++; 1287 hdr->nops++;
1288 hdr->replen += decode_open_downgrade_maxsz;
1106} 1289}
1107 1290
1108static void 1291static void
@@ -1116,6 +1299,7 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd
1116 WRITE32(len); 1299 WRITE32(len);
1117 WRITEMEM(fh->data, len); 1300 WRITEMEM(fh->data, len);
1118 hdr->nops++; 1301 hdr->nops++;
1302 hdr->replen += decode_putfh_maxsz;
1119} 1303}
1120 1304
1121static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) 1305static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
@@ -1125,6 +1309,7 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1125 RESERVE_SPACE(4); 1309 RESERVE_SPACE(4);
1126 WRITE32(OP_PUTROOTFH); 1310 WRITE32(OP_PUTROOTFH);
1127 hdr->nops++; 1311 hdr->nops++;
1312 hdr->replen += decode_putrootfh_maxsz;
1128} 1313}
1129 1314
1130static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx) 1315static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
@@ -1153,6 +1338,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
1153 WRITE64(args->offset); 1338 WRITE64(args->offset);
1154 WRITE32(args->count); 1339 WRITE32(args->count);
1155 hdr->nops++; 1340 hdr->nops++;
1341 hdr->replen += decode_read_maxsz;
1156} 1342}
1157 1343
1158static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1344static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
@@ -1178,6 +1364,7 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1178 WRITE32(attrs[0] & readdir->bitmask[0]); 1364 WRITE32(attrs[0] & readdir->bitmask[0]);
1179 WRITE32(attrs[1] & readdir->bitmask[1]); 1365 WRITE32(attrs[1] & readdir->bitmask[1]);
1180 hdr->nops++; 1366 hdr->nops++;
1367 hdr->replen += decode_readdir_maxsz;
1181 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", 1368 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
1182 __func__, 1369 __func__,
1183 (unsigned long long)readdir->cookie, 1370 (unsigned long long)readdir->cookie,
@@ -1194,6 +1381,7 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *
1194 RESERVE_SPACE(4); 1381 RESERVE_SPACE(4);
1195 WRITE32(OP_READLINK); 1382 WRITE32(OP_READLINK);
1196 hdr->nops++; 1383 hdr->nops++;
1384 hdr->replen += decode_readlink_maxsz;
1197} 1385}
1198 1386
1199static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 1387static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -1205,6 +1393,7 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc
1205 WRITE32(name->len); 1393 WRITE32(name->len);
1206 WRITEMEM(name->name, name->len); 1394 WRITEMEM(name->name, name->len);
1207 hdr->nops++; 1395 hdr->nops++;
1396 hdr->replen += decode_remove_maxsz;
1208} 1397}
1209 1398
1210static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr) 1399static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
@@ -1220,6 +1409,7 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co
1220 WRITE32(newname->len); 1409 WRITE32(newname->len);
1221 WRITEMEM(newname->name, newname->len); 1410 WRITEMEM(newname->name, newname->len);
1222 hdr->nops++; 1411 hdr->nops++;
1412 hdr->replen += decode_rename_maxsz;
1223} 1413}
1224 1414
1225static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr) 1415static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr)
@@ -1230,6 +1420,7 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client
1230 WRITE32(OP_RENEW); 1420 WRITE32(OP_RENEW);
1231 WRITE64(client_stateid->cl_clientid); 1421 WRITE64(client_stateid->cl_clientid);
1232 hdr->nops++; 1422 hdr->nops++;
1423 hdr->replen += decode_renew_maxsz;
1233} 1424}
1234 1425
1235static void 1426static void
@@ -1240,6 +1431,7 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1240 RESERVE_SPACE(4); 1431 RESERVE_SPACE(4);
1241 WRITE32(OP_RESTOREFH); 1432 WRITE32(OP_RESTOREFH);
1242 hdr->nops++; 1433 hdr->nops++;
1434 hdr->replen += decode_restorefh_maxsz;
1243} 1435}
1244 1436
1245static int 1437static int
@@ -1259,6 +1451,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
1259 WRITE32(arg->acl_len); 1451 WRITE32(arg->acl_len);
1260 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); 1452 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
1261 hdr->nops++; 1453 hdr->nops++;
1454 hdr->replen += decode_setacl_maxsz;
1262 return 0; 1455 return 0;
1263} 1456}
1264 1457
@@ -1270,6 +1463,7 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1270 RESERVE_SPACE(4); 1463 RESERVE_SPACE(4);
1271 WRITE32(OP_SAVEFH); 1464 WRITE32(OP_SAVEFH);
1272 hdr->nops++; 1465 hdr->nops++;
1466 hdr->replen += decode_savefh_maxsz;
1273} 1467}
1274 1468
1275static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr) 1469static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
@@ -1280,6 +1474,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
1280 WRITE32(OP_SETATTR); 1474 WRITE32(OP_SETATTR);
1281 WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE); 1475 WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
1282 hdr->nops++; 1476 hdr->nops++;
1477 hdr->replen += decode_setattr_maxsz;
1283 encode_attrs(xdr, arg->iap, server); 1478 encode_attrs(xdr, arg->iap, server);
1284} 1479}
1285 1480
@@ -1299,6 +1494,7 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
1299 RESERVE_SPACE(4); 1494 RESERVE_SPACE(4);
1300 WRITE32(setclientid->sc_cb_ident); 1495 WRITE32(setclientid->sc_cb_ident);
1301 hdr->nops++; 1496 hdr->nops++;
1497 hdr->replen += decode_setclientid_maxsz;
1302} 1498}
1303 1499
1304static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr) 1500static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
@@ -1310,6 +1506,7 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_
1310 WRITE64(client_state->cl_clientid); 1506 WRITE64(client_state->cl_clientid);
1311 WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); 1507 WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
1312 hdr->nops++; 1508 hdr->nops++;
1509 hdr->replen += decode_setclientid_confirm_maxsz;
1313} 1510}
1314 1511
1315static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr) 1512static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -1328,6 +1525,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg
1328 1525
1329 xdr_write_pages(xdr, args->pages, args->pgbase, args->count); 1526 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1330 hdr->nops++; 1527 hdr->nops++;
1528 hdr->replen += decode_write_maxsz;
1331} 1529}
1332 1530
1333static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr) 1531static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
@@ -1339,11 +1537,163 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state
1339 WRITE32(OP_DELEGRETURN); 1537 WRITE32(OP_DELEGRETURN);
1340 WRITEMEM(stateid->data, NFS4_STATEID_SIZE); 1538 WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
1341 hdr->nops++; 1539 hdr->nops++;
1540 hdr->replen += decode_delegreturn_maxsz;
1541}
1542
1543#if defined(CONFIG_NFS_V4_1)
1544/* NFSv4.1 operations */
1545static void encode_exchange_id(struct xdr_stream *xdr,
1546 struct nfs41_exchange_id_args *args,
1547 struct compound_hdr *hdr)
1548{
1549 __be32 *p;
1550
1551 RESERVE_SPACE(4 + sizeof(args->verifier->data));
1552 WRITE32(OP_EXCHANGE_ID);
1553 WRITEMEM(args->verifier->data, sizeof(args->verifier->data));
1554
1555 encode_string(xdr, args->id_len, args->id);
1556
1557 RESERVE_SPACE(12);
1558 WRITE32(args->flags);
1559 WRITE32(0); /* zero length state_protect4_a */
1560 WRITE32(0); /* zero length implementation id array */
1561 hdr->nops++;
1562 hdr->replen += decode_exchange_id_maxsz;
1563}
1564
1565static void encode_create_session(struct xdr_stream *xdr,
1566 struct nfs41_create_session_args *args,
1567 struct compound_hdr *hdr)
1568{
1569 __be32 *p;
1570 char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
1571 uint32_t len;
1572 struct nfs_client *clp = args->client;
1573
1574 RESERVE_SPACE(4);
1575 WRITE32(OP_CREATE_SESSION);
1576
1577 RESERVE_SPACE(8);
1578 WRITE64(clp->cl_ex_clid);
1579
1580 RESERVE_SPACE(8);
1581 WRITE32(clp->cl_seqid); /*Sequence id */
1582 WRITE32(args->flags); /*flags */
1583
1584 RESERVE_SPACE(2*28); /* 2 channel_attrs */
1585 /* Fore Channel */
1586 WRITE32(args->fc_attrs.headerpadsz); /* header padding size */
1587 WRITE32(args->fc_attrs.max_rqst_sz); /* max req size */
1588 WRITE32(args->fc_attrs.max_resp_sz); /* max resp size */
1589 WRITE32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */
1590 WRITE32(args->fc_attrs.max_ops); /* max operations */
1591 WRITE32(args->fc_attrs.max_reqs); /* max requests */
1592 WRITE32(0); /* rdmachannel_attrs */
1593
1594 /* Back Channel */
1595 WRITE32(args->fc_attrs.headerpadsz); /* header padding size */
1596 WRITE32(args->bc_attrs.max_rqst_sz); /* max req size */
1597 WRITE32(args->bc_attrs.max_resp_sz); /* max resp size */
1598 WRITE32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */
1599 WRITE32(args->bc_attrs.max_ops); /* max operations */
1600 WRITE32(args->bc_attrs.max_reqs); /* max requests */
1601 WRITE32(0); /* rdmachannel_attrs */
1602
1603 RESERVE_SPACE(4);
1604 WRITE32(args->cb_program); /* cb_program */
1605
1606 RESERVE_SPACE(4); /* # of security flavors */
1607 WRITE32(1);
1608
1609 RESERVE_SPACE(4);
1610 WRITE32(RPC_AUTH_UNIX); /* auth_sys */
1611
1612 /* authsys_parms rfc1831 */
1613 RESERVE_SPACE(4);
1614 WRITE32((u32)clp->cl_boot_time.tv_nsec); /* stamp */
1615 len = scnprintf(machine_name, sizeof(machine_name), "%s",
1616 clp->cl_ipaddr);
1617 RESERVE_SPACE(16 + len);
1618 WRITE32(len);
1619 WRITEMEM(machine_name, len);
1620 WRITE32(0); /* UID */
1621 WRITE32(0); /* GID */
1622 WRITE32(0); /* No more gids */
1623 hdr->nops++;
1624 hdr->replen += decode_create_session_maxsz;
1625}
1626
1627static void encode_destroy_session(struct xdr_stream *xdr,
1628 struct nfs4_session *session,
1629 struct compound_hdr *hdr)
1630{
1631 __be32 *p;
1632 RESERVE_SPACE(4 + NFS4_MAX_SESSIONID_LEN);
1633 WRITE32(OP_DESTROY_SESSION);
1634 WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
1635 hdr->nops++;
1636 hdr->replen += decode_destroy_session_maxsz;
1342} 1637}
1638#endif /* CONFIG_NFS_V4_1 */
1639
1640static void encode_sequence(struct xdr_stream *xdr,
1641 const struct nfs4_sequence_args *args,
1642 struct compound_hdr *hdr)
1643{
1644#if defined(CONFIG_NFS_V4_1)
1645 struct nfs4_session *session = args->sa_session;
1646 struct nfs4_slot_table *tp;
1647 struct nfs4_slot *slot;
1648 __be32 *p;
1649
1650 if (!session)
1651 return;
1652
1653 tp = &session->fc_slot_table;
1654
1655 WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
1656 slot = tp->slots + args->sa_slotid;
1657
1658 RESERVE_SPACE(4);
1659 WRITE32(OP_SEQUENCE);
1660
1661 /*
1662 * Sessionid + seqid + slotid + max slotid + cache_this
1663 */
1664 dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d "
1665 "max_slotid=%d cache_this=%d\n",
1666 __func__,
1667 ((u32 *)session->sess_id.data)[0],
1668 ((u32 *)session->sess_id.data)[1],
1669 ((u32 *)session->sess_id.data)[2],
1670 ((u32 *)session->sess_id.data)[3],
1671 slot->seq_nr, args->sa_slotid,
1672 tp->highest_used_slotid, args->sa_cache_this);
1673 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 16);
1674 WRITEMEM(session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
1675 WRITE32(slot->seq_nr);
1676 WRITE32(args->sa_slotid);
1677 WRITE32(tp->highest_used_slotid);
1678 WRITE32(args->sa_cache_this);
1679 hdr->nops++;
1680 hdr->replen += decode_sequence_maxsz;
1681#endif /* CONFIG_NFS_V4_1 */
1682}
1683
1343/* 1684/*
1344 * END OF "GENERIC" ENCODE ROUTINES. 1685 * END OF "GENERIC" ENCODE ROUTINES.
1345 */ 1686 */
1346 1687
1688static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
1689{
1690#if defined(CONFIG_NFS_V4_1)
1691 if (args->sa_session)
1692 return args->sa_session->clp->cl_minorversion;
1693#endif /* CONFIG_NFS_V4_1 */
1694 return 0;
1695}
1696
1347/* 1697/*
1348 * Encode an ACCESS request 1698 * Encode an ACCESS request
1349 */ 1699 */
@@ -1351,11 +1701,12 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
1351{ 1701{
1352 struct xdr_stream xdr; 1702 struct xdr_stream xdr;
1353 struct compound_hdr hdr = { 1703 struct compound_hdr hdr = {
1354 .nops = 0, 1704 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1355 }; 1705 };
1356 1706
1357 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1707 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1358 encode_compound_hdr(&xdr, &hdr); 1708 encode_compound_hdr(&xdr, req, &hdr);
1709 encode_sequence(&xdr, &args->seq_args, &hdr);
1359 encode_putfh(&xdr, args->fh, &hdr); 1710 encode_putfh(&xdr, args->fh, &hdr);
1360 encode_access(&xdr, args->access, &hdr); 1711 encode_access(&xdr, args->access, &hdr);
1361 encode_getfattr(&xdr, args->bitmask, &hdr); 1712 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1370,11 +1721,12 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
1370{ 1721{
1371 struct xdr_stream xdr; 1722 struct xdr_stream xdr;
1372 struct compound_hdr hdr = { 1723 struct compound_hdr hdr = {
1373 .nops = 0, 1724 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1374 }; 1725 };
1375 1726
1376 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1727 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1377 encode_compound_hdr(&xdr, &hdr); 1728 encode_compound_hdr(&xdr, req, &hdr);
1729 encode_sequence(&xdr, &args->seq_args, &hdr);
1378 encode_putfh(&xdr, args->dir_fh, &hdr); 1730 encode_putfh(&xdr, args->dir_fh, &hdr);
1379 encode_lookup(&xdr, args->name, &hdr); 1731 encode_lookup(&xdr, args->name, &hdr);
1380 encode_getfh(&xdr, &hdr); 1732 encode_getfh(&xdr, &hdr);
@@ -1390,11 +1742,12 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
1390{ 1742{
1391 struct xdr_stream xdr; 1743 struct xdr_stream xdr;
1392 struct compound_hdr hdr = { 1744 struct compound_hdr hdr = {
1393 .nops = 0, 1745 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1394 }; 1746 };
1395 1747
1396 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1748 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1397 encode_compound_hdr(&xdr, &hdr); 1749 encode_compound_hdr(&xdr, req, &hdr);
1750 encode_sequence(&xdr, &args->seq_args, &hdr);
1398 encode_putrootfh(&xdr, &hdr); 1751 encode_putrootfh(&xdr, &hdr);
1399 encode_getfh(&xdr, &hdr); 1752 encode_getfh(&xdr, &hdr);
1400 encode_getfattr(&xdr, args->bitmask, &hdr); 1753 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1409,11 +1762,12 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
1409{ 1762{
1410 struct xdr_stream xdr; 1763 struct xdr_stream xdr;
1411 struct compound_hdr hdr = { 1764 struct compound_hdr hdr = {
1412 .nops = 0, 1765 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1413 }; 1766 };
1414 1767
1415 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1768 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1416 encode_compound_hdr(&xdr, &hdr); 1769 encode_compound_hdr(&xdr, req, &hdr);
1770 encode_sequence(&xdr, &args->seq_args, &hdr);
1417 encode_putfh(&xdr, args->fh, &hdr); 1771 encode_putfh(&xdr, args->fh, &hdr);
1418 encode_remove(&xdr, &args->name, &hdr); 1772 encode_remove(&xdr, &args->name, &hdr);
1419 encode_getfattr(&xdr, args->bitmask, &hdr); 1773 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1428,11 +1782,12 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
1428{ 1782{
1429 struct xdr_stream xdr; 1783 struct xdr_stream xdr;
1430 struct compound_hdr hdr = { 1784 struct compound_hdr hdr = {
1431 .nops = 0, 1785 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1432 }; 1786 };
1433 1787
1434 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1788 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1435 encode_compound_hdr(&xdr, &hdr); 1789 encode_compound_hdr(&xdr, req, &hdr);
1790 encode_sequence(&xdr, &args->seq_args, &hdr);
1436 encode_putfh(&xdr, args->old_dir, &hdr); 1791 encode_putfh(&xdr, args->old_dir, &hdr);
1437 encode_savefh(&xdr, &hdr); 1792 encode_savefh(&xdr, &hdr);
1438 encode_putfh(&xdr, args->new_dir, &hdr); 1793 encode_putfh(&xdr, args->new_dir, &hdr);
@@ -1451,11 +1806,12 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
1451{ 1806{
1452 struct xdr_stream xdr; 1807 struct xdr_stream xdr;
1453 struct compound_hdr hdr = { 1808 struct compound_hdr hdr = {
1454 .nops = 0, 1809 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1455 }; 1810 };
1456 1811
1457 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1812 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1458 encode_compound_hdr(&xdr, &hdr); 1813 encode_compound_hdr(&xdr, req, &hdr);
1814 encode_sequence(&xdr, &args->seq_args, &hdr);
1459 encode_putfh(&xdr, args->fh, &hdr); 1815 encode_putfh(&xdr, args->fh, &hdr);
1460 encode_savefh(&xdr, &hdr); 1816 encode_savefh(&xdr, &hdr);
1461 encode_putfh(&xdr, args->dir_fh, &hdr); 1817 encode_putfh(&xdr, args->dir_fh, &hdr);
@@ -1474,11 +1830,12 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs
1474{ 1830{
1475 struct xdr_stream xdr; 1831 struct xdr_stream xdr;
1476 struct compound_hdr hdr = { 1832 struct compound_hdr hdr = {
1477 .nops = 0, 1833 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1478 }; 1834 };
1479 1835
1480 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1836 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1481 encode_compound_hdr(&xdr, &hdr); 1837 encode_compound_hdr(&xdr, req, &hdr);
1838 encode_sequence(&xdr, &args->seq_args, &hdr);
1482 encode_putfh(&xdr, args->dir_fh, &hdr); 1839 encode_putfh(&xdr, args->dir_fh, &hdr);
1483 encode_savefh(&xdr, &hdr); 1840 encode_savefh(&xdr, &hdr);
1484 encode_create(&xdr, args, &hdr); 1841 encode_create(&xdr, args, &hdr);
@@ -1505,11 +1862,12 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
1505{ 1862{
1506 struct xdr_stream xdr; 1863 struct xdr_stream xdr;
1507 struct compound_hdr hdr = { 1864 struct compound_hdr hdr = {
1508 .nops = 0, 1865 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1509 }; 1866 };
1510 1867
1511 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1868 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1512 encode_compound_hdr(&xdr, &hdr); 1869 encode_compound_hdr(&xdr, req, &hdr);
1870 encode_sequence(&xdr, &args->seq_args, &hdr);
1513 encode_putfh(&xdr, args->fh, &hdr); 1871 encode_putfh(&xdr, args->fh, &hdr);
1514 encode_getfattr(&xdr, args->bitmask, &hdr); 1872 encode_getfattr(&xdr, args->bitmask, &hdr);
1515 encode_nops(&hdr); 1873 encode_nops(&hdr);
@@ -1523,11 +1881,12 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
1523{ 1881{
1524 struct xdr_stream xdr; 1882 struct xdr_stream xdr;
1525 struct compound_hdr hdr = { 1883 struct compound_hdr hdr = {
1526 .nops = 0, 1884 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1527 }; 1885 };
1528 1886
1529 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1887 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1530 encode_compound_hdr(&xdr, &hdr); 1888 encode_compound_hdr(&xdr, req, &hdr);
1889 encode_sequence(&xdr, &args->seq_args, &hdr);
1531 encode_putfh(&xdr, args->fh, &hdr); 1890 encode_putfh(&xdr, args->fh, &hdr);
1532 encode_close(&xdr, args, &hdr); 1891 encode_close(&xdr, args, &hdr);
1533 encode_getfattr(&xdr, args->bitmask, &hdr); 1892 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1542,11 +1901,12 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg
1542{ 1901{
1543 struct xdr_stream xdr; 1902 struct xdr_stream xdr;
1544 struct compound_hdr hdr = { 1903 struct compound_hdr hdr = {
1545 .nops = 0, 1904 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1546 }; 1905 };
1547 1906
1548 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1907 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1549 encode_compound_hdr(&xdr, &hdr); 1908 encode_compound_hdr(&xdr, req, &hdr);
1909 encode_sequence(&xdr, &args->seq_args, &hdr);
1550 encode_putfh(&xdr, args->fh, &hdr); 1910 encode_putfh(&xdr, args->fh, &hdr);
1551 encode_savefh(&xdr, &hdr); 1911 encode_savefh(&xdr, &hdr);
1552 encode_open(&xdr, args, &hdr); 1912 encode_open(&xdr, args, &hdr);
@@ -1569,7 +1929,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs
1569 }; 1929 };
1570 1930
1571 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1931 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1572 encode_compound_hdr(&xdr, &hdr); 1932 encode_compound_hdr(&xdr, req, &hdr);
1573 encode_putfh(&xdr, args->fh, &hdr); 1933 encode_putfh(&xdr, args->fh, &hdr);
1574 encode_open_confirm(&xdr, args, &hdr); 1934 encode_open_confirm(&xdr, args, &hdr);
1575 encode_nops(&hdr); 1935 encode_nops(&hdr);
@@ -1583,11 +1943,12 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
1583{ 1943{
1584 struct xdr_stream xdr; 1944 struct xdr_stream xdr;
1585 struct compound_hdr hdr = { 1945 struct compound_hdr hdr = {
1586 .nops = 0, 1946 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1587 }; 1947 };
1588 1948
1589 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1949 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1590 encode_compound_hdr(&xdr, &hdr); 1950 encode_compound_hdr(&xdr, req, &hdr);
1951 encode_sequence(&xdr, &args->seq_args, &hdr);
1591 encode_putfh(&xdr, args->fh, &hdr); 1952 encode_putfh(&xdr, args->fh, &hdr);
1592 encode_open(&xdr, args, &hdr); 1953 encode_open(&xdr, args, &hdr);
1593 encode_getfattr(&xdr, args->bitmask, &hdr); 1954 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1602,11 +1963,12 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
1602{ 1963{
1603 struct xdr_stream xdr; 1964 struct xdr_stream xdr;
1604 struct compound_hdr hdr = { 1965 struct compound_hdr hdr = {
1605 .nops = 0, 1966 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1606 }; 1967 };
1607 1968
1608 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1969 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1609 encode_compound_hdr(&xdr, &hdr); 1970 encode_compound_hdr(&xdr, req, &hdr);
1971 encode_sequence(&xdr, &args->seq_args, &hdr);
1610 encode_putfh(&xdr, args->fh, &hdr); 1972 encode_putfh(&xdr, args->fh, &hdr);
1611 encode_open_downgrade(&xdr, args, &hdr); 1973 encode_open_downgrade(&xdr, args, &hdr);
1612 encode_getfattr(&xdr, args->bitmask, &hdr); 1974 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1621,11 +1983,12 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
1621{ 1983{
1622 struct xdr_stream xdr; 1984 struct xdr_stream xdr;
1623 struct compound_hdr hdr = { 1985 struct compound_hdr hdr = {
1624 .nops = 0, 1986 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1625 }; 1987 };
1626 1988
1627 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1989 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1628 encode_compound_hdr(&xdr, &hdr); 1990 encode_compound_hdr(&xdr, req, &hdr);
1991 encode_sequence(&xdr, &args->seq_args, &hdr);
1629 encode_putfh(&xdr, args->fh, &hdr); 1992 encode_putfh(&xdr, args->fh, &hdr);
1630 encode_lock(&xdr, args, &hdr); 1993 encode_lock(&xdr, args, &hdr);
1631 encode_nops(&hdr); 1994 encode_nops(&hdr);
@@ -1639,11 +2002,12 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
1639{ 2002{
1640 struct xdr_stream xdr; 2003 struct xdr_stream xdr;
1641 struct compound_hdr hdr = { 2004 struct compound_hdr hdr = {
1642 .nops = 0, 2005 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1643 }; 2006 };
1644 2007
1645 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2008 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1646 encode_compound_hdr(&xdr, &hdr); 2009 encode_compound_hdr(&xdr, req, &hdr);
2010 encode_sequence(&xdr, &args->seq_args, &hdr);
1647 encode_putfh(&xdr, args->fh, &hdr); 2011 encode_putfh(&xdr, args->fh, &hdr);
1648 encode_lockt(&xdr, args, &hdr); 2012 encode_lockt(&xdr, args, &hdr);
1649 encode_nops(&hdr); 2013 encode_nops(&hdr);
@@ -1657,11 +2021,12 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
1657{ 2021{
1658 struct xdr_stream xdr; 2022 struct xdr_stream xdr;
1659 struct compound_hdr hdr = { 2023 struct compound_hdr hdr = {
1660 .nops = 0, 2024 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1661 }; 2025 };
1662 2026
1663 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2027 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1664 encode_compound_hdr(&xdr, &hdr); 2028 encode_compound_hdr(&xdr, req, &hdr);
2029 encode_sequence(&xdr, &args->seq_args, &hdr);
1665 encode_putfh(&xdr, args->fh, &hdr); 2030 encode_putfh(&xdr, args->fh, &hdr);
1666 encode_locku(&xdr, args, &hdr); 2031 encode_locku(&xdr, args, &hdr);
1667 encode_nops(&hdr); 2032 encode_nops(&hdr);
@@ -1675,22 +2040,16 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
1675{ 2040{
1676 struct xdr_stream xdr; 2041 struct xdr_stream xdr;
1677 struct compound_hdr hdr = { 2042 struct compound_hdr hdr = {
1678 .nops = 0, 2043 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1679 }; 2044 };
1680 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1681 unsigned int replen;
1682 2045
1683 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2046 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1684 encode_compound_hdr(&xdr, &hdr); 2047 encode_compound_hdr(&xdr, req, &hdr);
2048 encode_sequence(&xdr, &args->seq_args, &hdr);
1685 encode_putfh(&xdr, args->fh, &hdr); 2049 encode_putfh(&xdr, args->fh, &hdr);
1686 encode_readlink(&xdr, args, req, &hdr); 2050 encode_readlink(&xdr, args, req, &hdr);
1687 2051
1688 /* set up reply kvec 2052 xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
1689 * toplevel_status + taglen + rescount + OP_PUTFH + status
1690 * + OP_READLINK + status + string length = 8
1691 */
1692 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
1693 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
1694 args->pgbase, args->pglen); 2053 args->pgbase, args->pglen);
1695 encode_nops(&hdr); 2054 encode_nops(&hdr);
1696 return 0; 2055 return 0;
@@ -1703,25 +2062,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
1703{ 2062{
1704 struct xdr_stream xdr; 2063 struct xdr_stream xdr;
1705 struct compound_hdr hdr = { 2064 struct compound_hdr hdr = {
1706 .nops = 0, 2065 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1707 }; 2066 };
1708 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1709 int replen;
1710 2067
1711 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2068 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1712 encode_compound_hdr(&xdr, &hdr); 2069 encode_compound_hdr(&xdr, req, &hdr);
2070 encode_sequence(&xdr, &args->seq_args, &hdr);
1713 encode_putfh(&xdr, args->fh, &hdr); 2071 encode_putfh(&xdr, args->fh, &hdr);
1714 encode_readdir(&xdr, args, req, &hdr); 2072 encode_readdir(&xdr, args, req, &hdr);
1715 2073
1716 /* set up reply kvec 2074 xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
1717 * toplevel_status + taglen + rescount + OP_PUTFH + status
1718 * + OP_READDIR + status + verifer(2) = 9
1719 */
1720 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
1721 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
1722 args->pgbase, args->count); 2075 args->pgbase, args->count);
1723 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n", 2076 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
1724 __func__, replen, args->pages, 2077 __func__, hdr.replen << 2, args->pages,
1725 args->pgbase, args->count); 2078 args->pgbase, args->count);
1726 encode_nops(&hdr); 2079 encode_nops(&hdr);
1727 return 0; 2080 return 0;
@@ -1732,24 +2085,18 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
1732 */ 2085 */
1733static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) 2086static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1734{ 2087{
1735 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1736 struct xdr_stream xdr; 2088 struct xdr_stream xdr;
1737 struct compound_hdr hdr = { 2089 struct compound_hdr hdr = {
1738 .nops = 0, 2090 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1739 }; 2091 };
1740 int replen;
1741 2092
1742 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2093 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1743 encode_compound_hdr(&xdr, &hdr); 2094 encode_compound_hdr(&xdr, req, &hdr);
2095 encode_sequence(&xdr, &args->seq_args, &hdr);
1744 encode_putfh(&xdr, args->fh, &hdr); 2096 encode_putfh(&xdr, args->fh, &hdr);
1745 encode_read(&xdr, args, &hdr); 2097 encode_read(&xdr, args, &hdr);
1746 2098
1747 /* set up reply kvec 2099 xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
1748 * toplevel status + taglen=0 + rescount + OP_PUTFH + status
1749 * + OP_READ + status + eof + datalen = 9
1750 */
1751 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
1752 xdr_inline_pages(&req->rq_rcv_buf, replen,
1753 args->pages, args->pgbase, args->count); 2100 args->pages, args->pgbase, args->count);
1754 req->rq_rcv_buf.flags |= XDRBUF_READ; 2101 req->rq_rcv_buf.flags |= XDRBUF_READ;
1755 encode_nops(&hdr); 2102 encode_nops(&hdr);
@@ -1763,11 +2110,12 @@ static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_seta
1763{ 2110{
1764 struct xdr_stream xdr; 2111 struct xdr_stream xdr;
1765 struct compound_hdr hdr = { 2112 struct compound_hdr hdr = {
1766 .nops = 0, 2113 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1767 }; 2114 };
1768 2115
1769 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2116 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1770 encode_compound_hdr(&xdr, &hdr); 2117 encode_compound_hdr(&xdr, req, &hdr);
2118 encode_sequence(&xdr, &args->seq_args, &hdr);
1771 encode_putfh(&xdr, args->fh, &hdr); 2119 encode_putfh(&xdr, args->fh, &hdr);
1772 encode_setattr(&xdr, args, args->server, &hdr); 2120 encode_setattr(&xdr, args, args->server, &hdr);
1773 encode_getfattr(&xdr, args->bitmask, &hdr); 2121 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1783,20 +2131,19 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
1783 struct nfs_getaclargs *args) 2131 struct nfs_getaclargs *args)
1784{ 2132{
1785 struct xdr_stream xdr; 2133 struct xdr_stream xdr;
1786 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1787 struct compound_hdr hdr = { 2134 struct compound_hdr hdr = {
1788 .nops = 0, 2135 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1789 }; 2136 };
1790 int replen; 2137 uint32_t replen;
1791 2138
1792 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2139 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1793 encode_compound_hdr(&xdr, &hdr); 2140 encode_compound_hdr(&xdr, req, &hdr);
2141 encode_sequence(&xdr, &args->seq_args, &hdr);
1794 encode_putfh(&xdr, args->fh, &hdr); 2142 encode_putfh(&xdr, args->fh, &hdr);
2143 replen = hdr.replen + nfs4_fattr_bitmap_maxsz + 1;
1795 encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr); 2144 encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
1796 2145
1797 /* set up reply buffer: */ 2146 xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
1798 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
1799 xdr_inline_pages(&req->rq_rcv_buf, replen,
1800 args->acl_pages, args->acl_pgbase, args->acl_len); 2147 args->acl_pages, args->acl_pgbase, args->acl_len);
1801 encode_nops(&hdr); 2148 encode_nops(&hdr);
1802 return 0; 2149 return 0;
@@ -1809,11 +2156,12 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
1809{ 2156{
1810 struct xdr_stream xdr; 2157 struct xdr_stream xdr;
1811 struct compound_hdr hdr = { 2158 struct compound_hdr hdr = {
1812 .nops = 0, 2159 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1813 }; 2160 };
1814 2161
1815 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2162 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1816 encode_compound_hdr(&xdr, &hdr); 2163 encode_compound_hdr(&xdr, req, &hdr);
2164 encode_sequence(&xdr, &args->seq_args, &hdr);
1817 encode_putfh(&xdr, args->fh, &hdr); 2165 encode_putfh(&xdr, args->fh, &hdr);
1818 encode_write(&xdr, args, &hdr); 2166 encode_write(&xdr, args, &hdr);
1819 req->rq_snd_buf.flags |= XDRBUF_WRITE; 2167 req->rq_snd_buf.flags |= XDRBUF_WRITE;
@@ -1829,11 +2177,12 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
1829{ 2177{
1830 struct xdr_stream xdr; 2178 struct xdr_stream xdr;
1831 struct compound_hdr hdr = { 2179 struct compound_hdr hdr = {
1832 .nops = 0, 2180 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1833 }; 2181 };
1834 2182
1835 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2183 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1836 encode_compound_hdr(&xdr, &hdr); 2184 encode_compound_hdr(&xdr, req, &hdr);
2185 encode_sequence(&xdr, &args->seq_args, &hdr);
1837 encode_putfh(&xdr, args->fh, &hdr); 2186 encode_putfh(&xdr, args->fh, &hdr);
1838 encode_commit(&xdr, args, &hdr); 2187 encode_commit(&xdr, args, &hdr);
1839 encode_getfattr(&xdr, args->bitmask, &hdr); 2188 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1848,11 +2197,12 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
1848{ 2197{
1849 struct xdr_stream xdr; 2198 struct xdr_stream xdr;
1850 struct compound_hdr hdr = { 2199 struct compound_hdr hdr = {
1851 .nops = 0, 2200 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1852 }; 2201 };
1853 2202
1854 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2203 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1855 encode_compound_hdr(&xdr, &hdr); 2204 encode_compound_hdr(&xdr, req, &hdr);
2205 encode_sequence(&xdr, &args->seq_args, &hdr);
1856 encode_putfh(&xdr, args->fh, &hdr); 2206 encode_putfh(&xdr, args->fh, &hdr);
1857 encode_fsinfo(&xdr, args->bitmask, &hdr); 2207 encode_fsinfo(&xdr, args->bitmask, &hdr);
1858 encode_nops(&hdr); 2208 encode_nops(&hdr);
@@ -1866,11 +2216,12 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
1866{ 2216{
1867 struct xdr_stream xdr; 2217 struct xdr_stream xdr;
1868 struct compound_hdr hdr = { 2218 struct compound_hdr hdr = {
1869 .nops = 0, 2219 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1870 }; 2220 };
1871 2221
1872 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2222 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1873 encode_compound_hdr(&xdr, &hdr); 2223 encode_compound_hdr(&xdr, req, &hdr);
2224 encode_sequence(&xdr, &args->seq_args, &hdr);
1874 encode_putfh(&xdr, args->fh, &hdr); 2225 encode_putfh(&xdr, args->fh, &hdr);
1875 encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0], 2226 encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
1876 &hdr); 2227 &hdr);
@@ -1885,11 +2236,12 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
1885{ 2236{
1886 struct xdr_stream xdr; 2237 struct xdr_stream xdr;
1887 struct compound_hdr hdr = { 2238 struct compound_hdr hdr = {
1888 .nops = 0, 2239 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1889 }; 2240 };
1890 2241
1891 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2242 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1892 encode_compound_hdr(&xdr, &hdr); 2243 encode_compound_hdr(&xdr, req, &hdr);
2244 encode_sequence(&xdr, &args->seq_args, &hdr);
1893 encode_putfh(&xdr, args->fh, &hdr); 2245 encode_putfh(&xdr, args->fh, &hdr);
1894 encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0], 2246 encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
1895 args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr); 2247 args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
@@ -1900,16 +2252,18 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
1900/* 2252/*
1901 * GETATTR_BITMAP request 2253 * GETATTR_BITMAP request
1902 */ 2254 */
1903static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle) 2255static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
2256 struct nfs4_server_caps_arg *args)
1904{ 2257{
1905 struct xdr_stream xdr; 2258 struct xdr_stream xdr;
1906 struct compound_hdr hdr = { 2259 struct compound_hdr hdr = {
1907 .nops = 0, 2260 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1908 }; 2261 };
1909 2262
1910 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2263 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1911 encode_compound_hdr(&xdr, &hdr); 2264 encode_compound_hdr(&xdr, req, &hdr);
1912 encode_putfh(&xdr, fhandle, &hdr); 2265 encode_sequence(&xdr, &args->seq_args, &hdr);
2266 encode_putfh(&xdr, args->fhandle, &hdr);
1913 encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| 2267 encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
1914 FATTR4_WORD0_LINK_SUPPORT| 2268 FATTR4_WORD0_LINK_SUPPORT|
1915 FATTR4_WORD0_SYMLINK_SUPPORT| 2269 FATTR4_WORD0_SYMLINK_SUPPORT|
@@ -1929,7 +2283,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client
1929 }; 2283 };
1930 2284
1931 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2285 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1932 encode_compound_hdr(&xdr, &hdr); 2286 encode_compound_hdr(&xdr, req, &hdr);
1933 encode_renew(&xdr, clp, &hdr); 2287 encode_renew(&xdr, clp, &hdr);
1934 encode_nops(&hdr); 2288 encode_nops(&hdr);
1935 return 0; 2289 return 0;
@@ -1946,7 +2300,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
1946 }; 2300 };
1947 2301
1948 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2302 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1949 encode_compound_hdr(&xdr, &hdr); 2303 encode_compound_hdr(&xdr, req, &hdr);
1950 encode_setclientid(&xdr, sc, &hdr); 2304 encode_setclientid(&xdr, sc, &hdr);
1951 encode_nops(&hdr); 2305 encode_nops(&hdr);
1952 return 0; 2306 return 0;
@@ -1964,7 +2318,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
1964 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; 2318 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
1965 2319
1966 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2320 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1967 encode_compound_hdr(&xdr, &hdr); 2321 encode_compound_hdr(&xdr, req, &hdr);
1968 encode_setclientid_confirm(&xdr, clp, &hdr); 2322 encode_setclientid_confirm(&xdr, clp, &hdr);
1969 encode_putrootfh(&xdr, &hdr); 2323 encode_putrootfh(&xdr, &hdr);
1970 encode_fsinfo(&xdr, lease_bitmap, &hdr); 2324 encode_fsinfo(&xdr, lease_bitmap, &hdr);
@@ -1979,11 +2333,12 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
1979{ 2333{
1980 struct xdr_stream xdr; 2334 struct xdr_stream xdr;
1981 struct compound_hdr hdr = { 2335 struct compound_hdr hdr = {
1982 .nops = 0, 2336 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1983 }; 2337 };
1984 2338
1985 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2339 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1986 encode_compound_hdr(&xdr, &hdr); 2340 encode_compound_hdr(&xdr, req, &hdr);
2341 encode_sequence(&xdr, &args->seq_args, &hdr);
1987 encode_putfh(&xdr, args->fhandle, &hdr); 2342 encode_putfh(&xdr, args->fhandle, &hdr);
1988 encode_delegreturn(&xdr, args->stateid, &hdr); 2343 encode_delegreturn(&xdr, args->stateid, &hdr);
1989 encode_getfattr(&xdr, args->bitmask, &hdr); 2344 encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1998,28 +2353,119 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
1998{ 2353{
1999 struct xdr_stream xdr; 2354 struct xdr_stream xdr;
2000 struct compound_hdr hdr = { 2355 struct compound_hdr hdr = {
2001 .nops = 0, 2356 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2002 }; 2357 };
2003 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 2358 uint32_t replen;
2004 int replen;
2005 2359
2006 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2360 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2007 encode_compound_hdr(&xdr, &hdr); 2361 encode_compound_hdr(&xdr, req, &hdr);
2362 encode_sequence(&xdr, &args->seq_args, &hdr);
2008 encode_putfh(&xdr, args->dir_fh, &hdr); 2363 encode_putfh(&xdr, args->dir_fh, &hdr);
2009 encode_lookup(&xdr, args->name, &hdr); 2364 encode_lookup(&xdr, args->name, &hdr);
2365 replen = hdr.replen; /* get the attribute into args->page */
2010 encode_fs_locations(&xdr, args->bitmask, &hdr); 2366 encode_fs_locations(&xdr, args->bitmask, &hdr);
2011 2367
2012 /* set up reply 2368 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
2013 * toplevel_status + OP_PUTFH + status
2014 * + OP_LOOKUP + status + OP_GETATTR + status = 7
2015 */
2016 replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
2017 xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
2018 0, PAGE_SIZE); 2369 0, PAGE_SIZE);
2019 encode_nops(&hdr); 2370 encode_nops(&hdr);
2020 return 0; 2371 return 0;
2021} 2372}
2022 2373
2374#if defined(CONFIG_NFS_V4_1)
2375/*
2376 * EXCHANGE_ID request
2377 */
2378static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p,
2379 struct nfs41_exchange_id_args *args)
2380{
2381 struct xdr_stream xdr;
2382 struct compound_hdr hdr = {
2383 .minorversion = args->client->cl_minorversion,
2384 };
2385
2386 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2387 encode_compound_hdr(&xdr, req, &hdr);
2388 encode_exchange_id(&xdr, args, &hdr);
2389 encode_nops(&hdr);
2390 return 0;
2391}
2392
2393/*
2394 * a CREATE_SESSION request
2395 */
2396static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p,
2397 struct nfs41_create_session_args *args)
2398{
2399 struct xdr_stream xdr;
2400 struct compound_hdr hdr = {
2401 .minorversion = args->client->cl_minorversion,
2402 };
2403
2404 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2405 encode_compound_hdr(&xdr, req, &hdr);
2406 encode_create_session(&xdr, args, &hdr);
2407 encode_nops(&hdr);
2408 return 0;
2409}
2410
2411/*
2412 * a DESTROY_SESSION request
2413 */
2414static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p,
2415 struct nfs4_session *session)
2416{
2417 struct xdr_stream xdr;
2418 struct compound_hdr hdr = {
2419 .minorversion = session->clp->cl_minorversion,
2420 };
2421
2422 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2423 encode_compound_hdr(&xdr, req, &hdr);
2424 encode_destroy_session(&xdr, session, &hdr);
2425 encode_nops(&hdr);
2426 return 0;
2427}
2428
2429/*
2430 * a SEQUENCE request
2431 */
2432static int nfs4_xdr_enc_sequence(struct rpc_rqst *req, uint32_t *p,
2433 struct nfs4_sequence_args *args)
2434{
2435 struct xdr_stream xdr;
2436 struct compound_hdr hdr = {
2437 .minorversion = nfs4_xdr_minorversion(args),
2438 };
2439
2440 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2441 encode_compound_hdr(&xdr, req, &hdr);
2442 encode_sequence(&xdr, args, &hdr);
2443 encode_nops(&hdr);
2444 return 0;
2445}
2446
2447/*
2448 * a GET_LEASE_TIME request
2449 */
2450static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p,
2451 struct nfs4_get_lease_time_args *args)
2452{
2453 struct xdr_stream xdr;
2454 struct compound_hdr hdr = {
2455 .minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
2456 };
2457 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
2458
2459 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2460 encode_compound_hdr(&xdr, req, &hdr);
2461 encode_sequence(&xdr, &args->la_seq_args, &hdr);
2462 encode_putrootfh(&xdr, &hdr);
2463 encode_fsinfo(&xdr, lease_bitmap, &hdr);
2464 encode_nops(&hdr);
2465 return 0;
2466}
2467#endif /* CONFIG_NFS_V4_1 */
2468
2023/* 2469/*
2024 * START OF "GENERIC" DECODE ROUTINES. 2470 * START OF "GENERIC" DECODE ROUTINES.
2025 * These may look a little ugly since they are imported from a "generic" 2471 * These may look a little ugly since they are imported from a "generic"
@@ -3657,7 +4103,7 @@ decode_savefh(struct xdr_stream *xdr)
3657 return decode_op_hdr(xdr, OP_SAVEFH); 4103 return decode_op_hdr(xdr, OP_SAVEFH);
3658} 4104}
3659 4105
3660static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res) 4106static int decode_setattr(struct xdr_stream *xdr)
3661{ 4107{
3662 __be32 *p; 4108 __be32 *p;
3663 uint32_t bmlen; 4109 uint32_t bmlen;
@@ -3735,6 +4181,169 @@ static int decode_delegreturn(struct xdr_stream *xdr)
3735 return decode_op_hdr(xdr, OP_DELEGRETURN); 4181 return decode_op_hdr(xdr, OP_DELEGRETURN);
3736} 4182}
3737 4183
4184#if defined(CONFIG_NFS_V4_1)
4185static int decode_exchange_id(struct xdr_stream *xdr,
4186 struct nfs41_exchange_id_res *res)
4187{
4188 __be32 *p;
4189 uint32_t dummy;
4190 int status;
4191 struct nfs_client *clp = res->client;
4192
4193 status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
4194 if (status)
4195 return status;
4196
4197 READ_BUF(8);
4198 READ64(clp->cl_ex_clid);
4199 READ_BUF(12);
4200 READ32(clp->cl_seqid);
4201 READ32(clp->cl_exchange_flags);
4202
4203 /* We ask for SP4_NONE */
4204 READ32(dummy);
4205 if (dummy != SP4_NONE)
4206 return -EIO;
4207
4208 /* Throw away minor_id */
4209 READ_BUF(8);
4210
4211 /* Throw away Major id */
4212 READ_BUF(4);
4213 READ32(dummy);
4214 READ_BUF(dummy);
4215
4216 /* Throw away server_scope */
4217 READ_BUF(4);
4218 READ32(dummy);
4219 READ_BUF(dummy);
4220
4221 /* Throw away Implementation id array */
4222 READ_BUF(4);
4223 READ32(dummy);
4224 READ_BUF(dummy);
4225
4226 return 0;
4227}
4228
4229static int decode_chan_attrs(struct xdr_stream *xdr,
4230 struct nfs4_channel_attrs *attrs)
4231{
4232 __be32 *p;
4233 u32 nr_attrs;
4234
4235 READ_BUF(28);
4236 READ32(attrs->headerpadsz);
4237 READ32(attrs->max_rqst_sz);
4238 READ32(attrs->max_resp_sz);
4239 READ32(attrs->max_resp_sz_cached);
4240 READ32(attrs->max_ops);
4241 READ32(attrs->max_reqs);
4242 READ32(nr_attrs);
4243 if (unlikely(nr_attrs > 1)) {
4244 printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u\n",
4245 __func__, nr_attrs);
4246 return -EINVAL;
4247 }
4248 if (nr_attrs == 1)
4249 READ_BUF(4); /* skip rdma_attrs */
4250 return 0;
4251}
4252
4253static int decode_create_session(struct xdr_stream *xdr,
4254 struct nfs41_create_session_res *res)
4255{
4256 __be32 *p;
4257 int status;
4258 struct nfs_client *clp = res->client;
4259 struct nfs4_session *session = clp->cl_session;
4260
4261 status = decode_op_hdr(xdr, OP_CREATE_SESSION);
4262
4263 if (status)
4264 return status;
4265
4266 /* sessionid */
4267 READ_BUF(NFS4_MAX_SESSIONID_LEN);
4268 COPYMEM(&session->sess_id, NFS4_MAX_SESSIONID_LEN);
4269
4270 /* seqid, flags */
4271 READ_BUF(8);
4272 READ32(clp->cl_seqid);
4273 READ32(session->flags);
4274
4275 /* Channel attributes */
4276 status = decode_chan_attrs(xdr, &session->fc_attrs);
4277 if (!status)
4278 status = decode_chan_attrs(xdr, &session->bc_attrs);
4279 return status;
4280}
4281
4282static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
4283{
4284 return decode_op_hdr(xdr, OP_DESTROY_SESSION);
4285}
4286#endif /* CONFIG_NFS_V4_1 */
4287
4288static int decode_sequence(struct xdr_stream *xdr,
4289 struct nfs4_sequence_res *res,
4290 struct rpc_rqst *rqstp)
4291{
4292#if defined(CONFIG_NFS_V4_1)
4293 struct nfs4_slot *slot;
4294 struct nfs4_sessionid id;
4295 u32 dummy;
4296 int status;
4297 __be32 *p;
4298
4299 if (!res->sr_session)
4300 return 0;
4301
4302 status = decode_op_hdr(xdr, OP_SEQUENCE);
4303 if (status)
4304 goto out_err;
4305
4306 /*
4307 * If the server returns different values for sessionID, slotID or
4308 * sequence number, the server is looney tunes.
4309 */
4310 status = -ESERVERFAULT;
4311
4312 slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid];
4313 READ_BUF(NFS4_MAX_SESSIONID_LEN + 20);
4314 COPYMEM(id.data, NFS4_MAX_SESSIONID_LEN);
4315 if (memcmp(id.data, res->sr_session->sess_id.data,
4316 NFS4_MAX_SESSIONID_LEN)) {
4317 dprintk("%s Invalid session id\n", __func__);
4318 goto out_err;
4319 }
4320 /* seqid */
4321 READ32(dummy);
4322 if (dummy != slot->seq_nr) {
4323 dprintk("%s Invalid sequence number\n", __func__);
4324 goto out_err;
4325 }
4326 /* slot id */
4327 READ32(dummy);
4328 if (dummy != res->sr_slotid) {
4329 dprintk("%s Invalid slot id\n", __func__);
4330 goto out_err;
4331 }
4332 /* highest slot id - currently not processed */
4333 READ32(dummy);
4334 /* target highest slot id - currently not processed */
4335 READ32(dummy);
4336 /* result flags - currently not processed */
4337 READ32(dummy);
4338 status = 0;
4339out_err:
4340 res->sr_status = status;
4341 return status;
4342#else /* CONFIG_NFS_V4_1 */
4343 return 0;
4344#endif /* CONFIG_NFS_V4_1 */
4345}
4346
3738/* 4347/*
3739 * END OF "GENERIC" DECODE ROUTINES. 4348 * END OF "GENERIC" DECODE ROUTINES.
3740 */ 4349 */
@@ -3752,6 +4361,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct
3752 status = decode_compound_hdr(&xdr, &hdr); 4361 status = decode_compound_hdr(&xdr, &hdr);
3753 if (status) 4362 if (status)
3754 goto out; 4363 goto out;
4364 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4365 if (status)
4366 goto out;
3755 status = decode_putfh(&xdr); 4367 status = decode_putfh(&xdr);
3756 if (status) 4368 if (status)
3757 goto out; 4369 goto out;
@@ -3773,7 +4385,11 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac
3773 int status; 4385 int status;
3774 4386
3775 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4387 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3776 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4388 status = decode_compound_hdr(&xdr, &hdr);
4389 if (status)
4390 goto out;
4391 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4392 if (status)
3777 goto out; 4393 goto out;
3778 status = decode_putfh(&xdr); 4394 status = decode_putfh(&xdr);
3779 if (status != 0) 4395 if (status != 0)
@@ -3796,7 +4412,11 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo
3796 int status; 4412 int status;
3797 4413
3798 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4414 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3799 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4415 status = decode_compound_hdr(&xdr, &hdr);
4416 if (status)
4417 goto out;
4418 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4419 if (status)
3800 goto out; 4420 goto out;
3801 if ((status = decode_putfh(&xdr)) != 0) 4421 if ((status = decode_putfh(&xdr)) != 0)
3802 goto out; 4422 goto out;
@@ -3819,7 +4439,11 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf
3819 int status; 4439 int status;
3820 4440
3821 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4441 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3822 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4442 status = decode_compound_hdr(&xdr, &hdr);
4443 if (status)
4444 goto out;
4445 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4446 if (status)
3823 goto out; 4447 goto out;
3824 if ((status = decode_putrootfh(&xdr)) != 0) 4448 if ((status = decode_putrootfh(&xdr)) != 0)
3825 goto out; 4449 goto out;
@@ -3839,7 +4463,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem
3839 int status; 4463 int status;
3840 4464
3841 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4465 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3842 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4466 status = decode_compound_hdr(&xdr, &hdr);
4467 if (status)
4468 goto out;
4469 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4470 if (status)
3843 goto out; 4471 goto out;
3844 if ((status = decode_putfh(&xdr)) != 0) 4472 if ((status = decode_putfh(&xdr)) != 0)
3845 goto out; 4473 goto out;
@@ -3860,7 +4488,11 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re
3860 int status; 4488 int status;
3861 4489
3862 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4490 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3863 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4491 status = decode_compound_hdr(&xdr, &hdr);
4492 if (status)
4493 goto out;
4494 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4495 if (status)
3864 goto out; 4496 goto out;
3865 if ((status = decode_putfh(&xdr)) != 0) 4497 if ((status = decode_putfh(&xdr)) != 0)
3866 goto out; 4498 goto out;
@@ -3890,7 +4522,11 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link
3890 int status; 4522 int status;
3891 4523
3892 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4524 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3893 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4525 status = decode_compound_hdr(&xdr, &hdr);
4526 if (status)
4527 goto out;
4528 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4529 if (status)
3894 goto out; 4530 goto out;
3895 if ((status = decode_putfh(&xdr)) != 0) 4531 if ((status = decode_putfh(&xdr)) != 0)
3896 goto out; 4532 goto out;
@@ -3923,7 +4559,11 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr
3923 int status; 4559 int status;
3924 4560
3925 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4561 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3926 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 4562 status = decode_compound_hdr(&xdr, &hdr);
4563 if (status)
4564 goto out;
4565 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4566 if (status)
3927 goto out; 4567 goto out;
3928 if ((status = decode_putfh(&xdr)) != 0) 4568 if ((status = decode_putfh(&xdr)) != 0)
3929 goto out; 4569 goto out;
@@ -3963,6 +4603,9 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g
3963 status = decode_compound_hdr(&xdr, &hdr); 4603 status = decode_compound_hdr(&xdr, &hdr);
3964 if (status) 4604 if (status)
3965 goto out; 4605 goto out;
4606 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4607 if (status)
4608 goto out;
3966 status = decode_putfh(&xdr); 4609 status = decode_putfh(&xdr);
3967 if (status) 4610 if (status)
3968 goto out; 4611 goto out;
@@ -3979,12 +4622,13 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
3979{ 4622{
3980 struct xdr_stream xdr; 4623 struct xdr_stream xdr;
3981 struct compound_hdr hdr = { 4624 struct compound_hdr hdr = {
3982 .nops = 0, 4625 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
3983 }; 4626 };
3984 int status; 4627 int status;
3985 4628
3986 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 4629 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
3987 encode_compound_hdr(&xdr, &hdr); 4630 encode_compound_hdr(&xdr, req, &hdr);
4631 encode_sequence(&xdr, &args->seq_args, &hdr);
3988 encode_putfh(&xdr, args->fh, &hdr); 4632 encode_putfh(&xdr, args->fh, &hdr);
3989 status = encode_setacl(&xdr, args, &hdr); 4633 status = encode_setacl(&xdr, args, &hdr);
3990 encode_nops(&hdr); 4634 encode_nops(&hdr);
@@ -3995,7 +4639,8 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
3995 * Decode SETACL response 4639 * Decode SETACL response
3996 */ 4640 */
3997static int 4641static int
3998nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res) 4642nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
4643 struct nfs_setaclres *res)
3999{ 4644{
4000 struct xdr_stream xdr; 4645 struct xdr_stream xdr;
4001 struct compound_hdr hdr; 4646 struct compound_hdr hdr;
@@ -4005,10 +4650,13 @@ nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
4005 status = decode_compound_hdr(&xdr, &hdr); 4650 status = decode_compound_hdr(&xdr, &hdr);
4006 if (status) 4651 if (status)
4007 goto out; 4652 goto out;
4653 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4654 if (status)
4655 goto out;
4008 status = decode_putfh(&xdr); 4656 status = decode_putfh(&xdr);
4009 if (status) 4657 if (status)
4010 goto out; 4658 goto out;
4011 status = decode_setattr(&xdr, res); 4659 status = decode_setattr(&xdr);
4012out: 4660out:
4013 return status; 4661 return status;
4014} 4662}
@@ -4017,7 +4665,8 @@ out:
4017 * Decode GETACL response 4665 * Decode GETACL response
4018 */ 4666 */
4019static int 4667static int
4020nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len) 4668nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
4669 struct nfs_getaclres *res)
4021{ 4670{
4022 struct xdr_stream xdr; 4671 struct xdr_stream xdr;
4023 struct compound_hdr hdr; 4672 struct compound_hdr hdr;
@@ -4027,10 +4676,13 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
4027 status = decode_compound_hdr(&xdr, &hdr); 4676 status = decode_compound_hdr(&xdr, &hdr);
4028 if (status) 4677 if (status)
4029 goto out; 4678 goto out;
4679 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4680 if (status)
4681 goto out;
4030 status = decode_putfh(&xdr); 4682 status = decode_putfh(&xdr);
4031 if (status) 4683 if (status)
4032 goto out; 4684 goto out;
4033 status = decode_getacl(&xdr, rqstp, acl_len); 4685 status = decode_getacl(&xdr, rqstp, &res->acl_len);
4034 4686
4035out: 4687out:
4036 return status; 4688 return status;
@@ -4049,6 +4701,9 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
4049 status = decode_compound_hdr(&xdr, &hdr); 4701 status = decode_compound_hdr(&xdr, &hdr);
4050 if (status) 4702 if (status)
4051 goto out; 4703 goto out;
4704 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4705 if (status)
4706 goto out;
4052 status = decode_putfh(&xdr); 4707 status = decode_putfh(&xdr);
4053 if (status) 4708 if (status)
4054 goto out; 4709 goto out;
@@ -4079,6 +4734,9 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr
4079 status = decode_compound_hdr(&xdr, &hdr); 4734 status = decode_compound_hdr(&xdr, &hdr);
4080 if (status) 4735 if (status)
4081 goto out; 4736 goto out;
4737 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4738 if (status)
4739 goto out;
4082 status = decode_putfh(&xdr); 4740 status = decode_putfh(&xdr);
4083 if (status) 4741 if (status)
4084 goto out; 4742 goto out;
@@ -4133,6 +4791,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf
4133 status = decode_compound_hdr(&xdr, &hdr); 4791 status = decode_compound_hdr(&xdr, &hdr);
4134 if (status) 4792 if (status)
4135 goto out; 4793 goto out;
4794 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4795 if (status)
4796 goto out;
4136 status = decode_putfh(&xdr); 4797 status = decode_putfh(&xdr);
4137 if (status) 4798 if (status)
4138 goto out; 4799 goto out;
@@ -4157,10 +4818,13 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se
4157 status = decode_compound_hdr(&xdr, &hdr); 4818 status = decode_compound_hdr(&xdr, &hdr);
4158 if (status) 4819 if (status)
4159 goto out; 4820 goto out;
4821 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4822 if (status)
4823 goto out;
4160 status = decode_putfh(&xdr); 4824 status = decode_putfh(&xdr);
4161 if (status) 4825 if (status)
4162 goto out; 4826 goto out;
4163 status = decode_setattr(&xdr, res); 4827 status = decode_setattr(&xdr);
4164 if (status) 4828 if (status)
4165 goto out; 4829 goto out;
4166 decode_getfattr(&xdr, res->fattr, res->server); 4830 decode_getfattr(&xdr, res->fattr, res->server);
@@ -4181,6 +4845,9 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_
4181 status = decode_compound_hdr(&xdr, &hdr); 4845 status = decode_compound_hdr(&xdr, &hdr);
4182 if (status) 4846 if (status)
4183 goto out; 4847 goto out;
4848 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4849 if (status)
4850 goto out;
4184 status = decode_putfh(&xdr); 4851 status = decode_putfh(&xdr);
4185 if (status) 4852 if (status)
4186 goto out; 4853 goto out;
@@ -4202,6 +4869,9 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
4202 status = decode_compound_hdr(&xdr, &hdr); 4869 status = decode_compound_hdr(&xdr, &hdr);
4203 if (status) 4870 if (status)
4204 goto out; 4871 goto out;
4872 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4873 if (status)
4874 goto out;
4205 status = decode_putfh(&xdr); 4875 status = decode_putfh(&xdr);
4206 if (status) 4876 if (status)
4207 goto out; 4877 goto out;
@@ -4223,6 +4893,9 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
4223 status = decode_compound_hdr(&xdr, &hdr); 4893 status = decode_compound_hdr(&xdr, &hdr);
4224 if (status) 4894 if (status)
4225 goto out; 4895 goto out;
4896 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4897 if (status)
4898 goto out;
4226 status = decode_putfh(&xdr); 4899 status = decode_putfh(&xdr);
4227 if (status) 4900 if (status)
4228 goto out; 4901 goto out;
@@ -4234,7 +4907,8 @@ out:
4234/* 4907/*
4235 * Decode READLINK response 4908 * Decode READLINK response
4236 */ 4909 */
4237static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res) 4910static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p,
4911 struct nfs4_readlink_res *res)
4238{ 4912{
4239 struct xdr_stream xdr; 4913 struct xdr_stream xdr;
4240 struct compound_hdr hdr; 4914 struct compound_hdr hdr;
@@ -4244,6 +4918,9 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
4244 status = decode_compound_hdr(&xdr, &hdr); 4918 status = decode_compound_hdr(&xdr, &hdr);
4245 if (status) 4919 if (status)
4246 goto out; 4920 goto out;
4921 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4922 if (status)
4923 goto out;
4247 status = decode_putfh(&xdr); 4924 status = decode_putfh(&xdr);
4248 if (status) 4925 if (status)
4249 goto out; 4926 goto out;
@@ -4265,6 +4942,9 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r
4265 status = decode_compound_hdr(&xdr, &hdr); 4942 status = decode_compound_hdr(&xdr, &hdr);
4266 if (status) 4943 if (status)
4267 goto out; 4944 goto out;
4945 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4946 if (status)
4947 goto out;
4268 status = decode_putfh(&xdr); 4948 status = decode_putfh(&xdr);
4269 if (status) 4949 if (status)
4270 goto out; 4950 goto out;
@@ -4286,6 +4966,9 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr
4286 status = decode_compound_hdr(&xdr, &hdr); 4966 status = decode_compound_hdr(&xdr, &hdr);
4287 if (status) 4967 if (status)
4288 goto out; 4968 goto out;
4969 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4970 if (status)
4971 goto out;
4289 status = decode_putfh(&xdr); 4972 status = decode_putfh(&xdr);
4290 if (status) 4973 if (status)
4291 goto out; 4974 goto out;
@@ -4309,6 +4992,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ
4309 status = decode_compound_hdr(&xdr, &hdr); 4992 status = decode_compound_hdr(&xdr, &hdr);
4310 if (status) 4993 if (status)
4311 goto out; 4994 goto out;
4995 status = decode_sequence(&xdr, &res->seq_res, rqstp);
4996 if (status)
4997 goto out;
4312 status = decode_putfh(&xdr); 4998 status = decode_putfh(&xdr);
4313 if (status) 4999 if (status)
4314 goto out; 5000 goto out;
@@ -4335,6 +5021,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri
4335 status = decode_compound_hdr(&xdr, &hdr); 5021 status = decode_compound_hdr(&xdr, &hdr);
4336 if (status) 5022 if (status)
4337 goto out; 5023 goto out;
5024 status = decode_sequence(&xdr, &res->seq_res, rqstp);
5025 if (status)
5026 goto out;
4338 status = decode_putfh(&xdr); 5027 status = decode_putfh(&xdr);
4339 if (status) 5028 if (status)
4340 goto out; 5029 goto out;
@@ -4349,7 +5038,8 @@ out:
4349/* 5038/*
4350 * FSINFO request 5039 * FSINFO request
4351 */ 5040 */
4352static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo) 5041static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
5042 struct nfs4_fsinfo_res *res)
4353{ 5043{
4354 struct xdr_stream xdr; 5044 struct xdr_stream xdr;
4355 struct compound_hdr hdr; 5045 struct compound_hdr hdr;
@@ -4358,16 +5048,19 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf
4358 xdr_init_decode(&xdr, &req->rq_rcv_buf, p); 5048 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4359 status = decode_compound_hdr(&xdr, &hdr); 5049 status = decode_compound_hdr(&xdr, &hdr);
4360 if (!status) 5050 if (!status)
5051 status = decode_sequence(&xdr, &res->seq_res, req);
5052 if (!status)
4361 status = decode_putfh(&xdr); 5053 status = decode_putfh(&xdr);
4362 if (!status) 5054 if (!status)
4363 status = decode_fsinfo(&xdr, fsinfo); 5055 status = decode_fsinfo(&xdr, res->fsinfo);
4364 return status; 5056 return status;
4365} 5057}
4366 5058
4367/* 5059/*
4368 * PATHCONF request 5060 * PATHCONF request
4369 */ 5061 */
4370static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf) 5062static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
5063 struct nfs4_pathconf_res *res)
4371{ 5064{
4372 struct xdr_stream xdr; 5065 struct xdr_stream xdr;
4373 struct compound_hdr hdr; 5066 struct compound_hdr hdr;
@@ -4376,16 +5069,19 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pat
4376 xdr_init_decode(&xdr, &req->rq_rcv_buf, p); 5069 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4377 status = decode_compound_hdr(&xdr, &hdr); 5070 status = decode_compound_hdr(&xdr, &hdr);
4378 if (!status) 5071 if (!status)
5072 status = decode_sequence(&xdr, &res->seq_res, req);
5073 if (!status)
4379 status = decode_putfh(&xdr); 5074 status = decode_putfh(&xdr);
4380 if (!status) 5075 if (!status)
4381 status = decode_pathconf(&xdr, pathconf); 5076 status = decode_pathconf(&xdr, res->pathconf);
4382 return status; 5077 return status;
4383} 5078}
4384 5079
4385/* 5080/*
4386 * STATFS request 5081 * STATFS request
4387 */ 5082 */
4388static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat) 5083static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
5084 struct nfs4_statfs_res *res)
4389{ 5085{
4390 struct xdr_stream xdr; 5086 struct xdr_stream xdr;
4391 struct compound_hdr hdr; 5087 struct compound_hdr hdr;
@@ -4394,9 +5090,11 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fssta
4394 xdr_init_decode(&xdr, &req->rq_rcv_buf, p); 5090 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4395 status = decode_compound_hdr(&xdr, &hdr); 5091 status = decode_compound_hdr(&xdr, &hdr);
4396 if (!status) 5092 if (!status)
5093 status = decode_sequence(&xdr, &res->seq_res, req);
5094 if (!status)
4397 status = decode_putfh(&xdr); 5095 status = decode_putfh(&xdr);
4398 if (!status) 5096 if (!status)
4399 status = decode_statfs(&xdr, fsstat); 5097 status = decode_statfs(&xdr, res->fsstat);
4400 return status; 5098 return status;
4401} 5099}
4402 5100
@@ -4410,7 +5108,11 @@ static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4
4410 int status; 5108 int status;
4411 5109
4412 xdr_init_decode(&xdr, &req->rq_rcv_buf, p); 5110 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4413 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 5111 status = decode_compound_hdr(&xdr, &hdr);
5112 if (status)
5113 goto out;
5114 status = decode_sequence(&xdr, &res->seq_res, req);
5115 if (status)
4414 goto out; 5116 goto out;
4415 if ((status = decode_putfh(&xdr)) != 0) 5117 if ((status = decode_putfh(&xdr)) != 0)
4416 goto out; 5118 goto out;
@@ -4483,7 +5185,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf
4483 5185
4484 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 5186 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4485 status = decode_compound_hdr(&xdr, &hdr); 5187 status = decode_compound_hdr(&xdr, &hdr);
4486 if (status != 0) 5188 if (status)
5189 goto out;
5190 status = decode_sequence(&xdr, &res->seq_res, rqstp);
5191 if (status)
4487 goto out; 5192 goto out;
4488 status = decode_putfh(&xdr); 5193 status = decode_putfh(&xdr);
4489 if (status != 0) 5194 if (status != 0)
@@ -4497,7 +5202,8 @@ out:
4497/* 5202/*
4498 * FS_LOCATIONS request 5203 * FS_LOCATIONS request
4499 */ 5204 */
4500static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res) 5205static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
5206 struct nfs4_fs_locations_res *res)
4501{ 5207{
4502 struct xdr_stream xdr; 5208 struct xdr_stream xdr;
4503 struct compound_hdr hdr; 5209 struct compound_hdr hdr;
@@ -4505,18 +5211,113 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
4505 5211
4506 xdr_init_decode(&xdr, &req->rq_rcv_buf, p); 5212 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4507 status = decode_compound_hdr(&xdr, &hdr); 5213 status = decode_compound_hdr(&xdr, &hdr);
4508 if (status != 0) 5214 if (status)
5215 goto out;
5216 status = decode_sequence(&xdr, &res->seq_res, req);
5217 if (status)
4509 goto out; 5218 goto out;
4510 if ((status = decode_putfh(&xdr)) != 0) 5219 if ((status = decode_putfh(&xdr)) != 0)
4511 goto out; 5220 goto out;
4512 if ((status = decode_lookup(&xdr)) != 0) 5221 if ((status = decode_lookup(&xdr)) != 0)
4513 goto out; 5222 goto out;
4514 xdr_enter_page(&xdr, PAGE_SIZE); 5223 xdr_enter_page(&xdr, PAGE_SIZE);
4515 status = decode_getfattr(&xdr, &res->fattr, res->server); 5224 status = decode_getfattr(&xdr, &res->fs_locations->fattr,
5225 res->fs_locations->server);
4516out: 5226out:
4517 return status; 5227 return status;
4518} 5228}
4519 5229
5230#if defined(CONFIG_NFS_V4_1)
5231/*
5232 * EXCHANGE_ID request
5233 */
5234static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p,
5235 void *res)
5236{
5237 struct xdr_stream xdr;
5238 struct compound_hdr hdr;
5239 int status;
5240
5241 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5242 status = decode_compound_hdr(&xdr, &hdr);
5243 if (!status)
5244 status = decode_exchange_id(&xdr, res);
5245 return status;
5246}
5247
5248/*
5249 * a CREATE_SESSION request
5250 */
5251static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p,
5252 struct nfs41_create_session_res *res)
5253{
5254 struct xdr_stream xdr;
5255 struct compound_hdr hdr;
5256 int status;
5257
5258 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5259 status = decode_compound_hdr(&xdr, &hdr);
5260 if (!status)
5261 status = decode_create_session(&xdr, res);
5262 return status;
5263}
5264
5265/*
5266 * a DESTROY_SESSION request
5267 */
5268static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p,
5269 void *dummy)
5270{
5271 struct xdr_stream xdr;
5272 struct compound_hdr hdr;
5273 int status;
5274
5275 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5276 status = decode_compound_hdr(&xdr, &hdr);
5277 if (!status)
5278 status = decode_destroy_session(&xdr, dummy);
5279 return status;
5280}
5281
5282/*
5283 * a SEQUENCE request
5284 */
5285static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p,
5286 struct nfs4_sequence_res *res)
5287{
5288 struct xdr_stream xdr;
5289 struct compound_hdr hdr;
5290 int status;
5291
5292 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5293 status = decode_compound_hdr(&xdr, &hdr);
5294 if (!status)
5295 status = decode_sequence(&xdr, res, rqstp);
5296 return status;
5297}
5298
5299/*
5300 * a GET_LEASE_TIME request
5301 */
5302static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p,
5303 struct nfs4_get_lease_time_res *res)
5304{
5305 struct xdr_stream xdr;
5306 struct compound_hdr hdr;
5307 int status;
5308
5309 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
5310 status = decode_compound_hdr(&xdr, &hdr);
5311 if (!status)
5312 status = decode_sequence(&xdr, &res->lr_seq_res, rqstp);
5313 if (!status)
5314 status = decode_putrootfh(&xdr);
5315 if (!status)
5316 status = decode_fsinfo(&xdr, res->lr_fsinfo);
5317 return status;
5318}
5319#endif /* CONFIG_NFS_V4_1 */
5320
4520__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) 5321__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
4521{ 5322{
4522 uint32_t bitmap[2] = {0}; 5323 uint32_t bitmap[2] = {0};
@@ -4686,6 +5487,13 @@ struct rpc_procinfo nfs4_procedures[] = {
4686 PROC(GETACL, enc_getacl, dec_getacl), 5487 PROC(GETACL, enc_getacl, dec_getacl),
4687 PROC(SETACL, enc_setacl, dec_setacl), 5488 PROC(SETACL, enc_setacl, dec_setacl),
4688 PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), 5489 PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
5490#if defined(CONFIG_NFS_V4_1)
5491 PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
5492 PROC(CREATE_SESSION, enc_create_session, dec_create_session),
5493 PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
5494 PROC(SEQUENCE, enc_sequence, dec_sequence),
5495 PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
5496#endif /* CONFIG_NFS_V4_1 */
4689}; 5497};
4690 5498
4691struct rpc_version nfs_version4 = { 5499struct rpc_version nfs_version4 = {
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index e3ed5908820b..8c55b27c0de4 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -92,6 +92,9 @@
92#undef NFSROOT_DEBUG 92#undef NFSROOT_DEBUG
93#define NFSDBG_FACILITY NFSDBG_ROOT 93#define NFSDBG_FACILITY NFSDBG_ROOT
94 94
95/* Default port to use if server is not running a portmapper */
96#define NFS_MNT_PORT 627
97
95/* Default path we try to mount. "%s" gets replaced by our IP address */ 98/* Default path we try to mount. "%s" gets replaced by our IP address */
96#define NFS_ROOT "/tftpboot/%s" 99#define NFS_ROOT "/tftpboot/%s"
97 100
@@ -487,6 +490,7 @@ static int __init root_nfs_get_handle(void)
487{ 490{
488 struct nfs_fh fh; 491 struct nfs_fh fh;
489 struct sockaddr_in sin; 492 struct sockaddr_in sin;
493 unsigned int auth_flav_len = 0;
490 struct nfs_mount_request request = { 494 struct nfs_mount_request request = {
491 .sap = (struct sockaddr *)&sin, 495 .sap = (struct sockaddr *)&sin,
492 .salen = sizeof(sin), 496 .salen = sizeof(sin),
@@ -496,6 +500,7 @@ static int __init root_nfs_get_handle(void)
496 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ? 500 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
497 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP, 501 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
498 .fh = &fh, 502 .fh = &fh,
503 .auth_flav_len = &auth_flav_len,
499 }; 504 };
500 int status; 505 int status;
501 506
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 4ace3c50a8eb..96c4ebfa46f4 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -22,6 +22,7 @@
22 22
23#include <asm/system.h> 23#include <asm/system.h>
24 24
25#include "nfs4_fs.h"
25#include "internal.h" 26#include "internal.h"
26#include "iostat.h" 27#include "iostat.h"
27#include "fscache.h" 28#include "fscache.h"
@@ -46,6 +47,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
46 memset(p, 0, sizeof(*p)); 47 memset(p, 0, sizeof(*p));
47 INIT_LIST_HEAD(&p->pages); 48 INIT_LIST_HEAD(&p->pages);
48 p->npages = pagecount; 49 p->npages = pagecount;
50 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
49 if (pagecount <= ARRAY_SIZE(p->page_array)) 51 if (pagecount <= ARRAY_SIZE(p->page_array))
50 p->pagevec = p->page_array; 52 p->pagevec = p->page_array;
51 else { 53 else {
@@ -357,19 +359,25 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
357 struct nfs_readres *resp = &data->res; 359 struct nfs_readres *resp = &data->res;
358 360
359 if (resp->eof || resp->count == argp->count) 361 if (resp->eof || resp->count == argp->count)
360 return; 362 goto out;
361 363
362 /* This is a short read! */ 364 /* This is a short read! */
363 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); 365 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
364 /* Has the server at least made some progress? */ 366 /* Has the server at least made some progress? */
365 if (resp->count == 0) 367 if (resp->count == 0)
366 return; 368 goto out;
367 369
368 /* Yes, so retry the read at the end of the data */ 370 /* Yes, so retry the read at the end of the data */
369 argp->offset += resp->count; 371 argp->offset += resp->count;
370 argp->pgbase += resp->count; 372 argp->pgbase += resp->count;
371 argp->count -= resp->count; 373 argp->count -= resp->count;
372 rpc_restart_call(task); 374 nfs4_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client);
375 return;
376out:
377 nfs4_sequence_free_slot(NFS_SERVER(data->inode)->nfs_client,
378 &data->res.seq_res);
379 return;
380
373} 381}
374 382
375/* 383/*
@@ -406,7 +414,23 @@ static void nfs_readpage_release_partial(void *calldata)
406 nfs_readdata_release(calldata); 414 nfs_readdata_release(calldata);
407} 415}
408 416
417#if defined(CONFIG_NFS_V4_1)
418void nfs_read_prepare(struct rpc_task *task, void *calldata)
419{
420 struct nfs_read_data *data = calldata;
421
422 if (nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
423 &data->args.seq_args, &data->res.seq_res,
424 0, task))
425 return;
426 rpc_call_start(task);
427}
428#endif /* CONFIG_NFS_V4_1 */
429
409static const struct rpc_call_ops nfs_read_partial_ops = { 430static const struct rpc_call_ops nfs_read_partial_ops = {
431#if defined(CONFIG_NFS_V4_1)
432 .rpc_call_prepare = nfs_read_prepare,
433#endif /* CONFIG_NFS_V4_1 */
410 .rpc_call_done = nfs_readpage_result_partial, 434 .rpc_call_done = nfs_readpage_result_partial,
411 .rpc_release = nfs_readpage_release_partial, 435 .rpc_release = nfs_readpage_release_partial,
412}; 436};
@@ -470,6 +494,9 @@ static void nfs_readpage_release_full(void *calldata)
470} 494}
471 495
472static const struct rpc_call_ops nfs_read_full_ops = { 496static const struct rpc_call_ops nfs_read_full_ops = {
497#if defined(CONFIG_NFS_V4_1)
498 .rpc_call_prepare = nfs_read_prepare,
499#endif /* CONFIG_NFS_V4_1 */
473 .rpc_call_done = nfs_readpage_result_full, 500 .rpc_call_done = nfs_readpage_result_full,
474 .rpc_release = nfs_readpage_release_full, 501 .rpc_release = nfs_readpage_release_full,
475}; 502};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 26127b69a275..3d460527daab 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -90,6 +90,7 @@ enum {
90 Opt_mountport, 90 Opt_mountport,
91 Opt_mountvers, 91 Opt_mountvers,
92 Opt_nfsvers, 92 Opt_nfsvers,
93 Opt_minorversion,
93 94
94 /* Mount options that take string arguments */ 95 /* Mount options that take string arguments */
95 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, 96 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
@@ -139,22 +140,23 @@ static const match_table_t nfs_mount_option_tokens = {
139 { Opt_fscache_uniq, "fsc=%s" }, 140 { Opt_fscache_uniq, "fsc=%s" },
140 { Opt_nofscache, "nofsc" }, 141 { Opt_nofscache, "nofsc" },
141 142
142 { Opt_port, "port=%u" }, 143 { Opt_port, "port=%s" },
143 { Opt_rsize, "rsize=%u" }, 144 { Opt_rsize, "rsize=%s" },
144 { Opt_wsize, "wsize=%u" }, 145 { Opt_wsize, "wsize=%s" },
145 { Opt_bsize, "bsize=%u" }, 146 { Opt_bsize, "bsize=%s" },
146 { Opt_timeo, "timeo=%u" }, 147 { Opt_timeo, "timeo=%s" },
147 { Opt_retrans, "retrans=%u" }, 148 { Opt_retrans, "retrans=%s" },
148 { Opt_acregmin, "acregmin=%u" }, 149 { Opt_acregmin, "acregmin=%s" },
149 { Opt_acregmax, "acregmax=%u" }, 150 { Opt_acregmax, "acregmax=%s" },
150 { Opt_acdirmin, "acdirmin=%u" }, 151 { Opt_acdirmin, "acdirmin=%s" },
151 { Opt_acdirmax, "acdirmax=%u" }, 152 { Opt_acdirmax, "acdirmax=%s" },
152 { Opt_actimeo, "actimeo=%u" }, 153 { Opt_actimeo, "actimeo=%s" },
153 { Opt_namelen, "namlen=%u" }, 154 { Opt_namelen, "namlen=%s" },
154 { Opt_mountport, "mountport=%u" }, 155 { Opt_mountport, "mountport=%s" },
155 { Opt_mountvers, "mountvers=%u" }, 156 { Opt_mountvers, "mountvers=%s" },
156 { Opt_nfsvers, "nfsvers=%u" }, 157 { Opt_nfsvers, "nfsvers=%s" },
157 { Opt_nfsvers, "vers=%u" }, 158 { Opt_nfsvers, "vers=%s" },
159 { Opt_minorversion, "minorversion=%u" },
158 160
159 { Opt_sec, "sec=%s" }, 161 { Opt_sec, "sec=%s" },
160 { Opt_proto, "proto=%s" }, 162 { Opt_proto, "proto=%s" },
@@ -514,7 +516,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
514 const char *nostr; 516 const char *nostr;
515 } nfs_info[] = { 517 } nfs_info[] = {
516 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 518 { NFS_MOUNT_SOFT, ",soft", ",hard" },
517 { NFS_MOUNT_INTR, ",intr", ",nointr" },
518 { NFS_MOUNT_POSIX, ",posix", "" }, 519 { NFS_MOUNT_POSIX, ",posix", "" },
519 { NFS_MOUNT_NOCTO, ",nocto", "" }, 520 { NFS_MOUNT_NOCTO, ",nocto", "" },
520 { NFS_MOUNT_NOAC, ",noac", "" }, 521 { NFS_MOUNT_NOAC, ",noac", "" },
@@ -943,11 +944,6 @@ static int nfs_parse_security_flavors(char *value,
943 return 1; 944 return 1;
944} 945}
945 946
946static void nfs_parse_invalid_value(const char *option)
947{
948 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
949}
950
951/* 947/*
952 * Error-check and convert a string of mount options from user space into 948 * Error-check and convert a string of mount options from user space into
953 * a data structure. The whole mount string is processed; bad options are 949 * a data structure. The whole mount string is processed; bad options are
@@ -958,7 +954,7 @@ static int nfs_parse_mount_options(char *raw,
958 struct nfs_parsed_mount_data *mnt) 954 struct nfs_parsed_mount_data *mnt)
959{ 955{
960 char *p, *string, *secdata; 956 char *p, *string, *secdata;
961 int rc, sloppy = 0, errors = 0; 957 int rc, sloppy = 0, invalid_option = 0;
962 958
963 if (!raw) { 959 if (!raw) {
964 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 960 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -982,7 +978,9 @@ static int nfs_parse_mount_options(char *raw,
982 978
983 while ((p = strsep(&raw, ",")) != NULL) { 979 while ((p = strsep(&raw, ",")) != NULL) {
984 substring_t args[MAX_OPT_ARGS]; 980 substring_t args[MAX_OPT_ARGS];
985 int option, token; 981 unsigned long option;
982 int int_option;
983 int token;
986 984
987 if (!*p) 985 if (!*p)
988 continue; 986 continue;
@@ -1091,114 +1089,156 @@ static int nfs_parse_mount_options(char *raw,
1091 * options that take numeric values 1089 * options that take numeric values
1092 */ 1090 */
1093 case Opt_port: 1091 case Opt_port:
1094 if (match_int(args, &option) || 1092 string = match_strdup(args);
1095 option < 0 || option > USHORT_MAX) { 1093 if (string == NULL)
1096 errors++; 1094 goto out_nomem;
1097 nfs_parse_invalid_value("port"); 1095 rc = strict_strtoul(string, 10, &option);
1098 } else 1096 kfree(string);
1099 mnt->nfs_server.port = option; 1097 if (rc != 0 || option > USHORT_MAX)
1098 goto out_invalid_value;
1099 mnt->nfs_server.port = option;
1100 break; 1100 break;
1101 case Opt_rsize: 1101 case Opt_rsize:
1102 if (match_int(args, &option) || option < 0) { 1102 string = match_strdup(args);
1103 errors++; 1103 if (string == NULL)
1104 nfs_parse_invalid_value("rsize"); 1104 goto out_nomem;
1105 } else 1105 rc = strict_strtoul(string, 10, &option);
1106 mnt->rsize = option; 1106 kfree(string);
1107 if (rc != 0)
1108 goto out_invalid_value;
1109 mnt->rsize = option;
1107 break; 1110 break;
1108 case Opt_wsize: 1111 case Opt_wsize:
1109 if (match_int(args, &option) || option < 0) { 1112 string = match_strdup(args);
1110 errors++; 1113 if (string == NULL)
1111 nfs_parse_invalid_value("wsize"); 1114 goto out_nomem;
1112 } else 1115 rc = strict_strtoul(string, 10, &option);
1113 mnt->wsize = option; 1116 kfree(string);
1117 if (rc != 0)
1118 goto out_invalid_value;
1119 mnt->wsize = option;
1114 break; 1120 break;
1115 case Opt_bsize: 1121 case Opt_bsize:
1116 if (match_int(args, &option) || option < 0) { 1122 string = match_strdup(args);
1117 errors++; 1123 if (string == NULL)
1118 nfs_parse_invalid_value("bsize"); 1124 goto out_nomem;
1119 } else 1125 rc = strict_strtoul(string, 10, &option);
1120 mnt->bsize = option; 1126 kfree(string);
1127 if (rc != 0)
1128 goto out_invalid_value;
1129 mnt->bsize = option;
1121 break; 1130 break;
1122 case Opt_timeo: 1131 case Opt_timeo:
1123 if (match_int(args, &option) || option <= 0) { 1132 string = match_strdup(args);
1124 errors++; 1133 if (string == NULL)
1125 nfs_parse_invalid_value("timeo"); 1134 goto out_nomem;
1126 } else 1135 rc = strict_strtoul(string, 10, &option);
1127 mnt->timeo = option; 1136 kfree(string);
1137 if (rc != 0 || option == 0)
1138 goto out_invalid_value;
1139 mnt->timeo = option;
1128 break; 1140 break;
1129 case Opt_retrans: 1141 case Opt_retrans:
1130 if (match_int(args, &option) || option <= 0) { 1142 string = match_strdup(args);
1131 errors++; 1143 if (string == NULL)
1132 nfs_parse_invalid_value("retrans"); 1144 goto out_nomem;
1133 } else 1145 rc = strict_strtoul(string, 10, &option);
1134 mnt->retrans = option; 1146 kfree(string);
1147 if (rc != 0 || option == 0)
1148 goto out_invalid_value;
1149 mnt->retrans = option;
1135 break; 1150 break;
1136 case Opt_acregmin: 1151 case Opt_acregmin:
1137 if (match_int(args, &option) || option < 0) { 1152 string = match_strdup(args);
1138 errors++; 1153 if (string == NULL)
1139 nfs_parse_invalid_value("acregmin"); 1154 goto out_nomem;
1140 } else 1155 rc = strict_strtoul(string, 10, &option);
1141 mnt->acregmin = option; 1156 kfree(string);
1157 if (rc != 0)
1158 goto out_invalid_value;
1159 mnt->acregmin = option;
1142 break; 1160 break;
1143 case Opt_acregmax: 1161 case Opt_acregmax:
1144 if (match_int(args, &option) || option < 0) { 1162 string = match_strdup(args);
1145 errors++; 1163 if (string == NULL)
1146 nfs_parse_invalid_value("acregmax"); 1164 goto out_nomem;
1147 } else 1165 rc = strict_strtoul(string, 10, &option);
1148 mnt->acregmax = option; 1166 kfree(string);
1167 if (rc != 0)
1168 goto out_invalid_value;
1169 mnt->acregmax = option;
1149 break; 1170 break;
1150 case Opt_acdirmin: 1171 case Opt_acdirmin:
1151 if (match_int(args, &option) || option < 0) { 1172 string = match_strdup(args);
1152 errors++; 1173 if (string == NULL)
1153 nfs_parse_invalid_value("acdirmin"); 1174 goto out_nomem;
1154 } else 1175 rc = strict_strtoul(string, 10, &option);
1155 mnt->acdirmin = option; 1176 kfree(string);
1177 if (rc != 0)
1178 goto out_invalid_value;
1179 mnt->acdirmin = option;
1156 break; 1180 break;
1157 case Opt_acdirmax: 1181 case Opt_acdirmax:
1158 if (match_int(args, &option) || option < 0) { 1182 string = match_strdup(args);
1159 errors++; 1183 if (string == NULL)
1160 nfs_parse_invalid_value("acdirmax"); 1184 goto out_nomem;
1161 } else 1185 rc = strict_strtoul(string, 10, &option);
1162 mnt->acdirmax = option; 1186 kfree(string);
1187 if (rc != 0)
1188 goto out_invalid_value;
1189 mnt->acdirmax = option;
1163 break; 1190 break;
1164 case Opt_actimeo: 1191 case Opt_actimeo:
1165 if (match_int(args, &option) || option < 0) { 1192 string = match_strdup(args);
1166 errors++; 1193 if (string == NULL)
1167 nfs_parse_invalid_value("actimeo"); 1194 goto out_nomem;
1168 } else 1195 rc = strict_strtoul(string, 10, &option);
1169 mnt->acregmin = mnt->acregmax = 1196 kfree(string);
1170 mnt->acdirmin = mnt->acdirmax = option; 1197 if (rc != 0)
1198 goto out_invalid_value;
1199 mnt->acregmin = mnt->acregmax =
1200 mnt->acdirmin = mnt->acdirmax = option;
1171 break; 1201 break;
1172 case Opt_namelen: 1202 case Opt_namelen:
1173 if (match_int(args, &option) || option < 0) { 1203 string = match_strdup(args);
1174 errors++; 1204 if (string == NULL)
1175 nfs_parse_invalid_value("namlen"); 1205 goto out_nomem;
1176 } else 1206 rc = strict_strtoul(string, 10, &option);
1177 mnt->namlen = option; 1207 kfree(string);
1208 if (rc != 0)
1209 goto out_invalid_value;
1210 mnt->namlen = option;
1178 break; 1211 break;
1179 case Opt_mountport: 1212 case Opt_mountport:
1180 if (match_int(args, &option) || 1213 string = match_strdup(args);
1181 option < 0 || option > USHORT_MAX) { 1214 if (string == NULL)
1182 errors++; 1215 goto out_nomem;
1183 nfs_parse_invalid_value("mountport"); 1216 rc = strict_strtoul(string, 10, &option);
1184 } else 1217 kfree(string);
1185 mnt->mount_server.port = option; 1218 if (rc != 0 || option > USHORT_MAX)
1219 goto out_invalid_value;
1220 mnt->mount_server.port = option;
1186 break; 1221 break;
1187 case Opt_mountvers: 1222 case Opt_mountvers:
1188 if (match_int(args, &option) || 1223 string = match_strdup(args);
1224 if (string == NULL)
1225 goto out_nomem;
1226 rc = strict_strtoul(string, 10, &option);
1227 kfree(string);
1228 if (rc != 0 ||
1189 option < NFS_MNT_VERSION || 1229 option < NFS_MNT_VERSION ||
1190 option > NFS_MNT3_VERSION) { 1230 option > NFS_MNT3_VERSION)
1191 errors++; 1231 goto out_invalid_value;
1192 nfs_parse_invalid_value("mountvers"); 1232 mnt->mount_server.version = option;
1193 } else
1194 mnt->mount_server.version = option;
1195 break; 1233 break;
1196 case Opt_nfsvers: 1234 case Opt_nfsvers:
1197 if (match_int(args, &option)) { 1235 string = match_strdup(args);
1198 errors++; 1236 if (string == NULL)
1199 nfs_parse_invalid_value("nfsvers"); 1237 goto out_nomem;
1200 break; 1238 rc = strict_strtoul(string, 10, &option);
1201 } 1239 kfree(string);
1240 if (rc != 0)
1241 goto out_invalid_value;
1202 switch (option) { 1242 switch (option) {
1203 case NFS2_VERSION: 1243 case NFS2_VERSION:
1204 mnt->flags &= ~NFS_MOUNT_VER3; 1244 mnt->flags &= ~NFS_MOUNT_VER3;
@@ -1207,10 +1247,16 @@ static int nfs_parse_mount_options(char *raw,
1207 mnt->flags |= NFS_MOUNT_VER3; 1247 mnt->flags |= NFS_MOUNT_VER3;
1208 break; 1248 break;
1209 default: 1249 default:
1210 errors++; 1250 goto out_invalid_value;
1211 nfs_parse_invalid_value("nfsvers");
1212 } 1251 }
1213 break; 1252 break;
1253 case Opt_minorversion:
1254 if (match_int(args, &int_option))
1255 return 0;
1256 if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION)
1257 return 0;
1258 mnt->minorversion = int_option;
1259 break;
1214 1260
1215 /* 1261 /*
1216 * options that take text values 1262 * options that take text values
@@ -1222,9 +1268,9 @@ static int nfs_parse_mount_options(char *raw,
1222 rc = nfs_parse_security_flavors(string, mnt); 1268 rc = nfs_parse_security_flavors(string, mnt);
1223 kfree(string); 1269 kfree(string);
1224 if (!rc) { 1270 if (!rc) {
1225 errors++;
1226 dfprintk(MOUNT, "NFS: unrecognized " 1271 dfprintk(MOUNT, "NFS: unrecognized "
1227 "security flavor\n"); 1272 "security flavor\n");
1273 return 0;
1228 } 1274 }
1229 break; 1275 break;
1230 case Opt_proto: 1276 case Opt_proto:
@@ -1238,23 +1284,25 @@ static int nfs_parse_mount_options(char *raw,
1238 case Opt_xprt_udp: 1284 case Opt_xprt_udp:
1239 mnt->flags &= ~NFS_MOUNT_TCP; 1285 mnt->flags &= ~NFS_MOUNT_TCP;
1240 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1286 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1287 kfree(string);
1241 break; 1288 break;
1242 case Opt_xprt_tcp: 1289 case Opt_xprt_tcp:
1243 mnt->flags |= NFS_MOUNT_TCP; 1290 mnt->flags |= NFS_MOUNT_TCP;
1244 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1291 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1292 kfree(string);
1245 break; 1293 break;
1246 case Opt_xprt_rdma: 1294 case Opt_xprt_rdma:
1247 /* vector side protocols to TCP */ 1295 /* vector side protocols to TCP */
1248 mnt->flags |= NFS_MOUNT_TCP; 1296 mnt->flags |= NFS_MOUNT_TCP;
1249 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1297 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1250 xprt_load_transport(string); 1298 xprt_load_transport(string);
1299 kfree(string);
1251 break; 1300 break;
1252 default: 1301 default:
1253 errors++;
1254 dfprintk(MOUNT, "NFS: unrecognized " 1302 dfprintk(MOUNT, "NFS: unrecognized "
1255 "transport protocol\n"); 1303 "transport protocol\n");
1304 return 0;
1256 } 1305 }
1257 kfree(string);
1258 break; 1306 break;
1259 case Opt_mountproto: 1307 case Opt_mountproto:
1260 string = match_strdup(args); 1308 string = match_strdup(args);
@@ -1273,9 +1321,9 @@ static int nfs_parse_mount_options(char *raw,
1273 break; 1321 break;
1274 case Opt_xprt_rdma: /* not used for side protocols */ 1322 case Opt_xprt_rdma: /* not used for side protocols */
1275 default: 1323 default:
1276 errors++;
1277 dfprintk(MOUNT, "NFS: unrecognized " 1324 dfprintk(MOUNT, "NFS: unrecognized "
1278 "transport protocol\n"); 1325 "transport protocol\n");
1326 return 0;
1279 } 1327 }
1280 break; 1328 break;
1281 case Opt_addr: 1329 case Opt_addr:
@@ -1331,9 +1379,9 @@ static int nfs_parse_mount_options(char *raw,
1331 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; 1379 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
1332 break; 1380 break;
1333 default: 1381 default:
1334 errors++;
1335 dfprintk(MOUNT, "NFS: invalid " 1382 dfprintk(MOUNT, "NFS: invalid "
1336 "lookupcache argument\n"); 1383 "lookupcache argument\n");
1384 return 0;
1337 }; 1385 };
1338 break; 1386 break;
1339 1387
@@ -1351,20 +1399,20 @@ static int nfs_parse_mount_options(char *raw,
1351 break; 1399 break;
1352 1400
1353 default: 1401 default:
1354 errors++; 1402 invalid_option = 1;
1355 dfprintk(MOUNT, "NFS: unrecognized mount option " 1403 dfprintk(MOUNT, "NFS: unrecognized mount option "
1356 "'%s'\n", p); 1404 "'%s'\n", p);
1357 } 1405 }
1358 } 1406 }
1359 1407
1360 if (errors > 0) { 1408 if (!sloppy && invalid_option)
1361 dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n", 1409 return 0;
1362 errors, (errors == 1 ? "" : "s")); 1410
1363 if (!sloppy)
1364 return 0;
1365 }
1366 return 1; 1411 return 1;
1367 1412
1413out_invalid_value:
1414 printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
1415 return 0;
1368out_nomem: 1416out_nomem:
1369 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1417 printk(KERN_INFO "NFS: not enough memory to parse option\n");
1370 return 0; 1418 return 0;
@@ -1381,6 +1429,7 @@ out_security_failure:
1381static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1429static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1382 struct nfs_fh *root_fh) 1430 struct nfs_fh *root_fh)
1383{ 1431{
1432 unsigned int auth_flavor_len = 0;
1384 struct nfs_mount_request request = { 1433 struct nfs_mount_request request = {
1385 .sap = (struct sockaddr *) 1434 .sap = (struct sockaddr *)
1386 &args->mount_server.address, 1435 &args->mount_server.address,
@@ -1388,6 +1437,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1388 .protocol = args->mount_server.protocol, 1437 .protocol = args->mount_server.protocol,
1389 .fh = root_fh, 1438 .fh = root_fh,
1390 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1439 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1440 .auth_flav_len = &auth_flavor_len,
1391 }; 1441 };
1392 int status; 1442 int status;
1393 1443
@@ -2240,6 +2290,11 @@ static void nfs4_fill_super(struct super_block *sb)
2240 nfs_initialise_sb(sb); 2290 nfs_initialise_sb(sb);
2241} 2291}
2242 2292
2293static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2294{
2295 args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
2296}
2297
2243/* 2298/*
2244 * Validate NFSv4 mount options 2299 * Validate NFSv4 mount options
2245 */ 2300 */
@@ -2263,6 +2318,7 @@ static int nfs4_validate_mount_data(void *options,
2263 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ 2318 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
2264 args->auth_flavors[0] = RPC_AUTH_UNIX; 2319 args->auth_flavors[0] = RPC_AUTH_UNIX;
2265 args->auth_flavor_len = 0; 2320 args->auth_flavor_len = 0;
2321 args->minorversion = 0;
2266 2322
2267 switch (data->version) { 2323 switch (data->version) {
2268 case 1: 2324 case 1:
@@ -2336,6 +2392,8 @@ static int nfs4_validate_mount_data(void *options,
2336 2392
2337 nfs_validate_transport_protocol(args); 2393 nfs_validate_transport_protocol(args);
2338 2394
2395 nfs4_validate_mount_flags(args);
2396
2339 if (args->auth_flavor_len > 1) 2397 if (args->auth_flavor_len > 1)
2340 goto out_inval_auth; 2398 goto out_inval_auth;
2341 2399
@@ -2477,12 +2535,13 @@ static void nfs4_kill_super(struct super_block *sb)
2477{ 2535{
2478 struct nfs_server *server = NFS_SB(sb); 2536 struct nfs_server *server = NFS_SB(sb);
2479 2537
2538 dprintk("--> %s\n", __func__);
2480 nfs_super_return_all_delegations(sb); 2539 nfs_super_return_all_delegations(sb);
2481 kill_anon_super(sb); 2540 kill_anon_super(sb);
2482
2483 nfs4_renewd_prepare_shutdown(server); 2541 nfs4_renewd_prepare_shutdown(server);
2484 nfs_fscache_release_super_cookie(sb); 2542 nfs_fscache_release_super_cookie(sb);
2485 nfs_free_server(server); 2543 nfs_free_server(server);
2544 dprintk("<-- %s\n", __func__);
2486} 2545}
2487 2546
2488/* 2547/*
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index ecc295347775..1064c91ae810 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -15,6 +15,7 @@
15#include <linux/wait.h> 15#include <linux/wait.h>
16 16
17#include "internal.h" 17#include "internal.h"
18#include "nfs4_fs.h"
18 19
19struct nfs_unlinkdata { 20struct nfs_unlinkdata {
20 struct hlist_node list; 21 struct hlist_node list;
@@ -82,7 +83,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
82 struct inode *dir = data->dir; 83 struct inode *dir = data->dir;
83 84
84 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 85 if (!NFS_PROTO(dir)->unlink_done(task, dir))
85 rpc_restart_call(task); 86 nfs4_restart_rpc(task, NFS_SERVER(dir)->nfs_client);
86} 87}
87 88
88/** 89/**
@@ -102,9 +103,25 @@ static void nfs_async_unlink_release(void *calldata)
102 nfs_sb_deactive(sb); 103 nfs_sb_deactive(sb);
103} 104}
104 105
106#if defined(CONFIG_NFS_V4_1)
107void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
108{
109 struct nfs_unlinkdata *data = calldata;
110 struct nfs_server *server = NFS_SERVER(data->dir);
111
112 if (nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
113 &data->res.seq_res, 1, task))
114 return;
115 rpc_call_start(task);
116}
117#endif /* CONFIG_NFS_V4_1 */
118
105static const struct rpc_call_ops nfs_unlink_ops = { 119static const struct rpc_call_ops nfs_unlink_ops = {
106 .rpc_call_done = nfs_async_unlink_done, 120 .rpc_call_done = nfs_async_unlink_done,
107 .rpc_release = nfs_async_unlink_release, 121 .rpc_release = nfs_async_unlink_release,
122#if defined(CONFIG_NFS_V4_1)
123 .rpc_call_prepare = nfs_unlink_prepare,
124#endif /* CONFIG_NFS_V4_1 */
108}; 125};
109 126
110static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data) 127static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
@@ -241,6 +258,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry)
241 status = PTR_ERR(data->cred); 258 status = PTR_ERR(data->cred);
242 goto out_free; 259 goto out_free;
243 } 260 }
261 data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
244 262
245 status = -EBUSY; 263 status = -EBUSY;
246 spin_lock(&dentry->d_lock); 264 spin_lock(&dentry->d_lock);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e560a78995a3..ce728829f79a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -25,6 +25,7 @@
25#include "delegation.h" 25#include "delegation.h"
26#include "internal.h" 26#include "internal.h"
27#include "iostat.h" 27#include "iostat.h"
28#include "nfs4_fs.h"
28 29
29#define NFSDBG_FACILITY NFSDBG_PAGECACHE 30#define NFSDBG_FACILITY NFSDBG_PAGECACHE
30 31
@@ -52,6 +53,7 @@ struct nfs_write_data *nfs_commitdata_alloc(void)
52 if (p) { 53 if (p) {
53 memset(p, 0, sizeof(*p)); 54 memset(p, 0, sizeof(*p));
54 INIT_LIST_HEAD(&p->pages); 55 INIT_LIST_HEAD(&p->pages);
56 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
55 } 57 }
56 return p; 58 return p;
57} 59}
@@ -71,6 +73,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
71 memset(p, 0, sizeof(*p)); 73 memset(p, 0, sizeof(*p));
72 INIT_LIST_HEAD(&p->pages); 74 INIT_LIST_HEAD(&p->pages);
73 p->npages = pagecount; 75 p->npages = pagecount;
76 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
74 if (pagecount <= ARRAY_SIZE(p->page_array)) 77 if (pagecount <= ARRAY_SIZE(p->page_array))
75 p->pagevec = p->page_array; 78 p->pagevec = p->page_array;
76 else { 79 else {
@@ -1048,7 +1051,23 @@ out:
1048 nfs_writedata_release(calldata); 1051 nfs_writedata_release(calldata);
1049} 1052}
1050 1053
1054#if defined(CONFIG_NFS_V4_1)
1055void nfs_write_prepare(struct rpc_task *task, void *calldata)
1056{
1057 struct nfs_write_data *data = calldata;
1058 struct nfs_client *clp = (NFS_SERVER(data->inode))->nfs_client;
1059
1060 if (nfs4_setup_sequence(clp, &data->args.seq_args,
1061 &data->res.seq_res, 1, task))
1062 return;
1063 rpc_call_start(task);
1064}
1065#endif /* CONFIG_NFS_V4_1 */
1066
1051static const struct rpc_call_ops nfs_write_partial_ops = { 1067static const struct rpc_call_ops nfs_write_partial_ops = {
1068#if defined(CONFIG_NFS_V4_1)
1069 .rpc_call_prepare = nfs_write_prepare,
1070#endif /* CONFIG_NFS_V4_1 */
1052 .rpc_call_done = nfs_writeback_done_partial, 1071 .rpc_call_done = nfs_writeback_done_partial,
1053 .rpc_release = nfs_writeback_release_partial, 1072 .rpc_release = nfs_writeback_release_partial,
1054}; 1073};
@@ -1111,6 +1130,9 @@ remove_request:
1111} 1130}
1112 1131
1113static const struct rpc_call_ops nfs_write_full_ops = { 1132static const struct rpc_call_ops nfs_write_full_ops = {
1133#if defined(CONFIG_NFS_V4_1)
1134 .rpc_call_prepare = nfs_write_prepare,
1135#endif /* CONFIG_NFS_V4_1 */
1114 .rpc_call_done = nfs_writeback_done_full, 1136 .rpc_call_done = nfs_writeback_done_full,
1115 .rpc_release = nfs_writeback_release_full, 1137 .rpc_release = nfs_writeback_release_full,
1116}; 1138};
@@ -1123,6 +1145,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1123{ 1145{
1124 struct nfs_writeargs *argp = &data->args; 1146 struct nfs_writeargs *argp = &data->args;
1125 struct nfs_writeres *resp = &data->res; 1147 struct nfs_writeres *resp = &data->res;
1148 struct nfs_server *server = NFS_SERVER(data->inode);
1126 int status; 1149 int status;
1127 1150
1128 dprintk("NFS: %5u nfs_writeback_done (status %d)\n", 1151 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1155,7 +1178,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1155 if (time_before(complain, jiffies)) { 1178 if (time_before(complain, jiffies)) {
1156 dprintk("NFS: faulty NFS server %s:" 1179 dprintk("NFS: faulty NFS server %s:"
1157 " (committed = %d) != (stable = %d)\n", 1180 " (committed = %d) != (stable = %d)\n",
1158 NFS_SERVER(data->inode)->nfs_client->cl_hostname, 1181 server->nfs_client->cl_hostname,
1159 resp->verf->committed, argp->stable); 1182 resp->verf->committed, argp->stable);
1160 complain = jiffies + 300 * HZ; 1183 complain = jiffies + 300 * HZ;
1161 } 1184 }
@@ -1181,7 +1204,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1181 */ 1204 */
1182 argp->stable = NFS_FILE_SYNC; 1205 argp->stable = NFS_FILE_SYNC;
1183 } 1206 }
1184 rpc_restart_call(task); 1207 nfs4_restart_rpc(task, server->nfs_client);
1185 return -EAGAIN; 1208 return -EAGAIN;
1186 } 1209 }
1187 if (time_before(complain, jiffies)) { 1210 if (time_before(complain, jiffies)) {
@@ -1193,6 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1193 /* Can't do anything about it except throw an error. */ 1216 /* Can't do anything about it except throw an error. */
1194 task->tk_status = -EIO; 1217 task->tk_status = -EIO;
1195 } 1218 }
1219 nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
1196 return 0; 1220 return 0;
1197} 1221}
1198 1222
@@ -1349,6 +1373,9 @@ static void nfs_commit_release(void *calldata)
1349} 1373}
1350 1374
1351static const struct rpc_call_ops nfs_commit_ops = { 1375static const struct rpc_call_ops nfs_commit_ops = {
1376#if defined(CONFIG_NFS_V4_1)
1377 .rpc_call_prepare = nfs_write_prepare,
1378#endif /* CONFIG_NFS_V4_1 */
1352 .rpc_call_done = nfs_commit_done, 1379 .rpc_call_done = nfs_commit_done,
1353 .rpc_release = nfs_commit_release, 1380 .rpc_release = nfs_commit_release,
1354}; 1381};
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 51855dfd8adb..c325b187966b 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -195,7 +195,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
195extern int nlmsvc_grace_period; 195extern int nlmsvc_grace_period;
196extern unsigned long nlmsvc_timeout; 196extern unsigned long nlmsvc_timeout;
197extern int nsm_use_hostnames; 197extern int nsm_use_hostnames;
198extern int nsm_local_state; 198extern u32 nsm_local_state;
199 199
200/* 200/*
201 * Lockd client functions 201 * Lockd client functions
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
index 214d499718f7..f387919bbc59 100644
--- a/include/linux/nfs.h
+++ b/include/linux/nfs.h
@@ -25,8 +25,9 @@
25#define NFSMODE_SOCK 0140000 25#define NFSMODE_SOCK 0140000
26#define NFSMODE_FIFO 0010000 26#define NFSMODE_FIFO 0010000
27 27
28#define NFS_MNT_PROGRAM 100005 28#define NFS_MNT_PROGRAM 100005
29#define NFS_MNT_PORT 627 29#define NFS_MNT_VERSION 1
30#define NFS_MNT3_VERSION 3
30 31
31/* 32/*
32 * NFS stats. The good thing with these values is that NFSv3 errors are 33 * NFS stats. The good thing with these values is that NFSv3 errors are
diff --git a/include/linux/nfs2.h b/include/linux/nfs2.h
index 0ed9517138fc..fde24b30cc9e 100644
--- a/include/linux/nfs2.h
+++ b/include/linux/nfs2.h
@@ -64,11 +64,4 @@ struct nfs2_fh {
64#define NFSPROC_READDIR 16 64#define NFSPROC_READDIR 16
65#define NFSPROC_STATFS 17 65#define NFSPROC_STATFS 17
66 66
67#define NFS_MNT_PROGRAM 100005
68#define NFS_MNT_VERSION 1
69#define MNTPROC_NULL 0
70#define MNTPROC_MNT 1
71#define MNTPROC_UMNT 3
72#define MNTPROC_UMNTALL 4
73
74#endif /* _LINUX_NFS2_H */ 67#endif /* _LINUX_NFS2_H */
diff --git a/include/linux/nfs3.h b/include/linux/nfs3.h
index 539f3b550eab..ac33806ec7f9 100644
--- a/include/linux/nfs3.h
+++ b/include/linux/nfs3.h
@@ -88,12 +88,7 @@ struct nfs3_fh {
88#define NFS3PROC_PATHCONF 20 88#define NFS3PROC_PATHCONF 20
89#define NFS3PROC_COMMIT 21 89#define NFS3PROC_COMMIT 21
90 90
91#define NFS_MNT3_PROGRAM 100005
92#define NFS_MNT3_VERSION 3 91#define NFS_MNT3_VERSION 3
93#define MOUNTPROC3_NULL 0
94#define MOUNTPROC3_MNT 1
95#define MOUNTPROC3_UMNT 3
96#define MOUNTPROC3_UMNTALL 4
97 92
98 93
99#if defined(__KERNEL__) 94#if defined(__KERNEL__)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index e3f0cbcbd0db..bd2eba530667 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -21,6 +21,7 @@
21#define NFS4_FHSIZE 128 21#define NFS4_FHSIZE 128
22#define NFS4_MAXPATHLEN PATH_MAX 22#define NFS4_MAXPATHLEN PATH_MAX
23#define NFS4_MAXNAMLEN NAME_MAX 23#define NFS4_MAXNAMLEN NAME_MAX
24#define NFS4_OPAQUE_LIMIT 1024
24#define NFS4_MAX_SESSIONID_LEN 16 25#define NFS4_MAX_SESSIONID_LEN 16
25 26
26#define NFS4_ACCESS_READ 0x0001 27#define NFS4_ACCESS_READ 0x0001
@@ -130,6 +131,16 @@
130 131
131#define NFS4_MAX_UINT64 (~(u64)0) 132#define NFS4_MAX_UINT64 (~(u64)0)
132 133
134/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
135 * If a compound requires more operations, adjust NFS4_MAX_OPS accordingly.
136 */
137#define NFS4_MAX_OPS 8
138
139/* Our NFS4 client back channel server only wants the cb_sequene and the
140 * actual operation per compound
141 */
142#define NFS4_MAX_BACK_CHANNEL_OPS 2
143
133enum nfs4_acl_whotype { 144enum nfs4_acl_whotype {
134 NFS4_ACL_WHO_NAMED = 0, 145 NFS4_ACL_WHO_NAMED = 0,
135 NFS4_ACL_WHO_OWNER, 146 NFS4_ACL_WHO_OWNER,
@@ -462,6 +473,13 @@ enum lock_type4 {
462#define NFSPROC4_NULL 0 473#define NFSPROC4_NULL 0
463#define NFSPROC4_COMPOUND 1 474#define NFSPROC4_COMPOUND 1
464#define NFS4_MINOR_VERSION 0 475#define NFS4_MINOR_VERSION 0
476
477#if defined(CONFIG_NFS_V4_1)
478#define NFS4_MAX_MINOR_VERSION 1
479#else
480#define NFS4_MAX_MINOR_VERSION 0
481#endif /* CONFIG_NFS_V4_1 */
482
465#define NFS4_DEBUG 1 483#define NFS4_DEBUG 1
466 484
467/* Index of predefined Linux client operations */ 485/* Index of predefined Linux client operations */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6ad75948cbf7..19fe15d12042 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -4,11 +4,17 @@
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/backing-dev.h> 5#include <linux/backing-dev.h>
6#include <linux/wait.h> 6#include <linux/wait.h>
7#include <linux/nfs_xdr.h>
8#include <linux/sunrpc/xprt.h>
7 9
8#include <asm/atomic.h> 10#include <asm/atomic.h>
9 11
12struct nfs4_session;
10struct nfs_iostats; 13struct nfs_iostats;
11struct nlm_host; 14struct nlm_host;
15struct nfs4_sequence_args;
16struct nfs4_sequence_res;
17struct nfs_server;
12 18
13/* 19/*
14 * The nfs_client identifies our client state to the server. 20 * The nfs_client identifies our client state to the server.
@@ -18,6 +24,7 @@ struct nfs_client {
18 int cl_cons_state; /* current construction state (-ve: init error) */ 24 int cl_cons_state; /* current construction state (-ve: init error) */
19#define NFS_CS_READY 0 /* ready to be used */ 25#define NFS_CS_READY 0 /* ready to be used */
20#define NFS_CS_INITING 1 /* busy initialising */ 26#define NFS_CS_INITING 1 /* busy initialising */
27#define NFS_CS_SESSION_INITING 2 /* busy initialising session */
21 unsigned long cl_res_state; /* NFS resources state */ 28 unsigned long cl_res_state; /* NFS resources state */
22#define NFS_CS_CALLBACK 1 /* - callback started */ 29#define NFS_CS_CALLBACK 1 /* - callback started */
23#define NFS_CS_IDMAP 2 /* - idmap started */ 30#define NFS_CS_IDMAP 2 /* - idmap started */
@@ -32,6 +39,7 @@ struct nfs_client {
32 const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ 39 const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
33 int cl_proto; /* Network transport protocol */ 40 int cl_proto; /* Network transport protocol */
34 41
42 u32 cl_minorversion;/* NFSv4 minorversion */
35 struct rpc_cred *cl_machine_cred; 43 struct rpc_cred *cl_machine_cred;
36 44
37#ifdef CONFIG_NFS_V4 45#ifdef CONFIG_NFS_V4
@@ -63,7 +71,22 @@ struct nfs_client {
63 */ 71 */
64 char cl_ipaddr[48]; 72 char cl_ipaddr[48];
65 unsigned char cl_id_uniquifier; 73 unsigned char cl_id_uniquifier;
66#endif 74 int (* cl_call_sync)(struct nfs_server *server,
75 struct rpc_message *msg,
76 struct nfs4_sequence_args *args,
77 struct nfs4_sequence_res *res,
78 int cache_reply);
79#endif /* CONFIG_NFS_V4 */
80
81#ifdef CONFIG_NFS_V4_1
82 /* clientid returned from EXCHANGE_ID, used by session operations */
83 u64 cl_ex_clid;
84 /* The sequence id to use for the next CREATE_SESSION */
85 u32 cl_seqid;
86 /* The flags used for obtaining the clientid during EXCHANGE_ID */
87 u32 cl_exchange_flags;
88 struct nfs4_session *cl_session; /* sharred session */
89#endif /* CONFIG_NFS_V4_1 */
67 90
68#ifdef CONFIG_NFS_FSCACHE 91#ifdef CONFIG_NFS_FSCACHE
69 struct fscache_cookie *fscache; /* client index cache cookie */ 92 struct fscache_cookie *fscache; /* client index cache cookie */
@@ -145,4 +168,46 @@ struct nfs_server {
145#define NFS_CAP_ACLS (1U << 3) 168#define NFS_CAP_ACLS (1U << 3)
146#define NFS_CAP_ATOMIC_OPEN (1U << 4) 169#define NFS_CAP_ATOMIC_OPEN (1U << 4)
147 170
171
172/* maximum number of slots to use */
173#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
174
175#if defined(CONFIG_NFS_V4_1)
176
177/* Sessions */
178#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
179struct nfs4_slot_table {
180 struct nfs4_slot *slots; /* seqid per slot */
181 unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
182 spinlock_t slot_tbl_lock;
183 struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
184 int max_slots; /* # slots in table */
185 int highest_used_slotid; /* sent to server on each SEQ.
186 * op for dynamic resizing */
187};
188
189static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp)
190{
191 return sp - tbl->slots;
192}
193
194/*
195 * Session related parameters
196 */
197struct nfs4_session {
198 struct nfs4_sessionid sess_id;
199 u32 flags;
200 unsigned long session_state;
201 u32 hash_alg;
202 u32 ssv_len;
203
204 /* The fore and back channel */
205 struct nfs4_channel_attrs fc_attrs;
206 struct nfs4_slot_table fc_slot_table;
207 struct nfs4_channel_attrs bc_attrs;
208 struct nfs4_slot_table bc_slot_table;
209 struct nfs_client *clp;
210};
211
212#endif /* CONFIG_NFS_V4_1 */
148#endif 213#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index b89c34e40bc2..62f63fb0c4c8 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -145,6 +145,44 @@ struct nfs4_change_info {
145}; 145};
146 146
147struct nfs_seqid; 147struct nfs_seqid;
148
149/* nfs41 sessions channel attributes */
150struct nfs4_channel_attrs {
151 u32 headerpadsz;
152 u32 max_rqst_sz;
153 u32 max_resp_sz;
154 u32 max_resp_sz_cached;
155 u32 max_ops;
156 u32 max_reqs;
157};
158
159/* nfs41 sessions slot seqid */
160struct nfs4_slot {
161 u32 seq_nr;
162};
163
164struct nfs4_sequence_args {
165 struct nfs4_session *sa_session;
166 u8 sa_slotid;
167 u8 sa_cache_this;
168};
169
170struct nfs4_sequence_res {
171 struct nfs4_session *sr_session;
172 u8 sr_slotid; /* slot used to send request */
173 unsigned long sr_renewal_time;
174 int sr_status; /* sequence operation status */
175};
176
177struct nfs4_get_lease_time_args {
178 struct nfs4_sequence_args la_seq_args;
179};
180
181struct nfs4_get_lease_time_res {
182 struct nfs_fsinfo *lr_fsinfo;
183 struct nfs4_sequence_res lr_seq_res;
184};
185
148/* 186/*
149 * Arguments to the open call. 187 * Arguments to the open call.
150 */ 188 */
@@ -165,6 +203,7 @@ struct nfs_openargs {
165 const struct nfs_server *server; /* Needed for ID mapping */ 203 const struct nfs_server *server; /* Needed for ID mapping */
166 const u32 * bitmask; 204 const u32 * bitmask;
167 __u32 claim; 205 __u32 claim;
206 struct nfs4_sequence_args seq_args;
168}; 207};
169 208
170struct nfs_openres { 209struct nfs_openres {
@@ -181,6 +220,7 @@ struct nfs_openres {
181 __u32 do_recall; 220 __u32 do_recall;
182 __u64 maxsize; 221 __u64 maxsize;
183 __u32 attrset[NFS4_BITMAP_SIZE]; 222 __u32 attrset[NFS4_BITMAP_SIZE];
223 struct nfs4_sequence_res seq_res;
184}; 224};
185 225
186/* 226/*
@@ -206,6 +246,7 @@ struct nfs_closeargs {
206 struct nfs_seqid * seqid; 246 struct nfs_seqid * seqid;
207 fmode_t fmode; 247 fmode_t fmode;
208 const u32 * bitmask; 248 const u32 * bitmask;
249 struct nfs4_sequence_args seq_args;
209}; 250};
210 251
211struct nfs_closeres { 252struct nfs_closeres {
@@ -213,6 +254,7 @@ struct nfs_closeres {
213 struct nfs_fattr * fattr; 254 struct nfs_fattr * fattr;
214 struct nfs_seqid * seqid; 255 struct nfs_seqid * seqid;
215 const struct nfs_server *server; 256 const struct nfs_server *server;
257 struct nfs4_sequence_res seq_res;
216}; 258};
217/* 259/*
218 * * Arguments to the lock,lockt, and locku call. 260 * * Arguments to the lock,lockt, and locku call.
@@ -233,12 +275,14 @@ struct nfs_lock_args {
233 unsigned char block : 1; 275 unsigned char block : 1;
234 unsigned char reclaim : 1; 276 unsigned char reclaim : 1;
235 unsigned char new_lock_owner : 1; 277 unsigned char new_lock_owner : 1;
278 struct nfs4_sequence_args seq_args;
236}; 279};
237 280
238struct nfs_lock_res { 281struct nfs_lock_res {
239 nfs4_stateid stateid; 282 nfs4_stateid stateid;
240 struct nfs_seqid * lock_seqid; 283 struct nfs_seqid * lock_seqid;
241 struct nfs_seqid * open_seqid; 284 struct nfs_seqid * open_seqid;
285 struct nfs4_sequence_res seq_res;
242}; 286};
243 287
244struct nfs_locku_args { 288struct nfs_locku_args {
@@ -246,32 +290,38 @@ struct nfs_locku_args {
246 struct file_lock * fl; 290 struct file_lock * fl;
247 struct nfs_seqid * seqid; 291 struct nfs_seqid * seqid;
248 nfs4_stateid * stateid; 292 nfs4_stateid * stateid;
293 struct nfs4_sequence_args seq_args;
249}; 294};
250 295
251struct nfs_locku_res { 296struct nfs_locku_res {
252 nfs4_stateid stateid; 297 nfs4_stateid stateid;
253 struct nfs_seqid * seqid; 298 struct nfs_seqid * seqid;
299 struct nfs4_sequence_res seq_res;
254}; 300};
255 301
256struct nfs_lockt_args { 302struct nfs_lockt_args {
257 struct nfs_fh * fh; 303 struct nfs_fh * fh;
258 struct file_lock * fl; 304 struct file_lock * fl;
259 struct nfs_lowner lock_owner; 305 struct nfs_lowner lock_owner;
306 struct nfs4_sequence_args seq_args;
260}; 307};
261 308
262struct nfs_lockt_res { 309struct nfs_lockt_res {
263 struct file_lock * denied; /* LOCK, LOCKT failed */ 310 struct file_lock * denied; /* LOCK, LOCKT failed */
311 struct nfs4_sequence_res seq_res;
264}; 312};
265 313
266struct nfs4_delegreturnargs { 314struct nfs4_delegreturnargs {
267 const struct nfs_fh *fhandle; 315 const struct nfs_fh *fhandle;
268 const nfs4_stateid *stateid; 316 const nfs4_stateid *stateid;
269 const u32 * bitmask; 317 const u32 * bitmask;
318 struct nfs4_sequence_args seq_args;
270}; 319};
271 320
272struct nfs4_delegreturnres { 321struct nfs4_delegreturnres {
273 struct nfs_fattr * fattr; 322 struct nfs_fattr * fattr;
274 const struct nfs_server *server; 323 const struct nfs_server *server;
324 struct nfs4_sequence_res seq_res;
275}; 325};
276 326
277/* 327/*
@@ -284,12 +334,14 @@ struct nfs_readargs {
284 __u32 count; 334 __u32 count;
285 unsigned int pgbase; 335 unsigned int pgbase;
286 struct page ** pages; 336 struct page ** pages;
337 struct nfs4_sequence_args seq_args;
287}; 338};
288 339
289struct nfs_readres { 340struct nfs_readres {
290 struct nfs_fattr * fattr; 341 struct nfs_fattr * fattr;
291 __u32 count; 342 __u32 count;
292 int eof; 343 int eof;
344 struct nfs4_sequence_res seq_res;
293}; 345};
294 346
295/* 347/*
@@ -304,6 +356,7 @@ struct nfs_writeargs {
304 unsigned int pgbase; 356 unsigned int pgbase;
305 struct page ** pages; 357 struct page ** pages;
306 const u32 * bitmask; 358 const u32 * bitmask;
359 struct nfs4_sequence_args seq_args;
307}; 360};
308 361
309struct nfs_writeverf { 362struct nfs_writeverf {
@@ -316,6 +369,7 @@ struct nfs_writeres {
316 struct nfs_writeverf * verf; 369 struct nfs_writeverf * verf;
317 __u32 count; 370 __u32 count;
318 const struct nfs_server *server; 371 const struct nfs_server *server;
372 struct nfs4_sequence_res seq_res;
319}; 373};
320 374
321/* 375/*
@@ -325,12 +379,14 @@ struct nfs_removeargs {
325 const struct nfs_fh *fh; 379 const struct nfs_fh *fh;
326 struct qstr name; 380 struct qstr name;
327 const u32 * bitmask; 381 const u32 * bitmask;
382 struct nfs4_sequence_args seq_args;
328}; 383};
329 384
330struct nfs_removeres { 385struct nfs_removeres {
331 const struct nfs_server *server; 386 const struct nfs_server *server;
332 struct nfs4_change_info cinfo; 387 struct nfs4_change_info cinfo;
333 struct nfs_fattr dir_attr; 388 struct nfs_fattr dir_attr;
389 struct nfs4_sequence_res seq_res;
334}; 390};
335 391
336/* 392/*
@@ -383,6 +439,7 @@ struct nfs_setattrargs {
383 struct iattr * iap; 439 struct iattr * iap;
384 const struct nfs_server * server; /* Needed for name mapping */ 440 const struct nfs_server * server; /* Needed for name mapping */
385 const u32 * bitmask; 441 const u32 * bitmask;
442 struct nfs4_sequence_args seq_args;
386}; 443};
387 444
388struct nfs_setaclargs { 445struct nfs_setaclargs {
@@ -390,6 +447,11 @@ struct nfs_setaclargs {
390 size_t acl_len; 447 size_t acl_len;
391 unsigned int acl_pgbase; 448 unsigned int acl_pgbase;
392 struct page ** acl_pages; 449 struct page ** acl_pages;
450 struct nfs4_sequence_args seq_args;
451};
452
453struct nfs_setaclres {
454 struct nfs4_sequence_res seq_res;
393}; 455};
394 456
395struct nfs_getaclargs { 457struct nfs_getaclargs {
@@ -397,11 +459,18 @@ struct nfs_getaclargs {
397 size_t acl_len; 459 size_t acl_len;
398 unsigned int acl_pgbase; 460 unsigned int acl_pgbase;
399 struct page ** acl_pages; 461 struct page ** acl_pages;
462 struct nfs4_sequence_args seq_args;
463};
464
465struct nfs_getaclres {
466 size_t acl_len;
467 struct nfs4_sequence_res seq_res;
400}; 468};
401 469
402struct nfs_setattrres { 470struct nfs_setattrres {
403 struct nfs_fattr * fattr; 471 struct nfs_fattr * fattr;
404 const struct nfs_server * server; 472 const struct nfs_server * server;
473 struct nfs4_sequence_res seq_res;
405}; 474};
406 475
407struct nfs_linkargs { 476struct nfs_linkargs {
@@ -583,6 +652,7 @@ struct nfs4_accessargs {
583 const struct nfs_fh * fh; 652 const struct nfs_fh * fh;
584 const u32 * bitmask; 653 const u32 * bitmask;
585 u32 access; 654 u32 access;
655 struct nfs4_sequence_args seq_args;
586}; 656};
587 657
588struct nfs4_accessres { 658struct nfs4_accessres {
@@ -590,6 +660,7 @@ struct nfs4_accessres {
590 struct nfs_fattr * fattr; 660 struct nfs_fattr * fattr;
591 u32 supported; 661 u32 supported;
592 u32 access; 662 u32 access;
663 struct nfs4_sequence_res seq_res;
593}; 664};
594 665
595struct nfs4_create_arg { 666struct nfs4_create_arg {
@@ -609,6 +680,7 @@ struct nfs4_create_arg {
609 const struct iattr * attrs; 680 const struct iattr * attrs;
610 const struct nfs_fh * dir_fh; 681 const struct nfs_fh * dir_fh;
611 const u32 * bitmask; 682 const u32 * bitmask;
683 struct nfs4_sequence_args seq_args;
612}; 684};
613 685
614struct nfs4_create_res { 686struct nfs4_create_res {
@@ -617,21 +689,30 @@ struct nfs4_create_res {
617 struct nfs_fattr * fattr; 689 struct nfs_fattr * fattr;
618 struct nfs4_change_info dir_cinfo; 690 struct nfs4_change_info dir_cinfo;
619 struct nfs_fattr * dir_fattr; 691 struct nfs_fattr * dir_fattr;
692 struct nfs4_sequence_res seq_res;
620}; 693};
621 694
622struct nfs4_fsinfo_arg { 695struct nfs4_fsinfo_arg {
623 const struct nfs_fh * fh; 696 const struct nfs_fh * fh;
624 const u32 * bitmask; 697 const u32 * bitmask;
698 struct nfs4_sequence_args seq_args;
699};
700
701struct nfs4_fsinfo_res {
702 struct nfs_fsinfo *fsinfo;
703 struct nfs4_sequence_res seq_res;
625}; 704};
626 705
627struct nfs4_getattr_arg { 706struct nfs4_getattr_arg {
628 const struct nfs_fh * fh; 707 const struct nfs_fh * fh;
629 const u32 * bitmask; 708 const u32 * bitmask;
709 struct nfs4_sequence_args seq_args;
630}; 710};
631 711
632struct nfs4_getattr_res { 712struct nfs4_getattr_res {
633 const struct nfs_server * server; 713 const struct nfs_server * server;
634 struct nfs_fattr * fattr; 714 struct nfs_fattr * fattr;
715 struct nfs4_sequence_res seq_res;
635}; 716};
636 717
637struct nfs4_link_arg { 718struct nfs4_link_arg {
@@ -639,6 +720,7 @@ struct nfs4_link_arg {
639 const struct nfs_fh * dir_fh; 720 const struct nfs_fh * dir_fh;
640 const struct qstr * name; 721 const struct qstr * name;
641 const u32 * bitmask; 722 const u32 * bitmask;
723 struct nfs4_sequence_args seq_args;
642}; 724};
643 725
644struct nfs4_link_res { 726struct nfs4_link_res {
@@ -646,6 +728,7 @@ struct nfs4_link_res {
646 struct nfs_fattr * fattr; 728 struct nfs_fattr * fattr;
647 struct nfs4_change_info cinfo; 729 struct nfs4_change_info cinfo;
648 struct nfs_fattr * dir_attr; 730 struct nfs_fattr * dir_attr;
731 struct nfs4_sequence_res seq_res;
649}; 732};
650 733
651 734
@@ -653,21 +736,30 @@ struct nfs4_lookup_arg {
653 const struct nfs_fh * dir_fh; 736 const struct nfs_fh * dir_fh;
654 const struct qstr * name; 737 const struct qstr * name;
655 const u32 * bitmask; 738 const u32 * bitmask;
739 struct nfs4_sequence_args seq_args;
656}; 740};
657 741
658struct nfs4_lookup_res { 742struct nfs4_lookup_res {
659 const struct nfs_server * server; 743 const struct nfs_server * server;
660 struct nfs_fattr * fattr; 744 struct nfs_fattr * fattr;
661 struct nfs_fh * fh; 745 struct nfs_fh * fh;
746 struct nfs4_sequence_res seq_res;
662}; 747};
663 748
664struct nfs4_lookup_root_arg { 749struct nfs4_lookup_root_arg {
665 const u32 * bitmask; 750 const u32 * bitmask;
751 struct nfs4_sequence_args seq_args;
666}; 752};
667 753
668struct nfs4_pathconf_arg { 754struct nfs4_pathconf_arg {
669 const struct nfs_fh * fh; 755 const struct nfs_fh * fh;
670 const u32 * bitmask; 756 const u32 * bitmask;
757 struct nfs4_sequence_args seq_args;
758};
759
760struct nfs4_pathconf_res {
761 struct nfs_pathconf *pathconf;
762 struct nfs4_sequence_res seq_res;
671}; 763};
672 764
673struct nfs4_readdir_arg { 765struct nfs4_readdir_arg {
@@ -678,11 +770,13 @@ struct nfs4_readdir_arg {
678 struct page ** pages; /* zero-copy data */ 770 struct page ** pages; /* zero-copy data */
679 unsigned int pgbase; /* zero-copy data */ 771 unsigned int pgbase; /* zero-copy data */
680 const u32 * bitmask; 772 const u32 * bitmask;
773 struct nfs4_sequence_args seq_args;
681}; 774};
682 775
683struct nfs4_readdir_res { 776struct nfs4_readdir_res {
684 nfs4_verifier verifier; 777 nfs4_verifier verifier;
685 unsigned int pgbase; 778 unsigned int pgbase;
779 struct nfs4_sequence_res seq_res;
686}; 780};
687 781
688struct nfs4_readlink { 782struct nfs4_readlink {
@@ -690,6 +784,11 @@ struct nfs4_readlink {
690 unsigned int pgbase; 784 unsigned int pgbase;
691 unsigned int pglen; /* zero-copy data */ 785 unsigned int pglen; /* zero-copy data */
692 struct page ** pages; /* zero-copy data */ 786 struct page ** pages; /* zero-copy data */
787 struct nfs4_sequence_args seq_args;
788};
789
790struct nfs4_readlink_res {
791 struct nfs4_sequence_res seq_res;
693}; 792};
694 793
695struct nfs4_rename_arg { 794struct nfs4_rename_arg {
@@ -698,6 +797,7 @@ struct nfs4_rename_arg {
698 const struct qstr * old_name; 797 const struct qstr * old_name;
699 const struct qstr * new_name; 798 const struct qstr * new_name;
700 const u32 * bitmask; 799 const u32 * bitmask;
800 struct nfs4_sequence_args seq_args;
701}; 801};
702 802
703struct nfs4_rename_res { 803struct nfs4_rename_res {
@@ -706,6 +806,7 @@ struct nfs4_rename_res {
706 struct nfs_fattr * old_fattr; 806 struct nfs_fattr * old_fattr;
707 struct nfs4_change_info new_cinfo; 807 struct nfs4_change_info new_cinfo;
708 struct nfs_fattr * new_fattr; 808 struct nfs_fattr * new_fattr;
809 struct nfs4_sequence_res seq_res;
709}; 810};
710 811
711#define NFS4_SETCLIENTID_NAMELEN (127) 812#define NFS4_SETCLIENTID_NAMELEN (127)
@@ -724,6 +825,17 @@ struct nfs4_setclientid {
724struct nfs4_statfs_arg { 825struct nfs4_statfs_arg {
725 const struct nfs_fh * fh; 826 const struct nfs_fh * fh;
726 const u32 * bitmask; 827 const u32 * bitmask;
828 struct nfs4_sequence_args seq_args;
829};
830
831struct nfs4_statfs_res {
832 struct nfs_fsstat *fsstat;
833 struct nfs4_sequence_res seq_res;
834};
835
836struct nfs4_server_caps_arg {
837 struct nfs_fh *fhandle;
838 struct nfs4_sequence_args seq_args;
727}; 839};
728 840
729struct nfs4_server_caps_res { 841struct nfs4_server_caps_res {
@@ -731,6 +843,7 @@ struct nfs4_server_caps_res {
731 u32 acl_bitmask; 843 u32 acl_bitmask;
732 u32 has_links; 844 u32 has_links;
733 u32 has_symlinks; 845 u32 has_symlinks;
846 struct nfs4_sequence_res seq_res;
734}; 847};
735 848
736struct nfs4_string { 849struct nfs4_string {
@@ -765,10 +878,68 @@ struct nfs4_fs_locations_arg {
765 const struct qstr *name; 878 const struct qstr *name;
766 struct page *page; 879 struct page *page;
767 const u32 *bitmask; 880 const u32 *bitmask;
881 struct nfs4_sequence_args seq_args;
882};
883
884struct nfs4_fs_locations_res {
885 struct nfs4_fs_locations *fs_locations;
886 struct nfs4_sequence_res seq_res;
768}; 887};
769 888
770#endif /* CONFIG_NFS_V4 */ 889#endif /* CONFIG_NFS_V4 */
771 890
891struct nfstime4 {
892 u64 seconds;
893 u32 nseconds;
894};
895
896#ifdef CONFIG_NFS_V4_1
897struct nfs_impl_id4 {
898 u32 domain_len;
899 char *domain;
900 u32 name_len;
901 char *name;
902 struct nfstime4 date;
903};
904
905#define NFS4_EXCHANGE_ID_LEN (48)
906struct nfs41_exchange_id_args {
907 struct nfs_client *client;
908 nfs4_verifier *verifier;
909 unsigned int id_len;
910 char id[NFS4_EXCHANGE_ID_LEN];
911 u32 flags;
912};
913
914struct server_owner {
915 uint64_t minor_id;
916 uint32_t major_id_sz;
917 char major_id[NFS4_OPAQUE_LIMIT];
918};
919
920struct server_scope {
921 uint32_t server_scope_sz;
922 char server_scope[NFS4_OPAQUE_LIMIT];
923};
924
925struct nfs41_exchange_id_res {
926 struct nfs_client *client;
927 u32 flags;
928};
929
930struct nfs41_create_session_args {
931 struct nfs_client *client;
932 uint32_t flags;
933 uint32_t cb_program;
934 struct nfs4_channel_attrs fc_attrs; /* Fore Channel */
935 struct nfs4_channel_attrs bc_attrs; /* Back Channel */
936};
937
938struct nfs41_create_session_res {
939 struct nfs_client *client;
940};
941#endif /* CONFIG_NFS_V4_1 */
942
772struct nfs_page; 943struct nfs_page;
773 944
774#define NFS_PAGEVEC_SIZE (8U) 945#define NFS_PAGEVEC_SIZE (8U)
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 4d61c873feed..7ef4b7ad1214 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -41,7 +41,6 @@
41#include <linux/kref.h> 41#include <linux/kref.h>
42#include <linux/sunrpc/clnt.h> 42#include <linux/sunrpc/clnt.h>
43 43
44#define NFS4_OPAQUE_LIMIT 1024
45typedef struct { 44typedef struct {
46 u32 cl_boot; 45 u32 cl_boot;
47 u32 cl_id; 46 u32 cl_id;
diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h
new file mode 100644
index 000000000000..6508f0dc0eff
--- /dev/null
+++ b/include/linux/sunrpc/bc_xprt.h
@@ -0,0 +1,49 @@
1/******************************************************************************
2
3(c) 2008 NetApp. All Rights Reserved.
4
5NetApp provides this source code under the GPL v2 License.
6The GPL v2 license is available at
7http://opensource.org/licenses/gpl-license.php.
8
9THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
13CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20
21******************************************************************************/
22
23/*
24 * Functions to create and manage the backchannel
25 */
26
27#ifndef _LINUX_SUNRPC_BC_XPRT_H
28#define _LINUX_SUNRPC_BC_XPRT_H
29
30#include <linux/sunrpc/svcsock.h>
31#include <linux/sunrpc/xprt.h>
32#include <linux/sunrpc/sched.h>
33
34#ifdef CONFIG_NFS_V4_1
35struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt);
36void xprt_free_bc_request(struct rpc_rqst *req);
37int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
38void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs);
39void bc_release_request(struct rpc_task *);
40int bc_send(struct rpc_rqst *req);
41#else /* CONFIG_NFS_V4_1 */
42static inline int xprt_setup_backchannel(struct rpc_xprt *xprt,
43 unsigned int min_reqs)
44{
45 return 0;
46}
47#endif /* CONFIG_NFS_V4_1 */
48#endif /* _LINUX_SUNRPC_BC_XPRT_H */
49
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index c39a21040dcb..37881f1a0bd7 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -143,6 +143,7 @@ int rpc_call_sync(struct rpc_clnt *clnt,
143 const struct rpc_message *msg, int flags); 143 const struct rpc_message *msg, int flags);
144struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, 144struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
145 int flags); 145 int flags);
146void rpc_restart_call_prepare(struct rpc_task *);
146void rpc_restart_call(struct rpc_task *); 147void rpc_restart_call(struct rpc_task *);
147void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); 148void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
148size_t rpc_max_payload(struct rpc_clnt *); 149size_t rpc_max_payload(struct rpc_clnt *);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 64981a2f1cae..401097781fc0 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -210,6 +210,8 @@ struct rpc_wait_queue {
210 */ 210 */
211struct rpc_task *rpc_new_task(const struct rpc_task_setup *); 211struct rpc_task *rpc_new_task(const struct rpc_task_setup *);
212struct rpc_task *rpc_run_task(const struct rpc_task_setup *); 212struct rpc_task *rpc_run_task(const struct rpc_task_setup *);
213struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
214 const struct rpc_call_ops *ops);
213void rpc_put_task(struct rpc_task *); 215void rpc_put_task(struct rpc_task *);
214void rpc_exit_task(struct rpc_task *); 216void rpc_exit_task(struct rpc_task *);
215void rpc_release_calldata(const struct rpc_call_ops *, void *); 217void rpc_release_calldata(const struct rpc_call_ops *, void *);
@@ -237,6 +239,7 @@ void rpc_show_tasks(void);
237int rpc_init_mempool(void); 239int rpc_init_mempool(void);
238void rpc_destroy_mempool(void); 240void rpc_destroy_mempool(void);
239extern struct workqueue_struct *rpciod_workqueue; 241extern struct workqueue_struct *rpciod_workqueue;
242void rpc_prepare_task(struct rpc_task *task);
240 243
241static inline void rpc_exit(struct rpc_task *task, int status) 244static inline void rpc_exit(struct rpc_task *task, int status)
242{ 245{
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 2a30775959e9..ea8009695c69 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -96,6 +96,15 @@ struct svc_serv {
96 svc_thread_fn sv_function; /* main function for threads */ 96 svc_thread_fn sv_function; /* main function for threads */
97 unsigned int sv_drc_max_pages; /* Total pages for DRC */ 97 unsigned int sv_drc_max_pages; /* Total pages for DRC */
98 unsigned int sv_drc_pages_used;/* DRC pages used */ 98 unsigned int sv_drc_pages_used;/* DRC pages used */
99#if defined(CONFIG_NFS_V4_1)
100 struct list_head sv_cb_list; /* queue for callback requests
101 * that arrive over the same
102 * connection */
103 spinlock_t sv_cb_lock; /* protects the svc_cb_list */
104 wait_queue_head_t sv_cb_waitq; /* sleep here if there are no
105 * entries in the svc_cb_list */
106 struct svc_xprt *bc_xprt;
107#endif /* CONFIG_NFS_V4_1 */
99}; 108};
100 109
101/* 110/*
@@ -411,6 +420,8 @@ int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
411int svc_pool_stats_open(struct svc_serv *serv, struct file *file); 420int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
412void svc_destroy(struct svc_serv *); 421void svc_destroy(struct svc_serv *);
413int svc_process(struct svc_rqst *); 422int svc_process(struct svc_rqst *);
423int bc_svc_process(struct svc_serv *, struct rpc_rqst *,
424 struct svc_rqst *);
414int svc_register(const struct svc_serv *, const int, 425int svc_register(const struct svc_serv *, const int,
415 const unsigned short, const unsigned short); 426 const unsigned short, const unsigned short);
416 427
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 483e10380aae..6bb1ec4ae310 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -42,6 +42,8 @@ int svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
42int svc_addsock(struct svc_serv *serv, int fd, char *name_return); 42int svc_addsock(struct svc_serv *serv, int fd, char *name_return);
43void svc_init_xprt_sock(void); 43void svc_init_xprt_sock(void);
44void svc_cleanup_xprt_sock(void); 44void svc_cleanup_xprt_sock(void);
45struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot);
46void svc_sock_destroy(struct svc_xprt *);
45 47
46/* 48/*
47 * svc_makesock socket characteristics 49 * svc_makesock socket characteristics
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 08afe43118f4..1175d58efc2e 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -67,7 +67,8 @@ struct rpc_rqst {
67 struct rpc_task * rq_task; /* RPC task data */ 67 struct rpc_task * rq_task; /* RPC task data */
68 __be32 rq_xid; /* request XID */ 68 __be32 rq_xid; /* request XID */
69 int rq_cong; /* has incremented xprt->cong */ 69 int rq_cong; /* has incremented xprt->cong */
70 int rq_received; /* receive completed */ 70 int rq_reply_bytes_recvd; /* number of reply */
71 /* bytes received */
71 u32 rq_seqno; /* gss seq no. used on req. */ 72 u32 rq_seqno; /* gss seq no. used on req. */
72 int rq_enc_pages_num; 73 int rq_enc_pages_num;
73 struct page **rq_enc_pages; /* scratch pages for use by 74 struct page **rq_enc_pages; /* scratch pages for use by
@@ -97,6 +98,12 @@ struct rpc_rqst {
97 98
98 unsigned long rq_xtime; /* when transmitted */ 99 unsigned long rq_xtime; /* when transmitted */
99 int rq_ntrans; 100 int rq_ntrans;
101
102#if defined(CONFIG_NFS_V4_1)
103 struct list_head rq_bc_list; /* Callback service list */
104 unsigned long rq_bc_pa_state; /* Backchannel prealloc state */
105 struct list_head rq_bc_pa_list; /* Backchannel prealloc list */
106#endif /* CONFIG_NFS_V4_1 */
100}; 107};
101#define rq_svec rq_snd_buf.head 108#define rq_svec rq_snd_buf.head
102#define rq_slen rq_snd_buf.len 109#define rq_slen rq_snd_buf.len
@@ -174,6 +181,15 @@ struct rpc_xprt {
174 spinlock_t reserve_lock; /* lock slot table */ 181 spinlock_t reserve_lock; /* lock slot table */
175 u32 xid; /* Next XID value to use */ 182 u32 xid; /* Next XID value to use */
176 struct rpc_task * snd_task; /* Task blocked in send */ 183 struct rpc_task * snd_task; /* Task blocked in send */
184#if defined(CONFIG_NFS_V4_1)
185 struct svc_serv *bc_serv; /* The RPC service which will */
186 /* process the callback */
187 unsigned int bc_alloc_count; /* Total number of preallocs */
188 spinlock_t bc_pa_lock; /* Protects the preallocated
189 * items */
190 struct list_head bc_pa_list; /* List of preallocated
191 * backchannel rpc_rqst's */
192#endif /* CONFIG_NFS_V4_1 */
177 struct list_head recv; 193 struct list_head recv;
178 194
179 struct { 195 struct {
@@ -192,6 +208,26 @@ struct rpc_xprt {
192 const char *address_strings[RPC_DISPLAY_MAX]; 208 const char *address_strings[RPC_DISPLAY_MAX];
193}; 209};
194 210
211#if defined(CONFIG_NFS_V4_1)
212/*
213 * Backchannel flags
214 */
215#define RPC_BC_PA_IN_USE 0x0001 /* Preallocated backchannel */
216 /* buffer in use */
217#endif /* CONFIG_NFS_V4_1 */
218
219#if defined(CONFIG_NFS_V4_1)
220static inline int bc_prealloc(struct rpc_rqst *req)
221{
222 return test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
223}
224#else
225static inline int bc_prealloc(struct rpc_rqst *req)
226{
227 return 0;
228}
229#endif /* CONFIG_NFS_V4_1 */
230
195struct xprt_create { 231struct xprt_create {
196 int ident; /* XPRT_TRANSPORT identifier */ 232 int ident; /* XPRT_TRANSPORT identifier */
197 struct sockaddr * srcaddr; /* optional local address */ 233 struct sockaddr * srcaddr; /* optional local address */
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 5369aa369b35..db73fd2a3f0e 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -13,5 +13,6 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
13 rpcb_clnt.o timer.o xdr.o \ 13 rpcb_clnt.o timer.o xdr.o \
14 sunrpc_syms.o cache.o rpc_pipe.o \ 14 sunrpc_syms.o cache.o rpc_pipe.o \
15 svc_xprt.o 15 svc_xprt.o
16sunrpc-$(CONFIG_NFS_V4_1) += backchannel_rqst.o bc_svc.o
16sunrpc-$(CONFIG_PROC_FS) += stats.o 17sunrpc-$(CONFIG_PROC_FS) += stats.o
17sunrpc-$(CONFIG_SYSCTL) += sysctl.o 18sunrpc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
new file mode 100644
index 000000000000..553621fb2c41
--- /dev/null
+++ b/net/sunrpc/backchannel_rqst.c
@@ -0,0 +1,281 @@
1/******************************************************************************
2
3(c) 2007 Network Appliance, Inc. All Rights Reserved.
4(c) 2009 NetApp. All Rights Reserved.
5
6NetApp provides this source code under the GPL v2 License.
7The GPL v2 license is available at
8http://opensource.org/licenses/gpl-license.php.
9
10THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
12LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
13A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
14CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
15EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
17PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22******************************************************************************/
23
24#include <linux/tcp.h>
25#include <linux/sunrpc/xprt.h>
26
27#ifdef RPC_DEBUG
28#define RPCDBG_FACILITY RPCDBG_TRANS
29#endif
30
31#if defined(CONFIG_NFS_V4_1)
32
33/*
34 * Helper routines that track the number of preallocation elements
35 * on the transport.
36 */
37static inline int xprt_need_to_requeue(struct rpc_xprt *xprt)
38{
39 return xprt->bc_alloc_count > 0;
40}
41
42static inline void xprt_inc_alloc_count(struct rpc_xprt *xprt, unsigned int n)
43{
44 xprt->bc_alloc_count += n;
45}
46
47static inline int xprt_dec_alloc_count(struct rpc_xprt *xprt, unsigned int n)
48{
49 return xprt->bc_alloc_count -= n;
50}
51
52/*
53 * Free the preallocated rpc_rqst structure and the memory
54 * buffers hanging off of it.
55 */
56static void xprt_free_allocation(struct rpc_rqst *req)
57{
58 struct xdr_buf *xbufp;
59
60 dprintk("RPC: free allocations for req= %p\n", req);
61 BUG_ON(test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
62 xbufp = &req->rq_private_buf;
63 free_page((unsigned long)xbufp->head[0].iov_base);
64 xbufp = &req->rq_snd_buf;
65 free_page((unsigned long)xbufp->head[0].iov_base);
66 list_del(&req->rq_bc_pa_list);
67 kfree(req);
68}
69
70/*
71 * Preallocate up to min_reqs structures and related buffers for use
72 * by the backchannel. This function can be called multiple times
73 * when creating new sessions that use the same rpc_xprt. The
74 * preallocated buffers are added to the pool of resources used by
75 * the rpc_xprt. Anyone of these resources may be used used by an
76 * incoming callback request. It's up to the higher levels in the
77 * stack to enforce that the maximum number of session slots is not
78 * being exceeded.
79 *
80 * Some callback arguments can be large. For example, a pNFS server
81 * using multiple deviceids. The list can be unbound, but the client
82 * has the ability to tell the server the maximum size of the callback
83 * requests. Each deviceID is 16 bytes, so allocate one page
84 * for the arguments to have enough room to receive a number of these
85 * deviceIDs. The NFS client indicates to the pNFS server that its
86 * callback requests can be up to 4096 bytes in size.
87 */
88int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs)
89{
90 struct page *page_rcv = NULL, *page_snd = NULL;
91 struct xdr_buf *xbufp = NULL;
92 struct rpc_rqst *req, *tmp;
93 struct list_head tmp_list;
94 int i;
95
96 dprintk("RPC: setup backchannel transport\n");
97
98 /*
99 * We use a temporary list to keep track of the preallocated
100 * buffers. Once we're done building the list we splice it
101 * into the backchannel preallocation list off of the rpc_xprt
102 * struct. This helps minimize the amount of time the list
103 * lock is held on the rpc_xprt struct. It also makes cleanup
104 * easier in case of memory allocation errors.
105 */
106 INIT_LIST_HEAD(&tmp_list);
107 for (i = 0; i < min_reqs; i++) {
108 /* Pre-allocate one backchannel rpc_rqst */
109 req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL);
110 if (req == NULL) {
111 printk(KERN_ERR "Failed to create bc rpc_rqst\n");
112 goto out_free;
113 }
114
115 /* Add the allocated buffer to the tmp list */
116 dprintk("RPC: adding req= %p\n", req);
117 list_add(&req->rq_bc_pa_list, &tmp_list);
118
119 req->rq_xprt = xprt;
120 INIT_LIST_HEAD(&req->rq_list);
121 INIT_LIST_HEAD(&req->rq_bc_list);
122
123 /* Preallocate one XDR receive buffer */
124 page_rcv = alloc_page(GFP_KERNEL);
125 if (page_rcv == NULL) {
126 printk(KERN_ERR "Failed to create bc receive xbuf\n");
127 goto out_free;
128 }
129 xbufp = &req->rq_rcv_buf;
130 xbufp->head[0].iov_base = page_address(page_rcv);
131 xbufp->head[0].iov_len = PAGE_SIZE;
132 xbufp->tail[0].iov_base = NULL;
133 xbufp->tail[0].iov_len = 0;
134 xbufp->page_len = 0;
135 xbufp->len = PAGE_SIZE;
136 xbufp->buflen = PAGE_SIZE;
137
138 /* Preallocate one XDR send buffer */
139 page_snd = alloc_page(GFP_KERNEL);
140 if (page_snd == NULL) {
141 printk(KERN_ERR "Failed to create bc snd xbuf\n");
142 goto out_free;
143 }
144
145 xbufp = &req->rq_snd_buf;
146 xbufp->head[0].iov_base = page_address(page_snd);
147 xbufp->head[0].iov_len = 0;
148 xbufp->tail[0].iov_base = NULL;
149 xbufp->tail[0].iov_len = 0;
150 xbufp->page_len = 0;
151 xbufp->len = 0;
152 xbufp->buflen = PAGE_SIZE;
153 }
154
155 /*
156 * Add the temporary list to the backchannel preallocation list
157 */
158 spin_lock_bh(&xprt->bc_pa_lock);
159 list_splice(&tmp_list, &xprt->bc_pa_list);
160 xprt_inc_alloc_count(xprt, min_reqs);
161 spin_unlock_bh(&xprt->bc_pa_lock);
162
163 dprintk("RPC: setup backchannel transport done\n");
164 return 0;
165
166out_free:
167 /*
168 * Memory allocation failed, free the temporary list
169 */
170 list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list)
171 xprt_free_allocation(req);
172
173 dprintk("RPC: setup backchannel transport failed\n");
174 return -1;
175}
176EXPORT_SYMBOL(xprt_setup_backchannel);
177
178/*
179 * Destroys the backchannel preallocated structures.
180 * Since these structures may have been allocated by multiple calls
181 * to xprt_setup_backchannel, we only destroy up to the maximum number
182 * of reqs specified by the caller.
183 * @xprt: the transport holding the preallocated strucures
184 * @max_reqs the maximum number of preallocated structures to destroy
185 */
186void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs)
187{
188 struct rpc_rqst *req = NULL, *tmp = NULL;
189
190 dprintk("RPC: destroy backchannel transport\n");
191
192 BUG_ON(max_reqs == 0);
193 spin_lock_bh(&xprt->bc_pa_lock);
194 xprt_dec_alloc_count(xprt, max_reqs);
195 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
196 dprintk("RPC: req=%p\n", req);
197 xprt_free_allocation(req);
198 if (--max_reqs == 0)
199 break;
200 }
201 spin_unlock_bh(&xprt->bc_pa_lock);
202
203 dprintk("RPC: backchannel list empty= %s\n",
204 list_empty(&xprt->bc_pa_list) ? "true" : "false");
205}
206EXPORT_SYMBOL(xprt_destroy_backchannel);
207
208/*
209 * One or more rpc_rqst structure have been preallocated during the
210 * backchannel setup. Buffer space for the send and private XDR buffers
211 * has been preallocated as well. Use xprt_alloc_bc_request to allocate
212 * to this request. Use xprt_free_bc_request to return it.
213 *
214 * We know that we're called in soft interrupt context, grab the spin_lock
215 * since there is no need to grab the bottom half spin_lock.
216 *
217 * Return an available rpc_rqst, otherwise NULL if non are available.
218 */
219struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt)
220{
221 struct rpc_rqst *req;
222
223 dprintk("RPC: allocate a backchannel request\n");
224 spin_lock(&xprt->bc_pa_lock);
225 if (!list_empty(&xprt->bc_pa_list)) {
226 req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
227 rq_bc_pa_list);
228 list_del(&req->rq_bc_pa_list);
229 } else {
230 req = NULL;
231 }
232 spin_unlock(&xprt->bc_pa_lock);
233
234 if (req != NULL) {
235 set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
236 req->rq_reply_bytes_recvd = 0;
237 req->rq_bytes_sent = 0;
238 memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
239 sizeof(req->rq_private_buf));
240 }
241 dprintk("RPC: backchannel req=%p\n", req);
242 return req;
243}
244
245/*
246 * Return the preallocated rpc_rqst structure and XDR buffers
247 * associated with this rpc_task.
248 */
249void xprt_free_bc_request(struct rpc_rqst *req)
250{
251 struct rpc_xprt *xprt = req->rq_xprt;
252
253 dprintk("RPC: free backchannel req=%p\n", req);
254
255 smp_mb__before_clear_bit();
256 BUG_ON(!test_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state));
257 clear_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
258 smp_mb__after_clear_bit();
259
260 if (!xprt_need_to_requeue(xprt)) {
261 /*
262 * The last remaining session was destroyed while this
263 * entry was in use. Free the entry and don't attempt
264 * to add back to the list because there is no need to
265 * have anymore preallocated entries.
266 */
267 dprintk("RPC: Last session removed req=%p\n", req);
268 xprt_free_allocation(req);
269 return;
270 }
271
272 /*
273 * Return it to the list of preallocations so that it
274 * may be reused by a new callback request.
275 */
276 spin_lock_bh(&xprt->bc_pa_lock);
277 list_add(&req->rq_bc_pa_list, &xprt->bc_pa_list);
278 spin_unlock_bh(&xprt->bc_pa_lock);
279}
280
281#endif /* CONFIG_NFS_V4_1 */
diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c
new file mode 100644
index 000000000000..13f214f53120
--- /dev/null
+++ b/net/sunrpc/bc_svc.c
@@ -0,0 +1,81 @@
1/******************************************************************************
2
3(c) 2007 Network Appliance, Inc. All Rights Reserved.
4(c) 2009 NetApp. All Rights Reserved.
5
6NetApp provides this source code under the GPL v2 License.
7The GPL v2 license is available at
8http://opensource.org/licenses/gpl-license.php.
9
10THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
12LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
13A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
14CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
15EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
17PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22******************************************************************************/
23
24/*
25 * The NFSv4.1 callback service helper routines.
26 * They implement the transport level processing required to send the
27 * reply over an existing open connection previously established by the client.
28 */
29
30#if defined(CONFIG_NFS_V4_1)
31
32#include <linux/module.h>
33
34#include <linux/sunrpc/xprt.h>
35#include <linux/sunrpc/sched.h>
36#include <linux/sunrpc/bc_xprt.h>
37
38#define RPCDBG_FACILITY RPCDBG_SVCDSP
39
40void bc_release_request(struct rpc_task *task)
41{
42 struct rpc_rqst *req = task->tk_rqstp;
43
44 dprintk("RPC: bc_release_request: task= %p\n", task);
45
46 /*
47 * Release this request only if it's a backchannel
48 * preallocated request
49 */
50 if (!bc_prealloc(req))
51 return;
52 xprt_free_bc_request(req);
53}
54
55/* Empty callback ops */
56static const struct rpc_call_ops nfs41_callback_ops = {
57};
58
59
60/*
61 * Send the callback reply
62 */
63int bc_send(struct rpc_rqst *req)
64{
65 struct rpc_task *task;
66 int ret;
67
68 dprintk("RPC: bc_send req= %p\n", req);
69 task = rpc_run_bc_task(req, &nfs41_callback_ops);
70 if (IS_ERR(task))
71 ret = PTR_ERR(task);
72 else {
73 BUG_ON(atomic_read(&task->tk_count) != 1);
74 ret = task->tk_status;
75 rpc_put_task(task);
76 }
77 return ret;
78 dprintk("RPC: bc_send ret= %d \n", ret);
79}
80
81#endif /* CONFIG_NFS_V4_1 */
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5abab094441f..5bc2f45bddf0 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -36,7 +36,9 @@
36#include <linux/sunrpc/clnt.h> 36#include <linux/sunrpc/clnt.h>
37#include <linux/sunrpc/rpc_pipe_fs.h> 37#include <linux/sunrpc/rpc_pipe_fs.h>
38#include <linux/sunrpc/metrics.h> 38#include <linux/sunrpc/metrics.h>
39#include <linux/sunrpc/bc_xprt.h>
39 40
41#include "sunrpc.h"
40 42
41#ifdef RPC_DEBUG 43#ifdef RPC_DEBUG
42# define RPCDBG_FACILITY RPCDBG_CALL 44# define RPCDBG_FACILITY RPCDBG_CALL
@@ -63,6 +65,9 @@ static void call_decode(struct rpc_task *task);
63static void call_bind(struct rpc_task *task); 65static void call_bind(struct rpc_task *task);
64static void call_bind_status(struct rpc_task *task); 66static void call_bind_status(struct rpc_task *task);
65static void call_transmit(struct rpc_task *task); 67static void call_transmit(struct rpc_task *task);
68#if defined(CONFIG_NFS_V4_1)
69static void call_bc_transmit(struct rpc_task *task);
70#endif /* CONFIG_NFS_V4_1 */
66static void call_status(struct rpc_task *task); 71static void call_status(struct rpc_task *task);
67static void call_transmit_status(struct rpc_task *task); 72static void call_transmit_status(struct rpc_task *task);
68static void call_refresh(struct rpc_task *task); 73static void call_refresh(struct rpc_task *task);
@@ -613,6 +618,50 @@ rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags,
613} 618}
614EXPORT_SYMBOL_GPL(rpc_call_async); 619EXPORT_SYMBOL_GPL(rpc_call_async);
615 620
621#if defined(CONFIG_NFS_V4_1)
622/**
623 * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run
624 * rpc_execute against it
625 * @ops: RPC call ops
626 */
627struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
628 const struct rpc_call_ops *tk_ops)
629{
630 struct rpc_task *task;
631 struct xdr_buf *xbufp = &req->rq_snd_buf;
632 struct rpc_task_setup task_setup_data = {
633 .callback_ops = tk_ops,
634 };
635
636 dprintk("RPC: rpc_run_bc_task req= %p\n", req);
637 /*
638 * Create an rpc_task to send the data
639 */
640 task = rpc_new_task(&task_setup_data);
641 if (!task) {
642 xprt_free_bc_request(req);
643 goto out;
644 }
645 task->tk_rqstp = req;
646
647 /*
648 * Set up the xdr_buf length.
649 * This also indicates that the buffer is XDR encoded already.
650 */
651 xbufp->len = xbufp->head[0].iov_len + xbufp->page_len +
652 xbufp->tail[0].iov_len;
653
654 task->tk_action = call_bc_transmit;
655 atomic_inc(&task->tk_count);
656 BUG_ON(atomic_read(&task->tk_count) != 2);
657 rpc_execute(task);
658
659out:
660 dprintk("RPC: rpc_run_bc_task: task= %p\n", task);
661 return task;
662}
663#endif /* CONFIG_NFS_V4_1 */
664
616void 665void
617rpc_call_start(struct rpc_task *task) 666rpc_call_start(struct rpc_task *task)
618{ 667{
@@ -695,6 +744,19 @@ void rpc_force_rebind(struct rpc_clnt *clnt)
695EXPORT_SYMBOL_GPL(rpc_force_rebind); 744EXPORT_SYMBOL_GPL(rpc_force_rebind);
696 745
697/* 746/*
747 * Restart an (async) RPC call from the call_prepare state.
748 * Usually called from within the exit handler.
749 */
750void
751rpc_restart_call_prepare(struct rpc_task *task)
752{
753 if (RPC_ASSASSINATED(task))
754 return;
755 task->tk_action = rpc_prepare_task;
756}
757EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
758
759/*
698 * Restart an (async) RPC call. Usually called from within the 760 * Restart an (async) RPC call. Usually called from within the
699 * exit handler. 761 * exit handler.
700 */ 762 */
@@ -1085,7 +1147,7 @@ call_transmit(struct rpc_task *task)
1085 * in order to allow access to the socket to other RPC requests. 1147 * in order to allow access to the socket to other RPC requests.
1086 */ 1148 */
1087 call_transmit_status(task); 1149 call_transmit_status(task);
1088 if (task->tk_msg.rpc_proc->p_decode != NULL) 1150 if (rpc_reply_expected(task))
1089 return; 1151 return;
1090 task->tk_action = rpc_exit_task; 1152 task->tk_action = rpc_exit_task;
1091 rpc_wake_up_queued_task(&task->tk_xprt->pending, task); 1153 rpc_wake_up_queued_task(&task->tk_xprt->pending, task);
@@ -1120,6 +1182,72 @@ call_transmit_status(struct rpc_task *task)
1120 } 1182 }
1121} 1183}
1122 1184
1185#if defined(CONFIG_NFS_V4_1)
1186/*
1187 * 5b. Send the backchannel RPC reply. On error, drop the reply. In
1188 * addition, disconnect on connectivity errors.
1189 */
1190static void
1191call_bc_transmit(struct rpc_task *task)
1192{
1193 struct rpc_rqst *req = task->tk_rqstp;
1194
1195 BUG_ON(task->tk_status != 0);
1196 task->tk_status = xprt_prepare_transmit(task);
1197 if (task->tk_status == -EAGAIN) {
1198 /*
1199 * Could not reserve the transport. Try again after the
1200 * transport is released.
1201 */
1202 task->tk_status = 0;
1203 task->tk_action = call_bc_transmit;
1204 return;
1205 }
1206
1207 task->tk_action = rpc_exit_task;
1208 if (task->tk_status < 0) {
1209 printk(KERN_NOTICE "RPC: Could not send backchannel reply "
1210 "error: %d\n", task->tk_status);
1211 return;
1212 }
1213
1214 xprt_transmit(task);
1215 xprt_end_transmit(task);
1216 dprint_status(task);
1217 switch (task->tk_status) {
1218 case 0:
1219 /* Success */
1220 break;
1221 case -EHOSTDOWN:
1222 case -EHOSTUNREACH:
1223 case -ENETUNREACH:
1224 case -ETIMEDOUT:
1225 /*
1226 * Problem reaching the server. Disconnect and let the
1227 * forechannel reestablish the connection. The server will
1228 * have to retransmit the backchannel request and we'll
1229 * reprocess it. Since these ops are idempotent, there's no
1230 * need to cache our reply at this time.
1231 */
1232 printk(KERN_NOTICE "RPC: Could not send backchannel reply "
1233 "error: %d\n", task->tk_status);
1234 xprt_conditional_disconnect(task->tk_xprt,
1235 req->rq_connect_cookie);
1236 break;
1237 default:
1238 /*
1239 * We were unable to reply and will have to drop the
1240 * request. The server should reconnect and retransmit.
1241 */
1242 BUG_ON(task->tk_status == -EAGAIN);
1243 printk(KERN_NOTICE "RPC: Could not send backchannel reply "
1244 "error: %d\n", task->tk_status);
1245 break;
1246 }
1247 rpc_wake_up_queued_task(&req->rq_xprt->pending, task);
1248}
1249#endif /* CONFIG_NFS_V4_1 */
1250
1123/* 1251/*
1124 * 6. Sort out the RPC call status 1252 * 6. Sort out the RPC call status
1125 */ 1253 */
@@ -1130,8 +1258,8 @@ call_status(struct rpc_task *task)
1130 struct rpc_rqst *req = task->tk_rqstp; 1258 struct rpc_rqst *req = task->tk_rqstp;
1131 int status; 1259 int status;
1132 1260
1133 if (req->rq_received > 0 && !req->rq_bytes_sent) 1261 if (req->rq_reply_bytes_recvd > 0 && !req->rq_bytes_sent)
1134 task->tk_status = req->rq_received; 1262 task->tk_status = req->rq_reply_bytes_recvd;
1135 1263
1136 dprint_status(task); 1264 dprint_status(task);
1137 1265
@@ -1248,7 +1376,7 @@ call_decode(struct rpc_task *task)
1248 1376
1249 /* 1377 /*
1250 * Ensure that we see all writes made by xprt_complete_rqst() 1378 * Ensure that we see all writes made by xprt_complete_rqst()
1251 * before it changed req->rq_received. 1379 * before it changed req->rq_reply_bytes_recvd.
1252 */ 1380 */
1253 smp_rmb(); 1381 smp_rmb();
1254 req->rq_rcv_buf.len = req->rq_private_buf.len; 1382 req->rq_rcv_buf.len = req->rq_private_buf.len;
@@ -1289,7 +1417,7 @@ out_retry:
1289 task->tk_status = 0; 1417 task->tk_status = 0;
1290 /* Note: rpc_verify_header() may have freed the RPC slot */ 1418 /* Note: rpc_verify_header() may have freed the RPC slot */
1291 if (task->tk_rqstp == req) { 1419 if (task->tk_rqstp == req) {
1292 req->rq_received = req->rq_rcv_buf.len = 0; 1420 req->rq_reply_bytes_recvd = req->rq_rcv_buf.len = 0;
1293 if (task->tk_client->cl_discrtry) 1421 if (task->tk_client->cl_discrtry)
1294 xprt_conditional_disconnect(task->tk_xprt, 1422 xprt_conditional_disconnect(task->tk_xprt,
1295 req->rq_connect_cookie); 1423 req->rq_connect_cookie);
@@ -1377,13 +1505,14 @@ rpc_verify_header(struct rpc_task *task)
1377 } 1505 }
1378 if ((len -= 3) < 0) 1506 if ((len -= 3) < 0)
1379 goto out_overflow; 1507 goto out_overflow;
1380 p += 1; /* skip XID */
1381 1508
1509 p += 1; /* skip XID */
1382 if ((n = ntohl(*p++)) != RPC_REPLY) { 1510 if ((n = ntohl(*p++)) != RPC_REPLY) {
1383 dprintk("RPC: %5u %s: not an RPC reply: %x\n", 1511 dprintk("RPC: %5u %s: not an RPC reply: %x\n",
1384 task->tk_pid, __func__, n); 1512 task->tk_pid, __func__, n);
1385 goto out_garbage; 1513 goto out_garbage;
1386 } 1514 }
1515
1387 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { 1516 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
1388 if (--len < 0) 1517 if (--len < 0)
1389 goto out_overflow; 1518 goto out_overflow;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index ff50a0546865..1102ce1251f7 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -569,7 +569,7 @@ EXPORT_SYMBOL_GPL(rpc_delay);
569/* 569/*
570 * Helper to call task->tk_ops->rpc_call_prepare 570 * Helper to call task->tk_ops->rpc_call_prepare
571 */ 571 */
572static void rpc_prepare_task(struct rpc_task *task) 572void rpc_prepare_task(struct rpc_task *task)
573{ 573{
574 task->tk_ops->rpc_call_prepare(task, task->tk_calldata); 574 task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
575} 575}
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 1ef6e46d9da2..1b4e6791ecf3 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -141,12 +141,14 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
141void rpc_count_iostats(struct rpc_task *task) 141void rpc_count_iostats(struct rpc_task *task)
142{ 142{
143 struct rpc_rqst *req = task->tk_rqstp; 143 struct rpc_rqst *req = task->tk_rqstp;
144 struct rpc_iostats *stats = task->tk_client->cl_metrics; 144 struct rpc_iostats *stats;
145 struct rpc_iostats *op_metrics; 145 struct rpc_iostats *op_metrics;
146 long rtt, execute, queue; 146 long rtt, execute, queue;
147 147
148 if (!stats || !req) 148 if (!task->tk_client || !task->tk_client->cl_metrics || !req)
149 return; 149 return;
150
151 stats = task->tk_client->cl_metrics;
150 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; 152 op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
151 153
152 op_metrics->om_ops++; 154 op_metrics->om_ops++;
@@ -154,7 +156,7 @@ void rpc_count_iostats(struct rpc_task *task)
154 op_metrics->om_timeouts += task->tk_timeouts; 156 op_metrics->om_timeouts += task->tk_timeouts;
155 157
156 op_metrics->om_bytes_sent += task->tk_bytes_sent; 158 op_metrics->om_bytes_sent += task->tk_bytes_sent;
157 op_metrics->om_bytes_recv += req->rq_received; 159 op_metrics->om_bytes_recv += req->rq_reply_bytes_recvd;
158 160
159 queue = (long)req->rq_xtime - task->tk_start; 161 queue = (long)req->rq_xtime - task->tk_start;
160 if (queue < 0) 162 if (queue < 0)
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
new file mode 100644
index 000000000000..5d9dd742264b
--- /dev/null
+++ b/net/sunrpc/sunrpc.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2
3(c) 2008 NetApp. All Rights Reserved.
4
5NetApp provides this source code under the GPL v2 License.
6The GPL v2 license is available at
7http://opensource.org/licenses/gpl-license.php.
8
9THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
13CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20
21******************************************************************************/
22
23/*
24 * Functions and macros used internally by RPC
25 */
26
27#ifndef _NET_SUNRPC_SUNRPC_H
28#define _NET_SUNRPC_SUNRPC_H
29
30static inline int rpc_reply_expected(struct rpc_task *task)
31{
32 return (task->tk_msg.rpc_proc != NULL) &&
33 (task->tk_msg.rpc_proc->p_decode != NULL);
34}
35
36#endif /* _NET_SUNRPC_SUNRPC_H */
37
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 5ed8931dfe98..952f206ff307 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -25,6 +25,7 @@
25#include <linux/sunrpc/stats.h> 25#include <linux/sunrpc/stats.h>
26#include <linux/sunrpc/svcsock.h> 26#include <linux/sunrpc/svcsock.h>
27#include <linux/sunrpc/clnt.h> 27#include <linux/sunrpc/clnt.h>
28#include <linux/sunrpc/bc_xprt.h>
28 29
29#define RPCDBG_FACILITY RPCDBG_SVCDSP 30#define RPCDBG_FACILITY RPCDBG_SVCDSP
30 31
@@ -486,6 +487,10 @@ svc_destroy(struct svc_serv *serv)
486 if (svc_serv_is_pooled(serv)) 487 if (svc_serv_is_pooled(serv))
487 svc_pool_map_put(); 488 svc_pool_map_put();
488 489
490#if defined(CONFIG_NFS_V4_1)
491 svc_sock_destroy(serv->bc_xprt);
492#endif /* CONFIG_NFS_V4_1 */
493
489 svc_unregister(serv); 494 svc_unregister(serv);
490 kfree(serv->sv_pools); 495 kfree(serv->sv_pools);
491 kfree(serv); 496 kfree(serv);
@@ -970,20 +975,18 @@ svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
970} 975}
971 976
972/* 977/*
973 * Process the RPC request. 978 * Common routine for processing the RPC request.
974 */ 979 */
975int 980static int
976svc_process(struct svc_rqst *rqstp) 981svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
977{ 982{
978 struct svc_program *progp; 983 struct svc_program *progp;
979 struct svc_version *versp = NULL; /* compiler food */ 984 struct svc_version *versp = NULL; /* compiler food */
980 struct svc_procedure *procp = NULL; 985 struct svc_procedure *procp = NULL;
981 struct kvec * argv = &rqstp->rq_arg.head[0];
982 struct kvec * resv = &rqstp->rq_res.head[0];
983 struct svc_serv *serv = rqstp->rq_server; 986 struct svc_serv *serv = rqstp->rq_server;
984 kxdrproc_t xdr; 987 kxdrproc_t xdr;
985 __be32 *statp; 988 __be32 *statp;
986 u32 dir, prog, vers, proc; 989 u32 prog, vers, proc;
987 __be32 auth_stat, rpc_stat; 990 __be32 auth_stat, rpc_stat;
988 int auth_res; 991 int auth_res;
989 __be32 *reply_statp; 992 __be32 *reply_statp;
@@ -993,19 +996,6 @@ svc_process(struct svc_rqst *rqstp)
993 if (argv->iov_len < 6*4) 996 if (argv->iov_len < 6*4)
994 goto err_short_len; 997 goto err_short_len;
995 998
996 /* setup response xdr_buf.
997 * Initially it has just one page
998 */
999 rqstp->rq_resused = 1;
1000 resv->iov_base = page_address(rqstp->rq_respages[0]);
1001 resv->iov_len = 0;
1002 rqstp->rq_res.pages = rqstp->rq_respages + 1;
1003 rqstp->rq_res.len = 0;
1004 rqstp->rq_res.page_base = 0;
1005 rqstp->rq_res.page_len = 0;
1006 rqstp->rq_res.buflen = PAGE_SIZE;
1007 rqstp->rq_res.tail[0].iov_base = NULL;
1008 rqstp->rq_res.tail[0].iov_len = 0;
1009 /* Will be turned off only in gss privacy case: */ 999 /* Will be turned off only in gss privacy case: */
1010 rqstp->rq_splice_ok = 1; 1000 rqstp->rq_splice_ok = 1;
1011 /* Will be turned off only when NFSv4 Sessions are used */ 1001 /* Will be turned off only when NFSv4 Sessions are used */
@@ -1014,17 +1004,13 @@ svc_process(struct svc_rqst *rqstp)
1014 /* Setup reply header */ 1004 /* Setup reply header */
1015 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); 1005 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
1016 1006
1017 rqstp->rq_xid = svc_getu32(argv);
1018 svc_putu32(resv, rqstp->rq_xid); 1007 svc_putu32(resv, rqstp->rq_xid);
1019 1008
1020 dir = svc_getnl(argv);
1021 vers = svc_getnl(argv); 1009 vers = svc_getnl(argv);
1022 1010
1023 /* First words of reply: */ 1011 /* First words of reply: */
1024 svc_putnl(resv, 1); /* REPLY */ 1012 svc_putnl(resv, 1); /* REPLY */
1025 1013
1026 if (dir != 0) /* direction != CALL */
1027 goto err_bad_dir;
1028 if (vers != 2) /* RPC version number */ 1014 if (vers != 2) /* RPC version number */
1029 goto err_bad_rpc; 1015 goto err_bad_rpc;
1030 1016
@@ -1147,7 +1133,7 @@ svc_process(struct svc_rqst *rqstp)
1147 sendit: 1133 sendit:
1148 if (svc_authorise(rqstp)) 1134 if (svc_authorise(rqstp))
1149 goto dropit; 1135 goto dropit;
1150 return svc_send(rqstp); 1136 return 1; /* Caller can now send it */
1151 1137
1152 dropit: 1138 dropit:
1153 svc_authorise(rqstp); /* doesn't hurt to call this twice */ 1139 svc_authorise(rqstp); /* doesn't hurt to call this twice */
@@ -1161,12 +1147,6 @@ err_short_len:
1161 1147
1162 goto dropit; /* drop request */ 1148 goto dropit; /* drop request */
1163 1149
1164err_bad_dir:
1165 svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
1166
1167 serv->sv_stats->rpcbadfmt++;
1168 goto dropit; /* drop request */
1169
1170err_bad_rpc: 1150err_bad_rpc:
1171 serv->sv_stats->rpcbadfmt++; 1151 serv->sv_stats->rpcbadfmt++;
1172 svc_putnl(resv, 1); /* REJECT */ 1152 svc_putnl(resv, 1); /* REJECT */
@@ -1220,6 +1200,100 @@ err_bad:
1220EXPORT_SYMBOL_GPL(svc_process); 1200EXPORT_SYMBOL_GPL(svc_process);
1221 1201
1222/* 1202/*
1203 * Process the RPC request.
1204 */
1205int
1206svc_process(struct svc_rqst *rqstp)
1207{
1208 struct kvec *argv = &rqstp->rq_arg.head[0];
1209 struct kvec *resv = &rqstp->rq_res.head[0];
1210 struct svc_serv *serv = rqstp->rq_server;
1211 u32 dir;
1212 int error;
1213
1214 /*
1215 * Setup response xdr_buf.
1216 * Initially it has just one page
1217 */
1218 rqstp->rq_resused = 1;
1219 resv->iov_base = page_address(rqstp->rq_respages[0]);
1220 resv->iov_len = 0;
1221 rqstp->rq_res.pages = rqstp->rq_respages + 1;
1222 rqstp->rq_res.len = 0;
1223 rqstp->rq_res.page_base = 0;
1224 rqstp->rq_res.page_len = 0;
1225 rqstp->rq_res.buflen = PAGE_SIZE;
1226 rqstp->rq_res.tail[0].iov_base = NULL;
1227 rqstp->rq_res.tail[0].iov_len = 0;
1228
1229 rqstp->rq_xid = svc_getu32(argv);
1230
1231 dir = svc_getnl(argv);
1232 if (dir != 0) {
1233 /* direction != CALL */
1234 svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
1235 serv->sv_stats->rpcbadfmt++;
1236 svc_drop(rqstp);
1237 return 0;
1238 }
1239
1240 error = svc_process_common(rqstp, argv, resv);
1241 if (error <= 0)
1242 return error;
1243
1244 return svc_send(rqstp);
1245}
1246
1247#if defined(CONFIG_NFS_V4_1)
1248/*
1249 * Process a backchannel RPC request that arrived over an existing
1250 * outbound connection
1251 */
1252int
1253bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
1254 struct svc_rqst *rqstp)
1255{
1256 struct kvec *argv = &rqstp->rq_arg.head[0];
1257 struct kvec *resv = &rqstp->rq_res.head[0];
1258 int error;
1259
1260 /* Build the svc_rqst used by the common processing routine */
1261 rqstp->rq_xprt = serv->bc_xprt;
1262 rqstp->rq_xid = req->rq_xid;
1263 rqstp->rq_prot = req->rq_xprt->prot;
1264 rqstp->rq_server = serv;
1265
1266 rqstp->rq_addrlen = sizeof(req->rq_xprt->addr);
1267 memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
1268 memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg));
1269 memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res));
1270
1271 /* reset result send buffer "put" position */
1272 resv->iov_len = 0;
1273
1274 if (rqstp->rq_prot != IPPROTO_TCP) {
1275 printk(KERN_ERR "No support for Non-TCP transports!\n");
1276 BUG();
1277 }
1278
1279 /*
1280 * Skip the next two words because they've already been
1281 * processed in the trasport
1282 */
1283 svc_getu32(argv); /* XID */
1284 svc_getnl(argv); /* CALLDIR */
1285
1286 error = svc_process_common(rqstp, argv, resv);
1287 if (error <= 0)
1288 return error;
1289
1290 memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf));
1291 return bc_send(req);
1292}
1293EXPORT_SYMBOL(bc_svc_process);
1294#endif /* CONFIG_NFS_V4_1 */
1295
1296/*
1223 * Return (transport-specific) limit on the rpc payload. 1297 * Return (transport-specific) limit on the rpc payload.
1224 */ 1298 */
1225u32 svc_max_payload(const struct svc_rqst *rqstp) 1299u32 svc_max_payload(const struct svc_rqst *rqstp)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 9d504234af4a..a2a03e500533 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1327,3 +1327,42 @@ static void svc_sock_free(struct svc_xprt *xprt)
1327 sock_release(svsk->sk_sock); 1327 sock_release(svsk->sk_sock);
1328 kfree(svsk); 1328 kfree(svsk);
1329} 1329}
1330
1331/*
1332 * Create a svc_xprt.
1333 *
1334 * For internal use only (e.g. nfsv4.1 backchannel).
1335 * Callers should typically use the xpo_create() method.
1336 */
1337struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot)
1338{
1339 struct svc_sock *svsk;
1340 struct svc_xprt *xprt = NULL;
1341
1342 dprintk("svc: %s\n", __func__);
1343 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
1344 if (!svsk)
1345 goto out;
1346
1347 xprt = &svsk->sk_xprt;
1348 if (prot == IPPROTO_TCP)
1349 svc_xprt_init(&svc_tcp_class, xprt, serv);
1350 else if (prot == IPPROTO_UDP)
1351 svc_xprt_init(&svc_udp_class, xprt, serv);
1352 else
1353 BUG();
1354out:
1355 dprintk("svc: %s return %p\n", __func__, xprt);
1356 return xprt;
1357}
1358EXPORT_SYMBOL_GPL(svc_sock_create);
1359
1360/*
1361 * Destroy a svc_sock.
1362 */
1363void svc_sock_destroy(struct svc_xprt *xprt)
1364{
1365 if (xprt)
1366 kfree(container_of(xprt, struct svc_sock, sk_xprt));
1367}
1368EXPORT_SYMBOL_GPL(svc_sock_destroy);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 06ca058572f2..f412a852bc73 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -12,8 +12,9 @@
12 * - Next, the caller puts together the RPC message, stuffs it into 12 * - Next, the caller puts together the RPC message, stuffs it into
13 * the request struct, and calls xprt_transmit(). 13 * the request struct, and calls xprt_transmit().
14 * - xprt_transmit sends the message and installs the caller on the 14 * - xprt_transmit sends the message and installs the caller on the
15 * transport's wait list. At the same time, it installs a timer that 15 * transport's wait list. At the same time, if a reply is expected,
16 * is run after the packet's timeout has expired. 16 * it installs a timer that is run after the packet's timeout has
17 * expired.
17 * - When a packet arrives, the data_ready handler walks the list of 18 * - When a packet arrives, the data_ready handler walks the list of
18 * pending requests for that transport. If a matching XID is found, the 19 * pending requests for that transport. If a matching XID is found, the
19 * caller is woken up, and the timer removed. 20 * caller is woken up, and the timer removed.
@@ -46,6 +47,8 @@
46#include <linux/sunrpc/clnt.h> 47#include <linux/sunrpc/clnt.h>
47#include <linux/sunrpc/metrics.h> 48#include <linux/sunrpc/metrics.h>
48 49
50#include "sunrpc.h"
51
49/* 52/*
50 * Local variables 53 * Local variables
51 */ 54 */
@@ -192,8 +195,8 @@ EXPORT_SYMBOL_GPL(xprt_load_transport);
192 */ 195 */
193int xprt_reserve_xprt(struct rpc_task *task) 196int xprt_reserve_xprt(struct rpc_task *task)
194{ 197{
195 struct rpc_xprt *xprt = task->tk_xprt;
196 struct rpc_rqst *req = task->tk_rqstp; 198 struct rpc_rqst *req = task->tk_rqstp;
199 struct rpc_xprt *xprt = req->rq_xprt;
197 200
198 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { 201 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
199 if (task == xprt->snd_task) 202 if (task == xprt->snd_task)
@@ -803,9 +806,10 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
803 806
804 list_del_init(&req->rq_list); 807 list_del_init(&req->rq_list);
805 req->rq_private_buf.len = copied; 808 req->rq_private_buf.len = copied;
806 /* Ensure all writes are done before we update req->rq_received */ 809 /* Ensure all writes are done before we update */
810 /* req->rq_reply_bytes_recvd */
807 smp_wmb(); 811 smp_wmb();
808 req->rq_received = copied; 812 req->rq_reply_bytes_recvd = copied;
809 rpc_wake_up_queued_task(&xprt->pending, task); 813 rpc_wake_up_queued_task(&xprt->pending, task);
810} 814}
811EXPORT_SYMBOL_GPL(xprt_complete_rqst); 815EXPORT_SYMBOL_GPL(xprt_complete_rqst);
@@ -820,7 +824,7 @@ static void xprt_timer(struct rpc_task *task)
820 dprintk("RPC: %5u xprt_timer\n", task->tk_pid); 824 dprintk("RPC: %5u xprt_timer\n", task->tk_pid);
821 825
822 spin_lock_bh(&xprt->transport_lock); 826 spin_lock_bh(&xprt->transport_lock);
823 if (!req->rq_received) { 827 if (!req->rq_reply_bytes_recvd) {
824 if (xprt->ops->timer) 828 if (xprt->ops->timer)
825 xprt->ops->timer(task); 829 xprt->ops->timer(task);
826 } else 830 } else
@@ -842,8 +846,8 @@ int xprt_prepare_transmit(struct rpc_task *task)
842 dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid); 846 dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid);
843 847
844 spin_lock_bh(&xprt->transport_lock); 848 spin_lock_bh(&xprt->transport_lock);
845 if (req->rq_received && !req->rq_bytes_sent) { 849 if (req->rq_reply_bytes_recvd && !req->rq_bytes_sent) {
846 err = req->rq_received; 850 err = req->rq_reply_bytes_recvd;
847 goto out_unlock; 851 goto out_unlock;
848 } 852 }
849 if (!xprt->ops->reserve_xprt(task)) 853 if (!xprt->ops->reserve_xprt(task))
@@ -855,7 +859,7 @@ out_unlock:
855 859
856void xprt_end_transmit(struct rpc_task *task) 860void xprt_end_transmit(struct rpc_task *task)
857{ 861{
858 xprt_release_write(task->tk_xprt, task); 862 xprt_release_write(task->tk_rqstp->rq_xprt, task);
859} 863}
860 864
861/** 865/**
@@ -872,8 +876,11 @@ void xprt_transmit(struct rpc_task *task)
872 876
873 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); 877 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
874 878
875 if (!req->rq_received) { 879 if (!req->rq_reply_bytes_recvd) {
876 if (list_empty(&req->rq_list)) { 880 if (list_empty(&req->rq_list) && rpc_reply_expected(task)) {
881 /*
882 * Add to the list only if we're expecting a reply
883 */
877 spin_lock_bh(&xprt->transport_lock); 884 spin_lock_bh(&xprt->transport_lock);
878 /* Update the softirq receive buffer */ 885 /* Update the softirq receive buffer */
879 memcpy(&req->rq_private_buf, &req->rq_rcv_buf, 886 memcpy(&req->rq_private_buf, &req->rq_rcv_buf,
@@ -908,8 +915,13 @@ void xprt_transmit(struct rpc_task *task)
908 /* Don't race with disconnect */ 915 /* Don't race with disconnect */
909 if (!xprt_connected(xprt)) 916 if (!xprt_connected(xprt))
910 task->tk_status = -ENOTCONN; 917 task->tk_status = -ENOTCONN;
911 else if (!req->rq_received) 918 else if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) {
919 /*
920 * Sleep on the pending queue since
921 * we're expecting a reply.
922 */
912 rpc_sleep_on(&xprt->pending, task, xprt_timer); 923 rpc_sleep_on(&xprt->pending, task, xprt_timer);
924 }
913 spin_unlock_bh(&xprt->transport_lock); 925 spin_unlock_bh(&xprt->transport_lock);
914} 926}
915 927
@@ -982,11 +994,17 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
982 */ 994 */
983void xprt_release(struct rpc_task *task) 995void xprt_release(struct rpc_task *task)
984{ 996{
985 struct rpc_xprt *xprt = task->tk_xprt; 997 struct rpc_xprt *xprt;
986 struct rpc_rqst *req; 998 struct rpc_rqst *req;
999 int is_bc_request;
987 1000
988 if (!(req = task->tk_rqstp)) 1001 if (!(req = task->tk_rqstp))
989 return; 1002 return;
1003
1004 /* Preallocated backchannel request? */
1005 is_bc_request = bc_prealloc(req);
1006
1007 xprt = req->rq_xprt;
990 rpc_count_iostats(task); 1008 rpc_count_iostats(task);
991 spin_lock_bh(&xprt->transport_lock); 1009 spin_lock_bh(&xprt->transport_lock);
992 xprt->ops->release_xprt(xprt, task); 1010 xprt->ops->release_xprt(xprt, task);
@@ -999,10 +1017,19 @@ void xprt_release(struct rpc_task *task)
999 mod_timer(&xprt->timer, 1017 mod_timer(&xprt->timer,
1000 xprt->last_used + xprt->idle_timeout); 1018 xprt->last_used + xprt->idle_timeout);
1001 spin_unlock_bh(&xprt->transport_lock); 1019 spin_unlock_bh(&xprt->transport_lock);
1002 xprt->ops->buf_free(req->rq_buffer); 1020 if (!bc_prealloc(req))
1021 xprt->ops->buf_free(req->rq_buffer);
1003 task->tk_rqstp = NULL; 1022 task->tk_rqstp = NULL;
1004 if (req->rq_release_snd_buf) 1023 if (req->rq_release_snd_buf)
1005 req->rq_release_snd_buf(req); 1024 req->rq_release_snd_buf(req);
1025
1026 /*
1027 * Early exit if this is a backchannel preallocated request.
1028 * There is no need to have it added to the RPC slot list.
1029 */
1030 if (is_bc_request)
1031 return;
1032
1006 memset(req, 0, sizeof(*req)); /* mark unused */ 1033 memset(req, 0, sizeof(*req)); /* mark unused */
1007 1034
1008 dprintk("RPC: %5u release request %p\n", task->tk_pid, req); 1035 dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
@@ -1049,6 +1076,11 @@ found:
1049 1076
1050 INIT_LIST_HEAD(&xprt->free); 1077 INIT_LIST_HEAD(&xprt->free);
1051 INIT_LIST_HEAD(&xprt->recv); 1078 INIT_LIST_HEAD(&xprt->recv);
1079#if defined(CONFIG_NFS_V4_1)
1080 spin_lock_init(&xprt->bc_pa_lock);
1081 INIT_LIST_HEAD(&xprt->bc_pa_list);
1082#endif /* CONFIG_NFS_V4_1 */
1083
1052 INIT_WORK(&xprt->task_cleanup, xprt_autoclose); 1084 INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
1053 setup_timer(&xprt->timer, xprt_init_autodisconnect, 1085 setup_timer(&xprt->timer, xprt_init_autodisconnect,
1054 (unsigned long)xprt); 1086 (unsigned long)xprt);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 6c2d61586551..83c73c4d017a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -34,6 +34,9 @@
34#include <linux/sunrpc/sched.h> 34#include <linux/sunrpc/sched.h>
35#include <linux/sunrpc/xprtsock.h> 35#include <linux/sunrpc/xprtsock.h>
36#include <linux/file.h> 36#include <linux/file.h>
37#ifdef CONFIG_NFS_V4_1
38#include <linux/sunrpc/bc_xprt.h>
39#endif
37 40
38#include <net/sock.h> 41#include <net/sock.h>
39#include <net/checksum.h> 42#include <net/checksum.h>
@@ -270,6 +273,13 @@ struct sock_xprt {
270#define TCP_RCV_COPY_FRAGHDR (1UL << 1) 273#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
271#define TCP_RCV_COPY_XID (1UL << 2) 274#define TCP_RCV_COPY_XID (1UL << 2)
272#define TCP_RCV_COPY_DATA (1UL << 3) 275#define TCP_RCV_COPY_DATA (1UL << 3)
276#define TCP_RCV_READ_CALLDIR (1UL << 4)
277#define TCP_RCV_COPY_CALLDIR (1UL << 5)
278
279/*
280 * TCP RPC flags
281 */
282#define TCP_RPC_REPLY (1UL << 6)
273 283
274static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) 284static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
275{ 285{
@@ -956,7 +966,7 @@ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_rea
956 transport->tcp_offset = 0; 966 transport->tcp_offset = 0;
957 967
958 /* Sanity check of the record length */ 968 /* Sanity check of the record length */
959 if (unlikely(transport->tcp_reclen < 4)) { 969 if (unlikely(transport->tcp_reclen < 8)) {
960 dprintk("RPC: invalid TCP record fragment length\n"); 970 dprintk("RPC: invalid TCP record fragment length\n");
961 xprt_force_disconnect(xprt); 971 xprt_force_disconnect(xprt);
962 return; 972 return;
@@ -991,33 +1001,77 @@ static inline void xs_tcp_read_xid(struct sock_xprt *transport, struct xdr_skb_r
991 if (used != len) 1001 if (used != len)
992 return; 1002 return;
993 transport->tcp_flags &= ~TCP_RCV_COPY_XID; 1003 transport->tcp_flags &= ~TCP_RCV_COPY_XID;
994 transport->tcp_flags |= TCP_RCV_COPY_DATA; 1004 transport->tcp_flags |= TCP_RCV_READ_CALLDIR;
995 transport->tcp_copied = 4; 1005 transport->tcp_copied = 4;
996 dprintk("RPC: reading reply for XID %08x\n", 1006 dprintk("RPC: reading %s XID %08x\n",
1007 (transport->tcp_flags & TCP_RPC_REPLY) ? "reply for"
1008 : "request with",
997 ntohl(transport->tcp_xid)); 1009 ntohl(transport->tcp_xid));
998 xs_tcp_check_fraghdr(transport); 1010 xs_tcp_check_fraghdr(transport);
999} 1011}
1000 1012
1001static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) 1013static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
1014 struct xdr_skb_reader *desc)
1002{ 1015{
1003 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 1016 size_t len, used;
1004 struct rpc_rqst *req; 1017 u32 offset;
1018 __be32 calldir;
1019
1020 /*
1021 * We want transport->tcp_offset to be 8 at the end of this routine
1022 * (4 bytes for the xid and 4 bytes for the call/reply flag).
1023 * When this function is called for the first time,
1024 * transport->tcp_offset is 4 (after having already read the xid).
1025 */
1026 offset = transport->tcp_offset - sizeof(transport->tcp_xid);
1027 len = sizeof(calldir) - offset;
1028 dprintk("RPC: reading CALL/REPLY flag (%Zu bytes)\n", len);
1029 used = xdr_skb_read_bits(desc, &calldir, len);
1030 transport->tcp_offset += used;
1031 if (used != len)
1032 return;
1033 transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR;
1034 transport->tcp_flags |= TCP_RCV_COPY_CALLDIR;
1035 transport->tcp_flags |= TCP_RCV_COPY_DATA;
1036 /*
1037 * We don't yet have the XDR buffer, so we will write the calldir
1038 * out after we get the buffer from the 'struct rpc_rqst'
1039 */
1040 if (ntohl(calldir) == RPC_REPLY)
1041 transport->tcp_flags |= TCP_RPC_REPLY;
1042 else
1043 transport->tcp_flags &= ~TCP_RPC_REPLY;
1044 dprintk("RPC: reading %s CALL/REPLY flag %08x\n",
1045 (transport->tcp_flags & TCP_RPC_REPLY) ?
1046 "reply for" : "request with", calldir);
1047 xs_tcp_check_fraghdr(transport);
1048}
1049
1050static inline void xs_tcp_read_common(struct rpc_xprt *xprt,
1051 struct xdr_skb_reader *desc,
1052 struct rpc_rqst *req)
1053{
1054 struct sock_xprt *transport =
1055 container_of(xprt, struct sock_xprt, xprt);
1005 struct xdr_buf *rcvbuf; 1056 struct xdr_buf *rcvbuf;
1006 size_t len; 1057 size_t len;
1007 ssize_t r; 1058 ssize_t r;
1008 1059
1009 /* Find and lock the request corresponding to this xid */ 1060 rcvbuf = &req->rq_private_buf;
1010 spin_lock(&xprt->transport_lock); 1061
1011 req = xprt_lookup_rqst(xprt, transport->tcp_xid); 1062 if (transport->tcp_flags & TCP_RCV_COPY_CALLDIR) {
1012 if (!req) { 1063 /*
1013 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1064 * Save the RPC direction in the XDR buffer
1014 dprintk("RPC: XID %08x request not found!\n", 1065 */
1015 ntohl(transport->tcp_xid)); 1066 __be32 calldir = transport->tcp_flags & TCP_RPC_REPLY ?
1016 spin_unlock(&xprt->transport_lock); 1067 htonl(RPC_REPLY) : 0;
1017 return; 1068
1069 memcpy(rcvbuf->head[0].iov_base + transport->tcp_copied,
1070 &calldir, sizeof(calldir));
1071 transport->tcp_copied += sizeof(calldir);
1072 transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR;
1018 } 1073 }
1019 1074
1020 rcvbuf = &req->rq_private_buf;
1021 len = desc->count; 1075 len = desc->count;
1022 if (len > transport->tcp_reclen - transport->tcp_offset) { 1076 if (len > transport->tcp_reclen - transport->tcp_offset) {
1023 struct xdr_skb_reader my_desc; 1077 struct xdr_skb_reader my_desc;
@@ -1054,7 +1108,7 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_rea
1054 "tcp_offset = %u, tcp_reclen = %u\n", 1108 "tcp_offset = %u, tcp_reclen = %u\n",
1055 xprt, transport->tcp_copied, 1109 xprt, transport->tcp_copied,
1056 transport->tcp_offset, transport->tcp_reclen); 1110 transport->tcp_offset, transport->tcp_reclen);
1057 goto out; 1111 return;
1058 } 1112 }
1059 1113
1060 dprintk("RPC: XID %08x read %Zd bytes\n", 1114 dprintk("RPC: XID %08x read %Zd bytes\n",
@@ -1070,11 +1124,125 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_rea
1070 transport->tcp_flags &= ~TCP_RCV_COPY_DATA; 1124 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
1071 } 1125 }
1072 1126
1073out: 1127 return;
1128}
1129
1130/*
1131 * Finds the request corresponding to the RPC xid and invokes the common
1132 * tcp read code to read the data.
1133 */
1134static inline int xs_tcp_read_reply(struct rpc_xprt *xprt,
1135 struct xdr_skb_reader *desc)
1136{
1137 struct sock_xprt *transport =
1138 container_of(xprt, struct sock_xprt, xprt);
1139 struct rpc_rqst *req;
1140
1141 dprintk("RPC: read reply XID %08x\n", ntohl(transport->tcp_xid));
1142
1143 /* Find and lock the request corresponding to this xid */
1144 spin_lock(&xprt->transport_lock);
1145 req = xprt_lookup_rqst(xprt, transport->tcp_xid);
1146 if (!req) {
1147 dprintk("RPC: XID %08x request not found!\n",
1148 ntohl(transport->tcp_xid));
1149 spin_unlock(&xprt->transport_lock);
1150 return -1;
1151 }
1152
1153 xs_tcp_read_common(xprt, desc, req);
1154
1074 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) 1155 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA))
1075 xprt_complete_rqst(req->rq_task, transport->tcp_copied); 1156 xprt_complete_rqst(req->rq_task, transport->tcp_copied);
1157
1076 spin_unlock(&xprt->transport_lock); 1158 spin_unlock(&xprt->transport_lock);
1077 xs_tcp_check_fraghdr(transport); 1159 return 0;
1160}
1161
1162#if defined(CONFIG_NFS_V4_1)
1163/*
1164 * Obtains an rpc_rqst previously allocated and invokes the common
1165 * tcp read code to read the data. The result is placed in the callback
1166 * queue.
1167 * If we're unable to obtain the rpc_rqst we schedule the closing of the
1168 * connection and return -1.
1169 */
1170static inline int xs_tcp_read_callback(struct rpc_xprt *xprt,
1171 struct xdr_skb_reader *desc)
1172{
1173 struct sock_xprt *transport =
1174 container_of(xprt, struct sock_xprt, xprt);
1175 struct rpc_rqst *req;
1176
1177 req = xprt_alloc_bc_request(xprt);
1178 if (req == NULL) {
1179 printk(KERN_WARNING "Callback slot table overflowed\n");
1180 xprt_force_disconnect(xprt);
1181 return -1;
1182 }
1183
1184 req->rq_xid = transport->tcp_xid;
1185 dprintk("RPC: read callback XID %08x\n", ntohl(req->rq_xid));
1186 xs_tcp_read_common(xprt, desc, req);
1187
1188 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA)) {
1189 struct svc_serv *bc_serv = xprt->bc_serv;
1190
1191 /*
1192 * Add callback request to callback list. The callback
1193 * service sleeps on the sv_cb_waitq waiting for new
1194 * requests. Wake it up after adding enqueing the
1195 * request.
1196 */
1197 dprintk("RPC: add callback request to list\n");
1198 spin_lock(&bc_serv->sv_cb_lock);
1199 list_add(&req->rq_bc_list, &bc_serv->sv_cb_list);
1200 spin_unlock(&bc_serv->sv_cb_lock);
1201 wake_up(&bc_serv->sv_cb_waitq);
1202 }
1203
1204 req->rq_private_buf.len = transport->tcp_copied;
1205
1206 return 0;
1207}
1208
1209static inline int _xs_tcp_read_data(struct rpc_xprt *xprt,
1210 struct xdr_skb_reader *desc)
1211{
1212 struct sock_xprt *transport =
1213 container_of(xprt, struct sock_xprt, xprt);
1214
1215 return (transport->tcp_flags & TCP_RPC_REPLY) ?
1216 xs_tcp_read_reply(xprt, desc) :
1217 xs_tcp_read_callback(xprt, desc);
1218}
1219#else
1220static inline int _xs_tcp_read_data(struct rpc_xprt *xprt,
1221 struct xdr_skb_reader *desc)
1222{
1223 return xs_tcp_read_reply(xprt, desc);
1224}
1225#endif /* CONFIG_NFS_V4_1 */
1226
1227/*
1228 * Read data off the transport. This can be either an RPC_CALL or an
1229 * RPC_REPLY. Relay the processing to helper functions.
1230 */
1231static void xs_tcp_read_data(struct rpc_xprt *xprt,
1232 struct xdr_skb_reader *desc)
1233{
1234 struct sock_xprt *transport =
1235 container_of(xprt, struct sock_xprt, xprt);
1236
1237 if (_xs_tcp_read_data(xprt, desc) == 0)
1238 xs_tcp_check_fraghdr(transport);
1239 else {
1240 /*
1241 * The transport_lock protects the request handling.
1242 * There's no need to hold it to update the tcp_flags.
1243 */
1244 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
1245 }
1078} 1246}
1079 1247
1080static inline void xs_tcp_read_discard(struct sock_xprt *transport, struct xdr_skb_reader *desc) 1248static inline void xs_tcp_read_discard(struct sock_xprt *transport, struct xdr_skb_reader *desc)
@@ -1114,9 +1282,14 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns
1114 xs_tcp_read_xid(transport, &desc); 1282 xs_tcp_read_xid(transport, &desc);
1115 continue; 1283 continue;
1116 } 1284 }
1285 /* Read in the call/reply flag */
1286 if (transport->tcp_flags & TCP_RCV_READ_CALLDIR) {
1287 xs_tcp_read_calldir(transport, &desc);
1288 continue;
1289 }
1117 /* Read in the request data */ 1290 /* Read in the request data */
1118 if (transport->tcp_flags & TCP_RCV_COPY_DATA) { 1291 if (transport->tcp_flags & TCP_RCV_COPY_DATA) {
1119 xs_tcp_read_request(xprt, &desc); 1292 xs_tcp_read_data(xprt, &desc);
1120 continue; 1293 continue;
1121 } 1294 }
1122 /* Skip over any trailing bytes on short reads */ 1295 /* Skip over any trailing bytes on short reads */
@@ -1792,6 +1965,7 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
1792 */ 1965 */
1793 set_bit(XPRT_CONNECTION_CLOSE, &xprt->state); 1966 set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
1794 xprt_force_disconnect(xprt); 1967 xprt_force_disconnect(xprt);
1968 break;
1795 case -ECONNREFUSED: 1969 case -ECONNREFUSED:
1796 case -ECONNRESET: 1970 case -ECONNRESET:
1797 case -ENETUNREACH: 1971 case -ENETUNREACH:
@@ -2010,6 +2184,9 @@ static struct rpc_xprt_ops xs_tcp_ops = {
2010 .buf_free = rpc_free, 2184 .buf_free = rpc_free,
2011 .send_request = xs_tcp_send_request, 2185 .send_request = xs_tcp_send_request,
2012 .set_retrans_timeout = xprt_set_retrans_timeout_def, 2186 .set_retrans_timeout = xprt_set_retrans_timeout_def,
2187#if defined(CONFIG_NFS_V4_1)
2188 .release_request = bc_release_request,
2189#endif /* CONFIG_NFS_V4_1 */
2013 .close = xs_tcp_close, 2190 .close = xs_tcp_close,
2014 .destroy = xs_destroy, 2191 .destroy = xs_destroy,
2015 .print_stats = xs_tcp_print_stats, 2192 .print_stats = xs_tcp_print_stats,