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 /fs | |
| 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>
Diffstat (limited to 'fs')
| -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 * |
