mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Fix failures and warnings reported by newpynfs20090424 test tool.
This fix addresses only issues with the pynfs reports, none of these issues are know to create problems for extant real clients. Submitted by: Bart Hsiao <bart.hsiao@gmail.com> Reworked by: myself Reviewed by: rmacklem Approved by: rmacklem Sponsored by: QNAP Systems Inc.
This commit is contained in:
parent
34ad8c7be4
commit
d8a5961f88
7 changed files with 90 additions and 34 deletions
|
|
@ -2837,6 +2837,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
|
||||||
#endif
|
#endif
|
||||||
vap->va_seq = zp->z_seq;
|
vap->va_seq = zp->z_seq;
|
||||||
vap->va_flags = 0; /* FreeBSD: Reset chflags(2) flags. */
|
vap->va_flags = 0; /* FreeBSD: Reset chflags(2) flags. */
|
||||||
|
vap->va_filerev = zp->z_seq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add in any requested optional attributes and the create time.
|
* Add in any requested optional attributes and the create time.
|
||||||
|
|
|
||||||
|
|
@ -820,7 +820,6 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||||
struct dqblk dqb;
|
struct dqblk dqb;
|
||||||
uid_t savuid;
|
uid_t savuid;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (compare) {
|
if (compare) {
|
||||||
retnotsup = 0;
|
retnotsup = 0;
|
||||||
error = nfsrv_getattrbits(nd, &attrbits, NULL, &retnotsup);
|
error = nfsrv_getattrbits(nd, &attrbits, NULL, &retnotsup);
|
||||||
|
|
@ -902,6 +901,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
if (compare && !(*retcmpp)) {
|
if (compare && !(*retcmpp)) {
|
||||||
NFSSETSUPP_ATTRBIT(&checkattrbits);
|
NFSSETSUPP_ATTRBIT(&checkattrbits);
|
||||||
|
|
||||||
|
/* Some filesystem do not support NFSv4ACL */
|
||||||
|
if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0) {
|
||||||
|
NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_ACL);
|
||||||
|
NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_ACLSUPPORT);
|
||||||
|
}
|
||||||
if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits)
|
if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits)
|
||||||
|| retnotsup)
|
|| retnotsup)
|
||||||
*retcmpp = NFSERR_NOTSAME;
|
*retcmpp = NFSERR_NOTSAME;
|
||||||
|
|
@ -1052,7 +1057,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||||
case NFSATTRBIT_ACL:
|
case NFSATTRBIT_ACL:
|
||||||
if (compare) {
|
if (compare) {
|
||||||
if (!(*retcmpp)) {
|
if (!(*retcmpp)) {
|
||||||
if (nfsrv_useacl) {
|
if (nfsrv_useacl && nfs_supportsnfsv4acls(vp)) {
|
||||||
NFSACL_T *naclp;
|
NFSACL_T *naclp;
|
||||||
|
|
||||||
naclp = acl_alloc(M_WAITOK);
|
naclp = acl_alloc(M_WAITOK);
|
||||||
|
|
@ -1073,21 +1078,22 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (vp != NULL && aclp != NULL)
|
if (vp != NULL && aclp != NULL)
|
||||||
error = nfsrv_dissectacl(nd, aclp, &aceerr,
|
error = nfsrv_dissectacl(nd, aclp, &aceerr,
|
||||||
&cnt, p);
|
&cnt, p);
|
||||||
else
|
else
|
||||||
error = nfsrv_dissectacl(nd, NULL, &aceerr,
|
error = nfsrv_dissectacl(nd, NULL, &aceerr,
|
||||||
&cnt, p);
|
&cnt, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
}
|
}
|
||||||
|
|
||||||
attrsum += cnt;
|
attrsum += cnt;
|
||||||
break;
|
break;
|
||||||
case NFSATTRBIT_ACLSUPPORT:
|
case NFSATTRBIT_ACLSUPPORT:
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
if (compare && !(*retcmpp)) {
|
if (compare && !(*retcmpp)) {
|
||||||
if (nfsrv_useacl) {
|
if (nfsrv_useacl && nfs_supportsnfsv4acls(vp)) {
|
||||||
if (fxdr_unsigned(u_int32_t, *tl) !=
|
if (fxdr_unsigned(u_int32_t, *tl) !=
|
||||||
NFSV4ACE_SUPTYPES)
|
NFSV4ACE_SUPTYPES)
|
||||||
*retcmpp = NFSERR_NOTSAME;
|
*retcmpp = NFSERR_NOTSAME;
|
||||||
|
|
@ -2090,6 +2096,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put out the attribute bitmap for the ones being filled in
|
* Put out the attribute bitmap for the ones being filled in
|
||||||
* and get the field for the number of attributes returned.
|
* and get the field for the number of attributes returned.
|
||||||
|
|
|
||||||
|
|
@ -644,9 +644,9 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
|
||||||
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
|
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
|
||||||
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
|
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
|
||||||
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
|
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
|
||||||
int nfsrv_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
|
int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
|
||||||
NFSACL_T *, NFSPROC_T *);
|
NFSACL_T *, NFSPROC_T *);
|
||||||
int nfsv4_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
|
int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
|
||||||
NFSACL_T *, NFSPROC_T *);
|
NFSACL_T *, NFSPROC_T *);
|
||||||
int nfsvno_checkexp(mount_t, NFSSOCKADDR_T, struct nfsexstuff *,
|
int nfsvno_checkexp(mount_t, NFSSOCKADDR_T, struct nfsexstuff *,
|
||||||
struct ucred **);
|
struct ucred **);
|
||||||
|
|
|
||||||
|
|
@ -996,7 +996,11 @@ struct nfsv3_sattr {
|
||||||
NFSATTRBM_TIMEDELTA | \
|
NFSATTRBM_TIMEDELTA | \
|
||||||
NFSATTRBM_TIMEMETADATA | \
|
NFSATTRBM_TIMEMETADATA | \
|
||||||
NFSATTRBM_TIMEMODIFY | \
|
NFSATTRBM_TIMEMODIFY | \
|
||||||
NFSATTRBM_MOUNTEDONFILEID)
|
NFSATTRBM_MOUNTEDONFILEID | \
|
||||||
|
NFSATTRBM_QUOTAHARD | \
|
||||||
|
NFSATTRBM_QUOTASOFT | \
|
||||||
|
NFSATTRBM_QUOTAUSED)
|
||||||
|
|
||||||
|
|
||||||
#ifdef QUOTA
|
#ifdef QUOTA
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1008,7 +1008,7 @@ nfsvno_getsymlink(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||||
*pathcpp = NULL;
|
*pathcpp = NULL;
|
||||||
*lenp = 0;
|
*lenp = 0;
|
||||||
if ((nd->nd_flag & ND_NFSV3) &&
|
if ((nd->nd_flag & ND_NFSV3) &&
|
||||||
(error = nfsrv_sattr(nd, nvap, NULL, NULL, p)))
|
(error = nfsrv_sattr(nd, NULL, nvap, NULL, NULL, p)))
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
len = fxdr_unsigned(int, *tl);
|
len = fxdr_unsigned(int, *tl);
|
||||||
|
|
@ -2298,7 +2298,7 @@ nfsmout:
|
||||||
* (Return 0 or EBADRPC)
|
* (Return 0 or EBADRPC)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
nfsrv_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
nfsrv_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap,
|
||||||
nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p)
|
nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p)
|
||||||
{
|
{
|
||||||
u_int32_t *tl;
|
u_int32_t *tl;
|
||||||
|
|
@ -2380,7 +2380,7 @@ nfsrv_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case ND_NFSV4:
|
case ND_NFSV4:
|
||||||
error = nfsv4_sattr(nd, nvap, attrbitp, aclp, p);
|
error = nfsv4_sattr(nd, vp, nvap, attrbitp, aclp, p);
|
||||||
};
|
};
|
||||||
nfsmout:
|
nfsmout:
|
||||||
NFSEXITCODE2(error, nd);
|
NFSEXITCODE2(error, nd);
|
||||||
|
|
@ -2392,7 +2392,7 @@ nfsmout:
|
||||||
* Returns NFSERR_BADXDR if it can't be parsed, 0 otherwise.
|
* Returns NFSERR_BADXDR if it can't be parsed, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap,
|
||||||
nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p)
|
nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p)
|
||||||
{
|
{
|
||||||
u_int32_t *tl;
|
u_int32_t *tl;
|
||||||
|
|
@ -2429,6 +2429,11 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||||
switch (bitpos) {
|
switch (bitpos) {
|
||||||
case NFSATTRBIT_SIZE:
|
case NFSATTRBIT_SIZE:
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER);
|
||||||
|
if (vp != NULL && vp->v_type != VREG) {
|
||||||
|
error = (vp->v_type == VDIR) ? NFSERR_ISDIR :
|
||||||
|
NFSERR_INVAL;
|
||||||
|
goto nfsmout;
|
||||||
|
}
|
||||||
nvap->na_size = fxdr_hyper(tl);
|
nvap->na_size = fxdr_hyper(tl);
|
||||||
attrsum += NFSX_HYPER;
|
attrsum += NFSX_HYPER;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,17 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
|
||||||
if (nd->nd_repstat == 0) {
|
if (nd->nd_repstat == 0) {
|
||||||
accmode = 0;
|
accmode = 0;
|
||||||
NFSSET_ATTRBIT(&tmpbits, &attrbits);
|
NFSSET_ATTRBIT(&tmpbits, &attrbits);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GETATTR with write-only attr time_access_set and time_modify_set
|
||||||
|
* should return NFS4ERR_INVAL.
|
||||||
|
*/
|
||||||
|
if (NFSISSET_ATTRBIT(&tmpbits, NFSATTRBIT_TIMEACCESSSET) ||
|
||||||
|
NFSISSET_ATTRBIT(&tmpbits, NFSATTRBIT_TIMEMODIFYSET)){
|
||||||
|
error = NFSERR_INVAL;
|
||||||
|
vput(vp);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (NFSISSET_ATTRBIT(&tmpbits, NFSATTRBIT_ACL)) {
|
if (NFSISSET_ATTRBIT(&tmpbits, NFSATTRBIT_ACL)) {
|
||||||
NFSCLRBIT_ATTRBIT(&tmpbits, NFSATTRBIT_ACL);
|
NFSCLRBIT_ATTRBIT(&tmpbits, NFSATTRBIT_ACL);
|
||||||
accmode |= VREAD_ACL;
|
accmode |= VREAD_ACL;
|
||||||
|
|
@ -315,7 +326,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
|
stateid.seqid = fxdr_unsigned(u_int32_t, *tl++);
|
||||||
NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER);
|
NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER);
|
||||||
}
|
}
|
||||||
error = nfsrv_sattr(nd, &nva, &attrbits, aclp, p);
|
error = nfsrv_sattr(nd, vp, &nva, &attrbits, aclp, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
preat_ret = nfsvno_getattr(vp, &nva2, nd->nd_cred, p, 1);
|
preat_ret = nfsvno_getattr(vp, &nva2, nd->nd_cred, p, 1);
|
||||||
|
|
@ -1019,7 +1030,7 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case NFSCREATE_GUARDED:
|
case NFSCREATE_GUARDED:
|
||||||
case NFSCREATE_UNCHECKED:
|
case NFSCREATE_UNCHECKED:
|
||||||
error = nfsrv_sattr(nd, &nva, NULL, NULL, p);
|
error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1204,7 +1215,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
vtyp = nfsv34tov_type(*tl);
|
vtyp = nfsv34tov_type(*tl);
|
||||||
}
|
}
|
||||||
error = nfsrv_sattr(nd, &nva, &attrbits, aclp, p);
|
error = nfsrv_sattr(nd, NULL, &nva, &attrbits, aclp, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
nva.na_type = vtyp;
|
nva.na_type = vtyp;
|
||||||
|
|
@ -1850,7 +1861,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
NFSVNO_ATTRINIT(&nva);
|
NFSVNO_ATTRINIT(&nva);
|
||||||
if (nd->nd_flag & ND_NFSV3) {
|
if (nd->nd_flag & ND_NFSV3) {
|
||||||
error = nfsrv_sattr(nd, &nva, NULL, NULL, p);
|
error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1967,11 +1978,21 @@ nfsrvd_commit(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
int error = 0, for_ret = 1, aft_ret = 1, cnt;
|
int error = 0, for_ret = 1, aft_ret = 1, cnt;
|
||||||
u_int64_t off;
|
u_int64_t off;
|
||||||
|
|
||||||
if (nd->nd_repstat) {
|
if (nd->nd_repstat) {
|
||||||
nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft);
|
nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return NFSERR_ISDIR in NFSv4 when commit on a directory. */
|
||||||
|
if (vp->v_type != VREG) {
|
||||||
|
if (nd->nd_flag & ND_NFSV3)
|
||||||
|
error = NFSERR_NOTSUPP;
|
||||||
|
else
|
||||||
|
error = (vp->v_type == VDIR) ? NFSERR_ISDIR : NFSERR_INVAL;
|
||||||
|
goto nfsmout;
|
||||||
|
}
|
||||||
NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX At this time VOP_FSYNC() does not accept offset and byte
|
* XXX At this time VOP_FSYNC() does not accept offset and byte
|
||||||
* count parameters, so these arguments are useless (someday maybe).
|
* count parameters, so these arguments are useless (someday maybe).
|
||||||
|
|
@ -2683,7 +2704,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case NFSCREATE_UNCHECKED:
|
case NFSCREATE_UNCHECKED:
|
||||||
case NFSCREATE_GUARDED:
|
case NFSCREATE_GUARDED:
|
||||||
error = nfsv4_sattr(nd, &nva, &attrbits, aclp, p);
|
error = nfsv4_sattr(nd, NULL, &nva, &attrbits, aclp, p);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
/*
|
/*
|
||||||
|
|
@ -2707,7 +2728,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF);
|
||||||
cverf[0] = *tl++;
|
cverf[0] = *tl++;
|
||||||
cverf[1] = *tl;
|
cverf[1] = *tl;
|
||||||
error = nfsv4_sattr(nd, &nva, &attrbits, aclp, p);
|
error = nfsv4_sattr(nd, vp, &nva, &attrbits, aclp, p);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
if (NFSISSET_ATTRBIT(&attrbits,
|
if (NFSISSET_ATTRBIT(&attrbits,
|
||||||
|
|
@ -2858,7 +2879,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
* The IETF working group decided that this is the correct
|
* The IETF working group decided that this is the correct
|
||||||
* error return for all non-regular files.
|
* error return for all non-regular files.
|
||||||
*/
|
*/
|
||||||
nd->nd_repstat = NFSERR_SYMLINK;
|
nd->nd_repstat = (vp->v_type == VDIR) ? NFSERR_ISDIR : NFSERR_SYMLINK;
|
||||||
}
|
}
|
||||||
if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_WRITEACCESS))
|
if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_WRITEACCESS))
|
||||||
nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred,
|
nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred,
|
||||||
|
|
@ -3197,6 +3218,11 @@ nfsrvd_opendowngrade(struct nfsrv_descript *nd, __unused int isdgram,
|
||||||
nfsv4stateid_t stateid;
|
nfsv4stateid_t stateid;
|
||||||
nfsquad_t clientid;
|
nfsquad_t clientid;
|
||||||
|
|
||||||
|
/* opendowngrade can only work on a file object.*/
|
||||||
|
if (vp->v_type != VREG) {
|
||||||
|
error = NFSERR_INVAL;
|
||||||
|
goto nfsmout;
|
||||||
|
}
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 3 * NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 3 * NFSX_UNSIGNED);
|
||||||
stp->ls_ownerlen = 0;
|
stp->ls_ownerlen = 0;
|
||||||
stp->ls_op = nd->nd_rp;
|
stp->ls_op = nd->nd_rp;
|
||||||
|
|
|
||||||
|
|
@ -1628,9 +1628,17 @@ tryagain:
|
||||||
*/
|
*/
|
||||||
if (error == 0 && (stp->ls_flags & NFSLCK_OPEN) &&
|
if (error == 0 && (stp->ls_flags & NFSLCK_OPEN) &&
|
||||||
((stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM) ||
|
((stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM) ||
|
||||||
(getlckret == 0 && stp->ls_lfp != lfp)))
|
(getlckret == 0 && stp->ls_lfp != lfp))){
|
||||||
error = NFSERR_BADSTATEID;
|
/*
|
||||||
if (error == 0 &&
|
* NFSLCK_SETATTR should return OK rather than NFSERR_BADSTATEID
|
||||||
|
* The only exception is using SETATTR with SIZE.
|
||||||
|
* */
|
||||||
|
if ((new_stp->ls_flags &
|
||||||
|
(NFSLCK_SETATTR | NFSLCK_CHECK)) != NFSLCK_SETATTR)
|
||||||
|
error = NFSERR_BADSTATEID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == 0 &&
|
||||||
(stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) &&
|
(stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) &&
|
||||||
getlckret == 0 && stp->ls_lfp != lfp)
|
getlckret == 0 && stp->ls_lfp != lfp)
|
||||||
error = NFSERR_BADSTATEID;
|
error = NFSERR_BADSTATEID;
|
||||||
|
|
@ -4909,12 +4917,17 @@ tryagain:
|
||||||
* Now, look for a conflicting open share.
|
* Now, look for a conflicting open share.
|
||||||
*/
|
*/
|
||||||
if (remove) {
|
if (remove) {
|
||||||
LIST_FOREACH(stp, &lfp->lf_open, ls_file) {
|
/*
|
||||||
if (stp->ls_flags & NFSLCK_WRITEDENY) {
|
* If the entry in the directory was the last reference to the
|
||||||
error = NFSERR_FILEOPEN;
|
* corresponding filesystem object, the object can be destroyed
|
||||||
break;
|
* */
|
||||||
|
if(lfp->lf_usecount>1)
|
||||||
|
LIST_FOREACH(stp, &lfp->lf_open, ls_file) {
|
||||||
|
if (stp->ls_flags & NFSLCK_WRITEDENY) {
|
||||||
|
error = NFSERR_FILEOPEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NFSUNLOCKSTATE();
|
NFSUNLOCKSTATE();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue