Re: [Ms-nfs41-client-devel] FreeBSD-16.0-CURRENT-amd64-20260224: NFSv4.2 on Windows: mkdir fails, touch works
Rick Macklem <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.hackers |
|---|---|
| Message-ID | <CAM5tNy4Ca+fqSw9mrmpDbAWWu4ViBHDgk1rQSHV_GPdvkZiv8w@mail.gmail.com> |
On Mon, Mar 9, 2026 at 9:43 AM Roland Mainz <[email protected]> wrote: > > On Sat, Mar 7, 2026 at 10:28 PM Rick Macklem <[email protected]> wrote: > > > > On Sat, Mar 7, 2026 at 9:27 AM Dan Shelton <[email protected]> wrote: > > > > > > Hello, > > > > > > some odd issue with FreeBSD 16.0-CURRENT main-n284403-895a97c875a0 > > > (installed from > > > FreeBSD-16.0-CURRENT-amd64-20260224-16822dac32ab-284159-disc1.iso) and > > > ms-nfs41-client: > > > $ /sbin/nfs_mount -o rw 'F:' 'nfs://42.28.16.228//nfsdata' > > > Successfully mounted '42.28.16.228@NFS@2049' to drive 'F:' > > > $ cd /cygdrive/f/dsheldon/tmp/freebsdtests > > > > > > $ touch x > > > $ mkdir y_dir > > > mkdir: cannot create directory ‘y_dir’: Permission denied > > > > > > I tried this: > > > $ chmod a+rwx . > > > $ mkdir y_dir > > > mkdir: cannot create directory ‘y_dir’: Permission denied > > > > > > > > > No ACLs involved. > > > The same setup works with FreeBSD 15.0. > > > > > > How can I debug this, or is this a known issue? > > Hmm. I don't think anything has changed for mkdir between > > 15.0 and man/16 in the NFS server code. Yep, the change was that FreeBSD16 supports Archive, but didn't handle setting it when doing a CREATE operation. > > > > - If the mkdir request (actually MKNOD in NFSv4) specifies > > an owner or owner_group, the permissions are checked as follows: > > - For setting owner to anything other than the uid of the caller in > > the RPC request's credentials, the caller must be root and the > > file system exported -maproot=root. > > - For setting an owner_group, the gid owner_group maps to must > > be in the gid list of the RPC's credentials. > > > > I'd suggest you capture packets when the mkdir fails and then.. > > - Either look at them in wireshark yourself and see what attributes > > are being set by the operation. In particular, check for any ACL > > being specified (I know you said ACLs are not involved, but..) > > along with OWNER and OWNER_GROUP. > > or > > - Make the packet capture available to me and I'll look at it. > > > > I suspect the NFS4ERR_PERM is being generated because of > > the attributes being set by the MKNOD operation and I suspect > > there is some difference between how you have 15.0 configured > > and main/16 configured. > [snip] > > It seems to be an issue with |FATTR4_ARCHIVE| ... I filed > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=293691 ("NFSv4.1 > client trying to set |FATTR4_ARCHIVE| gets EPERM for file/dir creation > attempts") for this, and added > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=292283 ("Bug 292283 > - (JAVA) NFSv4.1 client trying to set FATTR4_SYSTEM or FATTR4_HIDDEN > gets EPERM for file and dir creation attemps") as reference since the > same kind of workaround seems to work. > > Next release for ms-nfs41-client includes a workaround (see > https://github.com/kofemann/ms-nfs41-client/commit/7156d9f9deb25843e57fd455d8ec67951b82c737) > which should avoid this bug, but I will remove that workaround as soon > as a fixed release version of FreeBSD will become available... I've put a patch on this FreeBSD PR and am attaching it here. I will commit it soon to main and MFC it in time for the FreeBSD-15.1 release. I think you'll find that, for a main (FreeBSD-16) server, Open/Create does handle Archive. rick > > ---- > > Bye, > Roland > -- > __ . . __ > (o.\ \/ /.o) [email protected] > \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer > /O /==\ O\ TEL +49 641 3992797 > (;O/ \/ \O;) >
mkdirflags.patch
(application/octet-stream, 2.3 KB)
--- sys/fs/nfsserver/nfs_nfsdserv.c.mkdirflags 2026-03-09 14:10:48.537380000 -0700
+++ sys/fs/nfsserver/nfs_nfsdserv.c 2026-03-09 16:06:07.342968000 -0700
@@ -1416,12 +1416,13 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
vnode_t vp, dirp = NULL;
nfsattrbit_t attrbits;
char *bufp = NULL, *pathcp = NULL;
- u_long *hashp, cnflags;
+ u_long *hashp, cnflags, setflags;
NFSACL_T *aclp = NULL;
struct thread *p = curthread;
NFSVNO_ATTRINIT(&nva);
cnflags = LOCKPARENT;
+ setflags = (u_long)VNOVAL;
if (nd->nd_repstat) {
nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
goto out;
@@ -1576,9 +1577,16 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int i
}
}
+ /* For NFSv4, set na_flags via nfsrv_fixattr(). */
+ if (nd->nd_flag & ND_NFSV4) {
+ setflags = nva.na_flags;
+ nva.na_flags = VNOVAL;
+ }
nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p);
if (!nd->nd_repstat) {
vp = named.ni_vp;
+ if (nd->nd_flag & ND_NFSV4)
+ nva.na_flags = setflags;
nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, false);
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat)
@@ -2084,10 +2092,14 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct na
int pathlen)
{
u_int32_t *tl;
+ u_long setflags;
+ setflags = nvap->na_flags;
+ nvap->na_flags = (u_long)VNOVAL;
nd->nd_repstat = nfsvno_symlink(ndp, nvap, pathcp, pathlen,
!(nd->nd_flag & ND_NFSV2), nd->nd_saveduid, nd->nd_cred, p, exp);
if (!nd->nd_repstat && !(nd->nd_flag & ND_NFSV2)) {
+ nvap->na_flags = setflags;
nfsrv_fixattr(nd, ndp->ni_vp, nvap, aclp, p, attrbitp, false);
if (nd->nd_flag & ND_NFSV3) {
nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p);
@@ -2216,12 +2228,16 @@ nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct name
{
vnode_t vp;
u_int32_t *tl;
+ u_long setflags;
+ setflags = nvap->na_flags;
+ nvap->na_flags = (u_long)VNOVAL;
NFSVNO_SETATTRVAL(nvap, type, VDIR);
nd->nd_repstat = nfsvno_mkdir(ndp, nvap, nd->nd_saveduid,
nd->nd_cred, p, exp);
if (!nd->nd_repstat) {
vp = ndp->ni_vp;
+ nvap->na_flags = setflags;
nfsrv_fixattr(nd, vp, nvap, aclp, p, attrbitp, false);
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)