1
2
3
4
5
6
7
8
9#include <linux/completion.h>
10#include <linux/kthread.h>
11#include <linux/module.h>
12#include <linux/sched.h>
13#include <linux/slab.h>
14#include <linux/spinlock.h>
15#include <linux/iversion.h>
16
17#include <linux/nfs4.h>
18#include <linux/nfs_fs.h>
19#include <linux/nfs_xdr.h>
20
21#include "nfs4_fs.h"
22#include "nfs4session.h"
23#include "delegation.h"
24#include "internal.h"
25#include "nfs4trace.h"
26
27static void nfs_free_delegation(struct nfs_delegation *delegation)
28{
29 put_cred(delegation->cred);
30 delegation->cred = NULL;
31 kfree_rcu(delegation, rcu);
32}
33
34
35
36
37
38
39void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
40{
41 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
42}
43
44static bool
45nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
46 fmode_t flags)
47{
48 if (delegation != NULL && (delegation->type & flags) == flags &&
49 !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
50 !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
51 return true;
52 return false;
53}
54
55static int
56nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
57{
58 struct nfs_delegation *delegation;
59 int ret = 0;
60
61 flags &= FMODE_READ|FMODE_WRITE;
62 rcu_read_lock();
63 delegation = rcu_dereference(NFS_I(inode)->delegation);
64 if (nfs4_is_valid_delegation(delegation, flags)) {
65 if (mark)
66 nfs_mark_delegation_referenced(delegation);
67 ret = 1;
68 }
69 rcu_read_unlock();
70 return ret;
71}
72
73
74
75
76
77
78
79
80int nfs4_have_delegation(struct inode *inode, fmode_t flags)
81{
82 return nfs4_do_check_delegation(inode, flags, true);
83}
84
85
86
87
88
89int nfs4_check_delegation(struct inode *inode, fmode_t flags)
90{
91 return nfs4_do_check_delegation(inode, flags, false);
92}
93
94static int nfs_delegation_claim_locks(struct nfs4_state *state, const nfs4_stateid *stateid)
95{
96 struct inode *inode = state->inode;
97 struct file_lock *fl;
98 struct file_lock_context *flctx = inode->i_flctx;
99 struct list_head *list;
100 int status = 0;
101
102 if (flctx == NULL)
103 goto out;
104
105 list = &flctx->flc_posix;
106 spin_lock(&flctx->flc_lock);
107restart:
108 list_for_each_entry(fl, list, fl_list) {
109 if (nfs_file_open_context(fl->fl_file)->state != state)
110 continue;
111 spin_unlock(&flctx->flc_lock);
112 status = nfs4_lock_delegation_recall(fl, state, stateid);
113 if (status < 0)
114 goto out;
115 spin_lock(&flctx->flc_lock);
116 }
117 if (list == &flctx->flc_posix) {
118 list = &flctx->flc_flock;
119 goto restart;
120 }
121 spin_unlock(&flctx->flc_lock);
122out:
123 return status;
124}
125
126static int nfs_delegation_claim_opens(struct inode *inode,
127 const nfs4_stateid *stateid, fmode_t type)
128{
129 struct nfs_inode *nfsi = NFS_I(inode);
130 struct nfs_open_context *ctx;
131 struct nfs4_state_owner *sp;
132 struct nfs4_state *state;
133 unsigned int seq;
134 int err;
135
136again:
137 rcu_read_lock();
138 list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
139 state = ctx->state;
140 if (state == NULL)
141 continue;
142 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
143 continue;
144 if (!nfs4_valid_open_stateid(state))
145 continue;
146 if (!nfs4_stateid_match(&state->stateid, stateid))
147 continue;
148 if (!get_nfs_open_context(ctx))
149 continue;
150 rcu_read_unlock();
151 sp = state->owner;
152
153 mutex_lock(&sp->so_delegreturn_mutex);
154 seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
155 err = nfs4_open_delegation_recall(ctx, state, stateid, type);
156 if (!err)
157 err = nfs_delegation_claim_locks(state, stateid);
158 if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
159 err = -EAGAIN;
160 mutex_unlock(&sp->so_delegreturn_mutex);
161 put_nfs_open_context(ctx);
162 if (err != 0)
163 return err;
164 goto again;
165 }
166 rcu_read_unlock();
167 return 0;
168}
169
170
171
172
173
174
175
176
177
178
179void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
180 fmode_t type,
181 const nfs4_stateid *stateid,
182 unsigned long pagemod_limit)
183{
184 struct nfs_delegation *delegation;
185 const struct cred *oldcred = NULL;
186
187 rcu_read_lock();
188 delegation = rcu_dereference(NFS_I(inode)->delegation);
189 if (delegation != NULL) {
190 spin_lock(&delegation->lock);
191 if (delegation->inode != NULL) {
192 nfs4_stateid_copy(&delegation->stateid, stateid);
193 delegation->type = type;
194 delegation->pagemod_limit = pagemod_limit;
195 oldcred = delegation->cred;
196 delegation->cred = get_cred(cred);
197 clear_bit(NFS_DELEGATION_NEED_RECLAIM,
198 &delegation->flags);
199 spin_unlock(&delegation->lock);
200 rcu_read_unlock();
201 put_cred(oldcred);
202 trace_nfs4_reclaim_delegation(inode, type);
203 return;
204 }
205
206 spin_unlock(&delegation->lock);
207 }
208 rcu_read_unlock();
209 nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit);
210}
211
212static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
213{
214 int res = 0;
215
216 if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
217 res = nfs4_proc_delegreturn(inode,
218 delegation->cred,
219 &delegation->stateid,
220 issync);
221 nfs_free_delegation(delegation);
222 return res;
223}
224
225static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
226{
227 struct inode *inode = NULL;
228
229 spin_lock(&delegation->lock);
230 if (delegation->inode != NULL)
231 inode = igrab(delegation->inode);
232 spin_unlock(&delegation->lock);
233 return inode;
234}
235
236static struct nfs_delegation *
237nfs_start_delegation_return_locked(struct nfs_inode *nfsi)
238{
239 struct nfs_delegation *ret = NULL;
240 struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
241
242 if (delegation == NULL)
243 goto out;
244 spin_lock(&delegation->lock);
245 if (!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
246 ret = delegation;
247 spin_unlock(&delegation->lock);
248out:
249 return ret;
250}
251
252static struct nfs_delegation *
253nfs_start_delegation_return(struct nfs_inode *nfsi)
254{
255 struct nfs_delegation *delegation;
256
257 rcu_read_lock();
258 delegation = nfs_start_delegation_return_locked(nfsi);
259 rcu_read_unlock();
260 return delegation;
261}
262
263static void
264nfs_abort_delegation_return(struct nfs_delegation *delegation,
265 struct nfs_client *clp)
266{
267
268 spin_lock(&delegation->lock);
269 clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
270 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
271 spin_unlock(&delegation->lock);
272 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
273}
274
275static struct nfs_delegation *
276nfs_detach_delegation_locked(struct nfs_inode *nfsi,
277 struct nfs_delegation *delegation,
278 struct nfs_client *clp)
279{
280 struct nfs_delegation *deleg_cur =
281 rcu_dereference_protected(nfsi->delegation,
282 lockdep_is_held(&clp->cl_lock));
283
284 if (deleg_cur == NULL || delegation != deleg_cur)
285 return NULL;
286
287 spin_lock(&delegation->lock);
288 set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
289 list_del_rcu(&delegation->super_list);
290 delegation->inode = NULL;
291 rcu_assign_pointer(nfsi->delegation, NULL);
292 spin_unlock(&delegation->lock);
293 return delegation;
294}
295
296static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
297 struct nfs_delegation *delegation,
298 struct nfs_server *server)
299{
300 struct nfs_client *clp = server->nfs_client;
301
302 spin_lock(&clp->cl_lock);
303 delegation = nfs_detach_delegation_locked(nfsi, delegation, clp);
304 spin_unlock(&clp->cl_lock);
305 return delegation;
306}
307
308static struct nfs_delegation *
309nfs_inode_detach_delegation(struct inode *inode)
310{
311 struct nfs_inode *nfsi = NFS_I(inode);
312 struct nfs_server *server = NFS_SERVER(inode);
313 struct nfs_delegation *delegation;
314
315 delegation = nfs_start_delegation_return(nfsi);
316 if (delegation == NULL)
317 return NULL;
318 return nfs_detach_delegation(nfsi, delegation, server);
319}
320
321static void
322nfs_update_inplace_delegation(struct nfs_delegation *delegation,
323 const struct nfs_delegation *update)
324{
325 if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) {
326 delegation->stateid.seqid = update->stateid.seqid;
327 smp_wmb();
328 delegation->type = update->type;
329 }
330}
331
332
333
334
335
336
337
338
339
340
341
342int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
343 fmode_t type,
344 const nfs4_stateid *stateid,
345 unsigned long pagemod_limit)
346{
347 struct nfs_server *server = NFS_SERVER(inode);
348 struct nfs_client *clp = server->nfs_client;
349 struct nfs_inode *nfsi = NFS_I(inode);
350 struct nfs_delegation *delegation, *old_delegation;
351 struct nfs_delegation *freeme = NULL;
352 int status = 0;
353
354 delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
355 if (delegation == NULL)
356 return -ENOMEM;
357 nfs4_stateid_copy(&delegation->stateid, stateid);
358 delegation->type = type;
359 delegation->pagemod_limit = pagemod_limit;
360 delegation->change_attr = inode_peek_iversion_raw(inode);
361 delegation->cred = get_cred(cred);
362 delegation->inode = inode;
363 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
364 spin_lock_init(&delegation->lock);
365
366 spin_lock(&clp->cl_lock);
367 old_delegation = rcu_dereference_protected(nfsi->delegation,
368 lockdep_is_held(&clp->cl_lock));
369 if (old_delegation != NULL) {
370
371 if (nfs4_stateid_match_other(&old_delegation->stateid,
372 &delegation->stateid)) {
373 nfs_update_inplace_delegation(old_delegation,
374 delegation);
375 goto out;
376 }
377
378
379
380
381
382
383 dfprintk(FILE, "%s: server %s handed out "
384 "a duplicate delegation!\n",
385 __func__, clp->cl_hostname);
386 if (delegation->type == old_delegation->type ||
387 !(delegation->type & FMODE_WRITE)) {
388 freeme = delegation;
389 delegation = NULL;
390 goto out;
391 }
392 if (test_and_set_bit(NFS_DELEGATION_RETURNING,
393 &old_delegation->flags))
394 goto out;
395 freeme = nfs_detach_delegation_locked(nfsi,
396 old_delegation, clp);
397 if (freeme == NULL)
398 goto out;
399 }
400 list_add_tail_rcu(&delegation->super_list, &server->delegations);
401 rcu_assign_pointer(nfsi->delegation, delegation);
402 delegation = NULL;
403
404 trace_nfs4_set_delegation(inode, type);
405
406 spin_lock(&inode->i_lock);
407 if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME))
408 NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED;
409 spin_unlock(&inode->i_lock);
410out:
411 spin_unlock(&clp->cl_lock);
412 if (delegation != NULL)
413 nfs_free_delegation(delegation);
414 if (freeme != NULL)
415 nfs_do_return_delegation(inode, freeme, 0);
416 return status;
417}
418
419
420
421
422static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
423{
424 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
425 struct nfs_inode *nfsi = NFS_I(inode);
426 int err = 0;
427
428 if (delegation == NULL)
429 return 0;
430 do {
431 if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
432 break;
433 err = nfs_delegation_claim_opens(inode, &delegation->stateid,
434 delegation->type);
435 if (!issync || err != -EAGAIN)
436 break;
437
438
439
440 err = nfs4_wait_clnt_recover(clp);
441 } while (err == 0);
442
443 if (err) {
444 nfs_abort_delegation_return(delegation, clp);
445 goto out;
446 }
447 if (!nfs_detach_delegation(nfsi, delegation, NFS_SERVER(inode)))
448 goto out;
449
450 err = nfs_do_return_delegation(inode, delegation, issync);
451out:
452 return err;
453}
454
455static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
456{
457 bool ret = false;
458
459 if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
460 goto out;
461 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
462 ret = true;
463 if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
464 struct inode *inode;
465
466 spin_lock(&delegation->lock);
467 inode = delegation->inode;
468 if (inode && list_empty(&NFS_I(inode)->open_files))
469 ret = true;
470 spin_unlock(&delegation->lock);
471 }
472out:
473 return ret;
474}
475
476
477
478
479
480
481
482
483
484
485
486int nfs_client_return_marked_delegations(struct nfs_client *clp)
487{
488 struct nfs_delegation *delegation;
489 struct nfs_delegation *prev;
490 struct nfs_server *server;
491 struct inode *inode;
492 struct inode *place_holder = NULL;
493 struct nfs_delegation *place_holder_deleg = NULL;
494 int err = 0;
495
496restart:
497
498
499
500
501
502
503
504
505
506
507 rcu_read_lock();
508 prev = NULL;
509 if (place_holder)
510 server = NFS_SERVER(place_holder);
511 else
512 server = list_entry_rcu(clp->cl_superblocks.next,
513 struct nfs_server, client_link);
514 list_for_each_entry_from_rcu(server, &clp->cl_superblocks, client_link) {
515 delegation = NULL;
516 if (place_holder && server == NFS_SERVER(place_holder))
517 delegation = rcu_dereference(NFS_I(place_holder)->delegation);
518 if (!delegation || delegation != place_holder_deleg)
519 delegation = list_entry_rcu(server->delegations.next,
520 struct nfs_delegation, super_list);
521 list_for_each_entry_from_rcu(delegation, &server->delegations, super_list) {
522 struct inode *to_put = NULL;
523
524 if (!nfs_delegation_need_return(delegation)) {
525 prev = delegation;
526 continue;
527 }
528 if (!nfs_sb_active(server->super))
529 break;
530
531 if (prev) {
532 struct inode *tmp;
533
534 tmp = nfs_delegation_grab_inode(prev);
535 if (tmp) {
536 to_put = place_holder;
537 place_holder = tmp;
538 place_holder_deleg = prev;
539 }
540 }
541
542 inode = nfs_delegation_grab_inode(delegation);
543 if (inode == NULL) {
544 rcu_read_unlock();
545 if (to_put)
546 iput(to_put);
547 nfs_sb_deactive(server->super);
548 goto restart;
549 }
550 delegation = nfs_start_delegation_return_locked(NFS_I(inode));
551 rcu_read_unlock();
552
553 if (to_put)
554 iput(to_put);
555
556 err = nfs_end_delegation_return(inode, delegation, 0);
557 iput(inode);
558 nfs_sb_deactive(server->super);
559 cond_resched();
560 if (!err)
561 goto restart;
562 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
563 if (place_holder)
564 iput(place_holder);
565 return err;
566 }
567 }
568 rcu_read_unlock();
569 if (place_holder)
570 iput(place_holder);
571 return 0;
572}
573
574
575
576
577
578
579
580
581void nfs_inode_return_delegation_noreclaim(struct inode *inode)
582{
583 struct nfs_delegation *delegation;
584
585 delegation = nfs_inode_detach_delegation(inode);
586 if (delegation != NULL)
587 nfs_do_return_delegation(inode, delegation, 1);
588}
589
590
591
592
593
594
595
596
597
598
599
600int nfs4_inode_return_delegation(struct inode *inode)
601{
602 struct nfs_inode *nfsi = NFS_I(inode);
603 struct nfs_delegation *delegation;
604 int err = 0;
605
606 nfs_wb_all(inode);
607 delegation = nfs_start_delegation_return(nfsi);
608 if (delegation != NULL)
609 err = nfs_end_delegation_return(inode, delegation, 1);
610 return err;
611}
612
613
614
615
616
617
618
619
620
621int nfs4_inode_make_writeable(struct inode *inode)
622{
623 if (!nfs4_has_session(NFS_SERVER(inode)->nfs_client) ||
624 !nfs4_check_delegation(inode, FMODE_WRITE))
625 return nfs4_inode_return_delegation(inode);
626 return 0;
627}
628
629static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
630 struct nfs_delegation *delegation)
631{
632 set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
633 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
634}
635
636static void nfs_mark_return_delegation(struct nfs_server *server,
637 struct nfs_delegation *delegation)
638{
639 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
640 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
641}
642
643static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
644{
645 struct nfs_delegation *delegation;
646 bool ret = false;
647
648 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
649 nfs_mark_return_delegation(server, delegation);
650 ret = true;
651 }
652 return ret;
653}
654
655static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
656{
657 struct nfs_server *server;
658
659 rcu_read_lock();
660 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
661 nfs_server_mark_return_all_delegations(server);
662 rcu_read_unlock();
663}
664
665static void nfs_delegation_run_state_manager(struct nfs_client *clp)
666{
667 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
668 nfs4_schedule_state_manager(clp);
669}
670
671
672
673
674
675
676void nfs_expire_all_delegations(struct nfs_client *clp)
677{
678 nfs_client_mark_return_all_delegations(clp);
679 nfs_delegation_run_state_manager(clp);
680}
681
682
683
684
685
686
687void nfs_server_return_all_delegations(struct nfs_server *server)
688{
689 struct nfs_client *clp = server->nfs_client;
690 bool need_wait;
691
692 if (clp == NULL)
693 return;
694
695 rcu_read_lock();
696 need_wait = nfs_server_mark_return_all_delegations(server);
697 rcu_read_unlock();
698
699 if (need_wait) {
700 nfs4_schedule_state_manager(clp);
701 nfs4_wait_clnt_recover(clp);
702 }
703}
704
705static void nfs_mark_return_unused_delegation_types(struct nfs_server *server,
706 fmode_t flags)
707{
708 struct nfs_delegation *delegation;
709
710 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
711 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
712 continue;
713 if (delegation->type & flags)
714 nfs_mark_return_if_closed_delegation(server, delegation);
715 }
716}
717
718static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *clp,
719 fmode_t flags)
720{
721 struct nfs_server *server;
722
723 rcu_read_lock();
724 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
725 nfs_mark_return_unused_delegation_types(server, flags);
726 rcu_read_unlock();
727}
728
729static void nfs_mark_delegation_revoked(struct nfs_server *server,
730 struct nfs_delegation *delegation)
731{
732 set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
733 delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
734 nfs_mark_return_delegation(server, delegation);
735}
736
737static bool nfs_revoke_delegation(struct inode *inode,
738 const nfs4_stateid *stateid)
739{
740 struct nfs_delegation *delegation;
741 nfs4_stateid tmp;
742 bool ret = false;
743
744 rcu_read_lock();
745 delegation = rcu_dereference(NFS_I(inode)->delegation);
746 if (delegation == NULL)
747 goto out;
748 if (stateid == NULL) {
749 nfs4_stateid_copy(&tmp, &delegation->stateid);
750 stateid = &tmp;
751 } else if (!nfs4_stateid_match(stateid, &delegation->stateid))
752 goto out;
753 nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
754 ret = true;
755out:
756 rcu_read_unlock();
757 if (ret)
758 nfs_inode_find_state_and_recover(inode, stateid);
759 return ret;
760}
761
762void nfs_remove_bad_delegation(struct inode *inode,
763 const nfs4_stateid *stateid)
764{
765 struct nfs_delegation *delegation;
766
767 if (!nfs_revoke_delegation(inode, stateid))
768 return;
769 delegation = nfs_inode_detach_delegation(inode);
770 if (delegation)
771 nfs_free_delegation(delegation);
772}
773EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
774
775
776
777
778
779
780
781void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags)
782{
783 nfs_client_mark_return_unused_delegation_types(clp, flags);
784 nfs_delegation_run_state_manager(clp);
785}
786
787static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
788{
789 struct nfs_delegation *delegation;
790
791 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
792 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
793 continue;
794 nfs_mark_return_if_closed_delegation(server, delegation);
795 }
796}
797
798
799
800
801
802
803void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
804{
805 struct nfs_server *server;
806
807 rcu_read_lock();
808 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
809 nfs_mark_return_unreferenced_delegations(server);
810 rcu_read_unlock();
811
812 nfs_delegation_run_state_manager(clp);
813}
814
815
816
817
818
819
820
821
822int nfs_async_inode_return_delegation(struct inode *inode,
823 const nfs4_stateid *stateid)
824{
825 struct nfs_server *server = NFS_SERVER(inode);
826 struct nfs_client *clp = server->nfs_client;
827 struct nfs_delegation *delegation;
828
829 rcu_read_lock();
830 delegation = rcu_dereference(NFS_I(inode)->delegation);
831 if (delegation == NULL)
832 goto out_enoent;
833 if (stateid != NULL &&
834 !clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
835 goto out_enoent;
836 nfs_mark_return_delegation(server, delegation);
837 rcu_read_unlock();
838
839 nfs_delegation_run_state_manager(clp);
840 return 0;
841out_enoent:
842 rcu_read_unlock();
843 return -ENOENT;
844}
845
846static struct inode *
847nfs_delegation_find_inode_server(struct nfs_server *server,
848 const struct nfs_fh *fhandle)
849{
850 struct nfs_delegation *delegation;
851 struct inode *freeme, *res = NULL;
852
853 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
854 spin_lock(&delegation->lock);
855 if (delegation->inode != NULL &&
856 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
857 freeme = igrab(delegation->inode);
858 if (freeme && nfs_sb_active(freeme->i_sb))
859 res = freeme;
860 spin_unlock(&delegation->lock);
861 if (res != NULL)
862 return res;
863 if (freeme) {
864 rcu_read_unlock();
865 iput(freeme);
866 rcu_read_lock();
867 }
868 return ERR_PTR(-EAGAIN);
869 }
870 spin_unlock(&delegation->lock);
871 }
872 return ERR_PTR(-ENOENT);
873}
874
875
876
877
878
879
880
881
882
883struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
884 const struct nfs_fh *fhandle)
885{
886 struct nfs_server *server;
887 struct inode *res;
888
889 rcu_read_lock();
890 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
891 res = nfs_delegation_find_inode_server(server, fhandle);
892 if (res != ERR_PTR(-ENOENT)) {
893 rcu_read_unlock();
894 return res;
895 }
896 }
897 rcu_read_unlock();
898 return ERR_PTR(-ENOENT);
899}
900
901static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)
902{
903 struct nfs_delegation *delegation;
904
905 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
906
907
908
909
910 if (test_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags))
911 continue;
912 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
913 }
914}
915
916
917
918
919
920
921void nfs_delegation_mark_reclaim(struct nfs_client *clp)
922{
923 struct nfs_server *server;
924
925 rcu_read_lock();
926 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
927 nfs_delegation_mark_reclaim_server(server);
928 rcu_read_unlock();
929}
930
931
932
933
934
935
936void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
937{
938 struct nfs_delegation *delegation;
939 struct nfs_server *server;
940 struct inode *inode;
941
942restart:
943 rcu_read_lock();
944 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
945 list_for_each_entry_rcu(delegation, &server->delegations,
946 super_list) {
947 if (test_bit(NFS_DELEGATION_RETURNING,
948 &delegation->flags))
949 continue;
950 if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
951 &delegation->flags) == 0)
952 continue;
953 if (!nfs_sb_active(server->super))
954 break;
955 inode = nfs_delegation_grab_inode(delegation);
956 if (inode == NULL) {
957 rcu_read_unlock();
958 nfs_sb_deactive(server->super);
959 goto restart;
960 }
961 delegation = nfs_start_delegation_return_locked(NFS_I(inode));
962 rcu_read_unlock();
963 if (delegation != NULL) {
964 delegation = nfs_detach_delegation(NFS_I(inode),
965 delegation, server);
966 if (delegation != NULL)
967 nfs_free_delegation(delegation);
968 }
969 iput(inode);
970 nfs_sb_deactive(server->super);
971 cond_resched();
972 goto restart;
973 }
974 }
975 rcu_read_unlock();
976}
977
978static inline bool nfs4_server_rebooted(const struct nfs_client *clp)
979{
980 return (clp->cl_state & (BIT(NFS4CLNT_CHECK_LEASE) |
981 BIT(NFS4CLNT_LEASE_EXPIRED) |
982 BIT(NFS4CLNT_SESSION_RESET))) != 0;
983}
984
985static void nfs_mark_test_expired_delegation(struct nfs_server *server,
986 struct nfs_delegation *delegation)
987{
988 if (delegation->stateid.type == NFS4_INVALID_STATEID_TYPE)
989 return;
990 clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
991 set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
992 set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
993}
994
995static void nfs_inode_mark_test_expired_delegation(struct nfs_server *server,
996 struct inode *inode)
997{
998 struct nfs_delegation *delegation;
999
1000 rcu_read_lock();
1001 delegation = rcu_dereference(NFS_I(inode)->delegation);
1002 if (delegation)
1003 nfs_mark_test_expired_delegation(server, delegation);
1004 rcu_read_unlock();
1005
1006}
1007
1008static void nfs_delegation_mark_test_expired_server(struct nfs_server *server)
1009{
1010 struct nfs_delegation *delegation;
1011
1012 list_for_each_entry_rcu(delegation, &server->delegations, super_list)
1013 nfs_mark_test_expired_delegation(server, delegation);
1014}
1015
1016
1017
1018
1019
1020
1021
1022
1023void nfs_mark_test_expired_all_delegations(struct nfs_client *clp)
1024{
1025 struct nfs_server *server;
1026
1027 rcu_read_lock();
1028 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1029 nfs_delegation_mark_test_expired_server(server);
1030 rcu_read_unlock();
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042void nfs_reap_expired_delegations(struct nfs_client *clp)
1043{
1044 const struct nfs4_minor_version_ops *ops = clp->cl_mvops;
1045 struct nfs_delegation *delegation;
1046 struct nfs_server *server;
1047 struct inode *inode;
1048 const struct cred *cred;
1049 nfs4_stateid stateid;
1050
1051restart:
1052 rcu_read_lock();
1053 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
1054 list_for_each_entry_rcu(delegation, &server->delegations,
1055 super_list) {
1056 if (test_bit(NFS_DELEGATION_RETURNING,
1057 &delegation->flags))
1058 continue;
1059 if (test_bit(NFS_DELEGATION_TEST_EXPIRED,
1060 &delegation->flags) == 0)
1061 continue;
1062 if (!nfs_sb_active(server->super))
1063 break;
1064 inode = nfs_delegation_grab_inode(delegation);
1065 if (inode == NULL) {
1066 rcu_read_unlock();
1067 nfs_sb_deactive(server->super);
1068 goto restart;
1069 }
1070 cred = get_cred_rcu(delegation->cred);
1071 nfs4_stateid_copy(&stateid, &delegation->stateid);
1072 clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
1073 rcu_read_unlock();
1074 if (cred != NULL &&
1075 ops->test_and_free_expired(server, &stateid, cred) < 0) {
1076 nfs_revoke_delegation(inode, &stateid);
1077 nfs_inode_find_state_and_recover(inode, &stateid);
1078 }
1079 put_cred(cred);
1080 if (nfs4_server_rebooted(clp)) {
1081 nfs_inode_mark_test_expired_delegation(server,inode);
1082 iput(inode);
1083 nfs_sb_deactive(server->super);
1084 return;
1085 }
1086 iput(inode);
1087 nfs_sb_deactive(server->super);
1088 cond_resched();
1089 goto restart;
1090 }
1091 }
1092 rcu_read_unlock();
1093}
1094
1095void nfs_inode_find_delegation_state_and_recover(struct inode *inode,
1096 const nfs4_stateid *stateid)
1097{
1098 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
1099 struct nfs_delegation *delegation;
1100 bool found = false;
1101
1102 rcu_read_lock();
1103 delegation = rcu_dereference(NFS_I(inode)->delegation);
1104 if (delegation &&
1105 nfs4_stateid_match_other(&delegation->stateid, stateid)) {
1106 nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
1107 found = true;
1108 }
1109 rcu_read_unlock();
1110 if (found)
1111 nfs4_schedule_state_manager(clp);
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121int nfs_delegations_present(struct nfs_client *clp)
1122{
1123 struct nfs_server *server;
1124 int ret = 0;
1125
1126 rcu_read_lock();
1127 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1128 if (!list_empty(&server->delegations)) {
1129 ret = 1;
1130 break;
1131 }
1132 rcu_read_unlock();
1133 return ret;
1134}
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
1145{
1146 struct nfs_delegation *delegation;
1147 bool ret = false;
1148 if (!inode)
1149 goto out;
1150
1151 rcu_read_lock();
1152 delegation = rcu_dereference(NFS_I(inode)->delegation);
1153 if (delegation != NULL &&
1154 nfs4_stateid_match_other(dst, &delegation->stateid)) {
1155 dst->seqid = delegation->stateid.seqid;
1156 return ret;
1157 }
1158 rcu_read_unlock();
1159out:
1160 return ret;
1161}
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
1174 nfs4_stateid *dst, const struct cred **cred)
1175{
1176 struct nfs_inode *nfsi = NFS_I(inode);
1177 struct nfs_delegation *delegation;
1178 bool ret;
1179
1180 flags &= FMODE_READ|FMODE_WRITE;
1181 rcu_read_lock();
1182 delegation = rcu_dereference(nfsi->delegation);
1183 ret = nfs4_is_valid_delegation(delegation, flags);
1184 if (ret) {
1185 nfs4_stateid_copy(dst, &delegation->stateid);
1186 nfs_mark_delegation_referenced(delegation);
1187 if (cred)
1188 *cred = get_cred(delegation->cred);
1189 }
1190 rcu_read_unlock();
1191 return ret;
1192}
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202bool nfs4_delegation_flush_on_close(const struct inode *inode)
1203{
1204 struct nfs_inode *nfsi = NFS_I(inode);
1205 struct nfs_delegation *delegation;
1206 bool ret = true;
1207
1208 rcu_read_lock();
1209 delegation = rcu_dereference(nfsi->delegation);
1210 if (delegation == NULL || !(delegation->type & FMODE_WRITE))
1211 goto out;
1212 if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit)
1213 ret = false;
1214out:
1215 rcu_read_unlock();
1216 return ret;
1217}
1218