MFC: r259854
The NFSv4 server would call VOP_SETATTR() with a shared locked vnode when a Getattr for a file is done by a client other than the one that holds the file's delegation. This would only happen when delegations are enabled and the problem is fixed by this patch.
This commit is contained in:
parent
0b3ac62883
commit
e876d4736c
@ -613,7 +613,7 @@ void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t,
|
||||
nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, int32_t *,
|
||||
int, NFSACL_T *, nfsattrbit_t *, struct ucred *, NFSPROC_T *,
|
||||
struct nfsexstuff *, vnode_t *);
|
||||
void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
|
||||
int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
|
||||
NFSPROC_T *);
|
||||
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
|
||||
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
|
||||
|
@ -1469,8 +1469,9 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
* Updates the file rev and sets the mtime and ctime
|
||||
* to the current clock time, returning the va_filerev and va_Xtime
|
||||
* values.
|
||||
* Return ESTALE to indicate the vnode is VI_DOOMED.
|
||||
*/
|
||||
void
|
||||
int
|
||||
nfsvno_updfilerev(struct vnode *vp, struct nfsvattr *nvap,
|
||||
struct ucred *cred, struct thread *p)
|
||||
{
|
||||
@ -1478,8 +1479,14 @@ nfsvno_updfilerev(struct vnode *vp, struct nfsvattr *nvap,
|
||||
|
||||
VATTR_NULL(&va);
|
||||
vfs_timestamp(&va.va_mtime);
|
||||
if (NFSVOPISLOCKED(vp) != LK_EXCLUSIVE) {
|
||||
NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY);
|
||||
if ((vp->v_iflag & VI_DOOMED) != 0)
|
||||
return (ESTALE);
|
||||
}
|
||||
(void) VOP_SETATTR(vp, &va, cred);
|
||||
(void) nfsvno_getattr(vp, nvap, cred, p, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4853,15 +4853,15 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
nva.na_filerev > delegfilerev) ||
|
||||
(NFSVNO_ISSETSIZE(&nva) &&
|
||||
nva.na_size != nvap->na_size)) {
|
||||
nfsvno_updfilerev(vp, nvap, cred, p);
|
||||
error = nfsvno_updfilerev(vp, nvap, cred, p);
|
||||
if (NFSVNO_ISSETSIZE(&nva))
|
||||
nvap->na_size = nva.na_size;
|
||||
}
|
||||
}
|
||||
} else
|
||||
error = 0; /* Ignore callback errors for now. */
|
||||
} else {
|
||||
NFSUNLOCKSTATE();
|
||||
}
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user