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
++;
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
;
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
)))
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 unhash_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
);
920 while (!list_empty(&sop
->so_perfilestate
)) {
921 stp
= list_entry(sop
->so_perfilestate
.next
,
922 struct nfs4_stateid
, st_perfilestate
);
923 if (sop
->so_is_open_owner
)
924 release_stateid(stp
, OPEN_STATE
);
926 release_stateid(stp
, LOCK_STATE
);
931 release_stateowner(struct nfs4_stateowner
*sop
)
933 unhash_stateowner(sop
);
934 list_del(&sop
->so_close_lru
);
935 free_stateowner(sop
);
939 init_stateid(struct nfs4_stateid
*stp
, struct nfs4_file
*fp
, struct nfs4_stateowner
*sop
, struct nfsd4_open
*open
) {
940 unsigned int hashval
= stateid_hashval(sop
->so_id
, fp
->fi_id
);
942 INIT_LIST_HEAD(&stp
->st_hash
);
943 INIT_LIST_HEAD(&stp
->st_perfilestate
);
944 INIT_LIST_HEAD(&stp
->st_perlockowner
);
945 INIT_LIST_HEAD(&stp
->st_perfile
);
946 list_add(&stp
->st_hash
, &stateid_hashtbl
[hashval
]);
947 list_add(&stp
->st_perfilestate
, &sop
->so_perfilestate
);
949 list_add(&stp
->st_perfile
, &fp
->fi_perfile
);
950 stp
->st_stateowner
= sop
;
952 stp
->st_stateid
.si_boot
= boot_time
;
953 stp
->st_stateid
.si_stateownerid
= sop
->so_id
;
954 stp
->st_stateid
.si_fileid
= fp
->fi_id
;
955 stp
->st_stateid
.si_generation
= 0;
956 stp
->st_access_bmap
= 0;
957 stp
->st_deny_bmap
= 0;
958 __set_bit(open
->op_share_access
, &stp
->st_access_bmap
);
959 __set_bit(open
->op_share_deny
, &stp
->st_deny_bmap
);
963 release_stateid(struct nfs4_stateid
*stp
, int flags
) {
965 list_del(&stp
->st_hash
);
967 list_del(&stp
->st_perfile
);
968 list_del(&stp
->st_perfilestate
);
969 if ((stp
->st_vfs_set
) && (flags
& OPEN_STATE
)) {
970 release_stateid_lockowner(stp
);
971 nfsd_close(stp
->st_vfs_file
);
973 } else if ((stp
->st_vfs_set
) && (flags
& LOCK_STATE
)) {
974 struct file
*filp
= stp
->st_vfs_file
;
976 locks_remove_posix(filp
, (fl_owner_t
) stp
->st_stateowner
);
983 release_file(struct nfs4_file
*fp
)
986 list_del(&fp
->fi_hash
);
992 move_to_close_lru(struct nfs4_stateowner
*sop
)
994 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop
);
996 unhash_stateowner(sop
);
997 list_add_tail(&sop
->so_close_lru
, &close_lru
);
998 sop
->so_time
= get_seconds();
1002 release_state_owner(struct nfs4_stateid
*stp
, struct nfs4_stateowner
**sopp
,
1005 struct nfs4_stateowner
*sop
= stp
->st_stateowner
;
1006 struct nfs4_file
*fp
= stp
->st_file
;
1008 dprintk("NFSD: release_state_owner\n");
1009 release_stateid(stp
, flag
);
1011 /* place unused nfs4_stateowners on so_close_lru list to be
1012 * released by the laundromat service after the lease period
1013 * to enable us to handle CLOSE replay
1015 if (sop
->so_confirmed
&& list_empty(&sop
->so_perfilestate
))
1016 move_to_close_lru(sop
);
1017 /* unused nfs4_file's are releseed. XXX slab cache? */
1018 if (list_empty(&fp
->fi_perfile
)) {
1024 cmp_owner_str(struct nfs4_stateowner
*sop
, struct xdr_netobj
*owner
, clientid_t
*clid
) {
1025 return ((sop
->so_owner
.len
== owner
->len
) &&
1026 !memcmp(sop
->so_owner
.data
, owner
->data
, owner
->len
) &&
1027 (sop
->so_client
->cl_clientid
.cl_id
== clid
->cl_id
));
1030 /* search ownerstr_hashtbl[] for owner */
1032 find_openstateowner_str(unsigned int hashval
, struct nfsd4_open
*open
, struct nfs4_stateowner
**op
) {
1033 struct nfs4_stateowner
*local
= NULL
;
1035 list_for_each_entry(local
, &ownerstr_hashtbl
[hashval
], so_strhash
) {
1036 if (!cmp_owner_str(local
, &open
->op_owner
, &open
->op_clientid
))
1044 /* see if clientid is in confirmed hash table */
1046 verify_clientid(struct nfs4_client
**client
, clientid_t
*clid
) {
1048 struct nfs4_client
*clp
;
1049 unsigned int idhashval
= clientid_hashval(clid
->cl_id
);
1051 list_for_each_entry(clp
, &conf_id_hashtbl
[idhashval
], cl_idhash
) {
1052 if (!cmp_clid(&clp
->cl_clientid
, clid
))
1061 /* search file_hashtbl[] for file */
1063 find_file(unsigned int hashval
, struct inode
*ino
, struct nfs4_file
**fp
) {
1064 struct nfs4_file
*local
= NULL
;
1066 list_for_each_entry(local
, &file_hashtbl
[hashval
], fi_hash
) {
1067 if (local
->fi_inode
== ino
) {
1075 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
1076 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
1079 set_access(unsigned int *access
, unsigned long bmap
) {
1083 for (i
= 1; i
< 4; i
++) {
1084 if (test_bit(i
, &bmap
))
1090 set_deny(unsigned int *deny
, unsigned long bmap
) {
1094 for (i
= 0; i
< 4; i
++) {
1095 if (test_bit(i
, &bmap
))
1101 test_share(struct nfs4_stateid
*stp
, struct nfsd4_open
*open
) {
1102 unsigned int access
, deny
;
1104 set_access(&access
, stp
->st_access_bmap
);
1105 set_deny(&deny
, stp
->st_deny_bmap
);
1106 if ((access
& open
->op_share_deny
) || (deny
& open
->op_share_access
))
1112 * Called to check deny when READ with all zero stateid or
1113 * WRITE with all zero or all one stateid
1116 nfs4_share_conflict(struct svc_fh
*current_fh
, unsigned int deny_type
)
1118 struct inode
*ino
= current_fh
->fh_dentry
->d_inode
;
1119 unsigned int fi_hashval
;
1120 struct nfs4_file
*fp
;
1121 struct nfs4_stateid
*stp
;
1123 dprintk("NFSD: nfs4_share_conflict\n");
1125 fi_hashval
= file_hashval(ino
);
1126 if (find_file(fi_hashval
, ino
, &fp
)) {
1127 /* Search for conflicting share reservations */
1128 list_for_each_entry(stp
, &fp
->fi_perfile
, st_perfile
) {
1129 if (test_bit(deny_type
, &stp
->st_deny_bmap
) ||
1130 test_bit(NFS4_SHARE_DENY_BOTH
, &stp
->st_deny_bmap
))
1131 return nfserr_share_denied
;
1138 nfs4_file_upgrade(struct file
*filp
, unsigned int share_access
)
1142 if (share_access
& NFS4_SHARE_ACCESS_WRITE
) {
1143 status
= get_write_access(filp
->f_dentry
->d_inode
);
1145 return nfserrno(status
);
1146 filp
->f_mode
= (filp
->f_mode
| FMODE_WRITE
) & ~FMODE_READ
;
1152 nfs4_file_downgrade(struct file
*filp
, unsigned int share_access
)
1154 if (share_access
& NFS4_SHARE_ACCESS_WRITE
) {
1155 put_write_access(filp
->f_dentry
->d_inode
);
1156 filp
->f_mode
= (filp
->f_mode
| FMODE_READ
) & ~FMODE_WRITE
;
1162 * nfsd4_process_open1()
1163 * lookup stateowner.
1175 * called with nfs4_lock_state() held.
1178 nfsd4_process_open1(struct nfsd4_open
*open
)
1181 clientid_t
*clientid
= &open
->op_clientid
;
1182 struct nfs4_client
*clp
= NULL
;
1183 unsigned int strhashval
;
1184 struct nfs4_stateowner
*sop
= NULL
;
1186 status
= nfserr_inval
;
1187 if (!check_name(open
->op_owner
))
1190 status
= nfserr_stale_clientid
;
1191 if (STALE_CLIENTID(&open
->op_clientid
))
1194 strhashval
= ownerstr_hashval(clientid
->cl_id
, open
->op_owner
);
1195 if (find_openstateowner_str(strhashval
, open
, &sop
)) {
1196 open
->op_stateowner
= sop
;
1197 /* check for replay */
1198 if (open
->op_seqid
== sop
->so_seqid
){
1199 if (!sop
->so_replay
.rp_buflen
) {
1201 * The original OPEN failed in so spectacularly that we
1202 * don't even have replay data saved! Therefore, we
1203 * have no choice but to continue processing
1204 * this OPEN; presumably, we'll fail again for the same
1207 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1211 /* replay: indicate to calling function */
1212 status
= NFSERR_REPLAY_ME
;
1215 if (sop
->so_confirmed
) {
1216 if (open
->op_seqid
== sop
->so_seqid
+ 1) {
1220 status
= nfserr_bad_seqid
;
1223 /* If we get here, we received and OPEN for an unconfirmed
1225 * Since the sequid's are different, purge the
1226 * existing nfs4_stateowner, and instantiate a new one.
1228 clp
= sop
->so_client
;
1229 release_stateowner(sop
);
1230 goto instantiate_new_owner
;
1232 /* nfs4_stateowner not found.
1233 * verify clientid and instantiate new nfs4_stateowner
1234 * if verify fails this is presumably the result of the
1235 * client's lease expiring.
1237 * XXX compare clp->cl_addr with rqstp addr?
1239 status
= nfserr_expired
;
1240 if (!verify_clientid(&clp
, clientid
))
1242 instantiate_new_owner
:
1243 status
= nfserr_resource
;
1244 if (!(sop
= alloc_init_open_stateowner(strhashval
, clp
, open
)))
1246 open
->op_stateowner
= sop
;
1249 renew_client(sop
->so_client
);
1251 if (status
&& open
->op_claim_type
== NFS4_OPEN_CLAIM_PREVIOUS
)
1252 status
= nfserr_reclaim_bad
;
1256 * called with nfs4_lock_state() held.
1259 nfsd4_process_open2(struct svc_rqst
*rqstp
, struct svc_fh
*current_fh
, struct nfsd4_open
*open
)
1262 struct nfs4_stateowner
*sop
= open
->op_stateowner
;
1263 struct nfs4_file
*fp
= NULL
;
1265 unsigned int fi_hashval
;
1266 struct nfs4_stateid
*stq
, *stp
= NULL
;
1269 status
= nfserr_resource
;
1273 ino
= current_fh
->fh_dentry
->d_inode
;
1275 status
= nfserr_inval
;
1276 if (!TEST_ACCESS(open
->op_share_access
) || !TEST_DENY(open
->op_share_deny
))
1279 fi_hashval
= file_hashval(ino
);
1280 if (find_file(fi_hashval
, ino
, &fp
)) {
1281 /* Search for conflicting share reservations */
1282 status
= nfserr_share_denied
;
1283 list_for_each_entry(stq
, &fp
->fi_perfile
, st_perfile
) {
1284 if (stq
->st_stateowner
== sop
) {
1288 /* ignore lock owners */
1289 if (stq
->st_stateowner
->so_is_open_owner
== 0)
1291 if (!test_share(stq
,open
))
1295 /* No nfs4_file found; allocate and init a new one */
1296 status
= nfserr_resource
;
1297 if ((fp
= alloc_init_file(fi_hashval
, ino
)) == NULL
)
1304 status
= nfserr_resource
;
1305 if ((stp
= kmalloc(sizeof(struct nfs4_stateid
),
1306 GFP_KERNEL
)) == NULL
)
1309 if (open
->op_share_access
& NFS4_SHARE_ACCESS_WRITE
)
1313 if ((status
= nfsd_open(rqstp
, current_fh
, S_IFREG
,
1315 &stp
->st_vfs_file
)) != 0)
1320 init_stateid(stp
, fp
, sop
, open
);
1321 stp
->st_vfs_set
= 1;
1323 /* This is an upgrade of an existing OPEN.
1324 * OR the incoming share with the existing
1325 * nfs4_stateid share */
1326 unsigned int share_access
;
1328 set_access(&share_access
, stp
->st_access_bmap
);
1329 share_access
= ~share_access
;
1330 share_access
&= open
->op_share_access
;
1332 /* update the struct file */
1333 if ((status
= nfs4_file_upgrade(stp
->st_vfs_file
, share_access
)))
1335 /* remember the open */
1336 set_bit(open
->op_share_access
, &stp
->st_access_bmap
);
1337 set_bit(open
->op_share_deny
, &stp
->st_deny_bmap
);
1338 /* bump the stateid */
1339 update_stateid(&stp
->st_stateid
);
1341 dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1342 stp
->st_stateid
.si_boot
, stp
->st_stateid
.si_stateownerid
,
1343 stp
->st_stateid
.si_fileid
, stp
->st_stateid
.si_generation
);
1345 if (open
->op_truncate
) {
1346 iattr
.ia_valid
= ATTR_SIZE
;
1348 status
= nfsd_setattr(rqstp
, current_fh
, &iattr
, 0, (time_t)0);
1352 memcpy(&open
->op_stateid
, &stp
->st_stateid
, sizeof(stateid_t
));
1354 open
->op_delegate_type
= NFS4_OPEN_DELEGATE_NONE
;
1357 if (fp
&& list_empty(&fp
->fi_perfile
))
1360 if (open
->op_claim_type
== NFS4_OPEN_CLAIM_PREVIOUS
) {
1362 status
= nfserr_reclaim_bad
;
1364 /* successful reclaim. so_seqid is decremented because
1365 * it will be bumped in encode_open
1367 open
->op_stateowner
->so_confirmed
= 1;
1368 open
->op_stateowner
->so_seqid
--;
1372 * To finish the open response, we just need to set the rflags.
1374 open
->op_rflags
= 0;
1375 if (!open
->op_stateowner
->so_confirmed
)
1376 open
->op_rflags
|= NFS4_OPEN_RESULT_CONFIRM
;
1384 static struct work_struct laundromat_work
;
1385 static void laundromat_main(void *);
1386 static DECLARE_WORK(laundromat_work
, laundromat_main
, NULL
);
1389 nfsd4_renew(clientid_t
*clid
)
1391 struct nfs4_client
*clp
;
1392 unsigned int idhashval
;
1396 dprintk("process_renew(%08x/%08x): starting\n",
1397 clid
->cl_boot
, clid
->cl_id
);
1398 status
= nfserr_stale_clientid
;
1399 if (STALE_CLIENTID(clid
))
1402 idhashval
= clientid_hashval(clid
->cl_id
);
1403 list_for_each_entry(clp
, &conf_id_hashtbl
[idhashval
], cl_idhash
) {
1404 if (!cmp_clid(&clp
->cl_clientid
, clid
))
1409 list_for_each_entry(clp
, &unconf_id_hashtbl
[idhashval
], cl_idhash
) {
1410 if (!cmp_clid(&clp
->cl_clientid
, clid
))
1416 * Couldn't find an nfs4_client for this clientid.
1417 * Presumably this is because the client took too long to
1418 * RENEW, so return NFS4ERR_EXPIRED.
1420 dprintk("nfsd4_renew: clientid not found!\n");
1421 status
= nfserr_expired
;
1423 nfs4_unlock_state();
1428 nfs4_laundromat(void)
1430 struct nfs4_client
*clp
;
1431 struct nfs4_stateowner
*sop
;
1432 struct list_head
*pos
, *next
;
1433 time_t cutoff
= get_seconds() - NFSD_LEASE_TIME
;
1434 time_t t
, clientid_val
= NFSD_LEASE_TIME
;
1435 time_t u
, close_val
= NFSD_LEASE_TIME
;
1439 dprintk("NFSD: laundromat service - starting, examining clients\n");
1440 list_for_each_safe(pos
, next
, &client_lru
) {
1441 clp
= list_entry(pos
, struct nfs4_client
, cl_lru
);
1442 if (time_after((unsigned long)clp
->cl_time
, (unsigned long)cutoff
)) {
1443 t
= clp
->cl_time
- cutoff
;
1444 if (clientid_val
> t
)
1448 dprintk("NFSD: purging unused client (clientid %08x)\n",
1449 clp
->cl_clientid
.cl_id
);
1452 list_for_each_safe(pos
, next
, &close_lru
) {
1453 sop
= list_entry(pos
, struct nfs4_stateowner
, so_close_lru
);
1454 if (time_after((unsigned long)sop
->so_time
, (unsigned long)cutoff
)) {
1455 u
= sop
->so_time
- cutoff
;
1460 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1462 list_del(&sop
->so_close_lru
);
1463 free_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
;
1953 unsigned int hval
= lockownerid_hashval(sop
->so_id
);
1955 deny
->ld_sop
= NULL
;
1956 if (nfs4_verify_lock_stateowner(sop
, hval
))
1958 deny
->ld_start
= fl
->fl_start
;
1959 deny
->ld_length
= ~(u64
)0;
1960 if (fl
->fl_end
!= ~(u64
)0)
1961 deny
->ld_length
= fl
->fl_end
- fl
->fl_start
+ 1;
1962 deny
->ld_type
= NFS4_READ_LT
;
1963 if (fl
->fl_type
!= F_RDLCK
)
1964 deny
->ld_type
= NFS4_WRITE_LT
;
1967 static struct nfs4_stateowner
*
1968 find_lockstateowner(struct xdr_netobj
*owner
, clientid_t
*clid
)
1970 struct nfs4_stateowner
*local
= NULL
;
1973 for (i
= 0; i
< LOCK_HASH_SIZE
; i
++) {
1974 list_for_each_entry(local
, &lock_ownerid_hashtbl
[i
], so_idhash
) {
1975 if (!cmp_owner_str(local
, owner
, clid
))
1984 find_lockstateowner_str(unsigned int hashval
, struct xdr_netobj
*owner
, clientid_t
*clid
, struct nfs4_stateowner
**op
) {
1985 struct nfs4_stateowner
*local
= NULL
;
1987 list_for_each_entry(local
, &lock_ownerstr_hashtbl
[hashval
], so_strhash
) {
1988 if (!cmp_owner_str(local
, owner
, clid
))
1998 * Alloc a lock owner structure.
1999 * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
2002 * strhashval = lock_ownerstr_hashval
2003 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
2006 static struct nfs4_stateowner
*
2007 alloc_init_lock_stateowner(unsigned int strhashval
, struct nfs4_client
*clp
, struct nfs4_stateid
*open_stp
, struct nfsd4_lock
*lock
) {
2008 struct nfs4_stateowner
*sop
;
2009 struct nfs4_replay
*rp
;
2010 unsigned int idhashval
;
2012 if (!(sop
= alloc_stateowner(&lock
->lk_new_owner
)))
2014 idhashval
= lockownerid_hashval(current_ownerid
);
2015 INIT_LIST_HEAD(&sop
->so_idhash
);
2016 INIT_LIST_HEAD(&sop
->so_strhash
);
2017 INIT_LIST_HEAD(&sop
->so_perclient
);
2018 INIT_LIST_HEAD(&sop
->so_perfilestate
);
2019 INIT_LIST_HEAD(&sop
->so_perlockowner
);
2020 INIT_LIST_HEAD(&sop
->so_close_lru
); /* not used */
2022 list_add(&sop
->so_idhash
, &lock_ownerid_hashtbl
[idhashval
]);
2023 list_add(&sop
->so_strhash
, &lock_ownerstr_hashtbl
[strhashval
]);
2024 list_add(&sop
->so_perclient
, &clp
->cl_perclient
);
2025 list_add(&sop
->so_perlockowner
, &open_stp
->st_perlockowner
);
2027 sop
->so_is_open_owner
= 0;
2028 sop
->so_id
= current_ownerid
++;
2029 sop
->so_client
= clp
;
2030 sop
->so_seqid
= lock
->lk_new_lock_seqid
- 1;
2031 sop
->so_confirmed
= 1;
2032 rp
= &sop
->so_replay
;
2033 rp
->rp_status
= NFSERR_SERVERFAULT
;
2035 rp
->rp_buf
= rp
->rp_ibuf
;
2040 struct nfs4_stateid
*
2041 alloc_init_lock_stateid(struct nfs4_stateowner
*sop
, struct nfs4_file
*fp
, struct nfs4_stateid
*open_stp
)
2043 struct nfs4_stateid
*stp
;
2044 unsigned int hashval
= stateid_hashval(sop
->so_id
, fp
->fi_id
);
2046 if ((stp
= kmalloc(sizeof(struct nfs4_stateid
),
2047 GFP_KERNEL
)) == NULL
)
2049 INIT_LIST_HEAD(&stp
->st_hash
);
2050 INIT_LIST_HEAD(&stp
->st_perfile
);
2051 INIT_LIST_HEAD(&stp
->st_perfilestate
);
2052 INIT_LIST_HEAD(&stp
->st_perlockowner
); /* not used */
2053 list_add(&stp
->st_hash
, &lockstateid_hashtbl
[hashval
]);
2054 list_add(&stp
->st_perfile
, &fp
->fi_perfile
);
2056 list_add(&stp
->st_perfilestate
, &sop
->so_perfilestate
);
2057 stp
->st_stateowner
= sop
;
2059 stp
->st_stateid
.si_boot
= boot_time
;
2060 stp
->st_stateid
.si_stateownerid
= sop
->so_id
;
2061 stp
->st_stateid
.si_fileid
= fp
->fi_id
;
2062 stp
->st_stateid
.si_generation
= 0;
2063 stp
->st_vfs_file
= open_stp
->st_vfs_file
; /* FIXME refcount?? */
2064 stp
->st_vfs_set
= open_stp
->st_vfs_set
;
2065 stp
->st_access_bmap
= open_stp
->st_access_bmap
;
2066 stp
->st_deny_bmap
= open_stp
->st_deny_bmap
;
2073 check_lock_length(u64 offset
, u64 length
)
2075 return ((length
== 0) || ((length
!= ~(u64
)0) &&
2076 LOFF_OVERFLOW(offset
, length
)));
2082 * nfs4_unlock_state(); called in encode
2085 nfsd4_lock(struct svc_rqst
*rqstp
, struct svc_fh
*current_fh
, struct nfsd4_lock
*lock
)
2087 struct nfs4_stateowner
*lock_sop
= NULL
, *open_sop
= NULL
;
2088 struct nfs4_stateid
*lock_stp
;
2090 struct file_lock file_lock
;
2091 struct file_lock
*conflock
;
2093 unsigned int strhashval
;
2095 dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
2096 (long long) lock
->lk_offset
,
2097 (long long) lock
->lk_length
);
2099 if (nfs4_in_grace() && !lock
->lk_reclaim
)
2100 return nfserr_grace
;
2101 if (!nfs4_in_grace() && lock
->lk_reclaim
)
2102 return nfserr_no_grace
;
2104 if (check_lock_length(lock
->lk_offset
, lock
->lk_length
))
2105 return nfserr_inval
;
2107 lock
->lk_stateowner
= NULL
;
2110 if (lock
->lk_is_new
) {
2112 * Client indicates that this is a new lockowner.
2113 * Use open owner and open stateid to create lock owner and lock
2116 struct nfs4_stateid
*open_stp
= NULL
;
2117 struct nfs4_file
*fp
;
2119 status
= nfserr_stale_clientid
;
2120 if (STALE_CLIENTID(&lock
->lk_new_clientid
)) {
2121 printk("NFSD: nfsd4_lock: clientid is stale!\n");
2125 /* is the new lock seqid presented by the client zero? */
2126 status
= nfserr_bad_seqid
;
2127 if (lock
->v
.new.lock_seqid
!= 0)
2130 /* validate and update open stateid and open seqid */
2131 status
= nfs4_preprocess_seqid_op(current_fh
,
2132 lock
->lk_new_open_seqid
,
2133 &lock
->lk_new_open_stateid
,
2134 CHECK_FH
| OPEN_STATE
,
2135 &open_sop
, &open_stp
,
2136 &lock
->v
.new.clientid
);
2138 if (lock
->lk_reclaim
)
2139 status
= nfserr_reclaim_bad
;
2142 /* create lockowner and lock stateid */
2143 fp
= open_stp
->st_file
;
2144 strhashval
= lock_ownerstr_hashval(fp
->fi_inode
,
2145 open_sop
->so_client
->cl_clientid
.cl_id
,
2148 * If we already have this lock owner, the client is in
2149 * error (or our bookeeping is wrong!)
2150 * for asking for a 'new lock'.
2152 status
= nfserr_bad_stateid
;
2153 lock_sop
= find_lockstateowner(&lock
->v
.new.owner
,
2154 &lock
->v
.new.clientid
);
2157 status
= nfserr_resource
;
2158 if (!(lock
->lk_stateowner
= alloc_init_lock_stateowner(strhashval
, open_sop
->so_client
, open_stp
, lock
)))
2160 if ((lock_stp
= alloc_init_lock_stateid(lock
->lk_stateowner
,
2161 fp
, open_stp
)) == NULL
) {
2162 release_stateowner(lock
->lk_stateowner
);
2165 /* bump the open seqid used to create the lock */
2166 open_sop
->so_seqid
++;
2168 /* lock (lock owner + lock stateid) already exists */
2169 status
= nfs4_preprocess_seqid_op(current_fh
,
2170 lock
->lk_old_lock_seqid
,
2171 &lock
->lk_old_lock_stateid
,
2172 CHECK_FH
| LOCK_STATE
,
2173 &lock
->lk_stateowner
, &lock_stp
, NULL
);
2177 /* lock->lk_stateowner and lock_stp have been created or found */
2178 filp
= lock_stp
->st_vfs_file
;
2180 if ((status
= fh_verify(rqstp
, current_fh
, S_IFREG
, MAY_LOCK
))) {
2181 printk("NFSD: nfsd4_lock: permission denied!\n");
2185 locks_init_lock(&file_lock
);
2186 switch (lock
->lk_type
) {
2189 file_lock
.fl_type
= F_RDLCK
;
2192 case NFS4_WRITEW_LT
:
2193 file_lock
.fl_type
= F_WRLCK
;
2196 status
= nfserr_inval
;
2199 file_lock
.fl_owner
= (fl_owner_t
) lock
->lk_stateowner
;
2200 file_lock
.fl_pid
= current
->tgid
;
2201 file_lock
.fl_file
= filp
;
2202 file_lock
.fl_flags
= FL_POSIX
;
2204 file_lock
.fl_start
= lock
->lk_offset
;
2205 if ((lock
->lk_length
== ~(u64
)0) ||
2206 LOFF_OVERFLOW(lock
->lk_offset
, lock
->lk_length
))
2207 file_lock
.fl_end
= ~(u64
)0;
2209 file_lock
.fl_end
= lock
->lk_offset
+ lock
->lk_length
- 1;
2210 nfs4_transform_lock_offset(&file_lock
);
2213 * Try to lock the file in the VFS.
2214 * Note: locks.c uses the BKL to protect the inode's lock list.
2217 status
= posix_lock_file(filp
, &file_lock
);
2218 if (file_lock
.fl_ops
&& file_lock
.fl_ops
->fl_release_private
)
2219 file_lock
.fl_ops
->fl_release_private(&file_lock
);
2220 dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status
);
2222 case 0: /* success! */
2223 update_stateid(&lock_stp
->st_stateid
);
2224 memcpy(&lock
->lk_resp_stateid
, &lock_stp
->st_stateid
,
2228 goto conflicting_lock
;
2230 status
= nfserr_deadlock
;
2232 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status
);
2233 goto out_destroy_new_stateid
;
2237 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2238 status
= nfserr_denied
;
2239 /* XXX There is a race here. Future patch needed to provide
2240 * an atomic posix_lock_and_test_file
2242 if (!(conflock
= posix_test_lock(filp
, &file_lock
))) {
2243 status
= nfserr_serverfault
;
2246 nfs4_set_lock_denied(conflock
, &lock
->lk_denied
);
2248 out_destroy_new_stateid
:
2249 if (lock
->lk_is_new
) {
2250 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2252 * An error encountered after instantiation of the new
2253 * stateid has forced us to destroy it.
2255 if (!seqid_mutating_err(status
))
2256 open_sop
->so_seqid
--;
2258 release_state_owner(lock_stp
, &lock
->lk_stateowner
, LOCK_STATE
);
2268 nfsd4_lockt(struct svc_rqst
*rqstp
, struct svc_fh
*current_fh
, struct nfsd4_lockt
*lockt
)
2270 struct inode
*inode
;
2272 struct file_lock file_lock
;
2273 struct file_lock
*conflicting_lock
;
2274 unsigned int strhashval
;
2277 if (nfs4_in_grace())
2278 return nfserr_grace
;
2280 if (check_lock_length(lockt
->lt_offset
, lockt
->lt_length
))
2281 return nfserr_inval
;
2283 lockt
->lt_stateowner
= NULL
;
2286 status
= nfserr_stale_clientid
;
2287 if (STALE_CLIENTID(&lockt
->lt_clientid
)) {
2288 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2292 if ((status
= fh_verify(rqstp
, current_fh
, S_IFREG
, 0))) {
2293 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2294 if (status
== nfserr_symlink
)
2295 status
= nfserr_inval
;
2299 inode
= current_fh
->fh_dentry
->d_inode
;
2300 locks_init_lock(&file_lock
);
2301 switch (lockt
->lt_type
) {
2304 file_lock
.fl_type
= F_RDLCK
;
2307 case NFS4_WRITEW_LT
:
2308 file_lock
.fl_type
= F_WRLCK
;
2311 printk("NFSD: nfs4_lockt: bad lock type!\n");
2312 status
= nfserr_inval
;
2316 strhashval
= lock_ownerstr_hashval(inode
,
2317 lockt
->lt_clientid
.cl_id
, lockt
->lt_owner
);
2319 find_lockstateowner_str(strhashval
, &lockt
->lt_owner
,
2320 &lockt
->lt_clientid
,
2321 &lockt
->lt_stateowner
);
2322 if (lockt
->lt_stateowner
)
2323 file_lock
.fl_owner
= (fl_owner_t
)lockt
->lt_stateowner
;
2324 file_lock
.fl_pid
= current
->tgid
;
2325 file_lock
.fl_flags
= FL_POSIX
;
2327 file_lock
.fl_start
= lockt
->lt_offset
;
2328 if ((lockt
->lt_length
== ~(u64
)0) || LOFF_OVERFLOW(lockt
->lt_offset
, lockt
->lt_length
))
2329 file_lock
.fl_end
= ~(u64
)0;
2331 file_lock
.fl_end
= lockt
->lt_offset
+ lockt
->lt_length
- 1;
2333 nfs4_transform_lock_offset(&file_lock
);
2335 /* posix_test_lock uses the struct file _only_ to resolve the inode.
2336 * since LOCKT doesn't require an OPEN, and therefore a struct
2337 * file may not exist, pass posix_test_lock a struct file with
2338 * only the dentry:inode set.
2340 memset(&file
, 0, sizeof (struct file
));
2341 file
.f_dentry
= current_fh
->fh_dentry
;
2344 conflicting_lock
= posix_test_lock(&file
, &file_lock
);
2345 if (conflicting_lock
) {
2346 status
= nfserr_denied
;
2347 nfs4_set_lock_denied(conflicting_lock
, &lockt
->lt_denied
);
2350 nfs4_unlock_state();
2355 nfsd4_locku(struct svc_rqst
*rqstp
, struct svc_fh
*current_fh
, struct nfsd4_locku
*locku
)
2357 struct nfs4_stateid
*stp
;
2358 struct file
*filp
= NULL
;
2359 struct file_lock file_lock
;
2362 dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2363 (long long) locku
->lu_offset
,
2364 (long long) locku
->lu_length
);
2366 if (check_lock_length(locku
->lu_offset
, locku
->lu_length
))
2367 return nfserr_inval
;
2369 locku
->lu_stateowner
= NULL
;
2372 if ((status
= nfs4_preprocess_seqid_op(current_fh
,
2375 CHECK_FH
| LOCK_STATE
,
2376 &locku
->lu_stateowner
, &stp
, NULL
)))
2379 filp
= stp
->st_vfs_file
;
2381 locks_init_lock(&file_lock
);
2382 file_lock
.fl_type
= F_UNLCK
;
2383 file_lock
.fl_owner
= (fl_owner_t
) locku
->lu_stateowner
;
2384 file_lock
.fl_pid
= current
->tgid
;
2385 file_lock
.fl_file
= filp
;
2386 file_lock
.fl_flags
= FL_POSIX
;
2387 file_lock
.fl_start
= locku
->lu_offset
;
2389 if ((locku
->lu_length
== ~(u64
)0) || LOFF_OVERFLOW(locku
->lu_offset
, locku
->lu_length
))
2390 file_lock
.fl_end
= ~(u64
)0;
2392 file_lock
.fl_end
= locku
->lu_offset
+ locku
->lu_length
- 1;
2393 nfs4_transform_lock_offset(&file_lock
);
2396 * Try to unlock the file in the VFS.
2398 status
= posix_lock_file(filp
, &file_lock
);
2399 if (file_lock
.fl_ops
&& file_lock
.fl_ops
->fl_release_private
)
2400 file_lock
.fl_ops
->fl_release_private(&file_lock
);
2402 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2406 * OK, unlock succeeded; the only thing left to do is update the stateid.
2408 update_stateid(&stp
->st_stateid
);
2409 memcpy(&locku
->lu_stateid
, &stp
->st_stateid
, sizeof(stateid_t
));
2415 status
= nfserrno(status
);
2421 * 1: locks held by lockowner
2422 * 0: no locks held by lockowner
2425 check_for_locks(struct file
*filp
, struct nfs4_stateowner
*lowner
)
2427 struct file_lock
**flpp
;
2428 struct inode
*inode
= filp
->f_dentry
->d_inode
;
2432 for (flpp
= &inode
->i_flock
; *flpp
!= NULL
; flpp
= &(*flpp
)->fl_next
) {
2433 if ((*flpp
)->fl_owner
== (fl_owner_t
)lowner
)
2443 nfsd4_release_lockowner(struct svc_rqst
*rqstp
, struct nfsd4_release_lockowner
*rlockowner
)
2445 clientid_t
*clid
= &rlockowner
->rl_clientid
;
2446 struct nfs4_stateowner
*local
= NULL
;
2447 struct xdr_netobj
*owner
= &rlockowner
->rl_owner
;
2450 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2451 clid
->cl_boot
, clid
->cl_id
);
2453 /* XXX check for lease expiration */
2455 status
= nfserr_stale_clientid
;
2456 if (STALE_CLIENTID(clid
)) {
2457 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2464 local
= find_lockstateowner(owner
, clid
);
2466 struct nfs4_stateid
*stp
;
2468 /* check for any locks held by any stateid
2469 * associated with the (lock) stateowner */
2470 status
= nfserr_locks_held
;
2471 list_for_each_entry(stp
, &local
->so_perfilestate
,
2473 if (stp
->st_vfs_set
) {
2474 if (check_for_locks(stp
->st_vfs_file
, local
))
2478 /* no locks held by (lock) stateowner */
2480 release_stateowner(local
);
2483 nfs4_unlock_state();
2487 static inline struct nfs4_client_reclaim
*
2488 alloc_reclaim(int namelen
)
2490 struct nfs4_client_reclaim
*crp
= NULL
;
2492 crp
= kmalloc(sizeof(struct nfs4_client_reclaim
), GFP_KERNEL
);
2495 crp
->cr_name
.data
= kmalloc(namelen
, GFP_KERNEL
);
2496 if (!crp
->cr_name
.data
) {
2504 * failure => all reset bets are off, nfserr_no_grace...
2507 nfs4_client_to_reclaim(struct nfs4_client
*clp
)
2509 unsigned int strhashval
;
2510 struct nfs4_client_reclaim
*crp
= NULL
;
2512 crp
= alloc_reclaim(clp
->cl_name
.len
);
2515 strhashval
= clientstr_hashval(clp
->cl_name
.data
, clp
->cl_name
.len
);
2516 INIT_LIST_HEAD(&crp
->cr_strhash
);
2517 list_add(&crp
->cr_strhash
, &reclaim_str_hashtbl
[strhashval
]);
2518 memcpy(crp
->cr_name
.data
, clp
->cl_name
.data
, clp
->cl_name
.len
);
2519 crp
->cr_name
.len
= clp
->cl_name
.len
;
2520 crp
->cr_first_state
= clp
->cl_first_state
;
2521 crp
->cr_expired
= 0;
2526 nfs4_release_reclaim(void)
2528 struct nfs4_client_reclaim
*crp
= NULL
;
2531 BUG_ON(!nfs4_reclaim_init
);
2532 for (i
= 0; i
< CLIENT_HASH_SIZE
; i
++) {
2533 while (!list_empty(&reclaim_str_hashtbl
[i
])) {
2534 crp
= list_entry(reclaim_str_hashtbl
[i
].next
,
2535 struct nfs4_client_reclaim
, cr_strhash
);
2536 list_del(&crp
->cr_strhash
);
2537 kfree(crp
->cr_name
.data
);
2539 reclaim_str_hashtbl_size
--;
2542 BUG_ON(reclaim_str_hashtbl_size
);
2546 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
2547 struct nfs4_client_reclaim
*
2548 nfs4_find_reclaim_client(clientid_t
*clid
)
2550 unsigned int idhashval
= clientid_hashval(clid
->cl_id
);
2551 unsigned int strhashval
;
2552 struct nfs4_client
*clp
, *client
= NULL
;
2553 struct nfs4_client_reclaim
*crp
= NULL
;
2556 /* find clientid in conf_id_hashtbl */
2557 list_for_each_entry(clp
, &conf_id_hashtbl
[idhashval
], cl_idhash
) {
2558 if (cmp_clid(&clp
->cl_clientid
, clid
)) {
2566 /* find clp->cl_name in reclaim_str_hashtbl */
2567 strhashval
= clientstr_hashval(client
->cl_name
.data
,
2568 client
->cl_name
.len
);
2569 list_for_each_entry(crp
, &reclaim_str_hashtbl
[strhashval
], cr_strhash
) {
2570 if (cmp_name(&crp
->cr_name
, &client
->cl_name
)) {
2578 * Called from OPEN. Look for clientid in reclaim list.
2581 nfs4_check_open_reclaim(clientid_t
*clid
)
2583 struct nfs4_client_reclaim
*crp
;
2585 if ((crp
= nfs4_find_reclaim_client(clid
)) == NULL
)
2586 return nfserr_reclaim_bad
;
2587 if (crp
->cr_expired
)
2588 return nfserr_no_grace
;
2594 * Start and stop routines
2598 nfs4_state_init(void)
2605 if (!nfs4_reclaim_init
) {
2606 for (i
= 0; i
< CLIENT_HASH_SIZE
; i
++)
2607 INIT_LIST_HEAD(&reclaim_str_hashtbl
[i
]);
2608 reclaim_str_hashtbl_size
= 0;
2609 nfs4_reclaim_init
= 1;
2611 for (i
= 0; i
< CLIENT_HASH_SIZE
; i
++) {
2612 INIT_LIST_HEAD(&conf_id_hashtbl
[i
]);
2613 INIT_LIST_HEAD(&conf_str_hashtbl
[i
]);
2614 INIT_LIST_HEAD(&unconf_str_hashtbl
[i
]);
2615 INIT_LIST_HEAD(&unconf_id_hashtbl
[i
]);
2617 for (i
= 0; i
< FILE_HASH_SIZE
; i
++) {
2618 INIT_LIST_HEAD(&file_hashtbl
[i
]);
2620 for (i
= 0; i
< OWNER_HASH_SIZE
; i
++) {
2621 INIT_LIST_HEAD(&ownerstr_hashtbl
[i
]);
2622 INIT_LIST_HEAD(&ownerid_hashtbl
[i
]);
2624 for (i
= 0; i
< STATEID_HASH_SIZE
; i
++) {
2625 INIT_LIST_HEAD(&stateid_hashtbl
[i
]);
2626 INIT_LIST_HEAD(&lockstateid_hashtbl
[i
]);
2628 for (i
= 0; i
< LOCK_HASH_SIZE
; i
++) {
2629 INIT_LIST_HEAD(&lock_ownerid_hashtbl
[i
]);
2630 INIT_LIST_HEAD(&lock_ownerstr_hashtbl
[i
]);
2632 memset(&zerostateid
, 0, sizeof(stateid_t
));
2633 memset(&onestateid
, ~0, sizeof(stateid_t
));
2635 INIT_LIST_HEAD(&close_lru
);
2636 INIT_LIST_HEAD(&client_lru
);
2637 boot_time
= get_seconds();
2638 grace_time
= max(old_lease_time
, lease_time
);
2639 if (reclaim_str_hashtbl_size
== 0)
2642 printk("NFSD: starting %ld-second grace period\n", grace_time
);
2643 grace_end
= boot_time
+ grace_time
;
2644 INIT_WORK(&laundromat_work
,laundromat_main
, NULL
);
2645 schedule_delayed_work(&laundromat_work
, NFSD_LEASE_TIME
*HZ
);
2652 return get_seconds() < grace_end
;
2658 printk("NFSD: ERROR in reboot recovery. State reclaims will fail.\n");
2659 grace_end
= get_seconds();
2663 nfs4_lease_time(void)
2669 __nfs4_state_shutdown(void)
2672 struct nfs4_client
*clp
= NULL
;
2674 for (i
= 0; i
< CLIENT_HASH_SIZE
; i
++) {
2675 while (!list_empty(&conf_id_hashtbl
[i
])) {
2676 clp
= list_entry(conf_id_hashtbl
[i
].next
, struct nfs4_client
, cl_idhash
);
2679 while (!list_empty(&unconf_str_hashtbl
[i
])) {
2680 clp
= list_entry(unconf_str_hashtbl
[i
].next
, struct nfs4_client
, cl_strhash
);
2684 release_all_files();
2685 cancel_delayed_work(&laundromat_work
);
2686 flush_scheduled_work();
2688 dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2689 list_add_perfile
, list_del_perfile
);
2690 dprintk("NFSD: add_perclient %d del_perclient %d\n",
2691 add_perclient
, del_perclient
);
2692 dprintk("NFSD: alloc_file %d free_file %d\n",
2693 alloc_file
, free_file
);
2694 dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2695 alloc_sowner
, alloc_lsowner
, free_sowner
);
2696 dprintk("NFSD: vfsopen %d vfsclose %d\n",
2701 nfs4_state_shutdown(void)
2704 nfs4_release_reclaim();
2705 __nfs4_state_shutdown();
2706 nfs4_unlock_state();
2710 * Called when leasetime is changed.
2712 * if nfsd is not started, simply set the global lease.
2714 * if nfsd(s) are running, lease change requires nfsv4 state to be reset.
2715 * e.g: boot_time is reset, existing nfs4_client structs are
2716 * used to fill reclaim_str_hashtbl, then all state (except for the
2717 * reclaim_str_hashtbl) is re-initialized.
2719 * if the old lease time is greater than the new lease time, the grace
2720 * period needs to be set to the old lease time to allow clients to reclaim
2721 * their state. XXX - we may want to set the grace period == lease time
2722 * after an initial grace period == old lease time
2724 * if an error occurs in this process, the new lease is set, but the server
2725 * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
2726 * which means OPEN/LOCK/READ/WRITE will fail during grace period.
2728 * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
2729 * OPEN and LOCK reclaims.
2732 nfs4_reset_lease(time_t leasetime
)
2734 struct nfs4_client
*clp
;
2737 printk("NFSD: New leasetime %ld\n",leasetime
);
2741 old_lease_time
= lease_time
;
2742 lease_time
= leasetime
;
2744 nfs4_release_reclaim();
2746 /* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
2747 for (i
= 0; i
< CLIENT_HASH_SIZE
; i
++) {
2748 list_for_each_entry(clp
, &conf_id_hashtbl
[i
], cl_idhash
) {
2749 if (!nfs4_client_to_reclaim(clp
)) {
2750 nfs4_release_reclaim();
2753 reclaim_str_hashtbl_size
++;
2757 __nfs4_state_shutdown();
2759 nfs4_unlock_state();