aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index f4758ec42138..2563bebc4c67 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -454,18 +454,21 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
454/* 454/*
455 * Asynchronous delegation recall! 455 * Asynchronous delegation recall!
456 */ 456 */
457int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 457int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
458 int (*validate_stateid)(struct nfs_delegation *delegation,
459 const nfs4_stateid *stateid))
458{ 460{
459 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 461 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
460 struct nfs_delegation *delegation; 462 struct nfs_delegation *delegation;
461 463
462 rcu_read_lock(); 464 rcu_read_lock();
463 delegation = rcu_dereference(NFS_I(inode)->delegation); 465 delegation = rcu_dereference(NFS_I(inode)->delegation);
464 if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data, 466
465 sizeof(delegation->stateid.data)) != 0) { 467 if (!validate_stateid(delegation, stateid)) {
466 rcu_read_unlock(); 468 rcu_read_unlock();
467 return -ENOENT; 469 return -ENOENT;
468 } 470 }
471
469 nfs_mark_return_delegation(clp, delegation); 472 nfs_mark_return_delegation(clp, delegation);
470 rcu_read_unlock(); 473 rcu_read_unlock();
471 nfs_delegation_run_state_manager(clp); 474 nfs_delegation_run_state_manager(clp);