Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Sep 2019 21:53:45 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r351833 - in projects/nfsv42/sys/fs: nfs nfsserver
Message-ID:  <201909042153.x84Lrj9R013585@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Sep  4 21:53:45 2019
New Revision: 351833
URL: https://svnweb.freebsd.org/changeset/base/351833

Log:
  Factor out the code that creates an iovec from nfsvno_write().
  
  This patch factors out the code that creates an iovec from nfsvno_write()
  and modifies nfsvno_setxattr() to use it as well.
  It also modifies nfsvno_readlink() to use the nfsrv_createiovec() function
  already committed to create an iovec for nfsvno_read() and nfsvno_getxattr().

Modified:
  projects/nfsv42/sys/fs/nfs/nfs_var.h
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c

Modified: projects/nfsv42/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv42/sys/fs/nfs/nfs_var.h	Wed Sep  4 21:43:52 2019	(r351832)
+++ projects/nfsv42/sys/fs/nfs/nfs_var.h	Wed Sep  4 21:53:45 2019	(r351833)
@@ -673,8 +673,8 @@ int nfsvno_readlink(vnode_t, struct ucred *, NFSPROC_T
     mbuf_t *, int *);
 int nfsvno_read(vnode_t, off_t, int, struct ucred *, NFSPROC_T *,
     mbuf_t *, mbuf_t *);
-int nfsvno_write(vnode_t, off_t, int, int, int *, mbuf_t,
-    char *, struct ucred *, NFSPROC_T *);
+int nfsvno_write(vnode_t, off_t, int, int *, mbuf_t, char *, struct ucred *,
+    NFSPROC_T *);
 int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *,
     vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T,
     struct nfsexstuff *);
@@ -737,8 +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 *);
+int nfsvno_setxattr(struct vnode *, char *, int, struct mbuf *, char *,
+    struct ucred *, struct thread *);
 
 /* nfs_commonkrpc.c */
 int newnfs_nmcancelreqs(struct nfsmount *);

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Wed Sep  4 21:43:52 2019	(r351832)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Wed Sep  4 21:53:45 2019	(r351833)
@@ -108,6 +108,8 @@ extern struct nfsdevicehead nfsrv_devidhead;
 
 static int nfsrv_createiovec(int, struct mbuf **, struct mbuf **,
     struct iovec **);
