ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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 time_t boot_time;
55 static time_t grace_end = 0;
56 static u32 current_clientid = 1;
57 static u32 current_ownerid;
58 static u32 current_fileid;
59 static u32 nfs4_init;
60 stateid_t zerostateid;             /* bits all 0 */
61 stateid_t onestateid;              /* bits all 1 */
62
63 /* debug counters */
64 u32 list_add_perfile = 0; 
65 u32 list_del_perfile = 0;
66 u32 add_perclient = 0;
67 u32 del_perclient = 0;
68 u32 alloc_file = 0;
69 u32 free_file = 0;
70 u32 alloc_sowner = 0;
71 u32 free_sowner = 0;
72 u32 vfsopen = 0;
73 u32 vfsclose = 0;
74 u32 alloc_lsowner= 0;
75
76 /* forward declarations */
77 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
78
79 /* Locking:
80  *
81  * client_sema: 
82  *      protects clientid_hashtbl[], clientstr_hashtbl[],
83  *      unconfstr_hashtbl[], uncofid_hashtbl[].
84  */
85 static struct semaphore client_sema;
86
87 void
88 nfs4_lock_state(void)
89 {
90         down(&client_sema);
91 }
92
93 /*
94  * nfs4_unlock_state(); called in encode
95  */
96 void
97 nfs4_unlock_state(void)
98 {
99         up(&client_sema);
100 }
101
102 static inline u32
103 opaque_hashval(const void *ptr, int nbytes)
104 {
105         unsigned char *cptr = (unsigned char *) ptr;
106
107         u32 x = 0;
108         while (nbytes--) {
109                 x *= 37;
110                 x += *cptr++;
111         }
112         return x;
113 }
114
115 /* forward declarations */
116 static void release_stateowner(struct nfs4_stateowner *sop);
117 static void release_stateid(struct nfs4_stateid *stp, int flags);
118 static void release_file(struct nfs4_file *fp);
119
120
121 /* 
122  * SETCLIENTID state 
123  */
124
125 /* Hash tables for nfs4_clientid state */
126 #define CLIENT_HASH_BITS                 4
127 #define CLIENT_HASH_SIZE                (1 << CLIENT_HASH_BITS)
128 #define CLIENT_HASH_MASK                (CLIENT_HASH_SIZE - 1)
129
130 #define clientid_hashval(id) \
131         ((id) & CLIENT_HASH_MASK)
132 #define clientstr_hashval(name, namelen) \
133         (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
134
135 /* conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
136  * setclientid_confirmed info. 
137  *
138  * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 
139  * setclientid info.
140  *
141  * client_lru holds client queue ordered by nfs4_client.cl_time
142  * for lease renewal.
143  *
144  * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
145  * for last close replay.
146  */
147 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
148 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
149 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
150 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
151 static struct list_head client_lru;
152 static struct list_head close_lru;
153
154 static inline void
155 renew_client(struct nfs4_client *clp)
156 {
157         /*
158         * Move client to the end to the LRU list.
159         */
160         dprintk("renewing client (clientid %08x/%08x)\n", 
161                         clp->cl_clientid.cl_boot, 
162                         clp->cl_clientid.cl_id);
163         list_move_tail(&clp->cl_lru, &client_lru);
164         clp->cl_time = get_seconds();
165 }
166
167 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
168 static int
169 STALE_CLIENTID(clientid_t *clid)
170 {
171         if (clid->cl_boot == boot_time)
172                 return 0;
173         dprintk("NFSD stale clientid (%08x/%08x)\n", 
174                         clid->cl_boot, clid->cl_id);
175         return 1;
176 }
177
178 /* 
179  * XXX Should we use a slab cache ?
180  * This type of memory management is somewhat inefficient, but we use it
181  * anyway since SETCLIENTID is not a common operation.
182  */
183 static inline struct nfs4_client *
184 alloc_client(struct xdr_netobj name)
185 {
186         struct nfs4_client *clp;
187
188         if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) {
189                 memset(clp, 0, sizeof(*clp));
190                 if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) {
191                         memcpy(clp->cl_name.data, name.data, name.len);
192                         clp->cl_name.len = name.len;
193                 }
194                 else {
195                         kfree(clp);
196                         clp = NULL;
197                 }
198         }
199         return clp;
200 }
201
202 static inline void
203 free_client(struct nfs4_client *clp)
204 {
205         if (clp->cl_cred.cr_group_info)
206                 put_group_info(clp->cl_cred.cr_group_info);
207         kfree(clp->cl_name.data);
208         kfree(clp);
209 }
210
211 static void
212 expire_client(struct nfs4_client *clp)
213 {
214         struct nfs4_stateowner *sop;
215
216         dprintk("NFSD: expire_client\n");
217         list_del(&clp->cl_idhash);
218         list_del(&clp->cl_strhash);
219         list_del(&clp->cl_lru);
220         while (!list_empty(&clp->cl_perclient)) {
221                 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
222                 release_stateowner(sop);
223         }
224         free_client(clp);
225 }
226
227 static struct nfs4_client *
228 create_client(struct xdr_netobj name) {
229         struct nfs4_client *clp;
230
231         if(!(clp = alloc_client(name)))
232                 goto out;
233         INIT_LIST_HEAD(&clp->cl_idhash);
234         INIT_LIST_HEAD(&clp->cl_strhash);
235         INIT_LIST_HEAD(&clp->cl_perclient);
236         INIT_LIST_HEAD(&clp->cl_lru);
237 out:
238         return clp;
239 }
240
241 static void
242 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
243         memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
244 }
245
246 static void
247 copy_clid(struct nfs4_client *target, struct nfs4_client *source) {
248         target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 
249         target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
250 }
251
252 static void
253 copy_cred(struct svc_cred *target, struct svc_cred *source) {
254
255         target->cr_uid = source->cr_uid;
256         target->cr_gid = source->cr_gid;
257         target->cr_group_info = source->cr_group_info;
258         get_group_info(target->cr_group_info);
259 }
260
261 static int
262 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
263         if(!n1 || !n2)
264                 return 0;
265         return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
266 }
267
268 static int
269 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
270         return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
271 }
272
273 static int
274 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
275         return((cl1->cl_boot == cl2->cl_boot) &&
276                 (cl1->cl_id == cl2->cl_id));
277 }
278
279 /* XXX what about NGROUP */
280 static int
281 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
282         return(cr1->cr_uid == cr2->cr_uid);
283
284 }
285
286 static void
287 gen_clid(struct nfs4_client *clp) {
288         clp->cl_clientid.cl_boot = boot_time;
289         clp->cl_clientid.cl_id = current_clientid++; 
290 }
291
292 static void
293 gen_confirm(struct nfs4_client *clp) {
294         struct timespec         tv;
295         u32 *                   p;
296
297         tv = CURRENT_TIME;
298         p = (u32 *)clp->cl_confirm.data;
299         *p++ = tv.tv_sec;
300         *p++ = tv.tv_nsec;
301 }
302
303 static int
304 check_name(struct xdr_netobj name) {
305
306         if (name.len == 0) 
307                 return 0;
308         if (name.len > NFS4_OPAQUE_LIMIT) {
309                 printk("NFSD: check_name: name too long(%d)!\n", name.len);
310                 return 0;
311         }
312         return 1;
313 }
314
315 void
316 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
317 {
318         unsigned int idhashval;
319
320         list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
321         idhashval = clientid_hashval(clp->cl_clientid.cl_id);
322         list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
323         list_add_tail(&clp->cl_lru, &client_lru);
324         clp->cl_time = get_seconds();
325 }
326
327 void
328 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
329 {
330         unsigned int strhashval;
331
332         dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
333         list_del_init(&clp->cl_strhash);
334         list_del_init(&clp->cl_idhash);
335         list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
336         strhashval = clientstr_hashval(clp->cl_name.data, 
337                         clp->cl_name.len);
338         list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
339         renew_client(clp);
340 }
341
342 /*
343  * RFC 3010 has a complex implmentation description of processing a 
344  * SETCLIENTID request consisting of 5 bullets, labeled as 
345  * CASE0 - CASE4 below.
346  *
347  * NOTES:
348  *      callback information will be processed in a future patch
349  *
350  *      an unconfirmed record is added when:
351  *      NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
352  *      CASE 1: confirmed record found with matching name, principal,
353  *              verifier, and clientid.
354  *      CASE 2: confirmed record found with matching name, principal,
355  *              and there is no unconfirmed record with matching
356  *              name and principal
357  *
358  *      an unconfirmed record is replaced when:
359  *      CASE 3: confirmed record found with matching name, principal,
360  *              and an unconfirmed record is found with matching 
361  *              name, principal, and with clientid and
362  *              confirm that does not match the confirmed record.
363  *      CASE 4: there is no confirmed record with matching name and 
364  *              principal. there is an unconfirmed record with 
365  *              matching name, principal.
366  *
367  *      an unconfirmed record is deleted when:
368  *      CASE 1: an unconfirmed record that matches input name, verifier,
369  *              and confirmed clientid.
370  *      CASE 4: any unconfirmed records with matching name and principal
371  *              that exist after an unconfirmed record has been replaced
372  *              as described above.
373  *
374  */
375 int
376 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
377 {
378         u32                     ip_addr = rqstp->rq_addr.sin_addr.s_addr;
379         struct xdr_netobj       clname = { 
380                 .len = setclid->se_namelen,
381                 .data = setclid->se_name,
382         };
383         nfs4_verifier           clverifier = setclid->se_verf;
384         unsigned int            strhashval;
385         struct nfs4_client *    conf, * unconf, * new, * clp;
386         int                     status;
387         
388         status = nfserr_inval;
389         if (!check_name(clname))
390                 goto out;
391
392         /* 
393          * XXX The Duplicate Request Cache (DRC) has been checked (??)
394          * We get here on a DRC miss.
395          */
396
397         strhashval = clientstr_hashval(clname.data, clname.len);
398
399         conf = NULL;
400         nfs4_lock_state();
401         list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
402                 if (!cmp_name(&clp->cl_name, &clname))
403                         continue;
404                 /* 
405                  * CASE 0:
406                  * clname match, confirmed, different principal
407                  * or different ip_address
408                  */
409                 status = nfserr_clid_inuse;
410                 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
411                         printk("NFSD: setclientid: string in use by client"
412                         "(clientid %08x/%08x)\n",
413                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
414                         goto out;
415                 }
416                 if (clp->cl_addr != ip_addr) { 
417                         printk("NFSD: setclientid: string in use by client"
418                         "(clientid %08x/%08x)\n",
419                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
420                         goto out;
421                 }
422
423                 /* 
424                  * cl_name match from a previous SETCLIENTID operation
425                  * XXX check for additional matches?
426                  */
427                 conf = clp;
428                 break;
429         }
430         unconf = NULL;
431         list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
432                 if (!cmp_name(&clp->cl_name, &clname))
433                         continue;
434                 /* cl_name match from a previous SETCLIENTID operation */
435                 unconf = clp;
436                 break;
437         }
438         status = nfserr_resource;
439         if (!conf) {
440                 /* 
441                  * CASE 4:
442                  * placed first, because it is the normal case.
443                  */
444                 if (unconf)
445                         expire_client(unconf);
446                 if (!(new = create_client(clname)))
447                         goto out;
448                 copy_verf(new, &clverifier);
449                 new->cl_addr = ip_addr;
450                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
451                 gen_clid(new);
452                 gen_confirm(new);
453                 add_to_unconfirmed(new, strhashval);
454         } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
455                 /*
456                  * CASE 1:
457                  * cl_name match, confirmed, principal match
458                  * verifier match: probable callback update
459                  *
460                  * remove any unconfirmed nfs4_client with 
461                  * matching cl_name, cl_verifier, and cl_clientid
462                  *
463                  * create and insert an unconfirmed nfs4_client with same 
464                  * cl_name, cl_verifier, and cl_clientid as existing 
465                  * nfs4_client,  but with the new callback info and a 
466                  * new cl_confirm
467                  */
468                 if ((unconf) && 
469                     cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
470                      cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
471                                 expire_client(unconf);
472                 }
473                 if (!(new = create_client(clname)))
474                         goto out;
475                 copy_verf(new,&conf->cl_verifier);
476                 new->cl_addr = ip_addr;
477                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
478                 copy_clid(new, conf);
479                 gen_confirm(new);
480                 add_to_unconfirmed(new,strhashval);
481         } else if (!unconf) {
482                 /*
483                  * CASE 2:
484                  * clname match, confirmed, principal match
485                  * verfier does not match
486                  * no unconfirmed. create a new unconfirmed nfs4_client
487                  * using input clverifier, clname, and callback info
488                  * and generate a new cl_clientid and cl_confirm.
489                  */
490                 if (!(new = create_client(clname)))
491                         goto out;
492                 copy_verf(new,&clverifier);
493                 new->cl_addr = ip_addr;
494                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
495                 gen_clid(new);
496                 gen_confirm(new);
497                 add_to_unconfirmed(new, strhashval);
498         } else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
499               !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
500                 /*      
501                  * CASE3:
502                  * confirmed found (name, principal match)
503                  * confirmed verifier does not match input clverifier
504                  *
505                  * unconfirmed found (name match)
506                  * confirmed->cl_clientid != unconfirmed->cl_clientid and
507                  * confirmed->cl_confirm != unconfirmed->cl_confirm
508                  *
509                  * remove unconfirmed.
510                  *
511                  * create an unconfirmed nfs4_client 
512                  * with same cl_name as existing confirmed nfs4_client, 
513                  * but with new callback info, new cl_clientid,
514                  * new cl_verifier and a new cl_confirm
515                  */
516                 expire_client(unconf);
517                 if (!(new = create_client(clname)))
518                         goto out;
519                 copy_verf(new,&clverifier);
520                 new->cl_addr = ip_addr;
521                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
522                 gen_clid(new);
523                 gen_confirm(new);
524                 add_to_unconfirmed(new, strhashval);
525         } else {
526                 /* No cases hit !!! */
527                 status = nfserr_inval;
528                 goto out;
529
530         }
531         setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
532         setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
533         memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
534         printk(KERN_INFO "NFSD: this client will not receive delegations\n");
535         status = nfs_ok;
536 out:
537         nfs4_unlock_state();
538         return status;
539 }
540
541
542 /*
543  * RFC 3010 has a complex implmentation description of processing a 
544  * SETCLIENTID_CONFIRM request consisting of 4 bullets describing
545  * processing on a DRC miss, labeled as CASE1 - CASE4 below.
546  *
547  * NOTE: callback information will be processed here in a future patch
548  */
549 int
550 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
551 {
552         u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
553         unsigned int idhashval;
554         struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
555         nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
556         clientid_t * clid = &setclientid_confirm->sc_clientid;
557         int status;
558
559         status = nfserr_stale_clientid;
560         if (STALE_CLIENTID(clid))
561                 goto out;
562         /* 
563          * XXX The Duplicate Request Cache (DRC) has been checked (??)
564          * We get here on a DRC miss.
565          */
566
567         idhashval = clientid_hashval(clid->cl_id);
568         nfs4_lock_state();
569         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
570                 if (!cmp_clid(&clp->cl_clientid, clid))
571                         continue;
572
573                 status = nfserr_inval;
574                 /* 
575                  * Found a record for this clientid. If the IP addresses
576                  * don't match, return ERR_INVAL just as if the record had
577                  * not been found.
578                  */
579                 if (clp->cl_addr != ip_addr) { 
580                         printk("NFSD: setclientid: string in use by client"
581                         "(clientid %08x/%08x)\n",
582                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
583                         goto out;
584                 }
585                 conf = clp;
586                 break;
587         }
588         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
589                 if (!cmp_clid(&clp->cl_clientid, clid))
590                         continue;
591                 status = nfserr_inval;
592                 if (clp->cl_addr != ip_addr) { 
593                         printk("NFSD: setclientid: string in use by client"
594                         "(clientid %08x/%08x)\n",
595                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
596                         goto out;
597                 }
598                 unconf = clp;
599                 break;
600         }
601         /* CASE 1: 
602         * unconf record that matches input clientid and input confirm.
603         * conf record that matches input clientid.
604         * conf  and unconf records match names, verifiers 
605         */
606         if ((conf && unconf) && 
607             (cmp_verf(&unconf->cl_confirm, &confirm)) &&
608             (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
609             (cmp_name(&conf->cl_name,&unconf->cl_name))  &&
610             (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
611                 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 
612                         status = nfserr_clid_inuse;
613                 else {
614                         expire_client(conf);
615                         move_to_confirmed(unconf, idhashval);
616                         status = nfs_ok;
617                 }
618                 goto out;
619         } 
620         /* CASE 2:
621          * conf record that matches input clientid.
622          * if unconf record that matches input clientid, then unconf->cl_name
623          * or unconf->cl_verifier don't match the conf record.
624          */
625         if ((conf && !unconf) || 
626             ((conf && unconf) && 
627              (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
628               !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
629                 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
630                         status = nfserr_clid_inuse;
631                 } else {
632                         status = nfs_ok;
633                 }
634                 goto out;
635         }
636         /* CASE 3:
637          * conf record not found.
638          * unconf record found. 
639          * unconf->cl_confirm matches input confirm
640          */ 
641         if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
642                 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
643                         status = nfserr_clid_inuse;
644                 } else {
645                         status = nfs_ok;
646                         move_to_confirmed(unconf, idhashval);
647                 }
648                 goto out;
649         }
650         /* CASE 4:
651          * conf record not found, or if conf, then conf->cl_confirm does not
652          * match input confirm.
653          * unconf record not found, or if unconf, then unconf->cl_confirm 
654          * does not match input confirm.
655          */
656         if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
657             (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
658                 status = nfserr_stale_clientid;
659                 goto out;
660         }
661         /* check that we have hit one of the cases...*/
662         status = nfserr_inval;
663         goto out;
664 out:
665         /* XXX if status == nfs_ok, probe callback path */
666         nfs4_unlock_state();
667         return status;
668 }
669
670 /* 
671  * Open owner state (share locks)
672  */
673
674 /* hash tables for nfs4_stateowner */
675 #define OWNER_HASH_BITS              8
676 #define OWNER_HASH_SIZE             (1 << OWNER_HASH_BITS)
677 #define OWNER_HASH_MASK             (OWNER_HASH_SIZE - 1)
678
679 #define ownerid_hashval(id) \
680         ((id) & OWNER_HASH_MASK)
681 #define ownerstr_hashval(clientid, ownername) \
682         (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
683
684 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
685 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
686
687 /* hash table for nfs4_file */
688 #define FILE_HASH_BITS                   8
689 #define FILE_HASH_SIZE                  (1 << FILE_HASH_BITS)
690 #define FILE_HASH_MASK                  (FILE_HASH_SIZE - 1)
691 /* hash table for (open)nfs4_stateid */
692 #define STATEID_HASH_BITS              10
693 #define STATEID_HASH_SIZE              (1 << STATEID_HASH_BITS)
694 #define STATEID_HASH_MASK              (STATEID_HASH_SIZE - 1)
695
696 #define file_hashval(x) \
697         hash_ptr(x, FILE_HASH_BITS)
698 #define stateid_hashval(owner_id, file_id)  \
699         (((owner_id) + (file_id)) & STATEID_HASH_MASK)
700
701 static struct list_head file_hashtbl[FILE_HASH_SIZE];
702 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
703
704 /* OPEN Share state helper functions */
705 static inline struct nfs4_file *
706 alloc_init_file(unsigned int hashval, struct inode *ino) {
707         struct nfs4_file *fp;
708         if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
709                 INIT_LIST_HEAD(&fp->fi_hash);
710                 INIT_LIST_HEAD(&fp->fi_perfile);
711                 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
712                 fp->fi_inode = igrab(ino);
713                 fp->fi_id = current_fileid++;
714                 alloc_file++;
715                 return fp;
716         }
717         return (struct nfs4_file *)NULL;
718 }
719
720 static void
721 release_all_files(void)
722 {
723         int i;
724         struct nfs4_file *fp;
725
726         for (i=0;i<FILE_HASH_SIZE;i++) {
727                 while (!list_empty(&file_hashtbl[i])) {
728                         fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
729                         /* this should never be more than once... */
730                         if(!list_empty(&fp->fi_perfile)) {
731                                 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
732                         }
733                         release_file(fp);
734                 }
735         }
736 }
737
738 static inline struct nfs4_stateowner *
739 alloc_stateowner(struct xdr_netobj *owner)
740 {
741         struct nfs4_stateowner *sop;
742
743         if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
744                 if((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
745                         memcpy(sop->so_owner.data, owner->data, owner->len);
746                         sop->so_owner.len = owner->len;
747                         return sop;
748                 } 
749                 kfree(sop);
750         }
751         return (struct nfs4_stateowner *)NULL;
752 }
753
754 /* should use a slab cache */
755 static void
756 free_stateowner(struct nfs4_stateowner *sop) {
757         if(sop) {
758                 kfree(sop->so_owner.data);
759                 kfree(sop);
760                 sop = NULL;
761                 free_sowner++;
762         }
763 }
764
765 static struct nfs4_stateowner *
766 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
767         struct nfs4_stateowner *sop;
768         struct nfs4_replay *rp;
769         unsigned int idhashval;
770
771         if (!(sop = alloc_stateowner(&open->op_owner)))
772                 return (struct nfs4_stateowner *)NULL;
773         idhashval = ownerid_hashval(current_ownerid);
774         INIT_LIST_HEAD(&sop->so_idhash);
775         INIT_LIST_HEAD(&sop->so_strhash);
776         INIT_LIST_HEAD(&sop->so_perclient);
777         INIT_LIST_HEAD(&sop->so_perfilestate);
778         INIT_LIST_HEAD(&sop->so_perlockowner);  /* not used */
779         INIT_LIST_HEAD(&sop->so_close_lru);
780         sop->so_time = 0;
781         list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
782         list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
783         list_add(&sop->so_perclient, &clp->cl_perclient);
784         add_perclient++;
785         sop->so_is_open_owner = 1;
786         sop->so_id = current_ownerid++;
787         sop->so_client = clp;
788         sop->so_seqid = open->op_seqid;
789         sop->so_confirmed = 0;
790         rp = &sop->so_replay;
791         rp->rp_status = NFSERR_SERVERFAULT;
792         rp->rp_buflen = 0;
793         rp->rp_buf = rp->rp_ibuf;
794         alloc_sowner++;
795         return sop;
796 }
797
798 static void
799 release_stateid_lockowner(struct nfs4_stateid *open_stp)
800 {
801         struct nfs4_stateowner *lock_sop;
802
803         while (!list_empty(&open_stp->st_perlockowner)) {
804                 lock_sop = list_entry(open_stp->st_perlockowner.next,
805                                 struct nfs4_stateowner, so_perlockowner);
806                 /* list_del(&open_stp->st_perlockowner);  */
807                 BUG_ON(lock_sop->so_is_open_owner);
808                 release_stateowner(lock_sop);
809         }
810 }
811
812 static void
813 release_stateowner(struct nfs4_stateowner *sop)
814 {
815         struct nfs4_stateid *stp;
816
817         list_del(&sop->so_idhash);
818         list_del(&sop->so_strhash);
819         list_del(&sop->so_perclient);
820         list_del(&sop->so_perlockowner);
821         list_del(&sop->so_close_lru);
822         del_perclient++;
823         while (!list_empty(&sop->so_perfilestate)) {
824                 stp = list_entry(sop->so_perfilestate.next, 
825                         struct nfs4_stateid, st_perfilestate);
826                 if(sop->so_is_open_owner)
827                         release_stateid(stp, OPEN_STATE);
828                 else
829                         release_stateid(stp, LOCK_STATE);
830         }
831         free_stateowner(sop);
832 }
833
834 static inline void
835 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
836         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
837
838         INIT_LIST_HEAD(&stp->st_hash);
839         INIT_LIST_HEAD(&stp->st_perfilestate);
840         INIT_LIST_HEAD(&stp->st_perlockowner);
841         INIT_LIST_HEAD(&stp->st_perfile);
842         list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
843         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
844         list_add_perfile++;
845         list_add(&stp->st_perfile, &fp->fi_perfile);
846         stp->st_stateowner = sop;
847         stp->st_file = fp;
848         stp->st_stateid.si_boot = boot_time;
849         stp->st_stateid.si_stateownerid = sop->so_id;
850         stp->st_stateid.si_fileid = fp->fi_id;
851         stp->st_stateid.si_generation = 0;
852         stp->st_access_bmap = 0;
853         stp->st_deny_bmap = 0;
854         __set_bit(open->op_share_access, &stp->st_access_bmap);
855         __set_bit(open->op_share_deny, &stp->st_deny_bmap);
856 }
857
858 static void
859 release_stateid(struct nfs4_stateid *stp, int flags) {
860
861         list_del(&stp->st_hash);
862         list_del_perfile++;
863         list_del(&stp->st_perfile);
864         list_del(&stp->st_perfilestate);
865         if((stp->st_vfs_set) && (flags & OPEN_STATE)) {
866                 release_stateid_lockowner(stp);
867                 nfsd_close(&stp->st_vfs_file);
868                 vfsclose++;
869                 dput(stp->st_vfs_file.f_dentry);
870                 mntput(stp->st_vfs_file.f_vfsmnt);
871         } else if ((stp->st_vfs_set) && (flags & LOCK_STATE)) {
872                 struct file *filp = &stp->st_vfs_file;
873
874                 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
875         }
876         kfree(stp);
877         stp = NULL;
878 }
879
880 static void
881 release_file(struct nfs4_file *fp)
882 {
883         free_file++;
884         list_del(&fp->fi_hash);
885         iput(fp->fi_inode);
886         kfree(fp);
887 }       
888
889 void
890 move_to_close_lru(struct nfs4_stateowner *sop)
891 {
892         dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
893         /* remove stateowner from all other hash lists except perclient */
894         list_del_init(&sop->so_idhash);
895         list_del_init(&sop->so_strhash);
896         list_del_init(&sop->so_perlockowner);
897
898         list_add_tail(&sop->so_close_lru, &close_lru);
899         sop->so_time = get_seconds();
900 }
901
902 void
903 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
904                 int flag)
905 {
906         struct nfs4_stateowner *sop = stp->st_stateowner;
907         struct nfs4_file *fp = stp->st_file;
908
909         dprintk("NFSD: release_state_owner\n");
910         release_stateid(stp, flag);
911
912         /* place unused nfs4_stateowners on so_close_lru list to be
913          * released by the laundromat service after the lease period
914          * to enable us to handle CLOSE replay
915          */
916         if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
917                 move_to_close_lru(sop);
918         /* unused nfs4_file's are releseed. XXX slab cache? */
919         if (list_empty(&fp->fi_perfile)) {
920                 release_file(fp);
921         }
922 }
923
924 static int
925 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
926         return ((sop->so_owner.len == owner->len) && 
927          !memcmp(sop->so_owner.data, owner->data, owner->len) && 
928           (sop->so_client->cl_clientid.cl_id == clid->cl_id));
929 }
930
931 /* search ownerstr_hashtbl[] for owner */
932 static int
933 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
934         struct nfs4_stateowner *local = NULL;
935
936         list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) {
937                 if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid)) 
938                         continue;
939                 *op = local;
940                 return(1);
941         }
942         return 0;
943 }
944
945 /* see if clientid is in confirmed hash table */
946 static int
947 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
948
949         struct nfs4_client *clp;
950         unsigned int idhashval = clientid_hashval(clid->cl_id);
951
952         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
953                 if (!cmp_clid(&clp->cl_clientid, clid))
954                         continue;
955                 *client = clp;
956                 return 1;
957         }
958         *client = NULL;
959         return 0;
960 }
961
962 /* search file_hashtbl[] for file */
963 static int
964 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
965         struct nfs4_file *local = NULL;
966
967         list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) {
968                 if (local->fi_inode == ino) {
969                         *fp = local;
970                         return(1);
971                 }
972         }
973         return 0;
974 }
975
976 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
977 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
978
979 void
980 set_access(unsigned int *access, unsigned long bmap) {
981         int i;
982
983         *access = 0;
984         for (i = 1; i < 4; i++) {
985                 if(test_bit(i, &bmap))
986                         *access |= i;
987         }
988 }
989
990 void
991 set_deny(unsigned int *deny, unsigned long bmap) {
992         int i;
993
994         *deny = 0;
995         for (i = 0; i < 4; i++) {
996                 if(test_bit(i, &bmap))
997                         *deny |= i ;
998         }
999 }
1000
1001 static int
1002 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1003         unsigned int access, deny;
1004
1005         set_access(&access, stp->st_access_bmap);
1006         set_deny(&deny, stp->st_deny_bmap);
1007         if ((access & open->op_share_deny) || (deny & open->op_share_access))
1008                 return 0;
1009         return 1;
1010 }
1011
1012 /*
1013  * Called to check deny when READ with all zero stateid or
1014  * WRITE with all zero or all one stateid
1015  */
1016 int
1017 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1018 {
1019         struct inode *ino = current_fh->fh_dentry->d_inode;
1020         unsigned int fi_hashval;
1021         struct nfs4_file *fp;
1022         struct nfs4_stateid *stp;
1023
1024         dprintk("NFSD: nfs4_share_conflict\n");
1025
1026         fi_hashval = file_hashval(ino);
1027         if (find_file(fi_hashval, ino, &fp)) {
1028         /* Search for conflicting share reservations */
1029                 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
1030                         if (test_bit(deny_type, &stp->st_deny_bmap) ||
1031                             test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1032                                 return nfserr_share_denied;
1033                 }
1034         }
1035         return nfs_ok;
1036 }
1037
1038 static inline int
1039 nfs4_file_upgrade(struct file *filp, unsigned int share_access)
1040 {
1041 int status;
1042
1043         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1044                 status = get_write_access(filp->f_dentry->d_inode);
1045                 if (!status)
1046                         filp->f_mode = FMODE_WRITE;
1047                 else
1048                         return nfserrno(status);
1049         }
1050         return nfs_ok;
1051 }
1052
1053 static inline void
1054 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1055 {
1056         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1057                 put_write_access(filp->f_dentry->d_inode);
1058                 filp->f_mode = FMODE_READ;
1059         }
1060 }
1061
1062
1063 /*
1064  * nfsd4_process_open1()
1065  *      lookup stateowner.
1066  *              found:
1067  *                      check confirmed 
1068  *                              confirmed:
1069  *                                      check seqid
1070  *                              not confirmed:
1071  *                                      delete owner
1072  *                                      create new owner
1073  *              notfound:
1074  *                      verify clientid
1075  *                      create new owner
1076  *
1077  * called with nfs4_lock_state() held.
1078  */
1079 int
1080 nfsd4_process_open1(struct nfsd4_open *open)
1081 {
1082         int status;
1083         clientid_t *clientid = &open->op_clientid;
1084         struct nfs4_client *clp = NULL;
1085         unsigned int strhashval;
1086         struct nfs4_stateowner *sop = NULL;
1087
1088         status = nfserr_inval;
1089         if (!check_name(open->op_owner))
1090                 goto out;
1091
1092         status = nfserr_stale_clientid;
1093         if (STALE_CLIENTID(&open->op_clientid))
1094                 return status;
1095
1096         strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1097         if (find_openstateowner_str(strhashval, open, &sop)) {
1098                 open->op_stateowner = sop;
1099                 /* check for replay */
1100                 if (open->op_seqid == sop->so_seqid){
1101                         if (!sop->so_replay.rp_buflen) {
1102                         /*
1103                         * The original OPEN failed in so spectacularly that we
1104                         * don't even have replay data saved!  Therefore, we
1105                         * have no choice but to continue processing
1106                         * this OPEN; presumably, we'll fail again for the same
1107                         * reason.
1108                         */
1109                                 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1110                                 status = NFS_OK;
1111                                 goto renew;
1112                         }
1113                         /* replay: indicate to calling function */
1114                         status = NFSERR_REPLAY_ME;
1115                         return status;
1116                 }
1117                 if (sop->so_confirmed) {
1118                         if (open->op_seqid == sop->so_seqid + 1) { 
1119                                 status = nfs_ok;
1120                                 goto renew;
1121                         } 
1122                         status = nfserr_bad_seqid;
1123                         goto out;
1124                 }
1125                 /* If we get here, we received and OPEN for an unconfirmed
1126                  * nfs4_stateowner. 
1127                  * Since the sequid's are different, purge the 
1128                  * existing nfs4_stateowner, and instantiate a new one.
1129                  */
1130                 clp = sop->so_client;
1131                 release_stateowner(sop);
1132                 goto instantiate_new_owner;
1133         } 
1134         /* nfs4_stateowner not found. 
1135         * verify clientid and instantiate new nfs4_stateowner
1136         * if verify fails this is presumably the result of the 
1137         * client's lease expiring.
1138         *
1139         * XXX compare clp->cl_addr with rqstp addr? 
1140         */
1141         status = nfserr_expired;
1142         if (!verify_clientid(&clp, clientid))
1143                 goto out;
1144 instantiate_new_owner:
1145         status = nfserr_resource;
1146         if (!(sop = alloc_init_open_stateowner(strhashval, clp, open))) 
1147                 goto out;
1148         open->op_stateowner = sop;
1149         status = nfs_ok;
1150 renew:
1151         renew_client(sop->so_client);
1152 out:
1153         if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1154                 status = nfserr_reclaim_bad;
1155         return status;
1156 }
1157 /*
1158  * called with nfs4_lock_state() held.
1159  */
1160 int
1161 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1162 {
1163         struct iattr iattr;
1164         struct nfs4_stateowner *sop = open->op_stateowner;
1165         struct nfs4_file *fp = NULL;
1166         struct inode *ino;
1167         unsigned int fi_hashval;
1168         struct nfs4_stateid *stq, *stp = NULL;
1169         int status;
1170
1171         status = nfserr_resource;
1172         if (!sop)
1173                 return status;
1174
1175         ino = current_fh->fh_dentry->d_inode;
1176
1177         status = nfserr_inval;
1178         if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1179                 goto out;
1180
1181         fi_hashval = file_hashval(ino);
1182         if (find_file(fi_hashval, ino, &fp)) {
1183                 /* Search for conflicting share reservations */
1184                 status = nfserr_share_denied;
1185                 list_for_each_entry(stq, &fp->fi_perfile, st_perfile) {
1186                         if(stq->st_stateowner == sop) {
1187                                 stp = stq;
1188                                 continue;
1189                         }
1190                         /* ignore lock owners */
1191                         if (stq->st_stateowner->so_is_open_owner == 0)
1192                                 continue;
1193                         if (!test_share(stq,open))      
1194                                 goto out;
1195                 }
1196         } else {
1197         /* No nfs4_file found; allocate and init a new one */
1198                 status = nfserr_resource;
1199                 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1200                         goto out;
1201         }
1202
1203         if (!stp) {
1204                 int flags = 0;
1205
1206                 status = nfserr_resource;
1207                 if ((stp = kmalloc(sizeof(struct nfs4_stateid),
1208                                                 GFP_KERNEL)) == NULL)
1209                         goto out;
1210
1211                 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1212                         flags = MAY_WRITE;
1213                 else
1214                         flags = MAY_READ;
1215                 if ((status = nfsd_open(rqstp, current_fh,  S_IFREG,
1216                                               flags,
1217                                               &stp->st_vfs_file)) != 0)
1218                         goto out_free;
1219
1220                 vfsopen++;
1221                 dget(stp->st_vfs_file.f_dentry);
1222                 mntget(stp->st_vfs_file.f_vfsmnt);
1223
1224                 init_stateid(stp, fp, sop, open);
1225                 stp->st_vfs_set = 1;
1226         } else {
1227                 /* This is an upgrade of an existing OPEN. 
1228                  * OR the incoming share with the existing 
1229                  * nfs4_stateid share */
1230                 unsigned int share_access;
1231
1232                 set_access(&share_access, stp->st_access_bmap);
1233                 share_access = ~share_access;
1234                 share_access &= open->op_share_access;
1235
1236                 /* update the struct file */
1237                 if ((status = nfs4_file_upgrade(&stp->st_vfs_file, share_access)))
1238                         goto out;
1239                 /* remember the open */
1240                 set_bit(open->op_share_access, &stp->st_access_bmap);
1241                 set_bit(open->op_share_deny, &stp->st_deny_bmap);
1242                 /* bump the stateid */
1243                 update_stateid(&stp->st_stateid);
1244         }
1245         dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n\n",
1246                     stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1247                     stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1248
1249         if (open->op_truncate) {
1250                 iattr.ia_valid = ATTR_SIZE;
1251                 iattr.ia_size = 0;
1252                 status = nfsd_setattr(rqstp, current_fh, &iattr, 0, (time_t)0);
1253                 if (status)
1254                         goto out;
1255         }
1256         memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1257
1258         open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
1259         status = nfs_ok;
1260 out:
1261         if (fp && list_empty(&fp->fi_perfile))
1262                 release_file(fp);
1263
1264         if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
1265                 if (status)
1266                         status = nfserr_reclaim_bad;
1267                 else {
1268                 /* successful reclaim. so_seqid is decremented because
1269                 * it will be bumped in encode_open
1270                 */
1271                         open->op_stateowner->so_confirmed = 1;
1272                         open->op_stateowner->so_seqid--;
1273                 }
1274         }
1275         /*
1276         * To finish the open response, we just need to set the rflags.
1277         */
1278         open->op_rflags = 0;
1279         if (!open->op_stateowner->so_confirmed)
1280                 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1281
1282         return status;
1283 out_free:
1284         kfree(stp);
1285         goto out;
1286 }
1287
1288 static struct work_struct laundromat_work;
1289 static void laundromat_main(void *);
1290 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1291
1292 int 
1293 nfsd4_renew(clientid_t *clid)
1294 {
1295         struct nfs4_client *clp;
1296         unsigned int idhashval;
1297         int status;
1298
1299         nfs4_lock_state();
1300         dprintk("process_renew(%08x/%08x): starting\n", 
1301                         clid->cl_boot, clid->cl_id);
1302         status = nfserr_stale_clientid;
1303         if (STALE_CLIENTID(clid))
1304                 goto out;
1305         status = nfs_ok;
1306         idhashval = clientid_hashval(clid->cl_id);
1307         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1308                 if (!cmp_clid(&clp->cl_clientid, clid))
1309                         continue;
1310                 renew_client(clp);
1311                 goto out;
1312         }
1313         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1314                 if (!cmp_clid(&clp->cl_clientid, clid))
1315                         continue;
1316                 renew_client(clp);
1317         goto out;
1318         }
1319         /*
1320         * Couldn't find an nfs4_client for this clientid.  
1321         * Presumably this is because the client took too long to 
1322         * RENEW, so return NFS4ERR_EXPIRED.
1323         */
1324         dprintk("nfsd4_renew: clientid not found!\n");
1325         status = nfserr_expired;
1326 out:
1327         nfs4_unlock_state();
1328         return status;
1329 }
1330
1331 time_t
1332 nfs4_laundromat(void)
1333 {
1334         struct nfs4_client *clp;
1335         struct nfs4_stateowner *sop;
1336         struct list_head *pos, *next;
1337         time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1338         time_t t, clientid_val = NFSD_LEASE_TIME;
1339         time_t u, close_val = NFSD_LEASE_TIME;
1340
1341         nfs4_lock_state();
1342
1343         dprintk("NFSD: laundromat service - starting, examining clients\n");
1344         list_for_each_safe(pos, next, &client_lru) {
1345                 clp = list_entry(pos, struct nfs4_client, cl_lru);
1346                 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1347                         t = clp->cl_time - cutoff;
1348                         if (clientid_val > t)
1349                                 clientid_val = t;
1350                         break;
1351                 }
1352                 dprintk("NFSD: purging unused client (clientid %08x)\n",
1353                         clp->cl_clientid.cl_id);
1354                 expire_client(clp);
1355         }
1356         list_for_each_safe(pos, next, &close_lru) {
1357                 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
1358                 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
1359                         u = sop->so_time - cutoff;
1360                         if (close_val > u)
1361                                 close_val = u;
1362                         break;
1363                 }
1364                 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1365                         sop->so_id);
1366                 release_stateowner(sop);
1367         }
1368         if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1369                 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1370         nfs4_unlock_state();
1371         return clientid_val;
1372 }
1373
1374 void
1375 laundromat_main(void *not_used)
1376 {
1377         time_t t;
1378
1379         t = nfs4_laundromat();
1380         dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1381         schedule_delayed_work(&laundromat_work, t*HZ);
1382 }
1383
1384 /* search ownerid_hashtbl[] and close_lru for stateid owner
1385  * (stateid->si_stateownerid)
1386  */
1387 struct nfs4_stateowner *
1388 find_openstateowner_id(u32 st_id, int flags) {
1389         struct nfs4_stateowner *local = NULL;
1390
1391         dprintk("NFSD: find_openstateowner_id %d\n", st_id);
1392         if (flags & CLOSE_STATE) {
1393                 list_for_each_entry(local, &close_lru, so_close_lru) {
1394                         if(local->so_id == st_id)
1395                                 return local;
1396                 }
1397         }
1398         return NULL;
1399 }
1400
1401 static inline int
1402 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1403 {
1404         return (stp->st_vfs_set == 0 ||
1405                 fhp->fh_dentry->d_inode != stp->st_vfs_file.f_dentry->d_inode);
1406 }
1407
1408 static int
1409 STALE_STATEID(stateid_t *stateid)
1410 {
1411         if (stateid->si_boot == boot_time)
1412                 return 0;
1413         printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1414                 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1415                 stateid->si_generation);
1416         return 1;
1417 }
1418
1419
1420 /*
1421 * Checks for stateid operations
1422 */
1423 int
1424 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp)
1425 {
1426         struct nfs4_stateid *stp;
1427         int status;
1428
1429         dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
1430                 stateid->si_boot, stateid->si_stateownerid, 
1431                 stateid->si_fileid, stateid->si_generation); 
1432
1433         *stpp = NULL;
1434
1435         /* STALE STATEID */
1436         status = nfserr_stale_stateid;
1437         if (STALE_STATEID(stateid)) 
1438                 goto out;
1439
1440         /* BAD STATEID */
1441         status = nfserr_bad_stateid;
1442         if (!(stp = find_stateid(stateid, flags))) {
1443                 dprintk("NFSD: preprocess_stateid_op: no open stateid!\n");
1444                 goto out;
1445         }
1446         if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1447                 dprintk("NFSD: preprocess_stateid_op: fh-stateid mismatch!\n");
1448                 stp->st_vfs_set = 0;
1449                 goto out;
1450         }
1451         if (!stp->st_stateowner->so_confirmed) {
1452                 dprintk("preprocess_stateid_op: lockowner not confirmed yet!\n");
1453                 goto out;
1454         }
1455         if (stateid->si_generation > stp->st_stateid.si_generation) {
1456                 dprintk("preprocess_stateid_op: future stateid?!\n");
1457                 goto out;
1458         }
1459
1460         /* OLD STATEID */
1461         status = nfserr_old_stateid;
1462         if (stateid->si_generation < stp->st_stateid.si_generation) {
1463                 dprintk("preprocess_stateid_op: old stateid!\n");
1464                 goto out;
1465         }
1466         *stpp = stp;
1467         status = nfs_ok;
1468         renew_client(stp->st_stateowner->so_client);
1469 out:
1470         return status;
1471 }
1472
1473
1474 /* 
1475  * Checks for sequence id mutating operations. 
1476  */
1477 int
1478 nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid)
1479 {
1480         int status;
1481         struct nfs4_stateid *stp;
1482         struct nfs4_stateowner *sop;
1483
1484         dprintk("NFSD: preprocess_seqid_op: seqid=%d " 
1485                         "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
1486                 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1487                 stateid->si_generation);
1488                                 
1489         *stpp = NULL;
1490         *sopp = NULL;
1491
1492         status = nfserr_bad_stateid;
1493         if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
1494                 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
1495                 goto out;
1496         }
1497
1498         status = nfserr_stale_stateid;
1499         if (STALE_STATEID(stateid))
1500                 goto out;
1501         /*
1502         * We return BAD_STATEID if filehandle doesn't match stateid, 
1503         * the confirmed flag is incorrecly set, or the generation 
1504         * number is incorrect.  
1505         * If there is no entry in the openfile table for this id, 
1506         * we can't always return BAD_STATEID;
1507         * this might be a retransmitted CLOSE which has arrived after 
1508         * the openfile has been released.
1509         */
1510         if (!(stp = find_stateid(stateid, flags)))
1511                 goto no_nfs4_stateid;
1512
1513         status = nfserr_bad_stateid;
1514
1515         /* for new lock stateowners, check that the lock->v.new.open_stateid
1516          * refers to an open stateowner, and that the lockclid
1517          * (nfs4_lock->v.new.clientid) is the same as the
1518          * open_stateid->st_stateowner->so_client->clientid
1519          */
1520         if (lockclid) {
1521                 struct nfs4_stateowner *sop = stp->st_stateowner;
1522                 struct nfs4_client *clp = sop->so_client;
1523
1524                 if (!sop->so_is_open_owner)
1525                         goto out;
1526                 if (!cmp_clid(&clp->cl_clientid, lockclid))
1527                         goto out;
1528         }
1529
1530         if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
1531                 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
1532                 stp->st_vfs_set = 0;
1533                 goto out;
1534         }
1535
1536         *stpp = stp;
1537         *sopp = sop = stp->st_stateowner;
1538
1539         /*
1540         *  We now validate the seqid and stateid generation numbers.
1541         *  For the moment, we ignore the possibility of 
1542         *  generation number wraparound.
1543         */
1544         if (seqid != sop->so_seqid + 1)
1545                 goto check_replay;
1546
1547         if (sop->so_confirmed) {
1548                 if (flags & CONFIRM) {
1549                         printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
1550                         goto out;
1551                 }
1552         }
1553         else {
1554                 if (!(flags & CONFIRM)) {
1555                         printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
1556                         goto out;
1557                 }
1558         }
1559         if (stateid->si_generation > stp->st_stateid.si_generation) {
1560                 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
1561                 goto out;
1562         }
1563
1564         status = nfserr_old_stateid;
1565         if (stateid->si_generation < stp->st_stateid.si_generation) {
1566                 printk("NFSD: preprocess_seqid_op: old stateid!\n");
1567                 goto out;
1568         }
1569         /* XXX renew the client lease here */
1570         status = nfs_ok;
1571
1572 out:
1573         return status;
1574
1575 no_nfs4_stateid:
1576
1577         /*
1578         * We determine whether this is a bad stateid or a replay, 
1579         * starting by trying to look up the stateowner.
1580         * If stateowner is not found - stateid is bad.
1581         */
1582         if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
1583                 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
1584                 status = nfserr_bad_stateid;
1585                 goto out;
1586         }
1587         *sopp = sop;
1588
1589 check_replay:
1590         if (seqid == sop->so_seqid) {
1591                 printk("NFSD: preprocess_seqid_op: retransmission?\n");
1592                 /* indicate replay to calling function */
1593                 status = NFSERR_REPLAY_ME;
1594         } else  {
1595                 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
1596
1597                 *sopp = NULL;
1598                 status = nfserr_bad_seqid;
1599         }
1600         goto out;
1601 }
1602
1603 /*
1604  * nfs4_unlock_state(); called in encode
1605  */
1606 int
1607 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
1608 {
1609         int status;
1610         struct nfs4_stateowner *sop;
1611         struct nfs4_stateid *stp;
1612
1613         dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
1614                         (int)current_fh->fh_dentry->d_name.len,
1615                         current_fh->fh_dentry->d_name.name);
1616
1617         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
1618                 goto out;
1619
1620         oc->oc_stateowner = NULL;
1621         nfs4_lock_state();
1622
1623         if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
1624                                         &oc->oc_req_stateid,
1625                                         CHECK_FH | CONFIRM | OPEN_STATE,
1626                                         &oc->oc_stateowner, &stp, NULL)))
1627                 goto out; 
1628
1629         sop = oc->oc_stateowner;
1630         sop->so_confirmed = 1;
1631         update_stateid(&stp->st_stateid);
1632         memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
1633         dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " 
1634                 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
1635                          stp->st_stateid.si_boot,
1636                          stp->st_stateid.si_stateownerid,
1637                          stp->st_stateid.si_fileid,
1638                          stp->st_stateid.si_generation);
1639         status = nfs_ok;
1640 out:
1641         return status;
1642 }
1643
1644
1645 /*
1646  * unset all bits in union bitmap (bmap) that
1647  * do not exist in share (from successful OPEN_DOWNGRADE)
1648  */
1649 static void
1650 reset_union_bmap_access(unsigned long access, unsigned long *bmap)
1651 {
1652         int i;
1653         for (i = 1; i < 4; i++) {
1654                 if ((i & access) != i)
1655                         __clear_bit(i, bmap);
1656         }
1657 }
1658
1659 static void
1660 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
1661 {
1662         int i;
1663         for (i = 0; i < 4; i++) {
1664                 if ((i & deny) != i)
1665                         __clear_bit(i, bmap);
1666         }
1667 }
1668
1669 /*
1670  * nfs4_unlock_state(); called in encode
1671  */
1672
1673 int
1674 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
1675 {
1676         int status;
1677         struct nfs4_stateid *stp;
1678         unsigned int share_access;
1679
1680         dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 
1681                         (int)current_fh->fh_dentry->d_name.len,
1682                         current_fh->fh_dentry->d_name.name);
1683
1684         od->od_stateowner = NULL;
1685         status = nfserr_inval;
1686         if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
1687                 goto out;
1688
1689         nfs4_lock_state();
1690         if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, 
1691                                         &od->od_stateid, 
1692                                         CHECK_FH | OPEN_STATE, 
1693                                         &od->od_stateowner, &stp, NULL)))
1694                 goto out; 
1695
1696         status = nfserr_inval;
1697         if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
1698                 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
1699                         stp->st_access_bmap, od->od_share_access);
1700                 goto out;
1701         }
1702         if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) {
1703                 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
1704                         stp->st_deny_bmap, od->od_share_deny);
1705                 goto out;
1706         }
1707         set_access(&share_access, stp->st_access_bmap);
1708         nfs4_file_downgrade(&stp->st_vfs_file, 
1709                             share_access & ~od->od_share_access);
1710
1711         reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
1712         reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
1713
1714         update_stateid(&stp->st_stateid);
1715         memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
1716         status = nfs_ok;
1717 out:
1718         return status;
1719 }
1720
1721 /*
1722  * nfs4_unlock_state() called after encode
1723  */
1724 int
1725 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
1726 {
1727         int status;
1728         struct nfs4_stateid *stp;
1729
1730         dprintk("NFSD: nfsd4_close on file %.*s\n", 
1731                         (int)current_fh->fh_dentry->d_name.len,
1732                         current_fh->fh_dentry->d_name.name);
1733
1734         close->cl_stateowner = NULL;
1735         nfs4_lock_state();
1736         /* check close_lru for replay */
1737         if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, 
1738                                         &close->cl_stateid, 
1739                                         CHECK_FH | OPEN_STATE | CLOSE_STATE,
1740                                         &close->cl_stateowner, &stp, NULL)))
1741                 goto out; 
1742         /*
1743         *  Return success, but first update the stateid.
1744         */
1745         status = nfs_ok;
1746         update_stateid(&stp->st_stateid);
1747         memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
1748
1749         /* release_state_owner() calls nfsd_close() if needed */
1750         release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
1751 out:
1752         return status;
1753 }
1754
1755 /* 
1756  * Lock owner state (byte-range locks)
1757  */
1758 #define LOFF_OVERFLOW(start, len)      ((u64)(len) > ~(u64)(start))
1759 #define LOCK_HASH_BITS              8
1760 #define LOCK_HASH_SIZE             (1 << LOCK_HASH_BITS)
1761 #define LOCK_HASH_MASK             (LOCK_HASH_SIZE - 1)
1762
1763 #define lockownerid_hashval(id) \
1764         ((id) & LOCK_HASH_MASK)
1765 #define lock_ownerstr_hashval(x, clientid, ownername) \
1766         ((file_hashval(x) + (clientid) + opaque_hashval((ownername.data), (ownername.len))) & LOCK_HASH_MASK)
1767
1768 static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
1769 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
1770 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
1771
1772 struct nfs4_stateid *
1773 find_stateid(stateid_t *stid, int flags)
1774 {
1775         struct nfs4_stateid *local = NULL;
1776         u32 st_id = stid->si_stateownerid;
1777         u32 f_id = stid->si_fileid;
1778         unsigned int hashval;
1779
1780         dprintk("NFSD: find_stateid flags 0x%x\n",flags);
1781         if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) {
1782                 hashval = stateid_hashval(st_id, f_id);
1783                 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
1784                         if((local->st_stateid.si_stateownerid == st_id) &&
1785                            (local->st_stateid.si_fileid == f_id))
1786                                 return local;
1787                 }
1788         } 
1789         if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) {
1790                 hashval = stateid_hashval(st_id, f_id);
1791                 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
1792                         if((local->st_stateid.si_stateownerid == st_id) &&
1793                            (local->st_stateid.si_fileid == f_id))
1794                                 return local;
1795                 }
1796         } else
1797                 printk("NFSD: find_stateid: ERROR: no state flag\n");
1798         return NULL;
1799 }
1800
1801
1802 /*
1803  * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
1804  * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
1805  * byte, because of sign extension problems.  Since NFSv4 calls for 64-bit
1806  * locking, this prevents us from being completely protocol-compliant.  The
1807  * real solution to this problem is to start using unsigned file offsets in
1808  * the VFS, but this is a very deep change!
1809  */
1810 static inline void
1811 nfs4_transform_lock_offset(struct file_lock *lock)
1812 {
1813         if (lock->fl_start < 0)
1814                 lock->fl_start = OFFSET_MAX;
1815         if (lock->fl_end < 0)
1816                 lock->fl_end = OFFSET_MAX;
1817 }
1818
1819 int
1820 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
1821 {
1822         struct nfs4_stateowner *local = NULL;
1823         int status = 0;
1824                                 
1825         if (hashval >= LOCK_HASH_SIZE)
1826                 goto out;
1827         list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
1828                 if (local == sop) {
1829                         status = 1;
1830                         goto out;
1831                 }
1832         }
1833 out:
1834         return status;
1835 }
1836
1837
1838 static inline void
1839 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
1840 {
1841         struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
1842
1843         deny->ld_sop = NULL;
1844         if (nfs4_verify_lock_stateowner(sop, fl->fl_pid))
1845                 deny->ld_sop = sop;
1846         deny->ld_start = fl->fl_start;
1847         deny->ld_length = ~(u64)0;
1848         if (fl->fl_end != ~(u64)0)
1849                 deny->ld_length = fl->fl_end - fl->fl_start + 1;        
1850         deny->ld_type = NFS4_READ_LT;
1851         if (fl->fl_type != F_RDLCK)
1852                 deny->ld_type = NFS4_WRITE_LT;
1853 }
1854
1855
1856 static int
1857 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
1858         struct nfs4_stateowner *local = NULL;
1859
1860         list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) {
1861                 if(!cmp_owner_str(local, owner, clid)) 
1862                         continue;
1863                 *op = local;
1864                 return(1);
1865         }
1866         *op = NULL;
1867         return 0;
1868 }
1869
1870 /*
1871  * Alloc a lock owner structure.
1872  * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
1873  * occured. 
1874  *
1875  * strhashval = lock_ownerstr_hashval 
1876  * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode 
1877  */
1878
1879 static struct nfs4_stateowner *
1880 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
1881         struct nfs4_stateowner *sop;
1882         struct nfs4_replay *rp;
1883         unsigned int idhashval;
1884
1885         if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
1886                 return (struct nfs4_stateowner *)NULL;
1887         idhashval = lockownerid_hashval(current_ownerid);
1888         INIT_LIST_HEAD(&sop->so_idhash);
1889         INIT_LIST_HEAD(&sop->so_strhash);
1890         INIT_LIST_HEAD(&sop->so_perclient);
1891         INIT_LIST_HEAD(&sop->so_perfilestate);
1892         INIT_LIST_HEAD(&sop->so_perlockowner);
1893         INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
1894         sop->so_time = 0;
1895         list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
1896         list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
1897         list_add(&sop->so_perclient, &clp->cl_perclient);
1898         list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
1899         add_perclient++;
1900         sop->so_is_open_owner = 0;
1901         sop->so_id = current_ownerid++;
1902         sop->so_client = clp;
1903         sop->so_seqid = lock->lk_new_lock_seqid - 1;
1904         sop->so_confirmed = 1;
1905         rp = &sop->so_replay;
1906         rp->rp_status = NFSERR_SERVERFAULT;
1907         rp->rp_buflen = 0;
1908         rp->rp_buf = rp->rp_ibuf;
1909         alloc_lsowner++;
1910         return sop;
1911 }
1912
1913 struct nfs4_stateid *
1914 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
1915 {
1916         struct nfs4_stateid *stp;
1917         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
1918
1919         if ((stp = kmalloc(sizeof(struct nfs4_stateid), 
1920                                         GFP_KERNEL)) == NULL)
1921                 goto out;
1922         INIT_LIST_HEAD(&stp->st_hash);
1923         INIT_LIST_HEAD(&stp->st_perfile);
1924         INIT_LIST_HEAD(&stp->st_perfilestate);
1925         INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
1926         list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
1927         list_add(&stp->st_perfile, &fp->fi_perfile);
1928         list_add_perfile++;
1929         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
1930         stp->st_stateowner = sop;
1931         stp->st_file = fp;
1932         stp->st_stateid.si_boot = boot_time;
1933         stp->st_stateid.si_stateownerid = sop->so_id;
1934         stp->st_stateid.si_fileid = fp->fi_id;
1935         stp->st_stateid.si_generation = 0;
1936         stp->st_vfs_file = open_stp->st_vfs_file;
1937         stp->st_vfs_set = open_stp->st_vfs_set;
1938         stp->st_access_bmap = open_stp->st_access_bmap;
1939         stp->st_deny_bmap = open_stp->st_deny_bmap;
1940
1941 out:
1942         return stp;
1943 }
1944
1945 int
1946 check_lock_length(u64 offset, u64 length)
1947 {
1948         return ((length == 0)  || ((length != ~(u64)0) &&
1949              LOFF_OVERFLOW(offset, length)));
1950 }
1951
1952 /*
1953  *  LOCK operation 
1954  *
1955  * nfs4_unlock_state(); called in encode
1956  */
1957 int
1958 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
1959 {
1960         struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
1961         struct nfs4_stateid *lock_stp;
1962         struct file *filp;
1963         struct file_lock file_lock;
1964         struct file_lock *conflock;
1965         int status = 0;
1966         unsigned int strhashval;
1967
1968         dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
1969                 (long long) lock->lk_offset,
1970                 (long long) lock->lk_length);
1971
1972         if (nfs4_in_grace() && !lock->lk_reclaim)
1973                 return nfserr_grace;
1974         if (nfs4_in_no_grace() && lock->lk_reclaim)
1975                 return nfserr_no_grace;
1976
1977         if (check_lock_length(lock->lk_offset, lock->lk_length))
1978                  return nfserr_inval;
1979
1980         lock->lk_stateowner = NULL;
1981         nfs4_lock_state();
1982
1983         if (lock->lk_is_new) {
1984         /*
1985          * Client indicates that this is a new lockowner.
1986          * Use open owner and open stateid to create lock owner and lock 
1987          * stateid.
1988          */
1989                 struct nfs4_stateid *open_stp = NULL;
1990                 struct nfs4_file *fp;
1991                 
1992                 status = nfserr_stale_clientid;
1993                 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
1994                         printk("NFSD: nfsd4_lock: clientid is stale!\n");
1995                         goto out;
1996                 }
1997                 /* does the clientid in the lock owner own the open stateid? */
1998
1999                 /* validate and update open stateid and open seqid */
2000                 status = nfs4_preprocess_seqid_op(current_fh, 
2001                                         lock->lk_new_open_seqid,
2002                                         &lock->lk_new_open_stateid,
2003                                         CHECK_FH | OPEN_STATE,
2004                                         &open_sop, &open_stp,
2005                                         &lock->v.new.clientid);
2006                 if (status) {
2007                         if (lock->lk_reclaim)
2008                                 status = nfserr_reclaim_bad;
2009                         goto out;
2010                 }
2011                 /* create lockowner and lock stateid */
2012                 fp = open_stp->st_file;
2013                 strhashval = lock_ownerstr_hashval(fp->fi_inode, 
2014                                 open_sop->so_client->cl_clientid.cl_id, 
2015                                 lock->v.new.owner);
2016
2017                 /* 
2018                  * If we already have this lock owner, the client is in 
2019                  * error (or our bookeeping is wrong!) 
2020                  * for asking for a 'new lock'.
2021                  */
2022                 status = nfserr_bad_stateid;
2023                 if (find_lockstateowner_str(strhashval, &lock->v.new.owner,
2024                                         &lock->v.new.clientid, &lock_sop))
2025                         goto out;
2026                 status = nfserr_resource;
2027                 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2028                         goto out;
2029                 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 
2030                                                 fp, open_stp)) == NULL)
2031                         goto out;
2032                 /* bump the open seqid used to create the lock */
2033                 open_sop->so_seqid++;
2034         } else {
2035                 /* lock (lock owner + lock stateid) already exists */
2036                 status = nfs4_preprocess_seqid_op(current_fh,
2037                                        lock->lk_old_lock_seqid, 
2038                                        &lock->lk_old_lock_stateid, 
2039                                        CHECK_FH | LOCK_STATE, 
2040                                        &lock->lk_stateowner, &lock_stp, NULL);
2041                 if (status)
2042                         goto out;
2043         }
2044         /* lock->lk_stateowner and lock_stp have been created or found */
2045         filp = &lock_stp->st_vfs_file;
2046
2047         if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2048                 printk("NFSD: nfsd4_lock: permission denied!\n");
2049                 goto out;
2050         }
2051
2052         switch (lock->lk_type) {
2053                 case NFS4_READ_LT:
2054                 case NFS4_READW_LT:
2055                         file_lock.fl_type = F_RDLCK;
2056                 break;
2057                 case NFS4_WRITE_LT:
2058                 case NFS4_WRITEW_LT:
2059                         file_lock.fl_type = F_WRLCK;
2060                 break;
2061                 default:
2062                         status = nfserr_inval;
2063                 goto out;
2064         }
2065         file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
2066         file_lock.fl_pid = lockownerid_hashval(lock->lk_stateowner->so_id);
2067         file_lock.fl_file = filp;
2068         file_lock.fl_flags = FL_POSIX;
2069         file_lock.fl_notify = NULL;
2070         file_lock.fl_insert = NULL;
2071         file_lock.fl_remove = NULL;
2072
2073         file_lock.fl_start = lock->lk_offset;
2074         if ((lock->lk_length == ~(u64)0) || 
2075                         LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
2076                 file_lock.fl_end = ~(u64)0;
2077         else
2078                 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
2079         nfs4_transform_lock_offset(&file_lock);
2080
2081         /*
2082         * Try to lock the file in the VFS.
2083         * Note: locks.c uses the BKL to protect the inode's lock list.
2084         */
2085
2086         status = posix_lock_file(filp, &file_lock);
2087         dprintk("NFSD: nfsd4_lock: posix_test_lock passed. posix_lock_file status %d\n",status);
2088         switch (-status) {
2089         case 0: /* success! */
2090                 update_stateid(&lock_stp->st_stateid);
2091                 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 
2092                                 sizeof(stateid_t));
2093                 goto out;
2094         case (EAGAIN):
2095                 goto conflicting_lock;
2096         case (EDEADLK):
2097                 status = nfserr_deadlock;
2098         default:        
2099                 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
2100                 goto out_destroy_new_stateid;
2101         }
2102
2103 conflicting_lock:
2104         dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2105         status = nfserr_denied;
2106         /* XXX There is a race here. Future patch needed to provide 
2107          * an atomic posix_lock_and_test_file
2108          */
2109         if (!(conflock = posix_test_lock(filp, &file_lock))) {
2110                 status = nfserr_serverfault;
2111                 goto out;
2112         }
2113         nfs4_set_lock_denied(conflock, &lock->lk_denied);
2114
2115 out_destroy_new_stateid:
2116         if (lock->lk_is_new) {
2117                 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2118         /*
2119         * An error encountered after instantiation of the new
2120         * stateid has forced us to destroy it.
2121         */
2122                 if (!seqid_mutating_err(status))
2123                         open_sop->so_seqid--;
2124
2125                 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
2126         }
2127 out:
2128         return status;
2129 }
2130
2131 /*
2132  * LOCKT operation
2133  */
2134 int
2135 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2136 {
2137         struct inode *inode;
2138         struct nfs4_stateowner *sop;
2139         struct file file;
2140         struct file_lock file_lock;
2141         struct file_lock *conflicting_lock;
2142         unsigned int strhashval;
2143         int status;
2144
2145         if (nfs4_in_grace())
2146                 return nfserr_grace;
2147
2148         if (check_lock_length(lockt->lt_offset, lockt->lt_length))
2149                  return nfserr_inval;
2150
2151         lockt->lt_stateowner = NULL;
2152         nfs4_lock_state();
2153
2154         status = nfserr_stale_clientid;
2155         if (STALE_CLIENTID(&lockt->lt_clientid)) {
2156                 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2157                 goto out;
2158         }
2159
2160         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2161                 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2162                 if (status == nfserr_symlink)
2163                         status = nfserr_inval;
2164                 goto out;
2165         }
2166
2167         inode = current_fh->fh_dentry->d_inode;
2168         switch (lockt->lt_type) {
2169                 case NFS4_READ_LT:
2170                 case NFS4_READW_LT:
2171                         file_lock.fl_type = F_RDLCK;
2172                 break;
2173                 case NFS4_WRITE_LT:
2174                 case NFS4_WRITEW_LT:
2175                         file_lock.fl_type = F_WRLCK;
2176                 break;
2177                 default:
2178                         printk("NFSD: nfs4_lockt: bad lock type!\n");
2179                         status = nfserr_inval;
2180                 goto out;
2181         }
2182
2183         strhashval = lock_ownerstr_hashval(inode, 
2184                         lockt->lt_clientid.cl_id, lockt->lt_owner);
2185
2186         find_lockstateowner_str(strhashval, &lockt->lt_owner,
2187                                         &lockt->lt_clientid, 
2188                                         &lockt->lt_stateowner);
2189         sop = lockt->lt_stateowner;
2190         if (sop) {
2191                 file_lock.fl_owner = (fl_owner_t) sop;
2192                 file_lock.fl_pid = lockownerid_hashval(sop->so_id);
2193         } else {
2194                 file_lock.fl_owner = NULL;
2195                 file_lock.fl_pid = 0;
2196         }
2197         file_lock.fl_flags = FL_POSIX;
2198
2199         file_lock.fl_start = lockt->lt_offset;
2200         if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2201                 file_lock.fl_end = ~(u64)0;
2202         else
2203                 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2204
2205         nfs4_transform_lock_offset(&file_lock);
2206
2207         /* posix_test_lock uses the struct file _only_ to resolve the inode.
2208          * since LOCKT doesn't require an OPEN, and therefore a struct
2209          * file may not exist, pass posix_test_lock a struct file with
2210          * only the dentry:inode set.
2211          */
2212         memset(&file, 0, sizeof (struct file));
2213         file.f_dentry = current_fh->fh_dentry;
2214
2215         status = nfs_ok;
2216         conflicting_lock = posix_test_lock(&file, &file_lock);
2217         if (conflicting_lock) {
2218                 status = nfserr_denied;
2219                 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2220         }
2221 out:
2222         nfs4_unlock_state();
2223         return status;
2224 }
2225
2226 int
2227 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2228 {
2229         struct nfs4_stateid *stp;
2230         struct file *filp = NULL;
2231         struct file_lock file_lock;
2232         int status;
2233                                                         
2234         dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2235                 (long long) locku->lu_offset,
2236                 (long long) locku->lu_length);
2237
2238         if (check_lock_length(locku->lu_offset, locku->lu_length))
2239                  return nfserr_inval;
2240
2241         locku->lu_stateowner = NULL;
2242         nfs4_lock_state();
2243                                                                                 
2244         if ((status = nfs4_preprocess_seqid_op(current_fh, 
2245                                         locku->lu_seqid, 
2246                                         &locku->lu_stateid, 
2247                                         CHECK_FH | LOCK_STATE, 
2248                                         &locku->lu_stateowner, &stp, NULL)))
2249                 goto out;
2250
2251         filp = &stp->st_vfs_file;
2252         BUG_ON(!filp);
2253         file_lock.fl_type = F_UNLCK;
2254         file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2255         file_lock.fl_pid = lockownerid_hashval(locku->lu_stateowner->so_id);
2256         file_lock.fl_file = filp;
2257         file_lock.fl_flags = FL_POSIX; 
2258         file_lock.fl_notify = NULL;
2259         file_lock.fl_insert = NULL;
2260         file_lock.fl_remove = NULL;
2261         file_lock.fl_start = locku->lu_offset;
2262
2263         if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2264                 file_lock.fl_end = ~(u64)0;
2265         else
2266                 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2267         nfs4_transform_lock_offset(&file_lock);
2268
2269         /*
2270         *  Try to unlock the file in the VFS.
2271         */
2272         status = posix_lock_file(filp, &file_lock); 
2273         if (status) {
2274                 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2275                 goto out_nfserr;
2276         }
2277         /*
2278         * OK, unlock succeeded; the only thing left to do is update the stateid.
2279         */
2280         update_stateid(&stp->st_stateid);
2281         memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2282
2283 out:
2284         return status;
2285
2286 out_nfserr:
2287         status = nfserrno(status);
2288         goto out;
2289 }
2290
2291 /*
2292  * returns
2293  *      1: locks held by lockowner
2294  *      0: no locks held by lockowner
2295  */
2296 static int
2297 check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
2298 {
2299         struct file_lock **flpp;
2300         struct inode *inode = filp->f_dentry->d_inode;
2301         int status = 0;
2302
2303         lock_kernel();
2304         for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
2305                 if ((*flpp)->fl_owner == (fl_owner_t)lowner)
2306                         status = 1;
2307                         goto out;
2308         }
2309 out:
2310         unlock_kernel();
2311         return status;
2312 }
2313
2314 int
2315 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2316 {
2317         clientid_t *clid = &rlockowner->rl_clientid;
2318         struct nfs4_stateowner *local = NULL;
2319         struct xdr_netobj *owner = &rlockowner->rl_owner;
2320         int status, i;
2321
2322         dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2323                 clid->cl_boot, clid->cl_id);
2324
2325         /* XXX check for lease expiration */
2326
2327         status = nfserr_stale_clientid;
2328         if (STALE_CLIENTID(clid)) {
2329                 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2330                 return status;
2331         }
2332
2333         nfs4_lock_state();
2334
2335         /* find the lockowner */
2336         status = nfs_ok;
2337         for (i=0; i < LOCK_HASH_SIZE; i++) {
2338                 list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) {
2339                         if(cmp_owner_str(local, owner, clid))
2340                                 break;
2341                 }
2342         }
2343         if (local) {
2344                 struct nfs4_stateid *stp;
2345
2346                 /* check for any locks held by any stateid associated with the
2347                  * (lock) stateowner */
2348                 status = nfserr_locks_held;
2349                 list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) {
2350                         if(stp->st_vfs_set) {
2351                                 if (check_for_locks(&stp->st_vfs_file, local))
2352                                         goto out;
2353                         }
2354                 }
2355                 /* no locks held by (lock) stateowner */
2356                 status = nfs_ok;
2357                 release_stateowner(local);
2358         }
2359 out:
2360         nfs4_unlock_state();
2361         return status;
2362 }
2363
2364 /* 
2365  * Start and stop routines
2366  */
2367
2368 void 
2369 nfs4_state_init(void)
2370 {
2371         int i;
2372         time_t start = get_seconds();
2373
2374         if (nfs4_init)
2375                 return;
2376         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2377                 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
2378                 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
2379                 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
2380                 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
2381         }
2382         for (i = 0; i < FILE_HASH_SIZE; i++) {
2383                 INIT_LIST_HEAD(&file_hashtbl[i]);
2384         }
2385         for (i = 0; i < OWNER_HASH_SIZE; i++) {
2386                 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
2387                 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
2388         }
2389         for (i = 0; i < STATEID_HASH_SIZE; i++) {
2390                 INIT_LIST_HEAD(&stateid_hashtbl[i]);
2391                 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
2392         }
2393         for (i = 0; i < LOCK_HASH_SIZE; i++) {
2394                 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
2395                 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
2396         }
2397         memset(&zerostateid, 0, sizeof(stateid_t));
2398         memset(&onestateid, ~0, sizeof(stateid_t));
2399
2400         INIT_LIST_HEAD(&close_lru);
2401         INIT_LIST_HEAD(&client_lru);
2402         init_MUTEX(&client_sema);
2403         boot_time = start;
2404         grace_end = start + NFSD_LEASE_TIME;
2405         INIT_WORK(&laundromat_work,laundromat_main, NULL);
2406         schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
2407         nfs4_init = 1;
2408
2409 }
2410
2411 int
2412 nfs4_in_grace(void)
2413 {
2414         return time_before(get_seconds(), (unsigned long)grace_end);
2415 }
2416
2417 int
2418 nfs4_in_no_grace(void)
2419 {
2420         return (grace_end < get_seconds());
2421 }
2422
2423
2424 static void
2425 __nfs4_state_shutdown(void)
2426 {
2427         int i;
2428         struct nfs4_client *clp = NULL;
2429
2430         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
2431                 while (!list_empty(&conf_id_hashtbl[i])) {
2432                         clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
2433                         expire_client(clp);
2434                 }
2435                 while (!list_empty(&unconf_str_hashtbl[i])) {
2436                         clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
2437                         expire_client(clp);
2438                 }
2439         }
2440         release_all_files();
2441         cancel_delayed_work(&laundromat_work);
2442         flush_scheduled_work();
2443         nfs4_init = 0;
2444         dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
2445                         list_add_perfile, list_del_perfile);
2446         dprintk("NFSD: add_perclient %d del_perclient %d\n",
2447                         add_perclient, del_perclient);
2448         dprintk("NFSD: alloc_file %d free_file %d\n",
2449                         alloc_file, free_file);
2450         dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
2451                         alloc_sowner, alloc_lsowner, free_sowner);
2452         dprintk("NFSD: vfsopen %d vfsclose %d\n",
2453                         vfsopen, vfsclose);
2454 }
2455
2456 void
2457 nfs4_state_shutdown(void)
2458 {
2459         nfs4_lock_state();
2460         __nfs4_state_shutdown();
2461         nfs4_unlock_state();
2462 }