Author: mjg
Date: Sat Feb  1 20:38:38 2020
New Revision: 357387
URL: https://svnweb.freebsd.org/changeset/base/357387

Log:
  cache: replace kern___getcwd with vn_getcwd
  
  The previous routine was resulting in extra data copies most notably in
  linux_getcwd.

Modified:
  head/sys/compat/linux/linux_getcwd.c
  head/sys/kern/kern_sig.c
  head/sys/kern/vfs_cache.c
  head/sys/sys/syscallsubr.h
  head/sys/sys/vnode.h

Modified: head/sys/compat/linux/linux_getcwd.c
==============================================================================
--- head/sys/compat/linux/linux_getcwd.c        Sat Feb  1 20:38:22 2020        
(r357386)
+++ head/sys/compat/linux/linux_getcwd.c        Sat Feb  1 20:38:38 2020        
(r357387)
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/syscallsubr.h>
+#include <sys/vnode.h>
 #include <sys/proc.h>
 #include <sys/malloc.h>
 
@@ -60,28 +60,25 @@ __FBSDID("$FreeBSD$");
  * Find pathname of process's current directory.
  */
 int
-linux_getcwd(struct thread *td, struct linux_getcwd_args *args)
+linux_getcwd(struct thread *td, struct linux_getcwd_args *uap)
 {
-       char *path;
-       int error, lenused;
+       char *buf, *retbuf;
+       size_t buflen;
+       int error;
 
-       /*
-        * Linux returns ERANGE instead of EINVAL.
-        */
-       if (args->bufsize < 2)
+       buflen = uap->bufsize;
+       if (__predict_false(buflen < 2))
                return (ERANGE);
+       if (buflen > LINUX_PATH_MAX)
+               buflen = LINUX_PATH_MAX;
 
-       path = malloc(LINUX_PATH_MAX, M_LINUX, M_WAITOK);
-
-       error = kern___getcwd(td, path, UIO_SYSSPACE, args->bufsize,
-           LINUX_PATH_MAX);
+       buf = malloc(buflen, M_TEMP, M_WAITOK);
+       error = vn_getcwd(td, buf, &retbuf, &buflen);
        if (error == 0) {
-               lenused = strlen(path) + 1;
-               error = copyout(path, args->buf, lenused);
+               error = copyout(retbuf, uap->buf, buflen);
                if (error == 0)
-                       td->td_retval[0] = lenused;
+                       td->td_retval[0] = buflen;
        }
-
-       free(path, M_LINUX);
+       free(buf, M_TEMP);
        return (error);
 }

Modified: head/sys/kern/kern_sig.c
==============================================================================
--- head/sys/kern/kern_sig.c    Sat Feb  1 20:38:22 2020        (r357386)
+++ head/sys/kern/kern_sig.c    Sat Feb  1 20:38:38 2020        (r357387)
@@ -3608,6 +3608,7 @@ coredump(struct thread *td)
        struct vnode *vp;
        struct flock lf;
        struct vattr vattr;
+       size_t fullpathsize;
        int error, error1, locked;
        char *name;                     /* name of corefile */
        void *rl_cookie;
@@ -3711,13 +3712,14 @@ coredump(struct thread *td)
         * if the path of the core is relative, add the current dir in front if 
