DragonFly kernel List (threaded) for 2009-07
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
factoring out "at" syscalls common code in nlookup
Hello,
As part of implementing the at family of syscalls (openat(),
fstatat(), ...), I propose to put the common code handling the file
descriptor argument in the namecache as shown in the patch below.
Any objection?
Cheers,
Nicolas
---
sys/kern/vfs_nlookup.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
sys/kern/vfs_syscalls.c | 32 +++---------------------------
sys/sys/nlookup.h | 3 ++
3 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/sys/kern/vfs_nlookup.c b/sys/kern/vfs_nlookup.c
index 09758a6..4e1552a 100644
--- a/sys/kern/vfs_nlookup.c
+++ b/sys/kern/vfs_nlookup.c
@@ -65,6 +65,7 @@
#include <sys/malloc.h>
#include <sys/stat.h>
#include <sys/objcache.h>
+#include <sys/file.h>
#ifdef KTRACE
#include <sys/ktrace.h>
@@ -128,6 +129,49 @@ nlookup_init(struct nlookupdata *nd,
return(error);
}
+
+/*
+ * nlookup_init() for "at" family of syscalls.
+ *
+ * Works similarly to nlookup_init() but if path is relative and fd is not
+ * AT_FDCWD, path is interpreted relative to the directory pointed to by fd.
+ *
+ * Takes a ref on the file entry pointed to by fd that will be dropped by
+ * nlookup_done().
+ */
+int
+nlookup_init_at(struct nlookupdata *nd, int fd, const char *path,
+ enum uio_seg seg, int flags)
+{
+ struct thread *td = curthread;
+ struct proc *p = td->td_proc;
+ struct file* fp;
+ struct vnode *vp;
+ int error;
+
+ if ((error = nlookup_init(nd, path, seg, flags)) != 0)
+ return (error);
+
+ if (nd->nl_path[0] != '/' && fd != AT_FDCWD) {
+ if ((error = holdvnode(p->p_fd, fd, &fp)) != 0)
+ goto done;
+ nd->nl_atfp = fp;
+ vp = (struct vnode*)fp->f_data;
+ if (vp->v_type != VDIR || fp->f_nchandle.ncp == NULL) {
+ error = ENOTDIR;
+ goto done;
+ }
+ cache_drop(&nd->nl_nch);
+ cache_copy(&fp->f_nchandle, &nd->nl_nch);
+ }
+
+done:
+ if (error)
+ nlookup_done(nd);
+ return (error);
+
+}
+
/*
* This works similarly to nlookup_init() but does not assume a process
* context. rootnch is always chosen for the root directory and the cred
@@ -229,6 +273,10 @@ nlookup_done(struct nlookupdata *nd)
vrele(nd->nl_dvp);
nd->nl_dvp = NULL;
}
+ if (nd->nl_atfp) {
+ fdrop(nd->nl_atfp);
+ nd->nl_atfp = NULL;
+ }
nd->nl_flags = 0; /* clear remaining flags (just clear everything) */
}
diff --git a/sys/sys/nlookup.h b/sys/sys/nlookup.h
index cec3b96..cc709cc 100644
--- a/sys/sys/nlookup.h
+++ b/sys/sys/nlookup.h
@@ -85,6 +85,8 @@ struct nlookupdata {
int nl_flags; /* operations flags */
int nl_loopcnt; /* symlinks encountered */
+ struct file *nl_atfp; /* refs nlookup_init_at() fd or NULL */
+
/*
* These fields are populated by vn_open(). nlookup_done() will
* vn_close() a non-NULL vp so if you extract it be sure to NULL out
@@ -144,6 +146,7 @@ struct nlookupdata {
#ifdef _KERNEL
int nlookup_init(struct nlookupdata *, const char *, enum uio_seg, int);
+int nlookup_init_at(struct nlookupdata *, int, const char *, enum
uio_seg, int);
int nlookup_init_raw(struct nlookupdata *, const char *, enum
uio_seg, int, struct ucred *, struct nchandle *);
void nlookup_set_cred(struct nlookupdata *nd, struct ucred *cred);
void nlookup_zero(struct nlookupdata *);
--
1.6.0
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]