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: c5967721e106 ("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>

authored by NeilBrown and committed by Chuck Lever 40927f3d 7e8ae848

+9 -2
+9 -2
fs/nfsd/nfs4state.c
··· 8859 8859 */ 8860 8860 if (type == F_RDLCK) 8861 8861 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; 8863 8871 } 8864 8872 if (type == F_WRLCK) { 8865 8873 struct nfs4_delegation *dp = fl->c.flc_owner; ··· 8876 8868 spin_unlock(&ctx->flc_lock); 8877 8869 return 0; 8878 8870 } 8879 - break_lease: 8880 8871 nfsd_stats_wdeleg_getattr_inc(nn); 8881 8872 dp = fl->c.flc_owner; 8882 8873 refcount_inc(&dp->dl_stid.sc_count);