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:
Brian Feldman 2000-04-26 11:57:45 +00:00
parent 6ed16f20c3
commit b7db19017b
8 changed files with 116 additions and 216 deletions

View File

@ -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 *));

View File

@ -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);
}

View File

@ -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));

View File

@ -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);
}

View File

@ -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 *));

View File

@ -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);
}

View File

@ -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));

View File

@ -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 *));