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/nfs4.h>
47 #include <linux/nfsd/state.h>
48 #include <linux/nfsd/xdr4.h>
50 #define NFSDDBG_FACILITY NFSDDBG_PROC
54 static u32 current_clientid = 1;
55 static u32 current_ownerid;
56 static u32 current_fileid;
58 stateid_t zerostateid; /* bits all 0 */
59 stateid_t onestateid; /* bits all 1 */
62 u32 list_add_perfile = 0;
63 u32 list_del_perfile = 0;
64 u32 add_perclient = 0;
65 u32 del_perclient = 0;
74 /* forward declarations */
75 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
80 * protects clientid_hashtbl[], clientstr_hashtbl[],
81 * unconfstr_hashtbl[], uncofid_hashtbl[].
83 static struct semaphore client_sema;
92 nfs4_unlock_state(void)
98 opaque_hashval(const void *ptr, int nbytes)
100 unsigned char *cptr = (unsigned char *) ptr;
110 /* forward declarations */
111 static void release_stateowner(struct nfs4_stateowner *sop);
112 static void release_stateid(struct nfs4_stateid *stp, int flags);
113 static void release_file(struct nfs4_file *fp);
120 /* Hash tables for nfs4_clientid state */
121 #define CLIENT_HASH_BITS 4
122 #define CLIENT_HASH_SIZE (1 << CLIENT_HASH_BITS)
123 #define CLIENT_HASH_MASK (CLIENT_HASH_SIZE - 1)
125 #define clientid_hashval(id) \
126 ((id) & CLIENT_HASH_MASK)
127 #define clientstr_hashval(name, namelen) \
128 (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
130 /* conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
131 * setclientid_confirmed info.
133 * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
136 * client_lru holds client queue ordered by nfs4_client.cl_time
139 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
140 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
141 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
142 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
143 static struct list_head client_lru;
146 renew_client(struct nfs4_client *clp)
149 * Move client to the end to the LRU list.
151 dprintk("renewing client (clientid %08x/%08x)\n",
152 clp->cl_clientid.cl_boot,
153 clp->cl_clientid.cl_id);
154 list_move_tail(&clp->cl_lru, &client_lru);
155 clp->cl_time = get_seconds();
158 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
160 STALE_CLIENTID(clientid_t *clid)
162 if (clid->cl_boot == boot_time)
164 dprintk("NFSD stale clientid (%08x/%08x)\n",
165 clid->cl_boot, clid->cl_id);
170 * XXX Should we use a slab cache ?
171 * This type of memory management is somewhat inefficient, but we use it
172 * anyway since SETCLIENTID is not a common operation.
174 static inline struct nfs4_client *
175 alloc_client(struct xdr_netobj name)
177 struct nfs4_client *clp;
179 if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) {
180 memset(clp, 0, sizeof(*clp));
181 if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) {
182 memcpy(clp->cl_name.data, name.data, name.len);
183 clp->cl_name.len = name.len;
194 free_client(struct nfs4_client *clp)
196 kfree(clp->cl_name.data);
201 expire_client(struct nfs4_client *clp)
203 struct nfs4_stateowner *sop;
205 dprintk("NFSD: expire_client\n");
206 list_del(&clp->cl_idhash);
207 list_del(&clp->cl_strhash);
208 list_del(&clp->cl_lru);
209 while (!list_empty(&clp->cl_perclient)) {
210 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
211 release_stateowner(sop);
216 static struct nfs4_client *
217 create_client(struct xdr_netobj name) {
218 struct nfs4_client *clp;
220 if(!(clp = alloc_client(name)))
222 INIT_LIST_HEAD(&clp->cl_idhash);
223 INIT_LIST_HEAD(&clp->cl_strhash);
224 INIT_LIST_HEAD(&clp->cl_perclient);
225 INIT_LIST_HEAD(&clp->cl_lru);
231 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
232 memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
236 copy_clid(struct nfs4_client *target, struct nfs4_client *source) {
237 target->cl_clientid.cl_boot = source->cl_clientid.cl_boot;
238 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
242 copy_cred(struct svc_cred *target, struct svc_cred *source) {
245 target->cr_uid = source->cr_uid;
246 target->cr_gid = source->cr_gid;
247 for(i = 0; i < NGROUPS; i++)
248 target->cr_groups[i] = source->cr_groups[i];
252 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
255 return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
259 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
260 return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
264 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
265 return((cl1->cl_boot == cl2->cl_boot) &&
266 (cl1->cl_id == cl2->cl_id));
269 /* XXX what about NGROUP */
271 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
272 return((cr1->cr_uid == cr2->cr_uid) &&
273 (cr1->cr_gid == cr2->cr_gid));
278 gen_clid(struct nfs4_client *clp) {
279 clp->cl_clientid.cl_boot = boot_time;
280 clp->cl_clientid.cl_id = current_clientid++;
284 gen_confirm(struct nfs4_client *clp) {
289 p = (u32 *)clp->cl_confirm.data;
295 check_name(struct xdr_netobj name) {
299 if (name.len > NFS4_OPAQUE_LIMIT) {
300 printk("NFSD: check_name: name too long(%d)!\n", name.len);
307 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
309 unsigned int idhashval;
311 list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
312 idhashval = clientid_hashval(clp->cl_clientid.cl_id);
313 list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
314 list_add_tail(&clp->cl_lru, &client_lru);
315 clp->cl_time = get_seconds();
319 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
321 unsigned int strhashval;
323 dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
324 list_del_init(&clp->cl_strhash);
325 list_del_init(&clp->cl_idhash);
326 list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
327 strhashval = clientstr_hashval(clp->cl_name.data,
329 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
334 * RFC 3010 has a complex implmentation description of processing a
335 * SETCLIENTID request consisting of 5 bullets, labeled as
336 * CASE0 - CASE4 below.
339 * callback information will be processed in a future patch
341 * an unconfirmed record is added when:
342 * NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
343 * CASE 1: confirmed record found with matching name, principal,
344 * verifier, and clientid.
345 * CASE 2: confirmed record found with matching name, principal,
346 * and there is no unconfirmed record with matching
349 * an unconfirmed record is replaced when:
350 * CASE 3: confirmed record found with matching name, principal,
351 * and an unconfirmed record is found with matching
352 * name, principal, and with clientid and
353 * confirm that does not match the confirmed record.
354 * CASE 4: there is no confirmed record with matching name and
355 * principal. there is an unconfirmed record with
356 * matching name, principal.
358 * an unconfirmed record is deleted when:
359 * CASE 1: an unconfirmed record that matches input name, verifier,
360 * and confirmed clientid.
361 * CASE 4: any unconfirmed records with matching name and principal
362 * that exist after an unconfirmed record has been replaced
363 * as described above.
367 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
369 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
370 struct xdr_netobj clname = {
371 .len = setclid->se_namelen,
372 .data = setclid->se_name,
374 nfs4_verifier clverifier = setclid->se_verf;
375 unsigned int strhashval;
376 struct nfs4_client * conf, * unconf, * new, * clp;
378 struct list_head *pos, *next;
380 status = nfserr_inval;
381 if (!check_name(clname))
385 * XXX The Duplicate Request Cache (DRC) has been checked (??)
386 * We get here on a DRC miss.
389 strhashval = clientstr_hashval(clname.data, clname.len);
393 list_for_each_safe(pos, next, &conf_str_hashtbl[strhashval]) {
394 clp = list_entry(pos, struct nfs4_client, cl_strhash);
395 if (!cmp_name(&clp->cl_name, &clname))
399 * clname match, confirmed, different principal
400 * or different ip_address
402 status = nfserr_clid_inuse;
403 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
404 printk("NFSD: setclientid: string in use by client"
405 "(clientid %08x/%08x)\n",
406 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
409 if (clp->cl_addr != ip_addr) {
410 printk("NFSD: setclientid: string in use by client"
411 "(clientid %08x/%08x)\n",
412 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
417 * cl_name match from a previous SETCLIENTID operation
418 * XXX check for additional matches?
424 list_for_each_safe(pos, next, &unconf_str_hashtbl[strhashval]) {
425 clp = list_entry(pos, struct nfs4_client, cl_strhash);
426 if (!cmp_name(&clp->cl_name, &clname))
428 /* cl_name match from a previous SETCLIENTID operation */
432 status = nfserr_resource;
436 * placed first, because it is the normal case.
439 expire_client(unconf);
440 if (!(new = create_client(clname)))
442 copy_verf(new, &clverifier);
443 new->cl_addr = ip_addr;
444 copy_cred(&new->cl_cred,&rqstp->rq_cred);
447 add_to_unconfirmed(new, strhashval);
448 } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
451 * cl_name match, confirmed, principal match
452 * verifier match: probable callback update
454 * remove any unconfirmed nfs4_client with
455 * matching cl_name, cl_verifier, and cl_clientid
457 * create and insert an unconfirmed nfs4_client with same
458 * cl_name, cl_verifier, and cl_clientid as existing
459 * nfs4_client, but with the new callback info and a
463 cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
464 cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
465 expire_client(unconf);
467 if (!(new = create_client(clname)))
469 copy_verf(new,&conf->cl_verifier);
470 new->cl_addr = ip_addr;
471 copy_cred(&new->cl_cred,&rqstp->rq_cred);
472 copy_clid(new, conf);
474 add_to_unconfirmed(new,strhashval);
475 } else if (!unconf) {
478 * clname match, confirmed, principal match
479 * verfier does not match
480 * no unconfirmed. create a new unconfirmed nfs4_client
481 * using input clverifier, clname, and callback info
482 * and generate a new cl_clientid and cl_confirm.
484 if (!(new = create_client(clname)))
486 copy_verf(new,&clverifier);
487 new->cl_addr = ip_addr;
488 copy_cred(&new->cl_cred,&rqstp->rq_cred);
491 add_to_unconfirmed(new, strhashval);
492 } else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
493 !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
496 * confirmed found (name, principal match)
497 * confirmed verifier does not match input clverifier
499 * unconfirmed found (name match)
500 * confirmed->cl_clientid != unconfirmed->cl_clientid and
501 * confirmed->cl_confirm != unconfirmed->cl_confirm
503 * remove unconfirmed.
505 * create an unconfirmed nfs4_client
506 * with same cl_name as existing confirmed nfs4_client,
507 * but with new callback info, new cl_clientid,
508 * new cl_verifier and a new cl_confirm
510 expire_client(unconf);
511 if (!(new = create_client(clname)))
513 copy_verf(new,&clverifier);
514 new->cl_addr = ip_addr;
515 copy_cred(&new->cl_cred,&rqstp->rq_cred);
518 add_to_unconfirmed(new, strhashval);
520 /* No cases hit !!! */
521 status = nfserr_inval;
525 setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
526 setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
527 memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
528 printk(KERN_INFO "NFSD: this client will not receive delegations\n");
537 * RFC 3010 has a complex implmentation description of processing a
538 * SETCLIENTID_CONFIRM request consisting of 4 bullets describing
539 * processing on a DRC miss, labeled as CASE1 - CASE4 below.
541 * NOTE: callback information will be processed here in a future patch
544 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
546 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
547 unsigned int idhashval;
548 struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
549 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
550 clientid_t * clid = &setclientid_confirm->sc_clientid;
551 struct list_head *pos, *next;
554 status = nfserr_stale_clientid;
555 if (STALE_CLIENTID(clid))
558 * XXX The Duplicate Request Cache (DRC) has been checked (??)
559 * We get here on a DRC miss.
562 idhashval = clientid_hashval(clid->cl_id);
564 list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
565 clp = list_entry(pos, struct nfs4_client, cl_idhash);
566 if (!cmp_clid(&clp->cl_clientid, clid))
569 status = nfserr_inval;
571 * Found a record for this clientid. If the IP addresses
572 * don't match, return ERR_INVAL just as if the record had
575 if (clp->cl_addr != ip_addr) {
576 printk("NFSD: setclientid: string in use by client"
577 "(clientid %08x/%08x)\n",
578 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
584 list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) {
585 clp = list_entry(pos, struct nfs4_client, cl_idhash);
586 if (!cmp_clid(&clp->cl_clientid, clid))
588 status = nfserr_inval;
589 if (clp->cl_addr != ip_addr) {
590 printk("NFSD: setclientid: string in use by client"
591 "(clientid %08x/%08x)\n",
592 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
599 * unconf record that matches input clientid and input confirm.
600 * conf record that matches input clientid.
601 * conf and unconf records match names, verifiers
603 if ((conf && unconf) &&
604 (cmp_verf(&unconf->cl_confirm, &confirm)) &&
605 (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
606 (cmp_name(&conf->cl_name,&unconf->cl_name)) &&
607 (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
608 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred))
609 status = nfserr_clid_inuse;
612 move_to_confirmed(unconf, idhashval);
618 * conf record that matches input clientid.
619 * if unconf record that matches input clientid, then unconf->cl_name
620 * or unconf->cl_verifier don't match the conf record.
622 if ((conf && !unconf) ||
624 (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
625 !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
626 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
627 status = nfserr_clid_inuse;
634 * conf record not found.
635 * unconf record found.
636 * unconf->cl_confirm matches input confirm
638 if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
639 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
640 status = nfserr_clid_inuse;
643 move_to_confirmed(unconf, idhashval);
648 * conf record not found, or if conf, then conf->cl_confirm does not
649 * match input confirm.
650 * unconf record not found, or if unconf, then unconf->cl_confirm
651 * does not match input confirm.
653 if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
654 (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
655 status = nfserr_stale_clientid;
658 /* check that we have hit one of the cases...*/
659 status = nfserr_inval;
662 /* XXX if status == nfs_ok, probe callback path */
668 * Open owner state (share locks)
671 /* hash tables for nfs4_stateowner */
672 #define OWNER_HASH_BITS 8
673 #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS)
674 #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1)
676 #define ownerid_hashval(id) \
677 ((id) & OWNER_HASH_MASK)
678 #define ownerstr_hashval(clientid, ownername) \
679 (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
681 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
682 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
684 /* hash table for nfs4_file */
685 #define FILE_HASH_BITS 8
686 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
687 #define FILE_HASH_MASK (FILE_HASH_SIZE - 1)
688 /* hash table for (open)nfs4_stateid */
689 #define STATEID_HASH_BITS 10
690 #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
691 #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1)
693 #define file_hashval(x) \
694 hash_ptr(x, FILE_HASH_BITS)
695 #define stateid_hashval(owner_id, file_id) \
696 (((owner_id) + (file_id)) & STATEID_HASH_MASK)
698 static struct list_head file_hashtbl[FILE_HASH_SIZE];
699 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
701 /* OPEN Share state helper functions */
702 static inline struct nfs4_file *
703 alloc_init_file(unsigned int hashval, struct inode *ino) {
704 struct nfs4_file *fp;
705 if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
706 INIT_LIST_HEAD(&fp->fi_hash);
707 INIT_LIST_HEAD(&fp->fi_perfile);
708 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
709 fp->fi_inode = igrab(ino);
710 fp->fi_id = current_fileid++;
714 return (struct nfs4_file *)NULL;
718 release_all_files(void)
721 struct nfs4_file *fp;
723 for (i=0;i<FILE_HASH_SIZE;i++) {
724 while (!list_empty(&file_hashtbl[i])) {
725 fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
726 /* this should never be more than once... */
727 if(!list_empty(&fp->fi_perfile)) {
728 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
735 static inline struct nfs4_stateowner *
736 alloc_stateowner(struct xdr_netobj *owner)
738 struct nfs4_stateowner *sop;
740 if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
741 if((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
742 memcpy(sop->so_owner.data, owner->data, owner->len);
743 sop->so_owner.len = owner->len;
748 return (struct nfs4_stateowner *)NULL;
751 /* should use a slab cache */
753 free_stateowner(struct nfs4_stateowner *sop) {
755 kfree(sop->so_owner.data);
762 static struct nfs4_stateowner *
763 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
764 struct nfs4_stateowner *sop;
765 struct nfs4_replay *rp;
766 unsigned int idhashval;
768 if (!(sop = alloc_stateowner(&open->op_owner)))
769 return (struct nfs4_stateowner *)NULL;
770 idhashval = ownerid_hashval(current_ownerid);
771 INIT_LIST_HEAD(&sop->so_idhash);
772 INIT_LIST_HEAD(&sop->so_strhash);
773 INIT_LIST_HEAD(&sop->so_perclient);
774 INIT_LIST_HEAD(&sop->so_perfilestate);
775 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
776 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
777 list_add(&sop->so_perclient, &clp->cl_perclient);
779 sop->so_is_open_owner = 1;
780 sop->so_id = current_ownerid++;
781 sop->so_client = clp;
782 sop->so_seqid = open->op_seqid;
783 sop->so_confirmed = 0;
784 rp = &sop->so_replay;
785 rp->rp_status = NFSERR_SERVERFAULT;
787 rp->rp_buf = rp->rp_ibuf;
793 release_stateowner(struct nfs4_stateowner *sop)
795 struct nfs4_stateid *stp;
797 list_del_init(&sop->so_idhash);
798 list_del_init(&sop->so_strhash);
799 list_del_init(&sop->so_perclient);
801 while (!list_empty(&sop->so_perfilestate)) {
802 stp = list_entry(sop->so_perfilestate.next,
803 struct nfs4_stateid, st_perfilestate);
804 if(sop->so_is_open_owner)
805 release_stateid(stp, OPEN_STATE);
807 release_stateid(stp, LOCK_STATE);
809 free_stateowner(sop);
813 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
814 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
816 INIT_LIST_HEAD(&stp->st_hash);
817 INIT_LIST_HEAD(&stp->st_perfilestate);
818 INIT_LIST_HEAD(&stp->st_perfile);
819 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
820 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
822 list_add(&stp->st_perfile, &fp->fi_perfile);
823 stp->st_stateowner = sop;
825 stp->st_stateid.si_boot = boot_time;
826 stp->st_stateid.si_stateownerid = sop->so_id;
827 stp->st_stateid.si_fileid = fp->fi_id;
828 stp->st_stateid.si_generation = 0;
829 stp->st_share_access = open->op_share_access;
830 stp->st_share_deny = open->op_share_deny;
834 release_stateid(struct nfs4_stateid *stp, int flags) {
836 list_del_init(&stp->st_hash);
838 list_del_init(&stp->st_perfile);
839 list_del_init(&stp->st_perfilestate);
840 if((stp->st_vfs_set) && (flags & OPEN_STATE)) {
841 nfsd_close(&stp->st_vfs_file);
843 dput(stp->st_vfs_file.f_dentry);
844 mntput(stp->st_vfs_file.f_vfsmnt);
846 /* should use a slab cache */
852 release_file(struct nfs4_file *fp)
855 list_del_init(&fp->fi_hash);
861 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
864 struct nfs4_stateowner *sop = stp->st_stateowner;
865 struct nfs4_file *fp = stp->st_file;
867 dprintk("NFSD: release_state_owner\n");
868 release_stateid(stp, flag);
870 * release unused nfs4_stateowners.
871 * XXX will need to be placed on an open_stateid_lru list to be
872 * released by the laundromat service after the lease period
873 * to enable us to handle CLOSE replay
875 if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) {
876 release_stateowner(sop);
879 /* unused nfs4_file's are releseed. XXX slab cache? */
880 if (list_empty(&fp->fi_perfile)) {
886 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
887 return ((sop->so_owner.len == owner->len) &&
888 !memcmp(sop->so_owner.data, owner->data, owner->len) &&
889 (sop->so_client->cl_clientid.cl_id == clid->cl_id));
892 /* search ownerstr_hashtbl[] for owner */
894 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
895 struct list_head *pos, *next;
896 struct nfs4_stateowner *local = NULL;
898 list_for_each_safe(pos, next, &ownerstr_hashtbl[hashval]) {
899 local = list_entry(pos, struct nfs4_stateowner, so_strhash);
900 if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid))
908 /* see if clientid is in confirmed hash table */
910 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
912 struct list_head *pos, *next;
913 struct nfs4_client *clp;
914 unsigned int idhashval = clientid_hashval(clid->cl_id);
916 list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
917 clp = list_entry(pos, struct nfs4_client, cl_idhash);
918 if (!cmp_clid(&clp->cl_clientid, clid))
927 /* search file_hashtbl[] for file */
929 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
930 struct list_head *pos, *next;
931 struct nfs4_file *local = NULL;
933 list_for_each_safe(pos, next, &file_hashtbl[hashval]) {
934 local = list_entry(pos, struct nfs4_file, fi_hash);
935 if (local->fi_inode == ino) {
944 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
945 if ((stp->st_share_access & open->op_share_deny) ||
946 (stp->st_share_deny & open->op_share_access)) {
953 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
955 struct inode *ino = current_fh->fh_dentry->d_inode;
956 unsigned int fi_hashval;
957 struct nfs4_file *fp;
958 struct nfs4_stateid *stp;
959 struct list_head *pos, *next;
961 dprintk("NFSD: nfs4_share_conflict\n");
963 fi_hashval = file_hashval(ino);
964 if (find_file(fi_hashval, ino, &fp)) {
965 /* Search for conflicting share reservations */
966 list_for_each_safe(pos, next, &fp->fi_perfile) {
967 stp = list_entry(pos, struct nfs4_stateid, st_perfile);
968 if (stp->st_share_deny & deny_type)
969 return nfserr_share_denied;
976 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
980 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
981 status = get_write_access(filp->f_dentry->d_inode);
983 filp->f_mode = FMODE_WRITE;
985 return nfserrno(status);
991 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
993 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
994 put_write_access(filp->f_dentry->d_inode);
995 filp->f_mode = FMODE_READ;
1001 * nfsd4_process_open1()
1002 * lookup stateowner.
1015 nfsd4_process_open1(struct nfsd4_open *open)
1018 clientid_t *clientid = &open->op_clientid;
1019 struct nfs4_client *clp = NULL;
1020 unsigned int strhashval;
1021 struct nfs4_stateowner *sop = NULL;
1023 status = nfserr_inval;
1024 if (!check_name(open->op_owner))
1027 status = nfserr_stale_clientid;
1028 if (STALE_CLIENTID(&open->op_clientid))
1032 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1033 if (find_openstateowner_str(strhashval, open, &sop)) {
1034 open->op_stateowner = sop;
1035 /* check for replay */
1036 if (open->op_seqid == sop->so_seqid){
1037 if (!sop->so_replay.rp_buflen) {
1039 * The original OPEN failed in so spectacularly that we
1040 * don't even have replay data saved! Therefore, we
1041 * have no choice but to continue processing
1042 * this OPEN; presumably, we'll fail again for the same
1045 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1049 /* replay: indicate to calling function */
1050 status = NFSERR_REPLAY_ME;
1053 if (sop->so_confirmed) {
1054 if (open->op_seqid == sop->so_seqid + 1) {
1058 status = nfserr_bad_seqid;
1061 /* If we get here, we received and OPEN for an unconfirmed
1063 * Since the sequid's are different, purge the
1064 * existing nfs4_stateowner, and instantiate a new one.
1066 clp = sop->so_client;
1067 release_stateowner(sop);
1068 goto instantiate_new_owner;
1070 /* nfs4_stateowner not found.
1071 * verify clientid and instantiate new nfs4_stateowner
1072 * if verify fails this is presumably the result of the
1073 * client's lease expiring.
1075 * XXX compare clp->cl_addr with rqstp addr?
1077 status = nfserr_expired;
1078 if (!verify_clientid(&clp, clientid))
1080 instantiate_new_owner:
1081 status = nfserr_resource;
1082 if (!(sop = alloc_init_open_stateowner(strhashval, clp, open)))
1084 open->op_stateowner = sop;
1087 renew_client(sop->so_client);
1089 nfs4_unlock_state();
1094 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1097 struct nfs4_stateowner *sop = open->op_stateowner;
1098 struct nfs4_file *fp;
1100 unsigned int fi_hashval;
1101 struct list_head *pos, *next;
1102 struct nfs4_stateid *stq, *stp = NULL;
1105 status = nfserr_resource;
1109 ino = current_fh->fh_dentry->d_inode;
1112 fi_hashval = file_hashval(ino);
1113 if (find_file(fi_hashval, ino, &fp)) {
1114 /* Search for conflicting share reservations */
1115 status = nfserr_share_denied;
1116 list_for_each_safe(pos, next, &fp->fi_perfile) {
1117 stq = list_entry(pos, struct nfs4_stateid, st_perfile);
1118 if(stq->st_stateowner == sop) {
1122 if (!test_share(stq,open))
1126 /* No nfs4_file found; allocate and init a new one */
1127 status = nfserr_resource;
1128 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1135 status = nfserr_resource;
1136 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1137 GFP_KERNEL)) == NULL)
1140 if (open->op_share_access && NFS4_SHARE_ACCESS_WRITE)
1144 if ((status = nfsd_open(rqstp, current_fh, S_IFREG,
1146 &stp->st_vfs_file)) != 0)
1150 dget(stp->st_vfs_file.f_dentry);
1151 mntget(stp->st_vfs_file.f_vfsmnt);
1153 init_stateid(stp, fp, sop, open);
1154 stp->st_vfs_set = 1;
1156 /* This is an upgrade of an existing OPEN.
1157 * OR the incoming share with the existing
1158 * nfs4_stateid share */
1159 int share_access = open->op_share_access;
1161 share_access &= ~(stp->st_share_access);
1163 /* update the struct file */
1164 if ((status = nfs4_file_upgrade(&stp->st_vfs_file, share_access)))
1166 stp->st_share_access |= share_access;
1167 stp->st_share_deny |= open->op_share_deny;
1168 /* bump the stateid */
1169 update_stateid(&stp->st_stateid);
1171 dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1172 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1173 stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1175 if (open->op_truncate) {
1176 iattr.ia_valid = ATTR_SIZE;
1178 status = nfsd_setattr(rqstp, current_fh, &iattr, 0, (time_t)0);
1182 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1184 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
1187 if (fp && list_empty(&fp->fi_perfile))
1191 * To finish the open response, we just need to set the rflags.
1193 open->op_rflags = 0;
1194 if (!open->op_stateowner->so_confirmed)
1195 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1197 nfs4_unlock_state();
1203 static struct work_struct laundromat_work;
1204 static void laundromat_main(void *);
1205 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1208 nfsd4_renew(clientid_t *clid)
1210 struct nfs4_client *clp;
1211 struct list_head *pos, *next;
1212 unsigned int idhashval;
1216 dprintk("process_renew(%08x/%08x): starting\n",
1217 clid->cl_boot, clid->cl_id);
1218 status = nfserr_stale_clientid;
1219 if (STALE_CLIENTID(clid))
1222 idhashval = clientid_hashval(clid->cl_id);
1223 list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
1224 clp = list_entry(pos, struct nfs4_client, cl_idhash);
1225 if (!cmp_clid(&clp->cl_clientid, clid))
1230 list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) {
1231 clp = list_entry(pos, struct nfs4_client, cl_idhash);
1232 if (!cmp_clid(&clp->cl_clientid, clid))
1238 * Couldn't find an nfs4_client for this clientid.
1239 * Presumably this is because the client took too long to
1240 * RENEW, so return NFS4ERR_EXPIRED.
1242 dprintk("nfsd4_renew: clientid not found!\n");
1243 status = nfserr_expired;
1245 nfs4_unlock_state();
1250 nfs4_laundromat(void)
1252 struct nfs4_client *clp;
1253 struct list_head *pos, *next;
1254 time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1255 time_t t, return_val = NFSD_LEASE_TIME;
1259 dprintk("NFSD: laundromat service - starting, examining clients\n");
1260 list_for_each_safe(pos, next, &client_lru) {
1261 clp = list_entry(pos, struct nfs4_client, cl_lru);
1262 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1263 t = clp->cl_time - cutoff;
1268 dprintk("NFSD: purging unused client (clientid %08x)\n",
1269 clp->cl_clientid.cl_id);
1272 if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1273 return_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1274 nfs4_unlock_state();
1279 laundromat_main(void *not_used)
1283 t = nfs4_laundromat();
1284 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1285 schedule_delayed_work(&laundromat_work, t*HZ);
1288 /* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */
1289 struct nfs4_stateowner *
1290 find_openstateowner_id(u32 st_id) {
1291 struct list_head *pos, *next;
1292 struct nfs4_stateowner *local = NULL;
1293 unsigned int hashval = ownerid_hashval(st_id);
1295 list_for_each_safe(pos, next, &ownerid_hashtbl[hashval]) {
1296 local = list_entry(pos, struct nfs4_stateowner, so_idhash);
1297 if(local->so_id == st_id)
1304 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1306 return (fhp->fh_dentry != stp->st_vfs_file.f_dentry);
1310 STALE_STATEID(stateid_t *stateid)
1312 if (stateid->si_boot == boot_time)
1314 printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1315 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1316 stateid->si_generation);
1322 * Checks for stateid operations
1325 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
1327 struct nfs4_stateid *stp;
1330 dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
1331 stateid->si_boot, stateid->si_stateownerid,
1332 stateid->si_fileid, stateid->si_generation);
1337 status = nfserr_stale_stateid;
1338 if (STALE_STATEID(stateid))
1342 status = nfserr_bad_stateid;
1343 if (!(stp = find_stateid(stateid, flags))) {
1344 dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
1347 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1348 dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
1351 if (!stp->st_stateowner->so_confirmed) {
1352 dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
1355 if (stateid->si_generation > stp->st_stateid.si_generation) {
1356 dprintk("preprocess_stateid_op: future stateid?!\n");
1361 status = nfserr_old_stateid;
1362 if (stateid->si_generation < stp->st_stateid.si_generation) {
1363 dprintk("preprocess_stateid_op: old stateid!\n");
1368 renew_client(stp->st_stateowner->so_client);
1375 * Checks for sequence id mutating operations.
1378 nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp)
1381 struct nfs4_stateid *stp;
1382 struct nfs4_stateowner *sop;
1384 dprintk("NFSD: preprocess_seqid_op: seqid=%d "
1385 "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
1386 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1387 stateid->si_generation);
1392 status = nfserr_bad_stateid;
1393 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
1394 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
1398 status = nfserr_stale_stateid;
1399 if (STALE_STATEID(stateid))
1402 * We return BAD_STATEID if filehandle doesn't match stateid,
1403 * the confirmed flag is incorrecly set, or the generation
1404 * number is incorrect.
1405 * If there is no entry in the openfile table for this id,
1406 * we can't always return BAD_STATEID;
1407 * this might be a retransmitted CLOSE which has arrived after
1408 * the openfile has been released.
1410 if (!(stp = find_stateid(stateid, flags)))
1411 goto no_nfs4_stateid;
1413 status = nfserr_bad_stateid;
1415 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1416 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
1421 *sopp = sop = stp->st_stateowner;
1424 * We now validate the seqid and stateid generation numbers.
1425 * For the moment, we ignore the possibility of
1426 * generation number wraparound.
1428 if (seqid != sop->so_seqid + 1)
1431 if (sop->so_confirmed) {
1432 if (flags & CONFIRM) {
1433 printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
1438 if (!(flags & CONFIRM)) {
1439 printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
1443 if (stateid->si_generation > stp->st_stateid.si_generation) {
1444 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
1448 status = nfserr_old_stateid;
1449 if (stateid->si_generation < stp->st_stateid.si_generation) {
1450 printk("NFSD: preprocess_seqid_op: old stateid!\n");
1453 /* XXX renew the client lease here */
1462 * We determine whether this is a bad stateid or a replay,
1463 * starting by trying to look up the stateowner.
1464 * If stateowner is not found - stateid is bad.
1466 if (!(sop = find_openstateowner_id(stateid->si_stateownerid))) {
1467 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
1468 status = nfserr_bad_stateid;
1473 if (seqid == sop->so_seqid) {
1474 printk("NFSD: preprocess_seqid_op: retransmission?\n");
1475 /* indicate replay to calling function */
1476 status = NFSERR_REPLAY_ME;
1478 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
1480 status = nfserr_bad_seqid;
1485 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
1488 struct nfs4_stateowner *sop;
1489 struct nfs4_stateid *stp;
1491 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
1492 (int)current_fh->fh_dentry->d_name.len,
1493 current_fh->fh_dentry->d_name.name);
1494 oc->oc_stateowner = NULL;
1497 if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
1498 &oc->oc_req_stateid,
1499 CHECK_FH | CONFIRM | OPEN_STATE,
1500 &oc->oc_stateowner, &stp)))
1503 sop = oc->oc_stateowner;
1504 sop->so_confirmed = 1;
1505 update_stateid(&stp->st_stateid);
1506 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
1507 dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d "
1508 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
1509 stp->st_stateid.si_boot,
1510 stp->st_stateid.si_stateownerid,
1511 stp->st_stateid.si_fileid,
1512 stp->st_stateid.si_generation);
1515 nfs4_unlock_state();
1519 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
1522 struct nfs4_stateid *stp;
1524 dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
1525 (int)current_fh->fh_dentry->d_name.len,
1526 current_fh->fh_dentry->d_name.name);
1529 if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid,
1531 CHECK_FH | OPEN_STATE,
1532 &od->od_stateowner, &stp)))
1535 status = nfserr_inval;
1536 if (od->od_share_access & ~stp->st_share_access) {
1537 dprintk("NFSD:access not a subset current=%08x, desired=%08x\n",
1538 stp->st_share_access, od->od_share_access);
1541 if (od->od_share_deny & ~stp->st_share_deny) {
1542 dprintk("NFSD:deny not a subset current=%08x, desired=%08x\n",
1543 stp->st_share_deny, od->od_share_deny);
1546 nfs4_file_downgrade(&stp->st_vfs_file,
1547 stp->st_share_access & ~od->od_share_access);
1548 stp->st_share_access = od->od_share_access;
1549 stp->st_share_deny = od->od_share_deny;
1550 update_stateid(&stp->st_stateid);
1551 memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
1554 nfs4_unlock_state();
1559 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
1562 struct nfs4_stateid *stp;
1564 dprintk("NFSD: nfsd4_close on file %.*s\n",
1565 (int)current_fh->fh_dentry->d_name.len,
1566 current_fh->fh_dentry->d_name.name);
1569 if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid,
1571 CHECK_FH | OPEN_STATE,
1572 &close->cl_stateowner, &stp)))
1575 * Return success, but first update the stateid.
1578 update_stateid(&stp->st_stateid);
1579 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
1581 /* release_state_owner() calls nfsd_close() if needed */
1582 release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
1584 nfs4_unlock_state();
1589 * Lock owner state (byte-range locks)
1591 #define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
1592 #define LOCK_HASH_BITS 8
1593 #define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS)
1594 #define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1)
1596 #define lockownerid_hashval(id) \
1597 ((id) & LOCK_HASH_MASK)
1598 #define lock_ownerstr_hashval(x, clientid, ownername) \
1599 ((file_hashval(x) + (clientid) + opaque_hashval((ownername.data), (ownername.len))) & LOCK_HASH_MASK)
1601 static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
1602 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
1603 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
1605 struct nfs4_stateid *
1606 find_stateid(stateid_t *stid, int flags)
1608 struct list_head *pos, *next;
1609 struct nfs4_stateid *local = NULL;
1610 u32 st_id = stid->si_stateownerid;
1611 u32 f_id = stid->si_fileid;
1612 unsigned int hashval;
1614 dprintk("NFSD: find_stateid flags 0x%x\n",flags);
1615 if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
1616 hashval = stateid_hashval(st_id, f_id);
1617 list_for_each_safe(pos, next, &lockstateid_hashtbl[hashval]) {
1618 local = list_entry(pos, struct nfs4_stateid, st_hash);
1619 if((local->st_stateid.si_stateownerid == st_id) &&
1620 (local->st_stateid.si_fileid == f_id))
1624 if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
1625 hashval = stateid_hashval(st_id, f_id);
1626 list_for_each_safe(pos, next, &stateid_hashtbl[hashval]) {
1627 local = list_entry(pos, struct nfs4_stateid, st_hash);
1628 if((local->st_stateid.si_stateownerid == st_id) &&
1629 (local->st_stateid.si_fileid == f_id))
1633 printk("NFSD: find_stateid: ERROR: no state flag\n");
1639 * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
1640 * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
1641 * byte, because of sign extension problems. Since NFSv4 calls for 64-bit
1642 * locking, this prevents us from being completely protocol-compliant. The
1643 * real solution to this problem is to start using unsigned file offsets in
1644 * the VFS, but this is a very deep change!
1647 nfs4_transform_lock_offset(struct file_lock *lock)
1649 if (lock->fl_start < 0)
1650 lock->fl_start = OFFSET_MAX;
1651 if (lock->fl_end < 0)
1652 lock->fl_end = OFFSET_MAX;
1656 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
1658 struct list_head *pos, *next;
1659 struct nfs4_stateowner *local = NULL;
1662 if (hashval >= LOCK_HASH_SIZE)
1664 list_for_each_safe(pos, next, &lock_ownerid_hashtbl[hashval]) {
1665 local = list_entry(pos, struct nfs4_stateowner, so_idhash);
1677 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
1679 struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
1681 deny->ld_sop = NULL;
1682 if (nfs4_verify_lock_stateowner(sop, fl->fl_pid))
1684 deny->ld_start = fl->fl_start;
1685 deny->ld_length = ~(u64)0;
1686 if (fl->fl_end != ~(u64)0)
1687 deny->ld_length = fl->fl_end - fl->fl_start + 1;
1688 deny->ld_type = NFS4_READ_LT;
1689 if (fl->fl_type != F_RDLCK)
1690 deny->ld_type = NFS4_WRITE_LT;
1695 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
1696 struct list_head *pos, *next;
1697 struct nfs4_stateowner *local = NULL;
1699 list_for_each_safe(pos, next, &lock_ownerstr_hashtbl[hashval]) {
1700 local = list_entry(pos, struct nfs4_stateowner, so_strhash);
1701 if(!cmp_owner_str(local, owner, clid))
1711 * Alloc a lock owner structure.
1712 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
1715 * strhashval = lock_ownerstr_hashval
1716 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
1719 static struct nfs4_stateowner *
1720 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_lock *lock) {
1721 struct nfs4_stateowner *sop;
1722 struct nfs4_replay *rp;
1723 unsigned int idhashval;
1725 if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
1726 return (struct nfs4_stateowner *)NULL;
1727 idhashval = lockownerid_hashval(current_ownerid);
1728 INIT_LIST_HEAD(&sop->so_idhash);
1729 INIT_LIST_HEAD(&sop->so_strhash);
1730 INIT_LIST_HEAD(&sop->so_perclient);
1731 INIT_LIST_HEAD(&sop->so_perfilestate);
1732 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
1733 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
1734 list_add(&sop->so_perclient, &clp->cl_perclient);
1736 sop->so_is_open_owner = 0;
1737 sop->so_id = current_ownerid++;
1738 sop->so_client = clp;
1739 sop->so_seqid = lock->lk_new_lock_seqid - 1;
1740 sop->so_confirmed = 1;
1741 rp = &sop->so_replay;
1742 rp->rp_status = NFSERR_SERVERFAULT;
1744 rp->rp_buf = rp->rp_ibuf;
1749 struct nfs4_stateid *
1750 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
1752 struct nfs4_stateid *stp;
1753 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
1755 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1756 GFP_KERNEL)) == NULL)
1759 INIT_LIST_HEAD(&stp->st_hash);
1760 INIT_LIST_HEAD(&stp->st_perfile);
1761 INIT_LIST_HEAD(&stp->st_perfilestate);
1762 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
1763 list_add(&stp->st_perfile, &fp->fi_perfile);
1765 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
1766 stp->st_stateowner = sop;
1768 stp->st_stateid.si_boot = boot_time;
1769 stp->st_stateid.si_stateownerid = sop->so_id;
1770 stp->st_stateid.si_fileid = fp->fi_id;
1771 stp->st_stateid.si_generation = 0;
1772 stp->st_vfs_file = open_stp->st_vfs_file;
1773 stp->st_vfs_set = open_stp->st_vfs_set;
1774 stp->st_share_access = -1;
1775 stp->st_share_deny = -1;
1785 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
1787 struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
1788 struct nfs4_stateid *lock_stp;
1790 struct file_lock file_lock;
1791 struct file_lock *conflock;
1793 unsigned int strhashval;
1795 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
1796 lock->lk_offset, lock->lk_length);
1798 lock->lk_stateowner = NULL;
1801 if (lock->lk_is_new) {
1803 * Client indicates that this is a new lockowner.
1804 * Use open owner and open stateid to create lock owner and lock
1807 struct nfs4_stateid *open_stp = NULL;
1808 struct nfs4_file *fp;
1810 status = nfserr_stale_clientid;
1811 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
1812 printk("NFSD: nfsd4_lock: clientid is stale!\n");
1815 /* validate and update open stateid and open seqid */
1816 status = nfs4_preprocess_seqid_op(current_fh,
1817 lock->lk_new_open_seqid,
1818 &lock->lk_new_open_stateid,
1819 CHECK_FH | OPEN_STATE,
1820 &open_sop, &open_stp);
1823 /* create lockowner and lock stateid */
1824 fp = open_stp->st_file;
1825 strhashval = lock_ownerstr_hashval(fp->fi_inode,
1826 open_sop->so_client->cl_clientid.cl_id,
1830 * If we already have this lock owner, the client is in
1831 * error (or our bookeeping is wrong!)
1832 * for asking for a 'new lock'.
1834 status = nfserr_bad_stateid;
1835 if (find_lockstateowner_str(strhashval, &lock->v.new.owner,
1836 &lock->v.new.clientid, &lock_sop))
1838 status = nfserr_resource;
1839 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval,
1840 open_sop->so_client, lock)))
1842 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner,
1843 fp, open_stp)) == NULL)
1845 /* bump the open seqid used to create the lock */
1846 open_sop->so_seqid++;
1848 /* lock (lock owner + lock stateid) already exists */
1849 status = nfs4_preprocess_seqid_op(current_fh,
1850 lock->lk_old_lock_seqid,
1851 &lock->lk_old_lock_stateid,
1852 CHECK_FH | LOCK_STATE,
1853 &lock->lk_stateowner, &lock_stp);
1857 /* lock->lk_stateowner and lock_stp have been created or found */
1858 filp = &lock_stp->st_vfs_file;
1860 if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
1861 printk("NFSD: nfsd4_lock: permission denied!\n");
1865 switch (lock->lk_type) {
1868 file_lock.fl_type = F_RDLCK;
1871 case NFS4_WRITEW_LT:
1872 file_lock.fl_type = F_WRLCK;
1875 status = nfserr_inval;
1878 file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
1879 file_lock.fl_pid = lockownerid_hashval(lock->lk_stateowner->so_id);
1880 file_lock.fl_file = filp;
1881 file_lock.fl_flags = FL_POSIX;
1882 file_lock.fl_notify = NULL;
1883 file_lock.fl_insert = NULL;
1884 file_lock.fl_remove = NULL;
1886 file_lock.fl_start = lock->lk_offset;
1887 if ((lock->lk_length == ~(u64)0) ||
1888 LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
1889 file_lock.fl_end = ~(u64)0;
1891 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
1892 nfs4_transform_lock_offset(&file_lock);
1895 * Try to lock the file in the VFS.
1896 * Note: locks.c uses the BKL to protect the inode's lock list.
1899 status = posix_lock_file(filp, &file_lock);
1900 dprintk("NFSD: nfsd4_lock: posix_test_lock passed. posix_lock_file status %d\n",status);
1902 case 0: /* success! */
1903 update_stateid(&lock_stp->st_stateid);
1904 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid,
1908 goto conflicting_lock;
1910 status = nfserr_deadlock;
1912 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
1913 goto out_destroy_new_stateid;
1917 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
1918 status = nfserr_denied;
1919 /* XXX There is a race here. Future patch needed to provide
1920 * an atomic posix_lock_and_test_file
1922 if (!(conflock = posix_test_lock(filp, &file_lock))) {
1923 status = nfserr_serverfault;
1926 nfs4_set_lock_denied(conflock, &lock->lk_denied);
1928 out_destroy_new_stateid:
1929 if (lock->lk_is_new) {
1930 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
1932 * An error encountered after instantiation of the new
1933 * stateid has forced us to destroy it.
1935 if (!seqid_mutating_err(status))
1936 open_sop->so_seqid--;
1938 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
1941 nfs4_unlock_state();
1949 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
1951 struct inode *inode;
1952 struct nfs4_stateowner *sop;
1954 struct file_lock file_lock;
1955 struct file_lock *conflicting_lock;
1956 unsigned int strhashval;
1959 lockt->lt_stateowner = NULL;
1962 status = nfserr_stale_clientid;
1963 if (STALE_CLIENTID(&lockt->lt_clientid)) {
1964 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
1968 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
1969 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
1973 inode = current_fh->fh_dentry->d_inode;
1974 switch (lockt->lt_type) {
1977 file_lock.fl_type = F_RDLCK;
1980 case NFS4_WRITEW_LT:
1981 file_lock.fl_type = F_WRLCK;
1984 printk("NFSD: nfs4_lockt: bad lock type!\n");
1985 status = nfserr_inval;
1989 strhashval = lock_ownerstr_hashval(inode,
1990 lockt->lt_clientid.cl_id, lockt->lt_owner);
1992 if (find_lockstateowner_str(strhashval, &lockt->lt_owner,
1993 &lockt->lt_clientid,
1994 &lockt->lt_stateowner)) {
1995 printk("NFSD: nsfd4_lockt: lookup_lockowner() failed!\n");
1999 sop = lockt->lt_stateowner;
2001 file_lock.fl_owner = (fl_owner_t) sop;
2002 file_lock.fl_pid = lockownerid_hashval(sop->so_id);
2004 file_lock.fl_owner = NULL;
2005 file_lock.fl_pid = 0;
2007 file_lock.fl_flags = FL_POSIX;
2009 file_lock.fl_start = lockt->lt_offset;
2010 if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2011 file_lock.fl_end = ~(u64)0;
2013 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2015 nfs4_transform_lock_offset(&file_lock);
2017 /* posix_test_lock uses the struct file _only_ to resolve the inode.
2018 * since LOCKT doesn't require an OPEN, and therefore a struct
2019 * file may not exist, pass posix_test_lock a struct file with
2020 * only the dentry:inode set.
2022 memset(&file, 0, sizeof (struct file));
2023 file.f_dentry = current_fh->fh_dentry;
2026 conflicting_lock = posix_test_lock(&file, &file_lock);
2027 if (conflicting_lock) {
2028 status = nfserr_denied;
2029 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2032 nfs4_unlock_state();
2037 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2039 struct nfs4_stateid *stp;
2040 struct file *filp = NULL;
2041 struct file_lock file_lock;
2044 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2045 locku->lu_offset, locku->lu_length);
2048 if ((status = nfs4_preprocess_seqid_op(current_fh,
2051 CHECK_FH | LOCK_STATE,
2052 &locku->lu_stateowner, &stp)))
2055 filp = &stp->st_vfs_file;
2057 file_lock.fl_type = F_UNLCK;
2058 file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2059 file_lock.fl_pid = lockownerid_hashval(locku->lu_stateowner->so_id);
2060 file_lock.fl_file = filp;
2061 file_lock.fl_flags = FL_POSIX;
2062 file_lock.fl_notify = NULL;
2063 file_lock.fl_insert = NULL;
2064 file_lock.fl_remove = NULL;
2065 file_lock.fl_start = locku->lu_offset;
2067 if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2068 file_lock.fl_end = ~(u64)0;
2070 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2071 nfs4_transform_lock_offset(&file_lock);
2074 * Try to unlock the file in the VFS.
2076 status = posix_lock_file(filp, &file_lock);
2078 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2082 * OK, unlock succeeded; the only thing left to do is update the stateid.
2084 update_stateid(&stp->st_stateid);
2085 memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2088 nfs4_unlock_state();
2092 status = nfserrno(status);
2097 * Start and stop routines
2101 nfs4_state_init(void)
2107 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2108 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
2109 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
2110 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
2111 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
2113 for (i = 0; i < FILE_HASH_SIZE; i++) {
2114 INIT_LIST_HEAD(&file_hashtbl[i]);
2116 for (i = 0; i < OWNER_HASH_SIZE; i++) {
2117 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
2118 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
2120 for (i = 0; i < STATEID_HASH_SIZE; i++) {
2121 INIT_LIST_HEAD(&stateid_hashtbl[i]);
2122 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
2124 for (i = 0; i < LOCK_HASH_SIZE; i++) {
2125 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
2126 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
2128 memset(&zerostateid, 0, sizeof(stateid_t));
2129 memset(&onestateid, ~0, sizeof(stateid_t));
2131 INIT_LIST_HEAD(&client_lru);
2132 init_MUTEX(&client_sema);
2133 boot_time = get_seconds();
2134 INIT_WORK(&laundromat_work,laundromat_main, NULL);
2135 schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
2141 __nfs4_state_shutdown(void)
2144 struct nfs4_client *clp = NULL;
2146 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2147 while (!list_empty(&conf_id_hashtbl[i])) {
2148 clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
2151 while (!list_empty(&unconf_str_hashtbl[i])) {
2152 clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
2156 release_all_files();
2157 cancel_delayed_work(&laundromat_work);
2158 flush_scheduled_work();
2160 dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2161 list_add_perfile, list_del_perfile);
2162 dprintk("NFSD: add_perclient %d del_perclient %d\n",
2163 add_perclient, del_perclient);
2164 dprintk("NFSD: alloc_file %d free_file %d\n",
2165 alloc_file, free_file);
2166 dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2167 alloc_sowner, alloc_lsowner, free_sowner);
2168 dprintk("NFSD: vfsopen %d vfsclose %d\n",
2173 nfs4_state_shutdown(void)
2176 __nfs4_state_shutdown();
2177 nfs4_unlock_state();