Skip to content

Commit 40927f3

Browse files
neilbrownchucklever
authored andcommitted
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: c596772 ("NFSD: handle GETATTR conflict with write delegation") Signed-off-by: NeilBrown <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 7e8ae84 commit 40927f3

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

fs/nfsd/nfs4state.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8859,7 +8859,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
88598859
*/
88608860
if (type == F_RDLCK)
88618861
break;
8862-
goto break_lease;
8862+
8863+
nfsd_stats_wdeleg_getattr_inc(nn);
8864+
spin_unlock(&ctx->flc_lock);
8865+
8866+
status = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ));
8867+
if (status != nfserr_jukebox ||
8868+
!nfsd_wait_for_delegreturn(rqstp, inode))
8869+
return status;
8870+
return 0;
88638871
}
88648872
if (type == F_WRLCK) {
88658873
struct nfs4_delegation *dp = fl->c.flc_owner;
@@ -8868,7 +8876,6 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
88688876
spin_unlock(&ctx->flc_lock);
88698877
return 0;
88708878
}
8871-
break_lease:
88728879
nfsd_stats_wdeleg_getattr_inc(nn);
88738880
dp = fl->c.flc_owner;
88748881
refcount_inc(&dp->dl_stid.sc_count);

0 commit comments

Comments
 (0)