Module Name: src Committed By: hannken Date: Sat Jul 5 09:33:15 UTC 2014
Modified Files: src/sys/kern: vfs_vnode.c src/sys/sys: param.h vnode.h Log Message: Add vcache operations to support key changes: vcache_rekey_enter locks the old cache node and creates and locks the new cache node. It is an error if the new cache node exists. vcache_rekey_exit removes the old cache node and finalizes and unlocks the new cache node. No objections on tech-kern@ Welcome to 6.99.46 To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/sys/kern/vfs_vnode.c cvs rdiff -u -r1.455 -r1.456 src/sys/sys/param.h cvs rdiff -u -r1.248 -r1.249 src/sys/sys/vnode.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_vnode.c diff -u src/sys/kern/vfs_vnode.c:1.36 src/sys/kern/vfs_vnode.c:1.37 --- src/sys/kern/vfs_vnode.c:1.36 Thu May 8 08:21:53 2014 +++ src/sys/kern/vfs_vnode.c Sat Jul 5 09:33:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.36 2014/05/08 08:21:53 hannken Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.37 2014/07/05 09:33:15 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.36 2014/05/08 08:21:53 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.37 2014/07/05 09:33:15 hannken Exp $"); #define _VFS_VNODE_PRIVATE @@ -1324,6 +1324,88 @@ again: } /* + * Prepare key change: lock old and new cache node. + * Return an error if the new node already exists. + */ +int +vcache_rekey_enter(struct mount *mp, struct vnode *vp, + const void *old_key, size_t old_key_len, + const void *new_key, size_t new_key_len) +{ + uint32_t old_hash, new_hash; + struct vcache_key old_vcache_key, new_vcache_key; + struct vcache_node *node, *new_node; + + old_vcache_key.vk_mount = mp; + old_vcache_key.vk_key = old_key; + old_vcache_key.vk_key_len = old_key_len; + old_hash = vcache_hash(&old_vcache_key); + + new_vcache_key.vk_mount = mp; + new_vcache_key.vk_key = new_key; + new_vcache_key.vk_key_len = new_key_len; + new_hash = vcache_hash(&new_vcache_key); + + new_node = pool_cache_get(vcache.pool, PR_WAITOK); + new_node->vn_vnode = NULL; + new_node->vn_key = new_vcache_key; + + mutex_enter(&vcache.lock); + node = vcache_hash_lookup(&new_vcache_key, new_hash); + if (node != NULL) { + mutex_exit(&vcache.lock); + pool_cache_put(vcache.pool, new_node); + return EEXIST; + } + SLIST_INSERT_HEAD(&vcache.hashtab[new_hash & vcache.hashmask], + new_node, vn_hash); + node = vcache_hash_lookup(&old_vcache_key, old_hash); + KASSERT(node != NULL); + KASSERT(node->vn_vnode == vp); + node->vn_vnode = NULL; + node->vn_key = old_vcache_key; + mutex_exit(&vcache.lock); + return 0; +} + +/* + * Key change complete: remove old node and unlock new node. + */ +void +vcache_rekey_exit(struct mount *mp, struct vnode *vp, + const void *old_key, size_t old_key_len, + const void *new_key, size_t new_key_len) +{ + uint32_t old_hash, new_hash; + struct vcache_key old_vcache_key, new_vcache_key; + struct vcache_node *node; + + old_vcache_key.vk_mount = mp; + old_vcache_key.vk_key = old_key; + old_vcache_key.vk_key_len = old_key_len; + old_hash = vcache_hash(&old_vcache_key); + + new_vcache_key.vk_mount = mp; + new_vcache_key.vk_key = new_key; + new_vcache_key.vk_key_len = new_key_len; + new_hash = vcache_hash(&new_vcache_key); + + mutex_enter(&vcache.lock); + node = vcache_hash_lookup(&new_vcache_key, new_hash); + KASSERT(node != NULL && node->vn_vnode == NULL); + KASSERT(node->vn_key.vk_key_len == new_key_len); + node->vn_vnode = vp; + node->vn_key = new_vcache_key; + node = vcache_hash_lookup(&old_vcache_key, old_hash); + KASSERT(node != NULL); + KASSERT(node->vn_vnode == NULL); + SLIST_REMOVE(&vcache.hashtab[old_hash & vcache.hashmask], + node, vcache_node, vn_hash); + mutex_exit(&vcache.lock); + pool_cache_put(vcache.pool, node); +} + +/* * Remove a vnode / fs node pair from the cache. */ void Index: src/sys/sys/param.h diff -u src/sys/sys/param.h:1.455 src/sys/sys/param.h:1.456 --- src/sys/sys/param.h:1.455 Tue Jul 1 13:25:21 2014 +++ src/sys/sys/param.h Sat Jul 5 09:33:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.455 2014/07/01 13:25:21 rtr Exp $ */ +/* $NetBSD: param.h,v 1.456 2014/07/05 09:33:15 hannken Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -63,7 +63,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 699004500 /* NetBSD 6.99.45 */ +#define __NetBSD_Version__ 699004600 /* NetBSD 6.99.46 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) Index: src/sys/sys/vnode.h diff -u src/sys/sys/vnode.h:1.248 src/sys/sys/vnode.h:1.249 --- src/sys/sys/vnode.h:1.248 Sun May 25 13:51:26 2014 +++ src/sys/sys/vnode.h Sat Jul 5 09:33:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.248 2014/05/25 13:51:26 hannken Exp $ */ +/* $NetBSD: vnode.h,v 1.249 2014/07/05 09:33:15 hannken Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -557,6 +557,10 @@ struct vnode * void vnfree(struct vnode *); void vremfree(struct vnode *); int vcache_get(struct mount *, const void *, size_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 *, + const void *, size_t, const void *, size_t); void vcache_remove(struct mount *, const void *, size_t); /* see vnsubr(9) */