Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Sep 2019 04:57:58 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r351652 - in projects/nfsv42/sys/fs: nfs nfsclient nfsserver
Message-ID:  <201909010457.x814vwjS092517@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sun Sep  1 04:57:58 2019
New Revision: 351652
URL: https://svnweb.freebsd.org/changeset/base/351652

Log:
  Add the Set Extended attribute operation.
  
  RFC-8276 defines optional Extended attribute operations. This patch adds
  the set extended attribute operation. It also applies one fix to the
  get attribute operation added yesterday.

Modified:
  projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
  projects/nfsv42/sys/fs/nfs/nfs_var.h
  projects/nfsv42/sys/fs/nfs/nfsport.h
  projects/nfsv42/sys/fs/nfs/nfsproto.h
  projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c
  projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c

Modified: projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfs/nfs_commonsubs.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -181,7 +181,7 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = {
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Write Same */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Clone */
 	{ 0, 1, 0, 0, LK_SHARED, 1, 1 },		/* Getxattr */
-	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Setxattr */
+	{ 0, 1, 1, 1, LK_EXCLUSIVE, 1, 1 },		/* Setxattr */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Listxattrs */
 	{ 0, 0, 0, 0, LK_EXCLUSIVE, 1, 1 },		/* Removexattr */
 };
@@ -211,7 +211,7 @@ static struct nfsrv_lughash	*nfsgroupnamehash;
 static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-    0 };
+    0, 0 };
 
 /* local functions */
 static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -291,6 +291,7 @@ static struct {
 	{ NFSV4OP_SEEK, 2, "Seek", 4, },
 	{ NFSV4OP_SEEK, 1, "SeekDS", 6, },
 	{ NFSV4OP_GETXATTR, 2, "Getxattr", 8, },
+	{ NFSV4OP_SETXATTR, 2, "Setxattr", 8, },
 };
 
 /*
@@ -299,7 +300,7 @@ static struct {
 static int nfs_bigrequest[NFSV42_NPROCS] = {
 	0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 /*

Modified: projects/nfsv42/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_var.h	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfs/nfs_var.h	Sun Sep  1 04:57:58 2019	(r351652)
@@ -285,6 +285,8 @@ int nfsrvd_seek(struct nfsrv_descript *, int,
     vnode_t, struct nfsexstuff *);
 int nfsrvd_getxattr(struct nfsrv_descript *, int,
     vnode_t, struct nfsexstuff *);
+int nfsrvd_setxattr(struct nfsrv_descript *, int,
+    vnode_t, struct nfsexstuff *);
 int nfsrvd_notsupp(struct nfsrv_descript *, int,
     vnode_t, struct nfsexstuff *);
 
@@ -548,6 +550,8 @@ int nfsrpc_seek(vnode_t, off_t *, bool *, int, struct 
     struct nfsvattr *, int *);
 int nfsrpc_getextattr(vnode_t, const char *, struct uio *, ssize_t *,
     struct nfsvattr *, int *, struct ucred *, NFSPROC_T *);
+int nfsrpc_setextattr(vnode_t, const char *, struct uio *, struct nfsvattr *,
+    int *, struct ucred *, NFSPROC_T *);
 
 /* nfs_clstate.c */
 int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int,
@@ -733,6 +737,8 @@ int nfsvno_seek(struct nfsrv_descript *, struct vnode 
     bool *, struct ucred *, NFSPROC_T *);
 int nfsvno_getxattr(struct vnode *, char *, struct ucred *, struct thread *,
     struct mbuf **, struct mbuf **, int *);
+int nfsvno_setxattr(struct vnode *, char *, struct uio *, struct ucred *,
+    struct thread *);
 
 /* nfs_commonkrpc.c */
 int newnfs_nmcancelreqs(struct nfsmount *);

