2 * linux/fs/nfsd/nfs4state.c
4 * Copyright (c) 2001 The Regents of the University of Michigan.
7 * Kendrick Smith <kmsmith@umich.edu>
8 * Andy Adamson <kandros@umich.edu>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <linux/param.h>
38 #include <linux/major.h>
39 #include <linux/slab.h>
41 #include <linux/sunrpc/svc.h>
42 #include <linux/nfsd/nfsd.h>
43 #include <linux/nfsd/cache.h>
44 #include <linux/mount.h>
45 #include <linux/workqueue.h>
46 #include <linux/smp_lock.h>
47 #include <linux/nfs4.h>
48 #include <linux/nfsd/state.h>
49 #include <linux/nfsd/xdr4.h>
51 #define NFSDDBG_FACILITY NFSDDBG_PROC
55 static time_t grace_end = 0;
56 static u32 current_clientid = 1;
57 static u32 current_ownerid;
58 static u32 current_fileid;
60 stateid_t zerostateid; /* bits all 0 */
61 stateid_t onestateid; /* bits all 1 */
64 u32 list_add_perfile = 0;
65 u32 list_del_perfile = 0;
66 u32 add_perclient = 0;
67 u32 del_perclient = 0;
76 /* forward declarations */
77 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
82 * protects clientid_hashtbl[], clientstr_hashtbl[],
83 * unconfstr_hashtbl[], uncofid_hashtbl[].
85 static struct semaphore client_sema;
94 * nfs4_unlock_state(); called in encode
97 nfs4_unlock_state(void)
103 opaque_hashval(const void *ptr, int nbytes)
105 unsigned char *cptr = (unsigned char *) ptr;
115 /* forward declarations */
116 static void release_stateowner(struct nfs4_stateowner *sop);
117 static void release_stateid(struct nfs4_stateid *stp, int flags);
118 static void release_file(struct nfs4_file *fp);
125 /* Hash tables for nfs4_clientid state */
126 #define CLIENT_HASH_BITS 4
127 #define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
128 #define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
130 #define clientid_hashval(id) \
131 ((id) & CLIENT_HASH_MASK)
132 #define clientstr_hashval(name, namelen) \
133 (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
135 /* conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
136 * setclientid_confirmed info.
138 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
141 * client_lru holds client queue ordered by nfs4_client.cl_time
144 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
145 * for last close replay.
147 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
148 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
149 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
150 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
151 static struct list_head client_lru;
152 static struct list_head close_lru;
155 renew_client(struct nfs4_client *clp)
158 * Move client to the end to the LRU list.
160 dprintk("renewing client (clientid %08x/%08x)\n",
161 clp->cl_clientid.cl_boot,
162 clp->cl_clientid.cl_id);
163 list_move_tail(&clp->cl_lru, &client_lru);
164 clp->cl_time = get_seconds();
167 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
169 STALE_CLIENTID(clientid_t *clid)
171 if (clid->cl_boot == boot_time)
173 dprintk("NFSD stale clientid (%08x/%08x)\n",
174 clid->cl_boot, clid->cl_id);
179 * XXX Should we use a slab cache ?
180 * This type of memory management is somewhat inefficient, but we use it
181 * anyway since SETCLIENTID is not a common operation.
183 static inline struct nfs4_client *
184 alloc_client(struct xdr_netobj name)
186 struct nfs4_client *clp;
188 if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) {
189 memset(clp, 0, sizeof(*clp));
190 if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) {
191 memcpy(clp->cl_name.data, name.data, name.len);
192 clp->cl_name.len = name.len;
203 free_client(struct nfs4_client *clp)
205 if (clp->cl_cred.cr_group_info)
206 put_group_info(clp->cl_cred.cr_group_info);
207 kfree(clp->cl_name.data);
212 expire_client(struct nfs4_client *clp)
214 struct nfs4_stateowner *sop;
216 dprintk("NFSD: expire_client\n");
217 list_del(&clp->cl_idhash);
218 list_del(&clp->cl_strhash);
219 list_del(&clp->cl_lru);
220 while (!list_empty(&clp->cl_perclient)) {
221 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
222 release_stateowner(sop);
227 static struct nfs4_client *
228 create_client(struct xdr_netobj name) {
229 struct nfs4_client *clp;
231 if(!(clp = alloc_client(name)))
233 INIT_LIST_HEAD(&clp->cl_idhash);
234 INIT_LIST_HEAD(&clp->cl_strhash);
235 INIT_LIST_HEAD(&clp->cl_perclient);
236 INIT_LIST_HEAD(&clp->cl_lru);
242 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
243 memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
247 copy_clid(struct nfs4_client *target, struct nfs4_client *source) {
248 target->cl_clientid.cl_boot = source->cl_clientid.cl_boot;
249 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
253 copy_cred(struct svc_cred *target, struct svc_cred *source) {
255 target->cr_uid = source->cr_uid;
256 target->cr_gid = source->cr_gid;
257 target->cr_group_info = source->cr_group_info;
258 get_group_info(target->cr_group_info);
262 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
265 return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
269 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
270 return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
274 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
275 return((cl1->cl_boot == cl2->cl_boot) &&
276 (cl1->cl_id == cl2->cl_id));
279 /* XXX what about NGROUP */
281 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
282 return(cr1->cr_uid == cr2->cr_uid);
287 gen_clid(struct nfs4_client *clp) {
288 clp->cl_clientid.cl_boot = boot_time;
289 clp->cl_clientid.cl_id = current_clientid++;
293 gen_confirm(struct nfs4_client *clp) {
298 p = (u32 *)clp->cl_confirm.data;
304 check_name(struct xdr_netobj name) {
308 if (name.len > NFS4_OPAQUE_LIMIT) {
309 printk("NFSD: check_name: name too long(%d)!\n", name.len);
316 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
318 unsigned int idhashval;
320 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
321 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
322 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
323 list_add_tail(&clp->cl_lru, &client_lru);
324 clp->cl_time = get_seconds();
328 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
330 unsigned int strhashval;
332 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
333 list_del_init(&clp->cl_strhash);
334 list_del_init(&clp->cl_idhash);
335 list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
336 strhashval = clientstr_hashval(clp->cl_name.data,
338 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
343 * RFC 3010 has a complex implmentation description of processing a
344 * SETCLIENTID request consisting of 5 bullets, labeled as
345 * CASE0 - CASE4 below.
348 * callback information will be processed in a future patch
350 * an unconfirmed record is added when:
351 * NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
352 * CASE 1: confirmed record found with matching name, principal,
353 * verifier, and clientid.
354 * CASE 2: confirmed record found with matching name, principal,
355 * and there is no unconfirmed record with matching
358 * an unconfirmed record is replaced when:
359 * CASE 3: confirmed record found with matching name, principal,
360 * and an unconfirmed record is found with matching
361 * name, principal, and with clientid and
362 * confirm that does not match the confirmed record.
363 * CASE 4: there is no confirmed record with matching name and
364 * principal. there is an unconfirmed record with
365 * matching name, principal.
367 * an unconfirmed record is deleted when:
368 * CASE 1: an unconfirmed record that matches input name, verifier,
369 * and confirmed clientid.
370 * CASE 4: any unconfirmed records with matching name and principal
371 * that exist after an unconfirmed record has been replaced
372 * as described above.
376 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
378 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
379 struct xdr_netobj clname = {
380 .len = setclid->se_namelen,
381 .data = setclid->se_name,
383 nfs4_verifier clverifier = setclid->se_verf;
384 unsigned int strhashval;
385 struct nfs4_client * conf, * unconf, * new, * clp;
388 status = nfserr_inval;
389 if (!check_name(clname))
393 * XXX The Duplicate Request Cache (DRC) has been checked (??)
394 * We get here on a DRC miss.
397 strhashval = clientstr_hashval(clname.data, clname.len);
401 list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
402 if (!cmp_name(&clp->cl_name, &clname))
406 * clname match, confirmed, different principal
407 * or different ip_address
409 status = nfserr_clid_inuse;
410 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
411 printk("NFSD: setclientid: string in use by client"
412 "(clientid %08x/%08x)\n",
413 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
416 if (clp->cl_addr != ip_addr) {
417 printk("NFSD: setclientid: string in use by client"
418 "(clientid %08x/%08x)\n",
419 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
424 * cl_name match from a previous SETCLIENTID operation
425 * XXX check for additional matches?
431 list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
432 if (!cmp_name(&clp->cl_name, &clname))
434 /* cl_name match from a previous SETCLIENTID operation */
438 status = nfserr_resource;
442 * placed first, because it is the normal case.
445 expire_client(unconf);
446 if (!(new = create_client(clname)))
448 copy_verf(new, &clverifier);
449 new->cl_addr = ip_addr;
450 copy_cred(&new->cl_cred,&rqstp->rq_cred);
453 add_to_unconfirmed(new, strhashval);
454 } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
457 * cl_name match, confirmed, principal match
458 * verifier match: probable callback update
460 * remove any unconfirmed nfs4_client with
461 * matching cl_name, cl_verifier, and cl_clientid
463 * create and insert an unconfirmed nfs4_client with same
464 * cl_name, cl_verifier, and cl_clientid as existing
465 * nfs4_client, but with the new callback info and a
469 cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
470 cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
471 expire_client(unconf);
473 if (!(new = create_client(clname)))
475 copy_verf(new,&conf->cl_verifier);
476 new->cl_addr = ip_addr;
477 copy_cred(&new->cl_cred,&rqstp->rq_cred);
478 copy_clid(new, conf);
480 add_to_unconfirmed(new,strhashval);
481 } else if (!unconf) {
484 * clname match, confirmed, principal match
485 * verfier does not match
486 * no unconfirmed. create a new unconfirmed nfs4_client
487 * using input clverifier, clname, and callback info
488 * and generate a new cl_clientid and cl_confirm.
490 if (!(new = create_client(clname)))
492 copy_verf(new,&clverifier);
493 new->cl_addr = ip_addr;
494 copy_cred(&new->cl_cred,&rqstp->rq_cred);
497 add_to_unconfirmed(new, strhashval);
498 } else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
499 !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
502 * confirmed found (name, principal match)
503 * confirmed verifier does not match input clverifier
505 * unconfirmed found (name match)
506 * confirmed->cl_clientid != unconfirmed->cl_clientid and
507 * confirmed->cl_confirm != unconfirmed->cl_confirm
509 * remove unconfirmed.
511 * create an unconfirmed nfs4_client
512 * with same cl_name as existing confirmed nfs4_client,
513 * but with new callback info, new cl_clientid,
514 * new cl_verifier and a new cl_confirm
516 expire_client(unconf);
517 if (!(new = create_client(clname)))
519 copy_verf(new,&clverifier);
520 new->cl_addr = ip_addr;
521 copy_cred(&new->cl_cred,&rqstp->rq_cred);
524 add_to_unconfirmed(new, strhashval);
526 /* No cases hit !!! */
527 status = nfserr_inval;
531 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
532 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
533 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
534 printk(KERN_INFO "NFSD: this client will not receive delegations\n");
543 * RFC 3010 has a complex implmentation description of processing a
544 * SETCLIENTID_CONFIRM request consisting of 4 bullets describing
545 * processing on a DRC miss, labeled as CASE1 - CASE4 below.
547 * NOTE: callback information will be processed here in a future patch
550 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
552 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
553 unsigned int idhashval;
554 struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
555 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
556 clientid_t * clid = &setclientid_confirm->sc_clientid;
559 status = nfserr_stale_clientid;
560 if (STALE_CLIENTID(clid))
563 * XXX The Duplicate Request Cache (DRC) has been checked (??)
564 * We get here on a DRC miss.
567 idhashval = clientid_hashval(clid->cl_id);
569 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
570 if (!cmp_clid(&clp->cl_clientid, clid))
573 status = nfserr_inval;
575 * Found a record for this clientid. If the IP addresses
576 * don't match, return ERR_INVAL just as if the record had
579 if (clp->cl_addr != ip_addr) {
580 printk("NFSD: setclientid: string in use by client"
581 "(clientid %08x/%08x)\n",
582 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
588 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
589 if (!cmp_clid(&clp->cl_clientid, clid))
591 status = nfserr_inval;
592 if (clp->cl_addr != ip_addr) {
593 printk("NFSD: setclientid: string in use by client"
594 "(clientid %08x/%08x)\n",
595 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
602 * unconf record that matches input clientid and input confirm.
603 * conf record that matches input clientid.
604 * conf and unconf records match names, verifiers
606 if ((conf && unconf) &&
607 (cmp_verf(&unconf->cl_confirm, &confirm)) &&
608 (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
609 (cmp_name(&conf->cl_name,&unconf->cl_name)) &&
610 (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
611 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred))
612 status = nfserr_clid_inuse;
615 move_to_confirmed(unconf, idhashval);
621 * conf record that matches input clientid.
622 * if unconf record that matches input clientid, then unconf->cl_name
623 * or unconf->cl_verifier don't match the conf record.
625 if ((conf && !unconf) ||
627 (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
628 !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
629 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
630 status = nfserr_clid_inuse;
637 * conf record not found.
638 * unconf record found.
639 * unconf->cl_confirm matches input confirm
641 if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
642 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
643 status = nfserr_clid_inuse;
646 move_to_confirmed(unconf, idhashval);
651 * conf record not found, or if conf, then conf->cl_confirm does not
652 * match input confirm.
653 * unconf record not found, or if unconf, then unconf->cl_confirm
654 * does not match input confirm.
656 if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
657 (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
658 status = nfserr_stale_clientid;
661 /* check that we have hit one of the cases...*/
662 status = nfserr_inval;
665 /* XXX if status == nfs_ok, probe callback path */
671 * Open owner state (share locks)
674 /* hash tables for nfs4_stateowner */
675 #define OWNER_HASH_BITS 8
676 #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS)
677 #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1)
679 #define ownerid_hashval(id) \
680 ((id) & OWNER_HASH_MASK)
681 #define ownerstr_hashval(clientid, ownername) \
682 (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
684 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
685 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
687 /* hash table for nfs4_file */
688 #define FILE_HASH_BITS 8
689 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
690 #define FILE_HASH_MASK (FILE_HASH_SIZE - 1)
691 /* hash table for (open)nfs4_stateid */
692 #define STATEID_HASH_BITS 10
693 #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
694 #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1)
696 #define file_hashval(x) \
697 hash_ptr(x, FILE_HASH_BITS)
698 #define stateid_hashval(owner_id, file_id) \
699 (((owner_id) + (file_id)) & STATEID_HASH_MASK)
701 static struct list_head file_hashtbl[FILE_HASH_SIZE];
702 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
704 /* OPEN Share state helper functions */
705 static inline struct nfs4_file *
706 alloc_init_file(unsigned int hashval, struct inode *ino) {
707 struct nfs4_file *fp;
708 if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
709 INIT_LIST_HEAD(&fp->fi_hash);
710 INIT_LIST_HEAD(&fp->fi_perfile);
711 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
712 fp->fi_inode = igrab(ino);
713 fp->fi_id = current_fileid++;
717 return (struct nfs4_file *)NULL;
721 release_all_files(void)
724 struct nfs4_file *fp;
726 for (i=0;i<FILE_HASH_SIZE;i++) {
727 while (!list_empty(&file_hashtbl[i])) {
728 fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
729 /* this should never be more than once... */
730 if(!list_empty(&fp->fi_perfile)) {
731 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
738 static inline struct nfs4_stateowner *
739 alloc_stateowner(struct xdr_netobj *owner)
741 struct nfs4_stateowner *sop;
743 if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
744 if((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
745 memcpy(sop->so_owner.data, owner->data, owner->len);
746 sop->so_owner.len = owner->len;
751 return (struct nfs4_stateowner *)NULL;
754 /* should use a slab cache */
756 free_stateowner(struct nfs4_stateowner *sop) {
758 kfree(sop->so_owner.data);
765 static struct nfs4_stateowner *
766 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
767 struct nfs4_stateowner *sop;
768 struct nfs4_replay *rp;
769 unsigned int idhashval;
771 if (!(sop = alloc_stateowner(&open->op_owner)))
772 return (struct nfs4_stateowner *)NULL;
773 idhashval = ownerid_hashval(current_ownerid);
774 INIT_LIST_HEAD(&sop->so_idhash);
775 INIT_LIST_HEAD(&sop->so_strhash);
776 INIT_LIST_HEAD(&sop->so_perclient);
777 INIT_LIST_HEAD(&sop->so_perfilestate);
778 INIT_LIST_HEAD(&sop->so_perlockowner); /* not used */
779 INIT_LIST_HEAD(&sop->so_close_lru);
781 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
782 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
783 list_add(&sop->so_perclient, &clp->cl_perclient);
785 sop->so_is_open_owner = 1;
786 sop->so_id = current_ownerid++;
787 sop->so_client = clp;
788 sop->so_seqid = open->op_seqid;
789 sop->so_confirmed = 0;
790 rp = &sop->so_replay;
791 rp->rp_status = NFSERR_SERVERFAULT;
793 rp->rp_buf = rp->rp_ibuf;
799 release_stateid_lockowner(struct nfs4_stateid *open_stp)
801 struct nfs4_stateowner *lock_sop;
803 while (!list_empty(&open_stp->st_perlockowner)) {
804 lock_sop = list_entry(open_stp->st_perlockowner.next,
805 struct nfs4_stateowner, so_perlockowner);
806 /* list_del(&open_stp->st_perlockowner); */
807 BUG_ON(lock_sop->so_is_open_owner);
808 release_stateowner(lock_sop);
813 release_stateowner(struct nfs4_stateowner *sop)
815 struct nfs4_stateid *stp;
817 list_del(&sop->so_idhash);
818 list_del(&sop->so_strhash);
819 list_del(&sop->so_perclient);
820 list_del(&sop->so_perlockowner);
821 list_del(&sop->so_close_lru);
823 while (!list_empty(&sop->so_perfilestate)) {
824 stp = list_entry(sop->so_perfilestate.next,
825 struct nfs4_stateid, st_perfilestate);
826 if(sop->so_is_open_owner)
827 release_stateid(stp, OPEN_STATE);
829 release_stateid(stp, LOCK_STATE);
831 free_stateowner(sop);
835 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
836 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
838 INIT_LIST_HEAD(&stp->st_hash);
839 INIT_LIST_HEAD(&stp->st_perfilestate);
840 INIT_LIST_HEAD(&stp->st_perlockowner);
841 INIT_LIST_HEAD(&stp->st_perfile);
842 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
843 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
845 list_add(&stp->st_perfile, &fp->fi_perfile);
846 stp->st_stateowner = sop;
848 stp->st_stateid.si_boot = boot_time;
849 stp->st_stateid.si_stateownerid = sop->so_id;
850 stp->st_stateid.si_fileid = fp->fi_id;
851 stp->st_stateid.si_generation = 0;
852 stp->st_access_bmap = 0;
853 stp->st_deny_bmap = 0;
854 __set_bit(open->op_share_access, &stp->st_access_bmap);
855 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
859 release_stateid(struct nfs4_stateid *stp, int flags) {
861 list_del(&stp->st_hash);
863 list_del(&stp->st_perfile);
864 list_del(&stp->st_perfilestate);
865 if((stp->st_vfs_set) && (flags & OPEN_STATE)) {
866 release_stateid_lockowner(stp);
867 nfsd_close(&stp->st_vfs_file);
869 dput(stp->st_vfs_file.f_dentry);
870 mntput(stp->st_vfs_file.f_vfsmnt);
871 } else if ((stp->st_vfs_set) && (flags & LOCK_STATE)) {
872 struct file *filp = &stp->st_vfs_file;
874 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
881 release_file(struct nfs4_file *fp)
884 list_del(&fp->fi_hash);
890 move_to_close_lru(struct nfs4_stateowner *sop)
892 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
893 /* remove stateowner from all other hash lists except perclient */
894 list_del_init(&sop->so_idhash);
895 list_del_init(&sop->so_strhash);
896 list_del_init(&sop->so_perlockowner);
898 list_add_tail(&sop->so_close_lru, &close_lru);
899 sop->so_time = get_seconds();
903 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
906 struct nfs4_stateowner *sop = stp->st_stateowner;
907 struct nfs4_file *fp = stp->st_file;
909 dprintk("NFSD: release_state_owner\n");
910 release_stateid(stp, flag);
912 /* place unused nfs4_stateowners on so_close_lru list to be
913 * released by the laundromat service after the lease period
914 * to enable us to handle CLOSE replay
916 if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
917 move_to_close_lru(sop);
918 /* unused nfs4_file's are releseed. XXX slab cache? */
919 if (list_empty(&fp->fi_perfile)) {
925 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
926 return ((sop->so_owner.len == owner->len) &&
927 !memcmp(sop->so_owner.data, owner->data, owner->len) &&
928 (sop->so_client->cl_clientid.cl_id == clid->cl_id));
931 /* search ownerstr_hashtbl[] for owner */
933 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
934 struct nfs4_stateowner *local = NULL;
936 list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) {
937 if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid))
945 /* see if clientid is in confirmed hash table */
947 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
949 struct nfs4_client *clp;
950 unsigned int idhashval = clientid_hashval(clid->cl_id);
952 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
953 if (!cmp_clid(&clp->cl_clientid, clid))
962 /* search file_hashtbl[] for file */
964 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
965 struct nfs4_file *local = NULL;
967 list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) {
968 if (local->fi_inode == ino) {
976 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
977 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
980 set_access(unsigned int *access, unsigned long bmap) {
984 for (i = 1; i < 4; i++) {
985 if(test_bit(i, &bmap))
991 set_deny(unsigned int *deny, unsigned long bmap) {
995 for (i = 0; i < 4; i++) {
996 if(test_bit(i, &bmap))
1002 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1003 unsigned int access, deny;
1005 set_access(&access, stp->st_access_bmap);
1006 set_deny(&deny, stp->st_deny_bmap);
1007 if ((access & open->op_share_deny) || (deny & open->op_share_access))
1013 * Called to check deny when READ with all zero stateid or
1014 * WRITE with all zero or all one stateid
1017 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1019 struct inode *ino = current_fh->fh_dentry->d_inode;
1020 unsigned int fi_hashval;
1021 struct nfs4_file *fp;
1022 struct nfs4_stateid *stp;
1024 dprintk("NFSD: nfs4_share_conflict\n");
1026 fi_hashval = file_hashval(ino);
1027 if (find_file(fi_hashval, ino, &fp)) {
1028 /* Search for conflicting share reservations */
1029 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
1030 if (test_bit(deny_type, &stp->st_deny_bmap) ||
1031 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1032 return nfserr_share_denied;
1039 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
1043 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1044 status = get_write_access(filp->f_dentry->d_inode);
1046 filp->f_mode = FMODE_WRITE;
1048 return nfserrno(status);
1054 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1056 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1057 put_write_access(filp->f_dentry->d_inode);
1058 filp->f_mode = FMODE_READ;
1064 * nfsd4_process_open1()
1065 * lookup stateowner.
1077 * called with nfs4_lock_state() held.
1080 nfsd4_process_open1(struct nfsd4_open *open)
1083 clientid_t *clientid = &open->op_clientid;
1084 struct nfs4_client *clp = NULL;
1085 unsigned int strhashval;
1086 struct nfs4_stateowner *sop = NULL;
1088 status = nfserr_inval;
1089 if (!check_name(open->op_owner))
1092 status = nfserr_stale_clientid;
1093 if (STALE_CLIENTID(&open->op_clientid))
1096 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1097 if (find_openstateowner_str(strhashval, open, &sop)) {
1098 open->op_stateowner = sop;
1099 /* check for replay */
1100 if (open->op_seqid == sop->so_seqid){
1101 if (!sop->so_replay.rp_buflen) {
1103 * The original OPEN failed in so spectacularly that we
1104 * don't even have replay data saved! Therefore, we
1105 * have no choice but to continue processing
1106 * this OPEN; presumably, we'll fail again for the same
1109 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1113 /* replay: indicate to calling function */
1114 status = NFSERR_REPLAY_ME;
1117 if (sop->so_confirmed) {
1118 if (open->op_seqid == sop->so_seqid + 1) {
1122 status = nfserr_bad_seqid;
1125 /* If we get here, we received and OPEN for an unconfirmed
1127 * Since the sequid's are different, purge the
1128 * existing nfs4_stateowner, and instantiate a new one.
1130 clp = sop->so_client;
1131 release_stateowner(sop);
1132 goto instantiate_new_owner;
1134 /* nfs4_stateowner not found.
1135 * verify clientid and instantiate new nfs4_stateowner
1136 * if verify fails this is presumably the result of the
1137 * client's lease expiring.
1139 * XXX compare clp->cl_addr with rqstp addr?
1141 status = nfserr_expired;
1142 if (!verify_clientid(&clp, clientid))
1144 instantiate_new_owner:
1145 status = nfserr_resource;
1146 if (!(sop = alloc_init_open_stateowner(strhashval, clp, open)))
1148 open->op_stateowner = sop;
1151 renew_client(sop->so_client);
1153 if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1154 status = nfserr_reclaim_bad;
1158 * called with nfs4_lock_state() held.
1161 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1164 struct nfs4_stateowner *sop = open->op_stateowner;
1165 struct nfs4_file *fp = NULL;
1167 unsigned int fi_hashval;
1168 struct nfs4_stateid *stq, *stp = NULL;
1171 status = nfserr_resource;
1175 ino = current_fh->fh_dentry->d_inode;
1177 status = nfserr_inval;
1178 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1181 fi_hashval = file_hashval(ino);
1182 if (find_file(fi_hashval, ino, &fp)) {
1183 /* Search for conflicting share reservations */
1184 status = nfserr_share_denied;
1185 list_for_each_entry(stq, &fp->fi_perfile, st_perfile) {
1186 if(stq->st_stateowner == sop) {
1190 /* ignore lock owners */
1191 if (stq->st_stateowner->so_is_open_owner == 0)
1193 if (!test_share(stq,open))
1197 /* No nfs4_file found; allocate and init a new one */
1198 status = nfserr_resource;
1199 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1206 status = nfserr_resource;
1207 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1208 GFP_KERNEL)) == NULL)
1211 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1215 if ((status = nfsd_open(rqstp, current_fh, S_IFREG,
1217 &stp->st_vfs_file)) != 0)
1221 dget(stp->st_vfs_file.f_dentry);
1222 mntget(stp->st_vfs_file.f_vfsmnt);
1224 init_stateid(stp, fp, sop, open);
1225 stp->st_vfs_set = 1;
1227 /* This is an upgrade of an existing OPEN.
1228 * OR the incoming share with the existing
1229 * nfs4_stateid share */
1230 unsigned int share_access;
1232 set_access(&share_access, stp->st_access_bmap);
1233 share_access = ~share_access;
1234 share_access &= open->op_share_access;
1236 /* update the struct file */
1237 if ((status = nfs4_file_upgrade(&stp->st_vfs_file, share_access)))
1239 /* remember the open */
1240 set_bit(open->op_share_access, &stp->st_access_bmap);
1241 set_bit(open->op_share_deny, &stp->st_deny_bmap);
1242 /* bump the stateid */
1243 update_stateid(&stp->st_stateid);
1245 dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1246 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1247 stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1249 if (open->op_truncate) {
1250 iattr.ia_valid = ATTR_SIZE;
1252 status = nfsd_setattr(rqstp, current_fh, &iattr, 0, (time_t)0);
1256 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1258 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
1261 if (fp && list_empty(&fp->fi_perfile))
1264 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
1266 status = nfserr_reclaim_bad;
1268 /* successful reclaim. so_seqid is decremented because
1269 * it will be bumped in encode_open
1271 open->op_stateowner->so_confirmed = 1;
1272 open->op_stateowner->so_seqid--;
1276 * To finish the open response, we just need to set the rflags.
1278 open->op_rflags = 0;
1279 if (!open->op_stateowner->so_confirmed)
1280 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1288 static struct work_struct laundromat_work;
1289 static void laundromat_main(void *);
1290 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1293 nfsd4_renew(clientid_t *clid)
1295 struct nfs4_client *clp;
1296 unsigned int idhashval;
1300 dprintk("process_renew(%08x/%08x): starting\n",
1301 clid->cl_boot, clid->cl_id);
1302 status = nfserr_stale_clientid;
1303 if (STALE_CLIENTID(clid))
1306 idhashval = clientid_hashval(clid->cl_id);
1307 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1308 if (!cmp_clid(&clp->cl_clientid, clid))
1313 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1314 if (!cmp_clid(&clp->cl_clientid, clid))
1320 * Couldn't find an nfs4_client for this clientid.
1321 * Presumably this is because the client took too long to
1322 * RENEW, so return NFS4ERR_EXPIRED.
1324 dprintk("nfsd4_renew: clientid not found!\n");
1325 status = nfserr_expired;
1327 nfs4_unlock_state();
1332 nfs4_laundromat(void)
1334 struct nfs4_client *clp;
1335 struct nfs4_stateowner *sop;
1336 struct list_head *pos, *next;
1337 time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1338 time_t t, clientid_val = NFSD_LEASE_TIME;
1339 time_t u, close_val = NFSD_LEASE_TIME;
1343 dprintk("NFSD: laundromat service - starting, examining clients\n");
1344 list_for_each_safe(pos, next, &client_lru) {
1345 clp = list_entry(pos, struct nfs4_client, cl_lru);
1346 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1347 t = clp->cl_time - cutoff;
1348 if (clientid_val > t)
1352 dprintk("NFSD: purging unused client (clientid %08x)\n",
1353 clp->cl_clientid.cl_id);
1356 list_for_each_safe(pos, next, &close_lru) {
1357 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
1358 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
1359 u = sop->so_time - cutoff;
1364 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1366 release_stateowner(sop);
1368 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1369 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1370 nfs4_unlock_state();
1371 return clientid_val;
1375 laundromat_main(void *not_used)
1379 t = nfs4_laundromat();
1380 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1381 schedule_delayed_work(&laundromat_work, t*HZ);
1384 /* search ownerid_hashtbl[] and close_lru for stateid owner
1385 * (stateid->si_stateownerid)
1387 struct nfs4_stateowner *
1388 find_openstateowner_id(u32 st_id, int flags) {
1389 struct nfs4_stateowner *local = NULL;
1391 dprintk("NFSD: find_openstateowner_id %d\n", st_id);
1392 if (flags & CLOSE_STATE) {
1393 list_for_each_entry(local, &close_lru, so_close_lru) {
1394 if(local->so_id == st_id)
1402 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1404 return (stp->st_vfs_set == 0 ||
1405 fhp->fh_dentry->d_inode != stp->st_vfs_file.f_dentry->d_inode);
1409 STALE_STATEID(stateid_t *stateid)
1411 if (stateid->si_boot == boot_time)
1413 printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1414 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1415 stateid->si_generation);
1421 * Checks for stateid operations
1424 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
1426 struct nfs4_stateid *stp;
1429 dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
1430 stateid->si_boot, stateid->si_stateownerid,
1431 stateid->si_fileid, stateid->si_generation);
1436 status = nfserr_stale_stateid;
1437 if (STALE_STATEID(stateid))
1441 status = nfserr_bad_stateid;
1442 if (!(stp = find_stateid(stateid, flags))) {
1443 dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
1446 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1447 dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
1448 stp->st_vfs_set = 0;
1451 if (!stp->st_stateowner->so_confirmed) {
1452 dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
1455 if (stateid->si_generation > stp->st_stateid.si_generation) {
1456 dprintk("preprocess_stateid_op: future stateid?!\n");
1461 status = nfserr_old_stateid;
1462 if (stateid->si_generation < stp->st_stateid.si_generation) {
1463 dprintk("preprocess_stateid_op: old stateid!\n");
1468 renew_client(stp->st_stateowner->so_client);
1475 * Checks for sequence id mutating operations.
1478 nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid)
1481 struct nfs4_stateid *stp;
1482 struct nfs4_stateowner *sop;
1484 dprintk("NFSD: preprocess_seqid_op: seqid=%d "
1485 "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
1486 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1487 stateid->si_generation);
1492 status = nfserr_bad_stateid;
1493 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
1494 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
1498 status = nfserr_stale_stateid;
1499 if (STALE_STATEID(stateid))
1502 * We return BAD_STATEID if filehandle doesn't match stateid,
1503 * the confirmed flag is incorrecly set, or the generation
1504 * number is incorrect.
1505 * If there is no entry in the openfile table for this id,
1506 * we can't always return BAD_STATEID;
1507 * this might be a retransmitted CLOSE which has arrived after
1508 * the openfile has been released.
1510 if (!(stp = find_stateid(stateid, flags)))
1511 goto no_nfs4_stateid;
1513 status = nfserr_bad_stateid;
1515 /* for new lock stateowners, check that the lock->v.new.open_stateid
1516 * refers to an open stateowner, and that the lockclid
1517 * (nfs4_lock->v.new.clientid) is the same as the
1518 * open_stateid->st_stateowner->so_client->clientid
1521 struct nfs4_stateowner *sop = stp->st_stateowner;
1522 struct nfs4_client *clp = sop->so_client;
1524 if (!sop->so_is_open_owner)
1526 if (!cmp_clid(&clp->cl_clientid, lockclid))
1530 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1531 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
1532 stp->st_vfs_set = 0;
1537 *sopp = sop = stp->st_stateowner;
1540 * We now validate the seqid and stateid generation numbers.
1541 * For the moment, we ignore the possibility of
1542 * generation number wraparound.
1544 if (seqid != sop->so_seqid + 1)
1547 if (sop->so_confirmed) {
1548 if (flags & CONFIRM) {
1549 printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
1554 if (!(flags & CONFIRM)) {
1555 printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
1559 if (stateid->si_generation > stp->st_stateid.si_generation) {
1560 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
1564 status = nfserr_old_stateid;
1565 if (stateid->si_generation < stp->st_stateid.si_generation) {
1566 printk("NFSD: preprocess_seqid_op: old stateid!\n");
1569 /* XXX renew the client lease here */
1578 * We determine whether this is a bad stateid or a replay,
1579 * starting by trying to look up the stateowner.
1580 * If stateowner is not found - stateid is bad.
1582 if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
1583 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
1584 status = nfserr_bad_stateid;
1590 if (seqid == sop->so_seqid) {
1591 printk("NFSD: preprocess_seqid_op: retransmission?\n");
1592 /* indicate replay to calling function */
1593 status = NFSERR_REPLAY_ME;
1595 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
1598 status = nfserr_bad_seqid;
1604 * nfs4_unlock_state(); called in encode
1607 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
1610 struct nfs4_stateowner *sop;
1611 struct nfs4_stateid *stp;
1613 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
1614 (int)current_fh->fh_dentry->d_name.len,
1615 current_fh->fh_dentry->d_name.name);
1617 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
1620 oc->oc_stateowner = NULL;
1623 if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
1624 &oc->oc_req_stateid,
1625 CHECK_FH | CONFIRM | OPEN_STATE,
1626 &oc->oc_stateowner, &stp, NULL)))
1629 sop = oc->oc_stateowner;
1630 sop->so_confirmed = 1;
1631 update_stateid(&stp->st_stateid);
1632 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
1633 dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d "
1634 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
1635 stp->st_stateid.si_boot,
1636 stp->st_stateid.si_stateownerid,
1637 stp->st_stateid.si_fileid,
1638 stp->st_stateid.si_generation);
1646 * unset all bits in union bitmap (bmap) that
1647 * do not exist in share (from successful OPEN_DOWNGRADE)
1650 reset_union_bmap_access(unsigned long access, unsigned long *bmap)
1653 for (i = 1; i < 4; i++) {
1654 if ((i & access) != i)
1655 __clear_bit(i, bmap);
1660 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
1663 for (i = 0; i < 4; i++) {
1664 if ((i & deny) != i)
1665 __clear_bit(i, bmap);
1670 * nfs4_unlock_state(); called in encode
1674 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
1677 struct nfs4_stateid *stp;
1678 unsigned int share_access;
1680 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
1681 (int)current_fh->fh_dentry->d_name.len,
1682 current_fh->fh_dentry->d_name.name);
1684 od->od_stateowner = NULL;
1685 status = nfserr_inval;
1686 if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
1690 if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid,
1692 CHECK_FH | OPEN_STATE,
1693 &od->od_stateowner, &stp, NULL)))
1696 status = nfserr_inval;
1697 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
1698 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
1699 stp->st_access_bmap, od->od_share_access);
1702 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) {
1703 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
1704 stp->st_deny_bmap, od->od_share_deny);
1707 set_access(&share_access, stp->st_access_bmap);
1708 nfs4_file_downgrade(&stp->st_vfs_file,
1709 share_access & ~od->od_share_access);
1711 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
1712 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
1714 update_stateid(&stp->st_stateid);
1715 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
1722 * nfs4_unlock_state() called after encode
1725 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
1728 struct nfs4_stateid *stp;
1730 dprintk("NFSD: nfsd4_close on file %.*s\n",
1731 (int)current_fh->fh_dentry->d_name.len,
1732 current_fh->fh_dentry->d_name.name);
1734 close->cl_stateowner = NULL;
1736 /* check close_lru for replay */
1737 if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid,
1739 CHECK_FH | OPEN_STATE | CLOSE_STATE,
1740 &close->cl_stateowner, &stp, NULL)))
1743 * Return success, but first update the stateid.
1746 update_stateid(&stp->st_stateid);
1747 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
1749 /* release_state_owner() calls nfsd_close() if needed */
1750 release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
1756 * Lock owner state (byte-range locks)
1758 #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
1759 #define LOCK_HASH_BITS 8
1760 #define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS)
1761 #define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1)
1763 #define lockownerid_hashval(id) \
1764 ((id) & LOCK_HASH_MASK)
1765 #define lock_ownerstr_hashval(x, clientid, ownername) \
1766 ((file_hashval(x) + (clientid) + opaque_hashval((ownername.data), (ownername.len))) & LOCK_HASH_MASK)
1768 static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
1769 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
1770 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
1772 struct nfs4_stateid *
1773 find_stateid(stateid_t *stid, int flags)
1775 struct nfs4_stateid *local = NULL;
1776 u32 st_id = stid->si_stateownerid;
1777 u32 f_id = stid->si_fileid;
1778 unsigned int hashval;
1780 dprintk("NFSD: find_stateid flags 0x%x\n",flags);
1781 if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
1782 hashval = stateid_hashval(st_id, f_id);
1783 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
1784 if((local->st_stateid.si_stateownerid == st_id) &&
1785 (local->st_stateid.si_fileid == f_id))
1789 if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
1790 hashval = stateid_hashval(st_id, f_id);
1791 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
1792 if((local->st_stateid.si_stateownerid == st_id) &&
1793 (local->st_stateid.si_fileid == f_id))
1797 printk("NFSD: find_stateid: ERROR: no state flag\n");
1803 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
1804 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
1805 * byte, because of sign extension problems. Since NFSv4 calls for 64-bit
1806 * locking, this prevents us from being completely protocol-compliant. The
1807 * real solution to this problem is to start using unsigned file offsets in
1808 * the VFS, but this is a very deep change!
1811 nfs4_transform_lock_offset(struct file_lock *lock)
1813 if (lock->fl_start < 0)
1814 lock->fl_start = OFFSET_MAX;
1815 if (lock->fl_end < 0)
1816 lock->fl_end = OFFSET_MAX;
1820 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
1822 struct nfs4_stateowner *local = NULL;
1825 if (hashval >= LOCK_HASH_SIZE)
1827 list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
1839 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
1841 struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
1843 deny->ld_sop = NULL;
1844 if (nfs4_verify_lock_stateowner(sop, fl->fl_pid))
1846 deny->ld_start = fl->fl_start;
1847 deny->ld_length = ~(u64)0;
1848 if (fl->fl_end != ~(u64)0)
1849 deny->ld_length = fl->fl_end - fl->fl_start + 1;
1850 deny->ld_type = NFS4_READ_LT;
1851 if (fl->fl_type != F_RDLCK)
1852 deny->ld_type = NFS4_WRITE_LT;
1857 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
1858 struct nfs4_stateowner *local = NULL;
1860 list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) {
1861 if(!cmp_owner_str(local, owner, clid))
1871 * Alloc a lock owner structure.
1872 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
1875 * strhashval = lock_ownerstr_hashval
1876 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
1879 static struct nfs4_stateowner *
1880 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
1881 struct nfs4_stateowner *sop;
1882 struct nfs4_replay *rp;
1883 unsigned int idhashval;
1885 if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
1886 return (struct nfs4_stateowner *)NULL;
1887 idhashval = lockownerid_hashval(current_ownerid);
1888 INIT_LIST_HEAD(&sop->so_idhash);
1889 INIT_LIST_HEAD(&sop->so_strhash);
1890 INIT_LIST_HEAD(&sop->so_perclient);
1891 INIT_LIST_HEAD(&sop->so_perfilestate);
1892 INIT_LIST_HEAD(&sop->so_perlockowner);
1893 INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
1895 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
1896 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
1897 list_add(&sop->so_perclient, &clp->cl_perclient);
1898 list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
1900 sop->so_is_open_owner = 0;
1901 sop->so_id = current_ownerid++;
1902 sop->so_client = clp;
1903 sop->so_seqid = lock->lk_new_lock_seqid - 1;
1904 sop->so_confirmed = 1;
1905 rp = &sop->so_replay;
1906 rp->rp_status = NFSERR_SERVERFAULT;
1908 rp->rp_buf = rp->rp_ibuf;
1913 struct nfs4_stateid *
1914 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
1916 struct nfs4_stateid *stp;
1917 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
1919 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1920 GFP_KERNEL)) == NULL)
1922 INIT_LIST_HEAD(&stp->st_hash);
1923 INIT_LIST_HEAD(&stp->st_perfile);
1924 INIT_LIST_HEAD(&stp->st_perfilestate);
1925 INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
1926 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
1927 list_add(&stp->st_perfile, &fp->fi_perfile);
1929 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
1930 stp->st_stateowner = sop;
1932 stp->st_stateid.si_boot = boot_time;
1933 stp->st_stateid.si_stateownerid = sop->so_id;
1934 stp->st_stateid.si_fileid = fp->fi_id;
1935 stp->st_stateid.si_generation = 0;
1936 stp->st_vfs_file = open_stp->st_vfs_file;
1937 stp->st_vfs_set = open_stp->st_vfs_set;
1938 stp->st_access_bmap = open_stp->st_access_bmap;
1939 stp->st_deny_bmap = open_stp->st_deny_bmap;
1946 check_lock_length(u64 offset, u64 length)
1948 return ((length == 0) || ((length != ~(u64)0) &&
1949 LOFF_OVERFLOW(offset, length)));
1955 * nfs4_unlock_state(); called in encode
1958 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
1960 struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
1961 struct nfs4_stateid *lock_stp;
1963 struct file_lock file_lock;
1964 struct file_lock *conflock;
1966 unsigned int strhashval;
1968 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
1969 (long long) lock->lk_offset,
1970 (long long) lock->lk_length);
1972 if (nfs4_in_grace() && !lock->lk_reclaim)
1973 return nfserr_grace;
1974 if (nfs4_in_no_grace() && lock->lk_reclaim)
1975 return nfserr_no_grace;
1977 if (check_lock_length(lock->lk_offset, lock->lk_length))
1978 return nfserr_inval;
1980 lock->lk_stateowner = NULL;
1983 if (lock->lk_is_new) {
1985 * Client indicates that this is a new lockowner.
1986 * Use open owner and open stateid to create lock owner and lock
1989 struct nfs4_stateid *open_stp = NULL;
1990 struct nfs4_file *fp;
1992 status = nfserr_stale_clientid;
1993 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
1994 printk("NFSD: nfsd4_lock: clientid is stale!\n");
1997 /* does the clientid in the lock owner own the open stateid? */
1999 /* validate and update open stateid and open seqid */
2000 status = nfs4_preprocess_seqid_op(current_fh,
2001 lock->lk_new_open_seqid,
2002 &lock->lk_new_open_stateid,
2003 CHECK_FH | OPEN_STATE,
2004 &open_sop, &open_stp,
2005 &lock->v.new.clientid);
2007 if (lock->lk_reclaim)
2008 status = nfserr_reclaim_bad;
2011 /* create lockowner and lock stateid */
2012 fp = open_stp->st_file;
2013 strhashval = lock_ownerstr_hashval(fp->fi_inode,
2014 open_sop->so_client->cl_clientid.cl_id,
2018 * If we already have this lock owner, the client is in
2019 * error (or our bookeeping is wrong!)
2020 * for asking for a 'new lock'.
2022 status = nfserr_bad_stateid;
2023 if (find_lockstateowner_str(strhashval, &lock->v.new.owner,
2024 &lock->v.new.clientid, &lock_sop))
2026 status = nfserr_resource;
2027 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2029 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner,
2030 fp, open_stp)) == NULL)
2032 /* bump the open seqid used to create the lock */
2033 open_sop->so_seqid++;
2035 /* lock (lock owner + lock stateid) already exists */
2036 status = nfs4_preprocess_seqid_op(current_fh,
2037 lock->lk_old_lock_seqid,
2038 &lock->lk_old_lock_stateid,
2039 CHECK_FH | LOCK_STATE,
2040 &lock->lk_stateowner, &lock_stp, NULL);
2044 /* lock->lk_stateowner and lock_stp have been created or found */
2045 filp = &lock_stp->st_vfs_file;
2047 if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2048 printk("NFSD: nfsd4_lock: permission denied!\n");
2052 switch (lock->lk_type) {
2055 file_lock.fl_type = F_RDLCK;
2058 case NFS4_WRITEW_LT:
2059 file_lock.fl_type = F_WRLCK;
2062 status = nfserr_inval;
2065 file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
2066 file_lock.fl_pid = lockownerid_hashval(lock->lk_stateowner->so_id);
2067 file_lock.fl_file = filp;
2068 file_lock.fl_flags = FL_POSIX;
2069 file_lock.fl_notify = NULL;
2070 file_lock.fl_insert = NULL;
2071 file_lock.fl_remove = NULL;
2073 file_lock.fl_start = lock->lk_offset;
2074 if ((lock->lk_length == ~(u64)0) ||
2075 LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
2076 file_lock.fl_end = ~(u64)0;
2078 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
2079 nfs4_transform_lock_offset(&file_lock);
2082 * Try to lock the file in the VFS.
2083 * Note: locks.c uses the BKL to protect the inode's lock list.
2086 status = posix_lock_file(filp, &file_lock);
2087 dprintk("NFSD: nfsd4_lock: posix_test_lock passed. posix_lock_file status %d\n",status);
2089 case 0: /* success! */
2090 update_stateid(&lock_stp->st_stateid);
2091 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid,
2095 goto conflicting_lock;
2097 status = nfserr_deadlock;
2099 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
2100 goto out_destroy_new_stateid;
2104 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2105 status = nfserr_denied;
2106 /* XXX There is a race here. Future patch needed to provide
2107 * an atomic posix_lock_and_test_file
2109 if (!(conflock = posix_test_lock(filp, &file_lock))) {
2110 status = nfserr_serverfault;
2113 nfs4_set_lock_denied(conflock, &lock->lk_denied);
2115 out_destroy_new_stateid:
2116 if (lock->lk_is_new) {
2117 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2119 * An error encountered after instantiation of the new
2120 * stateid has forced us to destroy it.
2122 if (!seqid_mutating_err(status))
2123 open_sop->so_seqid--;
2125 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
2135 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2137 struct inode *inode;
2138 struct nfs4_stateowner *sop;
2140 struct file_lock file_lock;
2141 struct file_lock *conflicting_lock;
2142 unsigned int strhashval;
2145 if (nfs4_in_grace())
2146 return nfserr_grace;
2148 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
2149 return nfserr_inval;
2151 lockt->lt_stateowner = NULL;
2154 status = nfserr_stale_clientid;
2155 if (STALE_CLIENTID(&lockt->lt_clientid)) {
2156 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2160 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2161 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2162 if (status == nfserr_symlink)
2163 status = nfserr_inval;
2167 inode = current_fh->fh_dentry->d_inode;
2168 switch (lockt->lt_type) {
2171 file_lock.fl_type = F_RDLCK;
2174 case NFS4_WRITEW_LT:
2175 file_lock.fl_type = F_WRLCK;
2178 printk("NFSD: nfs4_lockt: bad lock type!\n");
2179 status = nfserr_inval;
2183 strhashval = lock_ownerstr_hashval(inode,
2184 lockt->lt_clientid.cl_id, lockt->lt_owner);
2186 find_lockstateowner_str(strhashval, &lockt->lt_owner,
2187 &lockt->lt_clientid,
2188 &lockt->lt_stateowner);
2189 sop = lockt->lt_stateowner;
2191 file_lock.fl_owner = (fl_owner_t) sop;
2192 file_lock.fl_pid = lockownerid_hashval(sop->so_id);
2194 file_lock.fl_owner = NULL;
2195 file_lock.fl_pid = 0;
2197 file_lock.fl_flags = FL_POSIX;
2199 file_lock.fl_start = lockt->lt_offset;
2200 if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2201 file_lock.fl_end = ~(u64)0;
2203 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2205 nfs4_transform_lock_offset(&file_lock);
2207 /* posix_test_lock uses the struct file _only_ to resolve the inode.
2208 * since LOCKT doesn't require an OPEN, and therefore a struct
2209 * file may not exist, pass posix_test_lock a struct file with
2210 * only the dentry:inode set.
2212 memset(&file, 0, sizeof (struct file));
2213 file.f_dentry = current_fh->fh_dentry;
2216 conflicting_lock = posix_test_lock(&file, &file_lock);
2217 if (conflicting_lock) {
2218 status = nfserr_denied;
2219 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2222 nfs4_unlock_state();
2227 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2229 struct nfs4_stateid *stp;
2230 struct file *filp = NULL;
2231 struct file_lock file_lock;
2234 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2235 (long long) locku->lu_offset,
2236 (long long) locku->lu_length);
2238 if (check_lock_length(locku->lu_offset, locku->lu_length))
2239 return nfserr_inval;
2241 locku->lu_stateowner = NULL;
2244 if ((status = nfs4_preprocess_seqid_op(current_fh,
2247 CHECK_FH | LOCK_STATE,
2248 &locku->lu_stateowner, &stp, NULL)))
2251 filp = &stp->st_vfs_file;
2253 file_lock.fl_type = F_UNLCK;
2254 file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2255 file_lock.fl_pid = lockownerid_hashval(locku->lu_stateowner->so_id);
2256 file_lock.fl_file = filp;
2257 file_lock.fl_flags = FL_POSIX;
2258 file_lock.fl_notify = NULL;
2259 file_lock.fl_insert = NULL;
2260 file_lock.fl_remove = NULL;
2261 file_lock.fl_start = locku->lu_offset;
2263 if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2264 file_lock.fl_end = ~(u64)0;
2266 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2267 nfs4_transform_lock_offset(&file_lock);
2270 * Try to unlock the file in the VFS.
2272 status = posix_lock_file(filp, &file_lock);
2274 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2278 * OK, unlock succeeded; the only thing left to do is update the stateid.
2280 update_stateid(&stp->st_stateid);
2281 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2287 status = nfserrno(status);
2293 * 1: locks held by lockowner
2294 * 0: no locks held by lockowner
2297 check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
2299 struct file_lock **flpp;
2300 struct inode *inode = filp->f_dentry->d_inode;
2304 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
2305 if ((*flpp)->fl_owner == (fl_owner_t)lowner)
2315 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2317 clientid_t *clid = &rlockowner->rl_clientid;
2318 struct nfs4_stateowner *local = NULL;
2319 struct xdr_netobj *owner = &rlockowner->rl_owner;
2322 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2323 clid->cl_boot, clid->cl_id);
2325 /* XXX check for lease expiration */
2327 status = nfserr_stale_clientid;
2328 if (STALE_CLIENTID(clid)) {
2329 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2335 /* find the lockowner */
2337 for (i=0; i < LOCK_HASH_SIZE; i++) {
2338 list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) {
2339 if(cmp_owner_str(local, owner, clid))
2344 struct nfs4_stateid *stp;
2346 /* check for any locks held by any stateid associated with the
2347 * (lock) stateowner */
2348 status = nfserr_locks_held;
2349 list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) {
2350 if(stp->st_vfs_set) {
2351 if (check_for_locks(&stp->st_vfs_file, local))
2355 /* no locks held by (lock) stateowner */
2357 release_stateowner(local);
2360 nfs4_unlock_state();
2365 * Start and stop routines
2369 nfs4_state_init(void)
2372 time_t start = get_seconds();
2376 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2377 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
2378 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
2379 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
2380 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
2382 for (i = 0; i < FILE_HASH_SIZE; i++) {
2383 INIT_LIST_HEAD(&file_hashtbl[i]);
2385 for (i = 0; i < OWNER_HASH_SIZE; i++) {
2386 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
2387 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
2389 for (i = 0; i < STATEID_HASH_SIZE; i++) {
2390 INIT_LIST_HEAD(&stateid_hashtbl[i]);
2391 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
2393 for (i = 0; i < LOCK_HASH_SIZE; i++) {
2394 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
2395 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
2397 memset(&zerostateid, 0, sizeof(stateid_t));
2398 memset(&onestateid, ~0, sizeof(stateid_t));
2400 INIT_LIST_HEAD(&close_lru);
2401 INIT_LIST_HEAD(&client_lru);
2402 init_MUTEX(&client_sema);
2404 grace_end = start + NFSD_LEASE_TIME;
2405 INIT_WORK(&laundromat_work,laundromat_main, NULL);
2406 schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
2414 return time_before(get_seconds(), (unsigned long)grace_end);
2418 nfs4_in_no_grace(void)
2420 return (grace_end < get_seconds());
2425 __nfs4_state_shutdown(void)
2428 struct nfs4_client *clp = NULL;
2430 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2431 while (!list_empty(&conf_id_hashtbl[i])) {
2432 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
2435 while (!list_empty(&unconf_str_hashtbl[i])) {
2436 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
2440 release_all_files();
2441 cancel_delayed_work(&laundromat_work);
2442 flush_scheduled_work();
2444 dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2445 list_add_perfile, list_del_perfile);
2446 dprintk("NFSD: add_perclient %d del_perclient %d\n",
2447 add_perclient, del_perclient);
2448 dprintk("NFSD: alloc_file %d free_file %d\n",
2449 alloc_file, free_file);
2450 dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2451 alloc_sowner, alloc_lsowner, free_sowner);
2452 dprintk("NFSD: vfsopen %d vfsclose %d\n",
2457 nfs4_state_shutdown(void)
2460 __nfs4_state_shutdown();
2461 nfs4_unlock_state();