cache: replace kern___getcwd with vn_getcwd
The previous routine was resulting in extra data copies most notably in linux_getcwd.
This commit is contained in:
parent
6a0086dd4d
commit
7739d92766
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357387
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -364,7 +364,7 @@ STATNODE_COUNTER(numposhits, "Number of cache hits (positive)");
|
||||
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_seg bufseg, size_t buflen,
|
||||
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 *buf, size_t *buflen)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user