diff options
author | kib <kib@FreeBSD.org> | 2008-03-31 12:01:21 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-03-31 12:01:21 +0000 |
commit | eff8c6d35eb85c880ee73166dbff3ba639b6569c (patch) | |
tree | f8cc8d866703361e98f57783e3292705ce2d5dbc /sys | |
parent | fb67926ebba3585578dba016e05aabe5090ea064 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 1 | ||||
-rw-r--r-- | sys/compat/linux/linux_uid16.c | 1 | ||||
-rw-r--r-- | sys/compat/linux/linux_util.c | 1 | ||||
-rw-r--r-- | sys/compat/pecoff/imgact_pecoff.c | 1 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_sysvec.c | 1 | ||||
-rw-r--r-- | sys/fs/coda/coda_vfsops.c | 1 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vfsops.c | 1 | ||||
-rw-r--r-- | sys/fs/nullfs/null_vfsops.c | 1 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 1 | ||||
-rw-r--r-- | sys/i386/ibcs2/ibcs2_util.c | 1 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_jail.c | 1 | ||||
-rw-r--r-- | sys/kern/vfs_acl.c | 1 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 1 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 26 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 1 | ||||
-rw-r--r-- | sys/security/mac/mac_syscalls.c | 1 | ||||
-rw-r--r-- | sys/sys/namei.h | 10 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 1 |
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> |