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
54 static time_t lease_time = 90; /* default lease time */
55 static time_t old_lease_time = 90; /* past incarnation lease time */
56 static u32 nfs4_reclaim_init = 0;
58 static time_t grace_end = 0;
59 static u32 current_clientid = 1;
60 static u32 current_ownerid;
61 static u32 current_fileid;
63 stateid_t zerostateid; /* bits all 0 */
64 stateid_t onestateid; /* bits all 1 */
67 u32 list_add_perfile = 0;
68 u32 list_del_perfile = 0;
69 u32 add_perclient = 0;
70 u32 del_perclient = 0;
79 /* forward declarations */
80 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
85 * protects clientid_hashtbl[], clientstr_hashtbl[],
86 * unconfstr_hashtbl[], uncofid_hashtbl[].
88 static DECLARE_MUTEX(client_sema);
97 * nfs4_unlock_state(); called in encode
100 nfs4_unlock_state(void)
106 opaque_hashval(const void *ptr, int nbytes)
108 unsigned char *cptr = (unsigned char *) ptr;
118 /* forward declarations */
119 static void release_stateowner(struct nfs4_stateowner *sop);
120 static void release_stateid(struct nfs4_stateid *stp, int flags);
121 static void release_file(struct nfs4_file *fp);
128 /* Hash tables for nfs4_clientid state */
129 #define CLIENT_HASH_BITS 4
130 #define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
131 #define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
133 #define clientid_hashval(id) \
134 ((id) & CLIENT_HASH_MASK)
135 #define clientstr_hashval(name, namelen) \
136 (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
138 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
139 * used in reboot/reset lease grace period processing
141 * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
142 * setclientid_confirmed info.
144 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
147 * client_lru holds client queue ordered by nfs4_client.cl_time
150 * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
151 * for last close replay.
153 static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
154 static int reclaim_str_hashtbl_size;
155 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
156 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
157 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
158 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
159 static struct list_head client_lru;
160 static struct list_head close_lru;
163 renew_client(struct nfs4_client *clp)
166 * Move client to the end to the LRU list.
168 dprintk("renewing client (clientid %08x/%08x)\n",
169 clp->cl_clientid.cl_boot,
170 clp->cl_clientid.cl_id);
171 list_move_tail(&clp->cl_lru, &client_lru);
172 clp->cl_time = get_seconds();
175 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
177 STALE_CLIENTID(clientid_t *clid)
179 if (clid->cl_boot == boot_time)
181 dprintk("NFSD stale clientid (%08x/%08x)\n",
182 clid->cl_boot, clid->cl_id);
187 * XXX Should we use a slab cache ?
188 * This type of memory management is somewhat inefficient, but we use it
189 * anyway since SETCLIENTID is not a common operation.
191 static inline struct nfs4_client *
192 alloc_client(struct xdr_netobj name)
194 struct nfs4_client *clp;
196 if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) {
197 memset(clp, 0, sizeof(*clp));
198 if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) {
199 memcpy(clp->cl_name.data, name.data, name.len);
200 clp->cl_name.len = name.len;
211 free_client(struct nfs4_client *clp)
213 if (clp->cl_cred.cr_group_info)
214 put_group_info(clp->cl_cred.cr_group_info);
215 kfree(clp->cl_name.data);
220 expire_client(struct nfs4_client *clp)
222 struct nfs4_stateowner *sop;
224 dprintk("NFSD: expire_client\n");
225 list_del(&clp->cl_idhash);
226 list_del(&clp->cl_strhash);
227 list_del(&clp->cl_lru);
228 while (!list_empty(&clp->cl_perclient)) {
229 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
230 release_stateowner(sop);
235 static struct nfs4_client *
236 create_client(struct xdr_netobj name) {
237 struct nfs4_client *clp;
239 if(!(clp = alloc_client(name)))
241 INIT_LIST_HEAD(&clp->cl_idhash);
242 INIT_LIST_HEAD(&clp->cl_strhash);
243 INIT_LIST_HEAD(&clp->cl_perclient);
244 INIT_LIST_HEAD(&clp->cl_lru);
250 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
251 memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
255 copy_clid(struct nfs4_client *target, struct nfs4_client *source) {
256 target->cl_clientid.cl_boot = source->cl_clientid.cl_boot;
257 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
261 copy_cred(struct svc_cred *target, struct svc_cred *source) {
263 target->cr_uid = source->cr_uid;
264 target->cr_gid = source->cr_gid;
265 target->cr_group_info = source->cr_group_info;
266 get_group_info(target->cr_group_info);
270 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
273 return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
277 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
278 return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
282 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
283 return((cl1->cl_boot == cl2->cl_boot) &&
284 (cl1->cl_id == cl2->cl_id));
287 /* XXX what about NGROUP */
289 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
290 return(cr1->cr_uid == cr2->cr_uid);
295 gen_clid(struct nfs4_client *clp) {
296 clp->cl_clientid.cl_boot = boot_time;
297 clp->cl_clientid.cl_id = current_clientid++;
301 gen_confirm(struct nfs4_client *clp) {
306 p = (u32 *)clp->cl_confirm.data;
312 check_name(struct xdr_netobj name) {
316 if (name.len > NFS4_OPAQUE_LIMIT) {
317 printk("NFSD: check_name: name too long(%d)!\n", name.len);
324 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
326 unsigned int idhashval;
328 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
329 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
330 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
331 list_add_tail(&clp->cl_lru, &client_lru);
332 clp->cl_time = get_seconds();
336 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
338 unsigned int strhashval;
340 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
341 list_del_init(&clp->cl_strhash);
342 list_del_init(&clp->cl_idhash);
343 list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
344 strhashval = clientstr_hashval(clp->cl_name.data,
346 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
351 /* a helper function for parse_callback */
353 parse_octet(unsigned int *lenp, char **addrp)
355 unsigned int len = *lenp;
367 if ((c < '0') || (c > '9')) {
373 n = (n * 10) + (c - '0');
384 /* parse and set the setclientid ipv4 callback address */
386 parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
391 u32 addrlen = addr_len;
392 char *addr = addr_val;
397 for(i = 4; i > 0 ; i--) {
398 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
401 cbaddr |= (temp << shift);
409 for(i = 2; i > 0 ; i--) {
410 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
413 cbport |= (temp << shift);
422 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
424 struct nfs4_callback *cb = &clp->cl_callback;
426 if( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
427 &cb->cb_addr, &cb->cb_port))) {
428 printk(KERN_INFO "NFSD: BAD callback address. client will not receive delegations\n");
432 cb->cb_netid.len = se->se_callback_netid_len;
433 cb->cb_netid.data = se->se_callback_netid_val;
434 cb->cb_prog = se->se_callback_prog;
435 cb->cb_ident = se->se_callback_ident;
440 * RFC 3010 has a complex implmentation description of processing a
441 * SETCLIENTID request consisting of 5 bullets, labeled as
442 * CASE0 - CASE4 below.
445 * callback information will be processed in a future patch
447 * an unconfirmed record is added when:
448 * NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
449 * CASE 1: confirmed record found with matching name, principal,
450 * verifier, and clientid.
451 * CASE 2: confirmed record found with matching name, principal,
452 * and there is no unconfirmed record with matching
455 * an unconfirmed record is replaced when:
456 * CASE 3: confirmed record found with matching name, principal,
457 * and an unconfirmed record is found with matching
458 * name, principal, and with clientid and
459 * confirm that does not match the confirmed record.
460 * CASE 4: there is no confirmed record with matching name and
461 * principal. there is an unconfirmed record with
462 * matching name, principal.
464 * an unconfirmed record is deleted when:
465 * CASE 1: an unconfirmed record that matches input name, verifier,
466 * and confirmed clientid.
467 * CASE 4: any unconfirmed records with matching name and principal
468 * that exist after an unconfirmed record has been replaced
469 * as described above.
473 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
475 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
476 struct xdr_netobj clname = {
477 .len = setclid->se_namelen,
478 .data = setclid->se_name,
480 nfs4_verifier clverifier = setclid->se_verf;
481 unsigned int strhashval;
482 struct nfs4_client * conf, * unconf, * new, * clp;
485 status = nfserr_inval;
486 if (!check_name(clname))
490 * XXX The Duplicate Request Cache (DRC) has been checked (??)
491 * We get here on a DRC miss.
494 strhashval = clientstr_hashval(clname.data, clname.len);
498 list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
499 if (!cmp_name(&clp->cl_name, &clname))
503 * clname match, confirmed, different principal
504 * or different ip_address
506 status = nfserr_clid_inuse;
507 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
508 printk("NFSD: setclientid: string in use by client"
509 "(clientid %08x/%08x)\n",
510 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
513 if (clp->cl_addr != ip_addr) {
514 printk("NFSD: setclientid: string in use by client"
515 "(clientid %08x/%08x)\n",
516 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
521 * cl_name match from a previous SETCLIENTID operation
522 * XXX check for additional matches?
528 list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
529 if (!cmp_name(&clp->cl_name, &clname))
531 /* cl_name match from a previous SETCLIENTID operation */
535 status = nfserr_resource;
539 * placed first, because it is the normal case.
542 expire_client(unconf);
543 if (!(new = create_client(clname)))
545 copy_verf(new, &clverifier);
546 new->cl_addr = ip_addr;
547 copy_cred(&new->cl_cred,&rqstp->rq_cred);
550 gen_callback(new, setclid);
551 add_to_unconfirmed(new, strhashval);
552 } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
555 * cl_name match, confirmed, principal match
556 * verifier match: probable callback update
558 * remove any unconfirmed nfs4_client with
559 * matching cl_name, cl_verifier, and cl_clientid
561 * create and insert an unconfirmed nfs4_client with same
562 * cl_name, cl_verifier, and cl_clientid as existing
563 * nfs4_client, but with the new callback info and a
567 cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
568 cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
569 expire_client(unconf);
571 if (!(new = create_client(clname)))
573 copy_verf(new,&conf->cl_verifier);
574 new->cl_addr = ip_addr;
575 copy_cred(&new->cl_cred,&rqstp->rq_cred);
576 copy_clid(new, conf);
578 gen_callback(new, setclid);
579 add_to_unconfirmed(new,strhashval);
580 } else if (!unconf) {
583 * clname match, confirmed, principal match
584 * verfier does not match
585 * no unconfirmed. create a new unconfirmed nfs4_client
586 * using input clverifier, clname, and callback info
587 * and generate a new cl_clientid and cl_confirm.
589 if (!(new = create_client(clname)))
591 copy_verf(new,&clverifier);
592 new->cl_addr = ip_addr;
593 copy_cred(&new->cl_cred,&rqstp->rq_cred);
596 gen_callback(new, setclid);
597 add_to_unconfirmed(new, strhashval);
598 } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
601 * confirmed found (name, principal match)
602 * confirmed verifier does not match input clverifier
604 * unconfirmed found (name match)
605 * confirmed->cl_confirm != unconfirmed->cl_confirm
607 * remove unconfirmed.
609 * create an unconfirmed nfs4_client
610 * with same cl_name as existing confirmed nfs4_client,
611 * but with new callback info, new cl_clientid,
612 * new cl_verifier and a new cl_confirm
614 expire_client(unconf);
615 if (!(new = create_client(clname)))
617 copy_verf(new,&clverifier);
618 new->cl_addr = ip_addr;
619 copy_cred(&new->cl_cred,&rqstp->rq_cred);
622 gen_callback(new, setclid);
623 add_to_unconfirmed(new, strhashval);
625 /* No cases hit !!! */
626 status = nfserr_inval;
630 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
631 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
632 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
641 * RFC 3010 has a complex implmentation description of processing a
642 * SETCLIENTID_CONFIRM request consisting of 4 bullets describing
643 * processing on a DRC miss, labeled as CASE1 - CASE4 below.
645 * NOTE: callback information will be processed here in a future patch
648 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
650 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
651 unsigned int idhashval;
652 struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
653 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
654 clientid_t * clid = &setclientid_confirm->sc_clientid;
657 status = nfserr_stale_clientid;
658 if (STALE_CLIENTID(clid))
661 * XXX The Duplicate Request Cache (DRC) has been checked (??)
662 * We get here on a DRC miss.
665 idhashval = clientid_hashval(clid->cl_id);
667 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
668 if (!cmp_clid(&clp->cl_clientid, clid))
671 status = nfserr_inval;
673 * Found a record for this clientid. If the IP addresses
674 * don't match, return ERR_INVAL just as if the record had
677 if (clp->cl_addr != ip_addr) {
678 printk("NFSD: setclientid: string in use by client"
679 "(clientid %08x/%08x)\n",
680 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
686 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
687 if (!cmp_clid(&clp->cl_clientid, clid))
689 status = nfserr_inval;
690 if (clp->cl_addr != ip_addr) {
691 printk("NFSD: setclientid: string in use by client"
692 "(clientid %08x/%08x)\n",
693 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
700 * unconf record that matches input clientid and input confirm.
701 * conf record that matches input clientid.
702 * conf and unconf records match names, verifiers
704 if ((conf && unconf) &&
705 (cmp_verf(&unconf->cl_confirm, &confirm)) &&
706 (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
707 (cmp_name(&conf->cl_name,&unconf->cl_name)) &&
708 (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
709 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred))
710 status = nfserr_clid_inuse;
713 move_to_confirmed(unconf, idhashval);
719 * conf record that matches input clientid.
720 * if unconf record that matches input clientid, then unconf->cl_name
721 * or unconf->cl_verifier don't match the conf record.
723 if ((conf && !unconf) ||
725 (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
726 !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
727 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
728 status = nfserr_clid_inuse;
735 * conf record not found.
736 * unconf record found.
737 * unconf->cl_confirm matches input confirm
739 if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
740 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
741 status = nfserr_clid_inuse;
744 move_to_confirmed(unconf, idhashval);
749 * conf record not found, or if conf, then conf->cl_confirm does not
750 * match input confirm.
751 * unconf record not found, or if unconf, then unconf->cl_confirm
752 * does not match input confirm.
754 if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
755 (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
756 status = nfserr_stale_clientid;
759 /* check that we have hit one of the cases...*/
760 status = nfserr_inval;
763 /* XXX if status == nfs_ok, probe callback path */
769 * Open owner state (share locks)
772 /* hash tables for nfs4_stateowner */
773 #define OWNER_HASH_BITS 8
774 #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS)
775 #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1)
777 #define ownerid_hashval(id) \
778 ((id) & OWNER_HASH_MASK)
779 #define ownerstr_hashval(clientid, ownername) \
780 (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
782 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
783 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
785 /* hash table for nfs4_file */
786 #define FILE_HASH_BITS 8
787 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
788 #define FILE_HASH_MASK (FILE_HASH_SIZE - 1)
789 /* hash table for (open)nfs4_stateid */
790 #define STATEID_HASH_BITS 10
791 #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
792 #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1)
794 #define file_hashval(x) \
795 hash_ptr(x, FILE_HASH_BITS)
796 #define stateid_hashval(owner_id, file_id) \
797 (((owner_id) + (file_id)) & STATEID_HASH_MASK)
799 static struct list_head file_hashtbl[FILE_HASH_SIZE];
800 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
802 /* OPEN Share state helper functions */
803 static inline struct nfs4_file *
804 alloc_init_file(unsigned int hashval, struct inode *ino) {
805 struct nfs4_file *fp;
806 if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
807 INIT_LIST_HEAD(&fp->fi_hash);
808 INIT_LIST_HEAD(&fp->fi_perfile);
809 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
810 fp->fi_inode = igrab(ino);
811 fp->fi_id = current_fileid++;
815 return (struct nfs4_file *)NULL;
819 release_all_files(void)
822 struct nfs4_file *fp;
824 for (i=0;i<FILE_HASH_SIZE;i++) {
825 while (!list_empty(&file_hashtbl[i])) {
826 fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
827 /* this should never be more than once... */
828 if(!list_empty(&fp->fi_perfile)) {
829 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
836 static inline struct nfs4_stateowner *
837 alloc_stateowner(struct xdr_netobj *owner)
839 struct nfs4_stateowner *sop;
841 if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
842 if((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
843 memcpy(sop->so_owner.data, owner->data, owner->len);
844 sop->so_owner.len = owner->len;
849 return (struct nfs4_stateowner *)NULL;
852 /* should use a slab cache */
854 free_stateowner(struct nfs4_stateowner *sop) {
856 kfree(sop->so_owner.data);
863 static struct nfs4_stateowner *
864 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
865 struct nfs4_stateowner *sop;
866 struct nfs4_replay *rp;
867 unsigned int idhashval;
869 if (!(sop = alloc_stateowner(&open->op_owner)))
870 return (struct nfs4_stateowner *)NULL;
871 idhashval = ownerid_hashval(current_ownerid);
872 INIT_LIST_HEAD(&sop->so_idhash);
873 INIT_LIST_HEAD(&sop->so_strhash);
874 INIT_LIST_HEAD(&sop->so_perclient);
875 INIT_LIST_HEAD(&sop->so_perfilestate);
876 INIT_LIST_HEAD(&sop->so_perlockowner); /* not used */
877 INIT_LIST_HEAD(&sop->so_close_lru);
879 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
880 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
881 list_add(&sop->so_perclient, &clp->cl_perclient);
883 sop->so_is_open_owner = 1;
884 sop->so_id = current_ownerid++;
885 sop->so_client = clp;
886 sop->so_seqid = open->op_seqid;
887 sop->so_confirmed = 0;
888 rp = &sop->so_replay;
889 rp->rp_status = NFSERR_SERVERFAULT;
891 rp->rp_buf = rp->rp_ibuf;
897 release_stateid_lockowner(struct nfs4_stateid *open_stp)
899 struct nfs4_stateowner *lock_sop;
901 while (!list_empty(&open_stp->st_perlockowner)) {
902 lock_sop = list_entry(open_stp->st_perlockowner.next,
903 struct nfs4_stateowner, so_perlockowner);
904 /* list_del(&open_stp->st_perlockowner); */
905 BUG_ON(lock_sop->so_is_open_owner);
906 release_stateowner(lock_sop);
911 release_stateowner(struct nfs4_stateowner *sop)
913 struct nfs4_stateid *stp;
915 list_del(&sop->so_idhash);
916 list_del(&sop->so_strhash);
917 list_del(&sop->so_perclient);
918 list_del(&sop->so_perlockowner);
919 list_del(&sop->so_close_lru);
921 while (!list_empty(&sop->so_perfilestate)) {
922 stp = list_entry(sop->so_perfilestate.next,
923 struct nfs4_stateid, st_perfilestate);
924 if(sop->so_is_open_owner)
925 release_stateid(stp, OPEN_STATE);
927 release_stateid(stp, LOCK_STATE);
929 free_stateowner(sop);
933 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
934 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
936 INIT_LIST_HEAD(&stp->st_hash);
937 INIT_LIST_HEAD(&stp->st_perfilestate);
938 INIT_LIST_HEAD(&stp->st_perlockowner);
939 INIT_LIST_HEAD(&stp->st_perfile);
940 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
941 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
943 list_add(&stp->st_perfile, &fp->fi_perfile);
944 stp->st_stateowner = sop;
946 stp->st_stateid.si_boot = boot_time;
947 stp->st_stateid.si_stateownerid = sop->so_id;
948 stp->st_stateid.si_fileid = fp->fi_id;
949 stp->st_stateid.si_generation = 0;
950 stp->st_access_bmap = 0;
951 stp->st_deny_bmap = 0;
952 __set_bit(open->op_share_access, &stp->st_access_bmap);
953 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
957 release_stateid(struct nfs4_stateid *stp, int flags) {
959 list_del(&stp->st_hash);
961 list_del(&stp->st_perfile);
962 list_del(&stp->st_perfilestate);
963 if((stp->st_vfs_set) && (flags & OPEN_STATE)) {
964 release_stateid_lockowner(stp);
965 nfsd_close(&stp->st_vfs_file);
967 dput(stp->st_vfs_file.f_dentry);
968 mntput(stp->st_vfs_file.f_vfsmnt);
969 } else if ((stp->st_vfs_set) && (flags & LOCK_STATE)) {
970 struct file *filp = &stp->st_vfs_file;
972 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
979 release_file(struct nfs4_file *fp)
982 list_del(&fp->fi_hash);
988 move_to_close_lru(struct nfs4_stateowner *sop)
990 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
991 /* remove stateowner from all other hash lists except perclient */
992 list_del_init(&sop->so_idhash);
993 list_del_init(&sop->so_strhash);
994 list_del_init(&sop->so_perlockowner);
996 list_add_tail(&sop->so_close_lru, &close_lru);
997 sop->so_time = get_seconds();
1001 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
1004 struct nfs4_stateowner *sop = stp->st_stateowner;
1005 struct nfs4_file *fp = stp->st_file;
1007 dprintk("NFSD: release_state_owner\n");
1008 release_stateid(stp, flag);
1010 /* place unused nfs4_stateowners on so_close_lru list to be
1011 * released by the laundromat service after the lease period
1012 * to enable us to handle CLOSE replay
1014 if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
1015 move_to_close_lru(sop);
1016 /* unused nfs4_file's are releseed. XXX slab cache? */
1017 if (list_empty(&fp->fi_perfile)) {
1023 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
1024 return ((sop->so_owner.len == owner->len) &&
1025 !memcmp(sop->so_owner.data, owner->data, owner->len) &&
1026 (sop->so_client->cl_clientid.cl_id == clid->cl_id));
1029 /* search ownerstr_hashtbl[] for owner */
1031 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
1032 struct nfs4_stateowner *local = NULL;
1034 list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) {
1035 if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid))
1043 /* see if clientid is in confirmed hash table */
1045 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
1047 struct nfs4_client *clp;
1048 unsigned int idhashval = clientid_hashval(clid->cl_id);
1050 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1051 if (!cmp_clid(&clp->cl_clientid, clid))
1060 /* search file_hashtbl[] for file */
1062 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
1063 struct nfs4_file *local = NULL;
1065 list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) {
1066 if (local->fi_inode == ino) {
1074 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
1075 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
1078 set_access(unsigned int *access, unsigned long bmap) {
1082 for (i = 1; i < 4; i++) {
1083 if(test_bit(i, &bmap))
1089 set_deny(unsigned int *deny, unsigned long bmap) {
1093 for (i = 0; i < 4; i++) {
1094 if(test_bit(i, &bmap))
1100 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1101 unsigned int access, deny;
1103 set_access(&access, stp->st_access_bmap);
1104 set_deny(&deny, stp->st_deny_bmap);
1105 if ((access & open->op_share_deny) || (deny & open->op_share_access))
1111 * Called to check deny when READ with all zero stateid or
1112 * WRITE with all zero or all one stateid
1115 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1117 struct inode *ino = current_fh->fh_dentry->d_inode;
1118 unsigned int fi_hashval;
1119 struct nfs4_file *fp;
1120 struct nfs4_stateid *stp;
1122 dprintk("NFSD: nfs4_share_conflict\n");
1124 fi_hashval = file_hashval(ino);
1125 if (find_file(fi_hashval, ino, &fp)) {
1126 /* Search for conflicting share reservations */
1127 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
1128 if (test_bit(deny_type, &stp->st_deny_bmap) ||
1129 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1130 return nfserr_share_denied;
1137 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
1141 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1142 status = get_write_access(filp->f_dentry->d_inode);
1144 return nfserrno(status);
1145 filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
1151 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1153 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1154 put_write_access(filp->f_dentry->d_inode);
1155 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
1161 * nfsd4_process_open1()
1162 * lookup stateowner.
1174 * called with nfs4_lock_state() held.
1177 nfsd4_process_open1(struct nfsd4_open *open)
1180 clientid_t *clientid = &open->op_clientid;
1181 struct nfs4_client *clp = NULL;
1182 unsigned int strhashval;
1183 struct nfs4_stateowner *sop = NULL;
1185 status = nfserr_inval;
1186 if (!check_name(open->op_owner))
1189 status = nfserr_stale_clientid;
1190 if (STALE_CLIENTID(&open->op_clientid))
1193 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1194 if (find_openstateowner_str(strhashval, open, &sop)) {
1195 open->op_stateowner = sop;
1196 /* check for replay */
1197 if (open->op_seqid == sop->so_seqid){
1198 if (!sop->so_replay.rp_buflen) {
1200 * The original OPEN failed in so spectacularly that we
1201 * don't even have replay data saved! Therefore, we
1202 * have no choice but to continue processing
1203 * this OPEN; presumably, we'll fail again for the same
1206 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1210 /* replay: indicate to calling function */
1211 status = NFSERR_REPLAY_ME;
1214 if (sop->so_confirmed) {
1215 if (open->op_seqid == sop->so_seqid + 1) {
1219 status = nfserr_bad_seqid;
1222 /* If we get here, we received and OPEN for an unconfirmed
1224 * Since the sequid's are different, purge the
1225 * existing nfs4_stateowner, and instantiate a new one.
1227 clp = sop->so_client;
1228 release_stateowner(sop);
1229 goto instantiate_new_owner;
1231 /* nfs4_stateowner not found.
1232 * verify clientid and instantiate new nfs4_stateowner
1233 * if verify fails this is presumably the result of the
1234 * client's lease expiring.
1236 * XXX compare clp->cl_addr with rqstp addr?
1238 status = nfserr_expired;
1239 if (!verify_clientid(&clp, clientid))
1241 instantiate_new_owner:
1242 status = nfserr_resource;
1243 if (!(sop = alloc_init_open_stateowner(strhashval, clp, open)))
1245 open->op_stateowner = sop;
1248 renew_client(sop->so_client);
1250 if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1251 status = nfserr_reclaim_bad;
1255 * called with nfs4_lock_state() held.
1258 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1261 struct nfs4_stateowner *sop = open->op_stateowner;
1262 struct nfs4_file *fp = NULL;
1264 unsigned int fi_hashval;
1265 struct nfs4_stateid *stq, *stp = NULL;
1268 status = nfserr_resource;
1272 ino = current_fh->fh_dentry->d_inode;
1274 status = nfserr_inval;
1275 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1278 fi_hashval = file_hashval(ino);
1279 if (find_file(fi_hashval, ino, &fp)) {
1280 /* Search for conflicting share reservations */
1281 status = nfserr_share_denied;
1282 list_for_each_entry(stq, &fp->fi_perfile, st_perfile) {
1283 if(stq->st_stateowner == sop) {
1287 /* ignore lock owners */
1288 if (stq->st_stateowner->so_is_open_owner == 0)
1290 if (!test_share(stq,open))
1294 /* No nfs4_file found; allocate and init a new one */
1295 status = nfserr_resource;
1296 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1303 status = nfserr_resource;
1304 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1305 GFP_KERNEL)) == NULL)
1308 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1312 if ((status = nfsd_open(rqstp, current_fh, S_IFREG,
1314 &stp->st_vfs_file)) != 0)
1318 dget(stp->st_vfs_file.f_dentry);
1319 mntget(stp->st_vfs_file.f_vfsmnt);
1321 init_stateid(stp, fp, sop, open);
1322 stp->st_vfs_set = 1;
1324 /* This is an upgrade of an existing OPEN.
1325 * OR the incoming share with the existing
1326 * nfs4_stateid share */
1327 unsigned int share_access;
1329 set_access(&share_access, stp->st_access_bmap);
1330 share_access = ~share_access;
1331 share_access &= open->op_share_access;
1333 /* update the struct file */
1334 if ((status = nfs4_file_upgrade(&stp->st_vfs_file, share_access)))
1336 /* remember the open */
1337 set_bit(open->op_share_access, &stp->st_access_bmap);
1338 set_bit(open->op_share_deny, &stp->st_deny_bmap);
1339 /* bump the stateid */
1340 update_stateid(&stp->st_stateid);
1342 dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1343 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1344 stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1346 if (open->op_truncate) {
1347 iattr.ia_valid = ATTR_SIZE;
1349 status = nfsd_setattr(rqstp, current_fh, &iattr, 0, (time_t)0);
1353 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1355 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
1358 if (fp && list_empty(&fp->fi_perfile))
1361 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
1363 status = nfserr_reclaim_bad;
1365 /* successful reclaim. so_seqid is decremented because
1366 * it will be bumped in encode_open
1368 open->op_stateowner->so_confirmed = 1;
1369 open->op_stateowner->so_seqid--;
1373 * To finish the open response, we just need to set the rflags.
1375 open->op_rflags = 0;
1376 if (!open->op_stateowner->so_confirmed)
1377 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1385 static struct work_struct laundromat_work;
1386 static void laundromat_main(void *);
1387 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1390 nfsd4_renew(clientid_t *clid)
1392 struct nfs4_client *clp;
1393 unsigned int idhashval;
1397 dprintk("process_renew(%08x/%08x): starting\n",
1398 clid->cl_boot, clid->cl_id);
1399 status = nfserr_stale_clientid;
1400 if (STALE_CLIENTID(clid))
1403 idhashval = clientid_hashval(clid->cl_id);
1404 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1405 if (!cmp_clid(&clp->cl_clientid, clid))
1410 list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1411 if (!cmp_clid(&clp->cl_clientid, clid))
1417 * Couldn't find an nfs4_client for this clientid.
1418 * Presumably this is because the client took too long to
1419 * RENEW, so return NFS4ERR_EXPIRED.
1421 dprintk("nfsd4_renew: clientid not found!\n");
1422 status = nfserr_expired;
1424 nfs4_unlock_state();
1429 nfs4_laundromat(void)
1431 struct nfs4_client *clp;
1432 struct nfs4_stateowner *sop;
1433 struct list_head *pos, *next;
1434 time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1435 time_t t, clientid_val = NFSD_LEASE_TIME;
1436 time_t u, close_val = NFSD_LEASE_TIME;
1440 dprintk("NFSD: laundromat service - starting, examining clients\n");
1441 list_for_each_safe(pos, next, &client_lru) {
1442 clp = list_entry(pos, struct nfs4_client, cl_lru);
1443 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1444 t = clp->cl_time - cutoff;
1445 if (clientid_val > t)
1449 dprintk("NFSD: purging unused client (clientid %08x)\n",
1450 clp->cl_clientid.cl_id);
1453 list_for_each_safe(pos, next, &close_lru) {
1454 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
1455 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
1456 u = sop->so_time - cutoff;
1461 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1463 release_stateowner(sop);
1465 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1466 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1467 nfs4_unlock_state();
1468 return clientid_val;
1472 laundromat_main(void *not_used)
1476 t = nfs4_laundromat();
1477 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1478 schedule_delayed_work(&laundromat_work, t*HZ);
1481 /* search ownerid_hashtbl[] and close_lru for stateid owner
1482 * (stateid->si_stateownerid)
1484 struct nfs4_stateowner *
1485 find_openstateowner_id(u32 st_id, int flags) {
1486 struct nfs4_stateowner *local = NULL;
1488 dprintk("NFSD: find_openstateowner_id %d\n", st_id);
1489 if (flags & CLOSE_STATE) {
1490 list_for_each_entry(local, &close_lru, so_close_lru) {
1491 if(local->so_id == st_id)
1499 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1501 return (stp->st_vfs_set == 0 ||
1502 fhp->fh_dentry->d_inode != stp->st_vfs_file.f_dentry->d_inode);
1506 STALE_STATEID(stateid_t *stateid)
1508 if (stateid->si_boot == boot_time)
1510 printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1511 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1512 stateid->si_generation);
1518 * Checks for stateid operations
1521 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
1523 struct nfs4_stateid *stp;
1526 dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
1527 stateid->si_boot, stateid->si_stateownerid,
1528 stateid->si_fileid, stateid->si_generation);
1533 status = nfserr_stale_stateid;
1534 if (STALE_STATEID(stateid))
1538 status = nfserr_bad_stateid;
1539 if (!(stp = find_stateid(stateid, flags))) {
1540 dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
1543 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1544 dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
1545 stp->st_vfs_set = 0;
1548 if (!stp->st_stateowner->so_confirmed) {
1549 dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
1552 if (stateid->si_generation > stp->st_stateid.si_generation) {
1553 dprintk("preprocess_stateid_op: future stateid?!\n");
1558 status = nfserr_old_stateid;
1559 if (stateid->si_generation < stp->st_stateid.si_generation) {
1560 dprintk("preprocess_stateid_op: old stateid!\n");
1565 renew_client(stp->st_stateowner->so_client);
1572 * Checks for sequence id mutating operations.
1575 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)
1578 struct nfs4_stateid *stp;
1579 struct nfs4_stateowner *sop;
1581 dprintk("NFSD: preprocess_seqid_op: seqid=%d "
1582 "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
1583 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1584 stateid->si_generation);
1589 status = nfserr_bad_stateid;
1590 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
1591 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
1595 status = nfserr_stale_stateid;
1596 if (STALE_STATEID(stateid))
1599 * We return BAD_STATEID if filehandle doesn't match stateid,
1600 * the confirmed flag is incorrecly set, or the generation
1601 * number is incorrect.
1602 * If there is no entry in the openfile table for this id,
1603 * we can't always return BAD_STATEID;
1604 * this might be a retransmitted CLOSE which has arrived after
1605 * the openfile has been released.
1607 if (!(stp = find_stateid(stateid, flags)))
1608 goto no_nfs4_stateid;
1610 status = nfserr_bad_stateid;
1612 /* for new lock stateowners:
1613 * check that the lock->v.new.open_stateid
1614 * refers to an open stateowner
1616 * check that the lockclid (nfs4_lock->v.new.clientid) is the same
1617 * as the open_stateid->st_stateowner->so_client->clientid
1620 struct nfs4_stateowner *sop = stp->st_stateowner;
1621 struct nfs4_client *clp = sop->so_client;
1623 if (!sop->so_is_open_owner)
1625 if (!cmp_clid(&clp->cl_clientid, lockclid))
1629 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1630 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
1631 stp->st_vfs_set = 0;
1636 *sopp = sop = stp->st_stateowner;
1639 * We now validate the seqid and stateid generation numbers.
1640 * For the moment, we ignore the possibility of
1641 * generation number wraparound.
1643 if (seqid != sop->so_seqid + 1)
1646 if (sop->so_confirmed) {
1647 if (flags & CONFIRM) {
1648 printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
1653 if (!(flags & CONFIRM)) {
1654 printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
1658 if (stateid->si_generation > stp->st_stateid.si_generation) {
1659 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
1663 status = nfserr_old_stateid;
1664 if (stateid->si_generation < stp->st_stateid.si_generation) {
1665 printk("NFSD: preprocess_seqid_op: old stateid!\n");
1668 /* XXX renew the client lease here */
1677 * We determine whether this is a bad stateid or a replay,
1678 * starting by trying to look up the stateowner.
1679 * If stateowner is not found - stateid is bad.
1681 if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
1682 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
1683 status = nfserr_bad_stateid;
1689 if (seqid == sop->so_seqid) {
1690 printk("NFSD: preprocess_seqid_op: retransmission?\n");
1691 /* indicate replay to calling function */
1692 status = NFSERR_REPLAY_ME;
1694 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
1697 status = nfserr_bad_seqid;
1703 * eventually, this will perform an upcall to the 'state daemon' as well as
1704 * set the cl_first_state field.
1707 first_state(struct nfs4_client *clp)
1709 if (!clp->cl_first_state)
1710 clp->cl_first_state = get_seconds();
1714 * nfs4_unlock_state(); called in encode
1717 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
1720 struct nfs4_stateowner *sop;
1721 struct nfs4_stateid *stp;
1723 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
1724 (int)current_fh->fh_dentry->d_name.len,
1725 current_fh->fh_dentry->d_name.name);
1727 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
1730 oc->oc_stateowner = NULL;
1733 if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
1734 &oc->oc_req_stateid,
1735 CHECK_FH | CONFIRM | OPEN_STATE,
1736 &oc->oc_stateowner, &stp, NULL)))
1739 sop = oc->oc_stateowner;
1740 sop->so_confirmed = 1;
1741 update_stateid(&stp->st_stateid);
1742 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
1743 dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d "
1744 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
1745 stp->st_stateid.si_boot,
1746 stp->st_stateid.si_stateownerid,
1747 stp->st_stateid.si_fileid,
1748 stp->st_stateid.si_generation);
1750 first_state(sop->so_client);
1757 * unset all bits in union bitmap (bmap) that
1758 * do not exist in share (from successful OPEN_DOWNGRADE)
1761 reset_union_bmap_access(unsigned long access, unsigned long *bmap)
1764 for (i = 1; i < 4; i++) {
1765 if ((i & access) != i)
1766 __clear_bit(i, bmap);
1771 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
1774 for (i = 0; i < 4; i++) {
1775 if ((i & deny) != i)
1776 __clear_bit(i, bmap);
1781 * nfs4_unlock_state(); called in encode
1785 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
1788 struct nfs4_stateid *stp;
1789 unsigned int share_access;
1791 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
1792 (int)current_fh->fh_dentry->d_name.len,
1793 current_fh->fh_dentry->d_name.name);
1795 od->od_stateowner = NULL;
1796 status = nfserr_inval;
1797 if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
1801 if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid,
1803 CHECK_FH | OPEN_STATE,
1804 &od->od_stateowner, &stp, NULL)))
1807 status = nfserr_inval;
1808 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
1809 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
1810 stp->st_access_bmap, od->od_share_access);
1813 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) {
1814 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
1815 stp->st_deny_bmap, od->od_share_deny);
1818 set_access(&share_access, stp->st_access_bmap);
1819 nfs4_file_downgrade(&stp->st_vfs_file,
1820 share_access & ~od->od_share_access);
1822 reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
1823 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
1825 update_stateid(&stp->st_stateid);
1826 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
1833 * nfs4_unlock_state() called after encode
1836 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
1839 struct nfs4_stateid *stp;
1841 dprintk("NFSD: nfsd4_close on file %.*s\n",
1842 (int)current_fh->fh_dentry->d_name.len,
1843 current_fh->fh_dentry->d_name.name);
1845 close->cl_stateowner = NULL;
1847 /* check close_lru for replay */
1848 if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid,
1850 CHECK_FH | OPEN_STATE | CLOSE_STATE,
1851 &close->cl_stateowner, &stp, NULL)))
1854 * Return success, but first update the stateid.
1857 update_stateid(&stp->st_stateid);
1858 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
1860 /* release_state_owner() calls nfsd_close() if needed */
1861 release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
1867 * Lock owner state (byte-range locks)
1869 #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
1870 #define LOCK_HASH_BITS 8
1871 #define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS)
1872 #define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1)
1874 #define lockownerid_hashval(id) \
1875 ((id) & LOCK_HASH_MASK)
1876 #define lock_ownerstr_hashval(x, clientid, ownername) \
1877 ((file_hashval(x) + (clientid) + opaque_hashval((ownername.data), (ownername.len))) & LOCK_HASH_MASK)
1879 static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
1880 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
1881 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
1883 struct nfs4_stateid *
1884 find_stateid(stateid_t *stid, int flags)
1886 struct nfs4_stateid *local = NULL;
1887 u32 st_id = stid->si_stateownerid;
1888 u32 f_id = stid->si_fileid;
1889 unsigned int hashval;
1891 dprintk("NFSD: find_stateid flags 0x%x\n",flags);
1892 if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
1893 hashval = stateid_hashval(st_id, f_id);
1894 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
1895 if((local->st_stateid.si_stateownerid == st_id) &&
1896 (local->st_stateid.si_fileid == f_id))
1900 if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
1901 hashval = stateid_hashval(st_id, f_id);
1902 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
1903 if((local->st_stateid.si_stateownerid == st_id) &&
1904 (local->st_stateid.si_fileid == f_id))
1908 printk("NFSD: find_stateid: ERROR: no state flag\n");
1914 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
1915 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
1916 * byte, because of sign extension problems. Since NFSv4 calls for 64-bit
1917 * locking, this prevents us from being completely protocol-compliant. The
1918 * real solution to this problem is to start using unsigned file offsets in
1919 * the VFS, but this is a very deep change!
1922 nfs4_transform_lock_offset(struct file_lock *lock)
1924 if (lock->fl_start < 0)
1925 lock->fl_start = OFFSET_MAX;
1926 if (lock->fl_end < 0)
1927 lock->fl_end = OFFSET_MAX;
1931 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
1933 struct nfs4_stateowner *local = NULL;
1936 if (hashval >= LOCK_HASH_SIZE)
1938 list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
1950 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
1952 struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
1954 deny->ld_sop = NULL;
1955 if (nfs4_verify_lock_stateowner(sop, fl->fl_pid))
1957 deny->ld_start = fl->fl_start;
1958 deny->ld_length = ~(u64)0;
1959 if (fl->fl_end != ~(u64)0)
1960 deny->ld_length = fl->fl_end - fl->fl_start + 1;
1961 deny->ld_type = NFS4_READ_LT;
1962 if (fl->fl_type != F_RDLCK)
1963 deny->ld_type = NFS4_WRITE_LT;
1966 static struct nfs4_stateowner *
1967 find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
1969 struct nfs4_stateowner *local = NULL;
1972 for (i = 0; i < LOCK_HASH_SIZE; i++) {
1973 list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
1974 if(!cmp_owner_str(local, owner, clid))
1983 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
1984 struct nfs4_stateowner *local = NULL;
1986 list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) {
1987 if(!cmp_owner_str(local, owner, clid))
1997 * Alloc a lock owner structure.
1998 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
2001 * strhashval = lock_ownerstr_hashval
2002 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
2005 static struct nfs4_stateowner *
2006 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
2007 struct nfs4_stateowner *sop;
2008 struct nfs4_replay *rp;
2009 unsigned int idhashval;
2011 if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
2012 return (struct nfs4_stateowner *)NULL;
2013 idhashval = lockownerid_hashval(current_ownerid);
2014 INIT_LIST_HEAD(&sop->so_idhash);
2015 INIT_LIST_HEAD(&sop->so_strhash);
2016 INIT_LIST_HEAD(&sop->so_perclient);
2017 INIT_LIST_HEAD(&sop->so_perfilestate);
2018 INIT_LIST_HEAD(&sop->so_perlockowner);
2019 INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
2021 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
2022 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
2023 list_add(&sop->so_perclient, &clp->cl_perclient);
2024 list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
2026 sop->so_is_open_owner = 0;
2027 sop->so_id = current_ownerid++;
2028 sop->so_client = clp;
2029 sop->so_seqid = lock->lk_new_lock_seqid - 1;
2030 sop->so_confirmed = 1;
2031 rp = &sop->so_replay;
2032 rp->rp_status = NFSERR_SERVERFAULT;
2034 rp->rp_buf = rp->rp_ibuf;
2039 struct nfs4_stateid *
2040 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
2042 struct nfs4_stateid *stp;
2043 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
2045 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
2046 GFP_KERNEL)) == NULL)
2048 INIT_LIST_HEAD(&stp->st_hash);
2049 INIT_LIST_HEAD(&stp->st_perfile);
2050 INIT_LIST_HEAD(&stp->st_perfilestate);
2051 INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
2052 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
2053 list_add(&stp->st_perfile, &fp->fi_perfile);
2055 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
2056 stp->st_stateowner = sop;
2058 stp->st_stateid.si_boot = boot_time;
2059 stp->st_stateid.si_stateownerid = sop->so_id;
2060 stp->st_stateid.si_fileid = fp->fi_id;
2061 stp->st_stateid.si_generation = 0;
2062 stp->st_vfs_file = open_stp->st_vfs_file;
2063 stp->st_vfs_set = open_stp->st_vfs_set;
2064 stp->st_access_bmap = open_stp->st_access_bmap;
2065 stp->st_deny_bmap = open_stp->st_deny_bmap;
2072 check_lock_length(u64 offset, u64 length)
2074 return ((length == 0) || ((length != ~(u64)0) &&
2075 LOFF_OVERFLOW(offset, length)));
2081 * nfs4_unlock_state(); called in encode
2084 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
2086 struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
2087 struct nfs4_stateid *lock_stp;
2089 struct file_lock file_lock;
2090 struct file_lock *conflock;
2092 unsigned int strhashval;
2094 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
2095 (long long) lock->lk_offset,
2096 (long long) lock->lk_length);
2098 if (nfs4_in_grace() && !lock->lk_reclaim)
2099 return nfserr_grace;
2100 if (!nfs4_in_grace() && lock->lk_reclaim)
2101 return nfserr_no_grace;
2103 if (check_lock_length(lock->lk_offset, lock->lk_length))
2104 return nfserr_inval;
2106 lock->lk_stateowner = NULL;
2109 if (lock->lk_is_new) {
2111 * Client indicates that this is a new lockowner.
2112 * Use open owner and open stateid to create lock owner and lock
2115 struct nfs4_stateid *open_stp = NULL;
2116 struct nfs4_file *fp;
2118 status = nfserr_stale_clientid;
2119 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
2120 printk("NFSD: nfsd4_lock: clientid is stale!\n");
2124 /* is the new lock seqid presented by the client zero? */
2125 status = nfserr_bad_seqid;
2126 if (lock->v.new.lock_seqid != 0)
2129 /* validate and update open stateid and open seqid */
2130 status = nfs4_preprocess_seqid_op(current_fh,
2131 lock->lk_new_open_seqid,
2132 &lock->lk_new_open_stateid,
2133 CHECK_FH | OPEN_STATE,
2134 &open_sop, &open_stp,
2135 &lock->v.new.clientid);
2137 if (lock->lk_reclaim)
2138 status = nfserr_reclaim_bad;
2141 /* create lockowner and lock stateid */
2142 fp = open_stp->st_file;
2143 strhashval = lock_ownerstr_hashval(fp->fi_inode,
2144 open_sop->so_client->cl_clientid.cl_id,
2147 * If we already have this lock owner, the client is in
2148 * error (or our bookeeping is wrong!)
2149 * for asking for a 'new lock'.
2151 status = nfserr_bad_stateid;
2152 lock_sop = find_lockstateowner(&lock->v.new.owner,
2153 &lock->v.new.clientid);
2156 status = nfserr_resource;
2157 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2159 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner,
2160 fp, open_stp)) == NULL)
2162 /* bump the open seqid used to create the lock */
2163 open_sop->so_seqid++;
2165 /* lock (lock owner + lock stateid) already exists */
2166 status = nfs4_preprocess_seqid_op(current_fh,
2167 lock->lk_old_lock_seqid,
2168 &lock->lk_old_lock_stateid,
2169 CHECK_FH | LOCK_STATE,
2170 &lock->lk_stateowner, &lock_stp, NULL);
2174 /* lock->lk_stateowner and lock_stp have been created or found */
2175 filp = &lock_stp->st_vfs_file;
2177 if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2178 printk("NFSD: nfsd4_lock: permission denied!\n");
2182 switch (lock->lk_type) {
2185 file_lock.fl_type = F_RDLCK;
2188 case NFS4_WRITEW_LT:
2189 file_lock.fl_type = F_WRLCK;
2192 status = nfserr_inval;
2195 file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
2196 file_lock.fl_pid = lockownerid_hashval(lock->lk_stateowner->so_id);
2197 file_lock.fl_file = filp;
2198 file_lock.fl_flags = FL_POSIX;
2199 file_lock.fl_notify = NULL;
2200 file_lock.fl_insert = NULL;
2201 file_lock.fl_remove = NULL;
2203 file_lock.fl_start = lock->lk_offset;
2204 if ((lock->lk_length == ~(u64)0) ||
2205 LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
2206 file_lock.fl_end = ~(u64)0;
2208 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
2209 nfs4_transform_lock_offset(&file_lock);
2212 * Try to lock the file in the VFS.
2213 * Note: locks.c uses the BKL to protect the inode's lock list.
2216 status = posix_lock_file(filp, &file_lock);
2217 dprintk("NFSD: nfsd4_lock: posix_test_lock passed. posix_lock_file status %d\n",status);
2219 case 0: /* success! */
2220 update_stateid(&lock_stp->st_stateid);
2221 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid,
2225 goto conflicting_lock;
2227 status = nfserr_deadlock;
2229 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
2230 goto out_destroy_new_stateid;
2234 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2235 status = nfserr_denied;
2236 /* XXX There is a race here. Future patch needed to provide
2237 * an atomic posix_lock_and_test_file
2239 if (!(conflock = posix_test_lock(filp, &file_lock))) {
2240 status = nfserr_serverfault;
2243 nfs4_set_lock_denied(conflock, &lock->lk_denied);
2245 out_destroy_new_stateid:
2246 if (lock->lk_is_new) {
2247 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2249 * An error encountered after instantiation of the new
2250 * stateid has forced us to destroy it.
2252 if (!seqid_mutating_err(status))
2253 open_sop->so_seqid--;
2255 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
2265 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2267 struct inode *inode;
2268 struct nfs4_stateowner *sop;
2270 struct file_lock file_lock;
2271 struct file_lock *conflicting_lock;
2272 unsigned int strhashval;
2275 if (nfs4_in_grace())
2276 return nfserr_grace;
2278 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
2279 return nfserr_inval;
2281 lockt->lt_stateowner = NULL;
2284 status = nfserr_stale_clientid;
2285 if (STALE_CLIENTID(&lockt->lt_clientid)) {
2286 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2290 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2291 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2292 if (status == nfserr_symlink)
2293 status = nfserr_inval;
2297 inode = current_fh->fh_dentry->d_inode;
2298 switch (lockt->lt_type) {
2301 file_lock.fl_type = F_RDLCK;
2304 case NFS4_WRITEW_LT:
2305 file_lock.fl_type = F_WRLCK;
2308 printk("NFSD: nfs4_lockt: bad lock type!\n");
2309 status = nfserr_inval;
2313 strhashval = lock_ownerstr_hashval(inode,
2314 lockt->lt_clientid.cl_id, lockt->lt_owner);
2316 find_lockstateowner_str(strhashval, &lockt->lt_owner,
2317 &lockt->lt_clientid,
2318 &lockt->lt_stateowner);
2319 sop = lockt->lt_stateowner;
2321 file_lock.fl_owner = (fl_owner_t) sop;
2322 file_lock.fl_pid = lockownerid_hashval(sop->so_id);
2324 file_lock.fl_owner = NULL;
2325 file_lock.fl_pid = 0;
2327 file_lock.fl_flags = FL_POSIX;
2329 file_lock.fl_start = lockt->lt_offset;
2330 if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2331 file_lock.fl_end = ~(u64)0;
2333 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2335 nfs4_transform_lock_offset(&file_lock);
2337 /* posix_test_lock uses the struct file _only_ to resolve the inode.
2338 * since LOCKT doesn't require an OPEN, and therefore a struct
2339 * file may not exist, pass posix_test_lock a struct file with
2340 * only the dentry:inode set.
2342 memset(&file, 0, sizeof (struct file));
2343 file.f_dentry = current_fh->fh_dentry;
2346 conflicting_lock = posix_test_lock(&file, &file_lock);
2347 if (conflicting_lock) {
2348 status = nfserr_denied;
2349 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2352 nfs4_unlock_state();
2357 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2359 struct nfs4_stateid *stp;
2360 struct file *filp = NULL;
2361 struct file_lock file_lock;
2364 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2365 (long long) locku->lu_offset,
2366 (long long) locku->lu_length);
2368 if (check_lock_length(locku->lu_offset, locku->lu_length))
2369 return nfserr_inval;
2371 locku->lu_stateowner = NULL;
2374 if ((status = nfs4_preprocess_seqid_op(current_fh,
2377 CHECK_FH | LOCK_STATE,
2378 &locku->lu_stateowner, &stp, NULL)))
2381 filp = &stp->st_vfs_file;
2383 file_lock.fl_type = F_UNLCK;
2384 file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2385 file_lock.fl_pid = lockownerid_hashval(locku->lu_stateowner->so_id);
2386 file_lock.fl_file = filp;
2387 file_lock.fl_flags = FL_POSIX;
2388 file_lock.fl_notify = NULL;
2389 file_lock.fl_insert = NULL;
2390 file_lock.fl_remove = NULL;
2391 file_lock.fl_start = locku->lu_offset;
2393 if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2394 file_lock.fl_end = ~(u64)0;
2396 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2397 nfs4_transform_lock_offset(&file_lock);
2400 * Try to unlock the file in the VFS.
2402 status = posix_lock_file(filp, &file_lock);
2404 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2408 * OK, unlock succeeded; the only thing left to do is update the stateid.
2410 update_stateid(&stp->st_stateid);
2411 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2417 status = nfserrno(status);
2423 * 1: locks held by lockowner
2424 * 0: no locks held by lockowner
2427 check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
2429 struct file_lock **flpp;
2430 struct inode *inode = filp->f_dentry->d_inode;
2434 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
2435 if ((*flpp)->fl_owner == (fl_owner_t)lowner)
2445 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2447 clientid_t *clid = &rlockowner->rl_clientid;
2448 struct nfs4_stateowner *local = NULL;
2449 struct xdr_netobj *owner = &rlockowner->rl_owner;
2452 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2453 clid->cl_boot, clid->cl_id);
2455 /* XXX check for lease expiration */
2457 status = nfserr_stale_clientid;
2458 if (STALE_CLIENTID(clid)) {
2459 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2466 local = find_lockstateowner(owner, clid);
2468 struct nfs4_stateid *stp;
2470 /* check for any locks held by any stateid
2471 * associated with the (lock) stateowner */
2472 status = nfserr_locks_held;
2473 list_for_each_entry(stp, &local->so_perfilestate,
2475 if(stp->st_vfs_set) {
2476 if (check_for_locks(&stp->st_vfs_file, local))
2480 /* no locks held by (lock) stateowner */
2482 release_stateowner(local);
2485 nfs4_unlock_state();
2489 static inline struct nfs4_client_reclaim *
2490 alloc_reclaim(int namelen)
2492 struct nfs4_client_reclaim *crp = NULL;
2494 crp = kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
2497 crp->cr_name.data = kmalloc(namelen, GFP_KERNEL);
2498 if (!crp->cr_name.data) {
2506 * failure => all reset bets are off, nfserr_no_grace...
2509 nfs4_client_to_reclaim(struct nfs4_client *clp)
2511 unsigned int strhashval;
2512 struct nfs4_client_reclaim *crp = NULL;
2514 crp = alloc_reclaim(clp->cl_name.len);
2517 strhashval = clientstr_hashval(clp->cl_name.data, clp->cl_name.len);
2518 INIT_LIST_HEAD(&crp->cr_strhash);
2519 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
2520 memcpy(crp->cr_name.data, clp->cl_name.data, clp->cl_name.len);
2521 crp->cr_name.len = clp->cl_name.len;
2522 crp->cr_first_state = clp->cl_first_state;
2523 crp->cr_expired = 0;
2528 nfs4_release_reclaim(void)
2530 struct nfs4_client_reclaim *crp = NULL;
2533 BUG_ON(!nfs4_reclaim_init);
2534 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2535 while (!list_empty(&reclaim_str_hashtbl[i])) {
2536 crp = list_entry(reclaim_str_hashtbl[i].next,
2537 struct nfs4_client_reclaim, cr_strhash);
2538 list_del(&crp->cr_strhash);
2539 kfree(crp->cr_name.data);
2541 reclaim_str_hashtbl_size--;
2544 BUG_ON(reclaim_str_hashtbl_size);
2548 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
2549 struct nfs4_client_reclaim *
2550 nfs4_find_reclaim_client(clientid_t *clid)
2552 unsigned int idhashval = clientid_hashval(clid->cl_id);
2553 unsigned int strhashval;
2554 struct nfs4_client *clp, *client = NULL;
2555 struct nfs4_client_reclaim *crp = NULL;
2558 /* find clientid in conf_id_hashtbl */
2559 list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
2560 if (cmp_clid(&clp->cl_clientid, clid)) {
2568 /* find clp->cl_name in reclaim_str_hashtbl */
2569 strhashval = clientstr_hashval(client->cl_name.data,
2570 client->cl_name.len);
2571 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
2572 if(cmp_name(&crp->cr_name, &client->cl_name)) {
2580 * Called from OPEN. Look for clientid in reclaim list.
2583 nfs4_check_open_reclaim(clientid_t *clid)
2585 struct nfs4_client_reclaim *crp;
2587 if ((crp = nfs4_find_reclaim_client(clid)) == NULL)
2588 return nfserr_reclaim_bad;
2589 if (crp->cr_expired)
2590 return nfserr_no_grace;
2596 * Start and stop routines
2600 nfs4_state_init(void)
2607 if (!nfs4_reclaim_init) {
2608 for (i = 0; i < CLIENT_HASH_SIZE; i++)
2609 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
2610 reclaim_str_hashtbl_size = 0;
2611 nfs4_reclaim_init = 1;
2613 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2614 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
2615 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
2616 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
2617 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
2619 for (i = 0; i < FILE_HASH_SIZE; i++) {
2620 INIT_LIST_HEAD(&file_hashtbl[i]);
2622 for (i = 0; i < OWNER_HASH_SIZE; i++) {
2623 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
2624 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
2626 for (i = 0; i < STATEID_HASH_SIZE; i++) {
2627 INIT_LIST_HEAD(&stateid_hashtbl[i]);
2628 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
2630 for (i = 0; i < LOCK_HASH_SIZE; i++) {
2631 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
2632 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
2634 memset(&zerostateid, 0, sizeof(stateid_t));
2635 memset(&onestateid, ~0, sizeof(stateid_t));
2637 INIT_LIST_HEAD(&close_lru);
2638 INIT_LIST_HEAD(&client_lru);
2639 boot_time = get_seconds();
2640 grace_time = max(old_lease_time, lease_time);
2641 if (reclaim_str_hashtbl_size == 0)
2644 printk("NFSD: starting %ld-second grace period\n", grace_time);
2645 grace_end = boot_time + grace_time;
2646 INIT_WORK(&laundromat_work,laundromat_main, NULL);
2647 schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
2654 return get_seconds() < grace_end;
2660 printk("NFSD: ERROR in reboot recovery. State reclaims will fail.\n");
2661 grace_end = get_seconds();
2665 nfs4_lease_time(void)
2671 __nfs4_state_shutdown(void)
2674 struct nfs4_client *clp = NULL;
2676 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2677 while (!list_empty(&conf_id_hashtbl[i])) {
2678 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
2681 while (!list_empty(&unconf_str_hashtbl[i])) {
2682 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
2686 release_all_files();
2687 cancel_delayed_work(&laundromat_work);
2688 flush_scheduled_work();
2690 dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2691 list_add_perfile, list_del_perfile);
2692 dprintk("NFSD: add_perclient %d del_perclient %d\n",
2693 add_perclient, del_perclient);
2694 dprintk("NFSD: alloc_file %d free_file %d\n",
2695 alloc_file, free_file);
2696 dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2697 alloc_sowner, alloc_lsowner, free_sowner);
2698 dprintk("NFSD: vfsopen %d vfsclose %d\n",
2703 nfs4_state_shutdown(void)
2706 nfs4_release_reclaim();
2707 __nfs4_state_shutdown();
2708 nfs4_unlock_state();
2712 * Called when leasetime is changed.
2714 * if nfsd is not started, simply set the global lease.
2716 * if nfsd(s) are running, lease change requires nfsv4 state to be reset.
2717 * e.g: boot_time is reset, existing nfs4_client structs are
2718 * used to fill reclaim_str_hashtbl, then all state (except for the
2719 * reclaim_str_hashtbl) is re-initialized.
2721 * if the old lease time is greater than the new lease time, the grace
2722 * period needs to be set to the old lease time to allow clients to reclaim
2723 * their state. XXX - we may want to set the grace period == lease time
2724 * after an initial grace period == old lease time
2726 * if an error occurs in this process, the new lease is set, but the server
2727 * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
2728 * which means OPEN/LOCK/READ/WRITE will fail during grace period.
2730 * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
2731 * OPEN and LOCK reclaims.
2734 nfs4_reset_lease(time_t leasetime)
2736 struct nfs4_client *clp;
2739 printk("NFSD: New leasetime %ld\n",leasetime);
2743 old_lease_time = lease_time;
2744 lease_time = leasetime;
2746 nfs4_release_reclaim();
2748 /* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
2749 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2750 list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
2751 if (!nfs4_client_to_reclaim(clp)) {
2752 nfs4_release_reclaim();
2755 reclaim_str_hashtbl_size++;
2759 __nfs4_state_shutdown();
2761 nfs4_unlock_state();