Modified: projects/nfsv42/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfsport.h	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfs/nfsport.h	Sun Sep  1 04:57:58 2019	(r351652)
@@ -408,11 +408,12 @@
 
 /* and the ones for the optional Extended attribute support (RFC-8276). */
 #define	NFSPROC_GETEXTATTR	61
+#define	NFSPROC_SETEXTATTR	62
 
 /*
  * Must be defined as one higher than the last NFSv4.2 Proc# above.
  */
-#define	NFSV42_NPROCS		62
+#define	NFSV42_NPROCS		63
 
 #endif	/* NFS_V3NPROCS */
 
@@ -441,7 +442,7 @@ struct nfsstatsv1 {
 	uint64_t	readlink_bios;
 	uint64_t	biocache_readdirs;
 	uint64_t	readdir_bios;
-	uint64_t	rpccnt[NFSV42_NPROCS + 7];
+	uint64_t	rpccnt[NFSV42_NPROCS + 6];
 	uint64_t	rpcretries;
 	uint64_t	srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS];
 	uint64_t	srvrpc_errs;

Modified: projects/nfsv42/sys/fs/nfs/nfsproto.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfsproto.h	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfs/nfsproto.h	Sun Sep  1 04:57:58 2019	(r351652)
@@ -390,11 +390,12 @@
 
 /* and the ones for the optional Extended attribute support (RFC-8276). */
 #define	NFSPROC_GETEXTATTR	61
+#define	NFSPROC_SETEXTATTR	62
 
 /*
  * Must be defined as one higher than the last NFSv4.2 Proc# above.
  */
-#define	NFSV42_NPROCS		62
+#define	NFSV42_NPROCS		63
 
 #endif	/* NFS_V3NPROCS */
 
@@ -1490,5 +1491,10 @@ typedef struct nfsv4stateid nfsv4stateid_t;
 /* Seek Contents. */
 #define	NFSV4CONTENT_DATA	0
 #define	NFSV4CONTENT_HOLE	1
