11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/slab.h>
16 #include <linux/nfs4.h>
17 #include <linux/nfs_fs.h>
24 static void nfs_free_delegation(
struct nfs_delegation *delegation)
26 if (delegation->cred) {
28 delegation->cred =
NULL;
40 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
52 struct nfs_delegation *delegation;
58 if (delegation !=
NULL && (delegation->type & flags) == flags) {
80 if (nfs_file_open_context(fl->
fl_file) != ctx)
93 static int nfs_delegation_claim_opens(
struct inode *inode,
const nfs4_stateid *stateid)
97 struct nfs4_state *
state;
101 spin_lock(&inode->
i_lock);
106 if (!
test_bit(NFS_DELEGATED_STATE, &state->flags))
108 if (!nfs4_stateid_match(&state->stateid, stateid))
111 spin_unlock(&inode->
i_lock);
114 err = nfs_delegation_claim_locks(ctx, state);
120 spin_unlock(&inode->
i_lock);
134 struct nfs_delegation *delegation;
135 struct rpc_cred *oldcred =
NULL;
139 if (delegation !=
NULL) {
140 spin_lock(&delegation->lock);
141 if (delegation->inode !=
NULL) {
142 nfs4_stateid_copy(&delegation->stateid, &res->
delegation);
144 delegation->maxsize = res->
maxsize;
145 oldcred = delegation->cred;
146 delegation->cred = get_rpccred(cred);
149 NFS_I(inode)->delegation_state = delegation->type;
150 spin_unlock(&delegation->lock);
155 spin_unlock(&delegation->lock);
164 static int nfs_do_return_delegation(
struct inode *inode,
struct nfs_delegation *delegation,
int issync)
169 nfs_free_delegation(delegation);
173 static struct inode *nfs_delegation_grab_inode(
struct nfs_delegation *delegation)
175 struct inode *inode =
NULL;
177 spin_lock(&delegation->lock);
178 if (delegation->inode !=
NULL)
179 inode =
igrab(delegation->inode);
180 spin_unlock(&delegation->lock);
184 static struct nfs_delegation *
185 nfs_detach_delegation_locked(
struct nfs_inode *nfsi,
188 struct nfs_delegation *delegation =
190 lockdep_is_held(&server->
nfs_client->cl_lock));
192 if (delegation ==
NULL)
195 spin_lock(&delegation->lock);
196 list_del_rcu(&delegation->super_list);
197 delegation->inode =
NULL;
198 nfsi->delegation_state = 0;
200 spin_unlock(&delegation->lock);
206 static struct nfs_delegation *nfs_detach_delegation(
struct nfs_inode *nfsi,
210 struct nfs_delegation *delegation;
212 spin_lock(&clp->cl_lock);
213 delegation = nfs_detach_delegation_locked(nfsi, server);
214 spin_unlock(&clp->cl_lock);
228 struct nfs_server *server = NFS_SERVER(inode);
231 struct nfs_delegation *delegation, *old_delegation;
232 struct nfs_delegation *freeme =
NULL;
236 if (delegation ==
NULL)
238 nfs4_stateid_copy(&delegation->stateid, &res->
delegation);
240 delegation->maxsize = res->
maxsize;
241 delegation->change_attr = inode->
i_version;
242 delegation->cred = get_rpccred(cred);
243 delegation->inode =
inode;
244 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
247 spin_lock(&clp->cl_lock);
249 lockdep_is_held(&clp->cl_lock));
250 if (old_delegation !=
NULL) {
251 if (nfs4_stateid_match(&delegation->stateid,
252 &old_delegation->stateid) &&
253 delegation->type == old_delegation->type) {
262 dfprintk(FILE,
"%s: server %s handed out "
263 "a duplicate delegation!\n",
265 if (delegation->type == old_delegation->type ||
271 freeme = nfs_detach_delegation_locked(nfsi, server);
273 list_add_rcu(&delegation->super_list, &server->
delegations);
274 nfsi->delegation_state = delegation->type;
279 spin_lock(&inode->
i_lock);
281 spin_unlock(&inode->
i_lock);
284 spin_unlock(&clp->cl_lock);
285 if (delegation !=
NULL)
286 nfs_free_delegation(delegation);
288 nfs_do_return_delegation(inode, freeme, 0);
295 static int __nfs_inode_return_delegation(
struct inode *inode,
struct nfs_delegation *delegation,
int issync)
305 err = nfs_delegation_claim_opens(inode, &delegation->stateid);
310 err = nfs_do_return_delegation(inode, delegation, issync);
327 struct nfs_delegation *delegation;
334 list_for_each_entry_rcu(server, &clp->
cl_superblocks, client_link) {
335 list_for_each_entry_rcu(delegation, &server->
delegations,
340 inode = nfs_delegation_grab_inode(delegation);
343 delegation = nfs_detach_delegation(NFS_I(inode),
347 if (delegation !=
NULL)
348 err = __nfs_inode_return_delegation(inode,
353 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
370 struct nfs_server *server = NFS_SERVER(inode);
372 struct nfs_delegation *delegation;
375 delegation = nfs_detach_delegation(nfsi, server);
376 if (delegation !=
NULL)
377 nfs_do_return_delegation(inode, delegation, 0);
393 struct nfs_server *server = NFS_SERVER(inode);
395 struct nfs_delegation *delegation;
400 delegation = nfs_detach_delegation(nfsi, server);
401 if (delegation !=
NULL) {
402 err = __nfs_inode_return_delegation(inode, delegation, 1);
408 static void nfs_mark_return_delegation(
struct nfs_server *server,
409 struct nfs_delegation *delegation)
411 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
423 struct nfs_delegation *delegation;
429 list_for_each_entry_rcu(delegation, &server->
delegations, super_list) {
430 spin_lock(&delegation->lock);
431 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
432 spin_unlock(&delegation->lock);
440 static void nfs_mark_return_all_delegation_types(
struct nfs_server *server,
443 struct nfs_delegation *delegation;
445 list_for_each_entry_rcu(delegation, &server->
delegations, super_list) {
448 if (delegation->type & flags)
449 nfs_mark_return_delegation(server, delegation);
453 static void nfs_client_mark_return_all_delegation_types(
struct nfs_client *clp,
460 nfs_mark_return_all_delegation_types(server, flags);
466 if (
test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
472 struct nfs_delegation *delegation;
474 delegation = nfs_detach_delegation(NFS_I(inode), NFS_SERVER(inode));
477 nfs_free_delegation(delegation);
490 nfs_client_mark_return_all_delegation_types(clp, flags);
491 nfs_delegation_run_state_manager(clp);
504 static void nfs_mark_return_unreferenced_delegations(
struct nfs_server *server)
506 struct nfs_delegation *delegation;
508 list_for_each_entry_rcu(delegation, &server->
delegations, super_list) {
511 nfs_mark_return_delegation(server, delegation);
526 nfs_mark_return_unreferenced_delegations(server);
529 nfs_delegation_run_state_manager(clp);
542 struct nfs_server *server = NFS_SERVER(inode);
544 struct nfs_delegation *delegation;
551 if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) {
555 nfs_mark_return_delegation(server, delegation);
558 nfs_delegation_run_state_manager(clp);
562 static struct inode *
563 nfs_delegation_find_inode_server(
struct nfs_server *server,
564 const struct nfs_fh *fhandle)
566 struct nfs_delegation *delegation;
569 list_for_each_entry_rcu(delegation, &server->
delegations, super_list) {
570 spin_lock(&delegation->lock);
571 if (delegation->inode !=
NULL &&
572 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
573 res =
igrab(delegation->inode);
575 spin_unlock(&delegation->lock);
591 const struct nfs_fh *fhandle)
594 struct inode *res =
NULL;
597 list_for_each_entry_rcu(server, &clp->
cl_superblocks, client_link) {
598 res = nfs_delegation_find_inode_server(server, fhandle);
606 static void nfs_delegation_mark_reclaim_server(
struct nfs_server *server)
608 struct nfs_delegation *delegation;
610 list_for_each_entry_rcu(delegation, &server->
delegations, super_list)
611 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
624 list_for_each_entry_rcu(server, &clp->cl_superblocks,
client_link)
625 nfs_delegation_mark_reclaim_server(server);
636 struct nfs_delegation *delegation;
642 list_for_each_entry_rcu(server, &clp->
cl_superblocks, client_link) {
643 list_for_each_entry_rcu(delegation, &server->
delegations,
645 if (
test_bit(NFS_DELEGATION_NEED_RECLAIM,
646 &delegation->flags) == 0)
648 inode = nfs_delegation_grab_inode(delegation);
651 delegation = nfs_detach_delegation(NFS_I(inode),
655 if (delegation !=
NULL)
656 nfs_free_delegation(delegation);
699 struct nfs_delegation *delegation;
705 ret = (delegation !=
NULL && (delegation->type &
flags) == flags);
707 nfs4_stateid_copy(dst, &delegation->stateid);