mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
NFS: nfs_delegation_find_inode_server must first reference the superblock
commit113aac6d56upstream. Before referencing the inode, we must ensure that the superblock can be referenced. Otherwise, we can end up with iput() calling superblock operations that are no longer valid or accessible. Fixes:e39d8a186e("NFSv4: Fix an Oops during delegation callbacks") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
01a12a24f9
commit
b4689562fa
|
|
@ -1011,22 +1011,24 @@ nfs_delegation_find_inode_server(struct nfs_server *server,
|
|||
const struct nfs_fh *fhandle)
|
||||
{
|
||||
struct nfs_delegation *delegation;
|
||||
struct inode *freeme, *res = NULL;
|
||||
struct super_block *freeme = NULL;
|
||||
struct inode *res = NULL;
|
||||
|
||||
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
|
||||
spin_lock(&delegation->lock);
|
||||
if (delegation->inode != NULL &&
|
||||
!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
|
||||
nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
|
||||
freeme = igrab(delegation->inode);
|
||||
if (freeme && nfs_sb_active(freeme->i_sb))
|
||||
res = freeme;
|
||||
if (nfs_sb_active(server->super)) {
|
||||
freeme = server->super;
|
||||
res = igrab(delegation->inode);
|
||||
}
|
||||
spin_unlock(&delegation->lock);
|
||||
if (res != NULL)
|
||||
return res;
|
||||
if (freeme) {
|
||||
rcu_read_unlock();
|
||||
iput(freeme);
|
||||
nfs_sb_deactive(freeme);
|
||||
rcu_read_lock();
|
||||
}
|
||||
return ERR_PTR(-EAGAIN);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user