summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_lookup.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-03-31 12:01:21 +0000
committerkib <kib@FreeBSD.org>2008-03-31 12:01:21 +0000
commiteff8c6d35eb85c880ee73166dbff3ba639b6569c (patch)
treef8cc8d866703361e98f57783e3292705ce2d5dbc /sys/kern/vfs_lookup.c
parentfb67926ebba3585578dba016e05aabe5090ea064 (diff)
downloadFreeBSD-src-eff8c6d35eb85c880ee73166dbff3ba639b6569c.zip
FreeBSD-src-eff8c6d35eb85c880ee73166dbff3ba639b6569c.tar.gz
Add the support for the AT_FDCWD and fd-relative name lookups to the
namei(9). Based on the submission by rdivacky, sponsored by Google Summer of Code 2007 Reviewed by: rwatson, rdivacky Tested by: pho
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r--sys/kern/vfs_lookup.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index c04916b..dc34249 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -192,10 +193,29 @@ namei(struct nameidata *ndp)
ndp->ni_rootdir = fdp->fd_rdir;
ndp->ni_topdir = fdp->fd_jdir;
- dp = fdp->fd_cdir;
+ if (cnp->cn_pnbuf[0] != '/' && ndp->ni_dirfd != AT_FDCWD) {
+ error = fgetvp(td, ndp->ni_dirfd, &dp);
+ FILEDESC_SUNLOCK(fdp);
+ if (error == 0 && dp->v_type != VDIR) {
+ vfslocked = VFS_LOCK_GIANT(dp->v_mount);
+ vrele(dp);
+ VFS_UNLOCK_GIANT(vfslocked);
+ error = ENOTDIR;
+ }
+ if (error) {
+ uma_zfree(namei_zone, cnp->cn_pnbuf);
+#ifdef DIAGNOSTIC
+ cnp->cn_pnbuf = NULL;
+ cnp->cn_nameptr = NULL;
+#endif
+ return (error);
+ }
+ } else {
+ dp = fdp->fd_cdir;
+ VREF(dp);
+ FILEDESC_SUNLOCK(fdp);
+ }
vfslocked = VFS_LOCK_GIANT(dp->v_mount);
- VREF(dp);
- FILEDESC_SUNLOCK(fdp);
for (;;) {
/*
* Check if root directory should replace current directory.
OpenPOWER on IntegriCloud