aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c91
1 files changed, 39 insertions, 52 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 2153f9bdbebd..6a8fedaa4f55 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1,6 +1,4 @@
1/* 1/*
2* linux/fs/nfsd/nfs4state.c
3*
4* Copyright (c) 2001 The Regents of the University of Michigan. 2* Copyright (c) 2001 The Regents of the University of Michigan.
5* All rights reserved. 3* All rights reserved.
6* 4*
@@ -34,28 +32,15 @@
34* 32*
35*/ 33*/
36 34
37#include <linux/param.h>
38#include <linux/major.h>
39#include <linux/slab.h>
40
41#include <linux/sunrpc/svc.h>
42#include <linux/nfsd/nfsd.h>
43#include <linux/nfsd/cache.h>
44#include <linux/file.h> 35#include <linux/file.h>
45#include <linux/mount.h>
46#include <linux/workqueue.h>
47#include <linux/smp_lock.h> 36#include <linux/smp_lock.h>
48#include <linux/kthread.h> 37#include <linux/slab.h>
49#include <linux/nfs4.h>
50#include <linux/nfsd/state.h>
51#include <linux/nfsd/xdr4.h>
52#include <linux/namei.h> 38#include <linux/namei.h>
53#include <linux/swap.h> 39#include <linux/swap.h>
54#include <linux/mutex.h>
55#include <linux/lockd/bind.h>
56#include <linux/module.h>
57#include <linux/sunrpc/svcauth_gss.h> 40#include <linux/sunrpc/svcauth_gss.h>
58#include <linux/sunrpc/clnt.h> 41#include <linux/sunrpc/clnt.h>
42#include "xdr4.h"
43#include "vfs.h"
59 44
60#define NFSDDBG_FACILITY NFSDDBG_PROC 45#define NFSDDBG_FACILITY NFSDDBG_PROC
61 46
@@ -477,13 +462,14 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan)
477 462
478/* 463/*
479 * fchan holds the client values on input, and the server values on output 464 * fchan holds the client values on input, and the server values on output
465 * sv_max_mesg is the maximum payload plus one page for overhead.
480 */ 466 */
481static int init_forechannel_attrs(struct svc_rqst *rqstp, 467static int init_forechannel_attrs(struct svc_rqst *rqstp,
482 struct nfsd4_channel_attrs *session_fchan, 468 struct nfsd4_channel_attrs *session_fchan,
483 struct nfsd4_channel_attrs *fchan) 469 struct nfsd4_channel_attrs *fchan)
484{ 470{
485 int status = 0; 471 int status = 0;
486 __u32 maxcount = svc_max_payload(rqstp); 472 __u32 maxcount = nfsd_serv->sv_max_mesg;
487 473
488 /* headerpadsz set to zero in encode routine */ 474 /* headerpadsz set to zero in encode routine */
489 475
@@ -523,6 +509,15 @@ free_session_slots(struct nfsd4_session *ses)
523 kfree(ses->se_slots[i]); 509 kfree(ses->se_slots[i]);
524} 510}
525 511
512/*
513 * We don't actually need to cache the rpc and session headers, so we
514 * can allocate a little less for each slot:
515 */
516static inline int slot_bytes(struct nfsd4_channel_attrs *ca)
517{
518 return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
519}
520
526static int 521static int
527alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, 522alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
528 struct nfsd4_create_session *cses) 523 struct nfsd4_create_session *cses)
@@ -554,7 +549,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
554 memcpy(new, &tmp, sizeof(*new)); 549 memcpy(new, &tmp, sizeof(*new));
555 550
556 /* allocate each struct nfsd4_slot and data cache in one piece */ 551 /* allocate each struct nfsd4_slot and data cache in one piece */
557 cachesize = new->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; 552 cachesize = slot_bytes(&new->se_fchannel);
558 for (i = 0; i < new->se_fchannel.maxreqs; i++) { 553 for (i = 0; i < new->se_fchannel.maxreqs; i++) {
559 sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); 554 sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL);
560 if (!sp) 555 if (!sp)
@@ -628,10 +623,12 @@ void
628free_session(struct kref *kref) 623free_session(struct kref *kref)
629{ 624{
630 struct nfsd4_session *ses; 625 struct nfsd4_session *ses;
626 int mem;
631 627
632 ses = container_of(kref, struct nfsd4_session, se_ref); 628 ses = container_of(kref, struct nfsd4_session, se_ref);
633 spin_lock(&nfsd_drc_lock); 629 spin_lock(&nfsd_drc_lock);
634 nfsd_drc_mem_used -= ses->se_fchannel.maxreqs * NFSD_SLOT_CACHE_SIZE; 630 mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel);
631 nfsd_drc_mem_used -= mem;
635 spin_unlock(&nfsd_drc_lock); 632 spin_unlock(&nfsd_drc_lock);
636 free_session_slots(ses); 633 free_session_slots(ses);
637 kfree(ses); 634 kfree(ses);
@@ -2002,7 +1999,9 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
2002{ 1999{
2003 if (share_access & NFS4_SHARE_ACCESS_WRITE) { 2000 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
2004 drop_file_write_access(filp); 2001 drop_file_write_access(filp);
2002 spin_lock(&filp->f_lock);
2005 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; 2003 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
2004 spin_unlock(&filp->f_lock);
2006 } 2005 }
2007} 2006}
2008 2007
@@ -2404,11 +2403,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2404 2403
2405 memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); 2404 memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
2406 2405
2407 dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n", 2406 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
2408 dp->dl_stateid.si_boot, 2407 STATEID_VAL(&dp->dl_stateid));
2409 dp->dl_stateid.si_stateownerid,
2410 dp->dl_stateid.si_fileid,
2411 dp->dl_stateid.si_generation);
2412out: 2408out:
2413 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS 2409 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
2414 && flag == NFS4_OPEN_DELEGATE_NONE 2410 && flag == NFS4_OPEN_DELEGATE_NONE
@@ -2487,8 +2483,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2487 } 2483 }
2488 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); 2484 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
2489 2485
2490 if (nfsd4_has_session(&resp->cstate)) 2486 if (nfsd4_has_session(&resp->cstate)) {
2491 open->op_stateowner->so_confirmed = 1; 2487 open->op_stateowner->so_confirmed = 1;
2488 nfsd4_create_clid_dir(open->op_stateowner->so_client);
2489 }
2492 2490
2493 /* 2491 /*
2494 * Attempt to hand out a delegation. No error return, because the 2492 * Attempt to hand out a delegation. No error return, because the
@@ -2498,9 +2496,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2498 2496
2499 status = nfs_ok; 2497 status = nfs_ok;
2500 2498
2501 dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n", 2499 dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
2502 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, 2500 STATEID_VAL(&stp->st_stateid));
2503 stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
2504out: 2501out:
2505 if (fp) 2502 if (fp)
2506 put_nfs4_file(fp); 2503 put_nfs4_file(fp);
@@ -2666,9 +2663,8 @@ STALE_STATEID(stateid_t *stateid)
2666{ 2663{
2667 if (time_after((unsigned long)boot_time, 2664 if (time_after((unsigned long)boot_time,
2668 (unsigned long)stateid->si_boot)) { 2665 (unsigned long)stateid->si_boot)) {
2669 dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", 2666 dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
2670 stateid->si_boot, stateid->si_stateownerid, 2667 STATEID_VAL(stateid));
2671 stateid->si_fileid, stateid->si_generation);
2672 return 1; 2668 return 1;
2673 } 2669 }
2674 return 0; 2670 return 0;
@@ -2680,9 +2676,8 @@ EXPIRED_STATEID(stateid_t *stateid)
2680 if (time_before((unsigned long)boot_time, 2676 if (time_before((unsigned long)boot_time,
2681 ((unsigned long)stateid->si_boot)) && 2677 ((unsigned long)stateid->si_boot)) &&
2682 time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { 2678 time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
2683 dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n", 2679 dprintk("NFSD: expired stateid " STATEID_FMT "!\n",
2684 stateid->si_boot, stateid->si_stateownerid, 2680 STATEID_VAL(stateid));
2685 stateid->si_fileid, stateid->si_generation);
2686 return 1; 2681 return 1;
2687 } 2682 }
2688 return 0; 2683 return 0;
@@ -2696,9 +2691,8 @@ stateid_error_map(stateid_t *stateid)
2696 if (EXPIRED_STATEID(stateid)) 2691 if (EXPIRED_STATEID(stateid))
2697 return nfserr_expired; 2692 return nfserr_expired;
2698 2693
2699 dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n", 2694 dprintk("NFSD: bad stateid " STATEID_FMT "!\n",
2700 stateid->si_boot, stateid->si_stateownerid, 2695 STATEID_VAL(stateid));
2701 stateid->si_fileid, stateid->si_generation);
2702 return nfserr_bad_stateid; 2696 return nfserr_bad_stateid;
2703} 2697}
2704 2698
@@ -2884,10 +2878,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
2884 struct svc_fh *current_fh = &cstate->current_fh; 2878 struct svc_fh *current_fh = &cstate->current_fh;
2885 __be32 status; 2879 __be32 status;
2886 2880
2887 dprintk("NFSD: preprocess_seqid_op: seqid=%d " 2881 dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
2888 "stateid = (%08x/%08x/%08x/%08x)\n", seqid, 2882 seqid, STATEID_VAL(stateid));
2889 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
2890 stateid->si_generation);
2891 2883
2892 *stpp = NULL; 2884 *stpp = NULL;
2893 *sopp = NULL; 2885 *sopp = NULL;
@@ -3019,12 +3011,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3019 sop->so_confirmed = 1; 3011 sop->so_confirmed = 1;
3020 update_stateid(&stp->st_stateid); 3012 update_stateid(&stp->st_stateid);
3021 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); 3013 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
3022 dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " 3014 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
3023 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid, 3015 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid));
3024 stp->st_stateid.si_boot,
3025 stp->st_stateid.si_stateownerid,
3026 stp->st_stateid.si_fileid,
3027 stp->st_stateid.si_generation);
3028 3016
3029 nfsd4_create_clid_dir(sop->so_client); 3017 nfsd4_create_clid_dir(sop->so_client);
3030out: 3018out:
@@ -3283,9 +3271,8 @@ find_delegation_stateid(struct inode *ino, stateid_t *stid)
3283 struct nfs4_file *fp; 3271 struct nfs4_file *fp;
3284 struct nfs4_delegation *dl; 3272 struct nfs4_delegation *dl;
3285 3273
3286 dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n", 3274 dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__,
3287 stid->si_boot, stid->si_stateownerid, 3275 STATEID_VAL(stid));
3288 stid->si_fileid, stid->si_generation);
3289 3276
3290 fp = find_file(ino); 3277 fp = find_file(ino);
3291 if (!fp) 3278 if (!fp)