mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
nfsd: Fix handling of attributes during Open/Create/Exclusive_41
When an NFSv4.n client specifies settings for attributes other mode during a Open/Create/Exclusive_41, these other attributes were not being set. This patch resolves the problem by calling nfsrv_fixsattr() after the VOP_CREATE() call in nfsvno_open() for this case. There is no extant NFSv4.n client that currently does this, as far as I know. MFC after: 2 weeks
This commit is contained in:
1 parent
51786cdeb0
commit
4fc11c92d3
6 files changed
+57
-17
No files matched your search
@@ -872,6 +872,11 @@ typedef enum { UNKNOWN=0, DELETED=1, NLINK_ZERO=2, VALID=3 } nfsremove_status;
|
||||
#define SUPPACL_NFSV4 1
|
||||
#define SUPPACL_POSIX 2
|
||||
|
||||
/* Values NFSv4 uses for exclusive_flag. */
|
||||
#define NFSV4_EXCLUSIVE_NONE 0
|
||||
#define NFSV4_EXCLUSIVE 1
|
||||
#define NFSV4_EXCLUSIVE_41 2
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NFS_NFS_H */
|
||||
@@ -410,7 +410,7 @@ int nfsv4_strtogid(struct nfsrv_descript *, u_char *, int, gid_t *);
|
||||
int nfsrv_checkuidgid(struct nfsrv_descript *, struct nfsvattr *);
|
||||
void nfsrv_fixattr(struct nfsrv_descript *, vnode_t,
|
||||
struct nfsvattr *, NFSACL_T *, NFSACL_T *, NFSPROC_T *, nfsattrbit_t *,
|
||||
struct nfsexstuff *);
|
||||
bool);
|
||||
int nfsrv_errmoved(int);
|
||||
int nfsrv_putreferralattr(struct nfsrv_descript *, nfsattrbit_t *,
|
||||
struct nfsreferral *, int, int *);
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#define NFSVNO_ISSETATIME(n) ((n)->na_atime.tv_sec != VNOVAL)
|
||||
#define NFSVNO_NOTSETMTIME(n) ((n)->na_mtime.tv_sec == VNOVAL)
|
||||
#define NFSVNO_ISSETMTIME(n) ((n)->na_mtime.tv_sec != VNOVAL)
|
||||
#define NFSVNO_NOTSETFLAGS(n) ((n)->na_flags == VNOVAL)
|
||||
#define NFSVNO_ISSETFLAGS(n) ((n)->na_flags != VNOVAL)
|
||||
|
||||
/*
|
||||
* This structure acts as a "catch-all" for information that
|
||||
|
||||
@@ -1972,6 +1972,7 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
NFSACL_T *aclp, NFSACL_T *daclp, nfsattrbit_t *attrbitp, struct ucred *cred,
|
||||
bool done_namei, struct nfsexstuff *exp, struct vnode **vpp)
|
||||
{
|
||||
struct vattr va;
|
||||
struct vnode *vp = NULL;
|
||||
u_quad_t tempsize;
|
||||
struct nfsexstuff nes;
|
||||
@@ -2018,23 +2019,52 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
&ndp->ni_vp : NULL, false);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
if (!nd->nd_repstat) {
|
||||
if (*exclusive_flagp) {
|
||||
*exclusive_flagp = 0;
|
||||
NFSVNO_ATTRINIT(nvap);
|
||||
nvap->na_atime.tv_sec = cverf[0];
|
||||
nvap->na_atime.tv_nsec = cverf[1];
|
||||
if (*exclusive_flagp != NFSV4_EXCLUSIVE_NONE) {
|
||||
VATTR_NULL(&va);
|
||||
va.va_atime.tv_sec = cverf[0];
|
||||
va.va_atime.tv_nsec = cverf[1];
|
||||
nd->nd_repstat = VOP_SETATTR(ndp->ni_vp,
|
||||
&nvap->na_vattr, cred);
|
||||
&va, cred);
|
||||
if (nd->nd_repstat != 0) {
|
||||
vput(ndp->ni_vp);
|
||||
ndp->ni_vp = NULL;
|
||||
nd->nd_repstat = NFSERR_NOTSUPP;
|
||||
} else
|
||||
} else {
|
||||
/*
|
||||
* Few clients set these
|
||||
* attributes in Open/Create
|
||||
* Exclusive_41. If this
|
||||
* changes, this should include
|
||||
* setting atime, instead of
|
||||
* the above.
|
||||
*/
|
||||
if (*exclusive_flagp ==
|
||||
NFSV4_EXCLUSIVE_41 &&
|
||||
(NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_OWNER) ||
|
||||
NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_OWNERGROUP) ||
|
||||
NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_TIMEMODIFYSET)||
|
||||
NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_ARCHIVE) ||
|
||||
NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_HIDDEN) ||
|
||||
NFSISSET_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_SYSTEM) ||
|
||||
aclp != NULL ||
|
||||
daclp != NULL))
|
||||
nfsrv_fixattr(nd,
|
||||
ndp->ni_vp, nvap,
|
||||
aclp, daclp, p,
|
||||
attrbitp, true);
|
||||
NFSSETBIT_ATTRBIT(attrbitp,
|
||||
NFSATTRBIT_TIMEACCESS);
|
||||
}
|
||||
*exclusive_flagp = NFSV4_EXCLUSIVE_NONE;
|
||||
} else {
|
||||
nfsrv_fixattr(nd, ndp->ni_vp, nvap,
|
||||
aclp, daclp, p, attrbitp, exp);
|
||||
aclp, daclp, p, attrbitp, false);
|
||||
}
|
||||
}
|
||||
vp = ndp->ni_vp;
|
||||
|
||||
@@ -1608,7 +1608,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p);
|
||||
if (!nd->nd_repstat) {
|
||||
vp = named.ni_vp;
|
||||
nfsrv_fixattr(nd, vp, &nva, aclp, daclp, p, &attrbits, exp);
|
||||
nfsrv_fixattr(nd, vp, &nva, aclp, daclp, p, &attrbits, false);
|
||||
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
|
||||
if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat)
|
||||
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1,
|
||||
@@ -2120,7 +2120,7 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
!(nd->nd_flag & ND_NFSV2), nd->nd_saveduid, nd->nd_cred, p, exp);
|
||||
if (!nd->nd_repstat && !(nd->nd_flag & ND_NFSV2)) {
|
||||
nfsrv_fixattr(nd, ndp->ni_vp, nvap, aclp, NULL, p, attrbitp,
|
||||
exp);
|
||||
false);
|
||||
if (nd->nd_flag & ND_NFSV3) {
|
||||
nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p);
|
||||
if (!nd->nd_repstat)
|
||||
@@ -2255,7 +2255,7 @@ nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
nd->nd_cred, p, exp);
|
||||
if (!nd->nd_repstat) {
|
||||
vp = ndp->ni_vp;
|
||||
nfsrv_fixattr(nd, vp, nvap, aclp, daclp, p, attrbitp, exp);
|
||||
nfsrv_fixattr(nd, vp, nvap, aclp, daclp, p, attrbitp, false);
|
||||
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
|
||||
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
|
||||
nd->nd_repstat = nfsvno_getattr(vp, nvap, nd, p, 1,
|
||||
@@ -2964,7 +2964,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
u_int32_t *tl;
|
||||
int i, retext;
|
||||
struct nfsstate *stp = NULL;
|
||||
int error = 0, create, claim, exclusive_flag = 0, override;
|
||||
int error = 0, create, claim, override;
|
||||
int exclusive_flag = NFSV4_EXCLUSIVE_NONE;
|
||||
u_int32_t rflags = NFSV4OPEN_LOCKTYPEPOSIX, acemask;
|
||||
int how = NFSCREATE_UNCHECKED;
|
||||
int32_t cverf[2], tverf[2] = { 0, 0 };
|
||||
@@ -3229,6 +3230,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
case NFSCREATE_EXCLUSIVE:
|
||||
if (nd->nd_repstat == 0 && named.ni_vp == NULL)
|
||||
nva.na_mode = 0;
|
||||
exclusive_flag = NFSV4_EXCLUSIVE;
|
||||
/* FALLTHROUGH */
|
||||
case NFSCREATE_EXCLUSIVE41:
|
||||
if (nd->nd_repstat == 0 && named.ni_vp != NULL) {
|
||||
@@ -3244,7 +3246,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
if (nd->nd_repstat != 0)
|
||||
done_namei = true;
|
||||
}
|
||||
exclusive_flag = 1;
|
||||
if (how == NFSCREATE_EXCLUSIVE41)
|
||||
exclusive_flag = NFSV4_EXCLUSIVE_41;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1645,7 +1645,7 @@ out:
|
||||
void
|
||||
nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
struct nfsvattr *nvap, NFSACL_T *aclp, NFSACL_T *daclp, NFSPROC_T *p,
|
||||
nfsattrbit_t *attrbitp, struct nfsexstuff *exp)
|
||||
nfsattrbit_t *attrbitp, bool atime_done)
|
||||
{
|
||||
int change = 0;
|
||||
struct nfsvattr nva;
|
||||
@@ -1675,7 +1675,7 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
}
|
||||
}
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_TIMEACCESSSET) &&
|
||||
NFSVNO_ISSETATIME(nvap)) {
|
||||
!atime_done && NFSVNO_ISSETATIME(nvap)) {
|
||||
nva.na_atime = nvap->na_atime;
|
||||
change++;
|
||||
NFSSETBIT_ATTRBIT(&nattrbits, NFSATTRBIT_TIMEACCESSSET);
|
||||
@@ -1736,7 +1736,7 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
}
|
||||
}
|
||||
if (change) {
|
||||
error = nfsvno_setattr(vp, &nva, nd->nd_cred, p, exp);
|
||||
error = nfsvno_setattr(vp, &nva, nd->nd_cred, p, NULL);
|
||||
if (error) {
|
||||
NFSCLRALL_ATTRBIT(attrbitp, &nattrbits);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user