diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-03-02 22:03:12 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-03-02 22:03:12 -0500 |
commit | 755a48a7a4eb05b9c8424e3017d947b2961a60e0 (patch) | |
tree | 357da4eb493a7cf80df34af3bcceaab442614756 | |
parent | b7e63a1079b266866a732cf699d8c4d61391bbda (diff) |
NFS: Fix a delegation callback race
The clean-up in commit 36281caa839f ended up removing a NULL pointer check
that is needed in order to prevent an Oops in
nfs_async_inode_return_delegation().
Reported-by: "Yan, Zheng" <zheng.z.yan@intel.com>
Link: http://lkml.kernel.org/r/5313E9F6.2020405@intel.com
Fixes: 36281caa839f (NFSv4: Further clean-ups of delegation stateid validation)
Cc: stable@vger.kernel.org # 3.4+
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r-- | fs/nfs/delegation.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index ef792f29f831..5d8ccecf5f5c 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -659,16 +659,19 @@ int nfs_async_inode_return_delegation(struct inode *inode, | |||
659 | 659 | ||
660 | rcu_read_lock(); | 660 | rcu_read_lock(); |
661 | delegation = rcu_dereference(NFS_I(inode)->delegation); | 661 | delegation = rcu_dereference(NFS_I(inode)->delegation); |
662 | if (delegation == NULL) | ||
663 | goto out_enoent; | ||
662 | 664 | ||
663 | if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) { | 665 | if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) |
664 | rcu_read_unlock(); | 666 | goto out_enoent; |
665 | return -ENOENT; | ||
666 | } | ||
667 | nfs_mark_return_delegation(server, delegation); | 667 | nfs_mark_return_delegation(server, delegation); |
668 | rcu_read_unlock(); | 668 | rcu_read_unlock(); |
669 | 669 | ||
670 | nfs_delegation_run_state_manager(clp); | 670 | nfs_delegation_run_state_manager(clp); |
671 | return 0; | 671 | return 0; |
672 | out_enoent: | ||
673 | rcu_read_unlock(); | ||
674 | return -ENOENT; | ||
672 | } | 675 | } |
673 | 676 | ||
674 | static struct inode * | 677 | static struct inode * |