VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / nfsd / nfs4state.c
1 /*
2 *  linux/fs/nfsd/nfs4state.c
3 *
4 *  Copyright (c) 2001 The Regents of the University of Michigan.
5 *  All rights reserved.
6 *
7 *  Kendrick Smith <kmsmith@umich.edu>
8 *  Andy Adamson <kandros@umich.edu>
9 *
10 *  Redistribution and use in source and binary forms, with or without
11 *  modification, are permitted provided that the following conditions
12 *  are met:
13 *
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.
22 *
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.
34 *
35 */
36
37 #include <linux/param.h>
38 #include <linux/major.h>
39 #include <linux/slab.h>
40
41 #include <linux/sunrpc/svc.h>
42 #include <linux/nfsd/nfsd.h>
43 #include <linux/nfsd/cache.h>
44 #include <linux/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>
50
51 #define NFSDDBG_FACILITY                NFSDDBG_PROC
52
53 /* Globals */
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;
57 time_t boot_time;
58 static time_t grace_end = 0;
59 static u32 current_clientid = 1;
60 static u32 current_ownerid;
61 static u32 current_fileid;
62 static u32 nfs4_init;
63 stateid_t zerostateid;             /* bits all 0 */
64 stateid_t onestateid;              /* bits all 1 */
65
66 /* debug counters */
67 u32 list_add_perfile = 0; 
68 u32 list_del_perfile = 0;
69 u32 add_perclient = 0;
70 u32 del_perclient = 0;
71 u32 alloc_file = 0;
72 u32 free_file = 0;
73 u32 alloc_sowner = 0;
74 u32 free_sowner = 0;
75 u32 vfsopen = 0;
76 u32 vfsclose = 0;
77 u32 alloc_lsowner= 0;
78
79 /* forward declarations */
80 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
81
82 /* Locking:
83  *
84  * client_sema: 
85  *      protects clientid_hashtbl[], clientstr_hashtbl[],
86  *      unconfstr_hashtbl[], uncofid_hashtbl[].
87  */
88 static DECLARE_MUTEX(client_sema);
89
90 void
91 nfs4_lock_state(void)
92 {
93         down(&client_sema);
94 }
95
96 /*
97  * nfs4_unlock_state(); called in encode
98  */
99 void
100 nfs4_unlock_state(void)
101 {
102         up(&client_sema);
103 }
104
105 static inline u32
106 opaque_hashval(const void *ptr, int nbytes)
107 {
108         unsigned char *cptr = (unsigned char *) ptr;
109
110         u32 x = 0;
111         while (nbytes--) {
112                 x *= 37;
113                 x += *cptr++;
114         }
115         return x;
116 }
117
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);
122
123
124 /* 
125  * SETCLIENTID state 
126  */
127
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)
132
133 #define clientid_hashval(id) \
134         ((id) & CLIENT_HASH_MASK)
135 #define clientstr_hashval(name, namelen) \
136         (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
137 /*
138  * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
139  * used in reboot/reset lease grace period processing
140  *
141  * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
142  * setclientid_confirmed info. 
143  *
144  * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 
145  * setclientid info.
146  *
147  * client_lru holds client queue ordered by nfs4_client.cl_time
148  * for lease renewal.
149  *
150  * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
151  * for last close replay.
152  */
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;
161
162 static inline void
163 renew_client(struct nfs4_client *clp)
164 {
165         /*
166         * Move client to the end to the LRU list.
167         */
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();
173 }
174
175 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
176 static int
177 STALE_CLIENTID(clientid_t *clid)
178 {
179         if (clid->cl_boot == boot_time)
180                 return 0;
181         dprintk("NFSD stale clientid (%08x/%08x)\n", 
182                         clid->cl_boot, clid->cl_id);
183         return 1;
184 }
185
186 /* 
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.
190  */
191 static inline struct nfs4_client *
192 alloc_client(struct xdr_netobj name)
193 {
194         struct nfs4_client *clp;
195
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;
201                 }
202                 else {
203                         kfree(clp);
204                         clp = NULL;
205                 }
206         }
207         return clp;
208 }
209
210 static inline void
211 free_client(struct nfs4_client *clp)
212 {
213         if (clp->cl_cred.cr_group_info)
214                 put_group_info(clp->cl_cred.cr_group_info);
215         kfree(clp->cl_name.data);
216         kfree(clp);
217 }
218
219 static void
220 expire_client(struct nfs4_client *clp)
221 {
222         struct nfs4_stateowner *sop;
223
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);
231         }
232         free_client(clp);
233 }
234
235 static struct nfs4_client *
236 create_client(struct xdr_netobj name) {
237         struct nfs4_client *clp;
238
239         if(!(clp = alloc_client(name)))
240                 goto out;
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);
245 out:
246         return clp;
247 }
248
249 static void
250 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
251         memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
252 }
253
254 static void
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; 
258 }
259
260 static void
261 copy_cred(struct svc_cred *target, struct svc_cred *source) {
262
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);
267 }
268
269 static int
270 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
271         if(!n1 || !n2)
272                 return 0;
273         return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
274 }
275
276 static int
277 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
278         return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
279 }
280
281 static int
282 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
283         return((cl1->cl_boot == cl2->cl_boot) &&
284                 (cl1->cl_id == cl2->cl_id));
285 }
286
287 /* XXX what about NGROUP */
288 static int
289 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
290         return(cr1->cr_uid == cr2->cr_uid);
291
292 }
293
294 static void
295 gen_clid(struct nfs4_client *clp) {
296         clp->cl_clientid.cl_boot = boot_time;
297         clp->cl_clientid.cl_id = current_clientid++; 
298 }
299
300 static void
301 gen_confirm(struct nfs4_client *clp) {
302         struct timespec         tv;
303         u32 *                   p;
304
305         tv = CURRENT_TIME;
306         p = (u32 *)clp->cl_confirm.data;
307         *p++ = tv.tv_sec;
308         *p++ = tv.tv_nsec;
309 }
310
311 static int
312 check_name(struct xdr_netobj name) {
313
314         if (name.len == 0) 
315                 return 0;
316         if (name.len > NFS4_OPAQUE_LIMIT) {
317                 printk("NFSD: check_name: name too long(%d)!\n", name.len);
318                 return 0;
319         }
320         return 1;
321 }
322
323 void
324 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
325 {
326         unsigned int idhashval;
327
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();
333 }
334
335 void
336 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
337 {
338         unsigned int strhashval;
339
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, 
345                         clp->cl_name.len);
346         list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
347         renew_client(clp);
348 }
349
350
351 /* a helper function for parse_callback */
352 static int
353 parse_octet(unsigned int *lenp, char **addrp)
354 {
355         unsigned int len = *lenp;
356         char *p = *addrp;
357         int n = -1;
358         char c;
359
360         for (;;) {
361                 if (!len)
362                         break;
363                 len--;
364                 c = *p++;
365                 if (c == '.')
366                         break;
367                 if ((c < '0') || (c > '9')) {
368                         n = -1;
369                         break;
370                 }
371                 if (n < 0)
372                         n = 0;
373                 n = (n * 10) + (c - '0');
374                 if (n > 255) {
375                         n = -1;
376                         break;
377                 }
378         }
379         *lenp = len;
380         *addrp = p;
381         return n;
382 }
383
384 /* parse and set the setclientid ipv4 callback address */
385 int
386 parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
387 {
388         int temp = 0;
389         u32 cbaddr = 0;
390         u16 cbport = 0;
391         u32 addrlen = addr_len;
392         char *addr = addr_val;
393         int i, shift;
394
395         /* ipaddress */
396         shift = 24;
397         for(i = 4; i > 0  ; i--) {
398                 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
399                         return 0;
400                 }
401                 cbaddr |= (temp << shift);
402                 if(shift > 0)
403                 shift -= 8;
404         }
405         *cbaddrp = cbaddr;
406
407         /* port */
408         shift = 8;
409         for(i = 2; i > 0  ; i--) {
410                 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
411                         return 0;
412                 }
413                 cbport |= (temp << shift);
414                 if(shift > 0)
415                         shift -= 8;
416         }
417         *cbportp = cbport;
418         return 1;
419 }
420
421 void
422 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
423 {
424         struct nfs4_callback *cb = &clp->cl_callback;
425
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");
429                 cb->cb_parsed = 0;
430                 return;
431         }
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;
436         cb->cb_parsed = 1;
437 }
438
439 /*
440  * RFC 3010 has a complex implmentation description of processing a 
441  * SETCLIENTID request consisting of 5 bullets, labeled as 
442  * CASE0 - CASE4 below.
443  *
444  * NOTES:
445  *      callback information will be processed in a future patch
446  *
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
453  *              name and principal
454  *
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.
463  *
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.
470  *
471  */
472 int
473 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
474 {
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,
479         };
480         nfs4_verifier           clverifier = setclid->se_verf;
481         unsigned int            strhashval;
482         struct nfs4_client *    conf, * unconf, * new, * clp;
483         int                     status;
484         
485         status = nfserr_inval;
486         if (!check_name(clname))
487                 goto out;
488
489         /* 
490          * XXX The Duplicate Request Cache (DRC) has been checked (??)
491          * We get here on a DRC miss.
492          */
493
494         strhashval = clientstr_hashval(clname.data, clname.len);
495
496         conf = NULL;
497         nfs4_lock_state();
498         list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
499                 if (!cmp_name(&clp->cl_name, &clname))
500                         continue;
501                 /* 
502                  * CASE 0:
503                  * clname match, confirmed, different principal
504                  * or different ip_address
505                  */
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);
511                         goto out;
512                 }
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);
517                         goto out;
518                 }
519
520                 /* 
521                  * cl_name match from a previous SETCLIENTID operation
522                  * XXX check for additional matches?
523                  */
524                 conf = clp;
525                 break;
526         }
527         unconf = NULL;
528         list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
529                 if (!cmp_name(&clp->cl_name, &clname))
530                         continue;
531                 /* cl_name match from a previous SETCLIENTID operation */
532                 unconf = clp;
533                 break;
534         }
535         status = nfserr_resource;
536         if (!conf) {
537                 /* 
538                  * CASE 4:
539                  * placed first, because it is the normal case.
540                  */
541                 if (unconf)
542                         expire_client(unconf);
543                 if (!(new = create_client(clname)))
544                         goto out;
545                 copy_verf(new, &clverifier);
546                 new->cl_addr = ip_addr;
547                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
548                 gen_clid(new);
549                 gen_confirm(new);
550                 gen_callback(new, setclid);
551                 add_to_unconfirmed(new, strhashval);
552         } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
553                 /*
554                  * CASE 1:
555                  * cl_name match, confirmed, principal match
556                  * verifier match: probable callback update
557                  *
558                  * remove any unconfirmed nfs4_client with 
559                  * matching cl_name, cl_verifier, and cl_clientid
560                  *
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 
564                  * new cl_confirm
565                  */
566                 if ((unconf) && 
567                     cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
568                      cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
569                                 expire_client(unconf);
570                 }
571                 if (!(new = create_client(clname)))
572                         goto out;
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);
577                 gen_confirm(new);
578                 gen_callback(new, setclid);
579                 add_to_unconfirmed(new,strhashval);
580         } else if (!unconf) {
581                 /*
582                  * CASE 2:
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.
588                  */
589                 if (!(new = create_client(clname)))
590                         goto out;
591                 copy_verf(new,&clverifier);
592                 new->cl_addr = ip_addr;
593                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
594                 gen_clid(new);
595                 gen_confirm(new);
596                 gen_callback(new, setclid);
597                 add_to_unconfirmed(new, strhashval);
598         } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
599                 /*      
600                  * CASE3:
601                  * confirmed found (name, principal match)
602                  * confirmed verifier does not match input clverifier
603                  *
604                  * unconfirmed found (name match)
605                  * confirmed->cl_confirm != unconfirmed->cl_confirm
606                  *
607                  * remove unconfirmed.
608                  *
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
613                  */
614                 expire_client(unconf);
615                 if (!(new = create_client(clname)))
616                         goto out;
617                 copy_verf(new,&clverifier);
618                 new->cl_addr = ip_addr;
619                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
620                 gen_clid(new);
621                 gen_confirm(new);
622                 gen_callback(new, setclid);
623                 add_to_unconfirmed(new, strhashval);
624         } else {
625                 /* No cases hit !!! */
626                 status = nfserr_inval;
627                 goto out;
628
629         }
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));
633         status = nfs_ok;
634 out:
635         nfs4_unlock_state();
636         return status;
637 }
638
639
640 /*
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.
644  *
645  * NOTE: callback information will be processed here in a future patch
646  */
647 int
648 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
649 {
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;
655         int status;
656
657         status = nfserr_stale_clientid;
658         if (STALE_CLIENTID(clid))
659                 goto out;
660         /* 
661          * XXX The Duplicate Request Cache (DRC) has been checked (??)
662          * We get here on a DRC miss.
663          */
664
665         idhashval = clientid_hashval(clid->cl_id);
666         nfs4_lock_state();
667         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
668                 if (!cmp_clid(&clp->cl_clientid, clid))
669                         continue;
670
671                 status = nfserr_inval;
672                 /* 
673                  * Found a record for this clientid. If the IP addresses
674                  * don't match, return ERR_INVAL just as if the record had
675                  * not been found.
676                  */
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);
681                         goto out;
682                 }
683                 conf = clp;
684                 break;
685         }
686         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
687                 if (!cmp_clid(&clp->cl_clientid, clid))
688                         continue;
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);
694                         goto out;
695                 }
696                 unconf = clp;
697                 break;
698         }
699         /* CASE 1: 
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 
703         */
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;
711                 else {
712                         expire_client(conf);
713                         move_to_confirmed(unconf, idhashval);
714                         status = nfs_ok;
715                 }
716                 goto out;
717         } 
718         /* CASE 2:
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.
722          */
723         if ((conf && !unconf) || 
724             ((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;
729                 } else {
730                         status = nfs_ok;
731                 }
732                 goto out;
733         }
734         /* CASE 3:
735          * conf record not found.
736          * unconf record found. 
737          * unconf->cl_confirm matches input confirm
738          */ 
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;
742                 } else {
743                         status = nfs_ok;
744                         move_to_confirmed(unconf, idhashval);
745                 }
746                 goto out;
747         }
748         /* CASE 4:
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.
753          */
754         if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
755             (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
756                 status = nfserr_stale_clientid;
757                 goto out;
758         }
759         /* check that we have hit one of the cases...*/
760         status = nfserr_inval;
761         goto out;
762 out:
763         /* XXX if status == nfs_ok, probe callback path */
764         nfs4_unlock_state();
765         return status;
766 }
767
768 /* 
769  * Open owner state (share locks)
770  */
771
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)
776
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)
781
782 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
783 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
784
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)
793
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)
798
799 static struct list_head file_hashtbl[FILE_HASH_SIZE];
800 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
801
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++;
812                 alloc_file++;
813                 return fp;
814         }
815         return (struct nfs4_file *)NULL;
816 }
817
818 static void
819 release_all_files(void)
820 {
821         int i;
822         struct nfs4_file *fp;
823
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);
830                         }
831                         release_file(fp);
832                 }
833         }
834 }
835
836 static inline struct nfs4_stateowner *
837 alloc_stateowner(struct xdr_netobj *owner)
838 {
839         struct nfs4_stateowner *sop;
840
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;
845                         return sop;
846                 } 
847                 kfree(sop);
848         }
849         return (struct nfs4_stateowner *)NULL;
850 }
851
852 /* should use a slab cache */
853 static void
854 free_stateowner(struct nfs4_stateowner *sop) {
855         if(sop) {
856                 kfree(sop->so_owner.data);
857                 kfree(sop);
858                 sop = NULL;
859                 free_sowner++;
860         }
861 }
862
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;
868
869         if (!(sop = alloc_stateowner(&open->op_owner)))
870                 return (struct nfs4_stateowner *)NULL;
871         idhashval = ownerid_hashval(current_ownerid);
872         INIT_LIST_HEAD(&sop->so_idhash);
873         INIT_LIST_HEAD(&sop->so_strhash);
874         INIT_LIST_HEAD(&sop->so_perclient);
875         INIT_LIST_HEAD(&sop->so_perfilestate);
876         INIT_LIST_HEAD(&sop->so_perlockowner);  /* not used */
877         INIT_LIST_HEAD(&sop->so_close_lru);
878         sop->so_time = 0;
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);
882         add_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;
890         rp->rp_buflen = 0;
891         rp->rp_buf = rp->rp_ibuf;
892         alloc_sowner++;
893         return sop;
894 }
895
896 static void
897 release_stateid_lockowner(struct nfs4_stateid *open_stp)
898 {
899         struct nfs4_stateowner *lock_sop;
900
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);
907         }
908 }
909
910 static void
911 release_stateowner(struct nfs4_stateowner *sop)
912 {
913         struct nfs4_stateid *stp;
914
915         list_del(&sop->so_idhash);
916         list_del(&sop->so_strhash);
917         list_del(&sop->so_perclient);
918         list_del(&sop->so_perlockowner);
919         list_del(&sop->so_close_lru);
920         del_perclient++;
921         while (!list_empty(&sop->so_perfilestate)) {
922                 stp = list_entry(sop->so_perfilestate.next, 
923                         struct nfs4_stateid, st_perfilestate);
924                 if(sop->so_is_open_owner)
925                         release_stateid(stp, OPEN_STATE);
926                 else
927                         release_stateid(stp, LOCK_STATE);
928         }
929         free_stateowner(sop);
930 }
931
932 static inline void
933 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
934         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
935
936         INIT_LIST_HEAD(&stp->st_hash);
937         INIT_LIST_HEAD(&stp->st_perfilestate);
938         INIT_LIST_HEAD(&stp->st_perlockowner);
939         INIT_LIST_HEAD(&stp->st_perfile);
940         list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
941         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
942         list_add_perfile++;
943         list_add(&stp->st_perfile, &fp->fi_perfile);
944         stp->st_stateowner = sop;
945         stp->st_file = fp;
946         stp->st_stateid.si_boot = boot_time;
947         stp->st_stateid.si_stateownerid = sop->so_id;
948         stp->st_stateid.si_fileid = fp->fi_id;
949         stp->st_stateid.si_generation = 0;
950         stp->st_access_bmap = 0;
951         stp->st_deny_bmap = 0;
952         __set_bit(open->op_share_access, &stp->st_access_bmap);
953         __set_bit(open->op_share_deny, &stp->st_deny_bmap);
954 }
955
956 static void
957 release_stateid(struct nfs4_stateid *stp, int flags) {
958
959         list_del(&stp->st_hash);
960         list_del_perfile++;
961         list_del(&stp->st_perfile);
962         list_del(&stp->st_perfilestate);
963         if((stp->st_vfs_set) && (flags & OPEN_STATE)) {
964                 release_stateid_lockowner(stp);
965                 nfsd_close(&stp->st_vfs_file);
966                 vfsclose++;
967                 dput(stp->st_vfs_file.f_dentry);
968                 mntput(stp->st_vfs_file.f_vfsmnt);
969         } else if ((stp->st_vfs_set) && (flags & LOCK_STATE)) {
970                 struct file *filp = &stp->st_vfs_file;
971
972                 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
973         }
974         kfree(stp);
975         stp = NULL;
976 }
977
978 static void
979 release_file(struct nfs4_file *fp)
980 {
981         free_file++;
982         list_del(&fp->fi_hash);
983         iput(fp->fi_inode);
984         kfree(fp);
985 }       
986
987 void
988 move_to_close_lru(struct nfs4_stateowner *sop)
989 {
990         dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
991         /* remove stateowner from all other hash lists except perclient */
992         list_del_init(&sop->so_idhash);
993         list_del_init(&sop->so_strhash);
994         list_del_init(&sop->so_perlockowner);
995
996         list_add_tail(&sop->so_close_lru, &close_lru);
997         sop->so_time = get_seconds();
998 }
999
1000 void
1001 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
1002                 int flag)
1003 {
1004         struct nfs4_stateowner *sop = stp->st_stateowner;
1005         struct nfs4_file *fp = stp->st_file;
1006
1007         dprintk("NFSD: release_state_owner\n");
1008         release_stateid(stp, flag);
1009
1010         /* place unused nfs4_stateowners on so_close_lru list to be
1011          * released by the laundromat service after the lease period
1012          * to enable us to handle CLOSE replay
1013          */
1014         if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
1015                 move_to_close_lru(sop);
1016         /* unused nfs4_file's are releseed. XXX slab cache? */
1017         if (list_empty(&fp->fi_perfile)) {
1018                 release_file(fp);
1019         }
1020 }
1021
1022 static int
1023 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
1024         return ((sop->so_owner.len == owner->len) && 
1025          !memcmp(sop->so_owner.data, owner->data, owner->len) && 
1026           (sop->so_client->cl_clientid.cl_id == clid->cl_id));
1027 }
1028
1029 /* search ownerstr_hashtbl[] for owner */
1030 static int
1031 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
1032         struct nfs4_stateowner *local = NULL;
1033
1034         list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) {
1035                 if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid)) 
1036                         continue;
1037                 *op = local;
1038                 return(1);
1039         }
1040         return 0;
1041 }
1042
1043 /* see if clientid is in confirmed hash table */
1044 static int
1045 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
1046
1047         struct nfs4_client *clp;
1048         unsigned int idhashval = clientid_hashval(clid->cl_id);
1049
1050         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1051                 if (!cmp_clid(&clp->cl_clientid, clid))
1052                         continue;
1053                 *client = clp;
1054                 return 1;
1055         }
1056         *client = NULL;
1057         return 0;
1058 }
1059
1060 /* search file_hashtbl[] for file */
1061 static int
1062 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
1063         struct nfs4_file *local = NULL;
1064
1065         list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) {
1066                 if (local->fi_inode == ino) {
1067                         *fp = local;
1068                         return(1);
1069                 }
1070         }
1071         return 0;
1072 }
1073
1074 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
1075 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
1076
1077 void
1078 set_access(unsigned int *access, unsigned long bmap) {
1079         int i;
1080
1081         *access = 0;
1082         for (i = 1; i < 4; i++) {
1083                 if(test_bit(i, &bmap))
1084                         *access |= i;
1085         }
1086 }
1087
1088 void
1089 set_deny(unsigned int *deny, unsigned long bmap) {
1090         int i;
1091
1092         *deny = 0;
1093         for (i = 0; i < 4; i++) {
1094                 if(test_bit(i, &bmap))
1095                         *deny |= i ;
1096         }
1097 }
1098
1099 static int
1100 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1101         unsigned int access, deny;
1102
1103         set_access(&access, stp->st_access_bmap);
1104         set_deny(&deny, stp->st_deny_bmap);
1105         if ((access & open->op_share_deny) || (deny & open->op_share_access))
1106                 return 0;
1107         return 1;
1108 }
1109
1110 /*
1111  * Called to check deny when READ with all zero stateid or
1112  * WRITE with all zero or all one stateid
1113  */
1114 int
1115 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1116 {
1117         struct inode *ino = current_fh->fh_dentry->d_inode;
1118         unsigned int fi_hashval;
1119         struct nfs4_file *fp;
1120         struct nfs4_stateid *stp;
1121
1122         dprintk("NFSD: nfs4_share_conflict\n");
1123
1124         fi_hashval = file_hashval(ino);
1125         if (find_file(fi_hashval, ino, &fp)) {
1126         /* Search for conflicting share reservations */
1127                 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
1128                         if (test_bit(deny_type, &stp->st_deny_bmap) ||
1129                             test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1130                                 return nfserr_share_denied;
1131                 }
1132         }
1133         return nfs_ok;
1134 }
1135
1136 static inline int
1137 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
1138 {
1139 int status;
1140
1141         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1142                 status = get_write_access(filp->f_dentry->d_inode);
1143                 if (status)
1144                         return nfserrno(status);
1145                 filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
1146         }
1147         return nfs_ok;
1148 }
1149
1150 static inline void
1151 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1152 {
1153         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1154                 put_write_access(filp->f_dentry->d_inode);
1155                 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
1156         }
1157 }
1158
1159
1160 /*
1161  * nfsd4_process_open1()
1162  *      lookup stateowner.
1163  *              found:
1164  *                      check confirmed 
1165  *                              confirmed:
1166  *                                      check seqid
1167  *                              not confirmed:
1168  *                                      delete owner
1169  *                                      create new owner
1170  *              notfound:
1171  *                      verify clientid
1172  *                      create new owner
1173  *
1174  * called with nfs4_lock_state() held.
1175  */
1176 int
1177 nfsd4_process_open1(struct nfsd4_open *open)
1178 {
1179         int status;
1180         clientid_t *clientid = &open->op_clientid;
1181         struct nfs4_client *clp = NULL;
1182         unsigned int strhashval;
1183         struct nfs4_stateowner *sop = NULL;
1184
1185         status = nfserr_inval;
1186         if (!check_name(open->op_owner))
1187                 goto out;
1188
1189         status = nfserr_stale_clientid;
1190         if (STALE_CLIENTID(&open->op_clientid))
1191                 return status;
1192
1193         strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1194         if (find_openstateowner_str(strhashval, open, &sop)) {
1195                 open->op_stateowner = sop;
1196                 /* check for replay */
1197                 if (open->op_seqid == sop->so_seqid){
1198                         if (!sop->so_replay.rp_buflen) {
1199                         /*
1200                         * The original OPEN failed in so spectacularly that we
1201                         * don't even have replay data saved!  Therefore, we
1202                         * have no choice but to continue processing
1203                         * this OPEN; presumably, we'll fail again for the same
1204                         * reason.
1205                         */
1206                                 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1207                                 status = NFS_OK;
1208                                 goto renew;
1209                         }
1210                         /* replay: indicate to calling function */
1211                         status = NFSERR_REPLAY_ME;
1212                         return status;
1213                 }
1214                 if (sop->so_confirmed) {
1215                         if (open->op_seqid == sop->so_seqid + 1) { 
1216                                 status = nfs_ok;
1217                                 goto renew;
1218                         } 
1219                         status = nfserr_bad_seqid;
1220                         goto out;
1221                 }
1222                 /* If we get here, we received and OPEN for an unconfirmed
1223                  * nfs4_stateowner. 
1224                  * Since the sequid's are different, purge the 
1225                  * existing nfs4_stateowner, and instantiate a new one.
1226                  */
1227                 clp = sop->so_client;
1228                 release_stateowner(sop);
1229                 goto instantiate_new_owner;
1230         } 
1231         /* nfs4_stateowner not found. 
1232         * verify clientid and instantiate new nfs4_stateowner
1233         * if verify fails this is presumably the result of the 
1234         * client's lease expiring.
1235         *
1236         * XXX compare clp->cl_addr with rqstp addr? 
1237         */
1238         status = nfserr_expired;
1239         if (!verify_clientid(&clp, clientid))
1240                 goto out;
1241 instantiate_new_owner:
1242         status = nfserr_resource;
1243         if (!(sop = alloc_init_open_stateowner(strhashval, clp, open))) 
1244                 goto out;
1245         open->op_stateowner = sop;
1246         status = nfs_ok;
1247 renew:
1248         renew_client(sop->so_client);
1249 out:
1250         if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1251                 status = nfserr_reclaim_bad;
1252         return status;
1253 }
1254 /*
1255  * called with nfs4_lock_state() held.
1256  */
1257 int
1258 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1259 {
1260         struct iattr iattr;
1261         struct nfs4_stateowner *sop = open->op_stateowner;
1262         struct nfs4_file *fp = NULL;
1263         struct inode *ino;
1264         unsigned int fi_hashval;
1265         struct nfs4_stateid *stq, *stp = NULL;
1266         int status;
1267
1268         status = nfserr_resource;
1269         if (!sop)
1270                 return status;
1271
1272         ino = current_fh->fh_dentry->d_inode;
1273
1274         status = nfserr_inval;
1275         if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1276                 goto out;
1277
1278         fi_hashval = file_hashval(ino);
1279         if (find_file(fi_hashval, ino, &fp)) {
1280                 /* Search for conflicting share reservations */
1281                 status = nfserr_share_denied;
1282                 list_for_each_entry(stq, &fp->fi_perfile, st_perfile) {
1283                         if(stq->st_stateowner == sop) {
1284                                 stp = stq;
1285                                 continue;
1286                         }
1287                         /* ignore lock owners */
1288                         if (stq->st_stateowner->so_is_open_owner == 0)
1289                                 continue;
1290                         if (!test_share(stq,open))      
1291                                 goto out;
1292                 }
1293         } else {
1294         /* No nfs4_file found; allocate and init a new one */
1295                 status = nfserr_resource;
1296                 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1297                         goto out;
1298         }
1299
1300         if (!stp) {
1301                 int flags = 0;
1302
1303                 status = nfserr_resource;
1304                 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1305                                                 GFP_KERNEL)) == NULL)
1306                         goto out;
1307
1308                 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1309                         flags = MAY_WRITE;
1310                 else
1311                         flags = MAY_READ;
1312                 if ((status = nfsd_open(rqstp, current_fh,  S_IFREG,
1313                                               flags,
1314                                               &stp->st_vfs_file)) != 0)
1315                         goto out_free;
1316
1317                 vfsopen++;
1318                 dget(stp->st_vfs_file.f_dentry);
1319                 mntget(stp->st_vfs_file.f_vfsmnt);
1320
1321                 init_stateid(stp, fp, sop, open);
1322                 stp->st_vfs_set = 1;
1323         } else {
1324                 /* This is an upgrade of an existing OPEN. 
1325                  * OR the incoming share with the existing 
1326                  * nfs4_stateid share */
1327                 unsigned int share_access;
1328
1329                 set_access(&share_access, stp->st_access_bmap);
1330                 share_access = ~share_access;
1331                 share_access &= open->op_share_access;
1332
1333                 /* update the struct file */
1334                 if ((status = nfs4_file_upgrade(&stp->st_vfs_file, share_access)))
1335                         goto out;
1336                 /* remember the open */
1337                 set_bit(open->op_share_access, &stp->st_access_bmap);
1338                 set_bit(open->op_share_deny, &stp->st_deny_bmap);
1339                 /* bump the stateid */
1340                 update_stateid(&stp->st_stateid);
1341         }
1342         dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1343                     stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1344                     stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1345
1346         if (open->op_truncate) {
1347                 iattr.ia_valid = ATTR_SIZE;
1348                 iattr.ia_size = 0;
1349                 status = nfsd_setattr(rqstp, current_fh, &iattr, 0, (time_t)0);
1350                 if (status)
1351                         goto out;
1352         }
1353         memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1354
1355         open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
1356         status = nfs_ok;
1357 out:
1358         if (fp && list_empty(&fp->fi_perfile))
1359                 release_file(fp);
1360
1361         if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
1362                 if (status)
1363                         status = nfserr_reclaim_bad;
1364                 else {
1365                 /* successful reclaim. so_seqid is decremented because
1366                 * it will be bumped in encode_open
1367                 */
1368                         open->op_stateowner->so_confirmed = 1;
1369                         open->op_stateowner->so_seqid--;
1370                 }
1371         }
1372         /*
1373         * To finish the open response, we just need to set the rflags.
1374         */
1375         open->op_rflags = 0;
1376         if (!open->op_stateowner->so_confirmed)
1377                 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1378
1379         return status;
1380 out_free:
1381         kfree(stp);
1382         goto out;
1383 }
1384
1385 static struct work_struct laundromat_work;
1386 static void laundromat_main(void *);
1387 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1388
1389 int 
1390 nfsd4_renew(clientid_t *clid)
1391 {
1392         struct nfs4_client *clp;
1393         unsigned int idhashval;
1394         int status;
1395
1396         nfs4_lock_state();
1397         dprintk("process_renew(%08x/%08x): starting\n", 
1398                         clid->cl_boot, clid->cl_id);
1399         status = nfserr_stale_clientid;
1400         if (STALE_CLIENTID(clid))
1401                 goto out;
1402         status = nfs_ok;
1403         idhashval = clientid_hashval(clid->cl_id);
1404         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1405                 if (!cmp_clid(&clp->cl_clientid, clid))
1406                         continue;
1407                 renew_client(clp);
1408                 goto out;
1409         }
1410         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1411                 if (!cmp_clid(&clp->cl_clientid, clid))
1412                         continue;
1413                 renew_client(clp);
1414         goto out;
1415         }
1416         /*
1417         * Couldn't find an nfs4_client for this clientid.  
1418         * Presumably this is because the client took too long to 
1419         * RENEW, so return NFS4ERR_EXPIRED.
1420         */
1421         dprintk("nfsd4_renew: clientid not found!\n");
1422         status = nfserr_expired;
1423 out:
1424         nfs4_unlock_state();
1425         return status;
1426 }
1427
1428 time_t
1429 nfs4_laundromat(void)
1430 {
1431         struct nfs4_client *clp;
1432         struct nfs4_stateowner *sop;
1433         struct list_head *pos, *next;
1434         time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1435         time_t t, clientid_val = NFSD_LEASE_TIME;
1436         time_t u, close_val = NFSD_LEASE_TIME;
1437
1438         nfs4_lock_state();
1439
1440         dprintk("NFSD: laundromat service - starting, examining clients\n");
1441         list_for_each_safe(pos, next, &client_lru) {
1442                 clp = list_entry(pos, struct nfs4_client, cl_lru);
1443                 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1444                         t = clp->cl_time - cutoff;
1445                         if (clientid_val > t)
1446                                 clientid_val = t;
1447                         break;
1448                 }
1449                 dprintk("NFSD: purging unused client (clientid %08x)\n",
1450                         clp->cl_clientid.cl_id);
1451                 expire_client(clp);
1452         }
1453         list_for_each_safe(pos, next, &close_lru) {
1454                 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
1455                 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
1456                         u = sop->so_time - cutoff;
1457                         if (close_val > u)
1458                                 close_val = u;
1459                         break;
1460                 }
1461                 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1462                         sop->so_id);
1463                 release_stateowner(sop);
1464         }
1465         if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1466                 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1467         nfs4_unlock_state();
1468         return clientid_val;
1469 }
1470
1471 void
1472 laundromat_main(void *not_used)
1473 {
1474         time_t t;
1475
1476         t = nfs4_laundromat();
1477         dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1478         schedule_delayed_work(&laundromat_work, t*HZ);
1479 }
1480
1481 /* search ownerid_hashtbl[] and close_lru for stateid owner
1482  * (stateid->si_stateownerid)
1483  */
1484 struct nfs4_stateowner *
1485 find_openstateowner_id(u32 st_id, int flags) {
1486         struct nfs4_stateowner *local = NULL;
1487
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)
1492                                 return local;
1493                 }
1494         }
1495         return NULL;
1496 }
1497
1498 static inline int
1499 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1500 {
1501         return (stp->st_vfs_set == 0 ||
1502                 fhp->fh_dentry->d_inode != stp->st_vfs_file.f_dentry->d_inode);
1503 }
1504
1505 static int
1506 STALE_STATEID(stateid_t *stateid)
1507 {
1508         if (stateid->si_boot == boot_time)
1509                 return 0;
1510         printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1511                 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1512                 stateid->si_generation);
1513         return 1;
1514 }
1515
1516
1517 /*
1518 * Checks for stateid operations
1519 */
1520 int
1521 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
1522 {
1523         struct nfs4_stateid *stp;
1524         int status;
1525
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); 
1529
1530         *stpp = NULL;
1531
1532         /* STALE STATEID */
1533         status = nfserr_stale_stateid;
1534         if (STALE_STATEID(stateid)) 
1535                 goto out;
1536
1537         /* BAD STATEID */
1538         status = nfserr_bad_stateid;
1539         if (!(stp = find_stateid(stateid, flags))) {
1540                 dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
1541                 goto out;
1542         }
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;
1546                 goto out;
1547         }
1548         if (!stp->st_stateowner->so_confirmed) {
1549                 dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
1550                 goto out;
1551         }
1552         if (stateid->si_generation > stp->st_stateid.si_generation) {
1553                 dprintk("preprocess_stateid_op: future stateid?!\n");
1554                 goto out;
1555         }
1556
1557         /* OLD STATEID */
1558         status = nfserr_old_stateid;
1559         if (stateid->si_generation < stp->st_stateid.si_generation) {
1560                 dprintk("preprocess_stateid_op: old stateid!\n");
1561                 goto out;
1562         }
1563         *stpp = stp;
1564         status = nfs_ok;
1565         renew_client(stp->st_stateowner->so_client);
1566 out:
1567         return status;
1568 }
1569
1570
1571 /* 
1572  * Checks for sequence id mutating operations. 
1573  */
1574 int
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)
1576 {
1577         int status;
1578         struct nfs4_stateid *stp;
1579         struct nfs4_stateowner *sop;
1580
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);
1585                                 
1586         *stpp = NULL;
1587         *sopp = NULL;
1588
1589         status = nfserr_bad_stateid;
1590         if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
1591                 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
1592                 goto out;
1593         }
1594
1595         status = nfserr_stale_stateid;
1596         if (STALE_STATEID(stateid))
1597                 goto out;
1598         /*
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.
1606         */
1607         if (!(stp = find_stateid(stateid, flags)))
1608                 goto no_nfs4_stateid;
1609
1610         status = nfserr_bad_stateid;
1611
1612         /* for new lock stateowners:
1613          * check that the lock->v.new.open_stateid
1614          * refers to an open stateowner
1615          *
1616          * check that the lockclid (nfs4_lock->v.new.clientid) is the same
1617          * as the open_stateid->st_stateowner->so_client->clientid
1618          */
1619         if (lockclid) {
1620                 struct nfs4_stateowner *sop = stp->st_stateowner;
1621                 struct nfs4_client *clp = sop->so_client;
1622
1623                 if (!sop->so_is_open_owner)
1624                         goto out;
1625                 if (!cmp_clid(&clp->cl_clientid, lockclid))
1626                         goto out;
1627         }
1628
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;
1632                 goto out;
1633         }
1634
1635         *stpp = stp;
1636         *sopp = sop = stp->st_stateowner;
1637
1638         /*
1639         *  We now validate the seqid and stateid generation numbers.
1640         *  For the moment, we ignore the possibility of 
1641         *  generation number wraparound.
1642         */
1643         if (seqid != sop->so_seqid + 1)
1644                 goto check_replay;
1645
1646         if (sop->so_confirmed) {
1647                 if (flags & CONFIRM) {
1648                         printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
1649                         goto out;
1650                 }
1651         }
1652         else {
1653                 if (!(flags & CONFIRM)) {
1654                         printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
1655                         goto out;
1656                 }
1657         }
1658         if (stateid->si_generation > stp->st_stateid.si_generation) {
1659                 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
1660                 goto out;
1661         }
1662
1663         status = nfserr_old_stateid;
1664         if (stateid->si_generation < stp->st_stateid.si_generation) {
1665                 printk("NFSD: preprocess_seqid_op: old stateid!\n");
1666                 goto out;
1667         }
1668         /* XXX renew the client lease here */
1669         status = nfs_ok;
1670
1671 out:
1672         return status;
1673
1674 no_nfs4_stateid:
1675
1676         /*
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.
1680         */
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;
1684                 goto out;
1685         }
1686         *sopp = sop;
1687
1688 check_replay:
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;
1693         } else  {
1694                 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
1695
1696                 *sopp = NULL;
1697                 status = nfserr_bad_seqid;
1698         }
1699         goto out;
1700 }
1701
1702 /*
1703  * eventually, this will perform an upcall to the 'state daemon' as well as
1704  * set the cl_first_state field.
1705  */
1706 void
1707 first_state(struct nfs4_client *clp)
1708 {
1709         if (!clp->cl_first_state)
1710                 clp->cl_first_state = get_seconds();
1711 }
1712
1713 /*
1714  * nfs4_unlock_state(); called in encode
1715  */
1716 int
1717 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
1718 {
1719         int status;
1720         struct nfs4_stateowner *sop;
1721         struct nfs4_stateid *stp;
1722
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);
1726
1727         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
1728                 goto out;
1729
1730         oc->oc_stateowner = NULL;
1731         nfs4_lock_state();
1732
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)))
1737                 goto out; 
1738
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);
1749         status = nfs_ok;
1750         first_state(sop->so_client);
1751 out:
1752         return status;
1753 }
1754
1755
1756 /*
1757  * unset all bits in union bitmap (bmap) that
1758  * do not exist in share (from successful OPEN_DOWNGRADE)
1759  */
1760 static void
1761 reset_union_bmap_access(unsigned long access, unsigned long *bmap)
1762 {
1763         int i;
1764         for (i = 1; i < 4; i++) {
1765                 if ((i & access) != i)
1766                         __clear_bit(i, bmap);
1767         }
1768 }
1769
1770 static void
1771 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
1772 {
1773         int i;
1774         for (i = 0; i < 4; i++) {
1775                 if ((i & deny) != i)
1776                         __clear_bit(i, bmap);
1777         }
1778 }
1779
1780 /*
1781  * nfs4_unlock_state(); called in encode
1782  */
1783
1784 int
1785 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
1786 {
1787         int status;
1788         struct nfs4_stateid *stp;
1789         unsigned int share_access;
1790
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);
1794
1795         od->od_stateowner = NULL;
1796         status = nfserr_inval;
1797         if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
1798                 goto out;
1799
1800         nfs4_lock_state();
1801         if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, 
1802                                         &od->od_stateid, 
1803                                         CHECK_FH | OPEN_STATE, 
1804                                         &od->od_stateowner, &stp, NULL)))
1805                 goto out; 
1806
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);
1811                 goto out;
1812         }
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);
1816                 goto out;
1817         }
1818         set_access(&share_access, stp->st_access_bmap);
1819         nfs4_file_downgrade(&stp->st_vfs_file, 
1820                             share_access & ~od->od_share_access);
1821
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);
1824
1825         update_stateid(&stp->st_stateid);
1826         memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
1827         status = nfs_ok;
1828 out:
1829         return status;
1830 }
1831
1832 /*
1833  * nfs4_unlock_state() called after encode
1834  */
1835 int
1836 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
1837 {
1838         int status;
1839         struct nfs4_stateid *stp;
1840
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);
1844
1845         close->cl_stateowner = NULL;
1846         nfs4_lock_state();
1847         /* check close_lru for replay */
1848         if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, 
1849                                         &close->cl_stateid, 
1850                                         CHECK_FH | OPEN_STATE | CLOSE_STATE,
1851                                         &close->cl_stateowner, &stp, NULL)))
1852                 goto out; 
1853         /*
1854         *  Return success, but first update the stateid.
1855         */
1856         status = nfs_ok;
1857         update_stateid(&stp->st_stateid);
1858         memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
1859
1860         /* release_state_owner() calls nfsd_close() if needed */
1861         release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
1862 out:
1863         return status;
1864 }
1865
1866 /* 
1867  * Lock owner state (byte-range locks)
1868  */
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)
1873
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)
1878
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];
1882
1883 struct nfs4_stateid *
1884 find_stateid(stateid_t *stid, int flags)
1885 {
1886         struct nfs4_stateid *local = NULL;
1887         u32 st_id = stid->si_stateownerid;
1888         u32 f_id = stid->si_fileid;
1889         unsigned int hashval;
1890
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))
1897                                 return local;
1898                 }
1899         } 
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))
1905                                 return local;
1906                 }
1907         } else
1908                 printk("NFSD: find_stateid: ERROR: no state flag\n");
1909         return NULL;
1910 }
1911
1912
1913 /*
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!
1920  */
1921 static inline void
1922 nfs4_transform_lock_offset(struct file_lock *lock)
1923 {
1924         if (lock->fl_start < 0)
1925                 lock->fl_start = OFFSET_MAX;
1926         if (lock->fl_end < 0)
1927                 lock->fl_end = OFFSET_MAX;
1928 }
1929
1930 int
1931 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
1932 {
1933         struct nfs4_stateowner *local = NULL;
1934         int status = 0;
1935                                 
1936         if (hashval >= LOCK_HASH_SIZE)
1937                 goto out;
1938         list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
1939                 if (local == sop) {
1940                         status = 1;
1941                         goto out;
1942                 }
1943         }
1944 out:
1945         return status;
1946 }
1947
1948
1949 static inline void
1950 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
1951 {
1952         struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
1953
1954         deny->ld_sop = NULL;
1955         if (nfs4_verify_lock_stateowner(sop, fl->fl_pid))
1956                 deny->ld_sop = sop;
1957         deny->ld_start = fl->fl_start;
1958         deny->ld_length = ~(u64)0;
1959         if (fl->fl_end != ~(u64)0)
1960                 deny->ld_length = fl->fl_end - fl->fl_start + 1;        
1961         deny->ld_type = NFS4_READ_LT;
1962         if (fl->fl_type != F_RDLCK)
1963                 deny->ld_type = NFS4_WRITE_LT;
1964 }
1965
1966 static struct nfs4_stateowner *
1967 find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
1968 {
1969         struct nfs4_stateowner *local = NULL;
1970         int i;
1971
1972         for (i = 0; i < LOCK_HASH_SIZE; i++) {
1973                 list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
1974                         if(!cmp_owner_str(local, owner, clid))
1975                                 continue;
1976                         return local;
1977                 }
1978         }
1979         return NULL;
1980 }
1981
1982 static int
1983 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
1984         struct nfs4_stateowner *local = NULL;
1985
1986         list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) {
1987                 if(!cmp_owner_str(local, owner, clid)) 
1988                         continue;
1989                 *op = local;
1990                 return(1);
1991         }
1992         *op = NULL;
1993         return 0;
1994 }
1995
1996 /*
1997  * Alloc a lock owner structure.
1998  * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
1999  * occured. 
2000  *
2001  * strhashval = lock_ownerstr_hashval 
2002  * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode 
2003  */
2004
2005 static struct nfs4_stateowner *
2006 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
2007         struct nfs4_stateowner *sop;
2008         struct nfs4_replay *rp;
2009         unsigned int idhashval;
2010
2011         if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
2012                 return (struct nfs4_stateowner *)NULL;
2013         idhashval = lockownerid_hashval(current_ownerid);
2014         INIT_LIST_HEAD(&sop->so_idhash);
2015         INIT_LIST_HEAD(&sop->so_strhash);
2016         INIT_LIST_HEAD(&sop->so_perclient);
2017         INIT_LIST_HEAD(&sop->so_perfilestate);
2018         INIT_LIST_HEAD(&sop->so_perlockowner);
2019         INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
2020         sop->so_time = 0;
2021         list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
2022         list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
2023         list_add(&sop->so_perclient, &clp->cl_perclient);
2024         list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
2025         add_perclient++;
2026         sop->so_is_open_owner = 0;
2027         sop->so_id = current_ownerid++;
2028         sop->so_client = clp;
2029         sop->so_seqid = lock->lk_new_lock_seqid - 1;
2030         sop->so_confirmed = 1;
2031         rp = &sop->so_replay;
2032         rp->rp_status = NFSERR_SERVERFAULT;
2033         rp->rp_buflen = 0;
2034         rp->rp_buf = rp->rp_ibuf;
2035         alloc_lsowner++;
2036         return sop;
2037 }
2038
2039 struct nfs4_stateid *
2040 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
2041 {
2042         struct nfs4_stateid *stp;
2043         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
2044
2045         if ((stp = kmalloc(sizeof(struct nfs4_stateid), 
2046                                         GFP_KERNEL)) == NULL)
2047                 goto out;
2048         INIT_LIST_HEAD(&stp->st_hash);
2049         INIT_LIST_HEAD(&stp->st_perfile);
2050         INIT_LIST_HEAD(&stp->st_perfilestate);
2051         INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
2052         list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
2053         list_add(&stp->st_perfile, &fp->fi_perfile);
2054         list_add_perfile++;
2055         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
2056         stp->st_stateowner = sop;
2057         stp->st_file = fp;
2058         stp->st_stateid.si_boot = boot_time;
2059         stp->st_stateid.si_stateownerid = sop->so_id;
2060         stp->st_stateid.si_fileid = fp->fi_id;
2061         stp->st_stateid.si_generation = 0;
2062         stp->st_vfs_file = open_stp->st_vfs_file;
2063         stp->st_vfs_set = open_stp->st_vfs_set;
2064         stp->st_access_bmap = open_stp->st_access_bmap;
2065         stp->st_deny_bmap = open_stp->st_deny_bmap;
2066
2067 out:
2068         return stp;
2069 }
2070
2071 int
2072 check_lock_length(u64 offset, u64 length)
2073 {
2074         return ((length == 0)  || ((length != ~(u64)0) &&
2075              LOFF_OVERFLOW(offset, length)));
2076 }
2077
2078 /*
2079  *  LOCK operation 
2080  *
2081  * nfs4_unlock_state(); called in encode
2082  */
2083 int
2084 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
2085 {
2086         struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
2087         struct nfs4_stateid *lock_stp;
2088         struct file *filp;
2089         struct file_lock file_lock;
2090         struct file_lock *conflock;
2091         int status = 0;
2092         unsigned int strhashval;
2093
2094         dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
2095                 (long long) lock->lk_offset,
2096                 (long long) lock->lk_length);
2097
2098         if (nfs4_in_grace() && !lock->lk_reclaim)
2099                 return nfserr_grace;
2100         if (!nfs4_in_grace() && lock->lk_reclaim)
2101                 return nfserr_no_grace;
2102
2103         if (check_lock_length(lock->lk_offset, lock->lk_length))
2104                  return nfserr_inval;
2105
2106         lock->lk_stateowner = NULL;
2107         nfs4_lock_state();
2108
2109         if (lock->lk_is_new) {
2110         /*
2111          * Client indicates that this is a new lockowner.
2112          * Use open owner and open stateid to create lock owner and lock 
2113          * stateid.
2114          */
2115                 struct nfs4_stateid *open_stp = NULL;
2116                 struct nfs4_file *fp;
2117                 
2118                 status = nfserr_stale_clientid;
2119                 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
2120                         printk("NFSD: nfsd4_lock: clientid is stale!\n");
2121                         goto out;
2122                 }
2123
2124                 /* is the new lock seqid presented by the client zero? */
2125                 status = nfserr_bad_seqid;
2126                 if (lock->v.new.lock_seqid != 0)
2127                         goto out;
2128
2129                 /* validate and update open stateid and open seqid */
2130                 status = nfs4_preprocess_seqid_op(current_fh, 
2131                                         lock->lk_new_open_seqid,
2132                                         &lock->lk_new_open_stateid,
2133                                         CHECK_FH | OPEN_STATE,
2134                                         &open_sop, &open_stp,
2135                                         &lock->v.new.clientid);
2136                 if (status) {
2137                         if (lock->lk_reclaim)
2138                                 status = nfserr_reclaim_bad;
2139                         goto out;
2140                 }
2141                 /* create lockowner and lock stateid */
2142                 fp = open_stp->st_file;
2143                 strhashval = lock_ownerstr_hashval(fp->fi_inode, 
2144                                 open_sop->so_client->cl_clientid.cl_id, 
2145                                 lock->v.new.owner);
2146                 /* 
2147                  * If we already have this lock owner, the client is in 
2148                  * error (or our bookeeping is wrong!) 
2149                  * for asking for a 'new lock'.
2150                  */
2151                 status = nfserr_bad_stateid;
2152                 lock_sop = find_lockstateowner(&lock->v.new.owner,
2153                                                 &lock->v.new.clientid);
2154                 if (lock_sop)
2155                         goto out;
2156                 status = nfserr_resource;
2157                 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2158                         goto out;
2159                 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 
2160                                                 fp, open_stp)) == NULL)
2161                         goto out;
2162                 /* bump the open seqid used to create the lock */
2163                 open_sop->so_seqid++;
2164         } else {
2165                 /* lock (lock owner + lock stateid) already exists */
2166                 status = nfs4_preprocess_seqid_op(current_fh,
2167                                        lock->lk_old_lock_seqid, 
2168                                        &lock->lk_old_lock_stateid, 
2169                                        CHECK_FH | LOCK_STATE, 
2170                                        &lock->lk_stateowner, &lock_stp, NULL);
2171                 if (status)
2172                         goto out;
2173         }
2174         /* lock->lk_stateowner and lock_stp have been created or found */
2175         filp = &lock_stp->st_vfs_file;
2176
2177         if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2178                 printk("NFSD: nfsd4_lock: permission denied!\n");
2179                 goto out;
2180         }
2181
2182         switch (lock->lk_type) {
2183                 case NFS4_READ_LT:
2184                 case NFS4_READW_LT:
2185                         file_lock.fl_type = F_RDLCK;
2186                 break;
2187                 case NFS4_WRITE_LT:
2188                 case NFS4_WRITEW_LT:
2189                         file_lock.fl_type = F_WRLCK;
2190                 break;
2191                 default:
2192                         status = nfserr_inval;
2193                 goto out;
2194         }
2195         file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
2196         file_lock.fl_pid = lockownerid_hashval(lock->lk_stateowner->so_id);
2197         file_lock.fl_file = filp;
2198         file_lock.fl_flags = FL_POSIX;
2199         file_lock.fl_notify = NULL;
2200         file_lock.fl_insert = NULL;
2201         file_lock.fl_remove = NULL;
2202
2203         file_lock.fl_start = lock->lk_offset;
2204         if ((lock->lk_length == ~(u64)0) || 
2205                         LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
2206                 file_lock.fl_end = ~(u64)0;
2207         else
2208                 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
2209         nfs4_transform_lock_offset(&file_lock);
2210
2211         /*
2212         * Try to lock the file in the VFS.
2213         * Note: locks.c uses the BKL to protect the inode's lock list.
2214         */
2215
2216         status = posix_lock_file(filp, &file_lock);
2217         dprintk("NFSD: nfsd4_lock: posix_test_lock passed. posix_lock_file status %d\n",status);
2218         switch (-status) {
2219         case 0: /* success! */
2220                 update_stateid(&lock_stp->st_stateid);
2221                 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 
2222                                 sizeof(stateid_t));
2223                 goto out;
2224         case (EAGAIN):
2225                 goto conflicting_lock;
2226         case (EDEADLK):
2227                 status = nfserr_deadlock;
2228         default:        
2229                 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
2230                 goto out_destroy_new_stateid;
2231         }
2232
2233 conflicting_lock:
2234         dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2235         status = nfserr_denied;
2236         /* XXX There is a race here. Future patch needed to provide 
2237          * an atomic posix_lock_and_test_file
2238          */
2239         if (!(conflock = posix_test_lock(filp, &file_lock))) {
2240                 status = nfserr_serverfault;
2241                 goto out;
2242         }
2243         nfs4_set_lock_denied(conflock, &lock->lk_denied);
2244
2245 out_destroy_new_stateid:
2246         if (lock->lk_is_new) {
2247                 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2248         /*
2249         * An error encountered after instantiation of the new
2250         * stateid has forced us to destroy it.
2251         */
2252                 if (!seqid_mutating_err(status))
2253                         open_sop->so_seqid--;
2254
2255                 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
2256         }
2257 out:
2258         return status;
2259 }
2260
2261 /*
2262  * LOCKT operation
2263  */
2264 int
2265 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2266 {
2267         struct inode *inode;
2268         struct nfs4_stateowner *sop;
2269         struct file file;
2270         struct file_lock file_lock;
2271         struct file_lock *conflicting_lock;
2272         unsigned int strhashval;
2273         int status;
2274
2275         if (nfs4_in_grace())
2276                 return nfserr_grace;
2277
2278         if (check_lock_length(lockt->lt_offset, lockt->lt_length))
2279                  return nfserr_inval;
2280
2281         lockt->lt_stateowner = NULL;
2282         nfs4_lock_state();
2283
2284         status = nfserr_stale_clientid;
2285         if (STALE_CLIENTID(&lockt->lt_clientid)) {
2286                 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2287                 goto out;
2288         }
2289
2290         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2291                 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2292                 if (status == nfserr_symlink)
2293                         status = nfserr_inval;
2294                 goto out;
2295         }
2296
2297         inode = current_fh->fh_dentry->d_inode;
2298         switch (lockt->lt_type) {
2299                 case NFS4_READ_LT:
2300                 case NFS4_READW_LT:
2301                         file_lock.fl_type = F_RDLCK;
2302                 break;
2303                 case NFS4_WRITE_LT:
2304                 case NFS4_WRITEW_LT:
2305                         file_lock.fl_type = F_WRLCK;
2306                 break;
2307                 default:
2308                         printk("NFSD: nfs4_lockt: bad lock type!\n");
2309                         status = nfserr_inval;
2310                 goto out;
2311         }
2312
2313         strhashval = lock_ownerstr_hashval(inode, 
2314                         lockt->lt_clientid.cl_id, lockt->lt_owner);
2315
2316         find_lockstateowner_str(strhashval, &lockt->lt_owner,
2317                                         &lockt->lt_clientid, 
2318                                         &lockt->lt_stateowner);
2319         sop = lockt->lt_stateowner;
2320         if (sop) {
2321                 file_lock.fl_owner = (fl_owner_t) sop;
2322                 file_lock.fl_pid = lockownerid_hashval(sop->so_id);
2323         } else {
2324                 file_lock.fl_owner = NULL;
2325                 file_lock.fl_pid = 0;
2326         }
2327         file_lock.fl_flags = FL_POSIX;
2328
2329         file_lock.fl_start = lockt->lt_offset;
2330         if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2331                 file_lock.fl_end = ~(u64)0;
2332         else
2333                 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2334
2335         nfs4_transform_lock_offset(&file_lock);
2336
2337         /* posix_test_lock uses the struct file _only_ to resolve the inode.
2338          * since LOCKT doesn't require an OPEN, and therefore a struct
2339          * file may not exist, pass posix_test_lock a struct file with
2340          * only the dentry:inode set.
2341          */
2342         memset(&file, 0, sizeof (struct file));
2343         file.f_dentry = current_fh->fh_dentry;
2344
2345         status = nfs_ok;
2346         conflicting_lock = posix_test_lock(&file, &file_lock);
2347         if (conflicting_lock) {
2348                 status = nfserr_denied;
2349                 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2350         }
2351 out:
2352         nfs4_unlock_state();
2353         return status;
2354 }
2355
2356 int
2357 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2358 {
2359         struct nfs4_stateid *stp;
2360         struct file *filp = NULL;
2361         struct file_lock file_lock;
2362         int status;
2363                                                         
2364         dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2365                 (long long) locku->lu_offset,
2366                 (long long) locku->lu_length);
2367
2368         if (check_lock_length(locku->lu_offset, locku->lu_length))
2369                  return nfserr_inval;
2370
2371         locku->lu_stateowner = NULL;
2372         nfs4_lock_state();
2373                                                                                 
2374         if ((status = nfs4_preprocess_seqid_op(current_fh, 
2375                                         locku->lu_seqid, 
2376                                         &locku->lu_stateid, 
2377                                         CHECK_FH | LOCK_STATE, 
2378                                         &locku->lu_stateowner, &stp, NULL)))
2379                 goto out;
2380
2381         filp = &stp->st_vfs_file;
2382         BUG_ON(!filp);
2383         file_lock.fl_type = F_UNLCK;
2384         file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2385         file_lock.fl_pid = lockownerid_hashval(locku->lu_stateowner->so_id);
2386         file_lock.fl_file = filp;
2387         file_lock.fl_flags = FL_POSIX; 
2388         file_lock.fl_notify = NULL;
2389         file_lock.fl_insert = NULL;
2390         file_lock.fl_remove = NULL;
2391         file_lock.fl_start = locku->lu_offset;
2392
2393         if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2394                 file_lock.fl_end = ~(u64)0;
2395         else
2396                 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2397         nfs4_transform_lock_offset(&file_lock);
2398
2399         /*
2400         *  Try to unlock the file in the VFS.
2401         */
2402         status = posix_lock_file(filp, &file_lock); 
2403         if (status) {
2404                 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2405                 goto out_nfserr;
2406         }
2407         /*
2408         * OK, unlock succeeded; the only thing left to do is update the stateid.
2409         */
2410         update_stateid(&stp->st_stateid);
2411         memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2412
2413 out:
2414         return status;
2415
2416 out_nfserr:
2417         status = nfserrno(status);
2418         goto out;
2419 }
2420
2421 /*
2422  * returns
2423  *      1: locks held by lockowner
2424  *      0: no locks held by lockowner
2425  */
2426 static int
2427 check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
2428 {
2429         struct file_lock **flpp;
2430         struct inode *inode = filp->f_dentry->d_inode;
2431         int status = 0;
2432
2433         lock_kernel();
2434         for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
2435                 if ((*flpp)->fl_owner == (fl_owner_t)lowner)
2436                         status = 1;
2437                         goto out;
2438         }
2439 out:
2440         unlock_kernel();
2441         return status;
2442 }
2443
2444 int
2445 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2446 {
2447         clientid_t *clid = &rlockowner->rl_clientid;
2448         struct nfs4_stateowner *local = NULL;
2449         struct xdr_netobj *owner = &rlockowner->rl_owner;
2450         int status;
2451
2452         dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2453                 clid->cl_boot, clid->cl_id);
2454
2455         /* XXX check for lease expiration */
2456
2457         status = nfserr_stale_clientid;
2458         if (STALE_CLIENTID(clid)) {
2459                 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2460                 return status;
2461         }
2462
2463         nfs4_lock_state();
2464
2465         status = nfs_ok;
2466         local = find_lockstateowner(owner, clid);
2467         if (local) {
2468                 struct nfs4_stateid *stp;
2469
2470                 /* check for any locks held by any stateid
2471                  * associated with the (lock) stateowner */
2472                 status = nfserr_locks_held;
2473                 list_for_each_entry(stp, &local->so_perfilestate,
2474                                 st_perfilestate) {
2475                         if(stp->st_vfs_set) {
2476                                 if (check_for_locks(&stp->st_vfs_file, local))
2477                                         goto out;
2478                         }
2479                 }
2480                 /* no locks held by (lock) stateowner */
2481                 status = nfs_ok;
2482                 release_stateowner(local);
2483         }
2484 out:
2485         nfs4_unlock_state();
2486         return status;
2487 }
2488
2489 static inline struct nfs4_client_reclaim *
2490 alloc_reclaim(int namelen)
2491 {
2492         struct nfs4_client_reclaim *crp = NULL;
2493
2494         crp = kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
2495         if (!crp)
2496                 return NULL;
2497         crp->cr_name.data = kmalloc(namelen, GFP_KERNEL);
2498         if (!crp->cr_name.data) {
2499                 kfree(crp);
2500                 return NULL;
2501         }
2502         return crp;
2503 }
2504
2505 /*
2506  * failure => all reset bets are off, nfserr_no_grace...
2507  */
2508 static int
2509 nfs4_client_to_reclaim(struct nfs4_client *clp)
2510 {
2511         unsigned int strhashval;
2512         struct nfs4_client_reclaim *crp = NULL;
2513
2514         crp = alloc_reclaim(clp->cl_name.len);
2515         if (!crp)
2516                 return 0;
2517         strhashval = clientstr_hashval(clp->cl_name.data, clp->cl_name.len);
2518         INIT_LIST_HEAD(&crp->cr_strhash);
2519         list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
2520         memcpy(crp->cr_name.data, clp->cl_name.data, clp->cl_name.len);
2521         crp->cr_name.len = clp->cl_name.len;
2522         crp->cr_first_state = clp->cl_first_state;
2523         crp->cr_expired = 0;
2524         return 1;
2525 }
2526
2527 static void
2528 nfs4_release_reclaim(void)
2529 {
2530         struct nfs4_client_reclaim *crp = NULL;
2531         int i;
2532
2533         BUG_ON(!nfs4_reclaim_init);
2534         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2535                 while (!list_empty(&reclaim_str_hashtbl[i])) {
2536                         crp = list_entry(reclaim_str_hashtbl[i].next,
2537                                         struct nfs4_client_reclaim, cr_strhash);
2538                         list_del(&crp->cr_strhash);
2539                         kfree(crp->cr_name.data);
2540                         kfree(crp);
2541                         reclaim_str_hashtbl_size--;
2542                 }
2543         }
2544         BUG_ON(reclaim_str_hashtbl_size);
2545 }
2546
2547 /*
2548  * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
2549 struct nfs4_client_reclaim *
2550 nfs4_find_reclaim_client(clientid_t *clid)
2551 {
2552         unsigned int idhashval = clientid_hashval(clid->cl_id);
2553         unsigned int strhashval;
2554         struct nfs4_client *clp, *client = NULL;
2555         struct nfs4_client_reclaim *crp = NULL;
2556
2557
2558         /* find clientid in conf_id_hashtbl */
2559         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
2560                 if (cmp_clid(&clp->cl_clientid, clid)) {
2561                         client = clp;
2562                         break;
2563                 }
2564         }
2565         if (!client)
2566                 return NULL;
2567
2568         /* find clp->cl_name in reclaim_str_hashtbl */
2569         strhashval = clientstr_hashval(client->cl_name.data,
2570                                       client->cl_name.len);
2571         list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
2572                 if(cmp_name(&crp->cr_name, &client->cl_name)) {
2573                         return crp;
2574                 }
2575         }
2576         return NULL;
2577 }
2578
2579 /*
2580 * Called from OPEN. Look for clientid in reclaim list.
2581 */
2582 int
2583 nfs4_check_open_reclaim(clientid_t *clid)
2584 {
2585         struct nfs4_client_reclaim *crp;
2586
2587         if ((crp = nfs4_find_reclaim_client(clid)) == NULL)
2588                 return nfserr_reclaim_bad;
2589         if (crp->cr_expired)
2590                 return nfserr_no_grace;
2591         return nfs_ok;
2592 }
2593
2594
2595 /* 
2596  * Start and stop routines
2597  */
2598
2599 void 
2600 nfs4_state_init(void)
2601 {
2602         int i;
2603         time_t grace_time;
2604
2605         if (nfs4_init)
2606                 return;
2607         if (!nfs4_reclaim_init) {
2608                 for (i = 0; i < CLIENT_HASH_SIZE; i++)
2609                         INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
2610                 reclaim_str_hashtbl_size = 0;
2611                 nfs4_reclaim_init = 1;
2612         }
2613         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2614                 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
2615                 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
2616                 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
2617                 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
2618         }
2619         for (i = 0; i < FILE_HASH_SIZE; i++) {
2620                 INIT_LIST_HEAD(&file_hashtbl[i]);
2621         }
2622         for (i = 0; i < OWNER_HASH_SIZE; i++) {
2623                 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
2624                 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
2625         }
2626         for (i = 0; i < STATEID_HASH_SIZE; i++) {
2627                 INIT_LIST_HEAD(&stateid_hashtbl[i]);
2628                 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
2629         }
2630         for (i = 0; i < LOCK_HASH_SIZE; i++) {
2631                 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
2632                 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
2633         }
2634         memset(&zerostateid, 0, sizeof(stateid_t));
2635         memset(&onestateid, ~0, sizeof(stateid_t));
2636
2637         INIT_LIST_HEAD(&close_lru);
2638         INIT_LIST_HEAD(&client_lru);
2639         boot_time = get_seconds();
2640         grace_time = max(old_lease_time, lease_time);
2641         if (reclaim_str_hashtbl_size == 0)
2642                 grace_time = 0;
2643         if (grace_time)
2644                 printk("NFSD: starting %ld-second grace period\n", grace_time);
2645         grace_end = boot_time + grace_time;
2646         INIT_WORK(&laundromat_work,laundromat_main, NULL);
2647         schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
2648         nfs4_init = 1;
2649 }
2650
2651 int
2652 nfs4_in_grace(void)
2653 {
2654         return get_seconds() < grace_end;
2655 }
2656
2657 void
2658 set_no_grace(void)
2659 {
2660         printk("NFSD: ERROR in reboot recovery.  State reclaims will fail.\n");
2661         grace_end = get_seconds();
2662 }
2663
2664 time_t
2665 nfs4_lease_time(void)
2666 {
2667         return lease_time;
2668 }
2669
2670 static void
2671 __nfs4_state_shutdown(void)
2672 {
2673         int i;
2674         struct nfs4_client *clp = NULL;
2675
2676         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2677                 while (!list_empty(&conf_id_hashtbl[i])) {
2678                         clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
2679                         expire_client(clp);
2680                 }
2681                 while (!list_empty(&unconf_str_hashtbl[i])) {
2682                         clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
2683                         expire_client(clp);
2684                 }
2685         }
2686         release_all_files();
2687         cancel_delayed_work(&laundromat_work);
2688         flush_scheduled_work();
2689         nfs4_init = 0;
2690         dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2691                         list_add_perfile, list_del_perfile);
2692         dprintk("NFSD: add_perclient %d del_perclient %d\n",
2693                         add_perclient, del_perclient);
2694         dprintk("NFSD: alloc_file %d free_file %d\n",
2695                         alloc_file, free_file);
2696         dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2697                         alloc_sowner, alloc_lsowner, free_sowner);
2698         dprintk("NFSD: vfsopen %d vfsclose %d\n",
2699                         vfsopen, vfsclose);
2700 }
2701
2702 void
2703 nfs4_state_shutdown(void)
2704 {
2705         nfs4_lock_state();
2706         nfs4_release_reclaim();
2707         __nfs4_state_shutdown();
2708         nfs4_unlock_state();
2709 }
2710
2711 /*
2712  * Called when leasetime is changed.
2713  *
2714  * if nfsd is not started, simply set the global lease.
2715  *
2716  * if nfsd(s) are running, lease change requires nfsv4 state to be reset.
2717  * e.g: boot_time is reset, existing nfs4_client structs are
2718  * used to fill reclaim_str_hashtbl, then all state (except for the
2719  * reclaim_str_hashtbl) is re-initialized.
2720  *
2721  * if the old lease time is greater than the new lease time, the grace
2722  * period needs to be set to the old lease time to allow clients to reclaim
2723  * their state. XXX - we may want to set the grace period == lease time
2724  * after an initial grace period == old lease time
2725  *
2726  * if an error occurs in this process, the new lease is set, but the server
2727  * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
2728  * which means OPEN/LOCK/READ/WRITE will fail during grace period.
2729  *
2730  * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
2731  * OPEN and LOCK reclaims.
2732  */
2733 void
2734 nfs4_reset_lease(time_t leasetime)
2735 {
2736         struct nfs4_client *clp;
2737         int i;
2738
2739         printk("NFSD: New leasetime %ld\n",leasetime);
2740         if (!nfs4_init)
2741                 return;
2742         nfs4_lock_state();
2743         old_lease_time = lease_time;
2744         lease_time = leasetime;
2745
2746         nfs4_release_reclaim();
2747
2748         /* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
2749         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2750                 list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
2751                         if (!nfs4_client_to_reclaim(clp)) {
2752                                 nfs4_release_reclaim();
2753                                 goto init_state;
2754                         }
2755                         reclaim_str_hashtbl_size++;
2756                 }
2757         }
2758 init_state:
2759         __nfs4_state_shutdown();
2760         nfs4_state_init();
2761         nfs4_unlock_state();
2762 }
2763