+static int nfsrv_createiovecw(int, struct mbuf *, char *, struct iovec **,
+    int *);
 static void nfsrv_pnfscreate(struct vnode *, struct vattr *, struct ucred *,
     NFSPROC_T *);
 static void nfsrv_pnfsremovesetup(struct vnode *, NFSPROC_T *, struct vnode **,
@@ -726,43 +728,21 @@ int
 nfsvno_readlink(struct vnode *vp, struct ucred *cred, struct thread *p,
     struct mbuf **mpp, struct mbuf **mpendp, int *lenp)
 {
-	struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
-	struct iovec *ivp = iv;
+	struct iovec *iv;
 	struct uio io, *uiop = &io;
-	struct mbuf *mp, *mp2 = NULL, *mp3 = NULL;
-	int i, len, tlen, error = 0;
+	struct mbuf *mp, *mp3;
+	int len, tlen, error = 0;
 
-	len = 0;
-	i = 0;
-	while (len < NFS_MAXPATHLEN) {
-		NFSMGET(mp);
-		MCLGET(mp, M_WAITOK);
-		mp->m_len = M_SIZE(mp);
-		if (len == 0) {
-			mp3 = mp2 = mp;
-		} else {
-			mp2->m_next = mp;
-			mp2 = mp;
-		}
-		if ((len + mp->m_len) > NFS_MAXPATHLEN) {
-			mp->m_len = NFS_MAXPATHLEN - len;
-			len = NFS_MAXPATHLEN;
-		} else {
-			len += mp->m_len;
-		}
-		ivp->iov_base = mtod(mp, caddr_t);
-		ivp->iov_len = mp->m_len;
-		i++;
-		ivp++;
-	}
+	len = NFS_MAXPATHLEN;
+	uiop->uio_iovcnt = nfsrv_createiovec(len, &mp3, &mp, &iv);
 	uiop->uio_iov = iv;
-	uiop->uio_iovcnt = i;
 	uiop->uio_offset = 0;
 	uiop->uio_resid = len;
 	uiop->uio_rw = UIO_READ;
 	uiop->uio_segflg = UIO_SYSSPACE;
 	uiop->uio_td = NULL;
 	error = VOP_READLINK(vp, uiop, cred);
+	free(iv, M_TEMP);
 	if (error) {
 		m_freem(mp3);
 		*lenp = 0;
@@ -898,34 +878,44 @@ out:
 }
 
 /*
- * Write vnode op from an mbuf list.
+ * Create the iovec for the mbuf chain passed in as an argument.
+ * The "cp" argument is where the data starts within the first mbuf in
+ * the chain. It returns the iovec and the iovcnt.
  */
-int
-nfsvno_write(struct vnode *vp, off_t off, int retlen, int cnt, int *stable,
-    struct mbuf *mp, char *cp, struct ucred *cred, struct thread *p)
+static int
+nfsrv_createiovecw(int retlen, struct mbuf *m, char *cp, struct iovec **ivpp,
+    int *iovcntp)
 {
+	struct mbuf *mp;
 	struct iovec *ivp;
-	int i, len;
-	struct iovec *iv;
-	int ioflags, error;
-	struct uio io, *uiop = &io;
-	struct nfsheur *nh;
+	int cnt, i, len;
 
 	/*
-	 * Attempt to write to a DS file. A return of ENOENT implies
-	 * there is no DS file to write.
+	 * Loop through the mbuf chain, counting how many mbufs are a
+	 * part of this write operation, so the iovec size is known.
 	 */
-	error = nfsrv_proxyds(NULL, vp, off, retlen, cred, p, NFSPROC_WRITEDS,
-	    &mp, cp, NULL, NULL, NULL, NULL, 0, NULL);
-	if (error != ENOENT) {
-		*stable = NFSWRITE_FILESYNC;
-		return (error);
+	cnt = 0;
+	len = retlen;
+	mp = m;
+	i = mtod(mp, caddr_t) + mbuf_len(mp) - cp;
+	while (len > 0) {
+		if (i > 0) {
+			len -= i;
+			cnt++;
+		}
+		mp = mbuf_next(mp);
+		if (!mp) {
+			if (len > 0)
+				return (EBADRPC);
+		} else
+			i = mbuf_len(mp);
 	}
 
-	ivp = malloc(cnt * sizeof (struct iovec), M_TEMP,
+	/* Now, create the iovec. */
+	mp = m;
+	*ivpp = ivp = malloc(cnt * sizeof (struct iovec), M_TEMP,
 	    M_WAITOK);
-	uiop->uio_iov = iv = ivp;
-	uiop->uio_iovcnt = cnt;
+	*iovcntp = cnt;
 	i = mtod(mp, caddr_t) + mp->m_len - cp;
 	len = retlen;
 	while (len > 0) {
@@ -944,11 +934,42 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, 
 			cp = mtod(mp, caddr_t);
 		}
 	}
+	return (0);
+}
 
+/*
+ * Write vnode op from an mbuf list.
+ */
+int
+nfsvno_write(struct vnode *vp, off_t off, int retlen, int *stable,
+    struct mbuf *mp, char *cp, struct ucred *cred, struct thread *p)
+{
+	struct iovec *iv;
+	int cnt, ioflags, error;
+	struct uio io, *uiop = &io;
+	struct nfsheur *nh;
+
+	/*
+	 * Attempt to write to a DS file. A return of ENOENT implies
+	 * there is no DS file to write.
+	 */
+	error = nfsrv_proxyds(NULL, vp, off, retlen, cred, p, NFSPROC_WRITEDS,
+	    &mp, cp, NULL, NULL, NULL, NULL, 0, NULL);
+	if (error != ENOENT) {
+		*stable = NFSWRITE_FILESYNC;
+		return (error);
+	}
+
+
 	if (*stable == NFSWRITE_UNSTABLE)
 		ioflags = IO_NODELOCKED;
 	else
 		ioflags = (IO_SYNC | IO_NODELOCKED);
+	error = nfsrv_createiovecw(retlen, mp, cp, &iv, &cnt);
+	if (error != 0)
+		return (error);
+	uiop->uio_iov = iv;
+	uiop->uio_iovcnt = cnt;
 	uiop->uio_resid = retlen;
 	uiop->uio_rw = UIO_WRITE;
 	uiop->uio_segflg = UIO_SYSSPACE;
@@ -5952,23 +5973,35 @@ out:
  * 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)
+nfsvno_setxattr(struct vnode *vp, char *name, int len, struct mbuf *m,
+    char *cp, struct ucred *cred, struct thread *p)
 {
-	int error;
+	struct iovec *iv;
+	struct uio uio, *uiop = &uio;
+	int cnt, error;
 
-	error = 0;
 #ifdef MAC
 	error = mac_vnode_check_setextattr(cred, vp, EXTATTR_NAMESPACE_USER,
 	    name);
+	if (error != 0)
+		goto out;
 #endif
 
-	if (error == 0)
+	uiop->uio_rw = UIO_WRITE;
+	uiop->uio_segflg = UIO_SYSSPACE;
+	uiop->uio_td = p;
+	uiop->uio_offset = 0;
+	uiop->uio_resid = len;
+	error = nfsrv_createiovecw(len, m, cp, &iv, &cnt);
+	uiop->uio_iov = iv;
+	uiop->uio_iovcnt = cnt;
+	if (error == 0) {
 		error = VOP_SETEXTATTR(vp, EXTATTR_NAMESPACE_USER, name, uiop,
 		    cred, p);
-	if (error == 0 && uiop->uio_resid > 0)
-		error = NFSERR_XATTR2BIG;
+		free(iv, M_TEMP);
+	}
 
+out:
 	NFSEXITCODE(error);
 	return (error);
 }

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Wed Sep  4 21:43:52 2019	(r351832)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Wed Sep  4 21:53:45 2019	(r351833)
@@ -869,9 +869,7 @@ APPLESTATIC int
 nfsrvd_write(struct nfsrv_descript *nd, __unused int isdgram,
     vnode_t vp, struct nfsexstuff *exp)
 {
-	int i, cnt;
 	u_int32_t *tl;
-	mbuf_t mp;
 	struct nfsvattr nva, forat;
 	int aftat_ret = 1, retlen, len, error = 0, forat_ret = 1;
 	int gotproxystateid, stable = NFSWRITE_FILESYNC;
@@ -953,28 +951,6 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
 			lop->lo_end = NFS64BITSSET;
 	}
 
-	/*
-	 * Loop through the mbuf chain, counting how many mbufs are a
-	 * part of this write operation, so the iovec size is known.
-	 */
-	cnt = 0;
-	mp = nd->nd_md;
-	i = NFSMTOD(mp, caddr_t) + mbuf_len(mp) - nd->nd_dpos;
-	while (len > 0) {
-		if (i > 0) {
-			len -= i;
-			cnt++;
-		}
-		mp = mbuf_next(mp);
-		if (!mp) {
-			if (len > 0) {
-				error = EBADRPC;
-				goto nfsmout;
-			}
-		} else
-			i = mbuf_len(mp);
-	}
-
 	if (retlen > NFS_SRVMAXIO || retlen < 0)
 		nd->nd_repstat = EIO;
 	if (vnode_vtype(vp) != VREG && !nd->nd_repstat) {
@@ -1016,7 +992,7 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i
 	 * which is to return ok so long as there are no permission problems.
 	 */
 	if (retlen > 0) {
-		nd->nd_repstat = nfsvno_write(vp, off, retlen, cnt, &stable,
+		nd->nd_repstat = nfsvno_write(vp, off, retlen, &stable,
 		    nd->nd_md, nd->nd_dpos, nd->nd_cred, p);
 		error = nfsm_advance(nd, NFSM_RNDUP(retlen), -1);
 		if (error)
@@ -5538,11 +5514,9 @@ nfsrvd_setxattr(struct nfsrv_descript *nd, __unused in
 {
 	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;
+	int error, len, opt, retlen;
 	char *name;
 	struct thread *p = curthread;
 
@@ -5599,65 +5573,18 @@ nfsrvd_setxattr(struct nfsrv_descript *nd, __unused in
 	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, len, nd->nd_md,
+		    nd->nd_dpos, nd->nd_cred, p);
+		if (nd->nd_repstat == ENXIO)
+			nd->nd_repstat = NFSERR_XATTR2BIG;
+	}
 	if (nd->nd_repstat == 0)
-		nd->nd_repstat = nfsvno_setxattr(vp, name, uiop, nd->nd_cred,
-		    p);
-	free(iv, M_TEMP);
+		nd->nd_repstat = nfsm_advance(nd, NFSM_RNDUP(len), -1);
 	if (nd->nd_repstat == 0)
 		nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, &attrbits);
 	if (nd->nd_repstat == 0) {



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