summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--sys/compat/linprocfs/linprocfs.c1
-rw-r--r--sys/compat/linux/linux_uid16.c1
-rw-r--r--sys/compat/linux/linux_util.c1
-rw-r--r--sys/compat/pecoff/imgact_pecoff.c1
-rw-r--r--sys/compat/svr4/svr4_sysvec.c1
-rw-r--r--sys/fs/coda/coda_vfsops.c1
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c1
-rw-r--r--sys/fs/nullfs/null_vfsops.c1
-rw-r--r--sys/fs/unionfs/union_vfsops.c1
-rw-r--r--sys/i386/ibcs2/ibcs2_util.c1
-rw-r--r--sys/i386/linux/linux_sysvec.c1
-rw-r--r--sys/kern/kern_jail.c1
-rw-r--r--sys/kern/vfs_acl.c1
-rw-r--r--sys/kern/vfs_extattr.c1
-rw-r--r--sys/kern/vfs_lookup.c26
-rw-r--r--sys/kern/vfs_mount.c1
-rw-r--r--sys/security/mac/mac_syscalls.c1
-rw-r--r--sys/sys/namei.h10
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c1
19 files changed, 47 insertions, 6 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 868f817..7d8e2b6 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/blist.h>
#include <sys/conf.h>
#include <sys/exec.h>
+#include <sys/fcntl.h>
#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c
index c474382..2685eaa 100644
--- a/sys/compat/linux/linux_uid16.c
+++ b/sys/compat/linux/linux_uid16.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c
index 222197c..2186e9a 100644
--- a/sys/compat/linux/linux_util.c
+++ b/sys/compat/linux/linux_util.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/linker_set.h>
diff --git a/sys/compat/pecoff/imgact_pecoff.c b/sys/compat/pecoff/imgact_pecoff.c
index cd2fab3..d32de0b 100644
--- a/sys/compat/pecoff/imgact_pecoff.c
+++ b/sys/compat/pecoff/imgact_pecoff.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/fcntl.h>
#include <sys/imgact.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index 47621fe..7f3b3c2 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c
index 2f7b373..de6e855 100644
--- a/sys/fs/coda/coda_vfsops.c
+++ b/sys/fs/coda/coda_vfsops.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 7ed4d65..e2525b2 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -52,6 +52,7 @@
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
+#include <sys/fcntl.h>
#include <sys/iconv.h>
#include <sys/kernel.h>
#include <sys/lock.h>
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index 7c93dd9..841c9ca 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -42,6 +42,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index 4c56661..a192381 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -39,6 +39,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/i386/ibcs2/ibcs2_util.c b/sys/i386/ibcs2/ibcs2_util.c
index 298fb84..9f385b7 100644
--- a/sys/i386/ibcs2/ibcs2_util.c
+++ b/sys/i386/ibcs2/ibcs2_util.c
@@ -32,6 +32,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syscallsubr.h>
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 379b487..df3f8d1 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
+#include <sys/fcntl.h>
#include <sys/imgact.h>
#include <sys/imgact_aout.h>
#include <sys/imgact_elf.h>
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 62fae6f..fe34616 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -22,6 +22,7 @@ __FBSDID("$FreeBSD$");
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/taskqueue.h>
+#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/mutex.h>
diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c
index fd681f9..760b0e7 100644
--- a/sys/kern/vfs_acl.c
+++ b/sys/kern/vfs_acl.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 28f3741..cd2b9cc 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/sysproto.h>
+#include <sys/fcntl.h>
#include <sys/namei.h>
#include <sys/filedesc.h>
#include <sys/limits.h>
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.
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 3961022..5061f2a 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/clock.h>
+#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c
index 9b5286c..701b019 100644
--- a/sys/security/mac/mac_syscalls.c
+++ b/sys/security/mac/mac_syscalls.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "opt_mac.h"
#include <sys/param.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
index 69148cc..478ff33 100644
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -69,6 +69,7 @@ struct nameidata {
struct vnode *ni_startdir; /* starting directory */
struct vnode *ni_rootdir; /* logical root directory */
struct vnode *ni_topdir; /* logical top directory */
+ int ni_dirfd; /* starting directory for *at functions */
/*
* Results: returned from/manipulated by lookup
*/
@@ -148,19 +149,22 @@ struct nameidata {
/*
* Initialization of a nameidata structure.
*/
-static void NDINIT(struct nameidata *, u_long, u_long, enum uio_seg,
- const char *, struct thread *);
+#define NDINIT(ndp, op, flags, segflg, namep, td) \
+ NDINIT_AT(ndp, op, flags, segflg, namep, AT_FDCWD, td)
+
static __inline void
-NDINIT(struct nameidata *ndp,
+NDINIT_AT(struct nameidata *ndp,
u_long op, u_long flags,
enum uio_seg segflg,
const char *namep,
+ int dirfd,
struct thread *td)
{
ndp->ni_cnd.cn_nameiop = op;
ndp->ni_cnd.cn_flags = flags;
ndp->ni_segflg = segflg;
ndp->ni_dirp = namep;
+ ndp->ni_dirfd = dirfd;
ndp->ni_cnd.cn_thread = td;
}
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 5bb8d5d..27f40d2 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/fcntl.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/sched.h>
OpenPOWER on IntegriCloud