aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 20:59:58 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 20:59:58 -0400
commit301933a0acfdec837fd8b4884093b3f0fff01d8a (patch)
tree1f2412a30d710493179b1b3743cf30302872df15 /fs/nfs
parent3fe0344faf7fdcb158bd5c1a9aec960a8d70c8e8 (diff)
parent68f3f90133d56e0c38f04f991e662c2b21592b31 (diff)
Merge commit 'linux-pnfs/nfs41-for-2.6.31' into nfsv41-for-2.6.31
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Kconfig9
-rw-r--r--fs/nfs/callback.c214
-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.c182
-rw-r--r--fs/nfs/direct.c9
-rw-r--r--fs/nfs/internal.h62
-rw-r--r--fs/nfs/nfs4_fs.h37
-rw-r--r--fs/nfs/nfs4proc.c1287
-rw-r--r--fs/nfs/nfs4renewd.c6
-rw-r--r--fs/nfs/nfs4state.c153
-rw-r--r--fs/nfs/nfs4xdr.c1072
-rw-r--r--fs/nfs/read.c33
-rw-r--r--fs/nfs/super.c13
-rw-r--r--fs/nfs/unlink.c20
-rw-r--r--fs/nfs/write.c31
17 files changed, 3307 insertions, 296 deletions
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..e69b8f61189e 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);
@@ -131,23 +127,168 @@ int nfs_callback_up(void)
131 goto out_err; 127 goto out_err;
132#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ 128#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
133 129
134 nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); 130 return svc_prepare_thread(serv, &serv->sv_pools[0]);
135 if (IS_ERR(nfs_callback_info.rqst)) { 131
136 ret = PTR_ERR(nfs_callback_info.rqst); 132out_err:
137 nfs_callback_info.rqst = NULL; 133 if (ret == 0)
134 ret = -ENOMEM;
135 return ERR_PTR(ret);
136}
137
138#if defined(CONFIG_NFS_V4_1)
139/*
140 * The callback service for NFSv4.1 callbacks
141 */
142static int
143nfs41_callback_svc(void *vrqstp)
144{
145 struct svc_rqst *rqstp = vrqstp;
146 struct svc_serv *serv = rqstp->rq_server;
147 struct rpc_rqst *req;
148 int error;
149 DEFINE_WAIT(wq);
150
151 set_freezable();
152
153 /*
154 * FIXME: do we really need to run this under the BKL? If so, please
155 * add a comment about what it's intended to protect.
156 */
157 lock_kernel();
158 while (!kthread_should_stop()) {
159 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
160 spin_lock_bh(&serv->sv_cb_lock);
161 if (!list_empty(&serv->sv_cb_list)) {
162 req = list_first_entry(&serv->sv_cb_list,
163 struct rpc_rqst, rq_bc_list);
164 list_del(&req->rq_bc_list);
165 spin_unlock_bh(&serv->sv_cb_lock);
166 dprintk("Invoking bc_svc_process()\n");
167 error = bc_svc_process(serv, req, rqstp);
168 dprintk("bc_svc_process() returned w/ error code= %d\n",
169 error);
170 } else {
171 spin_unlock_bh(&serv->sv_cb_lock);
172 schedule();
173 }
174 finish_wait(&serv->sv_cb_waitq, &wq);
175 }
176 unlock_kernel();
177 return 0;
178}
179
180/*
181 * Bring up the NFSv4.1 callback service
182 */
183struct svc_rqst *
184nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
185{
186 struct svc_xprt *bc_xprt;
187 struct svc_rqst *rqstp = ERR_PTR(-ENOMEM);
188
189 dprintk("--> %s\n", __func__);
190 /* Create a svc_sock for the service */
191 bc_xprt = svc_sock_create(serv, xprt->prot);
192 if (!bc_xprt)
193 goto out;
194
195 /*
196 * Save the svc_serv in the transport so that it can
197 * be referenced when the session backchannel is initialized
198 */
199 serv->bc_xprt = bc_xprt;
200 xprt->bc_serv = serv;
201
202 INIT_LIST_HEAD(&serv->sv_cb_list);
203 spin_lock_init(&serv->sv_cb_lock);
204 init_waitqueue_head(&serv->sv_cb_waitq);
205 rqstp = svc_prepare_thread(serv, &serv->sv_pools[0]);
206 if (IS_ERR(rqstp))
207 svc_sock_destroy(bc_xprt);
208out:
209 dprintk("--> %s return %p\n", __func__, rqstp);
210 return rqstp;
211}
212
213static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
214 struct svc_serv *serv, struct rpc_xprt *xprt,
215 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
216{
217 if (minorversion) {
218 *rqstpp = nfs41_callback_up(serv, xprt);
219 *callback_svc = nfs41_callback_svc;
220 }
221 return minorversion;
222}
223
224static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
225 struct nfs_callback_data *cb_info)
226{
227 if (minorversion)
228 xprt->bc_serv = cb_info->serv;
229}
230#else
231static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
232 struct svc_serv *serv, struct rpc_xprt *xprt,
233 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
234{
235 return 0;
236}
237
238static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
239 struct nfs_callback_data *cb_info)
240{
241}
242#endif /* CONFIG_NFS_V4_1 */
243
244/*
245 * Bring up the callback thread if it is not already up.
246 */
247int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
248{
249 struct svc_serv *serv = NULL;
250 struct svc_rqst *rqstp;
251 int (*callback_svc)(void *vrqstp);
252 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
253 char svc_name[12];
254 int ret = 0;
255 int minorversion_setup;
256
257 mutex_lock(&nfs_callback_mutex);
258 if (cb_info->users++ || cb_info->task != NULL) {
259 nfs_callback_bc_serv(minorversion, xprt, cb_info);
260 goto out;
261 }
262 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
263 if (!serv) {
264 ret = -ENOMEM;
265 goto out_err;
266 }
267
268 minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion,
269 serv, xprt, &rqstp, &callback_svc);
270 if (!minorversion_setup) {
271 /* v4.0 callback setup */
272 rqstp = nfs4_callback_up(serv);
273 callback_svc = nfs4_callback_svc;
274 }
275
276 if (IS_ERR(rqstp)) {
277 ret = PTR_ERR(rqstp);
138 goto out_err; 278 goto out_err;
139 } 279 }
140 280
141 svc_sock_update_bufs(serv); 281 svc_sock_update_bufs(serv);
142 282
143 nfs_callback_info.task = kthread_run(nfs_callback_svc, 283 sprintf(svc_name, "nfsv4.%u-svc", minorversion);
144 nfs_callback_info.rqst, 284 cb_info->serv = serv;
145 "nfsv4-svc"); 285 cb_info->rqst = rqstp;
146 if (IS_ERR(nfs_callback_info.task)) { 286 cb_info->task = kthread_run(callback_svc, cb_info->rqst, svc_name);
147 ret = PTR_ERR(nfs_callback_info.task); 287 if (IS_ERR(cb_info->task)) {
148 svc_exit_thread(nfs_callback_info.rqst); 288 ret = PTR_ERR(cb_info->task);
149 nfs_callback_info.rqst = NULL; 289 svc_exit_thread(cb_info->rqst);
150 nfs_callback_info.task = NULL; 290 cb_info->rqst = NULL;
291 cb_info->task = NULL;
151 goto out_err; 292 goto out_err;
152 } 293 }
153out: 294out:
@@ -164,22 +305,25 @@ out:
164out_err: 305out_err:
165 dprintk("NFS: Couldn't create callback socket or server thread; " 306 dprintk("NFS: Couldn't create callback socket or server thread; "
166 "err = %d\n", ret); 307 "err = %d\n", ret);
167 nfs_callback_info.users--; 308 cb_info->users--;
168 goto out; 309 goto out;
169} 310}
170 311
171/* 312/*
172 * Kill the callback thread if it's no longer being used. 313 * Kill the callback thread if it's no longer being used.
173 */ 314 */
174void nfs_callback_down(void) 315void nfs_callback_down(int minorversion)
175{ 316{
317 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
318
176 mutex_lock(&nfs_callback_mutex); 319 mutex_lock(&nfs_callback_mutex);
177 nfs_callback_info.users--; 320 cb_info->users--;
178 if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL) { 321 if (cb_info->users == 0 && cb_info->task != NULL) {
179 kthread_stop(nfs_callback_info.task); 322 kthread_stop(cb_info->task);
180 svc_exit_thread(nfs_callback_info.rqst); 323 svc_exit_thread(cb_info->rqst);
181 nfs_callback_info.rqst = NULL; 324 cb_info->serv = NULL;
182 nfs_callback_info.task = NULL; 325 cb_info->rqst = NULL;
326 cb_info->task = NULL;
183 } 327 }
184 mutex_unlock(&nfs_callback_mutex); 328 mutex_unlock(&nfs_callback_mutex);
185} 329}
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..4f75ec593be8 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/*
@@ -120,12 +122,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
120 122
121 clp->rpc_ops = cl_init->rpc_ops; 123 clp->rpc_ops = cl_init->rpc_ops;
122 124
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); 125 atomic_set(&clp->cl_count, 1);
130 clp->cl_cons_state = NFS_CS_INITING; 126 clp->cl_cons_state = NFS_CS_INITING;
131 127
@@ -135,7 +131,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
135 if (cl_init->hostname) { 131 if (cl_init->hostname) {
136 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL); 132 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
137 if (!clp->cl_hostname) 133 if (!clp->cl_hostname)
138 goto error_3; 134 goto error_cleanup;
139 } 135 }
140 136
141 INIT_LIST_HEAD(&clp->cl_superblocks); 137 INIT_LIST_HEAD(&clp->cl_superblocks);
@@ -150,6 +146,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
150 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); 146 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
151 clp->cl_boot_time = CURRENT_TIME; 147 clp->cl_boot_time = CURRENT_TIME;
152 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 148 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
149 clp->cl_minorversion = cl_init->minorversion;
153#endif 150#endif
154 cred = rpc_lookup_machine_cred(); 151 cred = rpc_lookup_machine_cred();
155 if (!IS_ERR(cred)) 152 if (!IS_ERR(cred))
@@ -159,10 +156,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
159 156
160 return clp; 157 return clp;
161 158
162error_3: 159error_cleanup:
163 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
164 nfs_callback_down();
165error_2:
166 kfree(clp); 160 kfree(clp);
167error_0: 161error_0:
168 return NULL; 162 return NULL;
@@ -182,12 +176,42 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
182} 176}
183 177
184/* 178/*
179 * Destroy the NFS4 callback service
180 */
181static void nfs4_destroy_callback(struct nfs_client *clp)
182{
183#ifdef CONFIG_NFS_V4
184 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
185 nfs_callback_down(clp->cl_minorversion);
186#endif /* CONFIG_NFS_V4 */
187}
188
189/*
190 * Clears/puts all minor version specific parts from an nfs_client struct
191 * reverting it to minorversion 0.
192 */
193static void nfs4_clear_client_minor_version(struct nfs_client *clp)
194{
195#ifdef CONFIG_NFS_V4_1
196 if (nfs4_has_session(clp)) {
197 nfs4_destroy_session(clp->cl_session);
198 clp->cl_session = NULL;
199 }
200
201 clp->cl_call_sync = _nfs4_call_sync;
202#endif /* CONFIG_NFS_V4_1 */
203
204 nfs4_destroy_callback(clp);
205}
206
207/*
185 * Destroy a shared client record 208 * Destroy a shared client record
186 */ 209 */
187static void nfs_free_client(struct nfs_client *clp) 210static void nfs_free_client(struct nfs_client *clp)
188{ 211{
189 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); 212 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
190 213
214 nfs4_clear_client_minor_version(clp);
191 nfs4_shutdown_client(clp); 215 nfs4_shutdown_client(clp);
192 216
193 nfs_fscache_release_client_cookie(clp); 217 nfs_fscache_release_client_cookie(clp);
@@ -196,9 +220,6 @@ static void nfs_free_client(struct nfs_client *clp)
196 if (!IS_ERR(clp->cl_rpcclient)) 220 if (!IS_ERR(clp->cl_rpcclient))
197 rpc_shutdown_client(clp->cl_rpcclient); 221 rpc_shutdown_client(clp->cl_rpcclient);
198 222
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) 223 if (clp->cl_machine_cred != NULL)
203 put_rpccred(clp->cl_machine_cred); 224 put_rpccred(clp->cl_machine_cred);
204 225
@@ -347,7 +368,8 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
347 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; 368 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
348 369
349 /* Don't match clients that failed to initialise properly */ 370 /* Don't match clients that failed to initialise properly */
350 if (clp->cl_cons_state != NFS_CS_READY) 371 if (!(clp->cl_cons_state == NFS_CS_READY ||
372 clp->cl_cons_state == NFS_CS_SESSION_INITING))
351 continue; 373 continue;
352 374
353 /* Different NFS versions cannot share the same nfs_client */ 375 /* Different NFS versions cannot share the same nfs_client */
@@ -420,7 +442,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
420 442
421 if (clp->cl_proto != data->proto) 443 if (clp->cl_proto != data->proto)
422 continue; 444 continue;
423 445 /* Match nfsv4 minorversion */
446 if (clp->cl_minorversion != data->minorversion)
447 continue;
424 /* Match the full socket address */ 448 /* Match the full socket address */
425 if (!nfs_sockaddr_cmp(sap, clap)) 449 if (!nfs_sockaddr_cmp(sap, clap))
426 continue; 450 continue;
@@ -478,7 +502,7 @@ found_client:
478 nfs_free_client(new); 502 nfs_free_client(new);
479 503
480 error = wait_event_killable(nfs_client_active_wq, 504 error = wait_event_killable(nfs_client_active_wq,
481 clp->cl_cons_state != NFS_CS_INITING); 505 clp->cl_cons_state < NFS_CS_INITING);
482 if (error < 0) { 506 if (error < 0) {
483 nfs_put_client(clp); 507 nfs_put_client(clp);
484 return ERR_PTR(-ERESTARTSYS); 508 return ERR_PTR(-ERESTARTSYS);
@@ -499,13 +523,29 @@ found_client:
499/* 523/*
500 * Mark a server as ready or failed 524 * Mark a server as ready or failed
501 */ 525 */
502static void nfs_mark_client_ready(struct nfs_client *clp, int state) 526void nfs_mark_client_ready(struct nfs_client *clp, int state)
503{ 527{
504 clp->cl_cons_state = state; 528 clp->cl_cons_state = state;
505 wake_up_all(&nfs_client_active_wq); 529 wake_up_all(&nfs_client_active_wq);
506} 530}
507 531
508/* 532/*
533 * With sessions, the client is not marked ready until after a
534 * successful EXCHANGE_ID and CREATE_SESSION.
535 *
536 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
537 * other versions of NFS can be tried.
538 */
539int nfs4_check_client_ready(struct nfs_client *clp)
540{
541 if (!nfs4_has_session(clp))
542 return 0;
543 if (clp->cl_cons_state < NFS_CS_READY)
544 return -EPROTONOSUPPORT;
545 return 0;
546}
547
548/*
509 * Initialise the timeout values for a connection 549 * Initialise the timeout values for a connection
510 */ 550 */
511static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, 551static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
@@ -1050,6 +1090,61 @@ error:
1050 1090
1051#ifdef CONFIG_NFS_V4 1091#ifdef CONFIG_NFS_V4
1052/* 1092/*
1093 * Initialize the NFS4 callback service
1094 */
1095static int nfs4_init_callback(struct nfs_client *clp)
1096{
1097 int error;
1098
1099 if (clp->rpc_ops->version == 4) {
1100 if (nfs4_has_session(clp)) {
1101 error = xprt_setup_backchannel(
1102 clp->cl_rpcclient->cl_xprt,
1103 NFS41_BC_MIN_CALLBACKS);
1104 if (error < 0)
1105 return error;
1106 }
1107
1108 error = nfs_callback_up(clp->cl_minorversion,
1109 clp->cl_rpcclient->cl_xprt);
1110 if (error < 0) {
1111 dprintk("%s: failed to start callback. Error = %d\n",
1112 __func__, error);
1113 return error;
1114 }
1115 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
1116 }
1117 return 0;
1118}
1119
1120/*
1121 * Initialize the minor version specific parts of an NFS4 client record
1122 */
1123static int nfs4_init_client_minor_version(struct nfs_client *clp)
1124{
1125 clp->cl_call_sync = _nfs4_call_sync;
1126
1127#if defined(CONFIG_NFS_V4_1)
1128 if (clp->cl_minorversion) {
1129 struct nfs4_session *session = NULL;
1130 /*
1131 * Create the session and mark it expired.
1132 * When a SEQUENCE operation encounters the expired session
1133 * it will do session recovery to initialize it.
1134 */
1135 session = nfs4_alloc_session(clp);
1136 if (!session)
1137 return -ENOMEM;
1138
1139 clp->cl_session = session;
1140 clp->cl_call_sync = _nfs4_call_sync_session;
1141 }
1142#endif /* CONFIG_NFS_V4_1 */
1143
1144 return nfs4_init_callback(clp);
1145}
1146
1147/*
1053 * Initialise an NFS4 client record 1148 * Initialise an NFS4 client record
1054 */ 1149 */
1055static int nfs4_init_client(struct nfs_client *clp, 1150static int nfs4_init_client(struct nfs_client *clp,
@@ -1083,7 +1178,12 @@ static int nfs4_init_client(struct nfs_client *clp,
1083 } 1178 }
1084 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state); 1179 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
1085 1180
1086 nfs_mark_client_ready(clp, NFS_CS_READY); 1181 error = nfs4_init_client_minor_version(clp);
1182 if (error < 0)
1183 goto error;
1184
1185 if (!nfs4_has_session(clp))
1186 nfs_mark_client_ready(clp, NFS_CS_READY);
1087 return 0; 1187 return 0;
1088 1188
1089error: 1189error:
@@ -1101,7 +1201,8 @@ static int nfs4_set_client(struct nfs_server *server,
1101 const size_t addrlen, 1201 const size_t addrlen,
1102 const char *ip_addr, 1202 const char *ip_addr,
1103 rpc_authflavor_t authflavour, 1203 rpc_authflavor_t authflavour,
1104 int proto, const struct rpc_timeout *timeparms) 1204 int proto, const struct rpc_timeout *timeparms,
1205 u32 minorversion)
1105{ 1206{
1106 struct nfs_client_initdata cl_init = { 1207 struct nfs_client_initdata cl_init = {
1107 .hostname = hostname, 1208 .hostname = hostname,
@@ -1109,6 +1210,7 @@ static int nfs4_set_client(struct nfs_server *server,
1109 .addrlen = addrlen, 1210 .addrlen = addrlen,
1110 .rpc_ops = &nfs_v4_clientops, 1211 .rpc_ops = &nfs_v4_clientops,
1111 .proto = proto, 1212 .proto = proto,
1213 .minorversion = minorversion,
1112 }; 1214 };
1113 struct nfs_client *clp; 1215 struct nfs_client *clp;
1114 int error; 1216 int error;
@@ -1138,6 +1240,36 @@ error:
1138} 1240}
1139 1241
1140/* 1242/*
1243 * Initialize a session.
1244 * Note: save the mount rsize and wsize for create_server negotiation.
1245 */
1246static void nfs4_init_session(struct nfs_client *clp,
1247 unsigned int wsize, unsigned int rsize)
1248{
1249#if defined(CONFIG_NFS_V4_1)
1250 if (nfs4_has_session(clp)) {
1251 clp->cl_session->fc_attrs.max_rqst_sz = wsize;
1252 clp->cl_session->fc_attrs.max_resp_sz = rsize;
1253 }
1254#endif /* CONFIG_NFS_V4_1 */
1255}
1256
1257/*
1258 * Session has been established, and the client marked ready.
1259 * Set the mount rsize and wsize with negotiated fore channel
1260 * attributes which will be bound checked in nfs_server_set_fsinfo.
1261 */
1262static void nfs4_session_set_rwsize(struct nfs_server *server)
1263{
1264#ifdef CONFIG_NFS_V4_1
1265 if (!nfs4_has_session(server->nfs_client))
1266 return;
1267 server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
1268 server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
1269#endif /* CONFIG_NFS_V4_1 */
1270}
1271
1272/*
1141 * Create a version 4 volume record 1273 * Create a version 4 volume record
1142 */ 1274 */
1143static int nfs4_init_server(struct nfs_server *server, 1275static int nfs4_init_server(struct nfs_server *server,
@@ -1164,7 +1296,8 @@ static int nfs4_init_server(struct nfs_server *server,
1164 data->client_address, 1296 data->client_address,
1165 data->auth_flavors[0], 1297 data->auth_flavors[0],
1166 data->nfs_server.protocol, 1298 data->nfs_server.protocol,
1167 &timeparms); 1299 &timeparms,
1300 data->minorversion);
1168 if (error < 0) 1301 if (error < 0)
1169 goto error; 1302 goto error;
1170 1303
@@ -1214,6 +1347,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1214 BUG_ON(!server->nfs_client->rpc_ops); 1347 BUG_ON(!server->nfs_client->rpc_ops);
1215 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1348 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1216 1349
1350 nfs4_init_session(server->nfs_client, server->wsize, server->rsize);
1351
1217 /* Probe the root fh to retrieve its FSID */ 1352 /* Probe the root fh to retrieve its FSID */
1218 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); 1353 error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
1219 if (error < 0) 1354 if (error < 0)
@@ -1224,6 +1359,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1224 (unsigned long long) server->fsid.minor); 1359 (unsigned long long) server->fsid.minor);
1225 dprintk("Mount FH: %d\n", mntfh->size); 1360 dprintk("Mount FH: %d\n", mntfh->size);
1226 1361
1362 nfs4_session_set_rwsize(server);
1363
1227 error = nfs_probe_fsinfo(server, mntfh, &fattr); 1364 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1228 if (error < 0) 1365 if (error < 0)
1229 goto error; 1366 goto error;
@@ -1282,7 +1419,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1282 parent_client->cl_ipaddr, 1419 parent_client->cl_ipaddr,
1283 data->authflavor, 1420 data->authflavor,
1284 parent_server->client->cl_xprt->prot, 1421 parent_server->client->cl_xprt->prot,
1285 parent_server->client->cl_timeout); 1422 parent_server->client->cl_timeout,
1423 parent_client->cl_minorversion);
1286 if (error < 0) 1424 if (error < 0)
1287 goto error; 1425 goto error;
1288 1426
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/internal.h b/fs/nfs/internal.h
index e4d6a8348adf..acee3274d275 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;
@@ -44,6 +57,7 @@ struct nfs_parsed_mount_data {
44 unsigned int auth_flavor_len; 57 unsigned int auth_flavor_len;
45 rpc_authflavor_t auth_flavors[1]; 58 rpc_authflavor_t auth_flavors[1];
46 char *client_address; 59 char *client_address;
60 unsigned int minorversion;
47 char *fscache_uniq; 61 char *fscache_uniq;
48 62
49 struct { 63 struct {
@@ -99,6 +113,8 @@ extern void nfs_free_server(struct nfs_server *server);
99extern struct nfs_server *nfs_clone_server(struct nfs_server *, 113extern struct nfs_server *nfs_clone_server(struct nfs_server *,
100 struct nfs_fh *, 114 struct nfs_fh *,
101 struct nfs_fattr *); 115 struct nfs_fattr *);
116extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
117extern int nfs4_check_client_ready(struct nfs_client *clp);
102#ifdef CONFIG_PROC_FS 118#ifdef CONFIG_PROC_FS
103extern int __init nfs_fs_proc_init(void); 119extern int __init nfs_fs_proc_init(void);
104extern void nfs_fs_proc_exit(void); 120extern void nfs_fs_proc_exit(void);
@@ -146,6 +162,20 @@ extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
146extern struct rpc_procinfo nfs3_procedures[]; 162extern struct rpc_procinfo nfs3_procedures[];
147extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int); 163extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
148 164
165/* nfs4proc.c */
166static inline void nfs4_restart_rpc(struct rpc_task *task,
167 const struct nfs_client *clp)
168{
169#ifdef CONFIG_NFS_V4_1
170 if (nfs4_has_session(clp) &&
171 test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
172 rpc_restart_call_prepare(task);
173 return;
174 }
175#endif /* CONFIG_NFS_V4_1 */
176 rpc_restart_call(task);
177}
178
149/* nfs4xdr.c */ 179/* nfs4xdr.c */
150#ifdef CONFIG_NFS_V4 180#ifdef CONFIG_NFS_V4
151extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus); 181extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
@@ -205,6 +235,38 @@ extern int nfs4_path_walk(struct nfs_server *server,
205 const char *path); 235 const char *path);
206#endif 236#endif
207 237
238/* read.c */
239extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
240
241/* write.c */
242extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
243
244/* nfs4proc.c */
245extern int _nfs4_call_sync(struct nfs_server *server,
246 struct rpc_message *msg,
247 struct nfs4_sequence_args *args,
248 struct nfs4_sequence_res *res,
249 int cache_reply);
250extern int _nfs4_call_sync_session(struct nfs_server *server,
251 struct rpc_message *msg,
252 struct nfs4_sequence_args *args,
253 struct nfs4_sequence_res *res,
254 int cache_reply);
255
256#ifdef CONFIG_NFS_V4_1
257extern void nfs41_sequence_free_slot(const struct nfs_client *,
258 struct nfs4_sequence_res *res);
259#endif /* CONFIG_NFS_V4_1 */
260
261static inline void nfs4_sequence_free_slot(const struct nfs_client *clp,
262 struct nfs4_sequence_res *res)
263{
264#ifdef CONFIG_NFS_V4_1
265 if (nfs4_has_session(clp))
266 nfs41_sequence_free_slot(clp, res);
267#endif /* CONFIG_NFS_V4_1 */
268}
269
208/* 270/*
209 * Determine the device name as a string 271 * Determine the device name as a string
210 */ 272 */
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..57dabb8a048e 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);
@@ -343,6 +711,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
343 p->o_arg.server = server; 711 p->o_arg.server = server;
344 p->o_arg.bitmask = server->attr_bitmask; 712 p->o_arg.bitmask = server->attr_bitmask;
345 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 713 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
714 p->o_res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
346 if (flags & O_EXCL) { 715 if (flags & O_EXCL) {
347 u32 *s = (u32 *) p->o_arg.u.verifier.data; 716 u32 *s = (u32 *) p->o_arg.u.verifier.data;
348 s[0] = jiffies; 717 s[0] = jiffies;
@@ -929,6 +1298,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
929 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); 1298 nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
930 } 1299 }
931 data->timestamp = jiffies; 1300 data->timestamp = jiffies;
1301 if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
1302 &data->o_arg.seq_args,
1303 &data->o_res.seq_res, 1, task))
1304 return;
932 rpc_call_start(task); 1305 rpc_call_start(task);
933 return; 1306 return;
934out_no_action: 1307out_no_action:
@@ -941,6 +1314,10 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
941 struct nfs4_opendata *data = calldata; 1314 struct nfs4_opendata *data = calldata;
942 1315
943 data->rpc_status = task->tk_status; 1316 data->rpc_status = task->tk_status;
1317
1318 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res,
1319 task->tk_status);
1320
944 if (RPC_ASSASSINATED(task)) 1321 if (RPC_ASSASSINATED(task))
945 return; 1322 return;
946 if (task->tk_status == 0) { 1323 if (task->tk_status == 0) {
@@ -1269,7 +1646,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
1269 } else 1646 } else
1270 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); 1647 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
1271 1648
1272 status = rpc_call_sync(server->client, &msg, 0); 1649 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
1273 if (status == 0 && state != NULL) 1650 if (status == 0 && state != NULL)
1274 renew_lease(server, timestamp); 1651 renew_lease(server, timestamp);
1275 return status; 1652 return status;
@@ -1318,6 +1695,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1318 struct nfs4_state *state = calldata->state; 1695 struct nfs4_state *state = calldata->state;
1319 struct nfs_server *server = NFS_SERVER(calldata->inode); 1696 struct nfs_server *server = NFS_SERVER(calldata->inode);
1320 1697
1698 nfs4_sequence_done(server, &calldata->res.seq_res, task->tk_status);
1321 if (RPC_ASSASSINATED(task)) 1699 if (RPC_ASSASSINATED(task))
1322 return; 1700 return;
1323 /* hmm. we are done with the inode, and in the process of freeing 1701 /* hmm. we are done with the inode, and in the process of freeing
@@ -1336,10 +1714,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1336 break; 1714 break;
1337 default: 1715 default:
1338 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1716 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
1339 rpc_restart_call(task); 1717 nfs4_restart_rpc(task, server->nfs_client);
1340 return; 1718 return;
1341 } 1719 }
1342 } 1720 }
1721 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res);
1343 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1722 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1344} 1723}
1345 1724
@@ -1380,6 +1759,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1380 calldata->arg.fmode = FMODE_WRITE; 1759 calldata->arg.fmode = FMODE_WRITE;
1381 } 1760 }
1382 calldata->timestamp = jiffies; 1761 calldata->timestamp = jiffies;
1762 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1763 &calldata->arg.seq_args, &calldata->res.seq_res,
1764 1, task))
1765 return;
1383 rpc_call_start(task); 1766 rpc_call_start(task);
1384} 1767}
1385 1768
@@ -1419,13 +1802,15 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1419 }; 1802 };
1420 int status = -ENOMEM; 1803 int status = -ENOMEM;
1421 1804
1422 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); 1805 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
1423 if (calldata == NULL) 1806 if (calldata == NULL)
1424 goto out; 1807 goto out;
1425 calldata->inode = state->inode; 1808 calldata->inode = state->inode;
1426 calldata->state = state; 1809 calldata->state = state;
1427 calldata->arg.fh = NFS_FH(state->inode); 1810 calldata->arg.fh = NFS_FH(state->inode);
1428 calldata->arg.stateid = &state->open_stateid; 1811 calldata->arg.stateid = &state->open_stateid;
1812 if (nfs4_has_session(server->nfs_client))
1813 memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
1429 /* Serialization for the sequence id */ 1814 /* Serialization for the sequence id */
1430 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1815 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1431 if (calldata->arg.seqid == NULL) 1816 if (calldata->arg.seqid == NULL)
@@ -1435,6 +1820,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1435 calldata->res.fattr = &calldata->fattr; 1820 calldata->res.fattr = &calldata->fattr;
1436 calldata->res.seqid = calldata->arg.seqid; 1821 calldata->res.seqid = calldata->arg.seqid;
1437 calldata->res.server = server; 1822 calldata->res.server = server;
1823 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
1438 calldata->path.mnt = mntget(path->mnt); 1824 calldata->path.mnt = mntget(path->mnt);
1439 calldata->path.dentry = dget(path->dentry); 1825 calldata->path.dentry = dget(path->dentry);
1440 1826
@@ -1584,15 +1970,18 @@ void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1584 1970
1585static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 1971static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
1586{ 1972{
1973 struct nfs4_server_caps_arg args = {
1974 .fhandle = fhandle,
1975 };
1587 struct nfs4_server_caps_res res = {}; 1976 struct nfs4_server_caps_res res = {};
1588 struct rpc_message msg = { 1977 struct rpc_message msg = {
1589 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS], 1978 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS],
1590 .rpc_argp = fhandle, 1979 .rpc_argp = &args,
1591 .rpc_resp = &res, 1980 .rpc_resp = &res,
1592 }; 1981 };
1593 int status; 1982 int status;
1594 1983
1595 status = rpc_call_sync(server->client, &msg, 0); 1984 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1596 if (status == 0) { 1985 if (status == 0) {
1597 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 1986 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
1598 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 1987 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
@@ -1606,6 +1995,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; 1995 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1607 server->acl_bitmask = res.acl_bitmask; 1996 server->acl_bitmask = res.acl_bitmask;
1608 } 1997 }
1998
1609 return status; 1999 return status;
1610} 2000}
1611 2001
@@ -1637,8 +2027,15 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
1637 .rpc_argp = &args, 2027 .rpc_argp = &args,
1638 .rpc_resp = &res, 2028 .rpc_resp = &res,
1639 }; 2029 };
2030 int status;
2031
1640 nfs_fattr_init(info->fattr); 2032 nfs_fattr_init(info->fattr);
1641 return rpc_call_sync(server->client, &msg, 0); 2033 status = nfs4_recover_expired_lease(server);
2034 if (!status)
2035 status = nfs4_check_client_ready(server->nfs_client);
2036 if (!status)
2037 status = nfs4_call_sync(server, &msg, &args, &res, 0);
2038 return status;
1642} 2039}
1643 2040
1644static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, 2041static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -1728,7 +2125,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
1728 }; 2125 };
1729 2126
1730 nfs_fattr_init(fattr); 2127 nfs_fattr_init(fattr);
1731 return rpc_call_sync(server->client, &msg, 0); 2128 return nfs4_call_sync(server, &msg, &args, &res, 0);
1732} 2129}
1733 2130
1734static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2131static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
@@ -1812,7 +2209,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
1812 nfs_fattr_init(fattr); 2209 nfs_fattr_init(fattr);
1813 2210
1814 dprintk("NFS call lookupfh %s\n", name->name); 2211 dprintk("NFS call lookupfh %s\n", name->name);
1815 status = rpc_call_sync(server->client, &msg, 0); 2212 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1816 dprintk("NFS reply lookupfh: %d\n", status); 2213 dprintk("NFS reply lookupfh: %d\n", status);
1817 return status; 2214 return status;
1818} 2215}
@@ -1898,7 +2295,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
1898 args.access |= NFS4_ACCESS_EXECUTE; 2295 args.access |= NFS4_ACCESS_EXECUTE;
1899 } 2296 }
1900 nfs_fattr_init(&fattr); 2297 nfs_fattr_init(&fattr);
1901 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 2298 status = nfs4_call_sync(server, &msg, &args, &res, 0);
1902 if (!status) { 2299 if (!status) {
1903 entry->mask = 0; 2300 entry->mask = 0;
1904 if (res.access & NFS4_ACCESS_READ) 2301 if (res.access & NFS4_ACCESS_READ)
@@ -1957,13 +2354,14 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
1957 .pglen = pglen, 2354 .pglen = pglen,
1958 .pages = &page, 2355 .pages = &page,
1959 }; 2356 };
2357 struct nfs4_readlink_res res;
1960 struct rpc_message msg = { 2358 struct rpc_message msg = {
1961 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK], 2359 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
1962 .rpc_argp = &args, 2360 .rpc_argp = &args,
1963 .rpc_resp = NULL, 2361 .rpc_resp = &res,
1964 }; 2362 };
1965 2363
1966 return rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 2364 return nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
1967} 2365}
1968 2366
1969static int nfs4_proc_readlink(struct inode *inode, struct page *page, 2367static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2057,7 +2455,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
2057 int status; 2455 int status;
2058 2456
2059 nfs_fattr_init(&res.dir_attr); 2457 nfs_fattr_init(&res.dir_attr);
2060 status = rpc_call_sync(server->client, &msg, 0); 2458 status = nfs4_call_sync(server, &msg, &args, &res, 1);
2061 if (status == 0) { 2459 if (status == 0) {
2062 update_changeattr(dir, &res.cinfo); 2460 update_changeattr(dir, &res.cinfo);
2063 nfs_post_op_update_inode(dir, &res.dir_attr); 2461 nfs_post_op_update_inode(dir, &res.dir_attr);
@@ -2092,8 +2490,10 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2092{ 2490{
2093 struct nfs_removeres *res = task->tk_msg.rpc_resp; 2491 struct nfs_removeres *res = task->tk_msg.rpc_resp;
2094 2492
2493 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2095 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2494 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2096 return 0; 2495 return 0;
2496 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2097 update_changeattr(dir, &res->cinfo); 2497 update_changeattr(dir, &res->cinfo);
2098 nfs_post_op_update_inode(dir, &res->dir_attr); 2498 nfs_post_op_update_inode(dir, &res->dir_attr);
2099 return 1; 2499 return 1;
@@ -2125,7 +2525,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2125 2525
2126 nfs_fattr_init(res.old_fattr); 2526 nfs_fattr_init(res.old_fattr);
2127 nfs_fattr_init(res.new_fattr); 2527 nfs_fattr_init(res.new_fattr);
2128 status = rpc_call_sync(server->client, &msg, 0); 2528 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
2129 2529
2130 if (!status) { 2530 if (!status) {
2131 update_changeattr(old_dir, &res.old_cinfo); 2531 update_changeattr(old_dir, &res.old_cinfo);
@@ -2174,7 +2574,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
2174 2574
2175 nfs_fattr_init(res.fattr); 2575 nfs_fattr_init(res.fattr);
2176 nfs_fattr_init(res.dir_attr); 2576 nfs_fattr_init(res.dir_attr);
2177 status = rpc_call_sync(server->client, &msg, 0); 2577 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
2178 if (!status) { 2578 if (!status) {
2179 update_changeattr(dir, &res.cinfo); 2579 update_changeattr(dir, &res.cinfo);
2180 nfs_post_op_update_inode(dir, res.dir_attr); 2580 nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2235,7 +2635,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
2235 2635
2236static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) 2636static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
2237{ 2637{
2238 int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); 2638 int status = nfs4_call_sync(NFS_SERVER(dir), &data->msg,
2639 &data->arg, &data->res, 1);
2239 if (status == 0) { 2640 if (status == 0) {
2240 update_changeattr(dir, &data->res.dir_cinfo); 2641 update_changeattr(dir, &data->res.dir_cinfo);
2241 nfs_post_op_update_inode(dir, data->res.dir_fattr); 2642 nfs_post_op_update_inode(dir, data->res.dir_fattr);
@@ -2344,7 +2745,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
2344 (unsigned long long)cookie); 2745 (unsigned long long)cookie);
2345 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 2746 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
2346 res.pgbase = args.pgbase; 2747 res.pgbase = args.pgbase;
2347 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 2748 status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
2348 if (status == 0) 2749 if (status == 0)
2349 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 2750 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
2350 2751
@@ -2422,14 +2823,17 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
2422 .fh = fhandle, 2823 .fh = fhandle,
2423 .bitmask = server->attr_bitmask, 2824 .bitmask = server->attr_bitmask,
2424 }; 2825 };
2826 struct nfs4_statfs_res res = {
2827 .fsstat = fsstat,
2828 };
2425 struct rpc_message msg = { 2829 struct rpc_message msg = {
2426 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS], 2830 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS],
2427 .rpc_argp = &args, 2831 .rpc_argp = &args,
2428 .rpc_resp = fsstat, 2832 .rpc_resp = &res,
2429 }; 2833 };
2430 2834
2431 nfs_fattr_init(fsstat->fattr); 2835 nfs_fattr_init(fsstat->fattr);
2432 return rpc_call_sync(server->client, &msg, 0); 2836 return nfs4_call_sync(server, &msg, &args, &res, 0);
2433} 2837}
2434 2838
2435static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) 2839static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
@@ -2451,13 +2855,16 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
2451 .fh = fhandle, 2855 .fh = fhandle,
2452 .bitmask = server->attr_bitmask, 2856 .bitmask = server->attr_bitmask,
2453 }; 2857 };
2858 struct nfs4_fsinfo_res res = {
2859 .fsinfo = fsinfo,
2860 };
2454 struct rpc_message msg = { 2861 struct rpc_message msg = {
2455 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO], 2862 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
2456 .rpc_argp = &args, 2863 .rpc_argp = &args,
2457 .rpc_resp = fsinfo, 2864 .rpc_resp = &res,
2458 }; 2865 };
2459 2866
2460 return rpc_call_sync(server->client, &msg, 0); 2867 return nfs4_call_sync(server, &msg, &args, &res, 0);
2461} 2868}
2462 2869
2463static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) 2870static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
@@ -2486,10 +2893,13 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
2486 .fh = fhandle, 2893 .fh = fhandle,
2487 .bitmask = server->attr_bitmask, 2894 .bitmask = server->attr_bitmask,
2488 }; 2895 };
2896 struct nfs4_pathconf_res res = {
2897 .pathconf = pathconf,
2898 };
2489 struct rpc_message msg = { 2899 struct rpc_message msg = {
2490 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF], 2900 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF],
2491 .rpc_argp = &args, 2901 .rpc_argp = &args,
2492 .rpc_resp = pathconf, 2902 .rpc_resp = &res,
2493 }; 2903 };
2494 2904
2495 /* None of the pathconf attributes are mandatory to implement */ 2905 /* None of the pathconf attributes are mandatory to implement */
@@ -2499,7 +2909,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
2499 } 2909 }
2500 2910
2501 nfs_fattr_init(pathconf->fattr); 2911 nfs_fattr_init(pathconf->fattr);
2502 return rpc_call_sync(server->client, &msg, 0); 2912 return nfs4_call_sync(server, &msg, &args, &res, 0);
2503} 2913}
2504 2914
2505static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, 2915static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2520,8 +2930,13 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2520{ 2930{
2521 struct nfs_server *server = NFS_SERVER(data->inode); 2931 struct nfs_server *server = NFS_SERVER(data->inode);
2522 2932
2933 dprintk("--> %s\n", __func__);
2934
2935 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2936 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2937
2523 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 2938 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2524 rpc_restart_call(task); 2939 nfs4_restart_rpc(task, server->nfs_client);
2525 return -EAGAIN; 2940 return -EAGAIN;
2526 } 2941 }
2527 2942
@@ -2541,8 +2956,12 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2541{ 2956{
2542 struct inode *inode = data->inode; 2957 struct inode *inode = data->inode;
2543 2958
2959 /* slot is freed in nfs_writeback_done */
2960 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
2961 task->tk_status);
2962
2544 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 2963 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
2545 rpc_restart_call(task); 2964 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
2546 return -EAGAIN; 2965 return -EAGAIN;
2547 } 2966 }
2548 if (task->tk_status >= 0) { 2967 if (task->tk_status >= 0) {
@@ -2567,10 +2986,14 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2567{ 2986{
2568 struct inode *inode = data->inode; 2987 struct inode *inode = data->inode;
2569 2988
2989 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
2990 task->tk_status);
2570 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 2991 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
2571 rpc_restart_call(task); 2992 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
2572 return -EAGAIN; 2993 return -EAGAIN;
2573 } 2994 }
2995 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
2996 &data->res.seq_res);
2574 nfs_refresh_inode(inode, data->res.fattr); 2997 nfs_refresh_inode(inode, data->res.fattr);
2575 return 0; 2998 return 0;
2576} 2999}
@@ -2603,6 +3026,9 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
2603 if (time_before(clp->cl_last_renewal,timestamp)) 3026 if (time_before(clp->cl_last_renewal,timestamp))
2604 clp->cl_last_renewal = timestamp; 3027 clp->cl_last_renewal = timestamp;
2605 spin_unlock(&clp->cl_lock); 3028 spin_unlock(&clp->cl_lock);
3029 dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__,
3030 task->tk_msg.rpc_cred);
3031 put_rpccred(task->tk_msg.rpc_cred);
2606} 3032}
2607 3033
2608static const struct rpc_call_ops nfs4_renew_ops = { 3034static const struct rpc_call_ops nfs4_renew_ops = {
@@ -2742,12 +3168,14 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
2742 .acl_pages = pages, 3168 .acl_pages = pages,
2743 .acl_len = buflen, 3169 .acl_len = buflen,
2744 }; 3170 };
2745 size_t resp_len = buflen; 3171 struct nfs_getaclres res = {
3172 .acl_len = buflen,
3173 };
2746 void *resp_buf; 3174 void *resp_buf;
2747 struct rpc_message msg = { 3175 struct rpc_message msg = {
2748 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], 3176 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
2749 .rpc_argp = &args, 3177 .rpc_argp = &args,
2750 .rpc_resp = &resp_len, 3178 .rpc_resp = &res,
2751 }; 3179 };
2752 struct page *localpage = NULL; 3180 struct page *localpage = NULL;
2753 int ret; 3181 int ret;
@@ -2761,26 +3189,26 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
2761 return -ENOMEM; 3189 return -ENOMEM;
2762 args.acl_pages[0] = localpage; 3190 args.acl_pages[0] = localpage;
2763 args.acl_pgbase = 0; 3191 args.acl_pgbase = 0;
2764 resp_len = args.acl_len = PAGE_SIZE; 3192 args.acl_len = PAGE_SIZE;
2765 } else { 3193 } else {
2766 resp_buf = buf; 3194 resp_buf = buf;
2767 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase); 3195 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
2768 } 3196 }
2769 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 3197 ret = nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
2770 if (ret) 3198 if (ret)
2771 goto out_free; 3199 goto out_free;
2772 if (resp_len > args.acl_len) 3200 if (res.acl_len > args.acl_len)
2773 nfs4_write_cached_acl(inode, NULL, resp_len); 3201 nfs4_write_cached_acl(inode, NULL, res.acl_len);
2774 else 3202 else
2775 nfs4_write_cached_acl(inode, resp_buf, resp_len); 3203 nfs4_write_cached_acl(inode, resp_buf, res.acl_len);
2776 if (buf) { 3204 if (buf) {
2777 ret = -ERANGE; 3205 ret = -ERANGE;
2778 if (resp_len > buflen) 3206 if (res.acl_len > buflen)
2779 goto out_free; 3207 goto out_free;
2780 if (localpage) 3208 if (localpage)
2781 memcpy(buf, resp_buf, resp_len); 3209 memcpy(buf, resp_buf, res.acl_len);
2782 } 3210 }
2783 ret = resp_len; 3211 ret = res.acl_len;
2784out_free: 3212out_free:
2785 if (localpage) 3213 if (localpage)
2786 __free_page(localpage); 3214 __free_page(localpage);
@@ -2827,10 +3255,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
2827 .acl_pages = pages, 3255 .acl_pages = pages,
2828 .acl_len = buflen, 3256 .acl_len = buflen,
2829 }; 3257 };
3258 struct nfs_setaclres res;
2830 struct rpc_message msg = { 3259 struct rpc_message msg = {
2831 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL], 3260 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
2832 .rpc_argp = &arg, 3261 .rpc_argp = &arg,
2833 .rpc_resp = NULL, 3262 .rpc_resp = &res,
2834 }; 3263 };
2835 int ret; 3264 int ret;
2836 3265
@@ -2838,7 +3267,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
2838 return -EOPNOTSUPP; 3267 return -EOPNOTSUPP;
2839 nfs_inode_return_delegation(inode); 3268 nfs_inode_return_delegation(inode);
2840 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 3269 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
2841 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 3270 ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
2842 nfs_access_zap_cache(inode); 3271 nfs_access_zap_cache(inode);
2843 nfs_zap_acl_cache(inode); 3272 nfs_zap_acl_cache(inode);
2844 return ret; 3273 return ret;
@@ -2857,10 +3286,8 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
2857} 3286}
2858 3287
2859static int 3288static int
2860nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state) 3289_nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs_client *clp, struct nfs4_state *state)
2861{ 3290{
2862 struct nfs_client *clp = server->nfs_client;
2863
2864 if (!clp || task->tk_status >= 0) 3291 if (!clp || task->tk_status >= 0)
2865 return 0; 3292 return 0;
2866 switch(task->tk_status) { 3293 switch(task->tk_status) {
@@ -2879,8 +3306,23 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
2879 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 3306 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
2880 task->tk_status = 0; 3307 task->tk_status = 0;
2881 return -EAGAIN; 3308 return -EAGAIN;
3309#if defined(CONFIG_NFS_V4_1)
3310 case -NFS4ERR_BADSESSION:
3311 case -NFS4ERR_BADSLOT:
3312 case -NFS4ERR_BAD_HIGH_SLOT:
3313 case -NFS4ERR_DEADSESSION:
3314 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
3315 case -NFS4ERR_SEQ_FALSE_RETRY:
3316 case -NFS4ERR_SEQ_MISORDERED:
3317 dprintk("%s ERROR %d, Reset session\n", __func__,
3318 task->tk_status);
3319 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
3320 task->tk_status = 0;
3321 return -EAGAIN;
3322#endif /* CONFIG_NFS_V4_1 */
2882 case -NFS4ERR_DELAY: 3323 case -NFS4ERR_DELAY:
2883 nfs_inc_server_stats(server, NFSIOS_DELAY); 3324 if (server)
3325 nfs_inc_server_stats(server, NFSIOS_DELAY);
2884 case -NFS4ERR_GRACE: 3326 case -NFS4ERR_GRACE:
2885 rpc_delay(task, NFS4_POLL_RETRY_MAX); 3327 rpc_delay(task, NFS4_POLL_RETRY_MAX);
2886 task->tk_status = 0; 3328 task->tk_status = 0;
@@ -2893,6 +3335,12 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
2893 return 0; 3335 return 0;
2894} 3336}
2895 3337
3338static int
3339nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
3340{
3341 return _nfs4_async_handle_error(task, server, server->nfs_client, state);
3342}
3343
2896int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 3344int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2897{ 3345{
2898 nfs4_verifier sc_verifier; 3346 nfs4_verifier sc_verifier;
@@ -3000,6 +3448,10 @@ struct nfs4_delegreturndata {
3000static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) 3448static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3001{ 3449{
3002 struct nfs4_delegreturndata *data = calldata; 3450 struct nfs4_delegreturndata *data = calldata;
3451
3452 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res,
3453 task->tk_status);
3454
3003 data->rpc_status = task->tk_status; 3455 data->rpc_status = task->tk_status;
3004 if (data->rpc_status == 0) 3456 if (data->rpc_status == 0)
3005 renew_lease(data->res.server, data->timestamp); 3457 renew_lease(data->res.server, data->timestamp);
@@ -3010,7 +3462,25 @@ static void nfs4_delegreturn_release(void *calldata)
3010 kfree(calldata); 3462 kfree(calldata);
3011} 3463}
3012 3464
3465#if defined(CONFIG_NFS_V4_1)
3466static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
3467{
3468 struct nfs4_delegreturndata *d_data;
3469
3470 d_data = (struct nfs4_delegreturndata *)data;
3471
3472 if (nfs4_setup_sequence(d_data->res.server->nfs_client,
3473 &d_data->args.seq_args,
3474 &d_data->res.seq_res, 1, task))
3475 return;
3476 rpc_call_start(task);
3477}
3478#endif /* CONFIG_NFS_V4_1 */
3479
3013static const struct rpc_call_ops nfs4_delegreturn_ops = { 3480static const struct rpc_call_ops nfs4_delegreturn_ops = {
3481#if defined(CONFIG_NFS_V4_1)
3482 .rpc_call_prepare = nfs4_delegreturn_prepare,
3483#endif /* CONFIG_NFS_V4_1 */
3014 .rpc_call_done = nfs4_delegreturn_done, 3484 .rpc_call_done = nfs4_delegreturn_done,
3015 .rpc_release = nfs4_delegreturn_release, 3485 .rpc_release = nfs4_delegreturn_release,
3016}; 3486};
@@ -3032,7 +3502,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3032 }; 3502 };
3033 int status = 0; 3503 int status = 0;
3034 3504
3035 data = kmalloc(sizeof(*data), GFP_KERNEL); 3505 data = kzalloc(sizeof(*data), GFP_KERNEL);
3036 if (data == NULL) 3506 if (data == NULL)
3037 return -ENOMEM; 3507 return -ENOMEM;
3038 data->args.fhandle = &data->fh; 3508 data->args.fhandle = &data->fh;
@@ -3042,6 +3512,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
3042 memcpy(&data->stateid, stateid, sizeof(data->stateid)); 3512 memcpy(&data->stateid, stateid, sizeof(data->stateid));
3043 data->res.fattr = &data->fattr; 3513 data->res.fattr = &data->fattr;
3044 data->res.server = server; 3514 data->res.server = server;
3515 data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3045 nfs_fattr_init(data->res.fattr); 3516 nfs_fattr_init(data->res.fattr);
3046 data->timestamp = jiffies; 3517 data->timestamp = jiffies;
3047 data->rpc_status = 0; 3518 data->rpc_status = 0;
@@ -3127,7 +3598,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3127 goto out; 3598 goto out;
3128 lsp = request->fl_u.nfs4_fl.owner; 3599 lsp = request->fl_u.nfs4_fl.owner;
3129 arg.lock_owner.id = lsp->ls_id.id; 3600 arg.lock_owner.id = lsp->ls_id.id;
3130 status = rpc_call_sync(server->client, &msg, 0); 3601 status = nfs4_call_sync(server, &msg, &arg, &res, 1);
3131 switch (status) { 3602 switch (status) {
3132 case 0: 3603 case 0:
3133 request->fl_type = F_UNLCK; 3604 request->fl_type = F_UNLCK;
@@ -3187,13 +3658,14 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3187 struct nfs4_unlockdata *p; 3658 struct nfs4_unlockdata *p;
3188 struct inode *inode = lsp->ls_state->inode; 3659 struct inode *inode = lsp->ls_state->inode;
3189 3660
3190 p = kmalloc(sizeof(*p), GFP_KERNEL); 3661 p = kzalloc(sizeof(*p), GFP_KERNEL);
3191 if (p == NULL) 3662 if (p == NULL)
3192 return NULL; 3663 return NULL;
3193 p->arg.fh = NFS_FH(inode); 3664 p->arg.fh = NFS_FH(inode);
3194 p->arg.fl = &p->fl; 3665 p->arg.fl = &p->fl;
3195 p->arg.seqid = seqid; 3666 p->arg.seqid = seqid;
3196 p->res.seqid = seqid; 3667 p->res.seqid = seqid;
3668 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3197 p->arg.stateid = &lsp->ls_stateid; 3669 p->arg.stateid = &lsp->ls_stateid;
3198 p->lsp = lsp; 3670 p->lsp = lsp;
3199 atomic_inc(&lsp->ls_count); 3671 atomic_inc(&lsp->ls_count);
@@ -3217,6 +3689,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3217{ 3689{
3218 struct nfs4_unlockdata *calldata = data; 3690 struct nfs4_unlockdata *calldata = data;
3219 3691
3692 nfs4_sequence_done(calldata->server, &calldata->res.seq_res,
3693 task->tk_status);
3220 if (RPC_ASSASSINATED(task)) 3694 if (RPC_ASSASSINATED(task))
3221 return; 3695 return;
3222 switch (task->tk_status) { 3696 switch (task->tk_status) {
@@ -3233,8 +3707,11 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3233 break; 3707 break;
3234 default: 3708 default:
3235 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3709 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3236 rpc_restart_call(task); 3710 nfs4_restart_rpc(task,
3711 calldata->server->nfs_client);
3237 } 3712 }
3713 nfs4_sequence_free_slot(calldata->server->nfs_client,
3714 &calldata->res.seq_res);
3238} 3715}
3239 3716
3240static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3717static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3249,6 +3726,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
3249 return; 3726 return;
3250 } 3727 }
3251 calldata->timestamp = jiffies; 3728 calldata->timestamp = jiffies;
3729 if (nfs4_setup_sequence(calldata->server->nfs_client,
3730 &calldata->arg.seq_args,
3731 &calldata->res.seq_res, 1, task))
3732 return;
3252 rpc_call_start(task); 3733 rpc_call_start(task);
3253} 3734}
3254 3735
@@ -3341,6 +3822,7 @@ struct nfs4_lockdata {
3341 unsigned long timestamp; 3822 unsigned long timestamp;
3342 int rpc_status; 3823 int rpc_status;
3343 int cancelled; 3824 int cancelled;
3825 struct nfs_server *server;
3344}; 3826};
3345 3827
3346static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, 3828static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
@@ -3366,7 +3848,9 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3366 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 3848 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3367 p->arg.lock_owner.id = lsp->ls_id.id; 3849 p->arg.lock_owner.id = lsp->ls_id.id;
3368 p->res.lock_seqid = p->arg.lock_seqid; 3850 p->res.lock_seqid = p->arg.lock_seqid;
3851 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
3369 p->lsp = lsp; 3852 p->lsp = lsp;
3853 p->server = server;
3370 atomic_inc(&lsp->ls_count); 3854 atomic_inc(&lsp->ls_count);
3371 p->ctx = get_nfs_open_context(ctx); 3855 p->ctx = get_nfs_open_context(ctx);
3372 memcpy(&p->fl, fl, sizeof(p->fl)); 3856 memcpy(&p->fl, fl, sizeof(p->fl));
@@ -3396,6 +3880,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3396 } else 3880 } else
3397 data->arg.new_lock_owner = 0; 3881 data->arg.new_lock_owner = 0;
3398 data->timestamp = jiffies; 3882 data->timestamp = jiffies;
3883 if (nfs4_setup_sequence(data->server->nfs_client, &data->arg.seq_args,
3884 &data->res.seq_res, 1, task))
3885 return;
3399 rpc_call_start(task); 3886 rpc_call_start(task);
3400 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 3887 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3401} 3888}
@@ -3406,6 +3893,9 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3406 3893
3407 dprintk("%s: begin!\n", __func__); 3894 dprintk("%s: begin!\n", __func__);
3408 3895
3896 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res,
3897 task->tk_status);
3898
3409 data->rpc_status = task->tk_status; 3899 data->rpc_status = task->tk_status;
3410 if (RPC_ASSASSINATED(task)) 3900 if (RPC_ASSASSINATED(task))
3411 goto out; 3901 goto out;
@@ -3706,10 +4196,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
3706 .page = page, 4196 .page = page,
3707 .bitmask = bitmask, 4197 .bitmask = bitmask,
3708 }; 4198 };
4199 struct nfs4_fs_locations_res res = {
4200 .fs_locations = fs_locations,
4201 };
3709 struct rpc_message msg = { 4202 struct rpc_message msg = {
3710 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], 4203 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
3711 .rpc_argp = &args, 4204 .rpc_argp = &args,
3712 .rpc_resp = fs_locations, 4205 .rpc_resp = &res,
3713 }; 4206 };
3714 int status; 4207 int status;
3715 4208
@@ -3717,24 +4210,720 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
3717 nfs_fattr_init(&fs_locations->fattr); 4210 nfs_fattr_init(&fs_locations->fattr);
3718 fs_locations->server = server; 4211 fs_locations->server = server;
3719 fs_locations->nlocations = 0; 4212 fs_locations->nlocations = 0;
3720 status = rpc_call_sync(server->client, &msg, 0); 4213 status = nfs4_call_sync(server, &msg, &args, &res, 0);
3721 nfs_fixup_referral_attributes(&fs_locations->fattr); 4214 nfs_fixup_referral_attributes(&fs_locations->fattr);
3722 dprintk("%s: returned status = %d\n", __func__, status); 4215 dprintk("%s: returned status = %d\n", __func__, status);
3723 return status; 4216 return status;
3724} 4217}
3725 4218
3726struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { 4219#ifdef CONFIG_NFS_V4_1
4220/*
4221 * nfs4_proc_exchange_id()
4222 *
4223 * Since the clientid has expired, all compounds using sessions
4224 * associated with the stale clientid will be returning
4225 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4226 * be in some phase of session reset.
4227 */
4228static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4229{
4230 nfs4_verifier verifier;
4231 struct nfs41_exchange_id_args args = {
4232 .client = clp,
4233 .flags = clp->cl_exchange_flags,
4234 };
4235 struct nfs41_exchange_id_res res = {
4236 .client = clp,
4237 };
4238 int status;
4239 struct rpc_message msg = {
4240 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
4241 .rpc_argp = &args,
4242 .rpc_resp = &res,
4243 .rpc_cred = cred,
4244 };
4245 __be32 *p;
4246
4247 dprintk("--> %s\n", __func__);
4248 BUG_ON(clp == NULL);
4249
4250 p = (u32 *)verifier.data;
4251 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4252 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
4253 args.verifier = &verifier;
4254
4255 while (1) {
4256 args.id_len = scnprintf(args.id, sizeof(args.id),
4257 "%s/%s %u",
4258 clp->cl_ipaddr,
4259 rpc_peeraddr2str(clp->cl_rpcclient,
4260 RPC_DISPLAY_ADDR),
4261 clp->cl_id_uniquifier);
4262
4263 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4264
4265 if (status != NFS4ERR_CLID_INUSE)
4266 break;
4267
4268 if (signalled())
4269 break;
4270
4271 if (++clp->cl_id_uniquifier == 0)
4272 break;
4273 }
4274
4275 dprintk("<-- %s status= %d\n", __func__, status);
4276 return status;
4277}
4278
4279struct nfs4_get_lease_time_data {
4280 struct nfs4_get_lease_time_args *args;
4281 struct nfs4_get_lease_time_res *res;
4282 struct nfs_client *clp;
4283};
4284
4285static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4286 void *calldata)
4287{
4288 int ret;
4289 struct nfs4_get_lease_time_data *data =
4290 (struct nfs4_get_lease_time_data *)calldata;
4291
4292 dprintk("--> %s\n", __func__);
4293 /* just setup sequence, do not trigger session recovery
4294 since we're invoked within one */
4295 ret = nfs41_setup_sequence(data->clp->cl_session,
4296 &data->args->la_seq_args,
4297 &data->res->lr_seq_res, 0, task);
4298
4299 BUG_ON(ret == -EAGAIN);
4300 rpc_call_start(task);
4301 dprintk("<-- %s\n", __func__);
4302}
4303
4304/*
4305 * Called from nfs4_state_manager thread for session setup, so don't recover
4306 * from sequence operation or clientid errors.
4307 */
4308static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4309{
4310 struct nfs4_get_lease_time_data *data =
4311 (struct nfs4_get_lease_time_data *)calldata;
4312
4313 dprintk("--> %s\n", __func__);
4314 nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status);
4315 switch (task->tk_status) {
4316 case -NFS4ERR_DELAY:
4317 case -NFS4ERR_GRACE:
4318 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4319 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4320 task->tk_status = 0;
4321 nfs4_restart_rpc(task, data->clp);
4322 return;
4323 }
4324 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4325 dprintk("<-- %s\n", __func__);
4326}
4327
4328struct rpc_call_ops nfs4_get_lease_time_ops = {
4329 .rpc_call_prepare = nfs4_get_lease_time_prepare,
4330 .rpc_call_done = nfs4_get_lease_time_done,
4331};
4332
4333int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4334{
4335 struct rpc_task *task;
4336 struct nfs4_get_lease_time_args args;
4337 struct nfs4_get_lease_time_res res = {
4338 .lr_fsinfo = fsinfo,
4339 };
4340 struct nfs4_get_lease_time_data data = {
4341 .args = &args,
4342 .res = &res,
4343 .clp = clp,
4344 };
4345 struct rpc_message msg = {
4346 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME],
4347 .rpc_argp = &args,
4348 .rpc_resp = &res,
4349 };
4350 struct rpc_task_setup task_setup = {
4351 .rpc_client = clp->cl_rpcclient,
4352 .rpc_message = &msg,
4353 .callback_ops = &nfs4_get_lease_time_ops,
4354 .callback_data = &data
4355 };
4356 int status;
4357
4358 res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
4359 dprintk("--> %s\n", __func__);
4360 task = rpc_run_task(&task_setup);
4361
4362 if (IS_ERR(task))
4363 status = PTR_ERR(task);
4364 else {
4365 status = task->tk_status;
4366 rpc_put_task(task);
4367 }
4368 dprintk("<-- %s return %d\n", __func__, status);
4369
4370 return status;
4371}
4372
4373/*
4374 * Reset a slot table
4375 */
4376static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
4377 int old_max_slots, int ivalue)
4378{
4379 int i;
4380 int ret = 0;
4381
4382 dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__, max_slots, tbl);
4383
4384 /*
4385 * Until we have dynamic slot table adjustment, insist
4386 * upon the same slot table size
4387 */
4388 if (max_slots != old_max_slots) {
4389 dprintk("%s reset slot table does't match old\n",
4390 __func__);
4391 ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */
4392 goto out;
4393 }
4394 spin_lock(&tbl->slot_tbl_lock);
4395 for (i = 0; i < max_slots; ++i)
4396 tbl->slots[i].seq_nr = ivalue;
4397 tbl->highest_used_slotid = -1;
4398 spin_unlock(&tbl->slot_tbl_lock);
4399 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4400 tbl, tbl->slots, tbl->max_slots);
4401out:
4402 dprintk("<-- %s: return %d\n", __func__, ret);
4403 return ret;
4404}
4405
4406/*
4407 * Reset the forechannel and backchannel slot tables
4408 */
4409static int nfs4_reset_slot_tables(struct nfs4_session *session)
4410{
4411 int status;
4412
4413 status = nfs4_reset_slot_table(&session->fc_slot_table,
4414 session->fc_attrs.max_reqs,
4415 session->fc_slot_table.max_slots,
4416 1);
4417 if (status)
4418 return status;
4419
4420 status = nfs4_reset_slot_table(&session->bc_slot_table,
4421 session->bc_attrs.max_reqs,
4422 session->bc_slot_table.max_slots,
4423 0);
4424 return status;
4425}
4426
4427/* Destroy the slot table */
4428static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4429{
4430 if (session->fc_slot_table.slots != NULL) {
4431 kfree(session->fc_slot_table.slots);
4432 session->fc_slot_table.slots = NULL;
4433 }
4434 if (session->bc_slot_table.slots != NULL) {
4435 kfree(session->bc_slot_table.slots);
4436 session->bc_slot_table.slots = NULL;
4437 }
4438 return;
4439}
4440
4441/*
4442 * Initialize slot table
4443 */
4444static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4445 int max_slots, int ivalue)
4446{
4447 int i;
4448 struct nfs4_slot *slot;
4449 int ret = -ENOMEM;
4450
4451 BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
4452
4453 dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
4454
4455 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4456 if (!slot)
4457 goto out;
4458 for (i = 0; i < max_slots; ++i)
4459 slot[i].seq_nr = ivalue;
4460 ret = 0;
4461
4462 spin_lock(&tbl->slot_tbl_lock);
4463 if (tbl->slots != NULL) {
4464 spin_unlock(&tbl->slot_tbl_lock);
4465 dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
4466 __func__, tbl, tbl->slots);
4467 WARN_ON(1);
4468 goto out_free;
4469 }
4470 tbl->max_slots = max_slots;
4471 tbl->slots = slot;
4472 tbl->highest_used_slotid = -1; /* no slot is currently used */
4473 spin_unlock(&tbl->slot_tbl_lock);
4474 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4475 tbl, tbl->slots, tbl->max_slots);
4476out:
4477 dprintk("<-- %s: return %d\n", __func__, ret);
4478 return ret;
4479
4480out_free:
4481 kfree(slot);
4482 goto out;
4483}
4484
4485/*
4486 * Initialize the forechannel and backchannel tables
4487 */
4488static int nfs4_init_slot_tables(struct nfs4_session *session)
4489{
4490 int status;
4491
4492 status = nfs4_init_slot_table(&session->fc_slot_table,
4493 session->fc_attrs.max_reqs, 1);
4494 if (status)
4495 return status;
4496
4497 status = nfs4_init_slot_table(&session->bc_slot_table,
4498 session->bc_attrs.max_reqs, 0);
4499 if (status)
4500 nfs4_destroy_slot_tables(session);
4501
4502 return status;
4503}
4504
4505struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4506{
4507 struct nfs4_session *session;
4508 struct nfs4_slot_table *tbl;
4509
4510 session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL);
4511 if (!session)
4512 return NULL;
4513
4514 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4515 /*
4516 * The create session reply races with the server back
4517 * channel probe. Mark the client NFS_CS_SESSION_INITING
4518 * so that the client back channel can find the
4519 * nfs_client struct
4520 */
4521 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4522
4523 tbl = &session->fc_slot_table;
4524 spin_lock_init(&tbl->slot_tbl_lock);
4525 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4526
4527 tbl = &session->bc_slot_table;
4528 spin_lock_init(&tbl->slot_tbl_lock);
4529 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4530
4531 session->clp = clp;
4532 return session;
4533}
4534
4535void nfs4_destroy_session(struct nfs4_session *session)
4536{
4537 nfs4_proc_destroy_session(session);
4538 dprintk("%s Destroy backchannel for xprt %p\n",
4539 __func__, session->clp->cl_rpcclient->cl_xprt);
4540 xprt_destroy_backchannel(session->clp->cl_rpcclient->cl_xprt,
4541 NFS41_BC_MIN_CALLBACKS);
4542 nfs4_destroy_slot_tables(session);
4543 kfree(session);
4544}
4545
4546/*
4547 * Initialize the values to be used by the client in CREATE_SESSION
4548 * If nfs4_init_session set the fore channel request and response sizes,
4549 * use them.
4550 *
4551 * Set the back channel max_resp_sz_cached to zero to force the client to
4552 * always set csa_cachethis to FALSE because the current implementation
4553 * of the back channel DRC only supports caching the CB_SEQUENCE operation.
4554 */
4555static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
4556{
4557 struct nfs4_session *session = args->client->cl_session;
4558 unsigned int mxrqst_sz = session->fc_attrs.max_rqst_sz,
4559 mxresp_sz = session->fc_attrs.max_resp_sz;
4560
4561 if (mxrqst_sz == 0)
4562 mxrqst_sz = NFS_MAX_FILE_IO_SIZE;
4563 if (mxresp_sz == 0)
4564 mxresp_sz = NFS_MAX_FILE_IO_SIZE;
4565 /* Fore channel attributes */
4566 args->fc_attrs.headerpadsz = 0;
4567 args->fc_attrs.max_rqst_sz = mxrqst_sz;
4568 args->fc_attrs.max_resp_sz = mxresp_sz;
4569 args->fc_attrs.max_resp_sz_cached = mxresp_sz;
4570 args->fc_attrs.max_ops = NFS4_MAX_OPS;
4571 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
4572
4573 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
4574 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
4575 __func__,
4576 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
4577 args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops,
4578 args->fc_attrs.max_reqs);
4579
4580 /* Back channel attributes */
4581 args->bc_attrs.headerpadsz = 0;
4582 args->bc_attrs.max_rqst_sz = PAGE_SIZE;
4583 args->bc_attrs.max_resp_sz = PAGE_SIZE;
4584 args->bc_attrs.max_resp_sz_cached = 0;
4585 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
4586 args->bc_attrs.max_reqs = 1;
4587
4588 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
4589 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
4590 __func__,
4591 args->bc_attrs.max_rqst_sz, args->bc_attrs.max_resp_sz,
4592 args->bc_attrs.max_resp_sz_cached, args->bc_attrs.max_ops,
4593 args->bc_attrs.max_reqs);
4594}
4595
4596static int _verify_channel_attr(char *chan, char *attr_name, u32 sent, u32 rcvd)
4597{
4598 if (rcvd <= sent)
4599 return 0;
4600 printk(KERN_WARNING "%s: Session INVALID: %s channel %s increased. "
4601 "sent=%u rcvd=%u\n", __func__, chan, attr_name, sent, rcvd);
4602 return -EINVAL;
4603}
4604
4605#define _verify_fore_channel_attr(_name_) \
4606 _verify_channel_attr("fore", #_name_, \
4607 args->fc_attrs._name_, \
4608 session->fc_attrs._name_)
4609
4610#define _verify_back_channel_attr(_name_) \
4611 _verify_channel_attr("back", #_name_, \
4612 args->bc_attrs._name_, \
4613 session->bc_attrs._name_)
4614
4615/*
4616 * The server is not allowed to increase the fore channel header pad size,
4617 * maximum response size, or maximum number of operations.
4618 *
4619 * The back channel attributes are only negotiatied down: We send what the
4620 * (back channel) server insists upon.
4621 */
4622static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args,
4623 struct nfs4_session *session)
4624{
4625 int ret = 0;
4626
4627 ret |= _verify_fore_channel_attr(headerpadsz);
4628 ret |= _verify_fore_channel_attr(max_resp_sz);
4629 ret |= _verify_fore_channel_attr(max_ops);
4630
4631 ret |= _verify_back_channel_attr(headerpadsz);
4632 ret |= _verify_back_channel_attr(max_rqst_sz);
4633 ret |= _verify_back_channel_attr(max_resp_sz);
4634 ret |= _verify_back_channel_attr(max_resp_sz_cached);
4635 ret |= _verify_back_channel_attr(max_ops);
4636 ret |= _verify_back_channel_attr(max_reqs);
4637
4638 return ret;
4639}
4640
4641static int _nfs4_proc_create_session(struct nfs_client *clp)
4642{
4643 struct nfs4_session *session = clp->cl_session;
4644 struct nfs41_create_session_args args = {
4645 .client = clp,
4646 .cb_program = NFS4_CALLBACK,
4647 };
4648 struct nfs41_create_session_res res = {
4649 .client = clp,
4650 };
4651 struct rpc_message msg = {
4652 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION],
4653 .rpc_argp = &args,
4654 .rpc_resp = &res,
4655 };
4656 int status;
4657
4658 nfs4_init_channel_attrs(&args);
4659 args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
4660
4661 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
4662
4663 if (!status)
4664 /* Verify the session's negotiated channel_attrs values */
4665 status = nfs4_verify_channel_attrs(&args, session);
4666 if (!status) {
4667 /* Increment the clientid slot sequence id */
4668 clp->cl_seqid++;
4669 }
4670
4671 return status;
4672}
4673
4674/*
4675 * Issues a CREATE_SESSION operation to the server.
4676 * It is the responsibility of the caller to verify the session is
4677 * expired before calling this routine.
4678 */
4679int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4680{
4681 int status;
4682 unsigned *ptr;
4683 struct nfs_fsinfo fsinfo;
4684 struct nfs4_session *session = clp->cl_session;
4685
4686 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
4687
4688 status = _nfs4_proc_create_session(clp);
4689 if (status)
4690 goto out;
4691
4692 /* Init or reset the fore channel */
4693 if (reset)
4694 status = nfs4_reset_slot_tables(session);
4695 else
4696 status = nfs4_init_slot_tables(session);
4697 dprintk("fore channel slot table initialization returned %d\n", status);
4698 if (status)
4699 goto out;
4700
4701 ptr = (unsigned *)&session->sess_id.data[0];
4702 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4703 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
4704
4705 if (reset)
4706 /* Lease time is aleady set */
4707 goto out;
4708
4709 /* Get the lease time */
4710 status = nfs4_proc_get_lease_time(clp, &fsinfo);
4711 if (status == 0) {
4712 /* Update lease time and schedule renewal */
4713 spin_lock(&clp->cl_lock);
4714 clp->cl_lease_time = fsinfo.lease_time * HZ;
4715 clp->cl_last_renewal = jiffies;
4716 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
4717 spin_unlock(&clp->cl_lock);
4718
4719 nfs4_schedule_state_renewal(clp);
4720 }
4721out:
4722 dprintk("<-- %s\n", __func__);
4723 return status;
4724}
4725
4726/*
4727 * Issue the over-the-wire RPC DESTROY_SESSION.
4728 * The caller must serialize access to this routine.
4729 */
4730int nfs4_proc_destroy_session(struct nfs4_session *session)
4731{
4732 int status = 0;
4733 struct rpc_message msg;
4734
4735 dprintk("--> nfs4_proc_destroy_session\n");
4736
4737 /* session is still being setup */
4738 if (session->clp->cl_cons_state != NFS_CS_READY)
4739 return status;
4740
4741 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION];
4742 msg.rpc_argp = session;
4743 msg.rpc_resp = NULL;
4744 msg.rpc_cred = NULL;
4745 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, 0);
4746
4747 if (status)
4748 printk(KERN_WARNING
4749 "Got error %d from the server on DESTROY_SESSION. "
4750 "Session has been destroyed regardless...\n", status);
4751
4752 dprintk("<-- nfs4_proc_destroy_session\n");
4753 return status;
4754}
4755
4756/*
4757 * Renew the cl_session lease.
4758 */
4759static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4760{
4761 struct nfs4_sequence_args args;
4762 struct nfs4_sequence_res res;
4763
4764 struct rpc_message msg = {
4765 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
4766 .rpc_argp = &args,
4767 .rpc_resp = &res,
4768 .rpc_cred = cred,
4769 };
4770
4771 args.sa_cache_this = 0;
4772
4773 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4774 &res, 0);
4775}
4776
4777void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4778{
4779 struct nfs_client *clp = (struct nfs_client *)data;
4780
4781 nfs41_sequence_done(clp, task->tk_msg.rpc_resp, task->tk_status);
4782
4783 if (task->tk_status < 0) {
4784 dprintk("%s ERROR %d\n", __func__, task->tk_status);
4785
4786 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4787 == -EAGAIN) {
4788 nfs4_restart_rpc(task, clp);
4789 return;
4790 }
4791 }
4792 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4793 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4794
4795 put_rpccred(task->tk_msg.rpc_cred);
4796 kfree(task->tk_msg.rpc_argp);
4797 kfree(task->tk_msg.rpc_resp);
4798
4799 dprintk("<-- %s\n", __func__);
4800}
4801
4802static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
4803{
4804 struct nfs_client *clp;
4805 struct nfs4_sequence_args *args;
4806 struct nfs4_sequence_res *res;
4807
4808 clp = (struct nfs_client *)data;
4809 args = task->tk_msg.rpc_argp;
4810 res = task->tk_msg.rpc_resp;
4811
4812 if (nfs4_setup_sequence(clp, args, res, 0, task))
4813 return;
4814 rpc_call_start(task);
4815}
4816
4817static const struct rpc_call_ops nfs41_sequence_ops = {
4818 .rpc_call_done = nfs41_sequence_call_done,
4819 .rpc_call_prepare = nfs41_sequence_prepare,
4820};
4821
4822static int nfs41_proc_async_sequence(struct nfs_client *clp,
4823 struct rpc_cred *cred)
4824{
4825 struct nfs4_sequence_args *args;
4826 struct nfs4_sequence_res *res;
4827 struct rpc_message msg = {
4828 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
4829 .rpc_cred = cred,
4830 };
4831
4832 args = kzalloc(sizeof(*args), GFP_KERNEL);
4833 if (!args)
4834 return -ENOMEM;
4835 res = kzalloc(sizeof(*res), GFP_KERNEL);
4836 if (!res) {
4837 kfree(args);
4838 return -ENOMEM;
4839 }
4840 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
4841 msg.rpc_argp = args;
4842 msg.rpc_resp = res;
4843
4844 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
4845 &nfs41_sequence_ops, (void *)clp);
4846}
4847
4848#endif /* CONFIG_NFS_V4_1 */
4849
4850struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
3727 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT, 4851 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
3728 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 4852 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
3729 .recover_open = nfs4_open_reclaim, 4853 .recover_open = nfs4_open_reclaim,
3730 .recover_lock = nfs4_lock_reclaim, 4854 .recover_lock = nfs4_lock_reclaim,
4855 .establish_clid = nfs4_init_clientid,
4856 .get_clid_cred = nfs4_get_setclientid_cred,
3731}; 4857};
3732 4858
3733struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = { 4859#if defined(CONFIG_NFS_V4_1)
4860struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4861 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
4862 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4863 .recover_open = nfs4_open_reclaim,
4864 .recover_lock = nfs4_lock_reclaim,
4865 .establish_clid = nfs4_proc_exchange_id,
4866 .get_clid_cred = nfs4_get_exchange_id_cred,
4867};
4868#endif /* CONFIG_NFS_V4_1 */
4869
4870struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
3734 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, 4871 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
3735 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 4872 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
3736 .recover_open = nfs4_open_expired, 4873 .recover_open = nfs4_open_expired,
3737 .recover_lock = nfs4_lock_expired, 4874 .recover_lock = nfs4_lock_expired,
4875 .establish_clid = nfs4_init_clientid,
4876 .get_clid_cred = nfs4_get_setclientid_cred,
4877};
4878
4879#if defined(CONFIG_NFS_V4_1)
4880struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
4881 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
4882 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4883 .recover_open = nfs4_open_expired,
4884 .recover_lock = nfs4_lock_expired,
4885 .establish_clid = nfs4_proc_exchange_id,
4886 .get_clid_cred = nfs4_get_exchange_id_cred,
4887};
4888#endif /* CONFIG_NFS_V4_1 */
4889
4890struct nfs4_state_maintenance_ops nfs40_state_renewal_ops = {
4891 .sched_state_renewal = nfs4_proc_async_renew,
4892 .get_state_renewal_cred_locked = nfs4_get_renew_cred_locked,
4893 .renew_lease = nfs4_proc_renew,
4894};
4895
4896#if defined(CONFIG_NFS_V4_1)
4897struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
4898 .sched_state_renewal = nfs41_proc_async_sequence,
4899 .get_state_renewal_cred_locked = nfs4_get_machine_cred_locked,
4900 .renew_lease = nfs4_proc_sequence,
4901};
4902#endif
4903
4904/*
4905 * Per minor version reboot and network partition recovery ops
4906 */
4907
4908struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[] = {
4909 &nfs40_reboot_recovery_ops,
4910#if defined(CONFIG_NFS_V4_1)
4911 &nfs41_reboot_recovery_ops,
4912#endif
4913};
4914
4915struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[] = {
4916 &nfs40_nograce_recovery_ops,
4917#if defined(CONFIG_NFS_V4_1)
4918 &nfs41_nograce_recovery_ops,
4919#endif
4920};
4921
4922struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = {
4923 &nfs40_state_renewal_ops,
4924#if defined(CONFIG_NFS_V4_1)
4925 &nfs41_state_renewal_ops,
4926#endif
3738}; 4927};
3739 4928
3740static const struct inode_operations nfs4_file_inode_operations = { 4929static 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..2cfca9929c9a 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/*
@@ -1042,6 +1048,14 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1042 case -NFS4ERR_EXPIRED: 1048 case -NFS4ERR_EXPIRED:
1043 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1049 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1044 nfs4_state_start_reclaim_nograce(clp); 1050 nfs4_state_start_reclaim_nograce(clp);
1051 case -NFS4ERR_BADSESSION:
1052 case -NFS4ERR_BADSLOT:
1053 case -NFS4ERR_BAD_HIGH_SLOT:
1054 case -NFS4ERR_DEADSESSION:
1055 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1056 case -NFS4ERR_SEQ_FALSE_RETRY:
1057 case -NFS4ERR_SEQ_MISORDERED:
1058 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1045 } 1059 }
1046} 1060}
1047 1061
@@ -1075,18 +1089,22 @@ restart:
1075static int nfs4_check_lease(struct nfs_client *clp) 1089static int nfs4_check_lease(struct nfs_client *clp)
1076{ 1090{
1077 struct rpc_cred *cred; 1091 struct rpc_cred *cred;
1092 struct nfs4_state_maintenance_ops *ops =
1093 nfs4_state_renewal_ops[clp->cl_minorversion];
1078 int status = -NFS4ERR_EXPIRED; 1094 int status = -NFS4ERR_EXPIRED;
1079 1095
1080 /* Is the client already known to have an expired lease? */ 1096 /* Is the client already known to have an expired lease? */
1081 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 1097 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1082 return 0; 1098 return 0;
1083 cred = nfs4_get_renew_cred(clp); 1099 spin_lock(&clp->cl_lock);
1100 cred = ops->get_state_renewal_cred_locked(clp);
1101 spin_unlock(&clp->cl_lock);
1084 if (cred == NULL) { 1102 if (cred == NULL) {
1085 cred = nfs4_get_setclientid_cred(clp); 1103 cred = nfs4_get_setclientid_cred(clp);
1086 if (cred == NULL) 1104 if (cred == NULL)
1087 goto out; 1105 goto out;
1088 } 1106 }
1089 status = nfs4_proc_renew(clp, cred); 1107 status = ops->renew_lease(clp, cred);
1090 put_rpccred(cred); 1108 put_rpccred(cred);
1091out: 1109out:
1092 nfs4_recovery_handle_error(clp, status); 1110 nfs4_recovery_handle_error(clp, status);
@@ -1096,21 +1114,98 @@ out:
1096static int nfs4_reclaim_lease(struct nfs_client *clp) 1114static int nfs4_reclaim_lease(struct nfs_client *clp)
1097{ 1115{
1098 struct rpc_cred *cred; 1116 struct rpc_cred *cred;
1117 struct nfs4_state_recovery_ops *ops =
1118 nfs4_reboot_recovery_ops[clp->cl_minorversion];
1099 int status = -ENOENT; 1119 int status = -ENOENT;
1100 1120
1101 cred = nfs4_get_setclientid_cred(clp); 1121 cred = ops->get_clid_cred(clp);
1102 if (cred != NULL) { 1122 if (cred != NULL) {
1103 status = nfs4_init_client(clp, cred); 1123 status = ops->establish_clid(clp, cred);
1104 put_rpccred(cred); 1124 put_rpccred(cred);
1105 /* Handle case where the user hasn't set up machine creds */ 1125 /* Handle case where the user hasn't set up machine creds */
1106 if (status == -EACCES && cred == clp->cl_machine_cred) { 1126 if (status == -EACCES && cred == clp->cl_machine_cred) {
1107 nfs4_clear_machine_cred(clp); 1127 nfs4_clear_machine_cred(clp);
1108 status = -EAGAIN; 1128 status = -EAGAIN;
1109 } 1129 }
1130 if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
1131 status = -EPROTONOSUPPORT;
1110 } 1132 }
1111 return status; 1133 return status;
1112} 1134}
1113 1135
1136#ifdef CONFIG_NFS_V4_1
1137static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
1138{
1139 switch (err) {
1140 case -NFS4ERR_STALE_CLIENTID:
1141 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1142 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1143 }
1144}
1145
1146static int nfs4_reset_session(struct nfs_client *clp)
1147{
1148 int status;
1149
1150 status = nfs4_proc_destroy_session(clp->cl_session);
1151 if (status && status != -NFS4ERR_BADSESSION &&
1152 status != -NFS4ERR_DEADSESSION) {
1153 nfs4_session_recovery_handle_error(clp, status);
1154 goto out;
1155 }
1156
1157 memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
1158 status = nfs4_proc_create_session(clp, 1);
1159 if (status)
1160 nfs4_session_recovery_handle_error(clp, status);
1161 /* fall through*/
1162out:
1163 /* Wake up the next rpc task even on error */
1164 rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
1165 return status;
1166}
1167
1168static int nfs4_initialize_session(struct nfs_client *clp)
1169{
1170 int status;
1171
1172 status = nfs4_proc_create_session(clp, 0);
1173 if (!status) {
1174 nfs_mark_client_ready(clp, NFS_CS_READY);
1175 } else if (status == -NFS4ERR_STALE_CLIENTID) {
1176 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1177 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1178 } else {
1179 nfs_mark_client_ready(clp, status);
1180 }
1181 return status;
1182}
1183#else /* CONFIG_NFS_V4_1 */
1184static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1185static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
1186#endif /* CONFIG_NFS_V4_1 */
1187
1188/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
1189 * on EXCHANGE_ID for v4.1
1190 */
1191static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1192{
1193 if (nfs4_has_session(clp)) {
1194 switch (status) {
1195 case -NFS4ERR_DELAY:
1196 case -NFS4ERR_CLID_INUSE:
1197 case -EAGAIN:
1198 break;
1199
1200 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1201 * in nfs4_exchange_id */
1202 default:
1203 return;
1204 }
1205 }
1206 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1207}
1208
1114static void nfs4_state_manager(struct nfs_client *clp) 1209static void nfs4_state_manager(struct nfs_client *clp)
1115{ 1210{
1116 int status = 0; 1211 int status = 0;
@@ -1121,9 +1216,12 @@ static void nfs4_state_manager(struct nfs_client *clp)
1121 /* We're going to have to re-establish a clientid */ 1216 /* We're going to have to re-establish a clientid */
1122 status = nfs4_reclaim_lease(clp); 1217 status = nfs4_reclaim_lease(clp);
1123 if (status) { 1218 if (status) {
1124 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1219 nfs4_set_lease_expired(clp, status);
1125 if (status == -EAGAIN) 1220 if (status == -EAGAIN)
1126 continue; 1221 continue;
1222 if (clp->cl_cons_state ==
1223 NFS_CS_SESSION_INITING)
1224 nfs_mark_client_ready(clp, status);
1127 goto out_error; 1225 goto out_error;
1128 } 1226 }
1129 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1227 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
@@ -1134,25 +1232,44 @@ static void nfs4_state_manager(struct nfs_client *clp)
1134 if (status != 0) 1232 if (status != 0)
1135 continue; 1233 continue;
1136 } 1234 }
1137 1235 /* Initialize or reset the session */
1236 if (nfs4_has_session(clp) &&
1237 test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
1238 if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
1239 status = nfs4_initialize_session(clp);
1240 else
1241 status = nfs4_reset_session(clp);
1242 if (status) {
1243 if (status == -NFS4ERR_STALE_CLIENTID)
1244 continue;
1245 goto out_error;
1246 }
1247 }
1138 /* First recover reboot state... */ 1248 /* First recover reboot state... */
1139 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { 1249 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1140 status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); 1250 status = nfs4_do_reclaim(clp,
1251 nfs4_reboot_recovery_ops[clp->cl_minorversion]);
1141 if (status == -NFS4ERR_STALE_CLIENTID) 1252 if (status == -NFS4ERR_STALE_CLIENTID)
1142 continue; 1253 continue;
1254 if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
1255 continue;
1143 nfs4_state_end_reclaim_reboot(clp); 1256 nfs4_state_end_reclaim_reboot(clp);
1144 continue; 1257 continue;
1145 } 1258 }
1146 1259
1147 /* Now recover expired state... */ 1260 /* Now recover expired state... */
1148 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { 1261 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
1149 status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops); 1262 status = nfs4_do_reclaim(clp,
1263 nfs4_nograce_recovery_ops[clp->cl_minorversion]);
1150 if (status < 0) { 1264 if (status < 0) {
1151 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); 1265 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1152 if (status == -NFS4ERR_STALE_CLIENTID) 1266 if (status == -NFS4ERR_STALE_CLIENTID)
1153 continue; 1267 continue;
1154 if (status == -NFS4ERR_EXPIRED) 1268 if (status == -NFS4ERR_EXPIRED)
1155 continue; 1269 continue;
1270 if (test_bit(NFS4CLNT_SESSION_SETUP,
1271 &clp->cl_state))
1272 continue;
1156 goto out_error; 1273 goto out_error;
1157 } else 1274 } else
1158 nfs4_state_end_reclaim_nograce(clp); 1275 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/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..6063054455f8 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,
@@ -155,6 +156,7 @@ static const match_table_t nfs_mount_option_tokens = {
155 { Opt_mountvers, "mountvers=%u" }, 156 { Opt_mountvers, "mountvers=%u" },
156 { Opt_nfsvers, "nfsvers=%u" }, 157 { Opt_nfsvers, "nfsvers=%u" },
157 { Opt_nfsvers, "vers=%u" }, 158 { Opt_nfsvers, "vers=%u" },
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" },
@@ -1211,6 +1213,13 @@ static int nfs_parse_mount_options(char *raw,
1211 nfs_parse_invalid_value("nfsvers"); 1213 nfs_parse_invalid_value("nfsvers");
1212 } 1214 }
1213 break; 1215 break;
1216 case Opt_minorversion:
1217 if (match_int(args, &option))
1218 return 0;
1219 if (option < 0 || option > NFS4_MAX_MINOR_VERSION)
1220 return 0;
1221 mnt->minorversion = option;
1222 break;
1214 1223
1215 /* 1224 /*
1216 * options that take text values 1225 * options that take text values
@@ -2263,6 +2272,7 @@ static int nfs4_validate_mount_data(void *options,
2263 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ 2272 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
2264 args->auth_flavors[0] = RPC_AUTH_UNIX; 2273 args->auth_flavors[0] = RPC_AUTH_UNIX;
2265 args->auth_flavor_len = 0; 2274 args->auth_flavor_len = 0;
2275 args->minorversion = 0;
2266 2276
2267 switch (data->version) { 2277 switch (data->version) {
2268 case 1: 2278 case 1:
@@ -2477,12 +2487,13 @@ static void nfs4_kill_super(struct super_block *sb)
2477{ 2487{
2478 struct nfs_server *server = NFS_SB(sb); 2488 struct nfs_server *server = NFS_SB(sb);
2479 2489
2490 dprintk("--> %s\n", __func__);
2480 nfs_super_return_all_delegations(sb); 2491 nfs_super_return_all_delegations(sb);
2481 kill_anon_super(sb); 2492 kill_anon_super(sb);
2482
2483 nfs4_renewd_prepare_shutdown(server); 2493 nfs4_renewd_prepare_shutdown(server);
2484 nfs_fscache_release_super_cookie(sb); 2494 nfs_fscache_release_super_cookie(sb);
2485 nfs_free_server(server); 2495 nfs_free_server(server);
2496 dprintk("<-- %s\n", __func__);
2486} 2497}
2487 2498
2488/* 2499/*
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};