Move procfs_fullpath() to vfs_cache.c, with a rename to textvp_fullpath().
There's no excuse to have code in synthetic filestores that allows direct references to the textvp anymore. Feature requested by: msmith Feature agreed to by: warner Move requested by: phk Move agreed to by: bde
This commit is contained in:
parent
6ed16f20c3
commit
b7db19017b
@ -140,7 +140,6 @@ int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct
|
||||
int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_fullpath __P((struct proc *p, char **retbuf, char **retfreebuf));
|
||||
|
||||
/* Return 1 if process has special kernel digging privileges */
|
||||
int procfs_kmemaccess __P((struct proc *));
|
||||
|
@ -410,99 +410,3 @@ procfs_exit(struct proc *p)
|
||||
pfs = pfs->pfs_next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Thus begins the fullpath magic.
|
||||
*/
|
||||
|
||||
SYSCTL_DECL(_vfs_cache);
|
||||
|
||||
#define STATNODE(name) \
|
||||
static u_int name; \
|
||||
SYSCTL_INT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
|
||||
|
||||
static int disablefullpath;
|
||||
SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW,
|
||||
&disablefullpath, 0, "");
|
||||
|
||||
STATNODE(numfullpathcalls);
|
||||
STATNODE(numfullpathfail1);
|
||||
STATNODE(numfullpathfail2);
|
||||
STATNODE(numfullpathfail3);
|
||||
STATNODE(numfullpathfail4);
|
||||
STATNODE(numfullpathfound);
|
||||
|
||||
int
|
||||
procfs_fullpath(struct proc *p, char **retbuf, char **retfreebuf) {
|
||||
char *bp, *buf;
|
||||
int i, slash_prefixed;
|
||||
struct filedesc *fdp;
|
||||
struct namecache *ncp;
|
||||
struct vnode *vp, *textvp;
|
||||
|
||||
numfullpathcalls++;
|
||||
if (disablefullpath)
|
||||
return (ENODEV);
|
||||
textvp = p->p_textvp;
|
||||
if (textvp == NULL)
|
||||
return (EINVAL);
|
||||
buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
bp = buf + MAXPATHLEN - 1;
|
||||
*bp = '\0';
|
||||
fdp = p->p_fd;
|
||||
slash_prefixed = 0;
|
||||
for (vp = textvp; vp != fdp->fd_rdir && vp != rootvnode;) {
|
||||
if (vp->v_flag & VROOT) {
|
||||
if (vp->v_mount == NULL) { /* forced unmount */
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
vp = vp->v_mount->mnt_vnodecovered;
|
||||
continue;
|
||||
}
|
||||
if (vp != textvp && vp->v_dd->v_id != vp->v_ddid) {
|
||||
numfullpathfail1++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOTDIR);
|
||||
}
|
||||
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
||||
if (!ncp) {
|
||||
numfullpathfail2++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOENT);
|
||||
}
|
||||
if (vp != textvp && ncp->nc_dvp != vp->v_dd) {
|
||||
numfullpathfail3++;
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = ncp->nc_name[i];
|
||||
}
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
slash_prefixed = 1;
|
||||
vp = ncp->nc_dvp;
|
||||
}
|
||||
if (!slash_prefixed) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
}
|
||||
numfullpathfound++;
|
||||
*retbuf = bp;
|
||||
*retfreebuf = buf;
|
||||
return (0);
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ procfs_getattr(ap)
|
||||
|
||||
case Pfile: {
|
||||
char *fullpath, *freepath;
|
||||
error = procfs_fullpath(procp, &fullpath, &freepath);
|
||||
error = textvp_fullpath(procp, &fullpath, &freepath);
|
||||
if (error == 0) {
|
||||
vap->va_size = strlen(fullpath);
|
||||
free(freepath, M_TEMP);
|
||||
@ -968,7 +968,7 @@ procfs_readlink(ap)
|
||||
return (uiomove("unknown", sizeof("unknown") - 1,
|
||||
ap->a_uio));
|
||||
}
|
||||
error = procfs_fullpath(procp, &fullpath, &freepath);
|
||||
error = textvp_fullpath(procp, &fullpath, &freepath);
|
||||
if (error != 0)
|
||||
return (uiomove("unknown", sizeof("unknown") - 1,
|
||||
ap->a_uio));
|
||||
|
@ -49,6 +49,22 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/filedesc.h>
|
||||
|
||||
/*
|
||||
* This structure describes the elements in the cache of recent
|
||||
* names looked up by namei.
|
||||
*/
|
||||
|
||||
struct namecache {
|
||||
LIST_ENTRY(namecache) nc_hash; /* hash chain */
|
||||
LIST_ENTRY(namecache) nc_src; /* source vnode list */
|
||||
TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */
|
||||
struct vnode *nc_dvp; /* vnode of parent of name */
|
||||
struct vnode *nc_vp; /* vnode the name refers to */
|
||||
u_char nc_flag; /* flag bits */
|
||||
u_char nc_nlen; /* length of name */
|
||||
char nc_name[0]; /* segment name */
|
||||
};
|
||||
|
||||
/*
|
||||
* Name caching works as follows:
|
||||
*
|
||||
@ -571,3 +587,97 @@ __getcwd(p, uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thus begins the fullpath magic.
|
||||
*/
|
||||
|
||||
#undef STATNODE
|
||||
#define STATNODE(name) \
|
||||
static u_int name; \
|
||||
SYSCTL_INT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
|
||||
|
||||
static int disablefullpath;
|
||||
SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW,
|
||||
&disablefullpath, 0, "");
|
||||
|
||||
STATNODE(numfullpathcalls);
|
||||
STATNODE(numfullpathfail1);
|
||||
STATNODE(numfullpathfail2);
|
||||
STATNODE(numfullpathfail3);
|
||||
STATNODE(numfullpathfail4);
|
||||
STATNODE(numfullpathfound);
|
||||
|
||||
int
|
||||
textvp_fullpath(struct proc *p, char **retbuf, char **retfreebuf) {
|
||||
char *bp, *buf;
|
||||
int i, slash_prefixed;
|
||||
struct filedesc *fdp;
|
||||
struct namecache *ncp;
|
||||
struct vnode *vp, *textvp;
|
||||
|
||||
numfullpathcalls++;
|
||||
if (disablefullpath)
|
||||
return (ENODEV);
|
||||
textvp = p->p_textvp;
|
||||
if (textvp == NULL)
|
||||
return (EINVAL);
|
||||
buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
bp = buf + MAXPATHLEN - 1;
|
||||
*bp = '\0';
|
||||
fdp = p->p_fd;
|
||||
slash_prefixed = 0;
|
||||
for (vp = textvp; vp != fdp->fd_rdir && vp != rootvnode;) {
|
||||
if (vp->v_flag & VROOT) {
|
||||
if (vp->v_mount == NULL) { /* forced unmount */
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
vp = vp->v_mount->mnt_vnodecovered;
|
||||
continue;
|
||||
}
|
||||
if (vp != textvp && vp->v_dd->v_id != vp->v_ddid) {
|
||||
numfullpathfail1++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOTDIR);
|
||||
}
|
||||
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
||||
if (!ncp) {
|
||||
numfullpathfail2++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOENT);
|
||||
}
|
||||
if (vp != textvp && ncp->nc_dvp != vp->v_dd) {
|
||||
numfullpathfail3++;
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = ncp->nc_name[i];
|
||||
}
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
slash_prefixed = 1;
|
||||
vp = ncp->nc_dvp;
|
||||
}
|
||||
if (!slash_prefixed) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
}
|
||||
numfullpathfound++;
|
||||
*retbuf = bp;
|
||||
*retfreebuf = buf;
|
||||
return (0);
|
||||
}
|
||||
|
@ -140,7 +140,6 @@ int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct
|
||||
int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_fullpath __P((struct proc *p, char **retbuf, char **retfreebuf));
|
||||
|
||||
/* Return 1 if process has special kernel digging privileges */
|
||||
int procfs_kmemaccess __P((struct proc *));
|
||||
|
@ -410,99 +410,3 @@ procfs_exit(struct proc *p)
|
||||
pfs = pfs->pfs_next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Thus begins the fullpath magic.
|
||||
*/
|
||||
|
||||
SYSCTL_DECL(_vfs_cache);
|
||||
|
||||
#define STATNODE(name) \
|
||||
static u_int name; \
|
||||
SYSCTL_INT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
|
||||
|
||||
static int disablefullpath;
|
||||
SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW,
|
||||
&disablefullpath, 0, "");
|
||||
|
||||
STATNODE(numfullpathcalls);
|
||||
STATNODE(numfullpathfail1);
|
||||
STATNODE(numfullpathfail2);
|
||||
STATNODE(numfullpathfail3);
|
||||
STATNODE(numfullpathfail4);
|
||||
STATNODE(numfullpathfound);
|
||||
|
||||
int
|
||||
procfs_fullpath(struct proc *p, char **retbuf, char **retfreebuf) {
|
||||
char *bp, *buf;
|
||||
int i, slash_prefixed;
|
||||
struct filedesc *fdp;
|
||||
struct namecache *ncp;
|
||||
struct vnode *vp, *textvp;
|
||||
|
||||
numfullpathcalls++;
|
||||
if (disablefullpath)
|
||||
return (ENODEV);
|
||||
textvp = p->p_textvp;
|
||||
if (textvp == NULL)
|
||||
return (EINVAL);
|
||||
buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
bp = buf + MAXPATHLEN - 1;
|
||||
*bp = '\0';
|
||||
fdp = p->p_fd;
|
||||
slash_prefixed = 0;
|
||||
for (vp = textvp; vp != fdp->fd_rdir && vp != rootvnode;) {
|
||||
if (vp->v_flag & VROOT) {
|
||||
if (vp->v_mount == NULL) { /* forced unmount */
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
vp = vp->v_mount->mnt_vnodecovered;
|
||||
continue;
|
||||
}
|
||||
if (vp != textvp && vp->v_dd->v_id != vp->v_ddid) {
|
||||
numfullpathfail1++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOTDIR);
|
||||
}
|
||||
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
||||
if (!ncp) {
|
||||
numfullpathfail2++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOENT);
|
||||
}
|
||||
if (vp != textvp && ncp->nc_dvp != vp->v_dd) {
|
||||
numfullpathfail3++;
|
||||
free(buf, M_TEMP);
|
||||
return (EBADF);
|
||||
}
|
||||
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = ncp->nc_name[i];
|
||||
}
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
slash_prefixed = 1;
|
||||
vp = ncp->nc_dvp;
|
||||
}
|
||||
if (!slash_prefixed) {
|
||||
if (bp == buf) {
|
||||
numfullpathfail4++;
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
*--bp = '/';
|
||||
}
|
||||
numfullpathfound++;
|
||||
*retbuf = bp;
|
||||
*retfreebuf = buf;
|
||||
return (0);
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ procfs_getattr(ap)
|
||||
|
||||
case Pfile: {
|
||||
char *fullpath, *freepath;
|
||||
error = procfs_fullpath(procp, &fullpath, &freepath);
|
||||
error = textvp_fullpath(procp, &fullpath, &freepath);
|
||||
if (error == 0) {
|
||||
vap->va_size = strlen(fullpath);
|
||||
free(freepath, M_TEMP);
|
||||
@ -968,7 +968,7 @@ procfs_readlink(ap)
|
||||
return (uiomove("unknown", sizeof("unknown") - 1,
|
||||
ap->a_uio));
|
||||
}
|
||||
error = procfs_fullpath(procp, &fullpath, &freepath);
|
||||
error = textvp_fullpath(procp, &fullpath, &freepath);
|
||||
if (error != 0)
|
||||
return (uiomove("unknown", sizeof("unknown") - 1,
|
||||
ap->a_uio));
|
||||
|
@ -74,24 +74,7 @@ enum vtagtype {
|
||||
TAILQ_HEAD(buflists, buf);
|
||||
|
||||
typedef int vop_t __P((void *));
|
||||
|
||||
/*
|
||||
* This structure describes the elements in the cache of recent
|
||||
* names looked up by namei.
|
||||
*/
|
||||
|
||||
struct vnode;
|
||||
|
||||
struct namecache {
|
||||
LIST_ENTRY(namecache) nc_hash; /* hash chain */
|
||||
LIST_ENTRY(namecache) nc_src; /* source vnode list */
|
||||
TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */
|
||||
struct vnode *nc_dvp; /* vnode of parent of name */
|
||||
struct vnode *nc_vp; /* vnode the name refers to */
|
||||
u_char nc_flag; /* flag bits */
|
||||
u_char nc_nlen; /* length of name */
|
||||
char nc_name[0]; /* segment name */
|
||||
};
|
||||
struct namecache;
|
||||
|
||||
/*
|
||||
* Reading or writing any of these items requires holding the appropriate lock.
|
||||
@ -567,6 +550,7 @@ int getnewvnode __P((enum vtagtype tag,
|
||||
int lease_check __P((struct vop_lease_args *ap));
|
||||
int spec_vnoperate __P((struct vop_generic_args *));
|
||||
int speedup_syncer __P((void));
|
||||
int textvp_fullpath __P((struct proc *p, char **retbuf, char **retfreebuf));
|
||||
void vattr_null __P((struct vattr *vap));
|
||||
int vcount __P((struct vnode *vp));
|
||||
void vdrop __P((struct vnode *));
|
||||
|
Loading…
x
Reference in New Issue
Block a user