Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Mar 2026 16:36:43 -0700
From:      Rick Macklem <rick.macklem@gmail.com>
To:        Roland Mainz <roland.mainz@nrubsig.org>
Cc:        freebsd-hackers@freebsd.org, ms-nfs41-client-devel@lists.sourceforge.net
Subject:   Re: [Ms-nfs41-client-devel] FreeBSD-16.0-CURRENT-amd64-20260224: NFSv4.2 on Windows: mkdir fails, touch works
Message-ID:  <CAM5tNy4Ca%2BfqSw9mrmpDbAWWu4ViBHDgk1rQSHV_GPdvkZiv8w@mail.gmail.com>
In-Reply-To: <CAKAoaQkY8G0Y%2B0wTfT1jer8_QxAmwtnk9EH1eTQJf9FQCGbX9Q@mail.gmail.com>
References:  <CAAvCNcAVcXUsjZy2XH7MJ4rY85efQAd2cnHuS6cvOUiAksTF1A@mail.gmail.com> <CAM5tNy4z=DD_F4LEnOsXKqM8feN9f1_e_z_whYcDOXM%2BDfpADw@mail.gmail.com> <CAKAoaQkY8G0Y%2B0wTfT1jer8_QxAmwtnk9EH1eTQJf9FQCGbX9Q@mail.gmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On Mon, Mar 9, 2026 at 9:43 AM Roland Mainz <roland.mainz@nrubsig.org> wrote:
>
> On Sat, Mar 7, 2026 at 10:28 PM Rick Macklem <rick.macklem@gmail.com> wrote:
> >
> > On Sat, Mar 7, 2026 at 9:27 AM Dan Shelton <dan.f.shelton@gmail.com> 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) roland.mainz@nrubsig.org
>   \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
>   /O /==\ O\  TEL +49 641 3992797
>  (;O/ \/ \O;)
>

[-- Attachment #2 --]
--- 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)
home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAM5tNy4Ca%2BfqSw9mrmpDbAWWu4ViBHDgk1rQSHV_GPdvkZiv8w>