vserver 1.9.5.x5
[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/kthread.h>
48 #include <linux/nfs4.h>
49 #include <linux/nfsd/state.h>
50 #include <linux/nfsd/xdr4.h>
51
52 #define NFSDDBG_FACILITY                NFSDDBG_PROC
53
54 /* Globals */
55 static time_t lease_time = 90;     /* default lease time */
56 static time_t old_lease_time = 90; /* past incarnation lease time */
57 static u32 nfs4_reclaim_init = 0;
58 time_t boot_time;
59 static time_t grace_end = 0;
60 static u32 current_clientid = 1;
61 static u32 current_ownerid = 1;
62 static u32 current_fileid = 1;
63 static u32 current_delegid = 1;
64 static u32 nfs4_init;
65 stateid_t zerostateid;             /* bits all 0 */
66 stateid_t onestateid;              /* bits all 1 */
67
68 /* debug counters */
69 u32 list_add_perfile = 0; 
70 u32 list_del_perfile = 0;
71 u32 add_perclient = 0;
72 u32 del_perclient = 0;
73 u32 alloc_file = 0;
74 u32 free_file = 0;
75 u32 alloc_sowner = 0;
76 u32 free_sowner = 0;
77 u32 vfsopen = 0;
78 u32 vfsclose = 0;
79 u32 alloc_lsowner= 0;
80 u32 alloc_delegation= 0;
81 u32 free_delegation= 0;
82
83 /* forward declarations */
84 struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
85 static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
86 static void release_delegation(struct nfs4_delegation *dp);
87 static void release_stateid_lockowner(struct nfs4_stateid *open_stp);
88
89 /* Locking:
90  *
91  * client_sema: 
92  *      protects clientid_hashtbl[], clientstr_hashtbl[],
93  *      unconfstr_hashtbl[], uncofid_hashtbl[].
94  */
95 static DECLARE_MUTEX(client_sema);
96
97 void
98 nfs4_lock_state(void)
99 {
100         down(&client_sema);
101 }
102
103 void
104 nfs4_unlock_state(void)
105 {
106         up(&client_sema);
107 }
108
109 static inline u32
110 opaque_hashval(const void *ptr, int nbytes)
111 {
112         unsigned char *cptr = (unsigned char *) ptr;
113
114         u32 x = 0;
115         while (nbytes--) {
116                 x *= 37;
117                 x += *cptr++;
118         }
119         return x;
120 }
121
122 /* forward declarations */
123 static void release_stateowner(struct nfs4_stateowner *sop);
124 static void release_stateid(struct nfs4_stateid *stp, int flags);
125 static void release_file(struct nfs4_file *fp);
126
127 /*
128  * Delegation state
129  */
130
131 /* recall_lock protects the del_recall_lru */
132 spinlock_t recall_lock;
133 static struct list_head del_recall_lru;
134
135 static struct nfs4_delegation *
136 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_file *fp, struct svc_fh *current_fh, u32 type)
137 {
138         struct nfs4_delegation *dp;
139
140         dprintk("NFSD alloc_init_deleg\n");
141         if ((dp = kmalloc(sizeof(struct nfs4_delegation),
142                 GFP_KERNEL)) == NULL)
143                 return dp;
144         INIT_LIST_HEAD(&dp->dl_del_perfile);
145         INIT_LIST_HEAD(&dp->dl_del_perclnt);
146         INIT_LIST_HEAD(&dp->dl_recall_lru);
147         dp->dl_client = clp;
148         dp->dl_file = fp;
149         dp->dl_flock = NULL;
150         dp->dl_stp = NULL;
151         dp->dl_type = type;
152         dp->dl_recall.cbr_dp = NULL;
153         dp->dl_recall.cbr_ident = 0;
154         dp->dl_recall.cbr_trunc = 0;
155         dp->dl_stateid.si_boot = boot_time;
156         dp->dl_stateid.si_stateownerid = current_delegid++;
157         dp->dl_stateid.si_fileid = 0;
158         dp->dl_stateid.si_generation = 0;
159         dp->dl_fhlen = current_fh->fh_handle.fh_size;
160         memcpy(dp->dl_fhval, &current_fh->fh_handle.fh_base,
161                         current_fh->fh_handle.fh_size);
162         dp->dl_time = 0;
163         atomic_set(&dp->dl_state, NFS4_NO_RECALL);
164         atomic_set(&dp->dl_count, 1);
165         atomic_set(&dp->dl_recall_cnt, 0);
166         list_add(&dp->dl_del_perfile, &fp->fi_del_perfile);
167         list_add(&dp->dl_del_perclnt, &clp->cl_del_perclnt);
168         alloc_delegation++;
169         return dp;
170 }
171
172 /*
173  * Free the delegation structure.
174  * Called with the recall_lock held.
175  */
176 static void
177 nfs4_free_delegation(struct nfs4_delegation *dp)
178 {
179         dprintk("NFSD: nfs4_free_delegation freeing dp %p\n",dp);
180         list_del(&dp->dl_recall_lru);
181         kfree(dp);
182         free_delegation++;
183 }
184
185 /* release_delegation:
186  *
187  * Remove the associated file_lock first, then remove the delegation.
188  * lease_modify() is called to remove the FS_LEASE file_lock from
189  * the i_flock list, eventually calling nfsd's lock_manager
190  * fl_release_callback.
191  *
192  * call either:
193  *   nfsd_close : if last close, locks_remove_flock calls lease_modify.
194  *                otherwise, recalled state set to NFS4_RECALL_COMPLETE
195  *                so that it will be reaped by the laundromat service.
196  * or
197  *   remove_lease (calls time_out_lease which calls lease_modify).
198  *   and nfs4_free_delegation.
199  *
200  * Called with nfs_lock_state() held.
201  * Called with the recall_lock held.
202  */
203
204 static void
205 release_delegation(struct nfs4_delegation *dp)
206 {
207         /* delayed nfsd_close */
208         if (dp->dl_stp) {
209                 struct file *filp = dp->dl_stp->st_vfs_file;
210
211                 dprintk("NFSD: release_delegation CLOSE\n");
212                 release_stateid_lockowner(dp->dl_stp);
213                 kfree(dp->dl_stp);
214                 dp->dl_stp = NULL;
215                 atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
216                 nfsd_close(filp);
217                 vfsclose++;
218         } else {
219                 dprintk("NFSD: release_delegation remove lease dl_flock %p\n",
220                         dp->dl_flock);
221                 remove_lease(dp->dl_flock);
222                 list_del_init(&dp->dl_del_perfile);
223                 list_del_init(&dp->dl_del_perclnt);
224                 /* dl_count > 0 => outstanding recall rpc */
225                 dprintk("NFSD: release_delegation free deleg dl_count %d\n",
226                                    atomic_read(&dp->dl_count));
227                 if ((atomic_read(&dp->dl_state) == NFS4_REAP_DELEG)
228                      || atomic_dec_and_test(&dp->dl_count))
229                         nfs4_free_delegation(dp);
230         }
231 }
232
233 /* 
234  * SETCLIENTID state 
235  */
236
237 /* Hash tables for nfs4_clientid state */
238 #define CLIENT_HASH_BITS                 4
239 #define CLIENT_HASH_SIZE                (1 << CLIENT_HASH_BITS)
240 #define CLIENT_HASH_MASK                (CLIENT_HASH_SIZE - 1)
241
242 #define clientid_hashval(id) \
243         ((id) & CLIENT_HASH_MASK)
244 #define clientstr_hashval(name, namelen) \
245         (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
246 /*
247  * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
248  * used in reboot/reset lease grace period processing
249  *
250  * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
251  * setclientid_confirmed info. 
252  *
253  * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 
254  * setclientid info.
255  *
256  * client_lru holds client queue ordered by nfs4_client.cl_time
257  * for lease renewal.
258  *
259  * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
260  * for last close replay.
261  */
262 static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
263 static int reclaim_str_hashtbl_size;
264 static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
265 static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
266 static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
267 static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
268 static struct list_head client_lru;
269 static struct list_head close_lru;
270
271 static inline void
272 renew_client(struct nfs4_client *clp)
273 {
274         /*
275         * Move client to the end to the LRU list.
276         */
277         dprintk("renewing client (clientid %08x/%08x)\n", 
278                         clp->cl_clientid.cl_boot, 
279                         clp->cl_clientid.cl_id);
280         list_move_tail(&clp->cl_lru, &client_lru);
281         clp->cl_time = get_seconds();
282 }
283
284 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
285 static int
286 STALE_CLIENTID(clientid_t *clid)
287 {
288         if (clid->cl_boot == boot_time)
289                 return 0;
290         dprintk("NFSD stale clientid (%08x/%08x)\n", 
291                         clid->cl_boot, clid->cl_id);
292         return 1;
293 }
294
295 /* 
296  * XXX Should we use a slab cache ?
297  * This type of memory management is somewhat inefficient, but we use it
298  * anyway since SETCLIENTID is not a common operation.
299  */
300 static inline struct nfs4_client *
301 alloc_client(struct xdr_netobj name)
302 {
303         struct nfs4_client *clp;
304
305         if ((clp = kmalloc(sizeof(struct nfs4_client), GFP_KERNEL))!= NULL) {
306                 memset(clp, 0, sizeof(*clp));
307                 if ((clp->cl_name.data = kmalloc(name.len, GFP_KERNEL)) != NULL) {
308                         memcpy(clp->cl_name.data, name.data, name.len);
309                         clp->cl_name.len = name.len;
310                 }
311                 else {
312                         kfree(clp);
313                         clp = NULL;
314                 }
315         }
316         return clp;
317 }
318
319 static inline void
320 free_client(struct nfs4_client *clp)
321 {
322         if (clp->cl_cred.cr_group_info)
323                 put_group_info(clp->cl_cred.cr_group_info);
324         kfree(clp->cl_name.data);
325         kfree(clp);
326 }
327
328 void
329 put_nfs4_client(struct nfs4_client *clp)
330 {
331         if (atomic_dec_and_test(&clp->cl_count))
332                 free_client(clp);
333 }
334
335 static void
336 expire_client(struct nfs4_client *clp)
337 {
338         struct nfs4_stateowner *sop;
339         struct nfs4_delegation *dp;
340         struct nfs4_callback *cb = &clp->cl_callback;
341         struct rpc_clnt *clnt = clp->cl_callback.cb_client;
342
343         dprintk("NFSD: expire_client cl_count %d\n",
344                             atomic_read(&clp->cl_count));
345
346         /* shutdown rpc client, ending any outstanding recall rpcs */
347         if (atomic_read(&cb->cb_set) == 1 && clnt) {
348                 rpc_shutdown_client(clnt);
349                 clnt = clp->cl_callback.cb_client = NULL;
350         }
351         spin_lock(&recall_lock);
352         while (!list_empty(&clp->cl_del_perclnt)) {
353                 dp = list_entry(clp->cl_del_perclnt.next, struct nfs4_delegation, dl_del_perclnt);
354                 dprintk("NFSD: expire client. dp %p, dl_state %d, fp %p\n",
355                                 dp, atomic_read(&dp->dl_state), dp->dl_flock);
356
357                 /* force release of delegation. */
358                 atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
359                 release_delegation(dp);
360         }
361         spin_unlock(&recall_lock);
362         list_del(&clp->cl_idhash);
363         list_del(&clp->cl_strhash);
364         list_del(&clp->cl_lru);
365         while (!list_empty(&clp->cl_perclient)) {
366                 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
367                 release_stateowner(sop);
368         }
369         put_nfs4_client(clp);
370 }
371
372 static struct nfs4_client *
373 create_client(struct xdr_netobj name) {
374         struct nfs4_client *clp;
375
376         if (!(clp = alloc_client(name)))
377                 goto out;
378         atomic_set(&clp->cl_count, 1);
379         atomic_set(&clp->cl_callback.cb_set, 0);
380         clp->cl_callback.cb_parsed = 0;
381         INIT_LIST_HEAD(&clp->cl_idhash);
382         INIT_LIST_HEAD(&clp->cl_strhash);
383         INIT_LIST_HEAD(&clp->cl_perclient);
384         INIT_LIST_HEAD(&clp->cl_del_perclnt);
385         INIT_LIST_HEAD(&clp->cl_lru);
386 out:
387         return clp;
388 }
389
390 static void
391 copy_verf(struct nfs4_client *target, nfs4_verifier *source) {
392         memcpy(target->cl_verifier.data, source->data, sizeof(target->cl_verifier.data));
393 }
394
395 static void
396 copy_clid(struct nfs4_client *target, struct nfs4_client *source) {
397         target->cl_clientid.cl_boot = source->cl_clientid.cl_boot; 
398         target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
399 }
400
401 static void
402 copy_cred(struct svc_cred *target, struct svc_cred *source) {
403
404         target->cr_uid = source->cr_uid;
405         target->cr_gid = source->cr_gid;
406         target->cr_group_info = source->cr_group_info;
407         get_group_info(target->cr_group_info);
408 }
409
410 static int
411 cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
412         if (!n1 || !n2)
413                 return 0;
414         return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
415 }
416
417 static int
418 cmp_verf(nfs4_verifier *v1, nfs4_verifier *v2) {
419         return(!memcmp(v1->data,v2->data,sizeof(v1->data)));
420 }
421
422 static int
423 cmp_clid(clientid_t * cl1, clientid_t * cl2) {
424         return((cl1->cl_boot == cl2->cl_boot) &&
425                 (cl1->cl_id == cl2->cl_id));
426 }
427
428 /* XXX what about NGROUP */
429 static int
430 cmp_creds(struct svc_cred *cr1, struct svc_cred *cr2){
431         return(cr1->cr_uid == cr2->cr_uid);
432
433 }
434
435 static void
436 gen_clid(struct nfs4_client *clp) {
437         clp->cl_clientid.cl_boot = boot_time;
438         clp->cl_clientid.cl_id = current_clientid++; 
439 }
440
441 static void
442 gen_confirm(struct nfs4_client *clp) {
443         struct timespec         tv;
444         u32 *                   p;
445
446         tv = CURRENT_TIME;
447         p = (u32 *)clp->cl_confirm.data;
448         *p++ = tv.tv_sec;
449         *p++ = tv.tv_nsec;
450 }
451
452 static int
453 check_name(struct xdr_netobj name) {
454
455         if (name.len == 0) 
456                 return 0;
457         if (name.len > NFS4_OPAQUE_LIMIT) {
458                 printk("NFSD: check_name: name too long(%d)!\n", name.len);
459                 return 0;
460         }
461         return 1;
462 }
463
464 void
465 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
466 {
467         unsigned int idhashval;
468
469         list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
470         idhashval = clientid_hashval(clp->cl_clientid.cl_id);
471         list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
472         list_add_tail(&clp->cl_lru, &client_lru);
473         clp->cl_time = get_seconds();
474 }
475
476 void
477 move_to_confirmed(struct nfs4_client *clp, unsigned int idhashval)
478 {
479         unsigned int strhashval;
480
481         dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
482         list_del_init(&clp->cl_strhash);
483         list_del_init(&clp->cl_idhash);
484         list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
485         strhashval = clientstr_hashval(clp->cl_name.data, 
486                         clp->cl_name.len);
487         list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
488         renew_client(clp);
489 }
490
491
492 /* a helper function for parse_callback */
493 static int
494 parse_octet(unsigned int *lenp, char **addrp)
495 {
496         unsigned int len = *lenp;
497         char *p = *addrp;
498         int n = -1;
499         char c;
500
501         for (;;) {
502                 if (!len)
503                         break;
504                 len--;
505                 c = *p++;
506                 if (c == '.')
507                         break;
508                 if ((c < '0') || (c > '9')) {
509                         n = -1;
510                         break;
511                 }
512                 if (n < 0)
513                         n = 0;
514                 n = (n * 10) + (c - '0');
515                 if (n > 255) {
516                         n = -1;
517                         break;
518                 }
519         }
520         *lenp = len;
521         *addrp = p;
522         return n;
523 }
524
525 /* parse and set the setclientid ipv4 callback address */
526 int
527 parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
528 {
529         int temp = 0;
530         u32 cbaddr = 0;
531         u16 cbport = 0;
532         u32 addrlen = addr_len;
533         char *addr = addr_val;
534         int i, shift;
535
536         /* ipaddress */
537         shift = 24;
538         for(i = 4; i > 0  ; i--) {
539                 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
540                         return 0;
541                 }
542                 cbaddr |= (temp << shift);
543                 if (shift > 0)
544                 shift -= 8;
545         }
546         *cbaddrp = cbaddr;
547
548         /* port */
549         shift = 8;
550         for(i = 2; i > 0  ; i--) {
551                 if ((temp = parse_octet(&addrlen, &addr)) < 0) {
552                         return 0;
553                 }
554                 cbport |= (temp << shift);
555                 if (shift > 0)
556                         shift -= 8;
557         }
558         *cbportp = cbport;
559         return 1;
560 }
561
562 void
563 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
564 {
565         struct nfs4_callback *cb = &clp->cl_callback;
566
567         /* Currently, we only support tcp for the callback channel */
568         if ((se->se_callback_netid_len != 3) || memcmp((char *)se->se_callback_netid_val, "tcp", 3))
569                 goto out_err;
570
571         if ( !(parse_ipv4(se->se_callback_addr_len, se->se_callback_addr_val,
572                          &cb->cb_addr, &cb->cb_port)))
573                 goto out_err;
574         cb->cb_prog = se->se_callback_prog;
575         cb->cb_ident = se->se_callback_ident;
576         cb->cb_parsed = 1;
577         return;
578 out_err:
579         printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
580                 "will not receive delegations\n",
581                 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
582
583         cb->cb_parsed = 0;
584         return;
585 }
586
587 /*
588  * RFC 3010 has a complex implmentation description of processing a 
589  * SETCLIENTID request consisting of 5 bullets, labeled as 
590  * CASE0 - CASE4 below.
591  *
592  * NOTES:
593  *      callback information will be processed in a future patch
594  *
595  *      an unconfirmed record is added when:
596  *      NORMAL (part of CASE 4): there is no confirmed nor unconfirmed record.
597  *      CASE 1: confirmed record found with matching name, principal,
598  *              verifier, and clientid.
599  *      CASE 2: confirmed record found with matching name, principal,
600  *              and there is no unconfirmed record with matching
601  *              name and principal
602  *
603  *      an unconfirmed record is replaced when:
604  *      CASE 3: confirmed record found with matching name, principal,
605  *              and an unconfirmed record is found with matching 
606  *              name, principal, and with clientid and
607  *              confirm that does not match the confirmed record.
608  *      CASE 4: there is no confirmed record with matching name and 
609  *              principal. there is an unconfirmed record with 
610  *              matching name, principal.
611  *
612  *      an unconfirmed record is deleted when:
613  *      CASE 1: an unconfirmed record that matches input name, verifier,
614  *              and confirmed clientid.
615  *      CASE 4: any unconfirmed records with matching name and principal
616  *              that exist after an unconfirmed record has been replaced
617  *              as described above.
618  *
619  */
620 int
621 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
622 {
623         u32                     ip_addr = rqstp->rq_addr.sin_addr.s_addr;
624         struct xdr_netobj       clname = { 
625                 .len = setclid->se_namelen,
626                 .data = setclid->se_name,
627         };
628         nfs4_verifier           clverifier = setclid->se_verf;
629         unsigned int            strhashval;
630         struct nfs4_client *    conf, * unconf, * new, * clp;
631         int                     status;
632         
633         status = nfserr_inval;
634         if (!check_name(clname))
635                 goto out;
636
637         /* 
638          * XXX The Duplicate Request Cache (DRC) has been checked (??)
639          * We get here on a DRC miss.
640          */
641
642         strhashval = clientstr_hashval(clname.data, clname.len);
643
644         conf = NULL;
645         nfs4_lock_state();
646         list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
647                 if (!cmp_name(&clp->cl_name, &clname))
648                         continue;
649                 /* 
650                  * CASE 0:
651                  * clname match, confirmed, different principal
652                  * or different ip_address
653                  */
654                 status = nfserr_clid_inuse;
655                 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
656                         printk("NFSD: setclientid: string in use by client"
657                         "(clientid %08x/%08x)\n",
658                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
659                         goto out;
660                 }
661                 if (clp->cl_addr != ip_addr) { 
662                         printk("NFSD: setclientid: string in use by client"
663                         "(clientid %08x/%08x)\n",
664                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
665                         goto out;
666                 }
667
668                 /* 
669                  * cl_name match from a previous SETCLIENTID operation
670                  * XXX check for additional matches?
671                  */
672                 conf = clp;
673                 break;
674         }
675         unconf = NULL;
676         list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
677                 if (!cmp_name(&clp->cl_name, &clname))
678                         continue;
679                 /* cl_name match from a previous SETCLIENTID operation */
680                 unconf = clp;
681                 break;
682         }
683         status = nfserr_resource;
684         if (!conf) {
685                 /* 
686                  * CASE 4:
687                  * placed first, because it is the normal case.
688                  */
689                 if (unconf)
690                         expire_client(unconf);
691                 if (!(new = create_client(clname)))
692                         goto out;
693                 copy_verf(new, &clverifier);
694                 new->cl_addr = ip_addr;
695                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
696                 gen_clid(new);
697                 gen_confirm(new);
698                 gen_callback(new, setclid);
699                 add_to_unconfirmed(new, strhashval);
700         } else if (cmp_verf(&conf->cl_verifier, &clverifier)) {
701                 /*
702                  * CASE 1:
703                  * cl_name match, confirmed, principal match
704                  * verifier match: probable callback update
705                  *
706                  * remove any unconfirmed nfs4_client with 
707                  * matching cl_name, cl_verifier, and cl_clientid
708                  *
709                  * create and insert an unconfirmed nfs4_client with same 
710                  * cl_name, cl_verifier, and cl_clientid as existing 
711                  * nfs4_client,  but with the new callback info and a 
712                  * new cl_confirm
713                  */
714                 if ((unconf) && 
715                     cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
716                      cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
717                                 expire_client(unconf);
718                 }
719                 if (!(new = create_client(clname)))
720                         goto out;
721                 copy_verf(new,&conf->cl_verifier);
722                 new->cl_addr = ip_addr;
723                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
724                 copy_clid(new, conf);
725                 gen_confirm(new);
726                 gen_callback(new, setclid);
727                 add_to_unconfirmed(new,strhashval);
728         } else if (!unconf) {
729                 /*
730                  * CASE 2:
731                  * clname match, confirmed, principal match
732                  * verfier does not match
733                  * no unconfirmed. create a new unconfirmed nfs4_client
734                  * using input clverifier, clname, and callback info
735                  * and generate a new cl_clientid and cl_confirm.
736                  */
737                 if (!(new = create_client(clname)))
738                         goto out;
739                 copy_verf(new,&clverifier);
740                 new->cl_addr = ip_addr;
741                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
742                 gen_clid(new);
743                 gen_confirm(new);
744                 gen_callback(new, setclid);
745                 add_to_unconfirmed(new, strhashval);
746         } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
747                 /*      
748                  * CASE3:
749                  * confirmed found (name, principal match)
750                  * confirmed verifier does not match input clverifier
751                  *
752                  * unconfirmed found (name match)
753                  * confirmed->cl_confirm != unconfirmed->cl_confirm
754                  *
755                  * remove unconfirmed.
756                  *
757                  * create an unconfirmed nfs4_client 
758                  * with same cl_name as existing confirmed nfs4_client, 
759                  * but with new callback info, new cl_clientid,
760                  * new cl_verifier and a new cl_confirm
761                  */
762                 expire_client(unconf);
763                 if (!(new = create_client(clname)))
764                         goto out;
765                 copy_verf(new,&clverifier);
766                 new->cl_addr = ip_addr;
767                 copy_cred(&new->cl_cred,&rqstp->rq_cred);
768                 gen_clid(new);
769                 gen_confirm(new);
770                 gen_callback(new, setclid);
771                 add_to_unconfirmed(new, strhashval);
772         } else {
773                 /* No cases hit !!! */
774                 status = nfserr_inval;
775                 goto out;
776
777         }
778         setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
779         setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
780         memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
781         status = nfs_ok;
782 out:
783         nfs4_unlock_state();
784         return status;
785 }
786
787
788 /*
789  * RFC 3010 has a complex implmentation description of processing a 
790  * SETCLIENTID_CONFIRM request consisting of 4 bullets describing
791  * processing on a DRC miss, labeled as CASE1 - CASE4 below.
792  *
793  * NOTE: callback information will be processed here in a future patch
794  */
795 int
796 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
797 {
798         u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
799         unsigned int idhashval;
800         struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
801         nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
802         clientid_t * clid = &setclientid_confirm->sc_clientid;
803         int status;
804
805         if (STALE_CLIENTID(clid))
806                 return nfserr_stale_clientid;
807         /* 
808          * XXX The Duplicate Request Cache (DRC) has been checked (??)
809          * We get here on a DRC miss.
810          */
811
812         idhashval = clientid_hashval(clid->cl_id);
813         nfs4_lock_state();
814         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
815                 if (!cmp_clid(&clp->cl_clientid, clid))
816                         continue;
817
818                 status = nfserr_inval;
819                 /* 
820                  * Found a record for this clientid. If the IP addresses
821                  * don't match, return ERR_INVAL just as if the record had
822                  * not been found.
823                  */
824                 if (clp->cl_addr != ip_addr) { 
825                         printk("NFSD: setclientid: string in use by client"
826                         "(clientid %08x/%08x)\n",
827                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
828                         goto out;
829                 }
830                 conf = clp;
831                 break;
832         }
833         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
834                 if (!cmp_clid(&clp->cl_clientid, clid))
835                         continue;
836                 status = nfserr_inval;
837                 if (clp->cl_addr != ip_addr) { 
838                         printk("NFSD: setclientid: string in use by client"
839                         "(clientid %08x/%08x)\n",
840                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
841                         goto out;
842                 }
843                 unconf = clp;
844                 break;
845         }
846         /* CASE 1: 
847         * unconf record that matches input clientid and input confirm.
848         * conf record that matches input clientid.
849         * conf  and unconf records match names, verifiers 
850         */
851         if ((conf && unconf) && 
852             (cmp_verf(&unconf->cl_confirm, &confirm)) &&
853             (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
854             (cmp_name(&conf->cl_name,&unconf->cl_name))  &&
855             (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
856                 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 
857                         status = nfserr_clid_inuse;
858                 else {
859                         expire_client(conf);
860                         clp = unconf;
861                         move_to_confirmed(unconf, idhashval);
862                         status = nfs_ok;
863                 }
864                 goto out;
865         } 
866         /* CASE 2:
867          * conf record that matches input clientid.
868          * if unconf record that matches input clientid, then unconf->cl_name
869          * or unconf->cl_verifier don't match the conf record.
870          */
871         if ((conf && !unconf) || 
872             ((conf && unconf) && 
873              (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
874               !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
875                 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
876                         status = nfserr_clid_inuse;
877                 } else {
878                         clp = conf;
879                         status = nfs_ok;
880                 }
881                 goto out;
882         }
883         /* CASE 3:
884          * conf record not found.
885          * unconf record found. 
886          * unconf->cl_confirm matches input confirm
887          */ 
888         if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
889                 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
890                         status = nfserr_clid_inuse;
891                 } else {
892                         status = nfs_ok;
893                         clp = unconf;
894                         move_to_confirmed(unconf, idhashval);
895                 }
896                 goto out;
897         }
898         /* CASE 4:
899          * conf record not found, or if conf, then conf->cl_confirm does not
900          * match input confirm.
901          * unconf record not found, or if unconf, then unconf->cl_confirm 
902          * does not match input confirm.
903          */
904         if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
905             (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
906                 status = nfserr_stale_clientid;
907                 goto out;
908         }
909         /* check that we have hit one of the cases...*/
910         status = nfserr_inval;
911         goto out;
912 out:
913         if (!status)
914                 nfsd4_probe_callback(clp);
915         nfs4_unlock_state();
916         return status;
917 }
918
919 /* 
920  * Open owner state (share locks)
921  */
922
923 /* hash tables for nfs4_stateowner */
924 #define OWNER_HASH_BITS              8
925 #define OWNER_HASH_SIZE             (1 << OWNER_HASH_BITS)
926 #define OWNER_HASH_MASK             (OWNER_HASH_SIZE - 1)
927
928 #define ownerid_hashval(id) \
929         ((id) & OWNER_HASH_MASK)
930 #define ownerstr_hashval(clientid, ownername) \
931         (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK)
932
933 static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE];
934 static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
935
936 /* hash table for nfs4_file */
937 #define FILE_HASH_BITS                   8
938 #define FILE_HASH_SIZE                  (1 << FILE_HASH_BITS)
939 #define FILE_HASH_MASK                  (FILE_HASH_SIZE - 1)
940 /* hash table for (open)nfs4_stateid */
941 #define STATEID_HASH_BITS              10
942 #define STATEID_HASH_SIZE              (1 << STATEID_HASH_BITS)
943 #define STATEID_HASH_MASK              (STATEID_HASH_SIZE - 1)
944
945 #define file_hashval(x) \
946         hash_ptr(x, FILE_HASH_BITS)
947 #define stateid_hashval(owner_id, file_id)  \
948         (((owner_id) + (file_id)) & STATEID_HASH_MASK)
949
950 static struct list_head file_hashtbl[FILE_HASH_SIZE];
951 static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
952
953 /* OPEN Share state helper functions */
954 static inline struct nfs4_file *
955 alloc_init_file(unsigned int hashval, struct inode *ino) {
956         struct nfs4_file *fp;
957         if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
958                 INIT_LIST_HEAD(&fp->fi_hash);
959                 INIT_LIST_HEAD(&fp->fi_perfile);
960                 INIT_LIST_HEAD(&fp->fi_del_perfile);
961                 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
962                 fp->fi_inode = igrab(ino);
963                 fp->fi_id = current_fileid++;
964                 alloc_file++;
965                 return fp;
966         }
967         return NULL;
968 }
969
970 static void
971 release_all_files(void)
972 {
973         int i;
974         struct nfs4_file *fp;
975
976         for (i=0;i<FILE_HASH_SIZE;i++) {
977                 while (!list_empty(&file_hashtbl[i])) {
978                         fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
979                         /* this should never be more than once... */
980                         if (!list_empty(&fp->fi_perfile) || !list_empty(&fp->fi_del_perfile)) {
981                                 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
982                         }
983                         release_file(fp);
984                 }
985         }
986 }
987
988 /* should use a slab cache */
989 void
990 nfs4_free_stateowner(struct kref *kref)
991 {
992         struct nfs4_stateowner *sop =
993                 container_of(kref, struct nfs4_stateowner, so_ref);
994         kfree(sop->so_owner.data);
995         kfree(sop);
996         free_sowner++;
997 }
998
999 static inline struct nfs4_stateowner *
1000 alloc_stateowner(struct xdr_netobj *owner)
1001 {
1002         struct nfs4_stateowner *sop;
1003
1004         if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
1005                 if ((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
1006                         memcpy(sop->so_owner.data, owner->data, owner->len);
1007                         sop->so_owner.len = owner->len;
1008                         kref_init(&sop->so_ref);
1009                         return sop;
1010                 } 
1011                 kfree(sop);
1012         }
1013         return NULL;
1014 }
1015
1016 static struct nfs4_stateowner *
1017 alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
1018         struct nfs4_stateowner *sop;
1019         struct nfs4_replay *rp;
1020         unsigned int idhashval;
1021
1022         if (!(sop = alloc_stateowner(&open->op_owner)))
1023                 return NULL;
1024         idhashval = ownerid_hashval(current_ownerid);
1025         INIT_LIST_HEAD(&sop->so_idhash);
1026         INIT_LIST_HEAD(&sop->so_strhash);
1027         INIT_LIST_HEAD(&sop->so_perclient);
1028         INIT_LIST_HEAD(&sop->so_perfilestate);
1029         INIT_LIST_HEAD(&sop->so_perlockowner);  /* not used */
1030         INIT_LIST_HEAD(&sop->so_close_lru);
1031         sop->so_time = 0;
1032         list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
1033         list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
1034         list_add(&sop->so_perclient, &clp->cl_perclient);
1035         add_perclient++;
1036         sop->so_is_open_owner = 1;
1037         sop->so_id = current_ownerid++;
1038         sop->so_client = clp;
1039         sop->so_seqid = open->op_seqid;
1040         sop->so_confirmed = 0;
1041         rp = &sop->so_replay;
1042         rp->rp_status = NFSERR_SERVERFAULT;
1043         rp->rp_buflen = 0;
1044         rp->rp_buf = rp->rp_ibuf;
1045         alloc_sowner++;
1046         return sop;
1047 }
1048
1049 static void
1050 release_stateid_lockowner(struct nfs4_stateid *open_stp)
1051 {
1052         struct nfs4_stateowner *lock_sop;
1053
1054         while (!list_empty(&open_stp->st_perlockowner)) {
1055                 lock_sop = list_entry(open_stp->st_perlockowner.next,
1056                                 struct nfs4_stateowner, so_perlockowner);
1057                 /* list_del(&open_stp->st_perlockowner);  */
1058                 BUG_ON(lock_sop->so_is_open_owner);
1059                 release_stateowner(lock_sop);
1060         }
1061 }
1062
1063 static void
1064 unhash_stateowner(struct nfs4_stateowner *sop)
1065 {
1066         struct nfs4_stateid *stp;
1067
1068         list_del(&sop->so_idhash);
1069         list_del(&sop->so_strhash);
1070         list_del(&sop->so_perclient);
1071         list_del(&sop->so_perlockowner);
1072         del_perclient++;
1073         while (!list_empty(&sop->so_perfilestate)) {
1074                 stp = list_entry(sop->so_perfilestate.next, 
1075                         struct nfs4_stateid, st_perfilestate);
1076                 if (sop->so_is_open_owner)
1077                         release_stateid(stp, OPEN_STATE);
1078                 else
1079                         release_stateid(stp, LOCK_STATE);
1080         }
1081 }
1082
1083 static void
1084 release_stateowner(struct nfs4_stateowner *sop)
1085 {
1086         unhash_stateowner(sop);
1087         list_del(&sop->so_close_lru);
1088         nfs4_put_stateowner(sop);
1089 }
1090
1091 static inline void
1092 init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
1093         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
1094
1095         INIT_LIST_HEAD(&stp->st_hash);
1096         INIT_LIST_HEAD(&stp->st_perfilestate);
1097         INIT_LIST_HEAD(&stp->st_perlockowner);
1098         INIT_LIST_HEAD(&stp->st_perfile);
1099         list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
1100         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
1101         list_add_perfile++;
1102         list_add(&stp->st_perfile, &fp->fi_perfile);
1103         stp->st_stateowner = sop;
1104         stp->st_file = fp;
1105         stp->st_stateid.si_boot = boot_time;
1106         stp->st_stateid.si_stateownerid = sop->so_id;
1107         stp->st_stateid.si_fileid = fp->fi_id;
1108         stp->st_stateid.si_generation = 0;
1109         stp->st_access_bmap = 0;
1110         stp->st_deny_bmap = 0;
1111         __set_bit(open->op_share_access, &stp->st_access_bmap);
1112         __set_bit(open->op_share_deny, &stp->st_deny_bmap);
1113 }
1114
1115 /*
1116 * Because nfsd_close() can call locks_remove_flock() which removes leases,
1117 * delay nfsd_close() for delegations from the nfsd_open() clientid
1118 * until the delegation is reaped.
1119 */
1120 static void
1121 release_stateid(struct nfs4_stateid *stp, int flags)
1122 {
1123         struct nfs4_delegation *dp;
1124         struct nfs4_file *fp = stp->st_file;
1125
1126         list_del(&stp->st_hash);
1127         list_del_perfile++;
1128         list_del(&stp->st_perfile);
1129         list_del(&stp->st_perfilestate);
1130         if ((stp->st_vfs_set) && (flags & OPEN_STATE)) {
1131                 list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
1132                         if(cmp_clid(&dp->dl_client->cl_clientid,
1133                             &stp->st_stateowner->so_client->cl_clientid)) {
1134                                 dp->dl_stp = stp;
1135                                 return;
1136                         }
1137                 }
1138                 release_stateid_lockowner(stp);
1139                 nfsd_close(stp->st_vfs_file);
1140                 vfsclose++;
1141         } else if ((stp->st_vfs_set) && (flags & LOCK_STATE)) {
1142                 struct file *filp = stp->st_vfs_file;
1143
1144                 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
1145         }
1146         kfree(stp);
1147         stp = NULL;
1148 }
1149
1150 static void
1151 release_file(struct nfs4_file *fp)
1152 {
1153         free_file++;
1154         list_del(&fp->fi_hash);
1155         iput(fp->fi_inode);
1156         kfree(fp);
1157 }       
1158
1159 void
1160 move_to_close_lru(struct nfs4_stateowner *sop)
1161 {
1162         dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
1163
1164         unhash_stateowner(sop);
1165         list_add_tail(&sop->so_close_lru, &close_lru);
1166         sop->so_time = get_seconds();
1167 }
1168
1169 void
1170 release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp,
1171                 int flag)
1172 {
1173         struct nfs4_stateowner *sop = stp->st_stateowner;
1174         struct nfs4_file *fp = stp->st_file;
1175
1176         dprintk("NFSD: release_state_owner\n");
1177         release_stateid(stp, flag);
1178
1179         /* place unused nfs4_stateowners on so_close_lru list to be
1180          * released by the laundromat service after the lease period
1181          * to enable us to handle CLOSE replay
1182          */
1183         if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
1184                 move_to_close_lru(sop);
1185         /* unused nfs4_file's are releseed. XXX slab cache? */
1186         if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) {
1187                 release_file(fp);
1188         }
1189 }
1190
1191 static int
1192 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
1193         return ((sop->so_owner.len == owner->len) && 
1194          !memcmp(sop->so_owner.data, owner->data, owner->len) && 
1195           (sop->so_client->cl_clientid.cl_id == clid->cl_id));
1196 }
1197
1198 /* search ownerstr_hashtbl[] for owner */
1199 static int
1200 find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
1201         struct nfs4_stateowner *local = NULL;
1202
1203         list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) {
1204                 if (!cmp_owner_str(local, &open->op_owner, &open->op_clientid))
1205                         continue;
1206                 *op = local;
1207                 return(1);
1208         }
1209         return 0;
1210 }
1211
1212 /* see if clientid is in confirmed hash table */
1213 static int
1214 verify_clientid(struct nfs4_client **client, clientid_t *clid) {
1215
1216         struct nfs4_client *clp;
1217         unsigned int idhashval = clientid_hashval(clid->cl_id);
1218
1219         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1220                 if (!cmp_clid(&clp->cl_clientid, clid))
1221                         continue;
1222                 *client = clp;
1223                 return 1;
1224         }
1225         *client = NULL;
1226         return 0;
1227 }
1228
1229 /* search file_hashtbl[] for file */
1230 static int
1231 find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) {
1232         struct nfs4_file *local = NULL;
1233
1234         list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) {
1235                 if (local->fi_inode == ino) {
1236                         *fp = local;
1237                         return(1);
1238                 }
1239         }
1240         return 0;
1241 }
1242
1243 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
1244 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
1245
1246 void
1247 set_access(unsigned int *access, unsigned long bmap) {
1248         int i;
1249
1250         *access = 0;
1251         for (i = 1; i < 4; i++) {
1252                 if (test_bit(i, &bmap))
1253                         *access |= i;
1254         }
1255 }
1256
1257 void
1258 set_deny(unsigned int *deny, unsigned long bmap) {
1259         int i;
1260
1261         *deny = 0;
1262         for (i = 0; i < 4; i++) {
1263                 if (test_bit(i, &bmap))
1264                         *deny |= i ;
1265         }
1266 }
1267
1268 static int
1269 test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1270         unsigned int access, deny;
1271
1272         set_access(&access, stp->st_access_bmap);
1273         set_deny(&deny, stp->st_deny_bmap);
1274         if ((access & open->op_share_deny) || (deny & open->op_share_access))
1275                 return 0;
1276         return 1;
1277 }
1278
1279 /*
1280  * Called to check deny when READ with all zero stateid or
1281  * WRITE with all zero or all one stateid
1282  */
1283 int
1284 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1285 {
1286         struct inode *ino = current_fh->fh_dentry->d_inode;
1287         unsigned int fi_hashval;
1288         struct nfs4_file *fp;
1289         struct nfs4_stateid *stp;
1290
1291         dprintk("NFSD: nfs4_share_conflict\n");
1292
1293         fi_hashval = file_hashval(ino);
1294         if (find_file(fi_hashval, ino, &fp)) {
1295         /* Search for conflicting share reservations */
1296                 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
1297                         if (test_bit(deny_type, &stp->st_deny_bmap) ||
1298                             test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1299                                 return nfserr_share_denied;
1300                 }
1301         }
1302         return nfs_ok;
1303 }
1304
1305 static inline void
1306 nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1307 {
1308         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1309                 put_write_access(filp->f_dentry->d_inode);
1310                 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
1311         }
1312 }
1313
1314 /*
1315  * Recall a delegation
1316  */
1317 static int
1318 do_recall(void *__dp)
1319 {
1320         struct nfs4_delegation *dp = __dp;
1321
1322         daemonize("nfsv4-recall");
1323
1324         atomic_inc(&dp->dl_count);
1325         nfsd4_cb_recall(dp);
1326         return 0;
1327 }
1328
1329 /*
1330  * Spawn a thread to perform a recall on the delegation represented
1331  * by the lease (file_lock)
1332  *
1333  * Called from break_lease() with lock_kernel() held,
1334  *
1335  */
1336 static
1337 void nfsd_break_deleg_cb(struct file_lock *fl)
1338 {
1339         struct nfs4_delegation *dp=  (struct nfs4_delegation *)fl->fl_owner;
1340         struct task_struct *t;
1341
1342         dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
1343         if (!dp)
1344                 return;
1345
1346         /* schedule delegation for recall */
1347         spin_lock(&recall_lock);
1348         atomic_set(&dp->dl_state, NFS4_RECALL_IN_PROGRESS);
1349         list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
1350         spin_unlock(&recall_lock);
1351
1352         /* only place dl_time is set. protected by lock_kernel*/
1353         dp->dl_time = get_seconds();
1354
1355         /* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */
1356         fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ;
1357
1358         t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
1359         if (IS_ERR(t)) {
1360                 struct nfs4_client *clp = dp->dl_client;
1361
1362                 printk(KERN_INFO "NFSD: Callback thread failed for "
1363                         "for client (clientid %08x/%08x)\n",
1364                         clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
1365         }
1366 }
1367
1368 /*
1369  * The file_lock is being reapd.
1370  *
1371  * Called by locks_free_lock() with lock_kernel() held.
1372  */
1373 static
1374 void nfsd_release_deleg_cb(struct file_lock *fl)
1375 {
1376         struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
1377
1378         dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d, dl_state %d\n", fl,dp, atomic_read(&dp->dl_count), atomic_read(&dp->dl_state));
1379
1380         if (!(fl->fl_flags & FL_LEASE) || !dp)
1381                 return;
1382         atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
1383         dp->dl_flock = NULL;
1384 }
1385
1386 /*
1387  * Set the delegation file_lock back pointer.
1388  *
1389  * Called from __setlease() with lock_kernel() held.
1390  */
1391 static
1392 void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
1393 {
1394         struct nfs4_delegation *dp = (struct nfs4_delegation *)new->fl_owner;
1395
1396         dprintk("NFSD: nfsd_copy_lock_deleg_cb: new fl %p dp %p\n", new, dp);
1397         if (!dp)
1398                 return;
1399         dp->dl_flock = new;
1400 }
1401
1402 struct lock_manager_operations nfsd_lease_mng_ops = {
1403         .fl_break = nfsd_break_deleg_cb,
1404         .fl_release_private = nfsd_release_deleg_cb,
1405         .fl_copy_lock = nfsd_copy_lock_deleg_cb,
1406 };
1407
1408
1409
1410 /*
1411  * nfsd4_process_open1()
1412  *      lookup stateowner.
1413  *              found:
1414  *                      check confirmed 
1415  *                              confirmed:
1416  *                                      check seqid
1417  *                              not confirmed:
1418  *                                      delete owner
1419  *                                      create new owner
1420  *              notfound:
1421  *                      verify clientid
1422  *                      create new owner
1423  *
1424  * called with nfs4_lock_state() held.
1425  */
1426 int
1427 nfsd4_process_open1(struct nfsd4_open *open)
1428 {
1429         int status;
1430         clientid_t *clientid = &open->op_clientid;
1431         struct nfs4_client *clp = NULL;
1432         unsigned int strhashval;
1433         struct nfs4_stateowner *sop = NULL;
1434
1435         status = nfserr_inval;
1436         if (!check_name(open->op_owner))
1437                 goto out;
1438
1439         status = nfserr_stale_clientid;
1440         if (STALE_CLIENTID(&open->op_clientid))
1441                 return status;
1442
1443         strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1444         if (find_openstateowner_str(strhashval, open, &sop)) {
1445                 open->op_stateowner = sop;
1446                 /* check for replay */
1447                 if (open->op_seqid == sop->so_seqid){
1448                         if (!sop->so_replay.rp_buflen) {
1449                         /*
1450                         * The original OPEN failed in so spectacularly that we
1451                         * don't even have replay data saved!  Therefore, we
1452                         * have no choice but to continue processing
1453                         * this OPEN; presumably, we'll fail again for the same
1454                         * reason.
1455                         */
1456                                 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1457                                 status = NFS_OK;
1458                                 goto renew;
1459                         }
1460                         /* replay: indicate to calling function */
1461                         status = NFSERR_REPLAY_ME;
1462                         return status;
1463                 }
1464                 if (sop->so_confirmed) {
1465                         if (open->op_seqid == sop->so_seqid + 1) { 
1466                                 status = nfs_ok;
1467                                 goto renew;
1468                         } 
1469                         status = nfserr_bad_seqid;
1470                         goto out;
1471                 }
1472                 /* If we get here, we received and OPEN for an unconfirmed
1473                  * nfs4_stateowner. 
1474                  * Since the sequid's are different, purge the 
1475                  * existing nfs4_stateowner, and instantiate a new one.
1476                  */
1477                 clp = sop->so_client;
1478                 release_stateowner(sop);
1479                 goto instantiate_new_owner;
1480         } 
1481         /* nfs4_stateowner not found. 
1482         * verify clientid and instantiate new nfs4_stateowner
1483         * if verify fails this is presumably the result of the 
1484         * client's lease expiring.
1485         *
1486         * XXX compare clp->cl_addr with rqstp addr? 
1487         */
1488         status = nfserr_expired;
1489         if (!verify_clientid(&clp, clientid))
1490                 goto out;
1491 instantiate_new_owner:
1492         status = nfserr_resource;
1493         if (!(sop = alloc_init_open_stateowner(strhashval, clp, open))) 
1494                 goto out;
1495         open->op_stateowner = sop;
1496         status = nfs_ok;
1497 renew:
1498         renew_client(sop->so_client);
1499 out:
1500         if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1501                 status = nfserr_reclaim_bad;
1502         return status;
1503 }
1504
1505 static int
1506 nfs4_deleg_conflict(u32 share, u32 dtype)
1507 {
1508         return (((share & NFS4_SHARE_ACCESS_WRITE) &&
1509                 dtype == NFS4_OPEN_DELEGATE_READ) ||
1510                 ((share & NFS4_SHARE_ACCESS_READ) &&
1511                 dtype == NFS4_OPEN_DELEGATE_WRITE));
1512 }
1513
1514 #define DONT_DELEGATE  8
1515
1516 /*
1517  * nfs4_check_deleg_recall()
1518  *
1519  * Test any delegation that is currently within an incompleted recalled
1520  * state, and return NFSERR_DELAY for conflicting open share.
1521  * flag is set to DONT_DELEGATE for shares that match the deleg type.
1522  */
1523 static int
1524 nfs4_check_deleg_recall(struct nfs4_file *fp, struct nfsd4_open *op, int *flag)
1525 {
1526         struct nfs4_delegation *dp;
1527         int status = 0;
1528
1529         list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
1530                 dprintk("NFSD: found delegation %p with dl_state %d\n",
1531                                          dp, atomic_read(&dp->dl_state));
1532                 if (atomic_read(&dp->dl_state) == NFS4_RECALL_IN_PROGRESS) {
1533                         if(nfs4_deleg_conflict(op->op_share_access, dp->dl_type))
1534                                 status = nfserr_jukebox;
1535                         else
1536                                 *flag = DONT_DELEGATE;
1537                 }
1538         }
1539         return status;
1540 }
1541
1542 static int
1543 nfs4_check_open(struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open, struct nfs4_stateid **stpp)
1544 {
1545         struct nfs4_stateid *local;
1546         int status = nfserr_share_denied;
1547
1548         list_for_each_entry(local, &fp->fi_perfile, st_perfile) {
1549                 /* have we seen this open owner */
1550                 if (local->st_stateowner == sop) {
1551                         *stpp = local;
1552                         continue;
1553                 }
1554                 /* ignore lock owners */
1555                 if (local->st_stateowner->so_is_open_owner == 0)
1556                         continue;
1557                 /* check for conflicting share reservations */
1558                 if (!test_share(local, open))
1559                         goto out;
1560         }
1561         status = 0;
1562 out:
1563         return status;
1564 }
1565
1566 static int
1567 nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
1568                 struct svc_fh *cur_fh, int flags)
1569 {
1570         struct nfs4_stateid *stp;
1571         int status;
1572
1573         stp = kmalloc(sizeof(struct nfs4_stateid), GFP_KERNEL);
1574         if (stp == NULL)
1575                 return nfserr_resource;
1576
1577         status = nfsd_open(rqstp, cur_fh, S_IFREG, flags, &stp->st_vfs_file);
1578         if (status) {
1579                 if (status == nfserr_dropit)
1580                         status = nfserr_jukebox;
1581                 kfree(stp);
1582                 return status;
1583         }
1584         vfsopen++;
1585         stp->st_vfs_set = 1;
1586         *stpp = stp;
1587         return 0;
1588 }
1589
1590 static int
1591 nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
1592 {
1593         struct file *filp = stp->st_vfs_file;
1594         struct inode *inode = filp->f_dentry->d_inode;
1595         unsigned int share_access;
1596         int status;
1597
1598         set_access(&share_access, stp->st_access_bmap);
1599         share_access = ~share_access;
1600         share_access &= open->op_share_access;
1601
1602         /* update the struct file */
1603         if (share_access & NFS4_SHARE_ACCESS_WRITE) {
1604                 status = get_write_access(inode);
1605                 if (status)
1606                         return nfserrno(status);
1607                 if (open->op_truncate) {
1608                         struct iattr iattr = {
1609                                 .ia_valid = ATTR_SIZE,
1610                                 .ia_size = 0,
1611                         };
1612                         status = nfsd_setattr(rqstp, cur_fh, &iattr, 0,
1613                                         (time_t)0);
1614                         if (status) {
1615                                 put_write_access(inode);
1616                                 return status;
1617                         }
1618                 }
1619
1620                 /* remember the open */
1621                 filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
1622                 set_bit(open->op_share_access, &stp->st_access_bmap);
1623                 set_bit(open->op_share_deny, &stp->st_deny_bmap);
1624         }
1625         return nfs_ok;
1626 }
1627
1628
1629 /* decrement seqid on successful reclaim, it will be bumped in encode_open */
1630 static void
1631 nfs4_set_claim_prev(struct nfsd4_open *open, int *status)
1632 {
1633         if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
1634                 if (*status)
1635                         *status = nfserr_reclaim_bad;
1636                 else {
1637                         open->op_stateowner->so_confirmed = 1;
1638                         open->op_stateowner->so_seqid--;
1639                 }
1640         }
1641 }
1642
1643 /*
1644  * Attempt to hand out a delegation.
1645  */
1646 static void
1647 nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp, int *flag)
1648 {
1649         struct nfs4_delegation *dp;
1650         struct nfs4_stateowner *sop = stp->st_stateowner;
1651         struct nfs4_callback *cb = &sop->so_client->cl_callback;
1652         struct file_lock fl, *flp = &fl;
1653         int status;
1654
1655         if (*flag == DONT_DELEGATE) {
1656                 *flag = NFS4_OPEN_DELEGATE_NONE;
1657                 return;
1658         }
1659
1660         /* set flag */
1661         *flag = NFS4_OPEN_DELEGATE_NONE;
1662         if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
1663              || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
1664                 return;
1665
1666         if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
1667                 *flag = NFS4_OPEN_DELEGATE_READ;
1668
1669         else if (!(open->op_share_access & NFS4_SHARE_ACCESS_READ))
1670                 *flag = NFS4_OPEN_DELEGATE_WRITE;
1671
1672         if (!(dp = alloc_init_deleg(sop->so_client, stp->st_file, fh, *flag)))
1673                 return;
1674         locks_init_lock(&fl);
1675         fl.fl_lmops = &nfsd_lease_mng_ops;
1676         fl.fl_flags = FL_LEASE;
1677         fl.fl_end = OFFSET_MAX;
1678         fl.fl_owner =  (fl_owner_t)dp;
1679         fl.fl_file = stp->st_vfs_file;
1680         fl.fl_pid = current->tgid;
1681
1682         if ((status = setlease(stp->st_vfs_file,
1683                 *flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
1684                 dprintk("NFSD: setlease failed [%d], no delegation\n", status);
1685                 list_del(&dp->dl_del_perfile);
1686                 list_del(&dp->dl_del_perclnt);
1687                 kfree(dp);
1688                 free_delegation++;
1689                 *flag = NFS4_OPEN_DELEGATE_NONE;
1690                 return;
1691         }
1692
1693         memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
1694
1695         dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n",
1696                      dp->dl_stateid.si_boot,
1697                      dp->dl_stateid.si_stateownerid,
1698                      dp->dl_stateid.si_fileid,
1699                      dp->dl_stateid.si_generation);
1700 }
1701
1702 /*
1703  * called with nfs4_lock_state() held.
1704  */
1705 int
1706 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
1707 {
1708         struct nfs4_stateowner *sop = open->op_stateowner;
1709         struct nfs4_file *fp = NULL;
1710         struct inode *ino = current_fh->fh_dentry->d_inode;
1711         unsigned int fi_hashval;
1712         struct nfs4_stateid *stp = NULL;
1713         int status, delegflag = 0;
1714
1715         status = nfserr_inval;
1716         if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1717                 goto out;
1718         /*
1719          * Lookup file; if found, lookup stateid and check open request,
1720          * and check for delegations in the process of being recalled.
1721          * If not found, create the nfs4_file struct
1722          */
1723         fi_hashval = file_hashval(ino);
1724         if (find_file(fi_hashval, ino, &fp)) {
1725                 if ((status = nfs4_check_open(fp, sop, open, &stp)))
1726                         goto out;
1727                 if ((status = nfs4_check_deleg_recall(fp, open, &delegflag)))
1728                         goto out;
1729         } else {
1730                 status = nfserr_resource;
1731                 if ((fp = alloc_init_file(fi_hashval, ino)) == NULL)
1732                         goto out;
1733         }
1734
1735         /*
1736          * OPEN the file, or upgrade an existing OPEN.
1737          * If truncate fails, the OPEN fails.
1738          */
1739         if (stp) {
1740                 /* Stateid was found, this is an OPEN upgrade */
1741                 status = nfs4_upgrade_open(rqstp, current_fh, stp, open);
1742                 if (status)
1743                         goto out;
1744         } else {
1745                 /* Stateid was not found, this is a new OPEN */
1746                 int flags = 0;
1747                 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1748                         flags = MAY_WRITE;
1749                 else
1750                         flags = MAY_READ;
1751                 if ((status = nfs4_new_open(rqstp, &stp, current_fh, flags)))
1752                         goto out;
1753                 init_stateid(stp, fp, sop, open);
1754                 if (open->op_truncate) {
1755                         struct iattr iattr = {
1756                                 .ia_valid = ATTR_SIZE,
1757                                 .ia_size = 0,
1758                         };
1759                         status = nfsd_setattr(rqstp, current_fh, &iattr, 0,
1760                                         (time_t)0);
1761                         if (status) {
1762                                 release_stateid(stp, OPEN_STATE);
1763                                 goto out;
1764                         }
1765                 }
1766         }
1767         memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
1768
1769         /*
1770         * Attempt to hand out a delegation. No error return, because the
1771         * OPEN succeeds even if we fail.
1772         */
1773         nfs4_open_delegation(current_fh, open, stp, &delegflag);
1774         open->op_delegate_type = delegflag;
1775
1776         status = nfs_ok;
1777
1778         dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
1779                     stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1780                     stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1781 out:
1782         /* take the opportunity to clean up unused state */
1783         if (fp && list_empty(&fp->fi_perfile))
1784                 release_file(fp);
1785
1786         /* CLAIM_PREVIOUS has different error returns */
1787         nfs4_set_claim_prev(open, &status);
1788         /*
1789         * To finish the open response, we just need to set the rflags.
1790         */
1791         open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
1792         if (!open->op_stateowner->so_confirmed)
1793                 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
1794
1795         return status;
1796 }
1797
1798 static struct work_struct laundromat_work;
1799 static void laundromat_main(void *);
1800 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
1801
1802 int 
1803 nfsd4_renew(clientid_t *clid)
1804 {
1805         struct nfs4_client *clp;
1806         unsigned int idhashval;
1807         int status;
1808
1809         nfs4_lock_state();
1810         dprintk("process_renew(%08x/%08x): starting\n", 
1811                         clid->cl_boot, clid->cl_id);
1812         status = nfserr_stale_clientid;
1813         if (STALE_CLIENTID(clid))
1814                 goto out;
1815         status = nfs_ok;
1816         idhashval = clientid_hashval(clid->cl_id);
1817         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
1818                 if (!cmp_clid(&clp->cl_clientid, clid))
1819                         continue;
1820                 renew_client(clp);
1821                 goto out;
1822         }
1823         list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
1824                 if (!cmp_clid(&clp->cl_clientid, clid))
1825                         continue;
1826                 renew_client(clp);
1827         goto out;
1828         }
1829         /*
1830         * Couldn't find an nfs4_client for this clientid.  
1831         * Presumably this is because the client took too long to 
1832         * RENEW, so return NFS4ERR_EXPIRED.
1833         */
1834         dprintk("nfsd4_renew: clientid not found!\n");
1835         status = nfserr_expired;
1836 out:
1837         nfs4_unlock_state();
1838         return status;
1839 }
1840
1841 time_t
1842 nfs4_laundromat(void)
1843 {
1844         struct nfs4_client *clp;
1845         struct nfs4_stateowner *sop;
1846         struct nfs4_delegation *dp;
1847         struct list_head *pos, *next;
1848         time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
1849         time_t t, clientid_val = NFSD_LEASE_TIME;
1850         time_t u, test_val = NFSD_LEASE_TIME;
1851
1852         nfs4_lock_state();
1853
1854         dprintk("NFSD: laundromat service - starting\n");
1855         list_for_each_safe(pos, next, &client_lru) {
1856                 clp = list_entry(pos, struct nfs4_client, cl_lru);
1857                 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
1858                         t = clp->cl_time - cutoff;
1859                         if (clientid_val > t)
1860                                 clientid_val = t;
1861                         break;
1862                 }
1863                 dprintk("NFSD: purging unused client (clientid %08x)\n",
1864                         clp->cl_clientid.cl_id);
1865                 expire_client(clp);
1866         }
1867         spin_lock(&recall_lock);
1868         list_for_each_safe(pos, next, &del_recall_lru) {
1869                 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
1870                 if (atomic_read(&dp->dl_state) == NFS4_RECALL_COMPLETE)
1871                         goto reap;
1872                 if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
1873                         u = dp->dl_time - cutoff;
1874                         if (test_val > u)
1875                                 test_val = u;
1876                         break;
1877                 }
1878 reap:
1879                 dprintk("NFSD: purging unused delegation dp %p, fp %p\n",
1880                                     dp, dp->dl_flock);
1881                 release_delegation(dp);
1882         }
1883         spin_unlock(&recall_lock);
1884         test_val = NFSD_LEASE_TIME;
1885         list_for_each_safe(pos, next, &close_lru) {
1886                 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
1887                 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
1888                         u = sop->so_time - cutoff;
1889                         if (test_val > u)
1890                                 test_val = u;
1891                         break;
1892                 }
1893                 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
1894                         sop->so_id);
1895                 list_del(&sop->so_close_lru);
1896                 nfs4_put_stateowner(sop);
1897         }
1898         if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
1899                 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
1900         nfs4_unlock_state();
1901         return clientid_val;
1902 }
1903
1904 void
1905 laundromat_main(void *not_used)
1906 {
1907         time_t t;
1908
1909         t = nfs4_laundromat();
1910         dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1911         schedule_delayed_work(&laundromat_work, t*HZ);
1912 }
1913
1914 /* search ownerid_hashtbl[] and close_lru for stateid owner
1915  * (stateid->si_stateownerid)
1916  */
1917 struct nfs4_stateowner *
1918 find_openstateowner_id(u32 st_id, int flags) {
1919         struct nfs4_stateowner *local = NULL;
1920
1921         dprintk("NFSD: find_openstateowner_id %d\n", st_id);
1922         if (flags & CLOSE_STATE) {
1923                 list_for_each_entry(local, &close_lru, so_close_lru) {
1924                         if (local->so_id == st_id)
1925                                 return local;
1926                 }
1927         }
1928         return NULL;
1929 }
1930
1931 static inline int
1932 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
1933 {
1934         return (stp->st_vfs_set == 0 ||
1935                 fhp->fh_dentry->d_inode != stp->st_vfs_file->f_dentry->d_inode);
1936 }
1937
1938 static int
1939 STALE_STATEID(stateid_t *stateid)
1940 {
1941         if (stateid->si_boot == boot_time)
1942                 return 0;
1943         printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
1944                 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
1945                 stateid->si_generation);
1946         return 1;
1947 }
1948
1949 static inline int
1950 access_permit_read(unsigned long access_bmap)
1951 {
1952         return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
1953                 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
1954 }
1955
1956 static inline int
1957 access_permit_write(unsigned long access_bmap)
1958 {
1959         return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) ||
1960                 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
1961 }
1962
1963 static
1964 int nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
1965 {
1966         int status = nfserr_openmode;
1967
1968         if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
1969                 goto out;
1970         if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap)))
1971                 goto out;
1972         status = nfs_ok;
1973 out:
1974         return status;
1975 }
1976
1977 static int
1978 nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
1979 {
1980         int status = nfserr_openmode;
1981
1982         if ((flags & WR_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
1983                 goto out;
1984         if ((flags & RD_STATE) & (dp->dl_type == NFS4_OPEN_DELEGATE_WRITE))
1985                 goto out;
1986         status = nfs_ok;
1987 out:
1988         return status;
1989 }
1990
1991 /*
1992 * Checks for stateid operations
1993 */
1994 int
1995 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags)
1996 {
1997         struct nfs4_stateid *stp = NULL;
1998         struct nfs4_delegation *dp = NULL;
1999         stateid_t *stidp;
2000         int status;
2001
2002         dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
2003                 stateid->si_boot, stateid->si_stateownerid, 
2004                 stateid->si_fileid, stateid->si_generation); 
2005
2006         /* STALE STATEID */
2007         status = nfserr_stale_stateid;
2008         if (STALE_STATEID(stateid)) 
2009                 goto out;
2010
2011         /* BAD STATEID */
2012         status = nfserr_bad_stateid;
2013         if (!stateid->si_fileid) { /* delegation stateid */
2014                 struct inode *ino = current_fh->fh_dentry->d_inode;
2015
2016                 if(!(dp = find_delegation_stateid(ino, stateid))) {
2017                         dprintk("NFSD: delegation stateid not found\n");
2018                         goto out;
2019                 }
2020                 stidp = &dp->dl_stateid;
2021         } else { /* open or lock stateid */
2022                 if (!(stp = find_stateid(stateid, flags))) {
2023                         dprintk("NFSD: open or lock stateid not found\n");
2024                         goto out;
2025                 }
2026                 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
2027                         goto out;
2028                 if (!stp->st_stateowner->so_confirmed)
2029                         goto out;
2030                 stidp = &stp->st_stateid;
2031         }
2032         if (stateid->si_generation > stidp->si_generation)
2033                 goto out;
2034
2035         /* OLD STATEID */
2036         status = nfserr_old_stateid;
2037         if (stateid->si_generation < stidp->si_generation)
2038                 goto out;
2039         if (stp) {
2040                 if ((status = nfs4_check_openmode(stp,flags)))
2041                         goto out;
2042                 renew_client(stp->st_stateowner->so_client);
2043         } else if (dp) {
2044                 if ((status = nfs4_check_delegmode(dp, flags)))
2045                         goto out;
2046                 renew_client(dp->dl_client);
2047                 if (flags & DELEG_RET) {
2048                         atomic_set(&dp->dl_state,NFS4_RECALL_COMPLETE);
2049                         spin_lock(&recall_lock);
2050                         release_delegation(dp);
2051                         spin_unlock(&recall_lock);
2052                 }
2053         }
2054         status = nfs_ok;
2055 out:
2056         return status;
2057 }
2058
2059
2060 /* 
2061  * Checks for sequence id mutating operations. 
2062  */
2063 int
2064 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)
2065 {
2066         int status;
2067         struct nfs4_stateid *stp;
2068         struct nfs4_stateowner *sop;
2069
2070         dprintk("NFSD: preprocess_seqid_op: seqid=%d " 
2071                         "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
2072                 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
2073                 stateid->si_generation);
2074                                 
2075         *stpp = NULL;
2076         *sopp = NULL;
2077
2078         status = nfserr_bad_stateid;
2079         if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
2080                 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
2081                 goto out;
2082         }
2083
2084         status = nfserr_stale_stateid;
2085         if (STALE_STATEID(stateid))
2086                 goto out;
2087         /*
2088         * We return BAD_STATEID if filehandle doesn't match stateid, 
2089         * the confirmed flag is incorrecly set, or the generation 
2090         * number is incorrect.  
2091         * If there is no entry in the openfile table for this id, 
2092         * we can't always return BAD_STATEID;
2093         * this might be a retransmitted CLOSE which has arrived after 
2094         * the openfile has been released.
2095         */
2096         if (!(stp = find_stateid(stateid, flags)))
2097                 goto no_nfs4_stateid;
2098
2099         status = nfserr_bad_stateid;
2100
2101         /* for new lock stateowners:
2102          * check that the lock->v.new.open_stateid
2103          * refers to an open stateowner
2104          *
2105          * check that the lockclid (nfs4_lock->v.new.clientid) is the same
2106          * as the open_stateid->st_stateowner->so_client->clientid
2107          */
2108         if (lockclid) {
2109                 struct nfs4_stateowner *sop = stp->st_stateowner;
2110                 struct nfs4_client *clp = sop->so_client;
2111
2112                 if (!sop->so_is_open_owner)
2113                         goto out;
2114                 if (!cmp_clid(&clp->cl_clientid, lockclid))
2115                         goto out;
2116         }
2117
2118         if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
2119                 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
2120                 stp->st_vfs_set = 0;
2121                 goto out;
2122         }
2123
2124         *stpp = stp;
2125         *sopp = sop = stp->st_stateowner;
2126
2127         /*
2128         *  We now validate the seqid and stateid generation numbers.
2129         *  For the moment, we ignore the possibility of 
2130         *  generation number wraparound.
2131         */
2132         if (seqid != sop->so_seqid + 1)
2133                 goto check_replay;
2134
2135         if (sop->so_confirmed) {
2136                 if (flags & CONFIRM) {
2137                         printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
2138                         goto out;
2139                 }
2140         }
2141         else {
2142                 if (!(flags & CONFIRM)) {
2143                         printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
2144                         goto out;
2145                 }
2146         }
2147         if (stateid->si_generation > stp->st_stateid.si_generation) {
2148                 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
2149                 goto out;
2150         }
2151
2152         status = nfserr_old_stateid;
2153         if (stateid->si_generation < stp->st_stateid.si_generation) {
2154                 printk("NFSD: preprocess_seqid_op: old stateid!\n");
2155                 goto out;
2156         }
2157         /* XXX renew the client lease here */
2158         status = nfs_ok;
2159
2160 out:
2161         return status;
2162
2163 no_nfs4_stateid:
2164
2165         /*
2166         * We determine whether this is a bad stateid or a replay, 
2167         * starting by trying to look up the stateowner.
2168         * If stateowner is not found - stateid is bad.
2169         */
2170         if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
2171                 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
2172                 status = nfserr_bad_stateid;
2173                 goto out;
2174         }
2175         *sopp = sop;
2176
2177 check_replay:
2178         if (seqid == sop->so_seqid) {
2179                 printk("NFSD: preprocess_seqid_op: retransmission?\n");
2180                 /* indicate replay to calling function */
2181                 status = NFSERR_REPLAY_ME;
2182         } else  {
2183                 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
2184
2185                 *sopp = NULL;
2186                 status = nfserr_bad_seqid;
2187         }
2188         goto out;
2189 }
2190
2191 /*
2192  * eventually, this will perform an upcall to the 'state daemon' as well as
2193  * set the cl_first_state field.
2194  */
2195 void
2196 first_state(struct nfs4_client *clp)
2197 {
2198         if (!clp->cl_first_state)
2199                 clp->cl_first_state = get_seconds();
2200 }
2201
2202 int
2203 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
2204 {
2205         int status;
2206         struct nfs4_stateowner *sop;
2207         struct nfs4_stateid *stp;
2208
2209         dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
2210                         (int)current_fh->fh_dentry->d_name.len,
2211                         current_fh->fh_dentry->d_name.name);
2212
2213         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
2214                 goto out;
2215
2216         nfs4_lock_state();
2217
2218         if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
2219                                         &oc->oc_req_stateid,
2220                                         CHECK_FH | CONFIRM | OPEN_STATE,
2221                                         &oc->oc_stateowner, &stp, NULL)))
2222                 goto out; 
2223
2224         sop = oc->oc_stateowner;
2225         sop->so_confirmed = 1;
2226         update_stateid(&stp->st_stateid);
2227         memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
2228         dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " 
2229                 "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
2230                          stp->st_stateid.si_boot,
2231                          stp->st_stateid.si_stateownerid,
2232                          stp->st_stateid.si_fileid,
2233                          stp->st_stateid.si_generation);
2234         status = nfs_ok;
2235         first_state(sop->so_client);
2236 out:
2237         if (oc->oc_stateowner)
2238                 nfs4_get_stateowner(oc->oc_stateowner);
2239         nfs4_unlock_state();
2240         return status;
2241 }
2242
2243
2244 /*
2245  * unset all bits in union bitmap (bmap) that
2246  * do not exist in share (from successful OPEN_DOWNGRADE)
2247  */
2248 static void
2249 reset_union_bmap_access(unsigned long access, unsigned long *bmap)
2250 {
2251         int i;
2252         for (i = 1; i < 4; i++) {
2253                 if ((i & access) != i)
2254                         __clear_bit(i, bmap);
2255         }
2256 }
2257
2258 static void
2259 reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
2260 {
2261         int i;
2262         for (i = 0; i < 4; i++) {
2263                 if ((i & deny) != i)
2264                         __clear_bit(i, bmap);
2265         }
2266 }
2267
2268 int
2269 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
2270 {
2271         int status;
2272         struct nfs4_stateid *stp;
2273         unsigned int share_access;
2274
2275         dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 
2276                         (int)current_fh->fh_dentry->d_name.len,
2277                         current_fh->fh_dentry->d_name.name);
2278
2279         if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny))
2280                 return nfserr_inval;
2281
2282         nfs4_lock_state();
2283         if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, 
2284                                         &od->od_stateid, 
2285                                         CHECK_FH | OPEN_STATE, 
2286                                         &od->od_stateowner, &stp, NULL)))
2287                 goto out; 
2288
2289         status = nfserr_inval;
2290         if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
2291                 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
2292                         stp->st_access_bmap, od->od_share_access);
2293                 goto out;
2294         }
2295         if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) {
2296                 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
2297                         stp->st_deny_bmap, od->od_share_deny);
2298                 goto out;
2299         }
2300         set_access(&share_access, stp->st_access_bmap);
2301         nfs4_file_downgrade(stp->st_vfs_file,
2302                             share_access & ~od->od_share_access);
2303
2304         reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
2305         reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
2306
2307         update_stateid(&stp->st_stateid);
2308         memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
2309         status = nfs_ok;
2310 out:
2311         if (od->od_stateowner)
2312                 nfs4_get_stateowner(od->od_stateowner);
2313         nfs4_unlock_state();
2314         return status;
2315 }
2316
2317 /*
2318  * nfs4_unlock_state() called after encode
2319  */
2320 int
2321 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
2322 {
2323         int status;
2324         struct nfs4_stateid *stp;
2325
2326         dprintk("NFSD: nfsd4_close on file %.*s\n", 
2327                         (int)current_fh->fh_dentry->d_name.len,
2328                         current_fh->fh_dentry->d_name.name);
2329
2330         nfs4_lock_state();
2331         /* check close_lru for replay */
2332         if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, 
2333                                         &close->cl_stateid, 
2334                                         CHECK_FH | OPEN_STATE | CLOSE_STATE,
2335                                         &close->cl_stateowner, &stp, NULL)))
2336                 goto out; 
2337         /*
2338         *  Return success, but first update the stateid.
2339         */
2340         status = nfs_ok;
2341         update_stateid(&stp->st_stateid);
2342         memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
2343
2344         /* release_state_owner() calls nfsd_close() if needed */
2345         release_state_owner(stp, &close->cl_stateowner, OPEN_STATE);
2346 out:
2347         if (close->cl_stateowner)
2348                 nfs4_get_stateowner(close->cl_stateowner);
2349         nfs4_unlock_state();
2350         return status;
2351 }
2352
2353 int
2354 nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
2355 {
2356         int status;
2357
2358         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
2359                 goto out;
2360
2361         nfs4_lock_state();
2362         status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET);
2363         nfs4_unlock_state();
2364 out:
2365         return status;
2366 }
2367
2368
2369 /* 
2370  * Lock owner state (byte-range locks)
2371  */
2372 #define LOFF_OVERFLOW(start, len)      ((u64)(len) > ~(u64)(start))
2373 #define LOCK_HASH_BITS              8
2374 #define LOCK_HASH_SIZE             (1 << LOCK_HASH_BITS)
2375 #define LOCK_HASH_MASK             (LOCK_HASH_SIZE - 1)
2376
2377 #define lockownerid_hashval(id) \
2378         ((id) & LOCK_HASH_MASK)
2379 #define lock_ownerstr_hashval(x, clientid, ownername) \
2380         ((file_hashval(x) + (clientid) + opaque_hashval((ownername.data), (ownername.len))) & LOCK_HASH_MASK)
2381
2382 static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
2383 static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
2384 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
2385
2386 struct nfs4_stateid *
2387 find_stateid(stateid_t *stid, int flags)
2388 {
2389         struct nfs4_stateid *local = NULL;
2390         u32 st_id = stid->si_stateownerid;
2391         u32 f_id = stid->si_fileid;
2392         unsigned int hashval;
2393
2394         dprintk("NFSD: find_stateid flags 0x%x\n",flags);
2395         if ((flags & LOCK_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
2396                 hashval = stateid_hashval(st_id, f_id);
2397                 list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
2398                         if ((local->st_stateid.si_stateownerid == st_id) &&
2399                             (local->st_stateid.si_fileid == f_id))
2400                                 return local;
2401                 }
2402         } 
2403         if ((flags & OPEN_STATE) || (flags & RD_STATE) || (flags & WR_STATE)) {
2404                 hashval = stateid_hashval(st_id, f_id);
2405                 list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
2406                         if ((local->st_stateid.si_stateownerid == st_id) &&
2407                             (local->st_stateid.si_fileid == f_id))
2408                                 return local;
2409                 }
2410         } else
2411                 printk("NFSD: find_stateid: ERROR: no state flag\n");
2412         return NULL;
2413 }
2414
2415 static struct nfs4_delegation *
2416 find_delegation_stateid(struct inode *ino, stateid_t *stid)
2417 {
2418         struct nfs4_delegation *dp = NULL;
2419         struct nfs4_file *fp = NULL;
2420         u32 st_id;
2421         unsigned int fi_hashval;
2422
2423         dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
2424                     stid->si_boot, stid->si_stateownerid,
2425                     stid->si_fileid, stid->si_generation);
2426
2427         if(!ino || !stid)
2428                 return NULL;
2429         st_id = stid->si_stateownerid;
2430         fi_hashval = file_hashval(ino);
2431         if (find_file(fi_hashval, ino, &fp)) {
2432                 list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
2433                         if(dp->dl_stateid.si_stateownerid == st_id) {
2434                                 dprintk("NFSD: find_delegation dp %p\n",dp);
2435                                 return dp;
2436                         }
2437                 }
2438         }
2439         return NULL;
2440 }
2441
2442 /*
2443  * TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
2444  * we can't properly handle lock requests that go beyond the (2^63 - 1)-th
2445  * byte, because of sign extension problems.  Since NFSv4 calls for 64-bit
2446  * locking, this prevents us from being completely protocol-compliant.  The
2447  * real solution to this problem is to start using unsigned file offsets in
2448  * the VFS, but this is a very deep change!
2449  */
2450 static inline void
2451 nfs4_transform_lock_offset(struct file_lock *lock)
2452 {
2453         if (lock->fl_start < 0)
2454                 lock->fl_start = OFFSET_MAX;
2455         if (lock->fl_end < 0)
2456                 lock->fl_end = OFFSET_MAX;
2457 }
2458
2459 int
2460 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
2461 {
2462         struct nfs4_stateowner *local = NULL;
2463         int status = 0;
2464                                 
2465         if (hashval >= LOCK_HASH_SIZE)
2466                 goto out;
2467         list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) {
2468                 if (local == sop) {
2469                         status = 1;
2470                         goto out;
2471                 }
2472         }
2473 out:
2474         return status;
2475 }
2476
2477
2478 static inline void
2479 nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
2480 {
2481         struct nfs4_stateowner *sop = (struct nfs4_stateowner *) fl->fl_owner;
2482         unsigned int hval = lockownerid_hashval(sop->so_id);
2483
2484         deny->ld_sop = NULL;
2485         if (nfs4_verify_lock_stateowner(sop, hval)) {
2486                 kref_get(&sop->so_ref);
2487                 deny->ld_sop = sop;
2488                 deny->ld_clientid = sop->so_client->cl_clientid;
2489         }
2490         deny->ld_start = fl->fl_start;
2491         deny->ld_length = ~(u64)0;
2492         if (fl->fl_end != ~(u64)0)
2493                 deny->ld_length = fl->fl_end - fl->fl_start + 1;        
2494         deny->ld_type = NFS4_READ_LT;
2495         if (fl->fl_type != F_RDLCK)
2496                 deny->ld_type = NFS4_WRITE_LT;
2497 }
2498
2499 static struct nfs4_stateowner *
2500 find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
2501 {
2502         struct nfs4_stateowner *local = NULL;
2503         int i;
2504
2505         for (i = 0; i < LOCK_HASH_SIZE; i++) {
2506                 list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
2507                         if (!cmp_owner_str(local, owner, clid))
2508                                 continue;
2509                         return local;
2510                 }
2511         }
2512         return NULL;
2513 }
2514
2515 static int
2516 find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) {
2517         struct nfs4_stateowner *local = NULL;
2518
2519         list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) {
2520                 if (!cmp_owner_str(local, owner, clid))
2521                         continue;
2522                 *op = local;
2523                 return(1);
2524         }
2525         *op = NULL;
2526         return 0;
2527 }
2528
2529 /*
2530  * Alloc a lock owner structure.
2531  * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has 
2532  * occured. 
2533  *
2534  * strhashval = lock_ownerstr_hashval 
2535  * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode 
2536  */
2537
2538 static struct nfs4_stateowner *
2539 alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
2540         struct nfs4_stateowner *sop;
2541         struct nfs4_replay *rp;
2542         unsigned int idhashval;
2543
2544         if (!(sop = alloc_stateowner(&lock->lk_new_owner)))
2545                 return NULL;
2546         idhashval = lockownerid_hashval(current_ownerid);
2547         INIT_LIST_HEAD(&sop->so_idhash);
2548         INIT_LIST_HEAD(&sop->so_strhash);
2549         INIT_LIST_HEAD(&sop->so_perclient);
2550         INIT_LIST_HEAD(&sop->so_perfilestate);
2551         INIT_LIST_HEAD(&sop->so_perlockowner);
2552         INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
2553         sop->so_time = 0;
2554         list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
2555         list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
2556         list_add(&sop->so_perclient, &clp->cl_perclient);
2557         list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
2558         add_perclient++;
2559         sop->so_is_open_owner = 0;
2560         sop->so_id = current_ownerid++;
2561         sop->so_client = clp;
2562         sop->so_seqid = lock->lk_new_lock_seqid - 1;
2563         sop->so_confirmed = 1;
2564         rp = &sop->so_replay;
2565         rp->rp_status = NFSERR_SERVERFAULT;
2566         rp->rp_buflen = 0;
2567         rp->rp_buf = rp->rp_ibuf;
2568         alloc_lsowner++;
2569         return sop;
2570 }
2571
2572 struct nfs4_stateid *
2573 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
2574 {
2575         struct nfs4_stateid *stp;
2576         unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
2577
2578         if ((stp = kmalloc(sizeof(struct nfs4_stateid), 
2579                                         GFP_KERNEL)) == NULL)
2580                 goto out;
2581         INIT_LIST_HEAD(&stp->st_hash);
2582         INIT_LIST_HEAD(&stp->st_perfile);
2583         INIT_LIST_HEAD(&stp->st_perfilestate);
2584         INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
2585         list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
2586         list_add(&stp->st_perfile, &fp->fi_perfile);
2587         list_add_perfile++;
2588         list_add(&stp->st_perfilestate, &sop->so_perfilestate);
2589         stp->st_stateowner = sop;
2590         stp->st_file = fp;
2591         stp->st_stateid.si_boot = boot_time;
2592         stp->st_stateid.si_stateownerid = sop->so_id;
2593         stp->st_stateid.si_fileid = fp->fi_id;
2594         stp->st_stateid.si_generation = 0;
2595         stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
2596         stp->st_vfs_set = open_stp->st_vfs_set;
2597         stp->st_access_bmap = open_stp->st_access_bmap;
2598         stp->st_deny_bmap = open_stp->st_deny_bmap;
2599
2600 out:
2601         return stp;
2602 }
2603
2604 int
2605 check_lock_length(u64 offset, u64 length)
2606 {
2607         return ((length == 0)  || ((length != ~(u64)0) &&
2608              LOFF_OVERFLOW(offset, length)));
2609 }
2610
2611 /*
2612  *  LOCK operation 
2613  */
2614 int
2615 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
2616 {
2617         struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
2618         struct nfs4_stateid *lock_stp;
2619         struct file *filp;
2620         struct file_lock file_lock;
2621         struct file_lock *conflock;
2622         int status = 0;
2623         unsigned int strhashval;
2624
2625         dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
2626                 (long long) lock->lk_offset,
2627                 (long long) lock->lk_length);
2628
2629         if (nfs4_in_grace() && !lock->lk_reclaim)
2630                 return nfserr_grace;
2631         if (!nfs4_in_grace() && lock->lk_reclaim)
2632                 return nfserr_no_grace;
2633
2634         if (check_lock_length(lock->lk_offset, lock->lk_length))
2635                  return nfserr_inval;
2636
2637         nfs4_lock_state();
2638
2639         if (lock->lk_is_new) {
2640         /*
2641          * Client indicates that this is a new lockowner.
2642          * Use open owner and open stateid to create lock owner and lock 
2643          * stateid.
2644          */
2645                 struct nfs4_stateid *open_stp = NULL;
2646                 struct nfs4_file *fp;
2647                 
2648                 status = nfserr_stale_clientid;
2649                 if (STALE_CLIENTID(&lock->lk_new_clientid)) {
2650                         printk("NFSD: nfsd4_lock: clientid is stale!\n");
2651                         goto out;
2652                 }
2653
2654                 /* is the new lock seqid presented by the client zero? */
2655                 status = nfserr_bad_seqid;
2656                 if (lock->v.new.lock_seqid != 0)
2657                         goto out;
2658
2659                 /* validate and update open stateid and open seqid */
2660                 status = nfs4_preprocess_seqid_op(current_fh, 
2661                                         lock->lk_new_open_seqid,
2662                                         &lock->lk_new_open_stateid,
2663                                         CHECK_FH | OPEN_STATE,
2664                                         &open_sop, &open_stp,
2665                                         &lock->v.new.clientid);
2666                 if (status) {
2667                         if (lock->lk_reclaim)
2668                                 status = nfserr_reclaim_bad;
2669                         goto out;
2670                 }
2671                 /* create lockowner and lock stateid */
2672                 fp = open_stp->st_file;
2673                 strhashval = lock_ownerstr_hashval(fp->fi_inode, 
2674                                 open_sop->so_client->cl_clientid.cl_id, 
2675                                 lock->v.new.owner);
2676                 /* 
2677                  * If we already have this lock owner, the client is in 
2678                  * error (or our bookeeping is wrong!) 
2679                  * for asking for a 'new lock'.
2680                  */
2681                 status = nfserr_bad_stateid;
2682                 lock_sop = find_lockstateowner(&lock->v.new.owner,
2683                                                 &lock->v.new.clientid);
2684                 if (lock_sop)
2685                         goto out;
2686                 status = nfserr_resource;
2687                 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2688                         goto out;
2689                 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 
2690                                                 fp, open_stp)) == NULL) {
2691                         release_stateowner(lock->lk_stateowner);
2692                         lock->lk_stateowner = NULL;
2693                         goto out;
2694                 }
2695                 /* bump the open seqid used to create the lock */
2696                 open_sop->so_seqid++;
2697         } else {
2698                 /* lock (lock owner + lock stateid) already exists */
2699                 status = nfs4_preprocess_seqid_op(current_fh,
2700                                        lock->lk_old_lock_seqid, 
2701                                        &lock->lk_old_lock_stateid, 
2702                                        CHECK_FH | LOCK_STATE, 
2703                                        &lock->lk_stateowner, &lock_stp, NULL);
2704                 if (status)
2705                         goto out;
2706         }
2707         /* lock->lk_stateowner and lock_stp have been created or found */
2708         filp = lock_stp->st_vfs_file;
2709
2710         if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
2711                 printk("NFSD: nfsd4_lock: permission denied!\n");
2712                 goto out;
2713         }
2714
2715         locks_init_lock(&file_lock);
2716         switch (lock->lk_type) {
2717                 case NFS4_READ_LT:
2718                 case NFS4_READW_LT:
2719                         file_lock.fl_type = F_RDLCK;
2720                 break;
2721                 case NFS4_WRITE_LT:
2722                 case NFS4_WRITEW_LT:
2723                         file_lock.fl_type = F_WRLCK;
2724                 break;
2725                 default:
2726                         status = nfserr_inval;
2727                 goto out;
2728         }
2729         file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
2730         file_lock.fl_pid = current->tgid;
2731         file_lock.fl_file = filp;
2732         file_lock.fl_flags = FL_POSIX;
2733
2734         file_lock.fl_start = lock->lk_offset;
2735         if ((lock->lk_length == ~(u64)0) || 
2736                         LOFF_OVERFLOW(lock->lk_offset, lock->lk_length))
2737                 file_lock.fl_end = ~(u64)0;
2738         else
2739                 file_lock.fl_end = lock->lk_offset + lock->lk_length - 1;
2740         nfs4_transform_lock_offset(&file_lock);
2741
2742         /*
2743         * Try to lock the file in the VFS.
2744         * Note: locks.c uses the BKL to protect the inode's lock list.
2745         */
2746
2747         status = posix_lock_file(filp, &file_lock);
2748         if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
2749                 file_lock.fl_ops->fl_release_private(&file_lock);
2750         dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status);
2751         switch (-status) {
2752         case 0: /* success! */
2753                 update_stateid(&lock_stp->st_stateid);
2754                 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 
2755                                 sizeof(stateid_t));
2756                 goto out;
2757         case (EAGAIN):
2758                 goto conflicting_lock;
2759         case (EDEADLK):
2760                 status = nfserr_deadlock;
2761         default:        
2762                 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
2763                 goto out_destroy_new_stateid;
2764         }
2765
2766 conflicting_lock:
2767         dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2768         status = nfserr_denied;
2769         /* XXX There is a race here. Future patch needed to provide 
2770          * an atomic posix_lock_and_test_file
2771          */
2772         if (!(conflock = posix_test_lock(filp, &file_lock))) {
2773                 status = nfserr_serverfault;
2774                 goto out;
2775         }
2776         nfs4_set_lock_denied(conflock, &lock->lk_denied);
2777
2778 out_destroy_new_stateid:
2779         if (lock->lk_is_new) {
2780                 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2781         /*
2782         * An error encountered after instantiation of the new
2783         * stateid has forced us to destroy it.
2784         */
2785                 if (!seqid_mutating_err(status))
2786                         open_sop->so_seqid--;
2787
2788                 release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE);
2789         }
2790 out:
2791         if (lock->lk_stateowner)
2792                 nfs4_get_stateowner(lock->lk_stateowner);
2793         nfs4_unlock_state();
2794         return status;
2795 }
2796
2797 /*
2798  * LOCKT operation
2799  */
2800 int
2801 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
2802 {
2803         struct inode *inode;
2804         struct file file;
2805         struct file_lock file_lock;
2806         struct file_lock *conflicting_lock;
2807         unsigned int strhashval;
2808         int status;
2809
2810         if (nfs4_in_grace())
2811                 return nfserr_grace;
2812
2813         if (check_lock_length(lockt->lt_offset, lockt->lt_length))
2814                  return nfserr_inval;
2815
2816         lockt->lt_stateowner = NULL;
2817         nfs4_lock_state();
2818
2819         status = nfserr_stale_clientid;
2820         if (STALE_CLIENTID(&lockt->lt_clientid)) {
2821                 printk("NFSD: nfsd4_lockt: clientid is stale!\n");
2822                 goto out;
2823         }
2824
2825         if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
2826                 printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
2827                 if (status == nfserr_symlink)
2828                         status = nfserr_inval;
2829                 goto out;
2830         }
2831
2832         inode = current_fh->fh_dentry->d_inode;
2833         locks_init_lock(&file_lock);
2834         switch (lockt->lt_type) {
2835                 case NFS4_READ_LT:
2836                 case NFS4_READW_LT:
2837                         file_lock.fl_type = F_RDLCK;
2838                 break;
2839                 case NFS4_WRITE_LT:
2840                 case NFS4_WRITEW_LT:
2841                         file_lock.fl_type = F_WRLCK;
2842                 break;
2843                 default:
2844                         printk("NFSD: nfs4_lockt: bad lock type!\n");
2845                         status = nfserr_inval;
2846                 goto out;
2847         }
2848
2849         strhashval = lock_ownerstr_hashval(inode, 
2850                         lockt->lt_clientid.cl_id, lockt->lt_owner);
2851
2852         find_lockstateowner_str(strhashval, &lockt->lt_owner,
2853                                         &lockt->lt_clientid, 
2854                                         &lockt->lt_stateowner);
2855         if (lockt->lt_stateowner)
2856                 file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner;
2857         file_lock.fl_pid = current->tgid;
2858         file_lock.fl_flags = FL_POSIX;
2859
2860         file_lock.fl_start = lockt->lt_offset;
2861         if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length))
2862                 file_lock.fl_end = ~(u64)0;
2863         else
2864                 file_lock.fl_end = lockt->lt_offset + lockt->lt_length - 1;
2865
2866         nfs4_transform_lock_offset(&file_lock);
2867
2868         /* posix_test_lock uses the struct file _only_ to resolve the inode.
2869          * since LOCKT doesn't require an OPEN, and therefore a struct
2870          * file may not exist, pass posix_test_lock a struct file with
2871          * only the dentry:inode set.
2872          */
2873         memset(&file, 0, sizeof (struct file));
2874         file.f_dentry = current_fh->fh_dentry;
2875
2876         status = nfs_ok;
2877         conflicting_lock = posix_test_lock(&file, &file_lock);
2878         if (conflicting_lock) {
2879                 status = nfserr_denied;
2880                 nfs4_set_lock_denied(conflicting_lock, &lockt->lt_denied);
2881         }
2882 out:
2883         nfs4_unlock_state();
2884         return status;
2885 }
2886
2887 int
2888 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
2889 {
2890         struct nfs4_stateid *stp;
2891         struct file *filp = NULL;
2892         struct file_lock file_lock;
2893         int status;
2894                                                         
2895         dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
2896                 (long long) locku->lu_offset,
2897                 (long long) locku->lu_length);
2898
2899         if (check_lock_length(locku->lu_offset, locku->lu_length))
2900                  return nfserr_inval;
2901
2902         nfs4_lock_state();
2903                                                                                 
2904         if ((status = nfs4_preprocess_seqid_op(current_fh, 
2905                                         locku->lu_seqid, 
2906                                         &locku->lu_stateid, 
2907                                         CHECK_FH | LOCK_STATE, 
2908                                         &locku->lu_stateowner, &stp, NULL)))
2909                 goto out;
2910
2911         filp = stp->st_vfs_file;
2912         BUG_ON(!filp);
2913         locks_init_lock(&file_lock);
2914         file_lock.fl_type = F_UNLCK;
2915         file_lock.fl_owner = (fl_owner_t) locku->lu_stateowner;
2916         file_lock.fl_pid = current->tgid;
2917         file_lock.fl_file = filp;
2918         file_lock.fl_flags = FL_POSIX; 
2919         file_lock.fl_start = locku->lu_offset;
2920
2921         if ((locku->lu_length == ~(u64)0) || LOFF_OVERFLOW(locku->lu_offset, locku->lu_length))
2922                 file_lock.fl_end = ~(u64)0;
2923         else
2924                 file_lock.fl_end = locku->lu_offset + locku->lu_length - 1;
2925         nfs4_transform_lock_offset(&file_lock);
2926
2927         /*
2928         *  Try to unlock the file in the VFS.
2929         */
2930         status = posix_lock_file(filp, &file_lock); 
2931         if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
2932                 file_lock.fl_ops->fl_release_private(&file_lock);
2933         if (status) {
2934                 printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
2935                 goto out_nfserr;
2936         }
2937         /*
2938         * OK, unlock succeeded; the only thing left to do is update the stateid.
2939         */
2940         update_stateid(&stp->st_stateid);
2941         memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
2942
2943 out:
2944         if (locku->lu_stateowner)
2945                 nfs4_get_stateowner(locku->lu_stateowner);
2946         nfs4_unlock_state();
2947         return status;
2948
2949 out_nfserr:
2950         status = nfserrno(status);
2951         goto out;
2952 }
2953
2954 /*
2955  * returns
2956  *      1: locks held by lockowner
2957  *      0: no locks held by lockowner
2958  */
2959 static int
2960 check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
2961 {
2962         struct file_lock **flpp;
2963         struct inode *inode = filp->f_dentry->d_inode;
2964         int status = 0;
2965
2966         lock_kernel();
2967         for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
2968                 if ((*flpp)->fl_owner == (fl_owner_t)lowner)
2969                         status = 1;
2970                         goto out;
2971         }
2972 out:
2973         unlock_kernel();
2974         return status;
2975 }
2976
2977 int
2978 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2979 {
2980         clientid_t *clid = &rlockowner->rl_clientid;
2981         struct nfs4_stateowner *local = NULL;
2982         struct xdr_netobj *owner = &rlockowner->rl_owner;
2983         int status;
2984
2985         dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
2986                 clid->cl_boot, clid->cl_id);
2987
2988         /* XXX check for lease expiration */
2989
2990         status = nfserr_stale_clientid;
2991         if (STALE_CLIENTID(clid)) {
2992                 printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
2993                 return status;
2994         }
2995
2996         nfs4_lock_state();
2997
2998         status = nfs_ok;
2999         local = find_lockstateowner(owner, clid);
3000         if (local) {
3001                 struct nfs4_stateid *stp;
3002
3003                 /* check for any locks held by any stateid
3004                  * associated with the (lock) stateowner */
3005                 status = nfserr_locks_held;
3006                 list_for_each_entry(stp, &local->so_perfilestate,
3007                                 st_perfilestate) {
3008                         if (stp->st_vfs_set) {
3009                                 if (check_for_locks(stp->st_vfs_file, local))
3010                                         goto out;
3011                         }
3012                 }
3013                 /* no locks held by (lock) stateowner */
3014                 status = nfs_ok;
3015                 release_stateowner(local);
3016         }
3017 out:
3018         nfs4_unlock_state();
3019         return status;
3020 }
3021
3022 static inline struct nfs4_client_reclaim *
3023 alloc_reclaim(int namelen)
3024 {
3025         struct nfs4_client_reclaim *crp = NULL;
3026
3027         crp = kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
3028         if (!crp)
3029                 return NULL;
3030         crp->cr_name.data = kmalloc(namelen, GFP_KERNEL);
3031         if (!crp->cr_name.data) {
3032                 kfree(crp);
3033                 return NULL;
3034         }
3035         return crp;
3036 }
3037
3038 /*
3039  * failure => all reset bets are off, nfserr_no_grace...
3040  */
3041 static int
3042 nfs4_client_to_reclaim(struct nfs4_client *clp)
3043 {
3044         unsigned int strhashval;
3045         struct nfs4_client_reclaim *crp = NULL;
3046
3047         crp = alloc_reclaim(clp->cl_name.len);
3048         if (!crp)
3049                 return 0;
3050         strhashval = clientstr_hashval(clp->cl_name.data, clp->cl_name.len);
3051         INIT_LIST_HEAD(&crp->cr_strhash);
3052         list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
3053         memcpy(crp->cr_name.data, clp->cl_name.data, clp->cl_name.len);
3054         crp->cr_name.len = clp->cl_name.len;
3055         crp->cr_first_state = clp->cl_first_state;
3056         crp->cr_expired = 0;
3057         return 1;
3058 }
3059
3060 static void
3061 nfs4_release_reclaim(void)
3062 {
3063         struct nfs4_client_reclaim *crp = NULL;
3064         int i;
3065
3066         BUG_ON(!nfs4_reclaim_init);
3067         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3068                 while (!list_empty(&reclaim_str_hashtbl[i])) {
3069                         crp = list_entry(reclaim_str_hashtbl[i].next,
3070                                         struct nfs4_client_reclaim, cr_strhash);
3071                         list_del(&crp->cr_strhash);
3072                         kfree(crp->cr_name.data);
3073                         kfree(crp);
3074                         reclaim_str_hashtbl_size--;
3075                 }
3076         }
3077         BUG_ON(reclaim_str_hashtbl_size);
3078 }
3079
3080 /*
3081  * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
3082 struct nfs4_client_reclaim *
3083 nfs4_find_reclaim_client(clientid_t *clid)
3084 {
3085         unsigned int idhashval = clientid_hashval(clid->cl_id);
3086         unsigned int strhashval;
3087         struct nfs4_client *clp, *client = NULL;
3088         struct nfs4_client_reclaim *crp = NULL;
3089
3090
3091         /* find clientid in conf_id_hashtbl */
3092         list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
3093                 if (cmp_clid(&clp->cl_clientid, clid)) {
3094                         client = clp;
3095                         break;
3096                 }
3097         }
3098         if (!client)
3099                 return NULL;
3100
3101         /* find clp->cl_name in reclaim_str_hashtbl */
3102         strhashval = clientstr_hashval(client->cl_name.data,
3103                                       client->cl_name.len);
3104         list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
3105                 if (cmp_name(&crp->cr_name, &client->cl_name)) {
3106                         return crp;
3107                 }
3108         }
3109         return NULL;
3110 }
3111
3112 /*
3113 * Called from OPEN. Look for clientid in reclaim list.
3114 */
3115 int
3116 nfs4_check_open_reclaim(clientid_t *clid)
3117 {
3118         struct nfs4_client_reclaim *crp;
3119
3120         if ((crp = nfs4_find_reclaim_client(clid)) == NULL)
3121                 return nfserr_reclaim_bad;
3122         if (crp->cr_expired)
3123                 return nfserr_no_grace;
3124         return nfs_ok;
3125 }
3126
3127
3128 /* 
3129  * Start and stop routines
3130  */
3131
3132 void 
3133 nfs4_state_init(void)
3134 {
3135         int i;
3136         time_t grace_time;
3137
3138         if (nfs4_init)
3139                 return;
3140         if (!nfs4_reclaim_init) {
3141                 for (i = 0; i < CLIENT_HASH_SIZE; i++)
3142                         INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
3143                 reclaim_str_hashtbl_size = 0;
3144                 nfs4_reclaim_init = 1;
3145         }
3146         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3147                 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
3148                 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
3149                 INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
3150                 INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
3151         }
3152         for (i = 0; i < FILE_HASH_SIZE; i++) {
3153                 INIT_LIST_HEAD(&file_hashtbl[i]);
3154         }
3155         for (i = 0; i < OWNER_HASH_SIZE; i++) {
3156                 INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
3157                 INIT_LIST_HEAD(&ownerid_hashtbl[i]);
3158         }
3159         for (i = 0; i < STATEID_HASH_SIZE; i++) {
3160                 INIT_LIST_HEAD(&stateid_hashtbl[i]);
3161                 INIT_LIST_HEAD(&lockstateid_hashtbl[i]);
3162         }
3163         for (i = 0; i < LOCK_HASH_SIZE; i++) {
3164                 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
3165                 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
3166         }
3167         memset(&zerostateid, 0, sizeof(stateid_t));
3168         memset(&onestateid, ~0, sizeof(stateid_t));
3169
3170         INIT_LIST_HEAD(&close_lru);
3171         INIT_LIST_HEAD(&client_lru);
3172         INIT_LIST_HEAD(&del_recall_lru);
3173         spin_lock_init(&recall_lock);
3174         boot_time = get_seconds();
3175         grace_time = max(old_lease_time, lease_time);
3176         if (reclaim_str_hashtbl_size == 0)
3177                 grace_time = 0;
3178         if (grace_time)
3179                 printk("NFSD: starting %ld-second grace period\n", grace_time);
3180         grace_end = boot_time + grace_time;
3181         INIT_WORK(&laundromat_work,laundromat_main, NULL);
3182         schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
3183         nfs4_init = 1;
3184 }
3185
3186 int
3187 nfs4_in_grace(void)
3188 {
3189         return get_seconds() < grace_end;
3190 }
3191
3192 void
3193 set_no_grace(void)
3194 {
3195         printk("NFSD: ERROR in reboot recovery.  State reclaims will fail.\n");
3196         grace_end = get_seconds();
3197 }
3198
3199 time_t
3200 nfs4_lease_time(void)
3201 {
3202         return lease_time;
3203 }
3204
3205 static void
3206 __nfs4_state_shutdown(void)
3207 {
3208         int i;
3209         struct nfs4_client *clp = NULL;
3210         struct nfs4_delegation *dp = NULL;
3211         struct list_head *pos, *next;
3212
3213         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3214                 while (!list_empty(&conf_id_hashtbl[i])) {
3215                         clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
3216                         expire_client(clp);
3217                 }
3218                 while (!list_empty(&unconf_str_hashtbl[i])) {
3219                         clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
3220                         expire_client(clp);
3221                 }
3222         }
3223         spin_lock(&recall_lock);
3224         list_for_each_safe(pos, next, &del_recall_lru) {
3225                 dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
3226                 atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
3227                 release_delegation(dp);
3228         }
3229         spin_unlock(&recall_lock);
3230
3231         release_all_files();
3232         cancel_delayed_work(&laundromat_work);
3233         flush_scheduled_work();
3234         nfs4_init = 0;
3235         dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
3236                         list_add_perfile, list_del_perfile);
3237         dprintk("NFSD: add_perclient %d del_perclient %d\n",
3238                         add_perclient, del_perclient);
3239         dprintk("NFSD: alloc_file %d free_file %d\n",
3240                         alloc_file, free_file);
3241         dprintk("NFSD: alloc_sowner %d alloc_lsowner %d free_sowner %d\n",
3242                         alloc_sowner, alloc_lsowner, free_sowner);
3243         dprintk("NFSD: vfsopen %d vfsclose %d\n",
3244                         vfsopen, vfsclose);
3245         dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
3246                         alloc_delegation, free_delegation);
3247
3248 }
3249
3250 void
3251 nfs4_state_shutdown(void)
3252 {
3253         nfs4_lock_state();
3254         nfs4_release_reclaim();
3255         __nfs4_state_shutdown();
3256         nfs4_unlock_state();
3257 }
3258
3259 /*
3260  * Called when leasetime is changed.
3261  *
3262  * if nfsd is not started, simply set the global lease.
3263  *
3264  * if nfsd(s) are running, lease change requires nfsv4 state to be reset.
3265  * e.g: boot_time is reset, existing nfs4_client structs are
3266  * used to fill reclaim_str_hashtbl, then all state (except for the
3267  * reclaim_str_hashtbl) is re-initialized.
3268  *
3269  * if the old lease time is greater than the new lease time, the grace
3270  * period needs to be set to the old lease time to allow clients to reclaim
3271  * their state. XXX - we may want to set the grace period == lease time
3272  * after an initial grace period == old lease time
3273  *
3274  * if an error occurs in this process, the new lease is set, but the server
3275  * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
3276  * which means OPEN/LOCK/READ/WRITE will fail during grace period.
3277  *
3278  * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
3279  * OPEN and LOCK reclaims.
3280  */
3281 void
3282 nfs4_reset_lease(time_t leasetime)
3283 {
3284         struct nfs4_client *clp;
3285         int i;
3286
3287         printk("NFSD: New leasetime %ld\n",leasetime);
3288         if (!nfs4_init)
3289                 return;
3290         nfs4_lock_state();
3291         old_lease_time = lease_time;
3292         lease_time = leasetime;
3293
3294         nfs4_release_reclaim();
3295
3296         /* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
3297         for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3298                 list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
3299                         if (!nfs4_client_to_reclaim(clp)) {
3300                                 nfs4_release_reclaim();
3301                                 goto init_state;
3302                         }
3303                         reclaim_str_hashtbl_size++;
3304                 }
3305         }
3306 init_state:
3307         __nfs4_state_shutdown();
3308         nfs4_state_init();
3309         nfs4_unlock_state();
3310 }
3311