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>