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.46diff -r1.36 -r1.37 src/sys/kern/vfs_vnode.c
(hannken)
--- src/sys/kern/vfs_vnode.c 2014/05/08 08:21:53 1.36
+++ src/sys/kern/vfs_vnode.c 2014/07/05 09:33:15 1.37
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vfs_vnode.c,v 1.36 2014/05/08 08:21:53 hannken Exp $ */ | 1 | /* $NetBSD: vfs_vnode.c,v 1.37 2014/07/05 09:33:15 hannken Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | |
9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | 9 | * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -106,27 +106,27 @@ | @@ -106,27 +106,27 @@ | |||
106 | * from zero, the interlock must be held. To change from a non-zero | 106 | * from zero, the interlock must be held. To change from a non-zero | |
107 | * value to zero, again the interlock must be held. | 107 | * value to zero, again the interlock must be held. | |
108 | * | 108 | * | |
109 | * Changing the usecount from a non-zero value to a non-zero value can | 109 | * Changing the usecount from a non-zero value to a non-zero value can | |
110 | * safely be done using atomic operations, without the interlock held. | 110 | * safely be done using atomic operations, without the interlock held. | |
111 | * | 111 | * | |
112 | * Note: if VI_CLEAN is set, vnode_t::v_interlock will be released while | 112 | * Note: if VI_CLEAN is set, vnode_t::v_interlock will be released while | |
113 | * mntvnode_lock is still held. | 113 | * mntvnode_lock is still held. | |
114 | * | 114 | * | |
115 | * See PR 41374. | 115 | * See PR 41374. | |
116 | */ | 116 | */ | |
117 | 117 | |||
118 | #include <sys/cdefs.h> | 118 | #include <sys/cdefs.h> | |
119 | __KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.36 2014/05/08 08:21:53 hannken Exp $"); | 119 | __KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.37 2014/07/05 09:33:15 hannken Exp $"); | |
120 | 120 | |||
121 | #define _VFS_VNODE_PRIVATE | 121 | #define _VFS_VNODE_PRIVATE | |
122 | 122 | |||
123 | #include <sys/param.h> | 123 | #include <sys/param.h> | |
124 | #include <sys/kernel.h> | 124 | #include <sys/kernel.h> | |
125 | 125 | |||
126 | #include <sys/atomic.h> | 126 | #include <sys/atomic.h> | |
127 | #include <sys/buf.h> | 127 | #include <sys/buf.h> | |
128 | #include <sys/conf.h> | 128 | #include <sys/conf.h> | |
129 | #include <sys/device.h> | 129 | #include <sys/device.h> | |
130 | #include <sys/hash.h> | 130 | #include <sys/hash.h> | |
131 | #include <sys/kauth.h> | 131 | #include <sys/kauth.h> | |
132 | #include <sys/kmem.h> | 132 | #include <sys/kmem.h> | |
@@ -1314,26 +1314,108 @@ again: | @@ -1314,26 +1314,108 @@ again: | |||
1314 | vp->v_vflag |= VV_MPSAFE; | 1314 | vp->v_vflag |= VV_MPSAFE; | |
1315 | vfs_unbusy(mp, true, NULL); | 1315 | vfs_unbusy(mp, true, NULL); | |
1316 | 1316 | |||
1317 | /* Finished loading, finalize node. */ | 1317 | /* Finished loading, finalize node. */ | |
1318 | mutex_enter(&vcache.lock); | 1318 | mutex_enter(&vcache.lock); | |
1319 | new_node->vn_key.vk_key = new_key; | 1319 | new_node->vn_key.vk_key = new_key; | |
1320 | new_node->vn_vnode = vp; | 1320 | new_node->vn_vnode = vp; | |
1321 | mutex_exit(&vcache.lock); | 1321 | mutex_exit(&vcache.lock); | |
1322 | *vpp = vp; | 1322 | *vpp = vp; | |
1323 | return 0; | 1323 | return 0; | |
1324 | } | 1324 | } | |
1325 | 1325 | |||
1326 | /* | 1326 | /* | |
1327 | * Prepare key change: lock old and new cache node. | |||
1328 | * Return an error if the new node already exists. | |||
1329 | */ | |||
1330 | int | |||
1331 | vcache_rekey_enter(struct mount *mp, struct vnode *vp, | |||
1332 | const void *old_key, size_t old_key_len, | |||
1333 | const void *new_key, size_t new_key_len) | |||
1334 | { | |||
1335 | uint32_t old_hash, new_hash; | |||
1336 | struct vcache_key old_vcache_key, new_vcache_key; | |||
1337 | struct vcache_node *node, *new_node; | |||
1338 | ||||
1339 | old_vcache_key.vk_mount = mp; | |||
1340 | old_vcache_key.vk_key = old_key; | |||
1341 | old_vcache_key.vk_key_len = old_key_len; | |||
1342 | old_hash = vcache_hash(&old_vcache_key); | |||
1343 | ||||
1344 | new_vcache_key.vk_mount = mp; | |||
1345 | new_vcache_key.vk_key = new_key; | |||
1346 | new_vcache_key.vk_key_len = new_key_len; | |||
1347 | new_hash = vcache_hash(&new_vcache_key); | |||
1348 | ||||
1349 | new_node = pool_cache_get(vcache.pool, PR_WAITOK); | |||
1350 | new_node->vn_vnode = NULL; | |||
1351 | new_node->vn_key = new_vcache_key; | |||
1352 | ||||
1353 | mutex_enter(&vcache.lock); | |||
1354 | node = vcache_hash_lookup(&new_vcache_key, new_hash); | |||
1355 | if (node != NULL) { | |||
1356 | mutex_exit(&vcache.lock); | |||
1357 | pool_cache_put(vcache.pool, new_node); | |||
1358 | return EEXIST; | |||
1359 | } | |||
1360 | SLIST_INSERT_HEAD(&vcache.hashtab[new_hash & vcache.hashmask], | |||
1361 | new_node, vn_hash); | |||
1362 | node = vcache_hash_lookup(&old_vcache_key, old_hash); | |||
1363 | KASSERT(node != NULL); | |||
1364 | KASSERT(node->vn_vnode == vp); | |||
1365 | node->vn_vnode = NULL; | |||
1366 | node->vn_key = old_vcache_key; | |||
1367 | mutex_exit(&vcache.lock); | |||
1368 | return 0; | |||
1369 | } | |||
1370 | ||||
1371 | /* | |||
1372 | * Key change complete: remove old node and unlock new node. | |||
1373 | */ | |||
1374 | void | |||
1375 | vcache_rekey_exit(struct mount *mp, struct vnode *vp, | |||
1376 | const void *old_key, size_t old_key_len, | |||
1377 | const void *new_key, size_t new_key_len) | |||
1378 | { | |||
1379 | uint32_t old_hash, new_hash; | |||
1380 | struct vcache_key old_vcache_key, new_vcache_key; | |||
1381 | struct vcache_node *node; | |||
1382 | ||||
1383 | old_vcache_key.vk_mount = mp; | |||
1384 | old_vcache_key.vk_key = old_key; | |||
1385 | old_vcache_key.vk_key_len = old_key_len; | |||
1386 | old_hash = vcache_hash(&old_vcache_key); | |||
1387 | ||||
1388 | new_vcache_key.vk_mount = mp; | |||
1389 | new_vcache_key.vk_key = new_key; | |||
1390 | new_vcache_key.vk_key_len = new_key_len; | |||
1391 | new_hash = vcache_hash(&new_vcache_key); | |||
1392 | ||||
1393 | mutex_enter(&vcache.lock); | |||
1394 | node = vcache_hash_lookup(&new_vcache_key, new_hash); | |||
1395 | KASSERT(node != NULL && node->vn_vnode == NULL); | |||
1396 | KASSERT(node->vn_key.vk_key_len == new_key_len); | |||
1397 | node->vn_vnode = vp; | |||
1398 | node->vn_key = new_vcache_key; | |||
1399 | node = vcache_hash_lookup(&old_vcache_key, old_hash); | |||
1400 | KASSERT(node != NULL); | |||
1401 | KASSERT(node->vn_vnode == NULL); | |||
1402 | SLIST_REMOVE(&vcache.hashtab[old_hash & vcache.hashmask], | |||
1403 | node, vcache_node, vn_hash); | |||
1404 | mutex_exit(&vcache.lock); | |||
1405 | pool_cache_put(vcache.pool, node); | |||
1406 | } | |||
1407 | ||||
1408 | /* | |||
1327 | * Remove a vnode / fs node pair from the cache. | 1409 | * Remove a vnode / fs node pair from the cache. | |
1328 | */ | 1410 | */ | |
1329 | void | 1411 | void | |
1330 | vcache_remove(struct mount *mp, const void *key, size_t key_len) | 1412 | vcache_remove(struct mount *mp, const void *key, size_t key_len) | |
1331 | { | 1413 | { | |
1332 | uint32_t hash; | 1414 | uint32_t hash; | |
1333 | struct vcache_key vcache_key; | 1415 | struct vcache_key vcache_key; | |
1334 | struct vcache_node *node; | 1416 | struct vcache_node *node; | |
1335 | 1417 | |||
1336 | vcache_key.vk_mount = mp; | 1418 | vcache_key.vk_mount = mp; | |
1337 | vcache_key.vk_key = key; | 1419 | vcache_key.vk_key = key; | |
1338 | vcache_key.vk_key_len = key_len; | 1420 | vcache_key.vk_key_len = key_len; | |
1339 | hash = vcache_hash(&vcache_key); | 1421 | hash = vcache_hash(&vcache_key); |
--- src/sys/sys/param.h 2014/07/01 13:25:21 1.455
+++ src/sys/sys/param.h 2014/07/05 09:33:15 1.456
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: param.h,v 1.455 2014/07/01 13:25:21 rtr Exp $ */ | 1 | /* $NetBSD: param.h,v 1.456 2014/07/05 09:33:15 hannken Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1982, 1986, 1989, 1993 | 4 | * Copyright (c) 1982, 1986, 1989, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * (c) UNIX System Laboratories, Inc. | 6 | * (c) UNIX System Laboratories, Inc. | |
7 | * All or some portions of this file are derived from material licensed | 7 | * All or some portions of this file are derived from material licensed | |
8 | * to the University of California by American Telephone and Telegraph | 8 | * to the University of California by American Telephone and Telegraph | |
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |
10 | * the permission of UNIX System Laboratories, Inc. | 10 | * the permission of UNIX System Laboratories, Inc. | |
11 | * | 11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | 13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | 14 | * are met: | |
@@ -53,27 +53,27 @@ | @@ -53,27 +53,27 @@ | |||
53 | * m = minor version; a minor number of 99 indicates current. | 53 | * m = minor version; a minor number of 99 indicates current. | |
54 | * r = 0 (*) | 54 | * r = 0 (*) | |
55 | * p = patchlevel | 55 | * p = patchlevel | |
56 | * | 56 | * | |
57 | * When new releases are made, src/gnu/usr.bin/groff/tmac/mdoc.local | 57 | * When new releases are made, src/gnu/usr.bin/groff/tmac/mdoc.local | |
58 | * needs to be updated and the changes sent back to the groff maintainers. | 58 | * needs to be updated and the changes sent back to the groff maintainers. | |
59 | * | 59 | * | |
60 | * (*) Up to 2.0I "release" used to be "",A-Z,Z[A-Z] but numeric | 60 | * (*) Up to 2.0I "release" used to be "",A-Z,Z[A-Z] but numeric | |
61 | * e.g. NetBSD-1.2D = 102040000 ('D' == 4) | 61 | * e.g. NetBSD-1.2D = 102040000 ('D' == 4) | |
62 | * NetBSD-2.0H (200080000) was changed on 20041001 to: | 62 | * NetBSD-2.0H (200080000) was changed on 20041001 to: | |
63 | * 2.99.9 (299000900) | 63 | * 2.99.9 (299000900) | |
64 | */ | 64 | */ | |
65 | 65 | |||
66 | #define __NetBSD_Version__ 699004500 /* NetBSD 6.99.45 */ | 66 | #define __NetBSD_Version__ 699004600 /* NetBSD 6.99.46 */ | |
67 | 67 | |||
68 | #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ | 68 | #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ | |
69 | (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) | 69 | (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) | |
70 | 70 | |||
71 | /* | 71 | /* | |
72 | * Historical NetBSD #define | 72 | * Historical NetBSD #define | |
73 | * | 73 | * | |
74 | * NetBSD 1.4 was the last release for which this value was incremented. | 74 | * NetBSD 1.4 was the last release for which this value was incremented. | |
75 | * The value is now permanently fixed at 199905. It will never be | 75 | * The value is now permanently fixed at 199905. It will never be | |
76 | * changed again. | 76 | * changed again. | |
77 | * | 77 | * | |
78 | * New code must use __NetBSD_Version__ instead, and should not even | 78 | * New code must use __NetBSD_Version__ instead, and should not even | |
79 | * count on NetBSD being defined. | 79 | * count on NetBSD being defined. |
--- src/sys/sys/vnode.h 2014/05/25 13:51:26 1.248
+++ src/sys/sys/vnode.h 2014/07/05 09:33:15 1.249
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vnode.h,v 1.248 2014/05/25 13:51:26 hannken Exp $ */ | 1 | /* $NetBSD: vnode.h,v 1.249 2014/07/05 09:33:15 hannken Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -547,26 +547,30 @@ void vput(struct vnode *); | @@ -547,26 +547,30 @@ void vput(struct vnode *); | |||
547 | bool vrecycle(struct vnode *); | 547 | bool vrecycle(struct vnode *); | |
548 | void vrele(struct vnode *); | 548 | void vrele(struct vnode *); | |
549 | void vrele_async(struct vnode *); | 549 | void vrele_async(struct vnode *); | |
550 | void vrele_flush(void); | 550 | void vrele_flush(void); | |
551 | int vtruncbuf(struct vnode *, daddr_t, bool, int); | 551 | int vtruncbuf(struct vnode *, daddr_t, bool, int); | |
552 | void vwakeup(struct buf *); | 552 | void vwakeup(struct buf *); | |
553 | int vdead_check(struct vnode *, int); | 553 | int vdead_check(struct vnode *, int); | |
554 | void vrevoke(struct vnode *); | 554 | void vrevoke(struct vnode *); | |
555 | struct vnode * | 555 | struct vnode * | |
556 | vnalloc(struct mount *); | 556 | vnalloc(struct mount *); | |
557 | void vnfree(struct vnode *); | 557 | void vnfree(struct vnode *); | |
558 | void vremfree(struct vnode *); | 558 | void vremfree(struct vnode *); | |
559 | int vcache_get(struct mount *, const void *, size_t, struct vnode **); | 559 | int vcache_get(struct mount *, const void *, size_t, struct vnode **); | |
560 | int vcache_rekey_enter(struct mount *, struct vnode *, | |||
561 | const void *, size_t, const void *, size_t); | |||
562 | void vcache_rekey_exit(struct mount *, struct vnode *, | |||
563 | const void *, size_t, const void *, size_t); | |||
560 | void vcache_remove(struct mount *, const void *, size_t); | 564 | void vcache_remove(struct mount *, const void *, size_t); | |
561 | 565 | |||
562 | /* see vnsubr(9) */ | 566 | /* see vnsubr(9) */ | |
563 | int vn_bwrite(void *); | 567 | int vn_bwrite(void *); | |
564 | int vn_close(struct vnode *, int, kauth_cred_t); | 568 | int vn_close(struct vnode *, int, kauth_cred_t); | |
565 | int vn_isunder(struct vnode *, struct vnode *, struct lwp *); | 569 | int vn_isunder(struct vnode *, struct vnode *, struct lwp *); | |
566 | int vn_lock(struct vnode *, int); | 570 | int vn_lock(struct vnode *, int); | |
567 | void vn_markexec(struct vnode *); | 571 | void vn_markexec(struct vnode *); | |
568 | int vn_marktext(struct vnode *); | 572 | int vn_marktext(struct vnode *); | |
569 | int vn_open(struct nameidata *, int, int); | 573 | int vn_open(struct nameidata *, int, int); | |
570 | int vn_rdwr(enum uio_rw, struct vnode *, void *, int, off_t, enum uio_seg, | 574 | int vn_rdwr(enum uio_rw, struct vnode *, void *, int, off_t, enum uio_seg, | |
571 | int, kauth_cred_t, size_t *, struct lwp *); | 575 | int, kauth_cred_t, size_t *, struct lwp *); | |
572 | int vn_readdir(struct file *, char *, int, u_int, int *, struct lwp *, | 576 | int vn_readdir(struct file *, char *, int, u_int, int *, struct lwp *, |