it.
         */
        if (name[0] != '/') {
-               fullpath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
-               if (kern___getcwd(td, fullpath, UIO_SYSSPACE, MAXPATHLEN, 
MAXPATHLEN) != 0) {
-                       free(fullpath, M_TEMP);
+               fullpathsize = MAXPATHLEN;
+               freepath = malloc(fullpathsize, M_TEMP, M_WAITOK);
+               if (vn_getcwd(td, freepath, &fullpath, &fullpathsize) != 0) {
+                       free(freepath, M_TEMP);
                        goto out2;
                }
                devctl_safe_quote_sb(sb, fullpath);
-               free(fullpath, M_TEMP);
+               free(freepath, M_TEMP);
                sbuf_putc(sb, '/');
        }
        devctl_safe_quote_sb(sb, name);

Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c   Sat Feb  1 20:38:22 2020        (r357386)
+++ head/sys/kern/vfs_cache.c   Sat Feb  1 20:38:38 2020        (r357387)
@@ -364,7 +364,7 @@ STATNODE_COUNTER(numposhits, "Number of cache hits (po
 STATNODE_COUNTER(numnegzaps,
     "Number of cache hits (negative) we do not want to cache");
 STATNODE_COUNTER(numneghits, "Number of cache hits (negative)");
-/* These count for kern___getcwd(), too. */
+/* These count for vn_getcwd(), too. */
 STATNODE_COUNTER(numfullpathcalls, "Number of fullpath search calls");
 STATNODE_COUNTER(numfullpathfail1, "Number of fullpath search errors 
(ENOTDIR)");
 STATNODE_COUNTER(numfullpathfail2,
@@ -2171,26 +2171,31 @@ vfs_cache_lookup(struct vop_lookup_args *ap)
 int
 sys___getcwd(struct thread *td, struct __getcwd_args *uap)
 {
+       char *buf, *retbuf;
+       size_t buflen;
+       int error;
 
-       return (kern___getcwd(td, uap->buf, UIO_USERSPACE, uap->buflen,
-           MAXPATHLEN));
+       buflen = uap->buflen;
+       if (__predict_false(buflen < 2))
+               return (EINVAL);
+       if (buflen > MAXPATHLEN)
+               buflen = MAXPATHLEN;
+
+       buf = malloc(buflen, M_TEMP, M_WAITOK);
+       error = vn_getcwd(td, buf, &retbuf, &buflen);
+       if (error == 0)
+               error = copyout(retbuf, uap->buf, buflen);
+       free(buf, M_TEMP);
+       return (error);
 }
 
 int
-kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen,
-    size_t path_max)
+vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
 {
-       char *bp, *tmpbuf;
        struct filedesc *fdp;
        struct vnode *cdir, *rdir;
        int error;
 
-       if (__predict_false(buflen < 2))
-               return (EINVAL);
-       if (buflen > path_max)
-               buflen = path_max;
-
-       tmpbuf = malloc(buflen, M_TEMP, M_WAITOK);
        fdp = td->td_proc->p_fd;
        FILEDESC_SLOCK(fdp);
        cdir = fdp->fd_cdir;
@@ -2198,21 +2203,14 @@ kern___getcwd(struct thread *td, char *buf, enum uio_s
        rdir = fdp->fd_rdir;
        vrefact(rdir);
        FILEDESC_SUNLOCK(fdp);
-       error = vn_fullpath1(td, cdir, rdir, tmpbuf, &bp, &buflen);
+       error = vn_fullpath1(td, cdir, rdir, buf, retbuf, buflen);
        vrele(rdir);
        vrele(cdir);
 
-       if (!error) {
-               if (bufseg == UIO_SYSSPACE)
-                       bcopy(bp, buf, buflen);
-               else
-                       error = copyout(bp, buf, buflen);
 #ifdef KTRACE
-       if (KTRPOINT(curthread, KTR_NAMEI))
-               ktrnamei(bp);
+       if (KTRPOINT(curthread, KTR_NAMEI) && error == 0)
+               ktrnamei(*retbuf);
 #endif
-       }
-       free(tmpbuf, M_TEMP);
        return (error);
 }
 
@@ -2338,7 +2336,7 @@ vn_vptocnp(struct vnode **vp, struct ucred *cred, char
 }
 
 /*
- * The magic behind kern___getcwd() and vn_fullpath().
+ * The magic behind vn_getcwd() and vn_fullpath().
  */
 static int
 vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h  Sat Feb  1 20:38:22 2020        (r357386)
+++ head/sys/sys/syscallsubr.h  Sat Feb  1 20:38:38 2020        (r357387)
@@ -65,8 +65,6 @@ struct uio;
 
 typedef int (*mmap_check_fp_fn)(struct file *, int, int, int);
 
-int    kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg,
-           size_t buflen, size_t path_max);
 int    kern_accept(struct thread *td, int s, struct sockaddr **name,
            socklen_t *namelen, struct file **fp);
 int    kern_accept4(struct thread *td, int s, struct sockaddr **name,

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Sat Feb  1 20:38:22 2020        (r357386)
+++ head/sys/sys/vnode.h        Sat Feb  1 20:38:38 2020        (r357387)
@@ -632,6 +632,7 @@ u_quad_t init_va_filerev(void);
 int    speedup_syncer(void);
 int    vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf,
            size_t *buflen);
+int    vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen);
 int    vn_fullpath(struct thread *td, struct vnode *vn,
            char **retbuf, char **freebuf);
 int    vn_fullpath_global(struct thread *td, struct vnode *vn,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to