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.
This commit is contained in:
dholland 2009-06-29 05:00:14 +00:00
parent 63eb8c3760
commit acfecf55d7
2 changed files with 106 additions and 3 deletions

View File

@ -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 <sys/cdefs.h>
__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;
}

View File

@ -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 *);