diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-04-30 01:03:52 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-04-30 01:03:52 +0000 |
commit | 5036769aa39703d4943918586791a962aac14dfe (patch) | |
tree | 83f54c9c73dbda459e9e9fe087e6b20fc6dc1d33 /sys/kern | |
parent | 5d87051bab21ea2e1ed16dddf71cde8c502679a6 (diff) |
Prune remaining of the code, no binary change
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_getcwd.c | 175 |
1 files changed, 53 insertions, 122 deletions
diff --git a/sys/kern/vfs_getcwd.c b/sys/kern/vfs_getcwd.c index ee47a2136eb..0e7df91bf0d 100644 --- a/sys/kern/vfs_getcwd.c +++ b/sys/kern/vfs_getcwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_getcwd.c,v 1.4 2006/04/30 00:34:34 pedro Exp $ */ +/* $OpenBSD: vfs_getcwd.c,v 1.5 2006/04/30 01:03:51 pedro Exp $ */ /* $NetBSD: vfs_getcwd.c,v 1.3.2.3 1999/07/11 10:24:09 sommerfeld Exp $ */ /* @@ -50,69 +50,35 @@ #include <sys/uio.h> #include <sys/malloc.h> #include <sys/dirent.h> -#include <ufs/ufs/dir.h> /* XXX only for DIRBLKSIZ */ +#include <ufs/ufs/dir.h> /* only for DIRBLKSIZ */ #include <sys/syscallargs.h> -static int getcwd_scandir(struct vnode **, struct vnode **, - char **, char *, struct proc *); +static int getcwd_scandir(struct vnode **, struct vnode **, char **, char *, + struct proc *); static int getcwd_getcache(struct vnode **, struct vnode **, char **, char *); -static int getcwd_common(struct vnode *, struct vnode *, - char **, char *, int, int, struct proc *); - +static int getcwd_common(struct vnode *, struct vnode *, char **, char *, int, + int, struct proc *); static int vn_isunder(struct vnode *, struct vnode *, struct proc *); -#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) - -/* - * Vnode variable naming conventions in this file: - * - * rvp: the current root we're aiming towards. - * lvp, *lvpp: the "lower" vnode - * uvp, *uvpp: the "upper" vnode. - * - * Since all the vnodes we're dealing with are directories, and the - * lookups are going *up* in the filesystem rather than *down*, the - * usual "pvp" (parent) or "dvp" (directory) naming conventions are - * too confusing. - */ +#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN + 1) + 4) -/* - * XXX: is EINVAL the right thing to return if a directory is - * malformed? - */ - - -/* - * Find parent vnode of *lvpp, return in *uvpp - * - * If we care about the name, scan it looking for name of directory - * entry pointing at lvp. - * - * Place the name in the buffer which starts at bufp, immediately - * before *bpp, and move bpp backwards to point at the start of it. - * - * On entry, *lvpp is a locked vnode reference; on exit, it is vput and NULL'ed - * On exit, *uvpp is either NULL or is a locked vnode reference. - */ +/* Find parent vnode of *lvpp, return in *uvpp */ static int -getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, - char **bpp, char *bufp, struct proc *p) +getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, char **bpp, + char *bufp, struct proc *p) { - int error = 0; - int eofflag; - off_t off; - int tries; + int eofflag, tries, dirbuflen, len, reclen, error = 0; + off_t off; struct uio uio; struct iovec iov; - char *dirbuf = NULL; - int dirbuflen; - ino_t fileno; + char *dirbuf = NULL; + ino_t fileno; struct vattr va; struct vnode *uvp = NULL; struct vnode *lvp = *lvpp; struct componentname cn; - int len, reclen; + tries = 0; /* @@ -129,10 +95,6 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, } } - /* - * Ok, we have to do it the hard way.. - * Next, get parent vnode using lookup of .. - */ cn.cn_nameiop = LOOKUP; cn.cn_flags = ISLASTCN | ISDOTDOT | RDONLY; cn.cn_proc = p; @@ -142,11 +104,8 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, cn.cn_namelen = 2; cn.cn_hash = 0; cn.cn_consume = 0; - - /* - * At this point, lvp is locked and will be unlocked by the lookup. - * On successful return, *uvpp will be locked - */ + + /* Get parent vnode using lookup of '..' */ error = VOP_LOOKUP(lvp, uvpp, &cn); if (error) { vput(lvp); @@ -154,6 +113,7 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, *uvpp = NULL; return (error); } + uvp = *uvpp; /* If we don't care about the pathname, we're done */ @@ -162,20 +122,22 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, *lvpp = NULL; return (0); } - + fileno = va.va_fileid; dirbuflen = DIRBLKSIZ; + if (dirbuflen < va.va_blocksize) dirbuflen = va.va_blocksize; - dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); + + dirbuf = (char *) malloc(dirbuflen, M_TEMP, M_WAITOK); off = 0; + do { char *cpos; struct dirent *dp; - /* call VOP_READDIR of parent */ iov.iov_base = dirbuf; iov.iov_len = dirbuflen; @@ -189,47 +151,35 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, eofflag = 0; + /* Call VOP_READDIR of parent */ error = VOP_READDIR(uvp, &uio, p->p_ucred, &eofflag, 0, 0); off = uio.uio_offset; - /* - * Try again if NFS tosses its cookies. - */ + /* Try again if NFS tosses its cookies */ if (error == EINVAL && tries < 3) { tries++; off = 0; continue; - } else if (error != 0) { - /* - * We simply bail on error, even if we don't - * have eofflag yet. This is the exact - * behavior of the old userland getcwd() - */ - goto out; + } else if (error) { + goto out; /* Old userland getcwd() behaviour */ } - /* No error */ cpos = dirbuf; tries = 0; - /* scan directory page looking for matching vnode */ + /* Scan directory page looking for matching vnode */ for (len = (dirbuflen - uio.uio_resid); len > 0; len -= reclen) { dp = (struct dirent *)cpos; reclen = dp->d_reclen; - /* check for malformed directory.. */ + /* Check for malformed directory */ if (reclen < DIRENT_MINSIZE) { error = EINVAL; goto out; } - /* - * XXX should perhaps do VOP_LOOKUP to - * check that we got back to the right place, - * but getting the locking games for that - * right would be heinous. - */ + if (dp->d_fileno == fileno) { char *bp = *bpp; bp -= dp->d_namlen; @@ -238,11 +188,14 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, error = ERANGE; goto out; } + bcopy(dp->d_name, bp, dp->d_namlen); error = 0; *bpp = bp; + goto out; } + cpos += reclen; } @@ -251,41 +204,26 @@ getcwd_scandir(struct vnode **lvpp, struct vnode **uvpp, error = ENOENT; out: + vrele(lvp); *lvpp = NULL; + free(dirbuf, M_TEMP); + return (error); } -/* - * Look in the vnode-to-name reverse cache to see if - * we can find things the easy way. - * - * XXX vget failure path is untested. - * - * On entry, *lvpp is a locked vnode reference. - * On exit, one of the following is the case: - * 0) Both *lvpp and *uvpp are NULL and failure is returned. - * 1) *uvpp is NULL, *lvpp remains locked and -1 is returned (cache miss) - * 2) *uvpp is a locked vnode reference, *lvpp is vput and NULL'ed - * and 0 is returned (cache hit) - */ - +/* Do a lookup in the vnode-to-name reverse */ static int -getcwd_getcache(struct vnode **lvpp, struct vnode **uvpp, - char **bpp, char *bufp) +getcwd_getcache(struct vnode **lvpp, struct vnode **uvpp, char **bpp, + char *bufp) { struct vnode *lvp, *uvp = NULL; - int error; - int vpid; struct proc *p = curproc; - + int error, vpid; + lvp = *lvpp; - /* - * This returns 0 on a cache hit, -1 on a clean cache miss, or - * an errno on other failure. - */ error = cache_revlookup(lvp, uvpp, bpp, bufp); if (error) { if (error != -1) { @@ -293,56 +231,49 @@ getcwd_getcache(struct vnode **lvpp, struct vnode **uvpp, *lvpp = NULL; *uvpp = NULL; } + return (error); } + uvp = *uvpp; vpid = uvp->v_id; - /* - * Since we're going up, we have to release the current lock - * before we take the parent lock. - */ + /* Release current lock before acquiring the parent lock */ VOP_UNLOCK(lvp, 0, p); error = vget(uvp, LK_EXCLUSIVE | LK_RETRY, p); - if (error != 0) + if (error) *uvpp = NULL; + /* - * Verify that vget succeeded, and check that vnode capability + * Verify that vget() succeeded, and check that vnode capability * didn't change while we were waiting for the lock. - * - * XXX: this is kind of nasty to have to check here. It - * should really be done in cache_revlookup() (see comments - * there, too). */ if (error || (vpid != uvp->v_id)) { /* - * Oops, we missed. If the vget failed, or the - * capability changed, try to get our lock back; if - * that works, tell caller to try things the hard way, - * otherwise give up. + * Try to get our lock back. If that works, tell the caller to + * try things the hard way, otherwise give up. */ if (!error) vput(uvp); + *uvpp = NULL; error = vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY, p); - if (!error) return (-1); } + vrele(lvp); *lvpp = NULL; + return (error); } -/* - * common routine shared by sys___getcwd() and vn_isunder() - */ - #define GETCWD_CHECK_ACCESS 0x0001 +/* Common routine shared by sys___getcwd() and vn_isunder() */ static int getcwd_common(struct vnode *lvp, struct vnode *rvp, char **bpp, char *bufp, int limit, int flags, struct proc *p) |