From acfecf55d7e68dde3b95f4a60f14e3b9ce425645 Mon Sep 17 00:00:00 2001 From: dholland Date: Mon, 29 Jun 2009 05:00:14 +0000 Subject: [PATCH] Add namei_simple_kernel and namei_simple_user. These provide the common case functionality of namei in a simple package with only a couple flags. A substantial majority of the namei call sites in the kernel can use this interface; this will isolate those areas from the changes arising as the internals of namei are fumigated. --- sys/kern/vfs_lookup.c | 77 +++++++++++++++++++++++++++++++++++++++++-- sys/sys/namei.src | 32 +++++++++++++++++- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index d81b4307ce98..6807d4415da5 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.115 2009/06/26 15:49:03 christos Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.116 2009/06/29 05:00:14 dholland Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.115 2009/06/26 15:49:03 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.116 2009/06/29 05:00:14 dholland Exp $"); #include "opt_magiclinks.h" @@ -1010,3 +1010,76 @@ bad: *vpp = NULL; return (error); } + +/* + * namei_simple - simple forms of namei. + * + * These are wrappers to allow the simple case callers of namei to be + * left alone while everything else changes under them. + */ + +/* Flags */ +struct namei_simple_flags_type { + int dummy; +}; +static const struct namei_simple_flags_type ns_nn, ns_nt, ns_fn, ns_ft; +const namei_simple_flags_t NSM_NOFOLLOW_NOEMULROOT = &ns_nn; +const namei_simple_flags_t NSM_NOFOLLOW_TRYEMULROOT = &ns_nt; +const namei_simple_flags_t NSM_FOLLOW_NOEMULROOT = &ns_fn; +const namei_simple_flags_t NSM_FOLLOW_TRYEMULROOT = &ns_ft; + +static +int +namei_simple_convert_flags(namei_simple_flags_t sflags) +{ + if (sflags == NSM_NOFOLLOW_NOEMULROOT) + return NOFOLLOW | 0; + if (sflags == NSM_NOFOLLOW_TRYEMULROOT) + return NOFOLLOW | TRYEMULROOT; + if (sflags == NSM_FOLLOW_NOEMULROOT) + return FOLLOW | 0; + if (sflags == NSM_FOLLOW_TRYEMULROOT) + return FOLLOW | TRYEMULROOT; + panic("namei_simple_convert_flags: bogus sflags\n"); + return 0; +} + +int +namei_simple_kernel(const char *path, namei_simple_flags_t sflags, + struct vnode **vp_ret) +{ + struct nameidata nd; + int err; + + NDINIT(&nd, + LOOKUP, + namei_simple_convert_flags(sflags), + UIO_SYSSPACE, + path); + err = namei(&nd); + if (err != 0) { + return err; + } + *vp_ret = nd.ni_vp; + return 0; +} + +int +namei_simple_user(const char *path, namei_simple_flags_t sflags, + struct vnode **vp_ret) +{ + struct nameidata nd; + int err; + + NDINIT(&nd, + LOOKUP, + namei_simple_convert_flags(sflags), + UIO_USERSPACE, + path); + err = namei(&nd); + if (err != 0) { + return err; + } + *vp_ret = nd.ni_vp; + return 0; +} diff --git a/sys/sys/namei.src b/sys/sys/namei.src index edca859e1742..b9ed88b400c8 100644 --- a/sys/sys/namei.src +++ b/sys/sys/namei.src @@ -1,4 +1,4 @@ -/* $NetBSD: namei.src,v 1.10 2009/02/11 00:19:11 enami Exp $ */ +/* $NetBSD: namei.src,v 1.11 2009/06/29 05:00:14 dholland Exp $ */ /* * Copyright (c) 1985, 1989, 1991, 1993 @@ -196,6 +196,36 @@ extern pool_cache_t pnbuf_cache; /* pathname buffer cache */ #define PNBUF_GET() pool_cache_get(pnbuf_cache, PR_WAITOK) #define PNBUF_PUT(pnb) pool_cache_put(pnbuf_cache, (pnb)) +/* + * Typesafe flags for namei_simple. + * + * This encoding is not optimal but serves the important purpose of + * not being type-compatible with the regular namei flags. + */ +struct namei_simple_flags_type; /* Opaque. */ +typedef const struct namei_simple_flags_type *namei_simple_flags_t; /* Gross. */ +extern const namei_simple_flags_t + NSM_NOFOLLOW_NOEMULROOT, + NSM_NOFOLLOW_TRYEMULROOT, + NSM_FOLLOW_NOEMULROOT, + NSM_FOLLOW_TRYEMULROOT; + +/* + * namei_simple_* - the simple cases of namei, with no struct + * nameidata involved. + * + * namei_simple_kernel takes a kernel-space path as the first argument. + * namei_simple_user takes a user-space path as the first argument. + * + * A namei call can be converted to namei_simple_* if: + * - the second arg to NDINIT is LOOKUP; + * - it does not need the parent vnode, nd.ni_dvp; + * - the only flags it uses are (NO)FOLLOW and TRYEMULROOT; + * - it does not do anything else gross with the contents of nd. + */ +int namei_simple_kernel(const char *, namei_simple_flags_t, struct vnode **); +int namei_simple_user(const char *, namei_simple_flags_t, struct vnode **); + int namei(struct nameidata *); uint32_t namei_hash(const char *, const char **); int lookup(struct nameidata *);