aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-11-02 23:56:40 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-11-02 23:56:40 -0400
commit31cbecb4ab538f433145bc5a46f3bea9b9627031 (patch)
treed6206d42dea7298f7ef05fd1f7bf474245f0d43a /fs/nfsd
parent2b72c9ccd22c4a3299e5a358dcd639fb253730f4 (diff)
parent278c023a99b0d6b471d0f4a79835c703482e29ac (diff)
Merge branch 'osd-devel' into nfs-for-next
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/export.c16
-rw-r--r--fs/nfsd/nfs4callback.c20
-rw-r--r--fs/nfsd/nfs4proc.c374
-rw-r--r--fs/nfsd/nfs4recover.c53
-rw-r--r--fs/nfsd/nfs4state.c1794
-rw-r--r--fs/nfsd/nfs4xdr.c380
-rw-r--r--fs/nfsd/nfsctl.c1
-rw-r--r--fs/nfsd/nfsd.h33
-rw-r--r--fs/nfsd/nfsfh.c39
-rw-r--r--fs/nfsd/state.h174
-rw-r--r--fs/nfsd/vfs.c31
-rw-r--r--fs/nfsd/vfs.h29
-rw-r--r--fs/nfsd/xdr4.h28
13 files changed, 1645 insertions, 1327 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index f4cc1e2bfc54..62f3b9074e84 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -16,7 +16,6 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/exportfs.h> 17#include <linux/exportfs.h>
18 18
19#include <linux/nfsd/syscall.h>
20#include <net/ipv6.h> 19#include <net/ipv6.h>
21 20
22#include "nfsd.h" 21#include "nfsd.h"
@@ -318,7 +317,6 @@ static void svc_export_put(struct kref *ref)
318 struct svc_export *exp = container_of(ref, struct svc_export, h.ref); 317 struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
319 path_put(&exp->ex_path); 318 path_put(&exp->ex_path);
320 auth_domain_put(exp->ex_client); 319 auth_domain_put(exp->ex_client);
321 kfree(exp->ex_pathname);
322 nfsd4_fslocs_free(&exp->ex_fslocs); 320 nfsd4_fslocs_free(&exp->ex_fslocs);
323 kfree(exp); 321 kfree(exp);
324} 322}
@@ -528,11 +526,6 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
528 526
529 exp.ex_client = dom; 527 exp.ex_client = dom;
530 528
531 err = -ENOMEM;
532 exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
533 if (!exp.ex_pathname)
534 goto out2;
535
536 /* expiry */ 529 /* expiry */
537 err = -EINVAL; 530 err = -EINVAL;
538 exp.h.expiry_time = get_expiry(&mesg); 531 exp.h.expiry_time = get_expiry(&mesg);
@@ -613,8 +606,6 @@ out4:
613 nfsd4_fslocs_free(&exp.ex_fslocs); 606 nfsd4_fslocs_free(&exp.ex_fslocs);
614 kfree(exp.ex_uuid); 607 kfree(exp.ex_uuid);
615out3: 608out3:
616 kfree(exp.ex_pathname);
617out2:
618 path_put(&exp.ex_path); 609 path_put(&exp.ex_path);
619out1: 610out1:
620 auth_domain_put(dom); 611 auth_domain_put(dom);
@@ -678,7 +669,6 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
678 new->ex_client = item->ex_client; 669 new->ex_client = item->ex_client;
679 new->ex_path.dentry = dget(item->ex_path.dentry); 670 new->ex_path.dentry = dget(item->ex_path.dentry);
680 new->ex_path.mnt = mntget(item->ex_path.mnt); 671 new->ex_path.mnt = mntget(item->ex_path.mnt);
681 new->ex_pathname = NULL;
682 new->ex_fslocs.locations = NULL; 672 new->ex_fslocs.locations = NULL;
683 new->ex_fslocs.locations_count = 0; 673 new->ex_fslocs.locations_count = 0;
684 new->ex_fslocs.migrated = 0; 674 new->ex_fslocs.migrated = 0;
@@ -696,8 +686,6 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
696 new->ex_fsid = item->ex_fsid; 686 new->ex_fsid = item->ex_fsid;
697 new->ex_uuid = item->ex_uuid; 687 new->ex_uuid = item->ex_uuid;
698 item->ex_uuid = NULL; 688 item->ex_uuid = NULL;
699 new->ex_pathname = item->ex_pathname;
700 item->ex_pathname = NULL;
701 new->ex_fslocs.locations = item->ex_fslocs.locations; 689 new->ex_fslocs.locations = item->ex_fslocs.locations;
702 item->ex_fslocs.locations = NULL; 690 item->ex_fslocs.locations = NULL;
703 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count; 691 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
@@ -1010,7 +998,7 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
1010 return exp; 998 return exp;
1011} 999}
1012 1000
1013static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp) 1001struct svc_export *rqst_find_fsidzero_export(struct svc_rqst *rqstp)
1014{ 1002{
1015 u32 fsidv[2]; 1003 u32 fsidv[2];
1016 1004
@@ -1030,7 +1018,7 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
1030 struct svc_export *exp; 1018 struct svc_export *exp;
1031 __be32 rv; 1019 __be32 rv;
1032 1020
1033 exp = find_fsidzero_export(rqstp); 1021 exp = rqst_find_fsidzero_export(rqstp);
1034 if (IS_ERR(exp)) 1022 if (IS_ERR(exp))
1035 return nfserrno(PTR_ERR(exp)); 1023 return nfserrno(PTR_ERR(exp));
1036 rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); 1024 rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 02eb4edf0ece..7748d6a18d97 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -39,6 +39,8 @@
39 39
40#define NFSDDBG_FACILITY NFSDDBG_PROC 40#define NFSDDBG_FACILITY NFSDDBG_PROC
41 41
42static void nfsd4_mark_cb_fault(struct nfs4_client *, int reason);
43
42#define NFSPROC4_CB_NULL 0 44#define NFSPROC4_CB_NULL 0
43#define NFSPROC4_CB_COMPOUND 1 45#define NFSPROC4_CB_COMPOUND 1
44 46
@@ -351,7 +353,7 @@ static void encode_cb_recall4args(struct xdr_stream *xdr,
351 __be32 *p; 353 __be32 *p;
352 354
353 encode_nfs_cb_opnum4(xdr, OP_CB_RECALL); 355 encode_nfs_cb_opnum4(xdr, OP_CB_RECALL);
354 encode_stateid4(xdr, &dp->dl_stateid); 356 encode_stateid4(xdr, &dp->dl_stid.sc_stateid);
355 357
356 p = xdr_reserve_space(xdr, 4); 358 p = xdr_reserve_space(xdr, 4);
357 *p++ = xdr_zero; /* truncate */ 359 *p++ = xdr_zero; /* truncate */
@@ -460,6 +462,8 @@ static int decode_cb_sequence4resok(struct xdr_stream *xdr,
460 */ 462 */
461 status = 0; 463 status = 0;
462out: 464out:
465 if (status)
466 nfsd4_mark_cb_fault(cb->cb_clp, status);
463 return status; 467 return status;
464out_overflow: 468out_overflow:
465 print_overflow_msg(__func__, xdr); 469 print_overflow_msg(__func__, xdr);
@@ -686,6 +690,12 @@ static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
686 warn_no_callback_path(clp, reason); 690 warn_no_callback_path(clp, reason);
687} 691}
688 692
693static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
694{
695 clp->cl_cb_state = NFSD4_CB_FAULT;
696 warn_no_callback_path(clp, reason);
697}
698
689static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 699static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
690{ 700{
691 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null); 701 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
@@ -787,7 +797,7 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
787{ 797{
788 struct nfsd4_callback *cb = calldata; 798 struct nfsd4_callback *cb = calldata;
789 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); 799 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
790 struct nfs4_client *clp = dp->dl_client; 800 struct nfs4_client *clp = dp->dl_stid.sc_client;
791 u32 minorversion = clp->cl_minorversion; 801 u32 minorversion = clp->cl_minorversion;
792 802
793 cb->cb_minorversion = minorversion; 803 cb->cb_minorversion = minorversion;
@@ -809,7 +819,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
809{ 819{
810 struct nfsd4_callback *cb = calldata; 820 struct nfsd4_callback *cb = calldata;
811 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); 821 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
812 struct nfs4_client *clp = dp->dl_client; 822 struct nfs4_client *clp = dp->dl_stid.sc_client;
813 823
814 dprintk("%s: minorversion=%d\n", __func__, 824 dprintk("%s: minorversion=%d\n", __func__,
815 clp->cl_minorversion); 825 clp->cl_minorversion);
@@ -832,7 +842,7 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
832{ 842{
833 struct nfsd4_callback *cb = calldata; 843 struct nfsd4_callback *cb = calldata;
834 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall); 844 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
835 struct nfs4_client *clp = dp->dl_client; 845 struct nfs4_client *clp = dp->dl_stid.sc_client;
836 struct rpc_clnt *current_rpc_client = clp->cl_cb_client; 846 struct rpc_clnt *current_rpc_client = clp->cl_cb_client;
837 847
838 nfsd4_cb_done(task, calldata); 848 nfsd4_cb_done(task, calldata);
@@ -1006,7 +1016,7 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
1006void nfsd4_cb_recall(struct nfs4_delegation *dp) 1016void nfsd4_cb_recall(struct nfs4_delegation *dp)
1007{ 1017{
1008 struct nfsd4_callback *cb = &dp->dl_recall; 1018 struct nfsd4_callback *cb = &dp->dl_recall;
1009 struct nfs4_client *clp = dp->dl_client; 1019 struct nfs4_client *clp = dp->dl_stid.sc_client;
1010 1020
1011 dp->dl_retries = 1; 1021 dp->dl_retries = 1;
1012 cb->cb_op = dp; 1022 cb->cb_op = dp;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e80777666618..fa383361bc61 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -35,6 +35,7 @@
35#include <linux/file.h> 35#include <linux/file.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37 37
38#include "idmap.h"
38#include "cache.h" 39#include "cache.h"
39#include "xdr4.h" 40#include "xdr4.h"
40#include "vfs.h" 41#include "vfs.h"
@@ -156,6 +157,8 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
156 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 157 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
157 return nfserr_inval; 158 return nfserr_inval;
158 159
160 accmode |= NFSD_MAY_READ_IF_EXEC;
161
159 if (open->op_share_access & NFS4_SHARE_ACCESS_READ) 162 if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
160 accmode |= NFSD_MAY_READ; 163 accmode |= NFSD_MAY_READ;
161 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 164 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
@@ -168,12 +171,29 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
168 return status; 171 return status;
169} 172}
170 173
174static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
175{
176 umode_t mode = fh->fh_dentry->d_inode->i_mode;
177
178 if (S_ISREG(mode))
179 return nfs_ok;
180 if (S_ISDIR(mode))
181 return nfserr_isdir;
182 /*
183 * Using err_symlink as our catch-all case may look odd; but
184 * there's no other obvious error for this case in 4.0, and we
185 * happen to know that it will cause the linux v4 client to do
186 * the right thing on attempts to open something other than a
187 * regular file.
188 */
189 return nfserr_symlink;
190}
191
171static __be32 192static __be32
172do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 193do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
173{ 194{
174 struct svc_fh resfh; 195 struct svc_fh resfh;
175 __be32 status; 196 __be32 status;
176 int created = 0;
177 197
178 fh_init(&resfh, NFS4_FHSIZE); 198 fh_init(&resfh, NFS4_FHSIZE);
179 open->op_truncate = 0; 199 open->op_truncate = 0;
@@ -202,7 +222,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
202 open->op_fname.len, &open->op_iattr, 222 open->op_fname.len, &open->op_iattr,
203 &resfh, open->op_createmode, 223 &resfh, open->op_createmode,
204 (u32 *)open->op_verf.data, 224 (u32 *)open->op_verf.data,
205 &open->op_truncate, &created); 225 &open->op_truncate, &open->op_created);
206 226
207 /* 227 /*
208 * Following rfc 3530 14.2.16, use the returned bitmask 228 * Following rfc 3530 14.2.16, use the returned bitmask
@@ -216,6 +236,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
216 status = nfsd_lookup(rqstp, current_fh, 236 status = nfsd_lookup(rqstp, current_fh,
217 open->op_fname.data, open->op_fname.len, &resfh); 237 open->op_fname.data, open->op_fname.len, &resfh);
218 fh_unlock(current_fh); 238 fh_unlock(current_fh);
239 if (status)
240 goto out;
241 status = nfsd_check_obj_isreg(&resfh);
219 } 242 }
220 if (status) 243 if (status)
221 goto out; 244 goto out;
@@ -227,9 +250,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
227 fh_dup2(current_fh, &resfh); 250 fh_dup2(current_fh, &resfh);
228 251
229 /* set reply cache */ 252 /* set reply cache */
230 fh_copy_shallow(&open->op_stateowner->so_replay.rp_openfh, 253 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
231 &resfh.fh_handle); 254 &resfh.fh_handle);
232 if (!created) 255 if (!open->op_created)
233 status = do_open_permission(rqstp, current_fh, open, 256 status = do_open_permission(rqstp, current_fh, open,
234 NFSD_MAY_NOP); 257 NFSD_MAY_NOP);
235 258
@@ -254,7 +277,7 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
254 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info)); 277 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
255 278
256 /* set replay cache */ 279 /* set replay cache */
257 fh_copy_shallow(&open->op_stateowner->so_replay.rp_openfh, 280 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
258 &current_fh->fh_handle); 281 &current_fh->fh_handle);
259 282
260 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 283 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
@@ -283,14 +306,18 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
283 __be32 status; 306 __be32 status;
284 struct nfsd4_compoundres *resp; 307 struct nfsd4_compoundres *resp;
285 308
286 dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", 309 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
287 (int)open->op_fname.len, open->op_fname.data, 310 (int)open->op_fname.len, open->op_fname.data,
288 open->op_stateowner); 311 open->op_openowner);
289 312
290 /* This check required by spec. */ 313 /* This check required by spec. */
291 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 314 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
292 return nfserr_inval; 315 return nfserr_inval;
293 316
317 /* We don't yet support WANT bits: */
318 open->op_share_access &= NFS4_SHARE_ACCESS_MASK;
319
320 open->op_created = 0;
294 /* 321 /*
295 * RFC5661 18.51.3 322 * RFC5661 18.51.3
296 * Before RECLAIM_COMPLETE done, server should deny new lock 323 * Before RECLAIM_COMPLETE done, server should deny new lock
@@ -309,7 +336,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
309 resp = rqstp->rq_resp; 336 resp = rqstp->rq_resp;
310 status = nfsd4_process_open1(&resp->cstate, open); 337 status = nfsd4_process_open1(&resp->cstate, open);
311 if (status == nfserr_replay_me) { 338 if (status == nfserr_replay_me) {
312 struct nfs4_replay *rp = &open->op_stateowner->so_replay; 339 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
313 fh_put(&cstate->current_fh); 340 fh_put(&cstate->current_fh);
314 fh_copy_shallow(&cstate->current_fh.fh_handle, 341 fh_copy_shallow(&cstate->current_fh.fh_handle,
315 &rp->rp_openfh); 342 &rp->rp_openfh);
@@ -339,32 +366,23 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
339 switch (open->op_claim_type) { 366 switch (open->op_claim_type) {
340 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 367 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
341 case NFS4_OPEN_CLAIM_NULL: 368 case NFS4_OPEN_CLAIM_NULL:
342 /*
343 * (1) set CURRENT_FH to the file being opened,
344 * creating it if necessary, (2) set open->op_cinfo,
345 * (3) set open->op_truncate if the file is to be
346 * truncated after opening, (4) do permission checking.
347 */
348 status = do_open_lookup(rqstp, &cstate->current_fh, 369 status = do_open_lookup(rqstp, &cstate->current_fh,
349 open); 370 open);
350 if (status) 371 if (status)
351 goto out; 372 goto out;
352 break; 373 break;
353 case NFS4_OPEN_CLAIM_PREVIOUS: 374 case NFS4_OPEN_CLAIM_PREVIOUS:
354 open->op_stateowner->so_confirmed = 1; 375 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
355 /* 376 case NFS4_OPEN_CLAIM_FH:
356 * The CURRENT_FH is already set to the file being 377 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
357 * opened. (1) set open->op_cinfo, (2) set
358 * open->op_truncate if the file is to be truncated
359 * after opening, (3) do permission checking.
360 */
361 status = do_open_fhandle(rqstp, &cstate->current_fh, 378 status = do_open_fhandle(rqstp, &cstate->current_fh,
362 open); 379 open);
363 if (status) 380 if (status)
364 goto out; 381 goto out;
365 break; 382 break;
383 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
366 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 384 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
367 open->op_stateowner->so_confirmed = 1; 385 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
368 dprintk("NFSD: unsupported OPEN claim type %d\n", 386 dprintk("NFSD: unsupported OPEN claim type %d\n",
369 open->op_claim_type); 387 open->op_claim_type);
370 status = nfserr_notsupp; 388 status = nfserr_notsupp;
@@ -381,12 +399,13 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
381 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 399 * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
382 */ 400 */
383 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 401 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
402 WARN_ON(status && open->op_created);
384out: 403out:
385 if (open->op_stateowner) { 404 nfsd4_cleanup_open_state(open, status);
386 nfs4_get_stateowner(open->op_stateowner); 405 if (open->op_openowner)
387 cstate->replay_owner = open->op_stateowner; 406 cstate->replay_owner = &open->op_openowner->oo_owner;
388 } 407 else
389 nfs4_unlock_state(); 408 nfs4_unlock_state();
390 return status; 409 return status;
391} 410}
392 411
@@ -467,17 +486,12 @@ static __be32
467nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 486nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
468 struct nfsd4_commit *commit) 487 struct nfsd4_commit *commit)
469{ 488{
470 __be32 status;
471
472 u32 *p = (u32 *)commit->co_verf.data; 489 u32 *p = (u32 *)commit->co_verf.data;
473 *p++ = nfssvc_boot.tv_sec; 490 *p++ = nfssvc_boot.tv_sec;
474 *p++ = nfssvc_boot.tv_usec; 491 *p++ = nfssvc_boot.tv_usec;
475 492
476 status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 493 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
477 commit->co_count); 494 commit->co_count);
478 if (status == nfserr_symlink)
479 status = nfserr_inval;
480 return status;
481} 495}
482 496
483static __be32 497static __be32
@@ -492,8 +506,6 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
492 506
493 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, 507 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR,
494 NFSD_MAY_CREATE); 508 NFSD_MAY_CREATE);
495 if (status == nfserr_symlink)
496 status = nfserr_notdir;
497 if (status) 509 if (status)
498 return status; 510 return status;
499 511
@@ -691,7 +703,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
691 readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); 703 readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
692 readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); 704 readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
693 705
694 if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || 706 if ((cookie == 1) || (cookie == 2) ||
695 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) 707 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
696 return nfserr_bad_cookie; 708 return nfserr_bad_cookie;
697 709
@@ -719,8 +731,6 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
719 return nfserr_grace; 731 return nfserr_grace;
720 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 732 status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
721 remove->rm_name, remove->rm_namelen); 733 remove->rm_name, remove->rm_namelen);
722 if (status == nfserr_symlink)
723 return nfserr_notdir;
724 if (!status) { 734 if (!status) {
725 fh_unlock(&cstate->current_fh); 735 fh_unlock(&cstate->current_fh);
726 set_change_info(&remove->rm_cinfo, &cstate->current_fh); 736 set_change_info(&remove->rm_cinfo, &cstate->current_fh);
@@ -751,8 +761,6 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
751 (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && 761 (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) &&
752 S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) 762 S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode)))
753 status = nfserr_exist; 763 status = nfserr_exist;
754 else if (status == nfserr_symlink)
755 status = nfserr_notdir;
756 764
757 if (!status) { 765 if (!status) {
758 set_change_info(&rename->rn_sinfo, &cstate->current_fh); 766 set_change_info(&rename->rn_sinfo, &cstate->current_fh);
@@ -892,8 +900,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
892 900
893 write->wr_bytes_written = cnt; 901 write->wr_bytes_written = cnt;
894 902
895 if (status == nfserr_symlink)
896 status = nfserr_inval;
897 return status; 903 return status;
898} 904}
899 905
@@ -930,7 +936,7 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
930 count = 4 + (verify->ve_attrlen >> 2); 936 count = 4 + (verify->ve_attrlen >> 2);
931 buf = kmalloc(count << 2, GFP_KERNEL); 937 buf = kmalloc(count << 2, GFP_KERNEL);
932 if (!buf) 938 if (!buf)
933 return nfserr_resource; 939 return nfserr_jukebox;
934 940
935 status = nfsd4_encode_fattr(&cstate->current_fh, 941 status = nfsd4_encode_fattr(&cstate->current_fh,
936 cstate->current_fh.fh_export, 942 cstate->current_fh.fh_export,
@@ -994,6 +1000,8 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
994 1000
995typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1001typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
996 void *); 1002 void *);
1003typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1004
997enum nfsd4_op_flags { 1005enum nfsd4_op_flags {
998 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1006 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
999 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 1007 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
@@ -1001,13 +1009,15 @@ enum nfsd4_op_flags {
1001 /* For rfc 5661 section 2.6.3.1.1: */ 1009 /* For rfc 5661 section 2.6.3.1.1: */
1002 OP_HANDLES_WRONGSEC = 1 << 3, 1010 OP_HANDLES_WRONGSEC = 1 << 3,
1003 OP_IS_PUTFH_LIKE = 1 << 4, 1011 OP_IS_PUTFH_LIKE = 1 << 4,
1004};
1005
1006struct nfsd4_operation {
1007 nfsd4op_func op_func;
1008 u32 op_flags;
1009 char *op_name;
1010 /* 1012 /*
1013 * These are the ops whose result size we estimate before
1014 * encoding, to avoid performing an op then not being able to
1015 * respond or cache a response. This includes writes and setattrs
1016 * as well as the operations usually called "nonidempotent":
1017 */
1018 OP_MODIFIES_SOMETHING = 1 << 5,
1019 /*
1020 * Cache compounds containing these ops in the xid-based drc:
1011 * We use the DRC for compounds containing non-idempotent 1021 * We use the DRC for compounds containing non-idempotent
1012 * operations, *except* those that are 4.1-specific (since 1022 * operations, *except* those that are 4.1-specific (since
1013 * sessions provide their own EOS), and except for stateful 1023 * sessions provide their own EOS), and except for stateful
@@ -1015,7 +1025,15 @@ struct nfsd4_operation {
1015 * (since sequence numbers provide EOS for open, lock, etc in 1025 * (since sequence numbers provide EOS for open, lock, etc in
1016 * the v4.0 case). 1026 * the v4.0 case).
1017 */ 1027 */
1018 bool op_cacheresult; 1028 OP_CACHEME = 1 << 6,
1029};
1030
1031struct nfsd4_operation {
1032 nfsd4op_func op_func;
1033 u32 op_flags;
1034 char *op_name;
1035 /* Try to get response size before operation */
1036 nfsd4op_rsize op_rsize_bop;
1019}; 1037};
1020 1038
1021static struct nfsd4_operation nfsd4_ops[]; 1039static struct nfsd4_operation nfsd4_ops[];
@@ -1062,7 +1080,7 @@ static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
1062 1080
1063bool nfsd4_cache_this_op(struct nfsd4_op *op) 1081bool nfsd4_cache_this_op(struct nfsd4_op *op)
1064{ 1082{
1065 return OPDESC(op)->op_cacheresult; 1083 return OPDESC(op)->op_flags & OP_CACHEME;
1066} 1084}
1067 1085
1068static bool need_wrongsec_check(struct svc_rqst *rqstp) 1086static bool need_wrongsec_check(struct svc_rqst *rqstp)
@@ -1110,6 +1128,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1110 struct nfsd4_operation *opdesc; 1128 struct nfsd4_operation *opdesc;
1111 struct nfsd4_compound_state *cstate = &resp->cstate; 1129 struct nfsd4_compound_state *cstate = &resp->cstate;
1112 int slack_bytes; 1130 int slack_bytes;
1131 u32 plen = 0;
1113 __be32 status; 1132 __be32 status;
1114 1133
1115 resp->xbuf = &rqstp->rq_res; 1134 resp->xbuf = &rqstp->rq_res;
@@ -1188,6 +1207,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1188 goto encode_op; 1207 goto encode_op;
1189 } 1208 }
1190 1209
1210 /* If op is non-idempotent */
1211 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
1212 plen = opdesc->op_rsize_bop(rqstp, op);
1213 op->status = nfsd4_check_resp_size(resp, plen);
1214 }
1215
1216 if (op->status)
1217 goto encode_op;
1218
1191 if (opdesc->op_func) 1219 if (opdesc->op_func)
1192 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1220 op->status = opdesc->op_func(rqstp, cstate, &op->u);
1193 else 1221 else
@@ -1217,7 +1245,7 @@ encode_op:
1217 be32_to_cpu(status)); 1245 be32_to_cpu(status));
1218 1246
1219 if (cstate->replay_owner) { 1247 if (cstate->replay_owner) {
1220 nfs4_put_stateowner(cstate->replay_owner); 1248 nfs4_unlock_state();
1221 cstate->replay_owner = NULL; 1249 cstate->replay_owner = NULL;
1222 } 1250 }
1223 /* XXX Ugh, we need to get rid of this kind of special case: */ 1251 /* XXX Ugh, we need to get rid of this kind of special case: */
@@ -1238,6 +1266,144 @@ out:
1238 return status; 1266 return status;
1239} 1267}
1240 1268
1269#define op_encode_hdr_size (2)
1270#define op_encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE))
1271#define op_encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE))
1272#define op_encode_change_info_maxsz (5)
1273#define nfs4_fattr_bitmap_maxsz (4)
1274
1275#define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1276#define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz)
1277
1278#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1279
1280#define op_encode_ace_maxsz (3 + nfs4_owner_maxsz)
1281#define op_encode_delegation_maxsz (1 + op_encode_stateid_maxsz + 1 + \
1282 op_encode_ace_maxsz)
1283
1284#define op_encode_channel_attrs_maxsz (6 + 1 + 1)
1285
1286static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1287{
1288 return (op_encode_hdr_size) * sizeof(__be32);
1289}
1290
1291static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1292{
1293 return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
1294}
1295
1296static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1297{
1298 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
1299}
1300
1301static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1302{
1303 return (op_encode_hdr_size + op_encode_change_info_maxsz
1304 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1305}
1306
1307static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1308{
1309 return (op_encode_hdr_size + op_encode_change_info_maxsz)
1310 * sizeof(__be32);
1311}
1312
1313static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1314{
1315 return (op_encode_hdr_size + op_encode_lock_denied_maxsz)
1316 * sizeof(__be32);
1317}
1318
1319static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1320{
1321 return (op_encode_hdr_size + op_encode_stateid_maxsz
1322 + op_encode_change_info_maxsz + 1
1323 + nfs4_fattr_bitmap_maxsz
1324 + op_encode_delegation_maxsz) * sizeof(__be32);
1325}
1326
1327static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1328{
1329 u32 maxcount = 0, rlen = 0;
1330
1331 maxcount = svc_max_payload(rqstp);
1332 rlen = op->u.read.rd_length;
1333
1334 if (rlen > maxcount)
1335 rlen = maxcount;
1336
1337 return (op_encode_hdr_size + 2) * sizeof(__be32) + rlen;
1338}
1339
1340static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1341{
1342 u32 rlen = op->u.readdir.rd_maxcount;
1343
1344 if (rlen > PAGE_SIZE)
1345 rlen = PAGE_SIZE;
1346
1347 return (op_encode_hdr_size + op_encode_verifier_maxsz)
1348 * sizeof(__be32) + rlen;
1349}
1350
1351static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1352{
1353 return (op_encode_hdr_size + op_encode_change_info_maxsz)
1354 * sizeof(__be32);
1355}
1356
1357static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1358{
1359 return (op_encode_hdr_size + op_encode_change_info_maxsz
1360 + op_encode_change_info_maxsz) * sizeof(__be32);
1361}
1362
1363static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1364{
1365 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1366}
1367
1368static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1369{
1370 return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32);
1371}
1372
1373static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1374{
1375 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
1376}
1377
1378static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1379{
1380 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1381 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\
1382 2 + /*eir_server_owner.so_minor_id */\
1383 /* eir_server_owner.so_major_id<> */\
1384 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1385 /* eir_server_scope<> */\
1386 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1387 1 + /* eir_server_impl_id array length */\
1388 0 /* ignored eir_server_impl_id contents */) * sizeof(__be32);
1389}
1390
1391static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1392{
1393 return (op_encode_hdr_size + \
1394 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\
1395 2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32);
1396}
1397
1398static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1399{
1400 return (op_encode_hdr_size + \
1401 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\
1402 2 + /* csr_sequence, csr_flags */\
1403 op_encode_channel_attrs_maxsz + \
1404 op_encode_channel_attrs_maxsz) * sizeof(__be32);
1405}
1406
1241static struct nfsd4_operation nfsd4_ops[] = { 1407static struct nfsd4_operation nfsd4_ops[] = {
1242 [OP_ACCESS] = { 1408 [OP_ACCESS] = {
1243 .op_func = (nfsd4op_func)nfsd4_access, 1409 .op_func = (nfsd4op_func)nfsd4_access,
@@ -1245,20 +1411,27 @@ static struct nfsd4_operation nfsd4_ops[] = {
1245 }, 1411 },
1246 [OP_CLOSE] = { 1412 [OP_CLOSE] = {
1247 .op_func = (nfsd4op_func)nfsd4_close, 1413 .op_func = (nfsd4op_func)nfsd4_close,
1414 .op_flags = OP_MODIFIES_SOMETHING,
1248 .op_name = "OP_CLOSE", 1415 .op_name = "OP_CLOSE",
1416 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1249 }, 1417 },
1250 [OP_COMMIT] = { 1418 [OP_COMMIT] = {
1251 .op_func = (nfsd4op_func)nfsd4_commit, 1419 .op_func = (nfsd4op_func)nfsd4_commit,
1420 .op_flags = OP_MODIFIES_SOMETHING,
1252 .op_name = "OP_COMMIT", 1421 .op_name = "OP_COMMIT",
1422 .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize,
1253 }, 1423 },
1254 [OP_CREATE] = { 1424 [OP_CREATE] = {
1255 .op_func = (nfsd4op_func)nfsd4_create, 1425 .op_func = (nfsd4op_func)nfsd4_create,
1426 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1256 .op_name = "OP_CREATE", 1427 .op_name = "OP_CREATE",
1257 .op_cacheresult = true, 1428 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize,
1258 }, 1429 },
1259 [OP_DELEGRETURN] = { 1430 [OP_DELEGRETURN] = {
1260 .op_func = (nfsd4op_func)nfsd4_delegreturn, 1431 .op_func = (nfsd4op_func)nfsd4_delegreturn,
1432 .op_flags = OP_MODIFIES_SOMETHING,
1261 .op_name = "OP_DELEGRETURN", 1433 .op_name = "OP_DELEGRETURN",
1434 .op_rsize_bop = nfsd4_only_status_rsize,
1262 }, 1435 },
1263 [OP_GETATTR] = { 1436 [OP_GETATTR] = {
1264 .op_func = (nfsd4op_func)nfsd4_getattr, 1437 .op_func = (nfsd4op_func)nfsd4_getattr,
@@ -1271,12 +1444,16 @@ static struct nfsd4_operation nfsd4_ops[] = {
1271 }, 1444 },
1272 [OP_LINK] = { 1445 [OP_LINK] = {
1273 .op_func = (nfsd4op_func)nfsd4_link, 1446 .op_func = (nfsd4op_func)nfsd4_link,
1447 .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING
1448 | OP_CACHEME,
1274 .op_name = "OP_LINK", 1449 .op_name = "OP_LINK",
1275 .op_cacheresult = true, 1450 .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize,
1276 }, 1451 },
1277 [OP_LOCK] = { 1452 [OP_LOCK] = {
1278 .op_func = (nfsd4op_func)nfsd4_lock, 1453 .op_func = (nfsd4op_func)nfsd4_lock,
1454 .op_flags = OP_MODIFIES_SOMETHING,
1279 .op_name = "OP_LOCK", 1455 .op_name = "OP_LOCK",
1456 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
1280 }, 1457 },
1281 [OP_LOCKT] = { 1458 [OP_LOCKT] = {
1282 .op_func = (nfsd4op_func)nfsd4_lockt, 1459 .op_func = (nfsd4op_func)nfsd4_lockt,
@@ -1284,7 +1461,9 @@ static struct nfsd4_operation nfsd4_ops[] = {
1284 }, 1461 },
1285 [OP_LOCKU] = { 1462 [OP_LOCKU] = {
1286 .op_func = (nfsd4op_func)nfsd4_locku, 1463 .op_func = (nfsd4op_func)nfsd4_locku,
1464 .op_flags = OP_MODIFIES_SOMETHING,
1287 .op_name = "OP_LOCKU", 1465 .op_name = "OP_LOCKU",
1466 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1288 }, 1467 },
1289 [OP_LOOKUP] = { 1468 [OP_LOOKUP] = {
1290 .op_func = (nfsd4op_func)nfsd4_lookup, 1469 .op_func = (nfsd4op_func)nfsd4_lookup,
@@ -1302,42 +1481,54 @@ static struct nfsd4_operation nfsd4_ops[] = {
1302 }, 1481 },
1303 [OP_OPEN] = { 1482 [OP_OPEN] = {
1304 .op_func = (nfsd4op_func)nfsd4_open, 1483 .op_func = (nfsd4op_func)nfsd4_open,
1305 .op_flags = OP_HANDLES_WRONGSEC, 1484 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1306 .op_name = "OP_OPEN", 1485 .op_name = "OP_OPEN",
1486 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
1307 }, 1487 },
1308 [OP_OPEN_CONFIRM] = { 1488 [OP_OPEN_CONFIRM] = {
1309 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1489 .op_func = (nfsd4op_func)nfsd4_open_confirm,
1490 .op_flags = OP_MODIFIES_SOMETHING,
1310 .op_name = "OP_OPEN_CONFIRM", 1491 .op_name = "OP_OPEN_CONFIRM",
1492 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1311 }, 1493 },
1312 [OP_OPEN_DOWNGRADE] = { 1494 [OP_OPEN_DOWNGRADE] = {
1313 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 1495 .op_func = (nfsd4op_func)nfsd4_open_downgrade,
1496 .op_flags = OP_MODIFIES_SOMETHING,
1314 .op_name = "OP_OPEN_DOWNGRADE", 1497 .op_name = "OP_OPEN_DOWNGRADE",
1498 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1315 }, 1499 },
1316 [OP_PUTFH] = { 1500 [OP_PUTFH] = {
1317 .op_func = (nfsd4op_func)nfsd4_putfh, 1501 .op_func = (nfsd4op_func)nfsd4_putfh,
1318 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1502 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1319 | OP_IS_PUTFH_LIKE, 1503 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
1320 .op_name = "OP_PUTFH", 1504 .op_name = "OP_PUTFH",
1505 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1321 }, 1506 },
1322 [OP_PUTPUBFH] = { 1507 [OP_PUTPUBFH] = {
1323 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1508 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1324 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1509 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1325 | OP_IS_PUTFH_LIKE, 1510 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
1326 .op_name = "OP_PUTPUBFH", 1511 .op_name = "OP_PUTPUBFH",
1512 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1327 }, 1513 },
1328 [OP_PUTROOTFH] = { 1514 [OP_PUTROOTFH] = {
1329 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1515 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1330 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1516 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1331 | OP_IS_PUTFH_LIKE, 1517 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
1332 .op_name = "OP_PUTROOTFH", 1518 .op_name = "OP_PUTROOTFH",
1519 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1333 }, 1520 },
1334 [OP_READ] = { 1521 [OP_READ] = {
1335 .op_func = (nfsd4op_func)nfsd4_read, 1522 .op_func = (nfsd4op_func)nfsd4_read,
1523 .op_flags = OP_MODIFIES_SOMETHING,
1336 .op_name = "OP_READ", 1524 .op_name = "OP_READ",
1525 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
1337 }, 1526 },
1338 [OP_READDIR] = { 1527 [OP_READDIR] = {
1339 .op_func = (nfsd4op_func)nfsd4_readdir, 1528 .op_func = (nfsd4op_func)nfsd4_readdir,
1529 .op_flags = OP_MODIFIES_SOMETHING,
1340 .op_name = "OP_READDIR", 1530 .op_name = "OP_READDIR",
1531 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize,
1341 }, 1532 },
1342 [OP_READLINK] = { 1533 [OP_READLINK] = {
1343 .op_func = (nfsd4op_func)nfsd4_readlink, 1534 .op_func = (nfsd4op_func)nfsd4_readlink,
@@ -1345,29 +1536,36 @@ static struct nfsd4_operation nfsd4_ops[] = {
1345 }, 1536 },
1346 [OP_REMOVE] = { 1537 [OP_REMOVE] = {
1347 .op_func = (nfsd4op_func)nfsd4_remove, 1538 .op_func = (nfsd4op_func)nfsd4_remove,
1539 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1348 .op_name = "OP_REMOVE", 1540 .op_name = "OP_REMOVE",
1349 .op_cacheresult = true, 1541 .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize,
1350 }, 1542 },
1351 [OP_RENAME] = { 1543 [OP_RENAME] = {
1352 .op_name = "OP_RENAME",
1353 .op_func = (nfsd4op_func)nfsd4_rename, 1544 .op_func = (nfsd4op_func)nfsd4_rename,
1354 .op_cacheresult = true, 1545 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1546 .op_name = "OP_RENAME",
1547 .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize,
1355 }, 1548 },
1356 [OP_RENEW] = { 1549 [OP_RENEW] = {
1357 .op_func = (nfsd4op_func)nfsd4_renew, 1550 .op_func = (nfsd4op_func)nfsd4_renew,
1358 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1551 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1552 | OP_MODIFIES_SOMETHING,
1359 .op_name = "OP_RENEW", 1553 .op_name = "OP_RENEW",
1554 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1555
1360 }, 1556 },
1361 [OP_RESTOREFH] = { 1557 [OP_RESTOREFH] = {
1362 .op_func = (nfsd4op_func)nfsd4_restorefh, 1558 .op_func = (nfsd4op_func)nfsd4_restorefh,
1363 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1559 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1364 | OP_IS_PUTFH_LIKE, 1560 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
1365 .op_name = "OP_RESTOREFH", 1561 .op_name = "OP_RESTOREFH",
1562 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1366 }, 1563 },
1367 [OP_SAVEFH] = { 1564 [OP_SAVEFH] = {
1368 .op_func = (nfsd4op_func)nfsd4_savefh, 1565 .op_func = (nfsd4op_func)nfsd4_savefh,
1369 .op_flags = OP_HANDLES_WRONGSEC, 1566 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1370 .op_name = "OP_SAVEFH", 1567 .op_name = "OP_SAVEFH",
1568 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1371 }, 1569 },
1372 [OP_SECINFO] = { 1570 [OP_SECINFO] = {
1373 .op_func = (nfsd4op_func)nfsd4_secinfo, 1571 .op_func = (nfsd4op_func)nfsd4_secinfo,
@@ -1377,19 +1575,22 @@ static struct nfsd4_operation nfsd4_ops[] = {
1377 [OP_SETATTR] = { 1575 [OP_SETATTR] = {
1378 .op_func = (nfsd4op_func)nfsd4_setattr, 1576 .op_func = (nfsd4op_func)nfsd4_setattr,
1379 .op_name = "OP_SETATTR", 1577 .op_name = "OP_SETATTR",
1380 .op_cacheresult = true, 1578 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1579 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize,
1381 }, 1580 },
1382 [OP_SETCLIENTID] = { 1581 [OP_SETCLIENTID] = {
1383 .op_func = (nfsd4op_func)nfsd4_setclientid, 1582 .op_func = (nfsd4op_func)nfsd4_setclientid,
1384 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1583 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1584 | OP_MODIFIES_SOMETHING | OP_CACHEME,
1385 .op_name = "OP_SETCLIENTID", 1585 .op_name = "OP_SETCLIENTID",
1386 .op_cacheresult = true, 1586 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize,
1387 }, 1587 },
1388 [OP_SETCLIENTID_CONFIRM] = { 1588 [OP_SETCLIENTID_CONFIRM] = {
1389 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, 1589 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm,
1390 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1590 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1591 | OP_MODIFIES_SOMETHING | OP_CACHEME,
1391 .op_name = "OP_SETCLIENTID_CONFIRM", 1592 .op_name = "OP_SETCLIENTID_CONFIRM",
1392 .op_cacheresult = true, 1593 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1393 }, 1594 },
1394 [OP_VERIFY] = { 1595 [OP_VERIFY] = {
1395 .op_func = (nfsd4op_func)nfsd4_verify, 1596 .op_func = (nfsd4op_func)nfsd4_verify,
@@ -1397,35 +1598,46 @@ static struct nfsd4_operation nfsd4_ops[] = {
1397 }, 1598 },
1398 [OP_WRITE] = { 1599 [OP_WRITE] = {
1399 .op_func = (nfsd4op_func)nfsd4_write, 1600 .op_func = (nfsd4op_func)nfsd4_write,
1601 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1400 .op_name = "OP_WRITE", 1602 .op_name = "OP_WRITE",
1401 .op_cacheresult = true, 1603 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1402 }, 1604 },
1403 [OP_RELEASE_LOCKOWNER] = { 1605 [OP_RELEASE_LOCKOWNER] = {
1404 .op_func = (nfsd4op_func)nfsd4_release_lockowner, 1606 .op_func = (nfsd4op_func)nfsd4_release_lockowner,
1405 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1607 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1608 | OP_MODIFIES_SOMETHING,
1406 .op_name = "OP_RELEASE_LOCKOWNER", 1609 .op_name = "OP_RELEASE_LOCKOWNER",
1610 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1407 }, 1611 },
1408 1612
1409 /* NFSv4.1 operations */ 1613 /* NFSv4.1 operations */
1410 [OP_EXCHANGE_ID] = { 1614 [OP_EXCHANGE_ID] = {
1411 .op_func = (nfsd4op_func)nfsd4_exchange_id, 1615 .op_func = (nfsd4op_func)nfsd4_exchange_id,
1412 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1616 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1617 | OP_MODIFIES_SOMETHING,
1413 .op_name = "OP_EXCHANGE_ID", 1618 .op_name = "OP_EXCHANGE_ID",
1619 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize,
1414 }, 1620 },
1415 [OP_BIND_CONN_TO_SESSION] = { 1621 [OP_BIND_CONN_TO_SESSION] = {
1416 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, 1622 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
1417 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1623 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1624 | OP_MODIFIES_SOMETHING,
1418 .op_name = "OP_BIND_CONN_TO_SESSION", 1625 .op_name = "OP_BIND_CONN_TO_SESSION",
1626 .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize,
1419 }, 1627 },
1420 [OP_CREATE_SESSION] = { 1628 [OP_CREATE_SESSION] = {
1421 .op_func = (nfsd4op_func)nfsd4_create_session, 1629 .op_func = (nfsd4op_func)nfsd4_create_session,
1422 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1630 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1631 | OP_MODIFIES_SOMETHING,
1423 .op_name = "OP_CREATE_SESSION", 1632 .op_name = "OP_CREATE_SESSION",
1633 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize,
1424 }, 1634 },
1425 [OP_DESTROY_SESSION] = { 1635 [OP_DESTROY_SESSION] = {
1426 .op_func = (nfsd4op_func)nfsd4_destroy_session, 1636 .op_func = (nfsd4op_func)nfsd4_destroy_session,
1427 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1637 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1638 | OP_MODIFIES_SOMETHING,
1428 .op_name = "OP_DESTROY_SESSION", 1639 .op_name = "OP_DESTROY_SESSION",
1640 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1429 }, 1641 },
1430 [OP_SEQUENCE] = { 1642 [OP_SEQUENCE] = {
1431 .op_func = (nfsd4op_func)nfsd4_sequence, 1643 .op_func = (nfsd4op_func)nfsd4_sequence,
@@ -1433,14 +1645,17 @@ static struct nfsd4_operation nfsd4_ops[] = {
1433 .op_name = "OP_SEQUENCE", 1645 .op_name = "OP_SEQUENCE",
1434 }, 1646 },
1435 [OP_DESTROY_CLIENTID] = { 1647 [OP_DESTROY_CLIENTID] = {
1436 .op_func = NULL, 1648 .op_func = (nfsd4op_func)nfsd4_destroy_clientid,
1437 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1649 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
1650 | OP_MODIFIES_SOMETHING,
1438 .op_name = "OP_DESTROY_CLIENTID", 1651 .op_name = "OP_DESTROY_CLIENTID",
1652 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1439 }, 1653 },
1440 [OP_RECLAIM_COMPLETE] = { 1654 [OP_RECLAIM_COMPLETE] = {
1441 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1655 .op_func = (nfsd4op_func)nfsd4_reclaim_complete,
1442 .op_flags = ALLOWED_WITHOUT_FH, 1656 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1443 .op_name = "OP_RECLAIM_COMPLETE", 1657 .op_name = "OP_RECLAIM_COMPLETE",
1658 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1444 }, 1659 },
1445 [OP_SECINFO_NO_NAME] = { 1660 [OP_SECINFO_NO_NAME] = {
1446 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, 1661 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
@@ -1454,8 +1669,9 @@ static struct nfsd4_operation nfsd4_ops[] = {
1454 }, 1669 },
1455 [OP_FREE_STATEID] = { 1670 [OP_FREE_STATEID] = {
1456 .op_func = (nfsd4op_func)nfsd4_free_stateid, 1671 .op_func = (nfsd4op_func)nfsd4_free_stateid,
1457 .op_flags = ALLOWED_WITHOUT_FH, 1672 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
1458 .op_name = "OP_FREE_STATEID", 1673 .op_name = "OP_FREE_STATEID",
1674 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1459 }, 1675 },
1460}; 1676};
1461 1677
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 29d77f60585b..ed083b9a731b 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -45,6 +45,7 @@
45 45
46/* Globals */ 46/* Globals */
47static struct file *rec_file; 47static struct file *rec_file;
48static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
48 49
49static int 50static int
50nfs4_save_creds(const struct cred **original_creds) 51nfs4_save_creds(const struct cred **original_creds)
@@ -88,7 +89,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88 struct xdr_netobj cksum; 89 struct xdr_netobj cksum;
89 struct hash_desc desc; 90 struct hash_desc desc;
90 struct scatterlist sg; 91 struct scatterlist sg;
91 __be32 status = nfserr_resource; 92 __be32 status = nfserr_jukebox;
92 93
93 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
94 clname->len, clname->data); 95 clname->len, clname->data);
@@ -129,6 +130,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
129 if (!rec_file || clp->cl_firststate) 130 if (!rec_file || clp->cl_firststate)
130 return 0; 131 return 0;
131 132
133 clp->cl_firststate = 1;
132 status = nfs4_save_creds(&original_cred); 134 status = nfs4_save_creds(&original_cred);
133 if (status < 0) 135 if (status < 0)
134 return status; 136 return status;
@@ -143,10 +145,8 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
143 goto out_unlock; 145 goto out_unlock;
144 } 146 }
145 status = -EEXIST; 147 status = -EEXIST;
146 if (dentry->d_inode) { 148 if (dentry->d_inode)
147 dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
148 goto out_put; 149 goto out_put;
149 }
150 status = mnt_want_write(rec_file->f_path.mnt); 150 status = mnt_want_write(rec_file->f_path.mnt);
151 if (status) 151 if (status)
152 goto out_put; 152 goto out_put;
@@ -156,12 +156,14 @@ out_put:
156 dput(dentry); 156 dput(dentry);
157out_unlock: 157out_unlock:
158 mutex_unlock(&dir->d_inode->i_mutex); 158 mutex_unlock(&dir->d_inode->i_mutex);
159 if (status == 0) { 159 if (status == 0)
160 clp->cl_firststate = 1;
161 vfs_fsync(rec_file, 0); 160 vfs_fsync(rec_file, 0);
162 } 161 else
162 printk(KERN_ERR "NFSD: failed to write recovery record"
163 " (err %d); please check that %s exists"
164 " and is writeable", status,
165 user_recovery_dirname);
163 nfs4_reset_creds(original_cred); 166 nfs4_reset_creds(original_cred);
164 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
165 return status; 167 return status;
166} 168}
167 169
@@ -354,13 +356,13 @@ nfsd4_recdir_load(void) {
354 */ 356 */
355 357
356void 358void
357nfsd4_init_recdir(char *rec_dirname) 359nfsd4_init_recdir()
358{ 360{
359 const struct cred *original_cred; 361 const struct cred *original_cred;
360 int status; 362 int status;
361 363
362 printk("NFSD: Using %s as the NFSv4 state recovery directory\n", 364 printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
363 rec_dirname); 365 user_recovery_dirname);
364 366
365 BUG_ON(rec_file); 367 BUG_ON(rec_file);
366 368
@@ -372,10 +374,10 @@ nfsd4_init_recdir(char *rec_dirname)
372 return; 374 return;
373 } 375 }
374 376
375 rec_file = filp_open(rec_dirname, O_RDONLY | O_DIRECTORY, 0); 377 rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0);
376 if (IS_ERR(rec_file)) { 378 if (IS_ERR(rec_file)) {
377 printk("NFSD: unable to find recovery directory %s\n", 379 printk("NFSD: unable to find recovery directory %s\n",
378 rec_dirname); 380 user_recovery_dirname);
379 rec_file = NULL; 381 rec_file = NULL;
380 } 382 }
381 383
@@ -390,3 +392,30 @@ nfsd4_shutdown_recdir(void)
390 fput(rec_file); 392 fput(rec_file);
391 rec_file = NULL; 393 rec_file = NULL;
392} 394}
395
396/*
397 * Change the NFSv4 recovery directory to recdir.
398 */
399int
400nfs4_reset_recoverydir(char *recdir)
401{
402 int status;
403 struct path path;
404
405 status = kern_path(recdir, LOOKUP_FOLLOW, &path);
406 if (status)
407 return status;
408 status = -ENOTDIR;
409 if (S_ISDIR(path.dentry->d_inode->i_mode)) {
410 strcpy(user_recovery_dirname, recdir);
411 status = 0;
412 }
413 path_put(&path);
414 return status;
415}
416
417char *
418nfs4_recoverydir(void)
419{
420 return user_recovery_dirname;
421}
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3787ec117400..47e94e33a975 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -49,9 +49,6 @@
49time_t nfsd4_lease = 90; /* default lease time */ 49time_t nfsd4_lease = 90; /* default lease time */
50time_t nfsd4_grace = 90; 50time_t nfsd4_grace = 90;
51static time_t boot_time; 51static time_t boot_time;
52static u32 current_ownerid = 1;
53static u32 current_fileid = 1;
54static u32 current_delegid = 1;
55static stateid_t zerostateid; /* bits all 0 */ 52static stateid_t zerostateid; /* bits all 0 */
56static stateid_t onestateid; /* bits all 1 */ 53static stateid_t onestateid; /* bits all 1 */
57static u64 current_sessionid = 1; 54static u64 current_sessionid = 1;
@@ -60,13 +57,7 @@ static u64 current_sessionid = 1;
60#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t))) 57#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
61 58
62/* forward declarations */ 59/* forward declarations */
63static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 60static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
64static struct nfs4_stateid * search_for_stateid(stateid_t *stid);
65static struct nfs4_delegation * search_for_delegation(stateid_t *stid);
66static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
67static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
68static void nfs4_set_recdir(char *recdir);
69static int check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner);
70 61
71/* Locking: */ 62/* Locking: */
72 63
@@ -80,7 +71,8 @@ static DEFINE_MUTEX(client_mutex);
80 */ 71 */
81static DEFINE_SPINLOCK(recall_lock); 72static DEFINE_SPINLOCK(recall_lock);
82 73
83static struct kmem_cache *stateowner_slab = NULL; 74static struct kmem_cache *openowner_slab = NULL;
75static struct kmem_cache *lockowner_slab = NULL;
84static struct kmem_cache *file_slab = NULL; 76static struct kmem_cache *file_slab = NULL;
85static struct kmem_cache *stateid_slab = NULL; 77static struct kmem_cache *stateid_slab = NULL;
86static struct kmem_cache *deleg_slab = NULL; 78static struct kmem_cache *deleg_slab = NULL;
@@ -112,6 +104,11 @@ opaque_hashval(const void *ptr, int nbytes)
112 104
113static struct list_head del_recall_lru; 105static struct list_head del_recall_lru;
114 106
107static void nfsd4_free_file(struct nfs4_file *f)
108{
109 kmem_cache_free(file_slab, f);
110}
111
115static inline void 112static inline void
116put_nfs4_file(struct nfs4_file *fi) 113put_nfs4_file(struct nfs4_file *fi)
117{ 114{
@@ -119,7 +116,7 @@ put_nfs4_file(struct nfs4_file *fi)
119 list_del(&fi->fi_hash); 116 list_del(&fi->fi_hash);
120 spin_unlock(&recall_lock); 117 spin_unlock(&recall_lock);
121 iput(fi->fi_inode); 118 iput(fi->fi_inode);
122 kmem_cache_free(file_slab, fi); 119 nfsd4_free_file(fi);
123 } 120 }
124} 121}
125 122
@@ -136,35 +133,33 @@ unsigned int max_delegations;
136 * Open owner state (share locks) 133 * Open owner state (share locks)
137 */ 134 */
138 135
139/* hash tables for nfs4_stateowner */ 136/* hash tables for open owners */
140#define OWNER_HASH_BITS 8 137#define OPEN_OWNER_HASH_BITS 8
141#define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) 138#define OPEN_OWNER_HASH_SIZE (1 << OPEN_OWNER_HASH_BITS)
142#define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) 139#define OPEN_OWNER_HASH_MASK (OPEN_OWNER_HASH_SIZE - 1)
143 140
144#define ownerid_hashval(id) \ 141static unsigned int open_ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
145 ((id) & OWNER_HASH_MASK) 142{
146#define ownerstr_hashval(clientid, ownername) \ 143 unsigned int ret;
147 (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
148 144
149static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE]; 145 ret = opaque_hashval(ownername->data, ownername->len);
150static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; 146 ret += clientid;
147 return ret & OPEN_OWNER_HASH_MASK;
148}
149
150static struct list_head open_ownerstr_hashtbl[OPEN_OWNER_HASH_SIZE];
151 151
152/* hash table for nfs4_file */ 152/* hash table for nfs4_file */
153#define FILE_HASH_BITS 8 153#define FILE_HASH_BITS 8
154#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) 154#define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
155 155
156/* hash table for (open)nfs4_stateid */ 156static unsigned int file_hashval(struct inode *ino)
157#define STATEID_HASH_BITS 10 157{
158#define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS) 158 /* XXX: why are we hashing on inode pointer, anyway? */
159#define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1) 159 return hash_ptr(ino, FILE_HASH_BITS);
160 160}
161#define file_hashval(x) \
162 hash_ptr(x, FILE_HASH_BITS)
163#define stateid_hashval(owner_id, file_id) \
164 (((owner_id) + (file_id)) & STATEID_HASH_MASK)
165 161
166static struct list_head file_hashtbl[FILE_HASH_SIZE]; 162static struct list_head file_hashtbl[FILE_HASH_SIZE];
167static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
168 163
169static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag) 164static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
170{ 165{
@@ -192,8 +187,15 @@ static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
192static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) 187static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
193{ 188{
194 if (atomic_dec_and_test(&fp->fi_access[oflag])) { 189 if (atomic_dec_and_test(&fp->fi_access[oflag])) {
195 nfs4_file_put_fd(fp, O_RDWR);
196 nfs4_file_put_fd(fp, oflag); 190 nfs4_file_put_fd(fp, oflag);
191 /*
192 * It's also safe to get rid of the RDWR open *if*
193 * we no longer have need of the other kind of access
194 * or if we already have the other kind of open:
195 */
196 if (fp->fi_fds[1-oflag]
197 || atomic_read(&fp->fi_access[1 - oflag]) == 0)
198 nfs4_file_put_fd(fp, O_RDWR);
197 } 199 }
198} 200}
199 201
@@ -206,8 +208,73 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
206 __nfs4_file_put_access(fp, oflag); 208 __nfs4_file_put_access(fp, oflag);
207} 209}
208 210
211static inline int get_new_stid(struct nfs4_stid *stid)
212{
213 static int min_stateid = 0;
214 struct idr *stateids = &stid->sc_client->cl_stateids;
215 int new_stid;
216 int error;
217
218 error = idr_get_new_above(stateids, stid, min_stateid, &new_stid);
219 /*
220 * Note: the necessary preallocation was done in
221 * nfs4_alloc_stateid(). The idr code caps the number of
222 * preallocations that can exist at a time, but the state lock
223 * prevents anyone from using ours before we get here:
224 */
225 BUG_ON(error);
226 /*
227 * It shouldn't be a problem to reuse an opaque stateid value.
228 * I don't think it is for 4.1. But with 4.0 I worry that, for
229 * example, a stray write retransmission could be accepted by
230 * the server when it should have been rejected. Therefore,
231 * adopt a trick from the sctp code to attempt to maximize the
232 * amount of time until an id is reused, by ensuring they always
233 * "increase" (mod INT_MAX):
234 */
235
236 min_stateid = new_stid+1;
237 if (min_stateid == INT_MAX)
238 min_stateid = 0;
239 return new_stid;
240}
241
242static void init_stid(struct nfs4_stid *stid, struct nfs4_client *cl, unsigned char type)
243{
244 stateid_t *s = &stid->sc_stateid;
245 int new_id;
246
247 stid->sc_type = type;
248 stid->sc_client = cl;
249 s->si_opaque.so_clid = cl->cl_clientid;
250 new_id = get_new_stid(stid);
251 s->si_opaque.so_id = (u32)new_id;
252 /* Will be incremented before return to client: */
253 s->si_generation = 0;
254}
255
256static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab)
257{
258 struct idr *stateids = &cl->cl_stateids;
259
260 if (!idr_pre_get(stateids, GFP_KERNEL))
261 return NULL;
262 /*
263 * Note: if we fail here (or any time between now and the time
264 * we actually get the new idr), we won't need to undo the idr
265 * preallocation, since the idr code caps the number of
266 * preallocated entries.
267 */
268 return kmem_cache_alloc(slab, GFP_KERNEL);
269}
270
271static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
272{
273 return openlockstateid(nfs4_alloc_stid(clp, stateid_slab));
274}
275
209static struct nfs4_delegation * 276static struct nfs4_delegation *
210alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type) 277alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type)
211{ 278{
212 struct nfs4_delegation *dp; 279 struct nfs4_delegation *dp;
213 struct nfs4_file *fp = stp->st_file; 280 struct nfs4_file *fp = stp->st_file;
@@ -224,21 +291,23 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
224 return NULL; 291 return NULL;
225 if (num_delegations > max_delegations) 292 if (num_delegations > max_delegations)
226 return NULL; 293 return NULL;
227 dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL); 294 dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab));
228 if (dp == NULL) 295 if (dp == NULL)
229 return dp; 296 return dp;
297 init_stid(&dp->dl_stid, clp, NFS4_DELEG_STID);
298 /*
299 * delegation seqid's are never incremented. The 4.1 special
300 * meaning of seqid 0 isn't meaningful, really, but let's avoid
301 * 0 anyway just for consistency and use 1:
302 */
303 dp->dl_stid.sc_stateid.si_generation = 1;
230 num_delegations++; 304 num_delegations++;
231 INIT_LIST_HEAD(&dp->dl_perfile); 305 INIT_LIST_HEAD(&dp->dl_perfile);
232 INIT_LIST_HEAD(&dp->dl_perclnt); 306 INIT_LIST_HEAD(&dp->dl_perclnt);
233 INIT_LIST_HEAD(&dp->dl_recall_lru); 307 INIT_LIST_HEAD(&dp->dl_recall_lru);
234 dp->dl_client = clp;
235 get_nfs4_file(fp); 308 get_nfs4_file(fp);
236 dp->dl_file = fp; 309 dp->dl_file = fp;
237 dp->dl_type = type; 310 dp->dl_type = type;
238 dp->dl_stateid.si_boot = boot_time;
239 dp->dl_stateid.si_stateownerid = current_delegid++;
240 dp->dl_stateid.si_fileid = 0;
241 dp->dl_stateid.si_generation = 0;
242 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 311 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
243 dp->dl_time = 0; 312 dp->dl_time = 0;
244 atomic_set(&dp->dl_count, 1); 313 atomic_set(&dp->dl_count, 1);
@@ -267,10 +336,18 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
267 } 336 }
268} 337}
269 338
339static void unhash_stid(struct nfs4_stid *s)
340{
341 struct idr *stateids = &s->sc_client->cl_stateids;
342
343 idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
344}
345
270/* Called under the state lock. */ 346/* Called under the state lock. */
271static void 347static void
272unhash_delegation(struct nfs4_delegation *dp) 348unhash_delegation(struct nfs4_delegation *dp)
273{ 349{
350 unhash_stid(&dp->dl_stid);
274 list_del_init(&dp->dl_perclnt); 351 list_del_init(&dp->dl_perclnt);
275 spin_lock(&recall_lock); 352 spin_lock(&recall_lock);
276 list_del_init(&dp->dl_perfile); 353 list_del_init(&dp->dl_perfile);
@@ -292,10 +369,16 @@ static DEFINE_SPINLOCK(client_lock);
292#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS) 369#define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
293#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1) 370#define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
294 371
295#define clientid_hashval(id) \ 372static unsigned int clientid_hashval(u32 id)
296 ((id) & CLIENT_HASH_MASK) 373{
297#define clientstr_hashval(name) \ 374 return id & CLIENT_HASH_MASK;
298 (opaque_hashval((name), 8) & CLIENT_HASH_MASK) 375}
376
377static unsigned int clientstr_hashval(const char *name)
378{
379 return opaque_hashval(name, 8) & CLIENT_HASH_MASK;
380}
381
299/* 382/*
300 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot 383 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
301 * used in reboot/reset lease grace period processing 384 * used in reboot/reset lease grace period processing
@@ -362,7 +445,7 @@ set_deny(unsigned int *deny, unsigned long bmap) {
362} 445}
363 446
364static int 447static int
365test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) { 448test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
366 unsigned int access, deny; 449 unsigned int access, deny;
367 450
368 set_access(&access, stp->st_access_bmap); 451 set_access(&access, stp->st_access_bmap);
@@ -385,14 +468,13 @@ static int nfs4_access_to_omode(u32 access)
385 BUG(); 468 BUG();
386} 469}
387 470
388static void unhash_generic_stateid(struct nfs4_stateid *stp) 471static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
389{ 472{
390 list_del(&stp->st_hash);
391 list_del(&stp->st_perfile); 473 list_del(&stp->st_perfile);
392 list_del(&stp->st_perstateowner); 474 list_del(&stp->st_perstateowner);
393} 475}
394 476
395static void free_generic_stateid(struct nfs4_stateid *stp) 477static void close_generic_stateid(struct nfs4_ol_stateid *stp)
396{ 478{
397 int i; 479 int i;
398 480
@@ -401,84 +483,106 @@ static void free_generic_stateid(struct nfs4_stateid *stp)
401 if (test_bit(i, &stp->st_access_bmap)) 483 if (test_bit(i, &stp->st_access_bmap))
402 nfs4_file_put_access(stp->st_file, 484 nfs4_file_put_access(stp->st_file,
403 nfs4_access_to_omode(i)); 485 nfs4_access_to_omode(i));
486 __clear_bit(i, &stp->st_access_bmap);
404 } 487 }
405 } 488 }
406 put_nfs4_file(stp->st_file); 489 put_nfs4_file(stp->st_file);
490 stp->st_file = NULL;
491}
492
493static void free_generic_stateid(struct nfs4_ol_stateid *stp)
494{
407 kmem_cache_free(stateid_slab, stp); 495 kmem_cache_free(stateid_slab, stp);
408} 496}
409 497
410static void release_lock_stateid(struct nfs4_stateid *stp) 498static void release_lock_stateid(struct nfs4_ol_stateid *stp)
411{ 499{
412 struct file *file; 500 struct file *file;
413 501
414 unhash_generic_stateid(stp); 502 unhash_generic_stateid(stp);
503 unhash_stid(&stp->st_stid);
415 file = find_any_file(stp->st_file); 504 file = find_any_file(stp->st_file);
416 if (file) 505 if (file)
417 locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); 506 locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner));
507 close_generic_stateid(stp);
418 free_generic_stateid(stp); 508 free_generic_stateid(stp);
419} 509}
420 510
421static void unhash_lockowner(struct nfs4_stateowner *sop) 511static void unhash_lockowner(struct nfs4_lockowner *lo)
422{ 512{
423 struct nfs4_stateid *stp; 513 struct nfs4_ol_stateid *stp;
424 514
425 list_del(&sop->so_idhash); 515 list_del(&lo->lo_owner.so_strhash);
426 list_del(&sop->so_strhash); 516 list_del(&lo->lo_perstateid);
427 list_del(&sop->so_perstateid); 517 while (!list_empty(&lo->lo_owner.so_stateids)) {
428 while (!list_empty(&sop->so_stateids)) { 518 stp = list_first_entry(&lo->lo_owner.so_stateids,
429 stp = list_first_entry(&sop->so_stateids, 519 struct nfs4_ol_stateid, st_perstateowner);
430 struct nfs4_stateid, st_perstateowner);
431 release_lock_stateid(stp); 520 release_lock_stateid(stp);
432 } 521 }
433} 522}
434 523
435static void release_lockowner(struct nfs4_stateowner *sop) 524static void release_lockowner(struct nfs4_lockowner *lo)
436{ 525{
437 unhash_lockowner(sop); 526 unhash_lockowner(lo);
438 nfs4_put_stateowner(sop); 527 nfs4_free_lockowner(lo);
439} 528}
440 529
441static void 530static void
442release_stateid_lockowners(struct nfs4_stateid *open_stp) 531release_stateid_lockowners(struct nfs4_ol_stateid *open_stp)
443{ 532{
444 struct nfs4_stateowner *lock_sop; 533 struct nfs4_lockowner *lo;
445 534
446 while (!list_empty(&open_stp->st_lockowners)) { 535 while (!list_empty(&open_stp->st_lockowners)) {
447 lock_sop = list_entry(open_stp->st_lockowners.next, 536 lo = list_entry(open_stp->st_lockowners.next,
448 struct nfs4_stateowner, so_perstateid); 537 struct nfs4_lockowner, lo_perstateid);
449 /* list_del(&open_stp->st_lockowners); */ 538 release_lockowner(lo);
450 BUG_ON(lock_sop->so_is_open_owner);
451 release_lockowner(lock_sop);
452 } 539 }
453} 540}
454 541
455static void release_open_stateid(struct nfs4_stateid *stp) 542static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
456{ 543{
457 unhash_generic_stateid(stp); 544 unhash_generic_stateid(stp);
458 release_stateid_lockowners(stp); 545 release_stateid_lockowners(stp);
546 close_generic_stateid(stp);
547}
548
549static void release_open_stateid(struct nfs4_ol_stateid *stp)
550{
551 unhash_open_stateid(stp);
552 unhash_stid(&stp->st_stid);
459 free_generic_stateid(stp); 553 free_generic_stateid(stp);
460} 554}
461 555
462static void unhash_openowner(struct nfs4_stateowner *sop) 556static void unhash_openowner(struct nfs4_openowner *oo)
463{ 557{
464 struct nfs4_stateid *stp; 558 struct nfs4_ol_stateid *stp;
465 559
466 list_del(&sop->so_idhash); 560 list_del(&oo->oo_owner.so_strhash);
467 list_del(&sop->so_strhash); 561 list_del(&oo->oo_perclient);
468 list_del(&sop->so_perclient); 562 while (!list_empty(&oo->oo_owner.so_stateids)) {
469 list_del(&sop->so_perstateid); /* XXX: necessary? */ 563 stp = list_first_entry(&oo->oo_owner.so_stateids,
470 while (!list_empty(&sop->so_stateids)) { 564 struct nfs4_ol_stateid, st_perstateowner);
471 stp = list_first_entry(&sop->so_stateids,
472 struct nfs4_stateid, st_perstateowner);
473 release_open_stateid(stp); 565 release_open_stateid(stp);
474 } 566 }
475} 567}
476 568
477static void release_openowner(struct nfs4_stateowner *sop) 569static void release_last_closed_stateid(struct nfs4_openowner *oo)
478{ 570{
479 unhash_openowner(sop); 571 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;
480 list_del(&sop->so_close_lru); 572
481 nfs4_put_stateowner(sop); 573 if (s) {
574 unhash_stid(&s->st_stid);
575 free_generic_stateid(s);
576 oo->oo_last_closed_stid = NULL;
577 }
578}
579
580static void release_openowner(struct nfs4_openowner *oo)
581{
582 unhash_openowner(oo);
583 list_del(&oo->oo_close_lru);
584 release_last_closed_stateid(oo);
585 nfs4_free_openowner(oo);
482} 586}
483 587
484#define SESSION_HASH_SIZE 512 588#define SESSION_HASH_SIZE 512
@@ -843,9 +947,6 @@ renew_client_locked(struct nfs4_client *clp)
843 return; 947 return;
844 } 948 }
845 949
846 /*
847 * Move client to the end to the LRU list.
848 */
849 dprintk("renewing client (clientid %08x/%08x)\n", 950 dprintk("renewing client (clientid %08x/%08x)\n",
850 clp->cl_clientid.cl_boot, 951 clp->cl_clientid.cl_boot,
851 clp->cl_clientid.cl_id); 952 clp->cl_clientid.cl_id);
@@ -943,7 +1044,7 @@ unhash_client_locked(struct nfs4_client *clp)
943static void 1044static void
944expire_client(struct nfs4_client *clp) 1045expire_client(struct nfs4_client *clp)
945{ 1046{
946 struct nfs4_stateowner *sop; 1047 struct nfs4_openowner *oo;
947 struct nfs4_delegation *dp; 1048 struct nfs4_delegation *dp;
948 struct list_head reaplist; 1049 struct list_head reaplist;
949 1050
@@ -961,8 +1062,8 @@ expire_client(struct nfs4_client *clp)
961 unhash_delegation(dp); 1062 unhash_delegation(dp);
962 } 1063 }
963 while (!list_empty(&clp->cl_openowners)) { 1064 while (!list_empty(&clp->cl_openowners)) {
964 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient); 1065 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
965 release_openowner(sop); 1066 release_openowner(oo);
966 } 1067 }
967 nfsd4_shutdown_callback(clp); 1068 nfsd4_shutdown_callback(clp);
968 if (clp->cl_cb_conn.cb_xprt) 1069 if (clp->cl_cb_conn.cb_xprt)
@@ -1038,6 +1139,23 @@ static void gen_confirm(struct nfs4_client *clp)
1038 *p++ = i++; 1139 *p++ = i++;
1039} 1140}
1040 1141
1142static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t)
1143{
1144 return idr_find(&cl->cl_stateids, t->si_opaque.so_id);
1145}
1146
1147static struct nfs4_stid *find_stateid_by_type(struct nfs4_client *cl, stateid_t *t, char typemask)
1148{
1149 struct nfs4_stid *s;
1150
1151 s = find_stateid(cl, t);
1152 if (!s)
1153 return NULL;
1154 if (typemask & s->sc_type)
1155 return s;
1156 return NULL;
1157}
1158
1041static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, 1159static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1042 struct svc_rqst *rqstp, nfs4_verifier *verf) 1160 struct svc_rqst *rqstp, nfs4_verifier *verf)
1043{ 1161{
@@ -1060,6 +1178,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1060 } 1178 }
1061 } 1179 }
1062 1180
1181 idr_init(&clp->cl_stateids);
1063 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1182 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1064 atomic_set(&clp->cl_refcount, 0); 1183 atomic_set(&clp->cl_refcount, 0);
1065 clp->cl_cb_state = NFSD4_CB_UNKNOWN; 1184 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
@@ -1083,17 +1202,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1083 return clp; 1202 return clp;
1084} 1203}
1085 1204
1086static int check_name(struct xdr_netobj name)
1087{
1088 if (name.len == 0)
1089 return 0;
1090 if (name.len > NFS4_OPAQUE_LIMIT) {
1091 dprintk("NFSD: check_name: name too long(%d)!\n", name.len);
1092 return 0;
1093 }
1094 return 1;
1095}
1096
1097static void 1205static void
1098add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 1206add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
1099{ 1207{
@@ -1125,8 +1233,10 @@ find_confirmed_client(clientid_t *clid)
1125 unsigned int idhashval = clientid_hashval(clid->cl_id); 1233 unsigned int idhashval = clientid_hashval(clid->cl_id);
1126 1234
1127 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { 1235 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1128 if (same_clid(&clp->cl_clientid, clid)) 1236 if (same_clid(&clp->cl_clientid, clid)) {
1237 renew_client(clp);
1129 return clp; 1238 return clp;
1239 }
1130 } 1240 }
1131 return NULL; 1241 return NULL;
1132} 1242}
@@ -1173,20 +1283,6 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
1173 return NULL; 1283 return NULL;
1174} 1284}
1175 1285
1176static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr)
1177{
1178 switch (family) {
1179 case AF_INET:
1180 ((struct sockaddr_in *)sa)->sin_family = AF_INET;
1181 ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr;
1182 return;
1183 case AF_INET6:
1184 ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6;
1185 ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6;
1186 return;
1187 }
1188}
1189
1190static void 1286static void
1191gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp) 1287gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
1192{ 1288{
@@ -1218,7 +1314,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
1218 1314
1219 conn->cb_prog = se->se_callback_prog; 1315 conn->cb_prog = se->se_callback_prog;
1220 conn->cb_ident = se->se_callback_ident; 1316 conn->cb_ident = se->se_callback_ident;
1221 rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr); 1317 memcpy(&conn->cb_saddr, &rqstp->rq_daddr, rqstp->rq_daddrlen);
1222 return; 1318 return;
1223out_err: 1319out_err:
1224 conn->cb_addr.ss_family = AF_UNSPEC; 1320 conn->cb_addr.ss_family = AF_UNSPEC;
@@ -1350,7 +1446,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1350 __func__, rqstp, exid, exid->clname.len, exid->clname.data, 1446 __func__, rqstp, exid, exid->clname.len, exid->clname.data,
1351 addr_str, exid->flags, exid->spa_how); 1447 addr_str, exid->flags, exid->spa_how);
1352 1448
1353 if (!check_name(exid->clname) || (exid->flags & ~EXCHGID4_FLAG_MASK_A)) 1449 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1354 return nfserr_inval; 1450 return nfserr_inval;
1355 1451
1356 /* Currently only support SP4_NONE */ 1452 /* Currently only support SP4_NONE */
@@ -1849,8 +1945,16 @@ out:
1849 1945
1850 nfsd4_get_session(cstate->session); 1946 nfsd4_get_session(cstate->session);
1851 atomic_inc(&clp->cl_refcount); 1947 atomic_inc(&clp->cl_refcount);
1852 if (clp->cl_cb_state == NFSD4_CB_DOWN) 1948 switch (clp->cl_cb_state) {
1853 seq->status_flags |= SEQ4_STATUS_CB_PATH_DOWN; 1949 case NFSD4_CB_DOWN:
1950 seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
1951 break;
1952 case NFSD4_CB_FAULT:
1953 seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
1954 break;
1955 default:
1956 seq->status_flags = 0;
1957 }
1854 } 1958 }
1855 kfree(conn); 1959 kfree(conn);
1856 spin_unlock(&client_lock); 1960 spin_unlock(&client_lock);
@@ -1858,6 +1962,50 @@ out:
1858 return status; 1962 return status;
1859} 1963}
1860 1964
1965static inline bool has_resources(struct nfs4_client *clp)
1966{
1967 return !list_empty(&clp->cl_openowners)
1968 || !list_empty(&clp->cl_delegations)
1969 || !list_empty(&clp->cl_sessions);
1970}
1971
1972__be32
1973nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc)
1974{
1975 struct nfs4_client *conf, *unconf, *clp;
1976 int status = 0;
1977
1978 nfs4_lock_state();
1979 unconf = find_unconfirmed_client(&dc->clientid);
1980 conf = find_confirmed_client(&dc->clientid);
1981
1982 if (conf) {
1983 clp = conf;
1984
1985 if (!is_client_expired(conf) && has_resources(conf)) {
1986 status = nfserr_clientid_busy;
1987 goto out;
1988 }
1989
1990 /* rfc5661 18.50.3 */
1991 if (cstate->session && conf == cstate->session->se_client) {
1992 status = nfserr_clientid_busy;
1993 goto out;
1994 }
1995 } else if (unconf)
1996 clp = unconf;
1997 else {
1998 status = nfserr_stale_clientid;
1999 goto out;
2000 }
2001
2002 expire_client(clp);
2003out:
2004 nfs4_unlock_state();
2005 dprintk("%s return %d\n", __func__, ntohl(status));
2006 return status;
2007}
2008
1861__be32 2009__be32
1862nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) 2010nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
1863{ 2011{
@@ -1900,19 +2048,13 @@ __be32
1900nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 2048nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1901 struct nfsd4_setclientid *setclid) 2049 struct nfsd4_setclientid *setclid)
1902{ 2050{
1903 struct xdr_netobj clname = { 2051 struct xdr_netobj clname = setclid->se_name;
1904 .len = setclid->se_namelen,
1905 .data = setclid->se_name,
1906 };
1907 nfs4_verifier clverifier = setclid->se_verf; 2052 nfs4_verifier clverifier = setclid->se_verf;
1908 unsigned int strhashval; 2053 unsigned int strhashval;
1909 struct nfs4_client *conf, *unconf, *new; 2054 struct nfs4_client *conf, *unconf, *new;
1910 __be32 status; 2055 __be32 status;
1911 char dname[HEXDIR_LEN]; 2056 char dname[HEXDIR_LEN];
1912 2057
1913 if (!check_name(clname))
1914 return nfserr_inval;
1915
1916 status = nfs4_make_rec_clidname(dname, &clname); 2058 status = nfs4_make_rec_clidname(dname, &clname);
1917 if (status) 2059 if (status)
1918 return status; 2060 return status;
@@ -1946,7 +2088,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1946 * of 5 bullet points, labeled as CASE0 - CASE4 below. 2088 * of 5 bullet points, labeled as CASE0 - CASE4 below.
1947 */ 2089 */
1948 unconf = find_unconfirmed_client_by_str(dname, strhashval); 2090 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1949 status = nfserr_resource; 2091 status = nfserr_jukebox;
1950 if (!conf) { 2092 if (!conf) {
1951 /* 2093 /*
1952 * RFC 3530 14.2.33 CASE 4: 2094 * RFC 3530 14.2.33 CASE 4:
@@ -2116,31 +2258,28 @@ out:
2116 return status; 2258 return status;
2117} 2259}
2118 2260
2261static struct nfs4_file *nfsd4_alloc_file(void)
2262{
2263 return kmem_cache_alloc(file_slab, GFP_KERNEL);
2264}
2265
2119/* OPEN Share state helper functions */ 2266/* OPEN Share state helper functions */
2120static inline struct nfs4_file * 2267static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
2121alloc_init_file(struct inode *ino)
2122{ 2268{
2123 struct nfs4_file *fp;
2124 unsigned int hashval = file_hashval(ino); 2269 unsigned int hashval = file_hashval(ino);
2125 2270
2126 fp = kmem_cache_alloc(file_slab, GFP_KERNEL); 2271 atomic_set(&fp->fi_ref, 1);
2127 if (fp) { 2272 INIT_LIST_HEAD(&fp->fi_hash);
2128 atomic_set(&fp->fi_ref, 1); 2273 INIT_LIST_HEAD(&fp->fi_stateids);
2129 INIT_LIST_HEAD(&fp->fi_hash); 2274 INIT_LIST_HEAD(&fp->fi_delegations);
2130 INIT_LIST_HEAD(&fp->fi_stateids); 2275 fp->fi_inode = igrab(ino);
2131 INIT_LIST_HEAD(&fp->fi_delegations); 2276 fp->fi_had_conflict = false;
2132 fp->fi_inode = igrab(ino); 2277 fp->fi_lease = NULL;
2133 fp->fi_id = current_fileid++; 2278 memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
2134 fp->fi_had_conflict = false; 2279 memset(fp->fi_access, 0, sizeof(fp->fi_access));
2135 fp->fi_lease = NULL; 2280 spin_lock(&recall_lock);
2136 memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); 2281 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
2137 memset(fp->fi_access, 0, sizeof(fp->fi_access)); 2282 spin_unlock(&recall_lock);
2138 spin_lock(&recall_lock);
2139 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
2140 spin_unlock(&recall_lock);
2141 return fp;
2142 }
2143 return NULL;
2144} 2283}
2145 2284
2146static void 2285static void
@@ -2155,7 +2294,8 @@ nfsd4_free_slab(struct kmem_cache **slab)
2155void 2294void
2156nfsd4_free_slabs(void) 2295nfsd4_free_slabs(void)
2157{ 2296{
2158 nfsd4_free_slab(&stateowner_slab); 2297 nfsd4_free_slab(&openowner_slab);
2298 nfsd4_free_slab(&lockowner_slab);
2159 nfsd4_free_slab(&file_slab); 2299 nfsd4_free_slab(&file_slab);
2160 nfsd4_free_slab(&stateid_slab); 2300 nfsd4_free_slab(&stateid_slab);
2161 nfsd4_free_slab(&deleg_slab); 2301 nfsd4_free_slab(&deleg_slab);
@@ -2164,16 +2304,20 @@ nfsd4_free_slabs(void)
2164static int 2304static int
2165nfsd4_init_slabs(void) 2305nfsd4_init_slabs(void)
2166{ 2306{
2167 stateowner_slab = kmem_cache_create("nfsd4_stateowners", 2307 openowner_slab = kmem_cache_create("nfsd4_openowners",
2168 sizeof(struct nfs4_stateowner), 0, 0, NULL); 2308 sizeof(struct nfs4_openowner), 0, 0, NULL);
2169 if (stateowner_slab == NULL) 2309 if (openowner_slab == NULL)
2310 goto out_nomem;
2311 lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2312 sizeof(struct nfs4_openowner), 0, 0, NULL);
2313 if (lockowner_slab == NULL)
2170 goto out_nomem; 2314 goto out_nomem;
2171 file_slab = kmem_cache_create("nfsd4_files", 2315 file_slab = kmem_cache_create("nfsd4_files",
2172 sizeof(struct nfs4_file), 0, 0, NULL); 2316 sizeof(struct nfs4_file), 0, 0, NULL);
2173 if (file_slab == NULL) 2317 if (file_slab == NULL)
2174 goto out_nomem; 2318 goto out_nomem;
2175 stateid_slab = kmem_cache_create("nfsd4_stateids", 2319 stateid_slab = kmem_cache_create("nfsd4_stateids",
2176 sizeof(struct nfs4_stateid), 0, 0, NULL); 2320 sizeof(struct nfs4_ol_stateid), 0, 0, NULL);
2177 if (stateid_slab == NULL) 2321 if (stateid_slab == NULL)
2178 goto out_nomem; 2322 goto out_nomem;
2179 deleg_slab = kmem_cache_create("nfsd4_delegations", 2323 deleg_slab = kmem_cache_create("nfsd4_delegations",
@@ -2187,97 +2331,94 @@ out_nomem:
2187 return -ENOMEM; 2331 return -ENOMEM;
2188} 2332}
2189 2333
2190void 2334void nfs4_free_openowner(struct nfs4_openowner *oo)
2191nfs4_free_stateowner(struct kref *kref)
2192{ 2335{
2193 struct nfs4_stateowner *sop = 2336 kfree(oo->oo_owner.so_owner.data);
2194 container_of(kref, struct nfs4_stateowner, so_ref); 2337 kmem_cache_free(openowner_slab, oo);
2195 kfree(sop->so_owner.data);
2196 kmem_cache_free(stateowner_slab, sop);
2197} 2338}
2198 2339
2199static inline struct nfs4_stateowner * 2340void nfs4_free_lockowner(struct nfs4_lockowner *lo)
2200alloc_stateowner(struct xdr_netobj *owner)
2201{ 2341{
2202 struct nfs4_stateowner *sop; 2342 kfree(lo->lo_owner.so_owner.data);
2343 kmem_cache_free(lockowner_slab, lo);
2344}
2203 2345
2204 if ((sop = kmem_cache_alloc(stateowner_slab, GFP_KERNEL))) { 2346static void init_nfs4_replay(struct nfs4_replay *rp)
2205 if ((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) { 2347{
2206 memcpy(sop->so_owner.data, owner->data, owner->len); 2348 rp->rp_status = nfserr_serverfault;
2207 sop->so_owner.len = owner->len; 2349 rp->rp_buflen = 0;
2208 kref_init(&sop->so_ref); 2350 rp->rp_buf = rp->rp_ibuf;
2209 return sop;
2210 }
2211 kmem_cache_free(stateowner_slab, sop);
2212 }
2213 return NULL;
2214} 2351}
2215 2352
2216static struct nfs4_stateowner * 2353static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
2217alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { 2354{
2218 struct nfs4_stateowner *sop; 2355 struct nfs4_stateowner *sop;
2219 struct nfs4_replay *rp;
2220 unsigned int idhashval;
2221 2356
2222 if (!(sop = alloc_stateowner(&open->op_owner))) 2357 sop = kmem_cache_alloc(slab, GFP_KERNEL);
2358 if (!sop)
2359 return NULL;
2360
2361 sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
2362 if (!sop->so_owner.data) {
2363 kmem_cache_free(slab, sop);
2223 return NULL; 2364 return NULL;
2224 idhashval = ownerid_hashval(current_ownerid); 2365 }
2225 INIT_LIST_HEAD(&sop->so_idhash); 2366 sop->so_owner.len = owner->len;
2226 INIT_LIST_HEAD(&sop->so_strhash); 2367
2227 INIT_LIST_HEAD(&sop->so_perclient);
2228 INIT_LIST_HEAD(&sop->so_stateids); 2368 INIT_LIST_HEAD(&sop->so_stateids);
2229 INIT_LIST_HEAD(&sop->so_perstateid); /* not used */
2230 INIT_LIST_HEAD(&sop->so_close_lru);
2231 sop->so_time = 0;
2232 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
2233 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
2234 list_add(&sop->so_perclient, &clp->cl_openowners);
2235 sop->so_is_open_owner = 1;
2236 sop->so_id = current_ownerid++;
2237 sop->so_client = clp; 2369 sop->so_client = clp;
2238 sop->so_seqid = open->op_seqid; 2370 init_nfs4_replay(&sop->so_replay);
2239 sop->so_confirmed = 0;
2240 rp = &sop->so_replay;
2241 rp->rp_status = nfserr_serverfault;
2242 rp->rp_buflen = 0;
2243 rp->rp_buf = rp->rp_ibuf;
2244 return sop; 2371 return sop;
2245} 2372}
2246 2373
2247static inline void 2374static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
2248init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 2375{
2249 struct nfs4_stateowner *sop = open->op_stateowner; 2376 list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]);
2250 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 2377 list_add(&oo->oo_perclient, &clp->cl_openowners);
2378}
2251 2379
2252 INIT_LIST_HEAD(&stp->st_hash); 2380static struct nfs4_openowner *
2253 INIT_LIST_HEAD(&stp->st_perstateowner); 2381alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
2382 struct nfs4_openowner *oo;
2383
2384 oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
2385 if (!oo)
2386 return NULL;
2387 oo->oo_owner.so_is_open_owner = 1;
2388 oo->oo_owner.so_seqid = open->op_seqid;
2389 oo->oo_flags = NFS4_OO_NEW;
2390 oo->oo_time = 0;
2391 oo->oo_last_closed_stid = NULL;
2392 INIT_LIST_HEAD(&oo->oo_close_lru);
2393 hash_openowner(oo, clp, strhashval);
2394 return oo;
2395}
2396
2397static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
2398 struct nfs4_openowner *oo = open->op_openowner;
2399 struct nfs4_client *clp = oo->oo_owner.so_client;
2400
2401 init_stid(&stp->st_stid, clp, NFS4_OPEN_STID);
2254 INIT_LIST_HEAD(&stp->st_lockowners); 2402 INIT_LIST_HEAD(&stp->st_lockowners);
2255 INIT_LIST_HEAD(&stp->st_perfile); 2403 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
2256 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
2257 list_add(&stp->st_perstateowner, &sop->so_stateids);
2258 list_add(&stp->st_perfile, &fp->fi_stateids); 2404 list_add(&stp->st_perfile, &fp->fi_stateids);
2259 stp->st_stateowner = sop; 2405 stp->st_stateowner = &oo->oo_owner;
2260 get_nfs4_file(fp); 2406 get_nfs4_file(fp);
2261 stp->st_file = fp; 2407 stp->st_file = fp;
2262 stp->st_stateid.si_boot = boot_time;
2263 stp->st_stateid.si_stateownerid = sop->so_id;
2264 stp->st_stateid.si_fileid = fp->fi_id;
2265 stp->st_stateid.si_generation = 0;
2266 stp->st_access_bmap = 0; 2408 stp->st_access_bmap = 0;
2267 stp->st_deny_bmap = 0; 2409 stp->st_deny_bmap = 0;
2268 __set_bit(open->op_share_access & ~NFS4_SHARE_WANT_MASK, 2410 __set_bit(open->op_share_access, &stp->st_access_bmap);
2269 &stp->st_access_bmap);
2270 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2411 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
2271 stp->st_openstp = NULL; 2412 stp->st_openstp = NULL;
2272} 2413}
2273 2414
2274static void 2415static void
2275move_to_close_lru(struct nfs4_stateowner *sop) 2416move_to_close_lru(struct nfs4_openowner *oo)
2276{ 2417{
2277 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); 2418 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
2278 2419
2279 list_move_tail(&sop->so_close_lru, &close_lru); 2420 list_move_tail(&oo->oo_close_lru, &close_lru);
2280 sop->so_time = get_seconds(); 2421 oo->oo_time = get_seconds();
2281} 2422}
2282 2423
2283static int 2424static int
@@ -2289,14 +2430,18 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
2289 (sop->so_client->cl_clientid.cl_id == clid->cl_id); 2430 (sop->so_client->cl_clientid.cl_id == clid->cl_id);
2290} 2431}
2291 2432
2292static struct nfs4_stateowner * 2433static struct nfs4_openowner *
2293find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) 2434find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
2294{ 2435{
2295 struct nfs4_stateowner *so = NULL; 2436 struct nfs4_stateowner *so;
2437 struct nfs4_openowner *oo;
2296 2438
2297 list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) { 2439 list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) {
2298 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) 2440 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
2299 return so; 2441 oo = openowner(so);
2442 renew_client(oo->oo_owner.so_client);
2443 return oo;
2444 }
2300 } 2445 }
2301 return NULL; 2446 return NULL;
2302} 2447}
@@ -2320,31 +2465,6 @@ find_file(struct inode *ino)
2320 return NULL; 2465 return NULL;
2321} 2466}
2322 2467
2323static inline int access_valid(u32 x, u32 minorversion)
2324{
2325 if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ)
2326 return 0;
2327 if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH)
2328 return 0;
2329 x &= ~NFS4_SHARE_ACCESS_MASK;
2330 if (minorversion && x) {
2331 if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL)
2332 return 0;
2333 if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED)
2334 return 0;
2335 x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK);
2336 }
2337 if (x)
2338 return 0;
2339 return 1;
2340}
2341
2342static inline int deny_valid(u32 x)
2343{
2344 /* Note: unlike access bits, deny bits may be zero. */
2345 return x <= NFS4_SHARE_DENY_BOTH;
2346}
2347
2348/* 2468/*
2349 * Called to check deny when READ with all zero stateid or 2469 * Called to check deny when READ with all zero stateid or
2350 * WRITE with all zero or all one stateid 2470 * WRITE with all zero or all one stateid
@@ -2354,7 +2474,7 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
2354{ 2474{
2355 struct inode *ino = current_fh->fh_dentry->d_inode; 2475 struct inode *ino = current_fh->fh_dentry->d_inode;
2356 struct nfs4_file *fp; 2476 struct nfs4_file *fp;
2357 struct nfs4_stateid *stp; 2477 struct nfs4_ol_stateid *stp;
2358 __be32 ret; 2478 __be32 ret;
2359 2479
2360 dprintk("NFSD: nfs4_share_conflict\n"); 2480 dprintk("NFSD: nfs4_share_conflict\n");
@@ -2429,6 +2549,16 @@ static const struct lock_manager_operations nfsd_lease_mng_ops = {
2429 .lm_change = nfsd_change_deleg_cb, 2549 .lm_change = nfsd_change_deleg_cb,
2430}; 2550};
2431 2551
2552static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4_stateowner *so, u32 seqid)
2553{
2554 if (nfsd4_has_session(cstate))
2555 return nfs_ok;
2556 if (seqid == so->so_seqid - 1)
2557 return nfserr_replay_me;
2558 if (seqid == so->so_seqid)
2559 return nfs_ok;
2560 return nfserr_bad_seqid;
2561}
2432 2562
2433__be32 2563__be32
2434nfsd4_process_open1(struct nfsd4_compound_state *cstate, 2564nfsd4_process_open1(struct nfsd4_compound_state *cstate,
@@ -2437,57 +2567,49 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2437 clientid_t *clientid = &open->op_clientid; 2567 clientid_t *clientid = &open->op_clientid;
2438 struct nfs4_client *clp = NULL; 2568 struct nfs4_client *clp = NULL;
2439 unsigned int strhashval; 2569 unsigned int strhashval;
2440 struct nfs4_stateowner *sop = NULL; 2570 struct nfs4_openowner *oo = NULL;
2441 2571 __be32 status;
2442 if (!check_name(open->op_owner))
2443 return nfserr_inval;
2444 2572
2445 if (STALE_CLIENTID(&open->op_clientid)) 2573 if (STALE_CLIENTID(&open->op_clientid))
2446 return nfserr_stale_clientid; 2574 return nfserr_stale_clientid;
2575 /*
2576 * In case we need it later, after we've already created the
2577 * file and don't want to risk a further failure:
2578 */
2579 open->op_file = nfsd4_alloc_file();
2580 if (open->op_file == NULL)
2581 return nfserr_jukebox;
2447 2582
2448 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); 2583 strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner);
2449 sop = find_openstateowner_str(strhashval, open); 2584 oo = find_openstateowner_str(strhashval, open);
2450 open->op_stateowner = sop; 2585 open->op_openowner = oo;
2451 if (!sop) { 2586 if (!oo) {
2452 /* Make sure the client's lease hasn't expired. */
2453 clp = find_confirmed_client(clientid); 2587 clp = find_confirmed_client(clientid);
2454 if (clp == NULL) 2588 if (clp == NULL)
2455 return nfserr_expired; 2589 return nfserr_expired;
2456 goto renew; 2590 goto new_owner;
2457 } 2591 }
2458 /* When sessions are used, skip open sequenceid processing */ 2592 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
2459 if (nfsd4_has_session(cstate))
2460 goto renew;
2461 if (!sop->so_confirmed) {
2462 /* Replace unconfirmed owners without checking for replay. */ 2593 /* Replace unconfirmed owners without checking for replay. */
2463 clp = sop->so_client; 2594 clp = oo->oo_owner.so_client;
2464 release_openowner(sop); 2595 release_openowner(oo);
2465 open->op_stateowner = NULL; 2596 open->op_openowner = NULL;
2466 goto renew; 2597 goto new_owner;
2467 }
2468 if (open->op_seqid == sop->so_seqid - 1) {
2469 if (sop->so_replay.rp_buflen)
2470 return nfserr_replay_me;
2471 /* The original OPEN failed so spectacularly
2472 * that we don't even have replay data saved!
2473 * Therefore, we have no choice but to continue
2474 * processing this OPEN; presumably, we'll
2475 * fail again for the same reason.
2476 */
2477 dprintk("nfsd4_process_open1: replay with no replay cache\n");
2478 goto renew;
2479 }
2480 if (open->op_seqid != sop->so_seqid)
2481 return nfserr_bad_seqid;
2482renew:
2483 if (open->op_stateowner == NULL) {
2484 sop = alloc_init_open_stateowner(strhashval, clp, open);
2485 if (sop == NULL)
2486 return nfserr_resource;
2487 open->op_stateowner = sop;
2488 } 2598 }
2489 list_del_init(&sop->so_close_lru); 2599 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
2490 renew_client(sop->so_client); 2600 if (status)
2601 return status;
2602 clp = oo->oo_owner.so_client;
2603 goto alloc_stateid;
2604new_owner:
2605 oo = alloc_init_open_stateowner(strhashval, clp, open);
2606 if (oo == NULL)
2607 return nfserr_jukebox;
2608 open->op_openowner = oo;
2609alloc_stateid:
2610 open->op_stp = nfs4_alloc_stateid(clp);
2611 if (!open->op_stp)
2612 return nfserr_jukebox;
2491 return nfs_ok; 2613 return nfs_ok;
2492} 2614}
2493 2615
@@ -2500,36 +2622,37 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
2500 return nfs_ok; 2622 return nfs_ok;
2501} 2623}
2502 2624
2503static struct nfs4_delegation * 2625static int share_access_to_flags(u32 share_access)
2504find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
2505{ 2626{
2506 struct nfs4_delegation *dp; 2627 share_access &= ~NFS4_SHARE_WANT_MASK;
2507 2628
2508 spin_lock(&recall_lock); 2629 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
2509 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
2510 if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid) {
2511 spin_unlock(&recall_lock);
2512 return dp;
2513 }
2514 spin_unlock(&recall_lock);
2515 return NULL;
2516} 2630}
2517 2631
2518static int share_access_to_flags(u32 share_access) 2632static struct nfs4_delegation *find_deleg_stateid(struct nfs4_client *cl, stateid_t *s)
2519{ 2633{
2520 share_access &= ~NFS4_SHARE_WANT_MASK; 2634 struct nfs4_stid *ret;
2521 2635
2522 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE; 2636 ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
2637 if (!ret)
2638 return NULL;
2639 return delegstateid(ret);
2640}
2641
2642static bool nfsd4_is_deleg_cur(struct nfsd4_open *open)
2643{
2644 return open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR ||
2645 open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH;
2523} 2646}
2524 2647
2525static __be32 2648static __be32
2526nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, 2649nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open *open,
2527 struct nfs4_delegation **dp) 2650 struct nfs4_delegation **dp)
2528{ 2651{
2529 int flags; 2652 int flags;
2530 __be32 status = nfserr_bad_stateid; 2653 __be32 status = nfserr_bad_stateid;
2531 2654
2532 *dp = find_delegation_file(fp, &open->op_delegate_stateid); 2655 *dp = find_deleg_stateid(cl, &open->op_delegate_stateid);
2533 if (*dp == NULL) 2656 if (*dp == NULL)
2534 goto out; 2657 goto out;
2535 flags = share_access_to_flags(open->op_share_access); 2658 flags = share_access_to_flags(open->op_share_access);
@@ -2537,41 +2660,37 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
2537 if (status) 2660 if (status)
2538 *dp = NULL; 2661 *dp = NULL;
2539out: 2662out:
2540 if (open->op_claim_type != NFS4_OPEN_CLAIM_DELEGATE_CUR) 2663 if (!nfsd4_is_deleg_cur(open))
2541 return nfs_ok; 2664 return nfs_ok;
2542 if (status) 2665 if (status)
2543 return status; 2666 return status;
2544 open->op_stateowner->so_confirmed = 1; 2667 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2545 return nfs_ok; 2668 return nfs_ok;
2546} 2669}
2547 2670
2548static __be32 2671static __be32
2549nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) 2672nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_stateid **stpp)
2550{ 2673{
2551 struct nfs4_stateid *local; 2674 struct nfs4_ol_stateid *local;
2552 __be32 status = nfserr_share_denied; 2675 struct nfs4_openowner *oo = open->op_openowner;
2553 struct nfs4_stateowner *sop = open->op_stateowner;
2554 2676
2555 list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 2677 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
2556 /* ignore lock owners */ 2678 /* ignore lock owners */
2557 if (local->st_stateowner->so_is_open_owner == 0) 2679 if (local->st_stateowner->so_is_open_owner == 0)
2558 continue; 2680 continue;
2559 /* remember if we have seen this open owner */ 2681 /* remember if we have seen this open owner */
2560 if (local->st_stateowner == sop) 2682 if (local->st_stateowner == &oo->oo_owner)
2561 *stpp = local; 2683 *stpp = local;
2562 /* check for conflicting share reservations */ 2684 /* check for conflicting share reservations */
2563 if (!test_share(local, open)) 2685 if (!test_share(local, open))
2564 goto out; 2686 return nfserr_share_denied;
2565 } 2687 }
2566 status = 0; 2688 return nfs_ok;
2567out:
2568 return status;
2569} 2689}
2570 2690
2571static inline struct nfs4_stateid * 2691static void nfs4_free_stateid(struct nfs4_ol_stateid *s)
2572nfs4_alloc_stateid(void)
2573{ 2692{
2574 return kmem_cache_alloc(stateid_slab, GFP_KERNEL); 2693 kmem_cache_free(stateid_slab, s);
2575} 2694}
2576 2695
2577static inline int nfs4_access_to_access(u32 nfs4_access) 2696static inline int nfs4_access_to_access(u32 nfs4_access)
@@ -2592,12 +2711,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
2592 int oflag = nfs4_access_to_omode(open->op_share_access); 2711 int oflag = nfs4_access_to_omode(open->op_share_access);
2593 int access = nfs4_access_to_access(open->op_share_access); 2712 int access = nfs4_access_to_access(open->op_share_access);
2594 2713
2595 /* CLAIM_DELEGATE_CUR is used in response to a broken lease;
2596 * allowing it to break the lease and return EAGAIN leaves the
2597 * client unable to make progress in returning the delegation */
2598 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
2599 access |= NFSD_MAY_NOT_BREAK_LEASE;
2600
2601 if (!fp->fi_fds[oflag]) { 2714 if (!fp->fi_fds[oflag]) {
2602 status = nfsd_open(rqstp, cur_fh, S_IFREG, access, 2715 status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
2603 &fp->fi_fds[oflag]); 2716 &fp->fi_fds[oflag]);
@@ -2609,27 +2722,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
2609 return nfs_ok; 2722 return nfs_ok;
2610} 2723}
2611 2724
2612static __be32
2613nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
2614 struct nfs4_file *fp, struct svc_fh *cur_fh,
2615 struct nfsd4_open *open)
2616{
2617 struct nfs4_stateid *stp;
2618 __be32 status;
2619
2620 stp = nfs4_alloc_stateid();
2621 if (stp == NULL)
2622 return nfserr_resource;
2623
2624 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2625 if (status) {
2626 kmem_cache_free(stateid_slab, stp);
2627 return status;
2628 }
2629 *stpp = stp;
2630 return 0;
2631}
2632
2633static inline __be32 2725static inline __be32
2634nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, 2726nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
2635 struct nfsd4_open *open) 2727 struct nfsd4_open *open)
@@ -2646,9 +2738,9 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
2646} 2738}
2647 2739
2648static __be32 2740static __be32
2649nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) 2741nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open)
2650{ 2742{
2651 u32 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; 2743 u32 op_share_access = open->op_share_access;
2652 bool new_access; 2744 bool new_access;
2653 __be32 status; 2745 __be32 status;
2654 2746
@@ -2677,8 +2769,8 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2677static void 2769static void
2678nfs4_set_claim_prev(struct nfsd4_open *open) 2770nfs4_set_claim_prev(struct nfsd4_open *open)
2679{ 2771{
2680 open->op_stateowner->so_confirmed = 1; 2772 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2681 open->op_stateowner->so_client->cl_firststate = 1; 2773 open->op_openowner->oo_owner.so_client->cl_firststate = 1;
2682} 2774}
2683 2775
2684/* Should we give out recallable state?: */ 2776/* Should we give out recallable state?: */
@@ -2721,7 +2813,7 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
2721 if (!fl) 2813 if (!fl)
2722 return -ENOMEM; 2814 return -ENOMEM;
2723 fl->fl_file = find_readable_file(fp); 2815 fl->fl_file = find_readable_file(fp);
2724 list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); 2816 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
2725 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); 2817 status = vfs_setlease(fl->fl_file, fl->fl_type, &fl);
2726 if (status) { 2818 if (status) {
2727 list_del_init(&dp->dl_perclnt); 2819 list_del_init(&dp->dl_perclnt);
@@ -2750,7 +2842,7 @@ static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag)
2750 atomic_inc(&fp->fi_delegees); 2842 atomic_inc(&fp->fi_delegees);
2751 list_add(&dp->dl_perfile, &fp->fi_delegations); 2843 list_add(&dp->dl_perfile, &fp->fi_delegations);
2752 spin_unlock(&recall_lock); 2844 spin_unlock(&recall_lock);
2753 list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); 2845 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
2754 return 0; 2846 return 0;
2755} 2847}
2756 2848
@@ -2758,14 +2850,14 @@ static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag)
2758 * Attempt to hand out a delegation. 2850 * Attempt to hand out a delegation.
2759 */ 2851 */
2760static void 2852static void
2761nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp) 2853nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_stateid *stp)
2762{ 2854{
2763 struct nfs4_delegation *dp; 2855 struct nfs4_delegation *dp;
2764 struct nfs4_stateowner *sop = stp->st_stateowner; 2856 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
2765 int cb_up; 2857 int cb_up;
2766 int status, flag = 0; 2858 int status, flag = 0;
2767 2859
2768 cb_up = nfsd4_cb_channel_good(sop->so_client); 2860 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
2769 flag = NFS4_OPEN_DELEGATE_NONE; 2861 flag = NFS4_OPEN_DELEGATE_NONE;
2770 open->op_recall = 0; 2862 open->op_recall = 0;
2771 switch (open->op_claim_type) { 2863 switch (open->op_claim_type) {
@@ -2781,7 +2873,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2781 * had the chance to reclaim theirs.... */ 2873 * had the chance to reclaim theirs.... */
2782 if (locks_in_grace()) 2874 if (locks_in_grace())
2783 goto out; 2875 goto out;
2784 if (!cb_up || !sop->so_confirmed) 2876 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
2785 goto out; 2877 goto out;
2786 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 2878 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
2787 flag = NFS4_OPEN_DELEGATE_WRITE; 2879 flag = NFS4_OPEN_DELEGATE_WRITE;
@@ -2792,17 +2884,17 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2792 goto out; 2884 goto out;
2793 } 2885 }
2794 2886
2795 dp = alloc_init_deleg(sop->so_client, stp, fh, flag); 2887 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
2796 if (dp == NULL) 2888 if (dp == NULL)
2797 goto out_no_deleg; 2889 goto out_no_deleg;
2798 status = nfs4_set_delegation(dp, flag); 2890 status = nfs4_set_delegation(dp, flag);
2799 if (status) 2891 if (status)
2800 goto out_free; 2892 goto out_free;
2801 2893
2802 memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); 2894 memcpy(&open->op_delegate_stateid, &dp->dl_stid.sc_stateid, sizeof(dp->dl_stid.sc_stateid));
2803 2895
2804 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 2896 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
2805 STATEID_VAL(&dp->dl_stateid)); 2897 STATEID_VAL(&dp->dl_stid.sc_stateid));
2806out: 2898out:
2807 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS 2899 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
2808 && flag == NFS4_OPEN_DELEGATE_NONE 2900 && flag == NFS4_OPEN_DELEGATE_NONE
@@ -2824,16 +2916,13 @@ __be32
2824nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 2916nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
2825{ 2917{
2826 struct nfsd4_compoundres *resp = rqstp->rq_resp; 2918 struct nfsd4_compoundres *resp = rqstp->rq_resp;
2919 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
2827 struct nfs4_file *fp = NULL; 2920 struct nfs4_file *fp = NULL;
2828 struct inode *ino = current_fh->fh_dentry->d_inode; 2921 struct inode *ino = current_fh->fh_dentry->d_inode;
2829 struct nfs4_stateid *stp = NULL; 2922 struct nfs4_ol_stateid *stp = NULL;
2830 struct nfs4_delegation *dp = NULL; 2923 struct nfs4_delegation *dp = NULL;
2831 __be32 status; 2924 __be32 status;
2832 2925
2833 status = nfserr_inval;
2834 if (!access_valid(open->op_share_access, resp->cstate.minorversion)
2835 || !deny_valid(open->op_share_deny))
2836 goto out;
2837 /* 2926 /*
2838 * Lookup file; if found, lookup stateid and check open request, 2927 * Lookup file; if found, lookup stateid and check open request,
2839 * and check for delegations in the process of being recalled. 2928 * and check for delegations in the process of being recalled.
@@ -2843,17 +2932,17 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2843 if (fp) { 2932 if (fp) {
2844 if ((status = nfs4_check_open(fp, open, &stp))) 2933 if ((status = nfs4_check_open(fp, open, &stp)))
2845 goto out; 2934 goto out;
2846 status = nfs4_check_deleg(fp, open, &dp); 2935 status = nfs4_check_deleg(cl, fp, open, &dp);
2847 if (status) 2936 if (status)
2848 goto out; 2937 goto out;
2849 } else { 2938 } else {
2850 status = nfserr_bad_stateid; 2939 status = nfserr_bad_stateid;
2851 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) 2940 if (nfsd4_is_deleg_cur(open))
2852 goto out;
2853 status = nfserr_resource;
2854 fp = alloc_init_file(ino);
2855 if (fp == NULL)
2856 goto out; 2941 goto out;
2942 status = nfserr_jukebox;
2943 fp = open->op_file;
2944 open->op_file = NULL;
2945 nfsd4_init_file(fp, ino);
2857 } 2946 }
2858 2947
2859 /* 2948 /*
@@ -2865,24 +2954,24 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2865 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); 2954 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
2866 if (status) 2955 if (status)
2867 goto out; 2956 goto out;
2868 update_stateid(&stp->st_stateid);
2869 } else { 2957 } else {
2870 status = nfs4_new_open(rqstp, &stp, fp, current_fh, open); 2958 status = nfs4_get_vfs_file(rqstp, fp, current_fh, open);
2871 if (status) 2959 if (status)
2872 goto out; 2960 goto out;
2873 init_stateid(stp, fp, open); 2961 stp = open->op_stp;
2962 open->op_stp = NULL;
2963 init_open_stateid(stp, fp, open);
2874 status = nfsd4_truncate(rqstp, current_fh, open); 2964 status = nfsd4_truncate(rqstp, current_fh, open);
2875 if (status) { 2965 if (status) {
2876 release_open_stateid(stp); 2966 release_open_stateid(stp);
2877 goto out; 2967 goto out;
2878 } 2968 }
2879 if (nfsd4_has_session(&resp->cstate))
2880 update_stateid(&stp->st_stateid);
2881 } 2969 }
2882 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); 2970 update_stateid(&stp->st_stid.sc_stateid);
2971 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
2883 2972
2884 if (nfsd4_has_session(&resp->cstate)) 2973 if (nfsd4_has_session(&resp->cstate))
2885 open->op_stateowner->so_confirmed = 1; 2974 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2886 2975
2887 /* 2976 /*
2888 * Attempt to hand out a delegation. No error return, because the 2977 * Attempt to hand out a delegation. No error return, because the
@@ -2893,7 +2982,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2893 status = nfs_ok; 2982 status = nfs_ok;
2894 2983
2895 dprintk("%s: stateid=" STATEID_FMT "\n", __func__, 2984 dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
2896 STATEID_VAL(&stp->st_stateid)); 2985 STATEID_VAL(&stp->st_stid.sc_stateid));
2897out: 2986out:
2898 if (fp) 2987 if (fp)
2899 put_nfs4_file(fp); 2988 put_nfs4_file(fp);
@@ -2903,13 +2992,34 @@ out:
2903 * To finish the open response, we just need to set the rflags. 2992 * To finish the open response, we just need to set the rflags.
2904 */ 2993 */
2905 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; 2994 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
2906 if (!open->op_stateowner->so_confirmed && 2995 if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED) &&
2907 !nfsd4_has_session(&resp->cstate)) 2996 !nfsd4_has_session(&resp->cstate))
2908 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; 2997 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
2909 2998
2910 return status; 2999 return status;
2911} 3000}
2912 3001
3002void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
3003{
3004 if (open->op_openowner) {
3005 struct nfs4_openowner *oo = open->op_openowner;
3006
3007 if (!list_empty(&oo->oo_owner.so_stateids))
3008 list_del_init(&oo->oo_close_lru);
3009 if (oo->oo_flags & NFS4_OO_NEW) {
3010 if (status) {
3011 release_openowner(oo);
3012 open->op_openowner = NULL;
3013 } else
3014 oo->oo_flags &= ~NFS4_OO_NEW;
3015 }
3016 }
3017 if (open->op_file)
3018 nfsd4_free_file(open->op_file);
3019 if (open->op_stp)
3020 nfs4_free_stateid(open->op_stp);
3021}
3022
2913__be32 3023__be32
2914nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3024nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2915 clientid_t *clid) 3025 clientid_t *clid)
@@ -2930,7 +3040,6 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2930 dprintk("nfsd4_renew: clientid not found!\n"); 3040 dprintk("nfsd4_renew: clientid not found!\n");
2931 goto out; 3041 goto out;
2932 } 3042 }
2933 renew_client(clp);
2934 status = nfserr_cb_path_down; 3043 status = nfserr_cb_path_down;
2935 if (!list_empty(&clp->cl_delegations) 3044 if (!list_empty(&clp->cl_delegations)
2936 && clp->cl_cb_state != NFSD4_CB_UP) 3045 && clp->cl_cb_state != NFSD4_CB_UP)
@@ -2962,7 +3071,7 @@ static time_t
2962nfs4_laundromat(void) 3071nfs4_laundromat(void)
2963{ 3072{
2964 struct nfs4_client *clp; 3073 struct nfs4_client *clp;
2965 struct nfs4_stateowner *sop; 3074 struct nfs4_openowner *oo;
2966 struct nfs4_delegation *dp; 3075 struct nfs4_delegation *dp;
2967 struct list_head *pos, *next, reaplist; 3076 struct list_head *pos, *next, reaplist;
2968 time_t cutoff = get_seconds() - nfsd4_lease; 3077 time_t cutoff = get_seconds() - nfsd4_lease;
@@ -3019,16 +3128,14 @@ nfs4_laundromat(void)
3019 } 3128 }
3020 test_val = nfsd4_lease; 3129 test_val = nfsd4_lease;
3021 list_for_each_safe(pos, next, &close_lru) { 3130 list_for_each_safe(pos, next, &close_lru) {
3022 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); 3131 oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
3023 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { 3132 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3024 u = sop->so_time - cutoff; 3133 u = oo->oo_time - cutoff;
3025 if (test_val > u) 3134 if (test_val > u)
3026 test_val = u; 3135 test_val = u;
3027 break; 3136 break;
3028 } 3137 }
3029 dprintk("NFSD: purging unused open stateowner (so_id %d)\n", 3138 release_openowner(oo);
3030 sop->so_id);
3031 release_openowner(sop);
3032 } 3139 }
3033 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) 3140 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
3034 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; 3141 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
@@ -3050,30 +3157,17 @@ laundromat_main(struct work_struct *not_used)
3050 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 3157 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
3051} 3158}
3052 3159
3053static struct nfs4_stateowner * 3160static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
3054search_close_lru(u32 st_id, int flags)
3055{ 3161{
3056 struct nfs4_stateowner *local = NULL; 3162 if (fhp->fh_dentry->d_inode != stp->st_file->fi_inode)
3057 3163 return nfserr_bad_stateid;
3058 if (flags & CLOSE_STATE) { 3164 return nfs_ok;
3059 list_for_each_entry(local, &close_lru, so_close_lru) {
3060 if (local->so_id == st_id)
3061 return local;
3062 }
3063 }
3064 return NULL;
3065}
3066
3067static inline int
3068nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
3069{
3070 return fhp->fh_dentry->d_inode != stp->st_file->fi_inode;
3071} 3165}
3072 3166
3073static int 3167static int
3074STALE_STATEID(stateid_t *stateid) 3168STALE_STATEID(stateid_t *stateid)
3075{ 3169{
3076 if (stateid->si_boot == boot_time) 3170 if (stateid->si_opaque.so_clid.cl_boot == boot_time)
3077 return 0; 3171 return 0;
3078 dprintk("NFSD: stale stateid " STATEID_FMT "!\n", 3172 dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
3079 STATEID_VAL(stateid)); 3173 STATEID_VAL(stateid));
@@ -3096,7 +3190,7 @@ access_permit_write(unsigned long access_bmap)
3096} 3190}
3097 3191
3098static 3192static
3099__be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags) 3193__be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
3100{ 3194{
3101 __be32 status = nfserr_openmode; 3195 __be32 status = nfserr_openmode;
3102 3196
@@ -3139,68 +3233,80 @@ grace_disallows_io(struct inode *inode)
3139 return locks_in_grace() && mandatory_lock(inode); 3233 return locks_in_grace() && mandatory_lock(inode);
3140} 3234}
3141 3235
3142static int check_stateid_generation(stateid_t *in, stateid_t *ref, int flags) 3236/* Returns true iff a is later than b: */
3237static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3238{
3239 return (s32)a->si_generation - (s32)b->si_generation > 0;
3240}
3241
3242static int check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
3143{ 3243{
3144 /* 3244 /*
3145 * When sessions are used the stateid generation number is ignored 3245 * When sessions are used the stateid generation number is ignored
3146 * when it is zero. 3246 * when it is zero.
3147 */ 3247 */
3148 if ((flags & HAS_SESSION) && in->si_generation == 0) 3248 if (has_session && in->si_generation == 0)
3149 goto out; 3249 return nfs_ok;
3250
3251 if (in->si_generation == ref->si_generation)
3252 return nfs_ok;
3150 3253
3151 /* If the client sends us a stateid from the future, it's buggy: */ 3254 /* If the client sends us a stateid from the future, it's buggy: */
3152 if (in->si_generation > ref->si_generation) 3255 if (stateid_generation_after(in, ref))
3153 return nfserr_bad_stateid; 3256 return nfserr_bad_stateid;
3154 /* 3257 /*
3155 * The following, however, can happen. For example, if the 3258 * However, we could see a stateid from the past, even from a
3156 * client sends an open and some IO at the same time, the open 3259 * non-buggy client. For example, if the client sends a lock
3157 * may bump si_generation while the IO is still in flight. 3260 * while some IO is outstanding, the lock may bump si_generation
3158 * Thanks to hard links and renames, the client never knows what 3261 * while the IO is still in flight. The client could avoid that
3159 * file an open will affect. So it could avoid that situation 3262 * situation by waiting for responses on all the IO requests,
3160 * only by serializing all opens and IO from the same open 3263 * but better performance may result in retrying IO that
3161 * owner. To recover from the old_stateid error, the client 3264 * receives an old_stateid error if requests are rarely
3162 * will just have to retry the IO: 3265 * reordered in flight:
3163 */ 3266 */
3164 if (in->si_generation < ref->si_generation) 3267 return nfserr_old_stateid;
3165 return nfserr_old_stateid;
3166out:
3167 return nfs_ok;
3168} 3268}
3169 3269
3170static int is_delegation_stateid(stateid_t *stateid) 3270__be32 nfs4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
3171{ 3271{
3172 return stateid->si_fileid == 0; 3272 struct nfs4_stid *s;
3173} 3273 struct nfs4_ol_stateid *ols;
3274 __be32 status;
3174 3275
3175static int is_open_stateid(struct nfs4_stateid *stateid) 3276 if (STALE_STATEID(stateid))
3176{ 3277 return nfserr_stale_stateid;
3177 return stateid->st_openstp == NULL; 3278
3279 s = find_stateid(cl, stateid);
3280 if (!s)
3281 return nfserr_stale_stateid;
3282 status = check_stateid_generation(stateid, &s->sc_stateid, 1);
3283 if (status)
3284 return status;
3285 if (!(s->sc_type & (NFS4_OPEN_STID | NFS4_LOCK_STID)))
3286 return nfs_ok;
3287 ols = openlockstateid(s);
3288 if (ols->st_stateowner->so_is_open_owner
3289 && !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
3290 return nfserr_bad_stateid;
3291 return nfs_ok;
3178} 3292}
3179 3293
3180__be32 nfs4_validate_stateid(stateid_t *stateid, int flags) 3294static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s)
3181{ 3295{
3182 struct nfs4_stateid *stp = NULL; 3296 struct nfs4_client *cl;
3183 __be32 status = nfserr_stale_stateid;
3184 3297
3298 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3299 return nfserr_bad_stateid;
3185 if (STALE_STATEID(stateid)) 3300 if (STALE_STATEID(stateid))
3186 goto out; 3301 return nfserr_stale_stateid;
3187 3302 cl = find_confirmed_client(&stateid->si_opaque.so_clid);
3188 status = nfserr_expired; 3303 if (!cl)
3189 stp = search_for_stateid(stateid); 3304 return nfserr_expired;
3190 if (!stp) 3305 *s = find_stateid_by_type(cl, stateid, typemask);
3191 goto out; 3306 if (!*s)
3192 status = nfserr_bad_stateid; 3307 return nfserr_bad_stateid;
3193 3308 return nfs_ok;
3194 if (!stp->st_stateowner->so_confirmed)
3195 goto out;
3196
3197 status = check_stateid_generation(stateid, &stp->st_stateid, flags);
3198 if (status)
3199 goto out;
3200 3309
3201 status = nfs_ok;
3202out:
3203 return status;
3204} 3310}
3205 3311
3206/* 3312/*
@@ -3210,7 +3316,8 @@ __be32
3210nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, 3316nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3211 stateid_t *stateid, int flags, struct file **filpp) 3317 stateid_t *stateid, int flags, struct file **filpp)
3212{ 3318{
3213 struct nfs4_stateid *stp = NULL; 3319 struct nfs4_stid *s;
3320 struct nfs4_ol_stateid *stp = NULL;
3214 struct nfs4_delegation *dp = NULL; 3321 struct nfs4_delegation *dp = NULL;
3215 struct svc_fh *current_fh = &cstate->current_fh; 3322 struct svc_fh *current_fh = &cstate->current_fh;
3216 struct inode *ino = current_fh->fh_dentry->d_inode; 3323 struct inode *ino = current_fh->fh_dentry->d_inode;
@@ -3222,60 +3329,47 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3222 if (grace_disallows_io(ino)) 3329 if (grace_disallows_io(ino))
3223 return nfserr_grace; 3330 return nfserr_grace;
3224 3331
3225 if (nfsd4_has_session(cstate))
3226 flags |= HAS_SESSION;
3227
3228 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3332 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
3229 return check_special_stateids(current_fh, stateid, flags); 3333 return check_special_stateids(current_fh, stateid, flags);
3230 3334
3231 status = nfserr_stale_stateid; 3335 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s);
3232 if (STALE_STATEID(stateid)) 3336 if (status)
3337 return status;
3338 status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
3339 if (status)
3233 goto out; 3340 goto out;
3234 3341 switch (s->sc_type) {
3235 /* 3342 case NFS4_DELEG_STID:
3236 * We assume that any stateid that has the current boot time, 3343 dp = delegstateid(s);
3237 * but that we can't find, is expired:
3238 */
3239 status = nfserr_expired;
3240 if (is_delegation_stateid(stateid)) {
3241 dp = find_delegation_stateid(ino, stateid);
3242 if (!dp)
3243 goto out;
3244 status = check_stateid_generation(stateid, &dp->dl_stateid,
3245 flags);
3246 if (status)
3247 goto out;
3248 status = nfs4_check_delegmode(dp, flags); 3344 status = nfs4_check_delegmode(dp, flags);
3249 if (status) 3345 if (status)
3250 goto out; 3346 goto out;
3251 renew_client(dp->dl_client);
3252 if (filpp) { 3347 if (filpp) {
3253 *filpp = dp->dl_file->fi_deleg_file; 3348 *filpp = dp->dl_file->fi_deleg_file;
3254 BUG_ON(!*filpp); 3349 BUG_ON(!*filpp);
3255 } 3350 }
3256 } else { /* open or lock stateid */ 3351 break;
3257 stp = find_stateid(stateid, flags); 3352 case NFS4_OPEN_STID:
3258 if (!stp) 3353 case NFS4_LOCK_STID:
3259 goto out; 3354 stp = openlockstateid(s);
3260 status = nfserr_bad_stateid; 3355 status = nfs4_check_fh(current_fh, stp);
3261 if (nfs4_check_fh(current_fh, stp))
3262 goto out;
3263 if (!stp->st_stateowner->so_confirmed)
3264 goto out;
3265 status = check_stateid_generation(stateid, &stp->st_stateid,
3266 flags);
3267 if (status) 3356 if (status)
3268 goto out; 3357 goto out;
3358 if (stp->st_stateowner->so_is_open_owner
3359 && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
3360 goto out;
3269 status = nfs4_check_openmode(stp, flags); 3361 status = nfs4_check_openmode(stp, flags);
3270 if (status) 3362 if (status)
3271 goto out; 3363 goto out;
3272 renew_client(stp->st_stateowner->so_client);
3273 if (filpp) { 3364 if (filpp) {
3274 if (flags & RD_STATE) 3365 if (flags & RD_STATE)
3275 *filpp = find_readable_file(stp->st_file); 3366 *filpp = find_readable_file(stp->st_file);
3276 else 3367 else
3277 *filpp = find_writeable_file(stp->st_file); 3368 *filpp = find_writeable_file(stp->st_file);
3278 } 3369 }
3370 break;
3371 default:
3372 return nfserr_bad_stateid;
3279 } 3373 }
3280 status = nfs_ok; 3374 status = nfs_ok;
3281out: 3375out:
@@ -3283,18 +3377,9 @@ out:
3283} 3377}
3284 3378
3285static __be32 3379static __be32
3286nfsd4_free_delegation_stateid(stateid_t *stateid) 3380nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
3287{ 3381{
3288 struct nfs4_delegation *dp = search_for_delegation(stateid); 3382 if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner)))
3289 if (dp)
3290 return nfserr_locks_held;
3291 return nfserr_bad_stateid;
3292}
3293
3294static __be32
3295nfsd4_free_lock_stateid(struct nfs4_stateid *stp)
3296{
3297 if (check_for_locks(stp->st_file, stp->st_stateowner))
3298 return nfserr_locks_held; 3383 return nfserr_locks_held;
3299 release_lock_stateid(stp); 3384 release_lock_stateid(stp);
3300 return nfs_ok; 3385 return nfs_ok;
@@ -3307,51 +3392,40 @@ __be32
3307nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3392nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3308 struct nfsd4_test_stateid *test_stateid) 3393 struct nfsd4_test_stateid *test_stateid)
3309{ 3394{
3310 test_stateid->ts_has_session = nfsd4_has_session(cstate); 3395 /* real work is done during encoding */
3311 return nfs_ok; 3396 return nfs_ok;
3312} 3397}
3313 3398
3314/*
3315 * Free a state id
3316 */
3317__be32 3399__be32
3318nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3400nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3319 struct nfsd4_free_stateid *free_stateid) 3401 struct nfsd4_free_stateid *free_stateid)
3320{ 3402{
3321 stateid_t *stateid = &free_stateid->fr_stateid; 3403 stateid_t *stateid = &free_stateid->fr_stateid;
3322 struct nfs4_stateid *stp; 3404 struct nfs4_stid *s;
3323 __be32 ret; 3405 struct nfs4_client *cl = cstate->session->se_client;
3406 __be32 ret = nfserr_bad_stateid;
3324 3407
3325 nfs4_lock_state(); 3408 nfs4_lock_state();
3326 if (is_delegation_stateid(stateid)) { 3409 s = find_stateid(cl, stateid);
3327 ret = nfsd4_free_delegation_stateid(stateid); 3410 if (!s)
3328 goto out;
3329 }
3330
3331 stp = search_for_stateid(stateid);
3332 if (!stp) {
3333 ret = nfserr_bad_stateid;
3334 goto out; 3411 goto out;
3335 } 3412 switch (s->sc_type) {
3336 if (stateid->si_generation != 0) { 3413 case NFS4_DELEG_STID:
3337 if (stateid->si_generation < stp->st_stateid.si_generation) {
3338 ret = nfserr_old_stateid;
3339 goto out;
3340 }
3341 if (stateid->si_generation > stp->st_stateid.si_generation) {
3342 ret = nfserr_bad_stateid;
3343 goto out;
3344 }
3345 }
3346
3347 if (is_open_stateid(stp)) {
3348 ret = nfserr_locks_held; 3414 ret = nfserr_locks_held;
3349 goto out; 3415 goto out;
3350 } else { 3416 case NFS4_OPEN_STID:
3351 ret = nfsd4_free_lock_stateid(stp); 3417 case NFS4_LOCK_STID:
3352 goto out; 3418 ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
3419 if (ret)
3420 goto out;
3421 if (s->sc_type == NFS4_LOCK_STID)
3422 ret = nfsd4_free_lock_stateid(openlockstateid(s));
3423 else
3424 ret = nfserr_locks_held;
3425 break;
3426 default:
3427 ret = nfserr_bad_stateid;
3353 } 3428 }
3354
3355out: 3429out:
3356 nfs4_unlock_state(); 3430 nfs4_unlock_state();
3357 return ret; 3431 return ret;
@@ -3364,124 +3438,64 @@ setlkflg (int type)
3364 RD_STATE : WR_STATE; 3438 RD_STATE : WR_STATE;
3365} 3439}
3366 3440
3441static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_t *stateid, u32 seqid, struct nfs4_ol_stateid *stp)
3442{
3443 struct svc_fh *current_fh = &cstate->current_fh;
3444 struct nfs4_stateowner *sop = stp->st_stateowner;
3445 __be32 status;
3446
3447 status = nfsd4_check_seqid(cstate, sop, seqid);
3448 if (status)
3449 return status;
3450 if (stp->st_stid.sc_type == NFS4_CLOSED_STID)
3451 /*
3452 * "Closed" stateid's exist *only* to return
3453 * nfserr_replay_me from the previous step.
3454 */
3455 return nfserr_bad_stateid;
3456 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
3457 if (status)
3458 return status;
3459 return nfs4_check_fh(current_fh, stp);
3460}
3461
3367/* 3462/*
3368 * Checks for sequence id mutating operations. 3463 * Checks for sequence id mutating operations.
3369 */ 3464 */
3370static __be32 3465static __be32
3371nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, 3466nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3372 stateid_t *stateid, int flags, 3467 stateid_t *stateid, char typemask,
3373 struct nfs4_stateowner **sopp, 3468 struct nfs4_ol_stateid **stpp)
3374 struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
3375{ 3469{
3376 struct nfs4_stateid *stp;
3377 struct nfs4_stateowner *sop;
3378 struct svc_fh *current_fh = &cstate->current_fh;
3379 __be32 status; 3470 __be32 status;
3471 struct nfs4_stid *s;
3380 3472
3381 dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, 3473 dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
3382 seqid, STATEID_VAL(stateid)); 3474 seqid, STATEID_VAL(stateid));
3383 3475
3384 *stpp = NULL; 3476 *stpp = NULL;
3385 *sopp = NULL; 3477 status = nfsd4_lookup_stateid(stateid, typemask, &s);
3386 3478 if (status)
3387 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { 3479 return status;
3388 dprintk("NFSD: preprocess_seqid_op: magic stateid!\n"); 3480 *stpp = openlockstateid(s);
3389 return nfserr_bad_stateid; 3481 cstate->replay_owner = (*stpp)->st_stateowner;
3390 }
3391
3392 if (STALE_STATEID(stateid))
3393 return nfserr_stale_stateid;
3394
3395 if (nfsd4_has_session(cstate))
3396 flags |= HAS_SESSION;
3397
3398 /*
3399 * We return BAD_STATEID if filehandle doesn't match stateid,
3400 * the confirmed flag is incorrecly set, or the generation
3401 * number is incorrect.
3402 */
3403 stp = find_stateid(stateid, flags);
3404 if (stp == NULL) {
3405 /*
3406 * Also, we should make sure this isn't just the result of
3407 * a replayed close:
3408 */
3409 sop = search_close_lru(stateid->si_stateownerid, flags);
3410 /* It's not stale; let's assume it's expired: */
3411 if (sop == NULL)
3412 return nfserr_expired;
3413 *sopp = sop;
3414 goto check_replay;
3415 }
3416
3417 *stpp = stp;
3418 *sopp = sop = stp->st_stateowner;
3419
3420 if (lock) {
3421 clientid_t *lockclid = &lock->v.new.clientid;
3422 struct nfs4_client *clp = sop->so_client;
3423 int lkflg = 0;
3424 __be32 status;
3425
3426 lkflg = setlkflg(lock->lk_type);
3427
3428 if (lock->lk_is_new) {
3429 if (!sop->so_is_open_owner)
3430 return nfserr_bad_stateid;
3431 if (!(flags & HAS_SESSION) &&
3432 !same_clid(&clp->cl_clientid, lockclid))
3433 return nfserr_bad_stateid;
3434 /* stp is the open stateid */
3435 status = nfs4_check_openmode(stp, lkflg);
3436 if (status)
3437 return status;
3438 } else {
3439 /* stp is the lock stateid */
3440 status = nfs4_check_openmode(stp->st_openstp, lkflg);
3441 if (status)
3442 return status;
3443 }
3444 }
3445 3482
3446 if (nfs4_check_fh(current_fh, stp)) { 3483 return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp);
3447 dprintk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); 3484}
3448 return nfserr_bad_stateid;
3449 }
3450 3485
3451 /* 3486static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, stateid_t *stateid, struct nfs4_ol_stateid **stpp)
3452 * We now validate the seqid and stateid generation numbers. 3487{
3453 * For the moment, we ignore the possibility of 3488 __be32 status;
3454 * generation number wraparound. 3489 struct nfs4_openowner *oo;
3455 */
3456 if (!(flags & HAS_SESSION) && seqid != sop->so_seqid)
3457 goto check_replay;
3458 3490
3459 if (sop->so_confirmed && flags & CONFIRM) { 3491 status = nfs4_preprocess_seqid_op(cstate, seqid, stateid,
3460 dprintk("NFSD: preprocess_seqid_op: expected" 3492 NFS4_OPEN_STID, stpp);
3461 " unconfirmed stateowner!\n");
3462 return nfserr_bad_stateid;
3463 }
3464 if (!sop->so_confirmed && !(flags & CONFIRM)) {
3465 dprintk("NFSD: preprocess_seqid_op: stateowner not"
3466 " confirmed yet!\n");
3467 return nfserr_bad_stateid;
3468 }
3469 status = check_stateid_generation(stateid, &stp->st_stateid, flags);
3470 if (status) 3493 if (status)
3471 return status; 3494 return status;
3472 renew_client(sop->so_client); 3495 oo = openowner((*stpp)->st_stateowner);
3496 if (!(oo->oo_flags & NFS4_OO_CONFIRMED))
3497 return nfserr_bad_stateid;
3473 return nfs_ok; 3498 return nfs_ok;
3474
3475check_replay:
3476 if (seqid == sop->so_seqid - 1) {
3477 dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
3478 /* indicate replay to calling function */
3479 return nfserr_replay_me;
3480 }
3481 dprintk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
3482 sop->so_seqid, seqid);
3483 *sopp = NULL;
3484 return nfserr_bad_seqid;
3485} 3499}
3486 3500
3487__be32 3501__be32
@@ -3489,8 +3503,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3489 struct nfsd4_open_confirm *oc) 3503 struct nfsd4_open_confirm *oc)
3490{ 3504{
3491 __be32 status; 3505 __be32 status;
3492 struct nfs4_stateowner *sop; 3506 struct nfs4_openowner *oo;
3493 struct nfs4_stateid *stp; 3507 struct nfs4_ol_stateid *stp;
3494 3508
3495 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", 3509 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
3496 (int)cstate->current_fh.fh_dentry->d_name.len, 3510 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3502,38 +3516,52 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3502 3516
3503 nfs4_lock_state(); 3517 nfs4_lock_state();
3504 3518
3505 if ((status = nfs4_preprocess_seqid_op(cstate, 3519 status = nfs4_preprocess_seqid_op(cstate,
3506 oc->oc_seqid, &oc->oc_req_stateid, 3520 oc->oc_seqid, &oc->oc_req_stateid,
3507 CONFIRM | OPEN_STATE, 3521 NFS4_OPEN_STID, &stp);
3508 &oc->oc_stateowner, &stp, NULL))) 3522 if (status)
3509 goto out; 3523 goto out;
3510 3524 oo = openowner(stp->st_stateowner);
3511 sop = oc->oc_stateowner; 3525 status = nfserr_bad_stateid;
3512 sop->so_confirmed = 1; 3526 if (oo->oo_flags & NFS4_OO_CONFIRMED)
3513 update_stateid(&stp->st_stateid); 3527 goto out;
3514 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); 3528 oo->oo_flags |= NFS4_OO_CONFIRMED;
3529 update_stateid(&stp->st_stid.sc_stateid);
3530 memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3515 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 3531 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
3516 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); 3532 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
3517 3533
3518 nfsd4_create_clid_dir(sop->so_client); 3534 nfsd4_create_clid_dir(oo->oo_owner.so_client);
3535 status = nfs_ok;
3519out: 3536out:
3520 if (oc->oc_stateowner) { 3537 if (!cstate->replay_owner)
3521 nfs4_get_stateowner(oc->oc_stateowner); 3538 nfs4_unlock_state();
3522 cstate->replay_owner = oc->oc_stateowner;
3523 }
3524 nfs4_unlock_state();
3525 return status; 3539 return status;
3526} 3540}
3527 3541
3528static inline void nfs4_file_downgrade(struct nfs4_stateid *stp, unsigned int to_access) 3542static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
3529{ 3543{
3530 int i; 3544 if (!test_bit(access, &stp->st_access_bmap))
3545 return;
3546 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access));
3547 __clear_bit(access, &stp->st_access_bmap);
3548}
3531 3549
3532 for (i = 1; i < 4; i++) { 3550static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
3533 if (test_bit(i, &stp->st_access_bmap) && !(i & to_access)) { 3551{
3534 nfs4_file_put_access(stp->st_file, i); 3552 switch (to_access) {
3535 __clear_bit(i, &stp->st_access_bmap); 3553 case NFS4_SHARE_ACCESS_READ:
3536 } 3554 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_WRITE);
3555 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
3556 break;
3557 case NFS4_SHARE_ACCESS_WRITE:
3558 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_READ);
3559 nfs4_stateid_downgrade_bit(stp, NFS4_SHARE_ACCESS_BOTH);
3560 break;
3561 case NFS4_SHARE_ACCESS_BOTH:
3562 break;
3563 default:
3564 BUG();
3537 } 3565 }
3538} 3566}
3539 3567
@@ -3553,24 +3581,20 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3553 struct nfsd4_open_downgrade *od) 3581 struct nfsd4_open_downgrade *od)
3554{ 3582{
3555 __be32 status; 3583 __be32 status;
3556 struct nfs4_stateid *stp; 3584 struct nfs4_ol_stateid *stp;
3557 3585
3558 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 3586 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
3559 (int)cstate->current_fh.fh_dentry->d_name.len, 3587 (int)cstate->current_fh.fh_dentry->d_name.len,
3560 cstate->current_fh.fh_dentry->d_name.name); 3588 cstate->current_fh.fh_dentry->d_name.name);
3561 3589
3562 if (!access_valid(od->od_share_access, cstate->minorversion) 3590 /* We don't yet support WANT bits: */
3563 || !deny_valid(od->od_share_deny)) 3591 od->od_share_access &= NFS4_SHARE_ACCESS_MASK;
3564 return nfserr_inval;
3565 3592
3566 nfs4_lock_state(); 3593 nfs4_lock_state();
3567 if ((status = nfs4_preprocess_seqid_op(cstate, 3594 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
3568 od->od_seqid, 3595 &od->od_stateid, &stp);
3569 &od->od_stateid, 3596 if (status)
3570 OPEN_STATE,
3571 &od->od_stateowner, &stp, NULL)))
3572 goto out; 3597 goto out;
3573
3574 status = nfserr_inval; 3598 status = nfserr_inval;
3575 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3599 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
3576 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3600 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
@@ -3582,22 +3606,45 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3582 stp->st_deny_bmap, od->od_share_deny); 3606 stp->st_deny_bmap, od->od_share_deny);
3583 goto out; 3607 goto out;
3584 } 3608 }
3585 nfs4_file_downgrade(stp, od->od_share_access); 3609 nfs4_stateid_downgrade(stp, od->od_share_access);
3586 3610
3587 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3611 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
3588 3612
3589 update_stateid(&stp->st_stateid); 3613 update_stateid(&stp->st_stid.sc_stateid);
3590 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); 3614 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3591 status = nfs_ok; 3615 status = nfs_ok;
3592out: 3616out:
3593 if (od->od_stateowner) { 3617 if (!cstate->replay_owner)
3594 nfs4_get_stateowner(od->od_stateowner); 3618 nfs4_unlock_state();
3595 cstate->replay_owner = od->od_stateowner;
3596 }
3597 nfs4_unlock_state();
3598 return status; 3619 return status;
3599} 3620}
3600 3621
3622void nfsd4_purge_closed_stateid(struct nfs4_stateowner *so)
3623{
3624 struct nfs4_openowner *oo;
3625 struct nfs4_ol_stateid *s;
3626
3627 if (!so->so_is_open_owner)
3628 return;
3629 oo = openowner(so);
3630 s = oo->oo_last_closed_stid;
3631 if (!s)
3632 return;
3633 if (!(oo->oo_flags & NFS4_OO_PURGE_CLOSE)) {
3634 /* Release the last_closed_stid on the next seqid bump: */
3635 oo->oo_flags |= NFS4_OO_PURGE_CLOSE;
3636 return;
3637 }
3638 oo->oo_flags &= ~NFS4_OO_PURGE_CLOSE;
3639 release_last_closed_stateid(oo);
3640}
3641
3642static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
3643{
3644 unhash_open_stateid(s);
3645 s->st_stid.sc_type = NFS4_CLOSED_STID;
3646}
3647
3601/* 3648/*
3602 * nfs4_unlock_state() called after encode 3649 * nfs4_unlock_state() called after encode
3603 */ 3650 */
@@ -3606,39 +3653,37 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3606 struct nfsd4_close *close) 3653 struct nfsd4_close *close)
3607{ 3654{
3608 __be32 status; 3655 __be32 status;
3609 struct nfs4_stateid *stp; 3656 struct nfs4_openowner *oo;
3657 struct nfs4_ol_stateid *stp;
3610 3658
3611 dprintk("NFSD: nfsd4_close on file %.*s\n", 3659 dprintk("NFSD: nfsd4_close on file %.*s\n",
3612 (int)cstate->current_fh.fh_dentry->d_name.len, 3660 (int)cstate->current_fh.fh_dentry->d_name.len,
3613 cstate->current_fh.fh_dentry->d_name.name); 3661 cstate->current_fh.fh_dentry->d_name.name);
3614 3662
3615 nfs4_lock_state(); 3663 nfs4_lock_state();
3616 /* check close_lru for replay */ 3664 status = nfs4_preprocess_seqid_op(cstate, close->cl_seqid,
3617 if ((status = nfs4_preprocess_seqid_op(cstate, 3665 &close->cl_stateid,
3618 close->cl_seqid, 3666 NFS4_OPEN_STID|NFS4_CLOSED_STID,
3619 &close->cl_stateid, 3667 &stp);
3620 OPEN_STATE | CLOSE_STATE, 3668 if (status)
3621 &close->cl_stateowner, &stp, NULL)))
3622 goto out; 3669 goto out;
3670 oo = openowner(stp->st_stateowner);
3623 status = nfs_ok; 3671 status = nfs_ok;
3624 update_stateid(&stp->st_stateid); 3672 update_stateid(&stp->st_stid.sc_stateid);
3625 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); 3673 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
3626 3674
3627 /* release_stateid() calls nfsd_close() if needed */ 3675 nfsd4_close_open_stateid(stp);
3628 release_open_stateid(stp); 3676 oo->oo_last_closed_stid = stp;
3629 3677
3630 /* place unused nfs4_stateowners on so_close_lru list to be 3678 /* place unused nfs4_stateowners on so_close_lru list to be
3631 * released by the laundromat service after the lease period 3679 * released by the laundromat service after the lease period
3632 * to enable us to handle CLOSE replay 3680 * to enable us to handle CLOSE replay
3633 */ 3681 */
3634 if (list_empty(&close->cl_stateowner->so_stateids)) 3682 if (list_empty(&oo->oo_owner.so_stateids))
3635 move_to_close_lru(close->cl_stateowner); 3683 move_to_close_lru(oo);
3636out: 3684out:
3637 if (close->cl_stateowner) { 3685 if (!cstate->replay_owner)
3638 nfs4_get_stateowner(close->cl_stateowner); 3686 nfs4_unlock_state();
3639 cstate->replay_owner = close->cl_stateowner;
3640 }
3641 nfs4_unlock_state();
3642 return status; 3687 return status;
3643} 3688}
3644 3689
@@ -3648,34 +3693,22 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3648{ 3693{
3649 struct nfs4_delegation *dp; 3694 struct nfs4_delegation *dp;
3650 stateid_t *stateid = &dr->dr_stateid; 3695 stateid_t *stateid = &dr->dr_stateid;
3696 struct nfs4_stid *s;
3651 struct inode *inode; 3697 struct inode *inode;
3652 __be32 status; 3698 __be32 status;
3653 int flags = 0;
3654 3699
3655 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) 3700 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
3656 return status; 3701 return status;
3657 inode = cstate->current_fh.fh_dentry->d_inode; 3702 inode = cstate->current_fh.fh_dentry->d_inode;
3658 3703
3659 if (nfsd4_has_session(cstate))
3660 flags |= HAS_SESSION;
3661 nfs4_lock_state(); 3704 nfs4_lock_state();
3662 status = nfserr_bad_stateid; 3705 status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s);
3663 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) 3706 if (status)
3664 goto out;
3665 status = nfserr_stale_stateid;
3666 if (STALE_STATEID(stateid))
3667 goto out;
3668 status = nfserr_bad_stateid;
3669 if (!is_delegation_stateid(stateid))
3670 goto out;
3671 status = nfserr_expired;
3672 dp = find_delegation_stateid(inode, stateid);
3673 if (!dp)
3674 goto out; 3707 goto out;
3675 status = check_stateid_generation(stateid, &dp->dl_stateid, flags); 3708 dp = delegstateid(s);
3709 status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
3676 if (status) 3710 if (status)
3677 goto out; 3711 goto out;
3678 renew_client(dp->dl_client);
3679 3712
3680 unhash_delegation(dp); 3713 unhash_delegation(dp);
3681out: 3714out:
@@ -3713,9 +3746,6 @@ last_byte_offset(u64 start, u64 len)
3713 return end > start ? end - 1: NFS4_MAX_UINT64; 3746 return end > start ? end - 1: NFS4_MAX_UINT64;
3714} 3747}
3715 3748
3716#define lockownerid_hashval(id) \
3717 ((id) & LOCK_HASH_MASK)
3718
3719static inline unsigned int 3749static inline unsigned int
3720lock_ownerstr_hashval(struct inode *inode, u32 cl_id, 3750lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
3721 struct xdr_netobj *ownername) 3751 struct xdr_netobj *ownername)
@@ -3725,101 +3755,7 @@ lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
3725 & LOCK_HASH_MASK; 3755 & LOCK_HASH_MASK;
3726} 3756}
3727 3757
3728static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
3729static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; 3758static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
3730static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
3731
3732static int
3733same_stateid(stateid_t *id_one, stateid_t *id_two)
3734{
3735 if (id_one->si_stateownerid != id_two->si_stateownerid)
3736 return 0;
3737 return id_one->si_fileid == id_two->si_fileid;
3738}
3739
3740static struct nfs4_stateid *
3741find_stateid(stateid_t *stid, int flags)
3742{
3743 struct nfs4_stateid *local;
3744 u32 st_id = stid->si_stateownerid;
3745 u32 f_id = stid->si_fileid;
3746 unsigned int hashval;
3747
3748 dprintk("NFSD: find_stateid flags 0x%x\n",flags);
3749 if (flags & (LOCK_STATE | RD_STATE | WR_STATE)) {
3750 hashval = stateid_hashval(st_id, f_id);
3751 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
3752 if ((local->st_stateid.si_stateownerid == st_id) &&
3753 (local->st_stateid.si_fileid == f_id))
3754 return local;
3755 }
3756 }
3757
3758 if (flags & (OPEN_STATE | RD_STATE | WR_STATE)) {
3759 hashval = stateid_hashval(st_id, f_id);
3760 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
3761 if ((local->st_stateid.si_stateownerid == st_id) &&
3762 (local->st_stateid.si_fileid == f_id))
3763 return local;
3764 }
3765 }
3766 return NULL;
3767}
3768
3769static struct nfs4_stateid *
3770search_for_stateid(stateid_t *stid)
3771{
3772 struct nfs4_stateid *local;
3773 unsigned int hashval = stateid_hashval(stid->si_stateownerid, stid->si_fileid);
3774
3775 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
3776 if (same_stateid(&local->st_stateid, stid))
3777 return local;
3778 }
3779
3780 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
3781 if (same_stateid(&local->st_stateid, stid))
3782 return local;
3783 }
3784 return NULL;
3785}
3786
3787static struct nfs4_delegation *
3788search_for_delegation(stateid_t *stid)
3789{
3790 struct nfs4_file *fp;
3791 struct nfs4_delegation *dp;
3792 struct list_head *pos;
3793 int i;
3794
3795 for (i = 0; i < FILE_HASH_SIZE; i++) {
3796 list_for_each_entry(fp, &file_hashtbl[i], fi_hash) {
3797 list_for_each(pos, &fp->fi_delegations) {
3798 dp = list_entry(pos, struct nfs4_delegation, dl_perfile);
3799 if (same_stateid(&dp->dl_stateid, stid))
3800 return dp;
3801 }
3802 }
3803 }
3804 return NULL;
3805}
3806
3807static struct nfs4_delegation *
3808find_delegation_stateid(struct inode *ino, stateid_t *stid)
3809{
3810 struct nfs4_file *fp;
3811 struct nfs4_delegation *dl;
3812
3813 dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__,
3814 STATEID_VAL(stid));
3815
3816 fp = find_file(ino);
3817 if (!fp)
3818 return NULL;
3819 dl = find_delegation_file(fp, stid);
3820 put_nfs4_file(fp);
3821 return dl;
3822}
3823 3759
3824/* 3760/*
3825 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that 3761 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
@@ -3846,15 +3782,21 @@ static const struct lock_manager_operations nfsd_posix_mng_ops = {
3846static inline void 3782static inline void
3847nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) 3783nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3848{ 3784{
3849 struct nfs4_stateowner *sop; 3785 struct nfs4_lockowner *lo;
3850 3786
3851 if (fl->fl_lmops == &nfsd_posix_mng_ops) { 3787 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
3852 sop = (struct nfs4_stateowner *) fl->fl_owner; 3788 lo = (struct nfs4_lockowner *) fl->fl_owner;
3853 kref_get(&sop->so_ref); 3789 deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data,
3854 deny->ld_sop = sop; 3790 lo->lo_owner.so_owner.len, GFP_KERNEL);
3855 deny->ld_clientid = sop->so_client->cl_clientid; 3791 if (!deny->ld_owner.data)
3792 /* We just don't care that much */
3793 goto nevermind;
3794 deny->ld_owner.len = lo->lo_owner.so_owner.len;
3795 deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
3856 } else { 3796 } else {
3857 deny->ld_sop = NULL; 3797nevermind:
3798 deny->ld_owner.len = 0;
3799 deny->ld_owner.data = NULL;
3858 deny->ld_clientid.cl_boot = 0; 3800 deny->ld_clientid.cl_boot = 0;
3859 deny->ld_clientid.cl_id = 0; 3801 deny->ld_clientid.cl_id = 0;
3860 } 3802 }
@@ -3867,8 +3809,8 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3867 deny->ld_type = NFS4_WRITE_LT; 3809 deny->ld_type = NFS4_WRITE_LT;
3868} 3810}
3869 3811
3870static struct nfs4_stateowner * 3812static struct nfs4_lockowner *
3871find_lockstateowner_str(struct inode *inode, clientid_t *clid, 3813find_lockowner_str(struct inode *inode, clientid_t *clid,
3872 struct xdr_netobj *owner) 3814 struct xdr_netobj *owner)
3873{ 3815{
3874 unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); 3816 unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner);
@@ -3876,11 +3818,17 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
3876 3818
3877 list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { 3819 list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
3878 if (same_owner_str(op, owner, clid)) 3820 if (same_owner_str(op, owner, clid))
3879 return op; 3821 return lockowner(op);
3880 } 3822 }
3881 return NULL; 3823 return NULL;
3882} 3824}
3883 3825
3826static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp)
3827{
3828 list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]);
3829 list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
3830}
3831
3884/* 3832/*
3885 * Alloc a lock owner structure. 3833 * Alloc a lock owner structure.
3886 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 3834 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
@@ -3889,67 +3837,40 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
3889 * strhashval = lock_ownerstr_hashval 3837 * strhashval = lock_ownerstr_hashval
3890 */ 3838 */
3891 3839
3892static struct nfs4_stateowner * 3840static struct nfs4_lockowner *
3893alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) { 3841alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp, struct nfsd4_lock *lock) {
3894 struct nfs4_stateowner *sop; 3842 struct nfs4_lockowner *lo;
3895 struct nfs4_replay *rp;
3896 unsigned int idhashval;
3897 3843
3898 if (!(sop = alloc_stateowner(&lock->lk_new_owner))) 3844 lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
3845 if (!lo)
3899 return NULL; 3846 return NULL;
3900 idhashval = lockownerid_hashval(current_ownerid); 3847 INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
3901 INIT_LIST_HEAD(&sop->so_idhash); 3848 lo->lo_owner.so_is_open_owner = 0;
3902 INIT_LIST_HEAD(&sop->so_strhash);
3903 INIT_LIST_HEAD(&sop->so_perclient);
3904 INIT_LIST_HEAD(&sop->so_stateids);
3905 INIT_LIST_HEAD(&sop->so_perstateid);
3906 INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
3907 sop->so_time = 0;
3908 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
3909 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
3910 list_add(&sop->so_perstateid, &open_stp->st_lockowners);
3911 sop->so_is_open_owner = 0;
3912 sop->so_id = current_ownerid++;
3913 sop->so_client = clp;
3914 /* It is the openowner seqid that will be incremented in encode in the 3849 /* It is the openowner seqid that will be incremented in encode in the
3915 * case of new lockowners; so increment the lock seqid manually: */ 3850 * case of new lockowners; so increment the lock seqid manually: */
3916 sop->so_seqid = lock->lk_new_lock_seqid + 1; 3851 lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1;
3917 sop->so_confirmed = 1; 3852 hash_lockowner(lo, strhashval, clp, open_stp);
3918 rp = &sop->so_replay; 3853 return lo;
3919 rp->rp_status = nfserr_serverfault;
3920 rp->rp_buflen = 0;
3921 rp->rp_buf = rp->rp_ibuf;
3922 return sop;
3923} 3854}
3924 3855
3925static struct nfs4_stateid * 3856static struct nfs4_ol_stateid *
3926alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp) 3857alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_ol_stateid *open_stp)
3927{ 3858{
3928 struct nfs4_stateid *stp; 3859 struct nfs4_ol_stateid *stp;
3929 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 3860 struct nfs4_client *clp = lo->lo_owner.so_client;
3930 3861
3931 stp = nfs4_alloc_stateid(); 3862 stp = nfs4_alloc_stateid(clp);
3932 if (stp == NULL) 3863 if (stp == NULL)
3933 goto out; 3864 return NULL;
3934 INIT_LIST_HEAD(&stp->st_hash); 3865 init_stid(&stp->st_stid, clp, NFS4_LOCK_STID);
3935 INIT_LIST_HEAD(&stp->st_perfile);
3936 INIT_LIST_HEAD(&stp->st_perstateowner);
3937 INIT_LIST_HEAD(&stp->st_lockowners); /* not used */
3938 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
3939 list_add(&stp->st_perfile, &fp->fi_stateids); 3866 list_add(&stp->st_perfile, &fp->fi_stateids);
3940 list_add(&stp->st_perstateowner, &sop->so_stateids); 3867 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
3941 stp->st_stateowner = sop; 3868 stp->st_stateowner = &lo->lo_owner;
3942 get_nfs4_file(fp); 3869 get_nfs4_file(fp);
3943 stp->st_file = fp; 3870 stp->st_file = fp;
3944 stp->st_stateid.si_boot = boot_time;
3945 stp->st_stateid.si_stateownerid = sop->so_id;
3946 stp->st_stateid.si_fileid = fp->fi_id;
3947 stp->st_stateid.si_generation = 0;
3948 stp->st_access_bmap = 0; 3871 stp->st_access_bmap = 0;
3949 stp->st_deny_bmap = open_stp->st_deny_bmap; 3872 stp->st_deny_bmap = open_stp->st_deny_bmap;
3950 stp->st_openstp = open_stp; 3873 stp->st_openstp = open_stp;
3951
3952out:
3953 return stp; 3874 return stp;
3954} 3875}
3955 3876
@@ -3960,7 +3881,7 @@ check_lock_length(u64 offset, u64 length)
3960 LOFF_OVERFLOW(offset, length))); 3881 LOFF_OVERFLOW(offset, length)));
3961} 3882}
3962 3883
3963static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access) 3884static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
3964{ 3885{
3965 struct nfs4_file *fp = lock_stp->st_file; 3886 struct nfs4_file *fp = lock_stp->st_file;
3966 int oflag = nfs4_access_to_omode(access); 3887 int oflag = nfs4_access_to_omode(access);
@@ -3978,15 +3899,16 @@ __be32
3978nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3899nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3979 struct nfsd4_lock *lock) 3900 struct nfsd4_lock *lock)
3980{ 3901{
3981 struct nfs4_stateowner *open_sop = NULL; 3902 struct nfs4_openowner *open_sop = NULL;
3982 struct nfs4_stateowner *lock_sop = NULL; 3903 struct nfs4_lockowner *lock_sop = NULL;
3983 struct nfs4_stateid *lock_stp; 3904 struct nfs4_ol_stateid *lock_stp;
3984 struct nfs4_file *fp; 3905 struct nfs4_file *fp;
3985 struct file *filp = NULL; 3906 struct file *filp = NULL;
3986 struct file_lock file_lock; 3907 struct file_lock file_lock;
3987 struct file_lock conflock; 3908 struct file_lock conflock;
3988 __be32 status = 0; 3909 __be32 status = 0;
3989 unsigned int strhashval; 3910 unsigned int strhashval;
3911 int lkflg;
3990 int err; 3912 int err;
3991 3913
3992 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n", 3914 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
@@ -4010,7 +3932,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4010 * Use open owner and open stateid to create lock owner and 3932 * Use open owner and open stateid to create lock owner and
4011 * lock stateid. 3933 * lock stateid.
4012 */ 3934 */
4013 struct nfs4_stateid *open_stp = NULL; 3935 struct nfs4_ol_stateid *open_stp = NULL;
4014 3936
4015 status = nfserr_stale_clientid; 3937 status = nfserr_stale_clientid;
4016 if (!nfsd4_has_session(cstate) && 3938 if (!nfsd4_has_session(cstate) &&
@@ -4018,26 +3940,29 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4018 goto out; 3940 goto out;
4019 3941
4020 /* validate and update open stateid and open seqid */ 3942 /* validate and update open stateid and open seqid */
4021 status = nfs4_preprocess_seqid_op(cstate, 3943 status = nfs4_preprocess_confirmed_seqid_op(cstate,
4022 lock->lk_new_open_seqid, 3944 lock->lk_new_open_seqid,
4023 &lock->lk_new_open_stateid, 3945 &lock->lk_new_open_stateid,
4024 OPEN_STATE, 3946 &open_stp);
4025 &lock->lk_replay_owner, &open_stp,
4026 lock);
4027 if (status) 3947 if (status)
4028 goto out; 3948 goto out;
4029 open_sop = lock->lk_replay_owner; 3949 open_sop = openowner(open_stp->st_stateowner);
3950 status = nfserr_bad_stateid;
3951 if (!nfsd4_has_session(cstate) &&
3952 !same_clid(&open_sop->oo_owner.so_client->cl_clientid,
3953 &lock->v.new.clientid))
3954 goto out;
4030 /* create lockowner and lock stateid */ 3955 /* create lockowner and lock stateid */
4031 fp = open_stp->st_file; 3956 fp = open_stp->st_file;
4032 strhashval = lock_ownerstr_hashval(fp->fi_inode, 3957 strhashval = lock_ownerstr_hashval(fp->fi_inode,
4033 open_sop->so_client->cl_clientid.cl_id, 3958 open_sop->oo_owner.so_client->cl_clientid.cl_id,
4034 &lock->v.new.owner); 3959 &lock->v.new.owner);
4035 /* XXX: Do we need to check for duplicate stateowners on 3960 /* XXX: Do we need to check for duplicate stateowners on
4036 * the same file, or should they just be allowed (and 3961 * the same file, or should they just be allowed (and
4037 * create new stateids)? */ 3962 * create new stateids)? */
4038 status = nfserr_resource; 3963 status = nfserr_jukebox;
4039 lock_sop = alloc_init_lock_stateowner(strhashval, 3964 lock_sop = alloc_init_lock_stateowner(strhashval,
4040 open_sop->so_client, open_stp, lock); 3965 open_sop->oo_owner.so_client, open_stp, lock);
4041 if (lock_sop == NULL) 3966 if (lock_sop == NULL)
4042 goto out; 3967 goto out;
4043 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); 3968 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
@@ -4046,16 +3971,20 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4046 } else { 3971 } else {
4047 /* lock (lock owner + lock stateid) already exists */ 3972 /* lock (lock owner + lock stateid) already exists */
4048 status = nfs4_preprocess_seqid_op(cstate, 3973 status = nfs4_preprocess_seqid_op(cstate,
4049 lock->lk_old_lock_seqid, 3974 lock->lk_old_lock_seqid,
4050 &lock->lk_old_lock_stateid, 3975 &lock->lk_old_lock_stateid,
4051 LOCK_STATE, 3976 NFS4_LOCK_STID, &lock_stp);
4052 &lock->lk_replay_owner, &lock_stp, lock);
4053 if (status) 3977 if (status)
4054 goto out; 3978 goto out;
4055 lock_sop = lock->lk_replay_owner; 3979 lock_sop = lockowner(lock_stp->st_stateowner);
4056 fp = lock_stp->st_file; 3980 fp = lock_stp->st_file;
4057 } 3981 }
4058 /* lock->lk_replay_owner and lock_stp have been created or found */ 3982 /* lock_sop and lock_stp have been created or found */
3983
3984 lkflg = setlkflg(lock->lk_type);
3985 status = nfs4_check_openmode(lock_stp, lkflg);
3986 if (status)
3987 goto out;
4059 3988
4060 status = nfserr_grace; 3989 status = nfserr_grace;
4061 if (locks_in_grace() && !lock->lk_reclaim) 3990 if (locks_in_grace() && !lock->lk_reclaim)
@@ -4106,8 +4035,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4106 err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock); 4035 err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
4107 switch (-err) { 4036 switch (-err) {
4108 case 0: /* success! */ 4037 case 0: /* success! */
4109 update_stateid(&lock_stp->st_stateid); 4038 update_stateid(&lock_stp->st_stid.sc_stateid);
4110 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 4039 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid,
4111 sizeof(stateid_t)); 4040 sizeof(stateid_t));
4112 status = 0; 4041 status = 0;
4113 break; 4042 break;
@@ -4119,19 +4048,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4119 case (EDEADLK): 4048 case (EDEADLK):
4120 status = nfserr_deadlock; 4049 status = nfserr_deadlock;
4121 break; 4050 break;
4122 default: 4051 default:
4123 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err); 4052 dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
4124 status = nfserr_resource; 4053 status = nfserrno(err);
4125 break; 4054 break;
4126 } 4055 }
4127out: 4056out:
4128 if (status && lock->lk_is_new && lock_sop) 4057 if (status && lock->lk_is_new && lock_sop)
4129 release_lockowner(lock_sop); 4058 release_lockowner(lock_sop);
4130 if (lock->lk_replay_owner) { 4059 if (!cstate->replay_owner)
4131 nfs4_get_stateowner(lock->lk_replay_owner); 4060 nfs4_unlock_state();
4132 cstate->replay_owner = lock->lk_replay_owner;
4133 }
4134 nfs4_unlock_state();
4135 return status; 4061 return status;
4136} 4062}
4137 4063
@@ -4163,6 +4089,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4163{ 4089{
4164 struct inode *inode; 4090 struct inode *inode;
4165 struct file_lock file_lock; 4091 struct file_lock file_lock;
4092 struct nfs4_lockowner *lo;
4166 int error; 4093 int error;
4167 __be32 status; 4094 __be32 status;
4168 4095
@@ -4172,19 +4099,14 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4172 if (check_lock_length(lockt->lt_offset, lockt->lt_length)) 4099 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
4173 return nfserr_inval; 4100 return nfserr_inval;
4174 4101
4175 lockt->lt_stateowner = NULL;
4176 nfs4_lock_state(); 4102 nfs4_lock_state();
4177 4103
4178 status = nfserr_stale_clientid; 4104 status = nfserr_stale_clientid;
4179 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid)) 4105 if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid))
4180 goto out; 4106 goto out;
4181 4107
4182 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) { 4108 if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
4183 dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
4184 if (status == nfserr_symlink)
4185 status = nfserr_inval;
4186 goto out; 4109 goto out;
4187 }
4188 4110
4189 inode = cstate->current_fh.fh_dentry->d_inode; 4111 inode = cstate->current_fh.fh_dentry->d_inode;
4190 locks_init_lock(&file_lock); 4112 locks_init_lock(&file_lock);
@@ -4203,10 +4125,9 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4203 goto out; 4125 goto out;
4204 } 4126 }
4205 4127
4206 lockt->lt_stateowner = find_lockstateowner_str(inode, 4128 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner);
4207 &lockt->lt_clientid, &lockt->lt_owner); 4129 if (lo)
4208 if (lockt->lt_stateowner) 4130 file_lock.fl_owner = (fl_owner_t)lo;
4209 file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner;
4210 file_lock.fl_pid = current->tgid; 4131 file_lock.fl_pid = current->tgid;
4211 file_lock.fl_flags = FL_POSIX; 4132 file_lock.fl_flags = FL_POSIX;
4212 4133
@@ -4234,7 +4155,7 @@ __be32
4234nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4155nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4235 struct nfsd4_locku *locku) 4156 struct nfsd4_locku *locku)
4236{ 4157{
4237 struct nfs4_stateid *stp; 4158 struct nfs4_ol_stateid *stp;
4238 struct file *filp = NULL; 4159 struct file *filp = NULL;
4239 struct file_lock file_lock; 4160 struct file_lock file_lock;
4240 __be32 status; 4161 __be32 status;
@@ -4249,13 +4170,10 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4249 4170
4250 nfs4_lock_state(); 4171 nfs4_lock_state();
4251 4172
4252 if ((status = nfs4_preprocess_seqid_op(cstate, 4173 status = nfs4_preprocess_seqid_op(cstate, locku->lu_seqid,
4253 locku->lu_seqid, 4174 &locku->lu_stateid, NFS4_LOCK_STID, &stp);
4254 &locku->lu_stateid, 4175 if (status)
4255 LOCK_STATE,
4256 &locku->lu_stateowner, &stp, NULL)))
4257 goto out; 4176 goto out;
4258
4259 filp = find_any_file(stp->st_file); 4177 filp = find_any_file(stp->st_file);
4260 if (!filp) { 4178 if (!filp) {
4261 status = nfserr_lock_range; 4179 status = nfserr_lock_range;
@@ -4264,7 +4182,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4264 BUG_ON(!filp); 4182 BUG_ON(!filp);
4265 locks_init_lock(&file_lock); 4183 locks_init_lock(&file_lock);
4266 file_lock.fl_type = F_UNLCK; 4184 file_lock.fl_type = F_UNLCK;
4267 file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner; 4185 file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4268 file_lock.fl_pid = current->tgid; 4186 file_lock.fl_pid = current->tgid;
4269 file_lock.fl_file = filp; 4187 file_lock.fl_file = filp;
4270 file_lock.fl_flags = FL_POSIX; 4188 file_lock.fl_flags = FL_POSIX;
@@ -4285,15 +4203,12 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4285 /* 4203 /*
4286 * OK, unlock succeeded; the only thing left to do is update the stateid. 4204 * OK, unlock succeeded; the only thing left to do is update the stateid.
4287 */ 4205 */
4288 update_stateid(&stp->st_stateid); 4206 update_stateid(&stp->st_stid.sc_stateid);
4289 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t)); 4207 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4290 4208
4291out: 4209out:
4292 if (locku->lu_stateowner) { 4210 if (!cstate->replay_owner)
4293 nfs4_get_stateowner(locku->lu_stateowner); 4211 nfs4_unlock_state();
4294 cstate->replay_owner = locku->lu_stateowner;
4295 }
4296 nfs4_unlock_state();
4297 return status; 4212 return status;
4298 4213
4299out_nfserr: 4214out_nfserr:
@@ -4307,7 +4222,7 @@ out_nfserr:
4307 * 0: no locks held by lockowner 4222 * 0: no locks held by lockowner
4308 */ 4223 */
4309static int 4224static int
4310check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner) 4225check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4311{ 4226{
4312 struct file_lock **flpp; 4227 struct file_lock **flpp;
4313 struct inode *inode = filp->fi_inode; 4228 struct inode *inode = filp->fi_inode;
@@ -4332,7 +4247,8 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4332{ 4247{
4333 clientid_t *clid = &rlockowner->rl_clientid; 4248 clientid_t *clid = &rlockowner->rl_clientid;
4334 struct nfs4_stateowner *sop; 4249 struct nfs4_stateowner *sop;
4335 struct nfs4_stateid *stp; 4250 struct nfs4_lockowner *lo;
4251 struct nfs4_ol_stateid *stp;
4336 struct xdr_netobj *owner = &rlockowner->rl_owner; 4252 struct xdr_netobj *owner = &rlockowner->rl_owner;
4337 struct list_head matches; 4253 struct list_head matches;
4338 int i; 4254 int i;
@@ -4356,16 +4272,15 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4356 * data structures. */ 4272 * data structures. */
4357 INIT_LIST_HEAD(&matches); 4273 INIT_LIST_HEAD(&matches);
4358 for (i = 0; i < LOCK_HASH_SIZE; i++) { 4274 for (i = 0; i < LOCK_HASH_SIZE; i++) {
4359 list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) { 4275 list_for_each_entry(sop, &lock_ownerstr_hashtbl[i], so_strhash) {
4360 if (!same_owner_str(sop, owner, clid)) 4276 if (!same_owner_str(sop, owner, clid))
4361 continue; 4277 continue;
4362 list_for_each_entry(stp, &sop->so_stateids, 4278 list_for_each_entry(stp, &sop->so_stateids,
4363 st_perstateowner) { 4279 st_perstateowner) {
4364 if (check_for_locks(stp->st_file, sop)) 4280 lo = lockowner(sop);
4281 if (check_for_locks(stp->st_file, lo))
4365 goto out; 4282 goto out;
4366 /* Note: so_perclient unused for lockowners, 4283 list_add(&lo->lo_list, &matches);
4367 * so it's OK to fool with here. */
4368 list_add(&sop->so_perclient, &matches);
4369 } 4284 }
4370 } 4285 }
4371 } 4286 }
@@ -4374,12 +4289,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4374 * have been checked. */ 4289 * have been checked. */
4375 status = nfs_ok; 4290 status = nfs_ok;
4376 while (!list_empty(&matches)) { 4291 while (!list_empty(&matches)) {
4377 sop = list_entry(matches.next, struct nfs4_stateowner, 4292 lo = list_entry(matches.next, struct nfs4_lockowner,
4378 so_perclient); 4293 lo_list);
4379 /* unhash_stateowner deletes so_perclient only 4294 /* unhash_stateowner deletes so_perclient only
4380 * for openowners. */ 4295 * for openowners. */
4381 list_del(&sop->so_perclient); 4296 list_del(&lo->lo_list);
4382 release_lockowner(sop); 4297 release_lockowner(lo);
4383 } 4298 }
4384out: 4299out:
4385 nfs4_unlock_state(); 4300 nfs4_unlock_state();
@@ -4501,16 +4416,10 @@ nfs4_state_init(void)
4501 for (i = 0; i < FILE_HASH_SIZE; i++) { 4416 for (i = 0; i < FILE_HASH_SIZE; i++) {
4502 INIT_LIST_HEAD(&file_hashtbl[i]); 4417 INIT_LIST_HEAD(&file_hashtbl[i]);
4503 } 4418 }
4504 for (i = 0; i < OWNER_HASH_SIZE; i++) { 4419 for (i = 0; i < OPEN_OWNER_HASH_SIZE; i++) {
4505 INIT_LIST_HEAD(&ownerstr_hashtbl[i]); 4420 INIT_LIST_HEAD(&open_ownerstr_hashtbl[i]);
4506 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
4507 }
4508 for (i = 0; i < STATEID_HASH_SIZE; i++) {
4509 INIT_LIST_HEAD(&stateid_hashtbl[i]);
4510 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
4511 } 4421 }
4512 for (i = 0; i < LOCK_HASH_SIZE; i++) { 4422 for (i = 0; i < LOCK_HASH_SIZE; i++) {
4513 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
4514 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]); 4423 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
4515 } 4424 }
4516 memset(&onestateid, ~0, sizeof(stateid_t)); 4425 memset(&onestateid, ~0, sizeof(stateid_t));
@@ -4527,7 +4436,7 @@ nfsd4_load_reboot_recovery_data(void)
4527 int status; 4436 int status;
4528 4437
4529 nfs4_lock_state(); 4438 nfs4_lock_state();
4530 nfsd4_init_recdir(user_recovery_dirname); 4439 nfsd4_init_recdir();
4531 status = nfsd4_recdir_load(); 4440 status = nfsd4_recdir_load();
4532 nfs4_unlock_state(); 4441 nfs4_unlock_state();
4533 if (status) 4442 if (status)
@@ -4636,40 +4545,3 @@ nfs4_state_shutdown(void)
4636 nfs4_unlock_state(); 4545 nfs4_unlock_state();
4637 nfsd4_destroy_callback_queue(); 4546 nfsd4_destroy_callback_queue();
4638} 4547}
4639
4640/*
4641 * user_recovery_dirname is protected by the nfsd_mutex since it's only
4642 * accessed when nfsd is starting.
4643 */
4644static void
4645nfs4_set_recdir(char *recdir)
4646{
4647 strcpy(user_recovery_dirname, recdir);
4648}
4649
4650/*
4651 * Change the NFSv4 recovery directory to recdir.
4652 */
4653int
4654nfs4_reset_recoverydir(char *recdir)
4655{
4656 int status;
4657 struct path path;
4658
4659 status = kern_path(recdir, LOOKUP_FOLLOW, &path);
4660 if (status)
4661 return status;
4662 status = -ENOTDIR;
4663 if (S_ISDIR(path.dentry->d_inode->i_mode)) {
4664 nfs4_set_recdir(recdir);
4665 status = 0;
4666 }
4667 path_put(&path);
4668 return status;
4669}
4670
4671char *
4672nfs4_recoverydir(void)
4673{
4674 return user_recovery_dirname;
4675}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c8bf405d19de..66d095d7955e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -456,7 +456,6 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
456{ 456{
457 DECODE_HEAD; 457 DECODE_HEAD;
458 458
459 close->cl_stateowner = NULL;
460 READ_BUF(4); 459 READ_BUF(4);
461 READ32(close->cl_seqid); 460 READ32(close->cl_seqid);
462 return nfsd4_decode_stateid(argp, &close->cl_stateid); 461 return nfsd4_decode_stateid(argp, &close->cl_stateid);
@@ -551,7 +550,6 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
551{ 550{
552 DECODE_HEAD; 551 DECODE_HEAD;
553 552
554 lock->lk_replay_owner = NULL;
555 /* 553 /*
556 * type, reclaim(boolean), offset, length, new_lock_owner(boolean) 554 * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
557 */ 555 */
@@ -611,7 +609,6 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
611{ 609{
612 DECODE_HEAD; 610 DECODE_HEAD;
613 611
614 locku->lu_stateowner = NULL;
615 READ_BUF(8); 612 READ_BUF(8);
616 READ32(locku->lu_type); 613 READ32(locku->lu_type);
617 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) 614 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
@@ -642,6 +639,83 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
642 DECODE_TAIL; 639 DECODE_TAIL;
643} 640}
644 641
642static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
643{
644 __be32 *p;
645 u32 w;
646
647 READ_BUF(4);
648 READ32(w);
649 *x = w;
650 switch (w & NFS4_SHARE_ACCESS_MASK) {
651 case NFS4_SHARE_ACCESS_READ:
652 case NFS4_SHARE_ACCESS_WRITE:
653 case NFS4_SHARE_ACCESS_BOTH:
654 break;
655 default:
656 return nfserr_bad_xdr;
657 }
658 w &= !NFS4_SHARE_ACCESS_MASK;
659 if (!w)
660 return nfs_ok;
661 if (!argp->minorversion)
662 return nfserr_bad_xdr;
663 switch (w & NFS4_SHARE_WANT_MASK) {
664 case NFS4_SHARE_WANT_NO_PREFERENCE:
665 case NFS4_SHARE_WANT_READ_DELEG:
666 case NFS4_SHARE_WANT_WRITE_DELEG:
667 case NFS4_SHARE_WANT_ANY_DELEG:
668 case NFS4_SHARE_WANT_NO_DELEG:
669 case NFS4_SHARE_WANT_CANCEL:
670 break;
671 default:
672 return nfserr_bad_xdr;
673 }
674 w &= ~NFS4_SHARE_WANT_MASK;
675 if (!w)
676 return nfs_ok;
677 switch (w) {
678 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
679 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
680 case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
681 NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
682 return nfs_ok;
683 }
684xdr_error:
685 return nfserr_bad_xdr;
686}
687
688static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
689{
690 __be32 *p;
691
692 READ_BUF(4);
693 READ32(*x);
694 /* Note: unlinke access bits, deny bits may be zero. */
695 if (*x & ~NFS4_SHARE_DENY_BOTH)
696 return nfserr_bad_xdr;
697 return nfs_ok;
698xdr_error:
699 return nfserr_bad_xdr;
700}
701
702static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
703{
704 __be32 *p;
705
706 READ_BUF(4);
707 READ32(o->len);
708
709 if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
710 return nfserr_bad_xdr;
711
712 READ_BUF(o->len);
713 SAVEMEM(o->data, o->len);
714 return nfs_ok;
715xdr_error:
716 return nfserr_bad_xdr;
717}
718
645static __be32 719static __be32
646nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 720nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
647{ 721{
@@ -649,19 +723,23 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
649 723
650 memset(open->op_bmval, 0, sizeof(open->op_bmval)); 724 memset(open->op_bmval, 0, sizeof(open->op_bmval));
651 open->op_iattr.ia_valid = 0; 725 open->op_iattr.ia_valid = 0;
652 open->op_stateowner = NULL; 726 open->op_openowner = NULL;
653 727
654 /* seqid, share_access, share_deny, clientid, ownerlen */ 728 /* seqid, share_access, share_deny, clientid, ownerlen */
655 READ_BUF(16 + sizeof(clientid_t)); 729 READ_BUF(4);
656 READ32(open->op_seqid); 730 READ32(open->op_seqid);
657 READ32(open->op_share_access); 731 status = nfsd4_decode_share_access(argp, &open->op_share_access);
658 READ32(open->op_share_deny); 732 if (status)
733 goto xdr_error;
734 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
735 if (status)
736 goto xdr_error;
737 READ_BUF(sizeof(clientid_t));
659 COPYMEM(&open->op_clientid, sizeof(clientid_t)); 738 COPYMEM(&open->op_clientid, sizeof(clientid_t));
660 READ32(open->op_owner.len); 739 status = nfsd4_decode_opaque(argp, &open->op_owner);
661 740 if (status)
662 /* owner, open_flag */ 741 goto xdr_error;
663 READ_BUF(open->op_owner.len + 4); 742 READ_BUF(4);
664 SAVEMEM(open->op_owner.data, open->op_owner.len);
665 READ32(open->op_create); 743 READ32(open->op_create);
666 switch (open->op_create) { 744 switch (open->op_create) {
667 case NFS4_OPEN_NOCREATE: 745 case NFS4_OPEN_NOCREATE:
@@ -727,6 +805,19 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
727 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 805 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
728 return status; 806 return status;
729 break; 807 break;
808 case NFS4_OPEN_CLAIM_FH:
809 case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
810 if (argp->minorversion < 1)
811 goto xdr_error;
812 /* void */
813 break;
814 case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
815 if (argp->minorversion < 1)
816 goto xdr_error;
817 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
818 if (status)
819 return status;
820 break;
730 default: 821 default:
731 goto xdr_error; 822 goto xdr_error;
732 } 823 }
@@ -739,7 +830,6 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
739{ 830{
740 DECODE_HEAD; 831 DECODE_HEAD;
741 832
742 open_conf->oc_stateowner = NULL;
743 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); 833 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
744 if (status) 834 if (status)
745 return status; 835 return status;
@@ -754,15 +844,17 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
754{ 844{
755 DECODE_HEAD; 845 DECODE_HEAD;
756 846
757 open_down->od_stateowner = NULL;
758 status = nfsd4_decode_stateid(argp, &open_down->od_stateid); 847 status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
759 if (status) 848 if (status)
760 return status; 849 return status;
761 READ_BUF(12); 850 READ_BUF(4);
762 READ32(open_down->od_seqid); 851 READ32(open_down->od_seqid);
763 READ32(open_down->od_share_access); 852 status = nfsd4_decode_share_access(argp, &open_down->od_share_access);
764 READ32(open_down->od_share_deny); 853 if (status)
765 854 return status;
855 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
856 if (status)
857 return status;
766 DECODE_TAIL; 858 DECODE_TAIL;
767} 859}
768 860
@@ -903,12 +995,13 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
903{ 995{
904 DECODE_HEAD; 996 DECODE_HEAD;
905 997
906 READ_BUF(12); 998 READ_BUF(8);
907 COPYMEM(setclientid->se_verf.data, 8); 999 COPYMEM(setclientid->se_verf.data, 8);
908 READ32(setclientid->se_namelen);
909 1000
910 READ_BUF(setclientid->se_namelen + 8); 1001 status = nfsd4_decode_opaque(argp, &setclientid->se_name);
911 SAVEMEM(setclientid->se_name, setclientid->se_namelen); 1002 if (status)
1003 return nfserr_bad_xdr;
1004 READ_BUF(8);
912 READ32(setclientid->se_callback_prog); 1005 READ32(setclientid->se_callback_prog);
913 READ32(setclientid->se_callback_netid_len); 1006 READ32(setclientid->se_callback_netid_len);
914 1007
@@ -1051,11 +1144,9 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1051 READ_BUF(NFS4_VERIFIER_SIZE); 1144 READ_BUF(NFS4_VERIFIER_SIZE);
1052 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE); 1145 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1053 1146
1054 READ_BUF(4); 1147 status = nfsd4_decode_opaque(argp, &exid->clname);
1055 READ32(exid->clname.len); 1148 if (status)
1056 1149 return nfserr_bad_xdr;
1057 READ_BUF(exid->clname.len);
1058 SAVEMEM(exid->clname.data, exid->clname.len);
1059 1150
1060 READ_BUF(4); 1151 READ_BUF(4);
1061 READ32(exid->flags); 1152 READ32(exid->flags);
@@ -1326,6 +1417,16 @@ xdr_error:
1326 goto out; 1417 goto out;
1327} 1418}
1328 1419
1420static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
1421{
1422 DECODE_HEAD;
1423
1424 READ_BUF(8);
1425 COPYMEM(&dc->clientid, 8);
1426
1427 DECODE_TAIL;
1428}
1429
1329static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) 1430static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
1330{ 1431{
1331 DECODE_HEAD; 1432 DECODE_HEAD;
@@ -1447,7 +1548,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1447 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, 1548 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
1448 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, 1549 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid,
1449 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, 1550 [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
1450 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, 1551 [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid,
1451 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, 1552 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
1452}; 1553};
1453 1554
@@ -1630,15 +1731,20 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1630 * we know whether the error to be returned is a sequence id mutating error. 1731 * we know whether the error to be returned is a sequence id mutating error.
1631 */ 1732 */
1632 1733
1633#define ENCODE_SEQID_OP_TAIL(stateowner) do { \ 1734static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, __be32 nfserr)
1634 if (seqid_mutating_err(nfserr) && stateowner) { \ 1735{
1635 stateowner->so_seqid++; \ 1736 struct nfs4_stateowner *stateowner = resp->cstate.replay_owner;
1636 stateowner->so_replay.rp_status = nfserr; \ 1737
1637 stateowner->so_replay.rp_buflen = \ 1738 if (seqid_mutating_err(ntohl(nfserr)) && stateowner) {
1638 (((char *)(resp)->p - (char *)save)); \ 1739 stateowner->so_seqid++;
1639 memcpy(stateowner->so_replay.rp_buf, save, \ 1740 stateowner->so_replay.rp_status = nfserr;
1640 stateowner->so_replay.rp_buflen); \ 1741 stateowner->so_replay.rp_buflen =
1641 } } while (0); 1742 (char *)resp->p - (char *)save;
1743 memcpy(stateowner->so_replay.rp_buf, save,
1744 stateowner->so_replay.rp_buflen);
1745 nfsd4_purge_closed_stateid(stateowner);
1746 }
1747}
1642 1748
1643/* Encode as an array of strings the string given with components 1749/* Encode as an array of strings the string given with components
1644 * separated @sep. 1750 * separated @sep.
@@ -1697,36 +1803,89 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1697} 1803}
1698 1804
1699/* 1805/*
1700 * Return the path to an export point in the pseudo filesystem namespace 1806 * Encode a path in RFC3530 'pathname4' format
1701 * Returned string is safe to use as long as the caller holds a reference
1702 * to @exp.
1703 */ 1807 */
1704static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat) 1808static __be32 nfsd4_encode_path(const struct path *root,
1809 const struct path *path, __be32 **pp, int *buflen)
1705{ 1810{
1706 struct svc_fh tmp_fh; 1811 struct path cur = {
1707 char *path = NULL, *rootpath; 1812 .mnt = path->mnt,
1708 size_t rootlen; 1813 .dentry = path->dentry,
1814 };
1815 __be32 *p = *pp;
1816 struct dentry **components = NULL;
1817 unsigned int ncomponents = 0;
1818 __be32 err = nfserr_jukebox;
1709 1819
1710 fh_init(&tmp_fh, NFS4_FHSIZE); 1820 dprintk("nfsd4_encode_components(");
1711 *stat = exp_pseudoroot(rqstp, &tmp_fh);
1712 if (*stat)
1713 return NULL;
1714 rootpath = tmp_fh.fh_export->ex_pathname;
1715 1821
1716 path = exp->ex_pathname; 1822 path_get(&cur);
1823 /* First walk the path up to the nfsd root, and store the
1824 * dentries/path components in an array.
1825 */
1826 for (;;) {
1827 if (cur.dentry == root->dentry && cur.mnt == root->mnt)
1828 break;
1829 if (cur.dentry == cur.mnt->mnt_root) {
1830 if (follow_up(&cur))
1831 continue;
1832 goto out_free;
1833 }
1834 if ((ncomponents & 15) == 0) {
1835 struct dentry **new;
1836 new = krealloc(components,
1837 sizeof(*new) * (ncomponents + 16),
1838 GFP_KERNEL);
1839 if (!new)
1840 goto out_free;
1841 components = new;
1842 }
1843 components[ncomponents++] = cur.dentry;
1844 cur.dentry = dget_parent(cur.dentry);
1845 }
1717 1846
1718 rootlen = strlen(rootpath); 1847 *buflen -= 4;
1719 if (strncmp(path, rootpath, rootlen)) { 1848 if (*buflen < 0)
1720 dprintk("nfsd: fs_locations failed;" 1849 goto out_free;
1721 "%s is not contained in %s\n", path, rootpath); 1850 WRITE32(ncomponents);
1722 *stat = nfserr_notsupp; 1851
1723 path = NULL; 1852 while (ncomponents) {
1724 goto out; 1853 struct dentry *dentry = components[ncomponents - 1];
1854 unsigned int len = dentry->d_name.len;
1855
1856 *buflen -= 4 + (XDR_QUADLEN(len) << 2);
1857 if (*buflen < 0)
1858 goto out_free;
1859 WRITE32(len);
1860 WRITEMEM(dentry->d_name.name, len);
1861 dprintk("/%s", dentry->d_name.name);
1862 dput(dentry);
1863 ncomponents--;
1725 } 1864 }
1726 path += rootlen; 1865
1727out: 1866 *pp = p;
1728 fh_put(&tmp_fh); 1867 err = 0;
1729 return path; 1868out_free:
1869 dprintk(")\n");
1870 while (ncomponents)
1871 dput(components[--ncomponents]);
1872 kfree(components);
1873 path_put(&cur);
1874 return err;
1875}
1876
1877static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
1878 const struct path *path, __be32 **pp, int *buflen)
1879{
1880 struct svc_export *exp_ps;
1881 __be32 res;
1882
1883 exp_ps = rqst_find_fsidzero_export(rqstp);
1884 if (IS_ERR(exp_ps))
1885 return nfserrno(PTR_ERR(exp_ps));
1886 res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen);
1887 exp_put(exp_ps);
1888 return res;
1730} 1889}
1731 1890
1732/* 1891/*
@@ -1740,11 +1899,8 @@ static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1740 int i; 1899 int i;
1741 __be32 *p = *pp; 1900 __be32 *p = *pp;
1742 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; 1901 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1743 char *root = nfsd4_path(rqstp, exp, &status);
1744 1902
1745 if (status) 1903 status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen);
1746 return status;
1747 status = nfsd4_encode_components('/', root, &p, buflen);
1748 if (status) 1904 if (status)
1749 return status; 1905 return status;
1750 if ((*buflen -= 4) < 0) 1906 if ((*buflen -= 4) < 0)
@@ -1760,12 +1916,19 @@ static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1760 return 0; 1916 return 0;
1761} 1917}
1762 1918
1763static u32 nfs4_ftypes[16] = { 1919static u32 nfs4_file_type(umode_t mode)
1764 NF4BAD, NF4FIFO, NF4CHR, NF4BAD, 1920{
1765 NF4DIR, NF4BAD, NF4BLK, NF4BAD, 1921 switch (mode & S_IFMT) {
1766 NF4REG, NF4BAD, NF4LNK, NF4BAD, 1922 case S_IFIFO: return NF4FIFO;
1767 NF4SOCK, NF4BAD, NF4LNK, NF4BAD, 1923 case S_IFCHR: return NF4CHR;
1768}; 1924 case S_IFDIR: return NF4DIR;
1925 case S_IFBLK: return NF4BLK;
1926 case S_IFLNK: return NF4LNK;
1927 case S_IFREG: return NF4REG;
1928 case S_IFSOCK: return NF4SOCK;
1929 default: return NF4BAD;
1930 };
1931}
1769 1932
1770static __be32 1933static __be32
1771nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1934nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
@@ -1954,7 +2117,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1954 if (bmval0 & FATTR4_WORD0_TYPE) { 2117 if (bmval0 & FATTR4_WORD0_TYPE) {
1955 if ((buflen -= 4) < 0) 2118 if ((buflen -= 4) < 0)
1956 goto out_resource; 2119 goto out_resource;
1957 dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12]; 2120 dummy = nfs4_file_type(stat.mode);
1958 if (dummy == NF4BAD) 2121 if (dummy == NF4BAD)
1959 goto out_serverfault; 2122 goto out_serverfault;
1960 WRITE32(dummy); 2123 WRITE32(dummy);
@@ -2488,7 +2651,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
2488 if (!nfserr) 2651 if (!nfserr)
2489 nfsd4_encode_stateid(resp, &close->cl_stateid); 2652 nfsd4_encode_stateid(resp, &close->cl_stateid);
2490 2653
2491 ENCODE_SEQID_OP_TAIL(close->cl_stateowner); 2654 encode_seqid_op_tail(resp, save, nfserr);
2492 return nfserr; 2655 return nfserr;
2493} 2656}
2494 2657
@@ -2564,17 +2727,18 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
2564static void 2727static void
2565nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld) 2728nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2566{ 2729{
2730 struct xdr_netobj *conf = &ld->ld_owner;
2567 __be32 *p; 2731 __be32 *p;
2568 2732
2569 RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0)); 2733 RESERVE_SPACE(32 + XDR_LEN(conf->len));
2570 WRITE64(ld->ld_start); 2734 WRITE64(ld->ld_start);
2571 WRITE64(ld->ld_length); 2735 WRITE64(ld->ld_length);
2572 WRITE32(ld->ld_type); 2736 WRITE32(ld->ld_type);
2573 if (ld->ld_sop) { 2737 if (conf->len) {
2574 WRITEMEM(&ld->ld_clientid, 8); 2738 WRITEMEM(&ld->ld_clientid, 8);
2575 WRITE32(ld->ld_sop->so_owner.len); 2739 WRITE32(conf->len);
2576 WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len); 2740 WRITEMEM(conf->data, conf->len);
2577 kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner); 2741 kfree(conf->data);
2578 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */ 2742 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */
2579 WRITE64((u64)0); /* clientid */ 2743 WRITE64((u64)0); /* clientid */
2580 WRITE32(0); /* length of owner name */ 2744 WRITE32(0); /* length of owner name */
@@ -2592,7 +2756,7 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
2592 else if (nfserr == nfserr_denied) 2756 else if (nfserr == nfserr_denied)
2593 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2757 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2594 2758
2595 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner); 2759 encode_seqid_op_tail(resp, save, nfserr);
2596 return nfserr; 2760 return nfserr;
2597} 2761}
2598 2762
@@ -2612,7 +2776,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
2612 if (!nfserr) 2776 if (!nfserr)
2613 nfsd4_encode_stateid(resp, &locku->lu_stateid); 2777 nfsd4_encode_stateid(resp, &locku->lu_stateid);
2614 2778
2615 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner); 2779 encode_seqid_op_tail(resp, save, nfserr);
2616 return nfserr; 2780 return nfserr;
2617} 2781}
2618 2782
@@ -2693,7 +2857,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
2693 } 2857 }
2694 /* XXX save filehandle here */ 2858 /* XXX save filehandle here */
2695out: 2859out:
2696 ENCODE_SEQID_OP_TAIL(open->op_stateowner); 2860 encode_seqid_op_tail(resp, save, nfserr);
2697 return nfserr; 2861 return nfserr;
2698} 2862}
2699 2863
@@ -2705,7 +2869,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
2705 if (!nfserr) 2869 if (!nfserr)
2706 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid); 2870 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2707 2871
2708 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner); 2872 encode_seqid_op_tail(resp, save, nfserr);
2709 return nfserr; 2873 return nfserr;
2710} 2874}
2711 2875
@@ -2717,7 +2881,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
2717 if (!nfserr) 2881 if (!nfserr)
2718 nfsd4_encode_stateid(resp, &od->od_stateid); 2882 nfsd4_encode_stateid(resp, &od->od_stateid);
2719 2883
2720 ENCODE_SEQID_OP_TAIL(od->od_stateowner); 2884 encode_seqid_op_tail(resp, save, nfserr);
2721 return nfserr; 2885 return nfserr;
2722} 2886}
2723 2887
@@ -2759,8 +2923,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2759 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, 2923 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2760 &maxcount); 2924 &maxcount);
2761 2925
2762 if (nfserr == nfserr_symlink)
2763 nfserr = nfserr_inval;
2764 if (nfserr) 2926 if (nfserr)
2765 return nfserr; 2927 return nfserr;
2766 eof = (read->rd_offset + maxcount >= 2928 eof = (read->rd_offset + maxcount >=
@@ -2886,8 +3048,6 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
2886 readdir->common.err == nfserr_toosmall && 3048 readdir->common.err == nfserr_toosmall &&
2887 readdir->buffer == page) 3049 readdir->buffer == page)
2888 nfserr = nfserr_toosmall; 3050 nfserr = nfserr_toosmall;
2889 if (nfserr == nfserr_symlink)
2890 nfserr = nfserr_notdir;
2891 if (nfserr) 3051 if (nfserr)
2892 goto err_no_verf; 3052 goto err_no_verf;
2893 3053
@@ -3218,9 +3378,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3218 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3378 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3219 WRITE32(seq->seqid); 3379 WRITE32(seq->seqid);
3220 WRITE32(seq->slotid); 3380 WRITE32(seq->slotid);
3221 WRITE32(seq->maxslots); 3381 /* Note slotid's are numbered from zero: */
3222 /* For now: target_maxslots = maxslots */ 3382 WRITE32(seq->maxslots - 1); /* sr_highest_slotid */
3223 WRITE32(seq->maxslots); 3383 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
3224 WRITE32(seq->status_flags); 3384 WRITE32(seq->status_flags);
3225 3385
3226 ADJUST_ARGS(); 3386 ADJUST_ARGS();
@@ -3233,6 +3393,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
3233 struct nfsd4_test_stateid *test_stateid) 3393 struct nfsd4_test_stateid *test_stateid)
3234{ 3394{
3235 struct nfsd4_compoundargs *argp; 3395 struct nfsd4_compoundargs *argp;
3396 struct nfs4_client *cl = resp->cstate.session->se_client;
3236 stateid_t si; 3397 stateid_t si;
3237 __be32 *p; 3398 __be32 *p;
3238 int i; 3399 int i;
@@ -3248,7 +3409,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
3248 nfs4_lock_state(); 3409 nfs4_lock_state();
3249 for (i = 0; i < test_stateid->ts_num_ids; i++) { 3410 for (i = 0; i < test_stateid->ts_num_ids; i++) {
3250 nfsd4_decode_stateid(argp, &si); 3411 nfsd4_decode_stateid(argp, &si);
3251 valid = nfs4_validate_stateid(&si, test_stateid->ts_has_session); 3412 valid = nfs4_validate_stateid(cl, &si);
3252 RESERVE_SPACE(4); 3413 RESERVE_SPACE(4);
3253 *p++ = htonl(valid); 3414 *p++ = htonl(valid);
3254 resp->p = p; 3415 resp->p = p;
@@ -3334,34 +3495,29 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3334 3495
3335/* 3496/*
3336 * Calculate the total amount of memory that the compound response has taken 3497 * Calculate the total amount of memory that the compound response has taken
3337 * after encoding the current operation. 3498 * after encoding the current operation with pad.
3338 * 3499 *
3339 * pad: add on 8 bytes for the next operation's op_code and status so that 3500 * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop()
3340 * there is room to cache a failure on the next operation. 3501 * which was specified at nfsd4_operation, else pad is zero.
3341 * 3502 *
3342 * Compare this length to the session se_fmaxresp_cached. 3503 * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached.
3343 * 3504 *
3344 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3505 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3345 * will be at least a page and will therefore hold the xdr_buf head. 3506 * will be at least a page and will therefore hold the xdr_buf head.
3346 */ 3507 */
3347static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp) 3508int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3348{ 3509{
3349 int status = 0;
3350 struct xdr_buf *xb = &resp->rqstp->rq_res; 3510 struct xdr_buf *xb = &resp->rqstp->rq_res;
3351 struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
3352 struct nfsd4_session *session = NULL; 3511 struct nfsd4_session *session = NULL;
3353 struct nfsd4_slot *slot = resp->cstate.slot; 3512 struct nfsd4_slot *slot = resp->cstate.slot;
3354 u32 length, tlen = 0, pad = 8; 3513 u32 length, tlen = 0;
3355 3514
3356 if (!nfsd4_has_session(&resp->cstate)) 3515 if (!nfsd4_has_session(&resp->cstate))
3357 return status; 3516 return 0;
3358 3517
3359 session = resp->cstate.session; 3518 session = resp->cstate.session;
3360 if (session == NULL || slot->sl_cachethis == 0) 3519 if (session == NULL)
3361 return status; 3520 return 0;
3362
3363 if (resp->opcnt >= args->opcnt)
3364 pad = 0; /* this is the last operation */
3365 3521
3366 if (xb->page_len == 0) { 3522 if (xb->page_len == 0) {
3367 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad; 3523 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
@@ -3374,10 +3530,14 @@ static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp)
3374 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__, 3530 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3375 length, xb->page_len, tlen, pad); 3531 length, xb->page_len, tlen, pad);
3376 3532
3377 if (length <= session->se_fchannel.maxresp_cached) 3533 if (length > session->se_fchannel.maxresp_sz)
3378 return status; 3534 return nfserr_rep_too_big;
3379 else 3535
3536 if (slot->sl_cachethis == 1 &&
3537 length > session->se_fchannel.maxresp_cached)
3380 return nfserr_rep_too_big_to_cache; 3538 return nfserr_rep_too_big_to_cache;
3539
3540 return 0;
3381} 3541}
3382 3542
3383void 3543void
@@ -3397,8 +3557,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3397 !nfsd4_enc_ops[op->opnum]); 3557 !nfsd4_enc_ops[op->opnum]);
3398 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); 3558 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3399 /* nfsd4_check_drc_limit guarantees enough room for error status */ 3559 /* nfsd4_check_drc_limit guarantees enough room for error status */
3400 if (!op->status && nfsd4_check_drc_limit(resp)) 3560 if (!op->status)
3401 op->status = nfserr_rep_too_big_to_cache; 3561 op->status = nfsd4_check_resp_size(resp, 0);
3402status: 3562status:
3403 /* 3563 /*
3404 * Note: We write the status directly, instead of using WRITE32(), 3564 * Note: We write the status directly, instead of using WRITE32(),
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index c7716143cbd1..db34a585e112 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -9,7 +9,6 @@
9#include <linux/ctype.h> 9#include <linux/ctype.h>
10 10
11#include <linux/sunrpc/svcsock.h> 11#include <linux/sunrpc/svcsock.h>
12#include <linux/nfsd/syscall.h>
13#include <linux/lockd/lockd.h> 12#include <linux/lockd/lockd.h>
14#include <linux/sunrpc/clnt.h> 13#include <linux/sunrpc/clnt.h>
15#include <linux/sunrpc/gss_api.h> 14#include <linux/sunrpc/gss_api.h>
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 7ecfa2420307..58134a23fdfb 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -11,13 +11,39 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/mount.h> 12#include <linux/mount.h>
13 13
14#include <linux/nfs.h>
15#include <linux/nfs2.h>
16#include <linux/nfs3.h>
17#include <linux/nfs4.h>
18#include <linux/sunrpc/msg_prot.h>
19
14#include <linux/nfsd/debug.h> 20#include <linux/nfsd/debug.h>
15#include <linux/nfsd/export.h> 21#include <linux/nfsd/export.h>
16#include <linux/nfsd/stats.h> 22#include <linux/nfsd/stats.h>
23
17/* 24/*
18 * nfsd version 25 * nfsd version
19 */ 26 */
20#define NFSD_SUPPORTED_MINOR_VERSION 1 27#define NFSD_SUPPORTED_MINOR_VERSION 1
28/*
29 * Maximum blocksizes supported by daemon under various circumstances.
30 */
31#define NFSSVC_MAXBLKSIZE RPCSVC_MAXPAYLOAD
32/* NFSv2 is limited by the protocol specification, see RFC 1094 */
33#define NFSSVC_MAXBLKSIZE_V2 (8*1024)
34
35
36/*
37 * Largest number of bytes we need to allocate for an NFS
38 * call or reply. Used to control buffer sizes. We use
39 * the length of v3 WRITE, READDIR and READDIR replies
40 * which are an RPC header, up to 26 XDR units of reply
41 * data, and some page data.
42 *
43 * Note that accuracy here doesn't matter too much as the
44 * size is rounded up to a page size when allocating space.
45 */
46#define NFSD_BUFSIZE ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE)
21 47
22struct readdir_cd { 48struct readdir_cd {
23 __be32 err; /* 0, nfserr, or nfserr_eof */ 49 __be32 err; /* 0, nfserr, or nfserr_eof */
@@ -335,6 +361,13 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
335#define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ 361#define NFSD_SUPPATTR_EXCLCREAT_WORD2 \
336 NFSD_WRITEABLE_ATTRS_WORD2 362 NFSD_WRITEABLE_ATTRS_WORD2
337 363
364extern int nfsd4_is_junction(struct dentry *dentry);
365#else
366static inline int nfsd4_is_junction(struct dentry *dentry)
367{
368 return 0;
369}
370
338#endif /* CONFIG_NFSD_V4 */ 371#endif /* CONFIG_NFSD_V4 */
339 372
340#endif /* LINUX_NFSD_NFSD_H */ 373#endif /* LINUX_NFSD_NFSD_H */
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 90c6aa6d5e0f..c763de5c1157 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -59,28 +59,25 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
59 * the write call). 59 * the write call).
60 */ 60 */
61static inline __be32 61static inline __be32
62nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) 62nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int requested)
63{ 63{
64 /* Type can be negative when creating hardlinks - not to a dir */ 64 mode &= S_IFMT;
65 if (type > 0 && (mode & S_IFMT) != type) { 65
66 if (rqstp->rq_vers == 4 && (mode & S_IFMT) == S_IFLNK) 66 if (requested == 0) /* the caller doesn't care */
67 return nfserr_symlink; 67 return nfs_ok;
68 else if (type == S_IFDIR) 68 if (mode == requested)
69 return nfserr_notdir; 69 return nfs_ok;
70 else if ((mode & S_IFMT) == S_IFDIR) 70 /*
71 return nfserr_isdir; 71 * v4 has an error more specific than err_notdir which we should
72 else 72 * return in preference to err_notdir:
73 return nfserr_inval; 73 */
74 } 74 if (rqstp->rq_vers == 4 && mode == S_IFLNK)
75 if (type < 0 && (mode & S_IFMT) == -type) { 75 return nfserr_symlink;
76 if (rqstp->rq_vers == 4 && (mode & S_IFMT) == S_IFLNK) 76 if (requested == S_IFDIR)
77 return nfserr_symlink; 77 return nfserr_notdir;
78 else if (type == -S_IFDIR) 78 if (mode == S_IFDIR)
79 return nfserr_isdir; 79 return nfserr_isdir;
80 else 80 return nfserr_inval;
81 return nfserr_notdir;
82 }
83 return 0;
84} 81}
85 82
86static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, 83static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 4eefaf1b42e8..a3cf38476a1b 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -35,6 +35,7 @@
35#ifndef _NFSD4_STATE_H 35#ifndef _NFSD4_STATE_H
36#define _NFSD4_STATE_H 36#define _NFSD4_STATE_H
37 37
38#include <linux/idr.h>
38#include <linux/sunrpc/svc_xprt.h> 39#include <linux/sunrpc/svc_xprt.h>
39#include <linux/nfsd/nfsfh.h> 40#include <linux/nfsd/nfsfh.h>
40#include "nfsfh.h" 41#include "nfsfh.h"
@@ -45,24 +46,20 @@ typedef struct {
45} clientid_t; 46} clientid_t;
46 47
47typedef struct { 48typedef struct {
48 u32 so_boot; 49 clientid_t so_clid;
49 u32 so_stateownerid; 50 u32 so_id;
50 u32 so_fileid;
51} stateid_opaque_t; 51} stateid_opaque_t;
52 52
53typedef struct { 53typedef struct {
54 u32 si_generation; 54 u32 si_generation;
55 stateid_opaque_t si_opaque; 55 stateid_opaque_t si_opaque;
56} stateid_t; 56} stateid_t;
57#define si_boot si_opaque.so_boot
58#define si_stateownerid si_opaque.so_stateownerid
59#define si_fileid si_opaque.so_fileid
60 57
61#define STATEID_FMT "(%08x/%08x/%08x/%08x)" 58#define STATEID_FMT "(%08x/%08x/%08x/%08x)"
62#define STATEID_VAL(s) \ 59#define STATEID_VAL(s) \
63 (s)->si_boot, \ 60 (s)->si_opaque.so_clid.cl_boot, \
64 (s)->si_stateownerid, \ 61 (s)->si_opaque.so_clid.cl_id, \
65 (s)->si_fileid, \ 62 (s)->si_opaque.so_id, \
66 (s)->si_generation 63 (s)->si_generation
67 64
68struct nfsd4_callback { 65struct nfsd4_callback {
@@ -76,17 +73,27 @@ struct nfsd4_callback {
76 bool cb_done; 73 bool cb_done;
77}; 74};
78 75
76struct nfs4_stid {
77#define NFS4_OPEN_STID 1
78#define NFS4_LOCK_STID 2
79#define NFS4_DELEG_STID 4
80/* For an open stateid kept around *only* to process close replays: */
81#define NFS4_CLOSED_STID 8
82 unsigned char sc_type;
83 stateid_t sc_stateid;
84 struct nfs4_client *sc_client;
85};
86
79struct nfs4_delegation { 87struct nfs4_delegation {
88 struct nfs4_stid dl_stid; /* must be first field */
80 struct list_head dl_perfile; 89 struct list_head dl_perfile;
81 struct list_head dl_perclnt; 90 struct list_head dl_perclnt;
82 struct list_head dl_recall_lru; /* delegation recalled */ 91 struct list_head dl_recall_lru; /* delegation recalled */
83 atomic_t dl_count; /* ref count */ 92 atomic_t dl_count; /* ref count */
84 struct nfs4_client *dl_client;
85 struct nfs4_file *dl_file; 93 struct nfs4_file *dl_file;
86 u32 dl_type; 94 u32 dl_type;
87 time_t dl_time; 95 time_t dl_time;
88/* For recall: */ 96/* For recall: */
89 stateid_t dl_stateid;
90 struct knfsd_fh dl_fh; 97 struct knfsd_fh dl_fh;
91 int dl_retries; 98 int dl_retries;
92 struct nfsd4_callback dl_recall; 99 struct nfsd4_callback dl_recall;
@@ -104,6 +111,11 @@ struct nfs4_cb_conn {
104 struct svc_xprt *cb_xprt; /* minorversion 1 only */ 111 struct svc_xprt *cb_xprt; /* minorversion 1 only */
105}; 112};
106 113
114static inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
115{
116 return container_of(s, struct nfs4_delegation, dl_stid);
117}
118
107/* Maximum number of slots per session. 160 is useful for long haul TCP */ 119/* Maximum number of slots per session. 160 is useful for long haul TCP */
108#define NFSD_MAX_SLOTS_PER_SESSION 160 120#define NFSD_MAX_SLOTS_PER_SESSION 160
109/* Maximum number of operations per session compound */ 121/* Maximum number of operations per session compound */
@@ -220,6 +232,7 @@ struct nfs4_client {
220 struct list_head cl_idhash; /* hash by cl_clientid.id */ 232 struct list_head cl_idhash; /* hash by cl_clientid.id */
221 struct list_head cl_strhash; /* hash by cl_name */ 233 struct list_head cl_strhash; /* hash by cl_name */
222 struct list_head cl_openowners; 234 struct list_head cl_openowners;
235 struct idr cl_stateids; /* stateid lookup */
223 struct list_head cl_delegations; 236 struct list_head cl_delegations;
224 struct list_head cl_lru; /* tail queue */ 237 struct list_head cl_lru; /* tail queue */
225 struct xdr_netobj cl_name; /* id generated by client */ 238 struct xdr_netobj cl_name; /* id generated by client */
@@ -245,6 +258,7 @@ struct nfs4_client {
245#define NFSD4_CB_UP 0 258#define NFSD4_CB_UP 0
246#define NFSD4_CB_UNKNOWN 1 259#define NFSD4_CB_UNKNOWN 1
247#define NFSD4_CB_DOWN 2 260#define NFSD4_CB_DOWN 2
261#define NFSD4_CB_FAULT 3
248 int cl_cb_state; 262 int cl_cb_state;
249 struct nfsd4_callback cl_cb_null; 263 struct nfsd4_callback cl_cb_null;
250 struct nfsd4_session *cl_cb_session; 264 struct nfsd4_session *cl_cb_session;
@@ -293,6 +307,9 @@ static inline void
293update_stateid(stateid_t *stateid) 307update_stateid(stateid_t *stateid)
294{ 308{
295 stateid->si_generation++; 309 stateid->si_generation++;
310 /* Wraparound recommendation from 3530bis-13 9.1.3.2: */
311 if (stateid->si_generation == 0)
312 stateid->si_generation = 1;
296} 313}
297 314
298/* A reasonable value for REPLAY_ISIZE was estimated as follows: 315/* A reasonable value for REPLAY_ISIZE was estimated as follows:
@@ -312,49 +329,57 @@ struct nfs4_replay {
312 __be32 rp_status; 329 __be32 rp_status;
313 unsigned int rp_buflen; 330 unsigned int rp_buflen;
314 char *rp_buf; 331 char *rp_buf;
315 unsigned intrp_allocated;
316 struct knfsd_fh rp_openfh; 332 struct knfsd_fh rp_openfh;
317 char rp_ibuf[NFSD4_REPLAY_ISIZE]; 333 char rp_ibuf[NFSD4_REPLAY_ISIZE];
318}; 334};
319 335
320/*
321* nfs4_stateowner can either be an open_owner, or a lock_owner
322*
323* so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[]
324* for lock_owner
325* so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[]
326* for lock_owner
327* so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client
328* struct is reaped.
329* so_perfilestate: heads the list of nfs4_stateid (either open or lock)
330* and is used to ensure no dangling nfs4_stateid references when we
331* release a stateowner.
332* so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when
333* close is called to reap associated byte-range locks
334* so_close_lru: (open) stateowner is placed on this list instead of being
335* reaped (when so_perfilestate is empty) to hold the last close replay.
336* reaped by laundramat thread after lease period.
337*/
338struct nfs4_stateowner { 336struct nfs4_stateowner {
339 struct kref so_ref;
340 struct list_head so_idhash; /* hash by so_id */
341 struct list_head so_strhash; /* hash by op_name */ 337 struct list_head so_strhash; /* hash by op_name */
342 struct list_head so_perclient;
343 struct list_head so_stateids; 338 struct list_head so_stateids;
344 struct list_head so_perstateid; /* for lockowners only */
345 struct list_head so_close_lru; /* tail queue */
346 time_t so_time; /* time of placement on so_close_lru */
347 int so_is_open_owner; /* 1=openowner,0=lockowner */
348 u32 so_id;
349 struct nfs4_client * so_client; 339 struct nfs4_client * so_client;
350 /* after increment in ENCODE_SEQID_OP_TAIL, represents the next 340 /* after increment in ENCODE_SEQID_OP_TAIL, represents the next
351 * sequence id expected from the client: */ 341 * sequence id expected from the client: */
352 u32 so_seqid; 342 u32 so_seqid;
353 struct xdr_netobj so_owner; /* open owner name */ 343 struct xdr_netobj so_owner; /* open owner name */
354 int so_confirmed; /* successful OPEN_CONFIRM? */
355 struct nfs4_replay so_replay; 344 struct nfs4_replay so_replay;
345 bool so_is_open_owner;
356}; 346};
357 347
348struct nfs4_openowner {
349 struct nfs4_stateowner oo_owner; /* must be first field */
350 struct list_head oo_perclient;
351 /*
352 * We keep around openowners a little while after last close,
353 * which saves clients from having to confirm, and allows us to
354 * handle close replays if they come soon enough. The close_lru
355 * is a list of such openowners, to be reaped by the laundromat
356 * thread eventually if they remain unused:
357 */
358 struct list_head oo_close_lru;
359 struct nfs4_ol_stateid *oo_last_closed_stid;
360 time_t oo_time; /* time of placement on so_close_lru */
361#define NFS4_OO_CONFIRMED 1
362#define NFS4_OO_PURGE_CLOSE 2
363#define NFS4_OO_NEW 4
364 unsigned char oo_flags;
365};
366
367struct nfs4_lockowner {
368 struct nfs4_stateowner lo_owner; /* must be first element */
369 struct list_head lo_perstateid; /* for lockowners only */
370 struct list_head lo_list; /* for temporary uses */
371};
372
373static inline struct nfs4_openowner * openowner(struct nfs4_stateowner *so)
374{
375 return container_of(so, struct nfs4_openowner, oo_owner);
376}
377
378static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
379{
380 return container_of(so, struct nfs4_lockowner, lo_owner);
381}
382
358/* 383/*
359* nfs4_file: a file opened by some number of (open) nfs4_stateowners. 384* nfs4_file: a file opened by some number of (open) nfs4_stateowners.
360* o fi_perfile list is used to search for conflicting 385* o fi_perfile list is used to search for conflicting
@@ -368,17 +393,17 @@ struct nfs4_file {
368 /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ 393 /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
369 struct file * fi_fds[3]; 394 struct file * fi_fds[3];
370 /* 395 /*
371 * Each open or lock stateid contributes 1 to either 396 * Each open or lock stateid contributes 0-4 to the counts
372 * fi_access[O_RDONLY], fi_access[O_WRONLY], or both, depending 397 * below depending on which bits are set in st_access_bitmap:
373 * on open or lock mode: 398 * 1 to fi_access[O_RDONLY] if NFS4_SHARE_ACCES_READ is set
399 * + 1 to fi_access[O_WRONLY] if NFS4_SHARE_ACCESS_WRITE is set
400 * + 1 to both of the above if NFS4_SHARE_ACCESS_BOTH is set.
374 */ 401 */
375 atomic_t fi_access[2]; 402 atomic_t fi_access[2];
376 struct file *fi_deleg_file; 403 struct file *fi_deleg_file;
377 struct file_lock *fi_lease; 404 struct file_lock *fi_lease;
378 atomic_t fi_delegees; 405 atomic_t fi_delegees;
379 struct inode *fi_inode; 406 struct inode *fi_inode;
380 u32 fi_id; /* used with stateowner->so_id
381 * for stateid_hashtbl hash */
382 bool fi_had_conflict; 407 bool fi_had_conflict;
383}; 408};
384 409
@@ -408,50 +433,27 @@ static inline struct file *find_any_file(struct nfs4_file *f)
408 return f->fi_fds[O_RDONLY]; 433 return f->fi_fds[O_RDONLY];
409} 434}
410 435
411/* 436/* "ol" stands for "Open or Lock". Better suggestions welcome. */
412* nfs4_stateid can either be an open stateid or (eventually) a lock stateid 437struct nfs4_ol_stateid {
413* 438 struct nfs4_stid st_stid; /* must be first field */
414* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file
415*
416* st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry
417* st_perfile: file_hashtbl[] entry.
418* st_perfile_state: nfs4_stateowner->so_perfilestate
419* st_perlockowner: (open stateid) list of lock nfs4_stateowners
420* st_access_bmap: used only for open stateid
421* st_deny_bmap: used only for open stateid
422* st_openstp: open stateid lock stateid was derived from
423*
424* XXX: open stateids and lock stateids have diverged sufficiently that
425* we should consider defining separate structs for the two cases.
426*/
427
428struct nfs4_stateid {
429 struct list_head st_hash;
430 struct list_head st_perfile; 439 struct list_head st_perfile;
431 struct list_head st_perstateowner; 440 struct list_head st_perstateowner;
432 struct list_head st_lockowners; 441 struct list_head st_lockowners;
433 struct nfs4_stateowner * st_stateowner; 442 struct nfs4_stateowner * st_stateowner;
434 struct nfs4_file * st_file; 443 struct nfs4_file * st_file;
435 stateid_t st_stateid;
436 unsigned long st_access_bmap; 444 unsigned long st_access_bmap;
437 unsigned long st_deny_bmap; 445 unsigned long st_deny_bmap;
438 struct nfs4_stateid * st_openstp; 446 struct nfs4_ol_stateid * st_openstp;
439}; 447};
440 448
449static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
450{
451 return container_of(s, struct nfs4_ol_stateid, st_stid);
452}
453
441/* flags for preprocess_seqid_op() */ 454/* flags for preprocess_seqid_op() */
442#define HAS_SESSION 0x00000001
443#define CONFIRM 0x00000002
444#define OPEN_STATE 0x00000004
445#define LOCK_STATE 0x00000008
446#define RD_STATE 0x00000010 455#define RD_STATE 0x00000010
447#define WR_STATE 0x00000020 456#define WR_STATE 0x00000020
448#define CLOSE_STATE 0x00000040
449
450#define seqid_mutating_err(err) \
451 (((err) != nfserr_stale_clientid) && \
452 ((err) != nfserr_bad_seqid) && \
453 ((err) != nfserr_stale_stateid) && \
454 ((err) != nfserr_bad_stateid))
455 457
456struct nfsd4_compound_state; 458struct nfsd4_compound_state;
457 459
@@ -461,7 +463,8 @@ extern void nfs4_lock_state(void);
461extern void nfs4_unlock_state(void); 463extern void nfs4_unlock_state(void);
462extern int nfs4_in_grace(void); 464extern int nfs4_in_grace(void);
463extern __be32 nfs4_check_open_reclaim(clientid_t *clid); 465extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
464extern void nfs4_free_stateowner(struct kref *kref); 466extern void nfs4_free_openowner(struct nfs4_openowner *);
467extern void nfs4_free_lockowner(struct nfs4_lockowner *);
465extern int set_callback_cred(void); 468extern int set_callback_cred(void);
466extern void nfsd4_probe_callback(struct nfs4_client *clp); 469extern void nfsd4_probe_callback(struct nfs4_client *clp);
467extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); 470extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
@@ -473,7 +476,7 @@ extern void nfsd4_destroy_callback_queue(void);
473extern void nfsd4_shutdown_callback(struct nfs4_client *); 476extern void nfsd4_shutdown_callback(struct nfs4_client *);
474extern void nfs4_put_delegation(struct nfs4_delegation *dp); 477extern void nfs4_put_delegation(struct nfs4_delegation *dp);
475extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); 478extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
476extern void nfsd4_init_recdir(char *recdir_name); 479extern void nfsd4_init_recdir(void);
477extern int nfsd4_recdir_load(void); 480extern int nfsd4_recdir_load(void);
478extern void nfsd4_shutdown_recdir(void); 481extern void nfsd4_shutdown_recdir(void);
479extern int nfs4_client_to_reclaim(const char *name); 482extern int nfs4_client_to_reclaim(const char *name);
@@ -482,18 +485,7 @@ extern void nfsd4_recdir_purge_old(void);
482extern int nfsd4_create_clid_dir(struct nfs4_client *clp); 485extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
483extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); 486extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
484extern void release_session_client(struct nfsd4_session *); 487extern void release_session_client(struct nfsd4_session *);
485extern __be32 nfs4_validate_stateid(stateid_t *, int); 488extern __be32 nfs4_validate_stateid(struct nfs4_client *, stateid_t *);
486 489extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *);
487static inline void
488nfs4_put_stateowner(struct nfs4_stateowner *so)
489{
490 kref_put(&so->so_ref, nfs4_free_stateowner);
491}
492
493static inline void
494nfs4_get_stateowner(struct nfs4_stateowner *so)
495{
496 kref_get(&so->so_ref);
497}
498 490
499#endif /* NFSD4_STATE_H */ 491#endif /* NFSD4_STATE_H */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index fd0acca5370a..7a2e442623c8 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -168,6 +168,8 @@ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
168{ 168{
169 if (d_mountpoint(dentry)) 169 if (d_mountpoint(dentry))
170 return 1; 170 return 1;
171 if (nfsd4_is_junction(dentry))
172 return 1;
171 if (!(exp->ex_flags & NFSEXP_V4ROOT)) 173 if (!(exp->ex_flags & NFSEXP_V4ROOT))
172 return 0; 174 return 0;
173 return dentry->d_inode != NULL; 175 return dentry->d_inode != NULL;
@@ -502,7 +504,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
502 unsigned int flags = 0; 504 unsigned int flags = 0;
503 505
504 /* Get inode */ 506 /* Get inode */
505 error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, NFSD_MAY_SATTR); 507 error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR);
506 if (error) 508 if (error)
507 return error; 509 return error;
508 510
@@ -592,6 +594,22 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac
592 return error; 594 return error;
593} 595}
594 596
597#define NFSD_XATTR_JUNCTION_PREFIX XATTR_TRUSTED_PREFIX "junction."
598#define NFSD_XATTR_JUNCTION_TYPE NFSD_XATTR_JUNCTION_PREFIX "type"
599int nfsd4_is_junction(struct dentry *dentry)
600{
601 struct inode *inode = dentry->d_inode;
602
603 if (inode == NULL)
604 return 0;
605 if (inode->i_mode & S_IXUGO)
606 return 0;
607 if (!(inode->i_mode & S_ISVTX))
608 return 0;
609 if (vfs_getxattr(dentry, NFSD_XATTR_JUNCTION_TYPE, NULL, 0) <= 0)
610 return 0;
611 return 1;
612}
595#endif /* defined(CONFIG_NFSD_V4) */ 613#endif /* defined(CONFIG_NFSD_V4) */
596 614
597#ifdef CONFIG_NFSD_V3 615#ifdef CONFIG_NFSD_V3
@@ -1352,7 +1370,7 @@ __be32
1352do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, 1370do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1353 char *fname, int flen, struct iattr *iap, 1371 char *fname, int flen, struct iattr *iap,
1354 struct svc_fh *resfhp, int createmode, u32 *verifier, 1372 struct svc_fh *resfhp, int createmode, u32 *verifier,
1355 int *truncp, int *created) 1373 bool *truncp, bool *created)
1356{ 1374{
1357 struct dentry *dentry, *dchild = NULL; 1375 struct dentry *dentry, *dchild = NULL;
1358 struct inode *dirp; 1376 struct inode *dirp;
@@ -1632,10 +1650,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1632 err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); 1650 err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE);
1633 if (err) 1651 if (err)
1634 goto out; 1652 goto out;
1635 err = fh_verify(rqstp, tfhp, -S_IFDIR, NFSD_MAY_NOP); 1653 err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP);
1636 if (err) 1654 if (err)
1637 goto out; 1655 goto out;
1638 1656 err = nfserr_isdir;
1657 if (S_ISDIR(tfhp->fh_dentry->d_inode->i_mode))
1658 goto out;
1639 err = nfserr_perm; 1659 err = nfserr_perm;
1640 if (!len) 1660 if (!len)
1641 goto out; 1661 goto out;
@@ -2114,7 +2134,8 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
2114 2134
2115 /* Allow read access to binaries even when mode 111 */ 2135 /* Allow read access to binaries even when mode 111 */
2116 if (err == -EACCES && S_ISREG(inode->i_mode) && 2136 if (err == -EACCES && S_ISREG(inode->i_mode) &&
2117 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) 2137 (acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE) ||
2138 acc == (NFSD_MAY_READ | NFSD_MAY_READ_IF_EXEC)))
2118 err = inode_permission(inode, MAY_EXEC); 2139 err = inode_permission(inode, MAY_EXEC);
2119 2140
2120 return err? nfserrno(err) : 0; 2141 return err? nfserrno(err) : 0;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index e0bbac04d1dd..3f54ad03bb2b 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -10,21 +10,22 @@
10/* 10/*
11 * Flags for nfsd_permission 11 * Flags for nfsd_permission
12 */ 12 */
13#define NFSD_MAY_NOP 0 13#define NFSD_MAY_NOP 0
14#define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ 14#define NFSD_MAY_EXEC 0x001 /* == MAY_EXEC */
15#define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ 15#define NFSD_MAY_WRITE 0x002 /* == MAY_WRITE */
16#define NFSD_MAY_READ 4 /* == MAY_READ */ 16#define NFSD_MAY_READ 0x004 /* == MAY_READ */
17#define NFSD_MAY_SATTR 8 17#define NFSD_MAY_SATTR 0x008
18#define NFSD_MAY_TRUNC 16 18#define NFSD_MAY_TRUNC 0x010
19#define NFSD_MAY_LOCK 32 19#define NFSD_MAY_LOCK 0x020
20#define NFSD_MAY_MASK 63 20#define NFSD_MAY_MASK 0x03f
21 21
22/* extra hints to permission and open routines: */ 22/* extra hints to permission and open routines: */
23#define NFSD_MAY_OWNER_OVERRIDE 64 23#define NFSD_MAY_OWNER_OVERRIDE 0x040
24#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ 24#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */
25#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 25#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100
26#define NFSD_MAY_NOT_BREAK_LEASE 512 26#define NFSD_MAY_NOT_BREAK_LEASE 0x200
27#define NFSD_MAY_BYPASS_GSS 1024 27#define NFSD_MAY_BYPASS_GSS 0x400
28#define NFSD_MAY_READ_IF_EXEC 0x800
28 29
29#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) 30#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
30#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) 31#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
@@ -61,7 +62,7 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
61__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, 62__be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *,
62 char *name, int len, struct iattr *attrs, 63 char *name, int len, struct iattr *attrs,
63 struct svc_fh *res, int createmode, 64 struct svc_fh *res, int createmode,
64 u32 *verifier, int *truncp, int *created); 65 u32 *verifier, bool *truncp, bool *created);
65__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, 66__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
66 loff_t, unsigned long); 67 loff_t, unsigned long);
67#endif /* CONFIG_NFSD_V3 */ 68#endif /* CONFIG_NFSD_V3 */
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index d2a8d04428c7..2364747ee97d 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -81,7 +81,6 @@ struct nfsd4_access {
81struct nfsd4_close { 81struct nfsd4_close {
82 u32 cl_seqid; /* request */ 82 u32 cl_seqid; /* request */
83 stateid_t cl_stateid; /* request+response */ 83 stateid_t cl_stateid; /* request+response */
84 struct nfs4_stateowner * cl_stateowner; /* response */
85}; 84};
86 85
87struct nfsd4_commit { 86struct nfsd4_commit {
@@ -131,7 +130,7 @@ struct nfsd4_link {
131 130
132struct nfsd4_lock_denied { 131struct nfsd4_lock_denied {
133 clientid_t ld_clientid; 132 clientid_t ld_clientid;
134 struct nfs4_stateowner *ld_sop; 133 struct xdr_netobj ld_owner;
135 u64 ld_start; 134 u64 ld_start;
136 u64 ld_length; 135 u64 ld_length;
137 u32 ld_type; 136 u32 ld_type;
@@ -165,9 +164,6 @@ struct nfsd4_lock {
165 } ok; 164 } ok;
166 struct nfsd4_lock_denied denied; 165 struct nfsd4_lock_denied denied;
167 } u; 166 } u;
168 /* The lk_replay_owner is the open owner in the open_to_lock_owner
169 * case and the lock owner otherwise: */
170 struct nfs4_stateowner *lk_replay_owner;
171}; 167};
172#define lk_new_open_seqid v.new.open_seqid 168#define lk_new_open_seqid v.new.open_seqid
173#define lk_new_open_stateid v.new.open_stateid 169#define lk_new_open_stateid v.new.open_stateid
@@ -188,7 +184,6 @@ struct nfsd4_lockt {
188 struct xdr_netobj lt_owner; 184 struct xdr_netobj lt_owner;
189 u64 lt_offset; 185 u64 lt_offset;
190 u64 lt_length; 186 u64 lt_length;
191 struct nfs4_stateowner * lt_stateowner;
192 struct nfsd4_lock_denied lt_denied; 187 struct nfsd4_lock_denied lt_denied;
193}; 188};
194 189
@@ -199,7 +194,6 @@ struct nfsd4_locku {
199 stateid_t lu_stateid; 194 stateid_t lu_stateid;
200 u64 lu_offset; 195 u64 lu_offset;
201 u64 lu_length; 196 u64 lu_length;
202 struct nfs4_stateowner *lu_stateowner;
203}; 197};
204 198
205 199
@@ -232,8 +226,11 @@ struct nfsd4_open {
232 u32 op_recall; /* recall */ 226 u32 op_recall; /* recall */
233 struct nfsd4_change_info op_cinfo; /* response */ 227 struct nfsd4_change_info op_cinfo; /* response */
234 u32 op_rflags; /* response */ 228 u32 op_rflags; /* response */
235 int op_truncate; /* used during processing */ 229 bool op_truncate; /* used during processing */
236 struct nfs4_stateowner *op_stateowner; /* used during processing */ 230 bool op_created; /* used during processing */
231 struct nfs4_openowner *op_openowner; /* used during processing */
232 struct nfs4_file *op_file; /* used during processing */
233 struct nfs4_ol_stateid *op_stp; /* used during processing */
237 struct nfs4_acl *op_acl; 234 struct nfs4_acl *op_acl;
238}; 235};
239#define op_iattr iattr 236#define op_iattr iattr
@@ -243,7 +240,6 @@ struct nfsd4_open_confirm {
243 stateid_t oc_req_stateid /* request */; 240 stateid_t oc_req_stateid /* request */;
244 u32 oc_seqid /* request */; 241 u32 oc_seqid /* request */;
245 stateid_t oc_resp_stateid /* response */; 242 stateid_t oc_resp_stateid /* response */;
246 struct nfs4_stateowner * oc_stateowner; /* response */
247}; 243};
248 244
249struct nfsd4_open_downgrade { 245struct nfsd4_open_downgrade {
@@ -251,7 +247,6 @@ struct nfsd4_open_downgrade {
251 u32 od_seqid; 247 u32 od_seqid;
252 u32 od_share_access; 248 u32 od_share_access;
253 u32 od_share_deny; 249 u32 od_share_deny;
254 struct nfs4_stateowner *od_stateowner;
255}; 250};
256 251
257 252
@@ -325,8 +320,7 @@ struct nfsd4_setattr {
325 320
326struct nfsd4_setclientid { 321struct nfsd4_setclientid {
327 nfs4_verifier se_verf; /* request */ 322 nfs4_verifier se_verf; /* request */
328 u32 se_namelen; /* request */ 323 struct xdr_netobj se_name;
329 char * se_name; /* request */
330 u32 se_callback_prog; /* request */ 324 u32 se_callback_prog; /* request */
331 u32 se_callback_netid_len; /* request */ 325 u32 se_callback_netid_len; /* request */
332 char * se_callback_netid_val; /* request */ 326 char * se_callback_netid_val; /* request */
@@ -351,7 +345,6 @@ struct nfsd4_saved_compoundargs {
351 345
352struct nfsd4_test_stateid { 346struct nfsd4_test_stateid {
353 __be32 ts_num_ids; 347 __be32 ts_num_ids;
354 __be32 ts_has_session;
355 struct nfsd4_compoundargs *ts_saved_args; 348 struct nfsd4_compoundargs *ts_saved_args;
356 struct nfsd4_saved_compoundargs ts_savedp; 349 struct nfsd4_saved_compoundargs ts_savedp;
357}; 350};
@@ -405,6 +398,10 @@ struct nfsd4_destroy_session {
405 struct nfs4_sessionid sessionid; 398 struct nfs4_sessionid sessionid;
406}; 399};
407 400
401struct nfsd4_destroy_clientid {
402 clientid_t clientid;
403};
404
408struct nfsd4_reclaim_complete { 405struct nfsd4_reclaim_complete {
409 u32 rca_one_fs; 406 u32 rca_one_fs;
410}; 407};
@@ -532,6 +529,7 @@ int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
532 struct nfsd4_compoundargs *); 529 struct nfsd4_compoundargs *);
533int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, 530int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
534 struct nfsd4_compoundres *); 531 struct nfsd4_compoundres *);
532int nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
535void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 533void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
536void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 534void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
537__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 535__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
@@ -558,11 +556,13 @@ extern __be32 nfsd4_sequence(struct svc_rqst *,
558extern __be32 nfsd4_destroy_session(struct svc_rqst *, 556extern __be32 nfsd4_destroy_session(struct svc_rqst *,
559 struct nfsd4_compound_state *, 557 struct nfsd4_compound_state *,
560 struct nfsd4_destroy_session *); 558 struct nfsd4_destroy_session *);
559extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *);
561__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); 560__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *);
562extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, 561extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
563 struct nfsd4_open *open); 562 struct nfsd4_open *open);
564extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, 563extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
565 struct svc_fh *current_fh, struct nfsd4_open *open); 564 struct svc_fh *current_fh, struct nfsd4_open *open);
565extern void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status);
566extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, 566extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
567 struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); 567 struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
568extern __be32 nfsd4_close(struct svc_rqst *rqstp, 568extern __be32 nfsd4_close(struct svc_rqst *rqstp,