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