mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
nfsd: fix nfsd4_deleg_getattr_conflict in presence of third party lease
It is not safe to dereference fl->c.flc_owner without first confirming
fl->fl_lmops is the expected manager. nfsd4_deleg_getattr_conflict()
tests fl_lmops but largely ignores the result and assumes that flc_owner
is an nfs4_delegation anyway. This is wrong.
With this patch we restore the "!= &nfsd_lease_mng_ops" case to behave
as it did before the change mentioned below. This is the same as the
current code, but without any reference to a possible delegation.
Fixes: c5967721e1
("NFSD: handle GETATTR conflict with write delegation")
Signed-off-by: NeilBrown <neilb@suse.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
7e8ae8486e
commit
40927f3d09
@ -8859,7 +8859,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
|
||||
*/
|
||||
if (type == F_RDLCK)
|
||||
break;
|
||||
goto break_lease;
|
||||
|
||||
nfsd_stats_wdeleg_getattr_inc(nn);
|
||||
spin_unlock(&ctx->flc_lock);
|
||||
|
||||
status = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ));
|
||||
if (status != nfserr_jukebox ||
|
||||
!nfsd_wait_for_delegreturn(rqstp, inode))
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
if (type == F_WRLCK) {
|
||||
struct nfs4_delegation *dp = fl->c.flc_owner;
|
||||
@ -8868,7 +8876,6 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
|
||||
spin_unlock(&ctx->flc_lock);
|
||||
return 0;
|
||||
}
|
||||
break_lease:
|
||||
nfsd_stats_wdeleg_getattr_inc(nn);
|
||||
dp = fl->c.flc_owner;
|
||||
refcount_inc(&dp->dl_stid.sc_count);
|
||||
|
Loading…
Reference in New Issue
Block a user