svn commit: r357387 - in head/sys: compat/linux kern sys
Mateusz Guzik
mjg at FreeBSD.org
Sat Feb 1 20:38:39 UTC 2020
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,
More information about the svn-src-all
mailing list