+
+/* Options for Set Extended attribute (RFC-8276). */
+#define	NFSV4SXATTR_EITHER	0
+#define	NFSV4SXATTR_CREATE	1
+#define	NFSV4SXATTR_REPLACE	2
 
 #endif	/* _NFS_NFSPROTO_H_ */

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -8278,9 +8278,10 @@ nfsrpc_getextattr(vnode_t vp, const char *name, struct
 				if (error == 0) {
 					/*
 					 * nfsm_mbufuio() advances to a multiple
-					 * of 4, so advance len2 as well.  Then
+					 * of 4, so round up len2 as well.  Then
 					 * we need to advance over the rest of
-					 * the data.
+					 * the data, rounding up the remaining
+					 * length.
 					 */
 					len2 = NFSM_RNDUP(len2);
 					len2 = NFSM_RNDUP(len - len2);
@@ -8291,7 +8292,7 @@ nfsrpc_getextattr(vnode_t vp, const char *name, struct
 			}
 		} else if (uiop == NULL && len > 0) {
 			/* Just wants the length and not the data. */
-			error = nfsm_advance(nd, len, -1);
+			error = nfsm_advance(nd, NFSM_RNDUP(len), -1);
 		} else
 			error = ENOATTR;
 		if (error != 0)
@@ -8299,6 +8300,49 @@ nfsrpc_getextattr(vnode_t vp, const char *name, struct
 		*lenp = len;
 		/* Just skip over Getattr op status. */
 		NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+		error = nfsm_loadattr(nd, nap);
+		if (error == 0)
+			*attrflagp = 1;
+	}
+	if (error == 0)
+		error = nd->nd_repstat;
+nfsmout:
+	mbuf_freem(nd->nd_mrep);
+	return (error);
+}
+
+/*
+ * The setextattr RPC.
+ */
+APPLESTATIC int
+nfsrpc_setextattr(vnode_t vp, const char *name, struct uio *uiop,
+    struct nfsvattr *nap, int *attrflagp, struct ucred *cred, NFSPROC_T *p)
+{
+	uint32_t *tl;
+	int error;
+	struct nfsrv_descript nfsd;
+	struct nfsrv_descript *nd = &nfsd;
+	nfsattrbit_t attrbits;
+
+	*attrflagp = 0;
+	NFSCL_REQSTART(nd, NFSPROC_SETEXTATTR, vp);
+	NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+	*tl = txdr_unsigned(NFSV4SXATTR_EITHER);
+	nfsm_strtom(nd, name, strlen(name));
+	NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+	*tl = txdr_unsigned(uiop->uio_resid);
+	nfsm_uiombuf(nd, uiop, uiop->uio_resid);
+	NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+	*tl = txdr_unsigned(NFSV4OP_GETATTR);
+	NFSGETATTR_ATTRBIT(&attrbits);
+	nfsrv_putattrbit(nd, &attrbits);
+	error = nfscl_request(nd, vp, p, cred, NULL);
+	if (error != 0)
+		return (error);
+	if (nd->nd_repstat == 0) {
+		/* Just skip over the reply and Getattr op status. */
+		NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_HYPER + 3 *
+		    NFSX_UNSIGNED);
 		error = nfsm_loadattr(nd, nap);
 		if (error == 0)
 			*attrflagp = 1;

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -149,6 +149,7 @@ static vop_allocate_t nfs_allocate;
 static vop_copy_file_range_t nfs_copy_file_range;
 static vop_ioctl_t nfs_ioctl;
 static vop_getextattr_t nfs_getextattr;
+static vop_setextattr_t nfs_setextattr;
 
 /*
  * Global vfs data structures for nfs
@@ -191,6 +192,7 @@ static struct vop_vector newnfs_vnodeops_nosig = {
 	.vop_copy_file_range =	nfs_copy_file_range,
 	.vop_ioctl =		nfs_ioctl,
 	.vop_getextattr =	nfs_getextattr,
+	.vop_setextattr =	nfs_setextattr,
 };
 
 static int
@@ -3790,7 +3792,63 @@ nfs_getextattr(struct vop_getextattr_args *ap)
 	switch (error) {
 	case NFSERR_NOTSUPP:
 	case NFSERR_OPILLEGAL:
-	case NFSERR_MINORVERMISMATCH:
+		mtx_lock(&nmp->nm_mtx);
+		nmp->nm_privflag |= NFSMNTP_NOXATTR;
+		mtx_unlock(&nmp->nm_mtx);
+		error = EOPNOTSUPP;
+		break;
+	case NFSERR_NOXATTR:
+	case NFSERR_XATTR2BIG:
+		error = ENOATTR;
+		break;
+	default:
+		error = nfscl_maperr(td, error, 0, 0);
+		break;
+	}
+	return (error);
+}
+
+/*
+ * nfs setextattr call
+ */
+static int
+nfs_setextattr(struct vop_setextattr_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct nfsmount *nmp;
+	struct ucred *cred;
+	struct thread *td = ap->a_td;
+	struct nfsvattr nfsva;
+	int attrflag, error, ret;
+
+	nmp = VFSTONFS(vp->v_mount);
+	mtx_lock(&nmp->nm_mtx);
+	if (!NFSHASNFSV4(nmp) || nmp->nm_minorvers < NFSV42_MINORVERSION ||
+	    (nmp->nm_privflag & NFSMNTP_NOXATTR) != 0 ||
+	    ap->a_attrnamespace != EXTATTR_NAMESPACE_USER) {
+		mtx_unlock(&nmp->nm_mtx);
+		return (EOPNOTSUPP);
+	}
+	mtx_unlock(&nmp->nm_mtx);
+
+	if (ap->a_uio->uio_resid <= 0 || ap->a_uio->uio_resid > nmp->nm_wsize)
+		return (EINVAL);
+	cred = ap->a_cred;
+	if (cred == NULL)
+		cred = td->td_ucred;
+	/* Do the actual NFSv4.2 Optional Extended Attribute (RFC-8276) RPC. */
+	attrflag = 0;
+	error = nfsrpc_setextattr(vp, ap->a_name, ap->a_uio, &nfsva,
+	    &attrflag, cred, td);
+	if (attrflag != 0) {
+		ret = nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
+		if (error == 0 && ret != 0)
+			error = ret;
+	}
+
+	switch (error) {
+	case NFSERR_NOTSUPP:
+	case NFSERR_OPILLEGAL:
 		mtx_lock(&nmp->nm_mtx);
 		nmp->nm_privflag |= NFSMNTP_NOXATTR;
 		mtx_unlock(&nmp->nm_mtx);

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -5947,6 +5947,31 @@ out:
 	return (error);
 }
 
+/*
+ * Set Extended attribute vnode op from an mbuf list.
+ */
+int
+nfsvno_setxattr(struct vnode *vp, char *name, struct uio *uiop,
+    struct ucred *cred, struct thread *p)
+{
+	int error;
+
+	error = 0;
+#ifdef MAC
+	error = mac_vnode_check_setextattr(cred, vp, EXTATTR_NAMESPACE_USER,
+	    name);
+#endif
+
+	if (error == 0)
+		error = VOP_SETEXTATTR(vp, EXTATTR_NAMESPACE_USER, name, uiop,
+		    cred, p);
+	if (error == 0 && uiop->uio_resid > 0)
+		error = NFSERR_XATTR2BIG;
+
+	NFSEXITCODE(error);
+	return (error);
+}
+
 extern int (*nfsd_call_nfsd)(struct thread *, struct nfssvc_args *);
 
 /*

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -5530,6 +5530,153 @@ nfsmout:
 }
 
 /*
+ * nfs set extended attribute service
+ */
+APPLESTATIC int
+nfsrvd_setxattr(struct nfsrv_descript *nd, __unused int isdgram,
+    vnode_t vp, __unused struct nfsexstuff *exp)
+{
+	uint32_t *tl;
+	mbuf_t mp = NULL, mpend = NULL;
+	struct iovec *ivp, *iv;
+	struct uio io, *uiop = &io;
+	struct nfsvattr ova, nva;
+	nfsattrbit_t attrbits;
+	int cnt, error, i, len, opt, rem, retlen;
+	char *name;
+	struct thread *p = curthread;
+
+	error = 0;
+	name = NULL;
+	if (nfs_rootfhset == 0 || nfsd_checkrootexp(nd) != 0) {
+		nd->nd_repstat = NFSERR_WRONGSEC;
+		goto nfsmout;
+	}
+	NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+	opt = fxdr_unsigned(int, *tl++);
+	len = fxdr_unsigned(int, *tl);
+	if (len <= 0) {
+		nd->nd_repstat = NFSERR_BADXDR;
+		goto nfsmout;
+	}
+	if (len > EXTATTR_MAXNAMELEN) {
+		nd->nd_repstat = NFSERR_NOXATTR;
+		goto nfsmout;
+	}
+	name = malloc(len + 1, M_TEMP, M_WAITOK);
+	error = nfsrv_mtostr(nd, name, len);
+	if (error != 0)
+		goto nfsmout;
+	NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+	len = fxdr_unsigned(int, *tl);
+	if (len <= 0 || len > IOSIZE_MAX) {
+		nd->nd_repstat = NFSERR_XATTR2BIG;
+		goto nfsmout;
+	}
+	switch (opt) {
+	case NFSV4SXATTR_CREATE:
+		error = nfsvno_getxattr(vp, name, nd->nd_cred, p, &mp, &mpend,
+		    &retlen);
+		if (error == 0)
+			m_freem(mp);
+		if (error != ENOATTR)
+			nd->nd_repstat = NFSERR_EXIST;
+		error = 0;
+		break;
+	case NFSV4SXATTR_REPLACE:
+		error = nfsvno_getxattr(vp, name, nd->nd_cred, p, &mp, &mpend,
+		    &retlen);
+		if (error == 0)
+			m_freem(mp);
+		else
+			nd->nd_repstat = NFSERR_NOXATTR;
+		break;
+	case NFSV4SXATTR_EITHER:
+		break;
+	default:
+		nd->nd_repstat = NFSERR_BADXDR;
+	}
+	if (nd->nd_repstat != 0)
+		goto nfsmout;
+
+	/* Figure out how many iovecs are needed. */
+	cnt = 1;
+	mp = nd->nd_md;
+	i = mp->m_len - (nd->nd_dpos - mtod(mp, char *));
+	while (i < len) {
+		mp = mp->m_next;
+		if (mp == NULL) {
+			nd->nd_repstat = NFSERR_BADXDR;
+			goto nfsmout;
+		}
+		i += mp->m_len;
+		cnt++;
+	}
+
+	/* Now create the uio structure and iovec. */
+	ivp = mallocarray(cnt, sizeof(*ivp), M_TEMP, M_WAITOK);
+	uiop->uio_iov = iv = ivp;
+	uiop->uio_iovcnt = cnt;
+	uiop->uio_resid = len;
+	rem = NFSM_RNDUP(len) - len;
+	cnt = len;
+	mp = nd->nd_md;
+	i = mp->m_len - (nd->nd_dpos - mtod(mp, char *));
+	while (cnt > 0) {
+		if (mp == NULL)
+			panic("nfsvno_write");
+		if (i > 0) {
+			i = min(i, cnt);
+			ivp->iov_base = nd->nd_dpos;
+			ivp->iov_len = i;
+			ivp++;
+			cnt -= i;
+			if (cnt == 0)
+				nd->nd_dpos += i;
+		}
+		if (cnt > 0) {
+			mp = mp->m_next;
+			if (mp != NULL) {
+				i = mp->m_len;
+				nd->nd_dpos = mtod(mp, caddr_t);
+			}
+		}
+	}
+	if (rem > 0)
+		nd->nd_dpos += rem;
+	nd->nd_md = mp;
+
+	uiop->uio_rw = UIO_WRITE;
+	uiop->uio_segflg = UIO_SYSSPACE;
+	uiop->uio_td = p;
+	uiop->uio_offset = 0;
+	/* Now, do the Set Extended attribute, with Change before and after. */
+	NFSZERO_ATTRBIT(&attrbits);
+	NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_CHANGE);
+	nd->nd_repstat = nfsvno_getattr(vp, &ova, nd, p, 1, &attrbits);
+	if (nd->nd_repstat == 0)
+		nd->nd_repstat = nfsvno_setxattr(vp, name, uiop, nd->nd_cred,
+		    p);
+	free(iv, M_TEMP);
+	if (nd->nd_repstat == 0)
+		nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, &attrbits);
+	if (nd->nd_repstat == 0) {
+		NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER + NFSX_UNSIGNED);
+		*tl++ = newnfs_true;
+		txdr_hyper(ova.na_filerev, tl); tl += 2;
+		txdr_hyper(nva.na_filerev, tl);
+	}
+
+nfsmout:
+	free(name, M_TEMP);
+	if (nd->nd_repstat == 0)
+		nd->nd_repstat = error;
+	vput(vp);
+	NFSEXITCODE2(0, nd);
+	return (0);
+}
+
+/*
  * nfsv4 service not supported
  */
 APPLESTATIC int

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Sun Sep  1 02:52:00 2019	(r351651)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdsocket.c	Sun Sep  1 04:57:58 2019	(r351652)
@@ -210,7 +210,7 @@ int (*nfsrv4_ops0[NFSV42_NOPS])(struct nfsrv_descript 
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 	nfsrvd_getxattr,
-	nfsrvd_notsupp,
+	nfsrvd_setxattr,
 	nfsrvd_notsupp,
 	nfsrvd_notsupp,
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909010457.x814vwjS092517>