svn commit: r351833 - in projects/nfsv42/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Wed Sep 4 21:53:46 UTC 2019
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) {
More information about the svn-src-projects
mailing list