Add new operation "vcache_new()" to allocate and initialise a new
vnode/fsnode pair: int vcache_new(struct mount *mp, struct vnode *dvp, struct vattr *vap, kauth_cred_t cred, struct vnode **vpp) where dvp is the (referenced) directory where we want to create the new node, vap passes va_type, va_mode and possibly va_rdev and cred gives the credentials to setup uid/guid. The node returned from vcache_new() is referenced, fully initialised and has link count zero. Welcome to NetBSD 7.99.7
This commit is contained in:
parent
4f8ab635ea
commit
b01cc29bb1
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_vnode.c,v 1.39 2014/10/03 14:45:38 hannken Exp $ */
|
||||
/* $NetBSD: vfs_vnode.c,v 1.40 2015/03/17 09:38:21 hannken Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -116,7 +116,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.39 2014/10/03 14:45:38 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.40 2015/03/17 09:38:21 hannken Exp $");
|
||||
|
||||
#define _VFS_VNODE_PRIVATE
|
||||
|
||||
|
@ -1329,6 +1329,82 @@ again:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new vnode / fs node pair and return it referenced through vpp.
|
||||
*/
|
||||
int
|
||||
vcache_new(struct mount *mp, struct vnode *dvp, struct vattr *vap,
|
||||
kauth_cred_t cred, struct vnode **vpp)
|
||||
{
|
||||
int error;
|
||||
uint32_t hash;
|
||||
struct vnode *vp;
|
||||
struct vcache_node *new_node;
|
||||
struct vcache_node *old_node __diagused;
|
||||
|
||||
*vpp = NULL;
|
||||
|
||||
/* Allocate and initialize a new vcache / vnode pair. */
|
||||
error = vfs_busy(mp, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
new_node = pool_cache_get(vcache.pool, PR_WAITOK);
|
||||
new_node->vn_key.vk_mount = mp;
|
||||
new_node->vn_vnode = NULL;
|
||||
vp = vnalloc(NULL);
|
||||
|
||||
/* Create and load the fs node. */
|
||||
vp->v_iflag |= VI_CHANGING;
|
||||
error = VFS_NEWVNODE(mp, dvp, vp, vap, cred,
|
||||
&new_node->vn_key.vk_key_len, &new_node->vn_key.vk_key);
|
||||
if (error) {
|
||||
pool_cache_put(vcache.pool, new_node);
|
||||
KASSERT(vp->v_usecount == 1);
|
||||
vp->v_usecount = 0;
|
||||
vnfree(vp);
|
||||
vfs_unbusy(mp, false, NULL);
|
||||
KASSERT(*vpp == NULL);
|
||||
return error;
|
||||
}
|
||||
KASSERT(new_node->vn_key.vk_key != NULL);
|
||||
KASSERT(vp->v_op != NULL);
|
||||
hash = vcache_hash(&new_node->vn_key);
|
||||
|
||||
/* Wait for previous instance to be reclaimed, then insert new node. */
|
||||
mutex_enter(&vcache.lock);
|
||||
while ((old_node = vcache_hash_lookup(&new_node->vn_key, hash))) {
|
||||
#ifdef DIAGNOSTIC
|
||||
if (old_node->vn_vnode != NULL)
|
||||
mutex_enter(old_node->vn_vnode->v_interlock);
|
||||
KASSERT(old_node->vn_vnode == NULL ||
|
||||
(old_node->vn_vnode->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0);
|
||||
if (old_node->vn_vnode != NULL)
|
||||
mutex_exit(old_node->vn_vnode->v_interlock);
|
||||
#endif
|
||||
mutex_exit(&vcache.lock);
|
||||
kpause("vcache", false, mstohz(20), NULL);
|
||||
mutex_enter(&vcache.lock);
|
||||
}
|
||||
SLIST_INSERT_HEAD(&vcache.hashtab[hash & vcache.hashmask],
|
||||
new_node, vn_hash);
|
||||
mutex_exit(&vcache.lock);
|
||||
vfs_insmntque(vp, mp);
|
||||
if ((mp->mnt_iflag & IMNT_MPSAFE) != 0)
|
||||
vp->v_vflag |= VV_MPSAFE;
|
||||
vfs_unbusy(mp, true, NULL);
|
||||
|
||||
/* Finished loading, finalize node. */
|
||||
mutex_enter(&vcache.lock);
|
||||
new_node->vn_vnode = vp;
|
||||
mutex_exit(&vcache.lock);
|
||||
mutex_enter(vp->v_interlock);
|
||||
vp->v_iflag &= ~VI_CHANGING;
|
||||
cv_broadcast(&vp->v_cv);
|
||||
mutex_exit(vp->v_interlock);
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare key change: lock old and new cache node.
|
||||
* Return an error if the new node already exists.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mount.h,v 1.215 2014/06/28 22:27:50 dholland Exp $ */
|
||||
/* $NetBSD: mount.h,v 1.216 2015/03/17 09:38:21 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1991, 1993
|
||||
|
@ -100,6 +100,7 @@
|
|||
#ifndef _STANDALONE
|
||||
|
||||
struct vnode;
|
||||
struct vattr;
|
||||
|
||||
/*
|
||||
* Structure per mounted file system. Each mounted file system has an
|
||||
|
@ -222,6 +223,9 @@ struct vfsops {
|
|||
int (*vfs_vget) (struct mount *, ino_t, struct vnode **);
|
||||
int (*vfs_loadvnode) (struct mount *, struct vnode *,
|
||||
const void *, size_t, const void **);
|
||||
int (*vfs_newvnode) (struct mount *, struct vnode *, struct vnode *,
|
||||
struct vattr *, kauth_cred_t,
|
||||
size_t *, const void **);
|
||||
int (*vfs_fhtovp) (struct mount *, struct fid *,
|
||||
struct vnode **);
|
||||
int (*vfs_vptofh) (struct vnode *, struct fid *, size_t *);
|
||||
|
@ -246,6 +250,8 @@ struct vfsops {
|
|||
#define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
|
||||
#define VFS_LOADVNODE(MP, VP, KEY, KEY_LEN, NEW_KEY) \
|
||||
(*(MP)->mnt_op->vfs_loadvnode)(MP, VP, KEY, KEY_LEN, NEW_KEY)
|
||||
#define VFS_NEWVNODE(MP, DVP, VP, VAP, CRED, NEW_LEN, NEW_KEY) \
|
||||
(*(MP)->mnt_op->vfs_newvnode)(MP, DVP, VP, VAP, CRED, NEW_LEN, NEW_KEY)
|
||||
|
||||
#define VFS_RENAMELOCK_ENTER(MP) (*(MP)->mnt_op->vfs_renamelock_enter)(MP)
|
||||
#define VFS_RENAMELOCK_EXIT(MP) (*(MP)->mnt_op->vfs_renamelock_exit)(MP)
|
||||
|
@ -287,6 +293,9 @@ int fsname##_sync(struct mount *, int, struct kauth_cred *); \
|
|||
int fsname##_vget(struct mount *, ino_t, struct vnode **); \
|
||||
int fsname##_loadvnode(struct mount *, struct vnode *, \
|
||||
const void *, size_t, const void **); \
|
||||
int fsname##_newvnode(struct mount *, struct vnode *, \
|
||||
struct vnode *, struct vattr *, kauth_cred_t, \
|
||||
size_t *, const void **); \
|
||||
int fsname##_fhtovp(struct mount *, struct fid *, struct vnode **); \
|
||||
int fsname##_vptofh(struct vnode *, struct fid *, size_t *); \
|
||||
void fsname##_init(void); \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: param.h,v 1.466 2015/03/07 16:34:55 christos Exp $ */
|
||||
/* $NetBSD: param.h,v 1.467 2015/03/17 09:38:21 hannken Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -63,7 +63,7 @@
|
|||
* 2.99.9 (299000900)
|
||||
*/
|
||||
|
||||
#define __NetBSD_Version__ 799000600 /* NetBSD 7.99.6 */
|
||||
#define __NetBSD_Version__ 799000700 /* NetBSD 7.99.7 */
|
||||
|
||||
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
|
||||
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vnode.h,v 1.249 2014/07/05 09:33:15 hannken Exp $ */
|
||||
/* $NetBSD: vnode.h,v 1.250 2015/03/17 09:38:21 hannken Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -557,6 +557,8 @@ struct vnode *
|
|||
void vnfree(struct vnode *);
|
||||
void vremfree(struct vnode *);
|
||||
int vcache_get(struct mount *, const void *, size_t, struct vnode **);
|
||||
int vcache_new(struct mount *, struct vnode *,
|
||||
struct vattr *, kauth_cred_t, struct vnode **);
|
||||
int vcache_rekey_enter(struct mount *, struct vnode *,
|
||||
const void *, size_t, const void *, size_t);
|
||||
void vcache_rekey_exit(struct mount *, struct vnode *,
|
||||
|
|
Loading…
Reference in New Issue