]> git.karo-electronics.de Git - mv-sheeva.git/blob - fs/nfs/delegation.c
nfsd: break lease on unlink due to rename
[mv-sheeva.git] / fs / nfs / delegation.c
1 /*
2  * linux/fs/nfs/delegation.c
3  *
4  * Copyright (C) 2004 Trond Myklebust
5  *
6  * NFS file delegation management
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
16 #include <linux/nfs4.h>
17 #include <linux/nfs_fs.h>
18 #include <linux/nfs_xdr.h>
19
20 #include "nfs4_fs.h"
21 #include "delegation.h"
22 #include "internal.h"
23
24 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
25 {
26         if (delegation->cred)
27                 put_rpccred(delegation->cred);
28         kfree(delegation);
29 }
30
31 static void nfs_free_delegation_callback(struct rcu_head *head)
32 {
33         struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
34
35         nfs_do_free_delegation(delegation);
36 }
37
38 static void nfs_free_delegation(struct nfs_delegation *delegation)
39 {
40         call_rcu(&delegation->rcu, nfs_free_delegation_callback);
41 }
42
43 /**
44  * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
45  * @delegation: delegation to process
46  *
47  */
48 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
49 {
50         set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
51 }
52
53 /**
54  * nfs_have_delegation - check if inode has a delegation
55  * @inode: inode to check
56  * @flags: delegation types to check for
57  *
58  * Returns one if inode has the indicated delegation, otherwise zero.
59  */
60 int nfs_have_delegation(struct inode *inode, fmode_t flags)
61 {
62         struct nfs_delegation *delegation;
63         int ret = 0;
64
65         flags &= FMODE_READ|FMODE_WRITE;
66         rcu_read_lock();
67         delegation = rcu_dereference(NFS_I(inode)->delegation);
68         if (delegation != NULL && (delegation->type & flags) == flags) {
69                 nfs_mark_delegation_referenced(delegation);
70                 ret = 1;
71         }
72         rcu_read_unlock();
73         return ret;
74 }
75
76 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
77 {
78         struct inode *inode = state->inode;
79         struct file_lock *fl;
80         int status = 0;
81
82         if (inode->i_flock == NULL)
83                 goto out;
84
85         /* Protect inode->i_flock using the file locks lock */
86         lock_flocks();
87         for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
88                 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
89                         continue;
90                 if (nfs_file_open_context(fl->fl_file) != ctx)
91                         continue;
92                 unlock_flocks();
93                 status = nfs4_lock_delegation_recall(state, fl);
94                 if (status < 0)
95                         goto out;
96                 lock_flocks();
97         }
98         unlock_flocks();
99 out:
100         return status;
101 }
102
103 static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
104 {
105         struct nfs_inode *nfsi = NFS_I(inode);
106         struct nfs_open_context *ctx;
107         struct nfs4_state *state;
108         int err;
109
110 again:
111         spin_lock(&inode->i_lock);
112         list_for_each_entry(ctx, &nfsi->open_files, list) {
113                 state = ctx->state;
114                 if (state == NULL)
115                         continue;
116                 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
117                         continue;
118                 if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
119                         continue;
120                 get_nfs_open_context(ctx);
121                 spin_unlock(&inode->i_lock);
122                 err = nfs4_open_delegation_recall(ctx, state, stateid);
123                 if (err >= 0)
124                         err = nfs_delegation_claim_locks(ctx, state);
125                 put_nfs_open_context(ctx);
126                 if (err != 0)
127                         return err;
128                 goto again;
129         }
130         spin_unlock(&inode->i_lock);
131         return 0;
132 }
133
134 /**
135  * nfs_inode_reclaim_delegation - process a delegation reclaim request
136  * @inode: inode to process
137  * @cred: credential to use for request
138  * @res: new delegation state from server
139  *
140  */
141 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
142                                   struct nfs_openres *res)
143 {
144         struct nfs_delegation *delegation;
145         struct rpc_cred *oldcred = NULL;
146
147         rcu_read_lock();
148         delegation = rcu_dereference(NFS_I(inode)->delegation);
149         if (delegation != NULL) {
150                 spin_lock(&delegation->lock);
151                 if (delegation->inode != NULL) {
152                         memcpy(delegation->stateid.data, res->delegation.data,
153                                sizeof(delegation->stateid.data));
154                         delegation->type = res->delegation_type;
155                         delegation->maxsize = res->maxsize;
156                         oldcred = delegation->cred;
157                         delegation->cred = get_rpccred(cred);
158                         clear_bit(NFS_DELEGATION_NEED_RECLAIM,
159                                   &delegation->flags);
160                         NFS_I(inode)->delegation_state = delegation->type;
161                         spin_unlock(&delegation->lock);
162                         put_rpccred(oldcred);
163                         rcu_read_unlock();
164                 } else {
165                         /* We appear to have raced with a delegation return. */
166                         spin_unlock(&delegation->lock);
167                         rcu_read_unlock();
168                         nfs_inode_set_delegation(inode, cred, res);
169                 }
170         } else {
171                 rcu_read_unlock();
172         }
173 }
174
175 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
176 {
177         int res = 0;
178
179         res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
180         nfs_free_delegation(delegation);
181         return res;
182 }
183
184 static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
185 {
186         struct inode *inode = NULL;
187
188         spin_lock(&delegation->lock);
189         if (delegation->inode != NULL)
190                 inode = igrab(delegation->inode);
191         spin_unlock(&delegation->lock);
192         return inode;
193 }
194
195 static struct nfs_delegation *
196 nfs_detach_delegation_locked(struct nfs_inode *nfsi,
197                              struct nfs_server *server)
198 {
199         struct nfs_delegation *delegation =
200                 rcu_dereference_protected(nfsi->delegation,
201                                 lockdep_is_held(&server->nfs_client->cl_lock));
202
203         if (delegation == NULL)
204                 goto nomatch;
205
206         spin_lock(&delegation->lock);
207         list_del_rcu(&delegation->super_list);
208         delegation->inode = NULL;
209         nfsi->delegation_state = 0;
210         rcu_assign_pointer(nfsi->delegation, NULL);
211         spin_unlock(&delegation->lock);
212         return delegation;
213 nomatch:
214         return NULL;
215 }
216
217 static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
218                                                     struct nfs_server *server)
219 {
220         struct nfs_client *clp = server->nfs_client;
221         struct nfs_delegation *delegation;
222
223         spin_lock(&clp->cl_lock);
224         delegation = nfs_detach_delegation_locked(nfsi, server);
225         spin_unlock(&clp->cl_lock);
226         return delegation;
227 }
228
229 /**
230  * nfs_inode_set_delegation - set up a delegation on an inode
231  * @inode: inode to which delegation applies
232  * @cred: cred to use for subsequent delegation processing
233  * @res: new delegation state from server
234  *
235  * Returns zero on success, or a negative errno value.
236  */
237 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
238 {
239         struct nfs_server *server = NFS_SERVER(inode);
240         struct nfs_client *clp = server->nfs_client;
241         struct nfs_inode *nfsi = NFS_I(inode);
242         struct nfs_delegation *delegation, *old_delegation;
243         struct nfs_delegation *freeme = NULL;
244         int status = 0;
245
246         delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
247         if (delegation == NULL)
248                 return -ENOMEM;
249         memcpy(delegation->stateid.data, res->delegation.data,
250                         sizeof(delegation->stateid.data));
251         delegation->type = res->delegation_type;
252         delegation->maxsize = res->maxsize;
253         delegation->change_attr = nfsi->change_attr;
254         delegation->cred = get_rpccred(cred);
255         delegation->inode = inode;
256         delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
257         spin_lock_init(&delegation->lock);
258
259         spin_lock(&clp->cl_lock);
260         old_delegation = rcu_dereference_protected(nfsi->delegation,
261                                         lockdep_is_held(&clp->cl_lock));
262         if (old_delegation != NULL) {
263                 if (memcmp(&delegation->stateid, &old_delegation->stateid,
264                                         sizeof(old_delegation->stateid)) == 0 &&
265                                 delegation->type == old_delegation->type) {
266                         goto out;
267                 }
268                 /*
269                  * Deal with broken servers that hand out two
270                  * delegations for the same file.
271                  */
272                 dfprintk(FILE, "%s: server %s handed out "
273                                 "a duplicate delegation!\n",
274                                 __func__, clp->cl_hostname);
275                 if (delegation->type <= old_delegation->type) {
276                         freeme = delegation;
277                         delegation = NULL;
278                         goto out;
279                 }
280                 freeme = nfs_detach_delegation_locked(nfsi, server);
281         }
282         list_add_rcu(&delegation->super_list, &server->delegations);
283         nfsi->delegation_state = delegation->type;
284         rcu_assign_pointer(nfsi->delegation, delegation);
285         delegation = NULL;
286
287         /* Ensure we revalidate the attributes and page cache! */
288         spin_lock(&inode->i_lock);
289         nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
290         spin_unlock(&inode->i_lock);
291
292 out:
293         spin_unlock(&clp->cl_lock);
294         if (delegation != NULL)
295                 nfs_free_delegation(delegation);
296         if (freeme != NULL)
297                 nfs_do_return_delegation(inode, freeme, 0);
298         return status;
299 }
300
301 /*
302  * Basic procedure for returning a delegation to the server
303  */
304 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
305 {
306         struct nfs_inode *nfsi = NFS_I(inode);
307         int err;
308
309         /*
310          * Guard against new delegated open/lock/unlock calls and against
311          * state recovery
312          */
313         down_write(&nfsi->rwsem);
314         err = nfs_delegation_claim_opens(inode, &delegation->stateid);
315         up_write(&nfsi->rwsem);
316         if (err)
317                 goto out;
318
319         err = nfs_do_return_delegation(inode, delegation, issync);
320 out:
321         return err;
322 }
323
324 /**
325  * nfs_client_return_marked_delegations - return previously marked delegations
326  * @clp: nfs_client to process
327  *
328  * Returns zero on success, or a negative errno value.
329  */
330 int nfs_client_return_marked_delegations(struct nfs_client *clp)
331 {
332         struct nfs_delegation *delegation;
333         struct nfs_server *server;
334         struct inode *inode;
335         int err = 0;
336
337 restart:
338         rcu_read_lock();
339         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
340                 list_for_each_entry_rcu(delegation, &server->delegations,
341                                                                 super_list) {
342                         if (!test_and_clear_bit(NFS_DELEGATION_RETURN,
343                                                         &delegation->flags))
344                                 continue;
345                         inode = nfs_delegation_grab_inode(delegation);
346                         if (inode == NULL)
347                                 continue;
348                         delegation = nfs_detach_delegation(NFS_I(inode),
349                                                                 server);
350                         rcu_read_unlock();
351
352                         if (delegation != NULL) {
353                                 filemap_flush(inode->i_mapping);
354                                 err = __nfs_inode_return_delegation(inode,
355                                                                 delegation, 0);
356                         }
357                         iput(inode);
358                         if (!err)
359                                 goto restart;
360                         set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
361                         return err;
362                 }
363         }
364         rcu_read_unlock();
365         return 0;
366 }
367
368 /**
369  * nfs_inode_return_delegation_noreclaim - return delegation, don't reclaim opens
370  * @inode: inode to process
371  *
372  * Does not protect against delegation reclaims, therefore really only safe
373  * to be called from nfs4_clear_inode().
374  */
375 void nfs_inode_return_delegation_noreclaim(struct inode *inode)
376 {
377         struct nfs_server *server = NFS_SERVER(inode);
378         struct nfs_inode *nfsi = NFS_I(inode);
379         struct nfs_delegation *delegation;
380
381         if (rcu_access_pointer(nfsi->delegation) != NULL) {
382                 delegation = nfs_detach_delegation(nfsi, server);
383                 if (delegation != NULL)
384                         nfs_do_return_delegation(inode, delegation, 0);
385         }
386 }
387
388 /**
389  * nfs_inode_return_delegation - synchronously return a delegation
390  * @inode: inode to process
391  *
392  * Returns zero on success, or a negative errno value.
393  */
394 int nfs_inode_return_delegation(struct inode *inode)
395 {
396         struct nfs_server *server = NFS_SERVER(inode);
397         struct nfs_inode *nfsi = NFS_I(inode);
398         struct nfs_delegation *delegation;
399         int err = 0;
400
401         if (rcu_access_pointer(nfsi->delegation) != NULL) {
402                 delegation = nfs_detach_delegation(nfsi, server);
403                 if (delegation != NULL) {
404                         nfs_wb_all(inode);
405                         err = __nfs_inode_return_delegation(inode, delegation, 1);
406                 }
407         }
408         return err;
409 }
410
411 static void nfs_mark_return_delegation(struct nfs_delegation *delegation)
412 {
413         struct nfs_client *clp = NFS_SERVER(delegation->inode)->nfs_client;
414
415         set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
416         set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
417 }
418
419 /**
420  * nfs_super_return_all_delegations - return delegations for one superblock
421  * @sb: sb to process
422  *
423  */
424 void nfs_super_return_all_delegations(struct super_block *sb)
425 {
426         struct nfs_server *server = NFS_SB(sb);
427         struct nfs_client *clp = server->nfs_client;
428         struct nfs_delegation *delegation;
429
430         if (clp == NULL)
431                 return;
432
433         rcu_read_lock();
434         list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
435                 spin_lock(&delegation->lock);
436                 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
437                 spin_unlock(&delegation->lock);
438         }
439         rcu_read_unlock();
440
441         if (nfs_client_return_marked_delegations(clp) != 0)
442                 nfs4_schedule_state_manager(clp);
443 }
444
445 static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
446                                                  fmode_t flags)
447 {
448         struct nfs_delegation *delegation;
449
450         list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
451                 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
452                         continue;
453                 if (delegation->type & flags)
454                         nfs_mark_return_delegation(delegation);
455         }
456 }
457
458 static void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp,
459                                                         fmode_t flags)
460 {
461         struct nfs_server *server;
462
463         rcu_read_lock();
464         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
465                 nfs_mark_return_all_delegation_types(server, flags);
466         rcu_read_unlock();
467 }
468
469 static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
470 {
471         nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
472 }
473
474 static void nfs_delegation_run_state_manager(struct nfs_client *clp)
475 {
476         if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
477                 nfs4_schedule_state_manager(clp);
478 }
479
480 /**
481  * nfs_expire_all_delegation_types
482  * @clp: client to process
483  * @flags: delegation types to expire
484  *
485  */
486 void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
487 {
488         nfs_client_mark_return_all_delegation_types(clp, flags);
489         nfs_delegation_run_state_manager(clp);
490 }
491
492 /**
493  * nfs_expire_all_delegations
494  * @clp: client to process
495  *
496  */
497 void nfs_expire_all_delegations(struct nfs_client *clp)
498 {
499         nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
500 }
501
502 /**
503  * nfs_handle_cb_pathdown - return all delegations after NFS4ERR_CB_PATH_DOWN
504  * @clp: client to process
505  *
506  */
507 void nfs_handle_cb_pathdown(struct nfs_client *clp)
508 {
509         if (clp == NULL)
510                 return;
511         nfs_client_mark_return_all_delegations(clp);
512 }
513
514 static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
515 {
516         struct nfs_delegation *delegation;
517
518         list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
519                 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
520                         continue;
521                 nfs_mark_return_delegation(delegation);
522         }
523 }
524
525 /**
526  * nfs_expire_unreferenced_delegations - Eliminate unused delegations
527  * @clp: nfs_client to process
528  *
529  */
530 void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
531 {
532         struct nfs_server *server;
533
534         rcu_read_lock();
535         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
536                 nfs_mark_return_unreferenced_delegations(server);
537         rcu_read_unlock();
538
539         nfs_delegation_run_state_manager(clp);
540 }
541
542 /**
543  * nfs_async_inode_return_delegation - asynchronously return a delegation
544  * @inode: inode to process
545  * @stateid: state ID information from CB_RECALL arguments
546  *
547  * Returns zero on success, or a negative errno value.
548  */
549 int nfs_async_inode_return_delegation(struct inode *inode,
550                                       const nfs4_stateid *stateid)
551 {
552         struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
553         struct nfs_delegation *delegation;
554
555         rcu_read_lock();
556         delegation = rcu_dereference(NFS_I(inode)->delegation);
557
558         if (!clp->cl_mvops->validate_stateid(delegation, stateid)) {
559                 rcu_read_unlock();
560                 return -ENOENT;
561         }
562         nfs_mark_return_delegation(delegation);
563         rcu_read_unlock();
564
565         nfs_delegation_run_state_manager(clp);
566         return 0;
567 }
568
569 static struct inode *
570 nfs_delegation_find_inode_server(struct nfs_server *server,
571                                  const struct nfs_fh *fhandle)
572 {
573         struct nfs_delegation *delegation;
574         struct inode *res = NULL;
575
576         list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
577                 spin_lock(&delegation->lock);
578                 if (delegation->inode != NULL &&
579                     nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
580                         res = igrab(delegation->inode);
581                 }
582                 spin_unlock(&delegation->lock);
583                 if (res != NULL)
584                         break;
585         }
586         return res;
587 }
588
589 /**
590  * nfs_delegation_find_inode - retrieve the inode associated with a delegation
591  * @clp: client state handle
592  * @fhandle: filehandle from a delegation recall
593  *
594  * Returns pointer to inode matching "fhandle," or NULL if a matching inode
595  * cannot be found.
596  */
597 struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
598                                         const struct nfs_fh *fhandle)
599 {
600         struct nfs_server *server;
601         struct inode *res = NULL;
602
603         rcu_read_lock();
604         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
605                 res = nfs_delegation_find_inode_server(server, fhandle);
606                 if (res != NULL)
607                         break;
608         }
609         rcu_read_unlock();
610         return res;
611 }
612
613 static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)
614 {
615         struct nfs_delegation *delegation;
616
617         list_for_each_entry_rcu(delegation, &server->delegations, super_list)
618                 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
619 }
620
621 /**
622  * nfs_delegation_mark_reclaim - mark all delegations as needing to be reclaimed
623  * @clp: nfs_client to process
624  *
625  */
626 void nfs_delegation_mark_reclaim(struct nfs_client *clp)
627 {
628         struct nfs_server *server;
629
630         rcu_read_lock();
631         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
632                 nfs_delegation_mark_reclaim_server(server);
633         rcu_read_unlock();
634 }
635
636 /**
637  * nfs_delegation_reap_unclaimed - reap unclaimed delegations after reboot recovery is done
638  * @clp: nfs_client to process
639  *
640  */
641 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
642 {
643         struct nfs_delegation *delegation;
644         struct nfs_server *server;
645         struct inode *inode;
646
647 restart:
648         rcu_read_lock();
649         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
650                 list_for_each_entry_rcu(delegation, &server->delegations,
651                                                                 super_list) {
652                         if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
653                                                 &delegation->flags) == 0)
654                                 continue;
655                         inode = nfs_delegation_grab_inode(delegation);
656                         if (inode == NULL)
657                                 continue;
658                         delegation = nfs_detach_delegation(NFS_I(inode),
659                                                                 server);
660                         rcu_read_unlock();
661
662                         if (delegation != NULL)
663                                 nfs_free_delegation(delegation);
664                         iput(inode);
665                         goto restart;
666                 }
667         }
668         rcu_read_unlock();
669 }
670
671 /**
672  * nfs_delegations_present - check for existence of delegations
673  * @clp: client state handle
674  *
675  * Returns one if there are any nfs_delegation structures attached
676  * to this nfs_client.
677  */
678 int nfs_delegations_present(struct nfs_client *clp)
679 {
680         struct nfs_server *server;
681         int ret = 0;
682
683         rcu_read_lock();
684         list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
685                 if (!list_empty(&server->delegations)) {
686                         ret = 1;
687                         break;
688                 }
689         rcu_read_unlock();
690         return ret;
691 }
692
693 /**
694  * nfs4_copy_delegation_stateid - Copy inode's state ID information
695  * @dst: stateid data structure to fill in
696  * @inode: inode to check
697  *
698  * Returns one and fills in "dst->data" * if inode had a delegation,
699  * otherwise zero is returned.
700  */
701 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
702 {
703         struct nfs_inode *nfsi = NFS_I(inode);
704         struct nfs_delegation *delegation;
705         int ret = 0;
706
707         rcu_read_lock();
708         delegation = rcu_dereference(nfsi->delegation);
709         if (delegation != NULL) {
710                 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));
711                 ret = 1;
712         }
713         rcu_read_unlock();
714         return ret;
715 }