xref: /dflybsd-src/sys/vfs/hammer/hammer_subs.c (revision 2f85fa4d65e69cdd2ee4ed3da50f49a52009eb4c)
1427e5fc6SMatthew Dillon /*
2b84de5afSMatthew Dillon  * Copyright (c) 2007-2008 The DragonFly Project.  All rights reserved.
3427e5fc6SMatthew Dillon  *
4427e5fc6SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
5427e5fc6SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
6427e5fc6SMatthew Dillon  *
7427e5fc6SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
8427e5fc6SMatthew Dillon  * modification, are permitted provided that the following conditions
9427e5fc6SMatthew Dillon  * are met:
10427e5fc6SMatthew Dillon  *
11427e5fc6SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
12427e5fc6SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
13427e5fc6SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
14427e5fc6SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
15427e5fc6SMatthew Dillon  *    the documentation and/or other materials provided with the
16427e5fc6SMatthew Dillon  *    distribution.
17427e5fc6SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
18427e5fc6SMatthew Dillon  *    contributors may be used to endorse or promote products derived
19427e5fc6SMatthew Dillon  *    from this software without specific, prior written permission.
20427e5fc6SMatthew Dillon  *
21427e5fc6SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22427e5fc6SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23427e5fc6SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24427e5fc6SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25427e5fc6SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26427e5fc6SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27427e5fc6SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28427e5fc6SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29427e5fc6SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30427e5fc6SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31427e5fc6SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32427e5fc6SMatthew Dillon  * SUCH DAMAGE.
33427e5fc6SMatthew Dillon  *
34*2f85fa4dSMatthew Dillon  * $DragonFly: src/sys/vfs/hammer/hammer_subs.c,v 1.20 2008/05/18 01:48:50 dillon Exp $
35427e5fc6SMatthew Dillon  */
36427e5fc6SMatthew Dillon /*
37427e5fc6SMatthew Dillon  * HAMMER structural locking
38427e5fc6SMatthew Dillon  */
39427e5fc6SMatthew Dillon 
40427e5fc6SMatthew Dillon #include "hammer.h"
416b4f890bSMatthew Dillon #include <sys/dirent.h>
42427e5fc6SMatthew Dillon 
43427e5fc6SMatthew Dillon void
448cd0a023SMatthew Dillon hammer_lock_ex(struct hammer_lock *lock)
45427e5fc6SMatthew Dillon {
46427e5fc6SMatthew Dillon 	thread_t td = curthread;
47427e5fc6SMatthew Dillon 
488cd0a023SMatthew Dillon 	KKASSERT(lock->refs > 0);
4966325755SMatthew Dillon 	crit_enter();
50427e5fc6SMatthew Dillon 	if (lock->locktd != td) {
51c0ade690SMatthew Dillon 		while (lock->locktd != NULL || lock->lockcount) {
52427e5fc6SMatthew Dillon 			lock->wanted = 1;
537d683b0fSMatthew Dillon 			if (hammer_debug_locks) {
547d683b0fSMatthew Dillon 				kprintf("hammer_lock_ex: held by %p\n",
557d683b0fSMatthew Dillon 					lock->locktd);
567d683b0fSMatthew Dillon 			}
577d683b0fSMatthew Dillon 			++hammer_contention_count;
58427e5fc6SMatthew Dillon 			tsleep(lock, 0, "hmrlck", 0);
597d683b0fSMatthew Dillon 			if (hammer_debug_locks)
60c0ade690SMatthew Dillon 				kprintf("hammer_lock_ex: try again\n");
61427e5fc6SMatthew Dillon 		}
62427e5fc6SMatthew Dillon 		lock->locktd = td;
63427e5fc6SMatthew Dillon 	}
640b075555SMatthew Dillon 	KKASSERT(lock->lockcount >= 0);
658cd0a023SMatthew Dillon 	++lock->lockcount;
668cd0a023SMatthew Dillon 	crit_exit();
678cd0a023SMatthew Dillon }
688cd0a023SMatthew Dillon 
698cd0a023SMatthew Dillon /*
708cd0a023SMatthew Dillon  * Try to obtain an exclusive lock
718cd0a023SMatthew Dillon  */
728cd0a023SMatthew Dillon int
738cd0a023SMatthew Dillon hammer_lock_ex_try(struct hammer_lock *lock)
748cd0a023SMatthew Dillon {
758cd0a023SMatthew Dillon 	thread_t td = curthread;
768cd0a023SMatthew Dillon 
778cd0a023SMatthew Dillon 	KKASSERT(lock->refs > 0);
788cd0a023SMatthew Dillon 	crit_enter();
798cd0a023SMatthew Dillon 	if (lock->locktd != td) {
804d75d829SMatthew Dillon 		if (lock->locktd != NULL || lock->lockcount) {
814d75d829SMatthew Dillon 			crit_exit();
828cd0a023SMatthew Dillon 			return(EAGAIN);
834d75d829SMatthew Dillon 		}
848cd0a023SMatthew Dillon 		lock->locktd = td;
858cd0a023SMatthew Dillon 	}
860b075555SMatthew Dillon 	KKASSERT(lock->lockcount >= 0);
878cd0a023SMatthew Dillon 	++lock->lockcount;
888cd0a023SMatthew Dillon 	crit_exit();
898cd0a023SMatthew Dillon 	return(0);
908cd0a023SMatthew Dillon }
918cd0a023SMatthew Dillon 
928cd0a023SMatthew Dillon void
938cd0a023SMatthew Dillon hammer_lock_sh(struct hammer_lock *lock)
948cd0a023SMatthew Dillon {
958cd0a023SMatthew Dillon 	KKASSERT(lock->refs > 0);
968cd0a023SMatthew Dillon 	crit_enter();
978cd0a023SMatthew Dillon 	while (lock->locktd != NULL) {
988cd0a023SMatthew Dillon 		if (lock->locktd == curthread) {
996a37e7e4SMatthew Dillon 			Debugger("hammer_lock_sh: lock_sh on exclusive");
1008cd0a023SMatthew Dillon 			++lock->lockcount;
1018cd0a023SMatthew Dillon 			crit_exit();
1028cd0a023SMatthew Dillon 			return;
1038cd0a023SMatthew Dillon 		}
1048cd0a023SMatthew Dillon 		lock->wanted = 1;
1058cd0a023SMatthew Dillon 		tsleep(lock, 0, "hmrlck", 0);
1068cd0a023SMatthew Dillon 	}
1078cd0a023SMatthew Dillon 	KKASSERT(lock->lockcount <= 0);
1088cd0a023SMatthew Dillon 	--lock->lockcount;
10966325755SMatthew Dillon 	crit_exit();
110427e5fc6SMatthew Dillon }
111427e5fc6SMatthew Dillon 
1126a37e7e4SMatthew Dillon /*
1136a37e7e4SMatthew Dillon  * Upgrade a shared lock to an exclusively held lock.  This function will
1146a37e7e4SMatthew Dillon  * return EDEADLK If there is more then one shared holder.
1156a37e7e4SMatthew Dillon  *
1166a37e7e4SMatthew Dillon  * No error occurs and no action is taken if the lock is already exclusively
1177aa3b8a6SMatthew Dillon  * held by the caller.  If the lock is not held at all or held exclusively
1187aa3b8a6SMatthew Dillon  * by someone else, this function will panic.
1196a37e7e4SMatthew Dillon  */
1206a37e7e4SMatthew Dillon int
1216a37e7e4SMatthew Dillon hammer_lock_upgrade(struct hammer_lock *lock)
1226a37e7e4SMatthew Dillon {
1236a37e7e4SMatthew Dillon 	int error;
1246a37e7e4SMatthew Dillon 
1256a37e7e4SMatthew Dillon 	crit_enter();
1266a37e7e4SMatthew Dillon 	if (lock->lockcount > 0) {
1277aa3b8a6SMatthew Dillon 		if (lock->locktd != curthread)
1287aa3b8a6SMatthew Dillon 			panic("hammer_lock_upgrade: illegal lock state");
1296a37e7e4SMatthew Dillon 		error = 0;
1306a37e7e4SMatthew Dillon 	} else if (lock->lockcount == -1) {
1316a37e7e4SMatthew Dillon 		lock->lockcount = 1;
1326a37e7e4SMatthew Dillon 		lock->locktd = curthread;
1336a37e7e4SMatthew Dillon 		error = 0;
1347aa3b8a6SMatthew Dillon 	} else if (lock->lockcount != 0) {
1356a37e7e4SMatthew Dillon 		error = EDEADLK;
1367aa3b8a6SMatthew Dillon 	} else {
1377aa3b8a6SMatthew Dillon 		panic("hammer_lock_upgrade: lock is not held");
1387aa3b8a6SMatthew Dillon 		/* NOT REACHED */
1397aa3b8a6SMatthew Dillon 		error = 0;
1406a37e7e4SMatthew Dillon 	}
1416a37e7e4SMatthew Dillon 	crit_exit();
1426a37e7e4SMatthew Dillon 	return(error);
1436a37e7e4SMatthew Dillon }
1446a37e7e4SMatthew Dillon 
1456a37e7e4SMatthew Dillon /*
1466a37e7e4SMatthew Dillon  * Downgrade an exclusively held lock to a shared lock.
1476a37e7e4SMatthew Dillon  */
148427e5fc6SMatthew Dillon void
1496a37e7e4SMatthew Dillon hammer_lock_downgrade(struct hammer_lock *lock)
150427e5fc6SMatthew Dillon {
1517aa3b8a6SMatthew Dillon 	KKASSERT(lock->lockcount == 1 && lock->locktd == curthread);
15266325755SMatthew Dillon 	crit_enter();
1538cd0a023SMatthew Dillon 	lock->lockcount = -1;
154427e5fc6SMatthew Dillon 	lock->locktd = NULL;
155427e5fc6SMatthew Dillon 	if (lock->wanted) {
156427e5fc6SMatthew Dillon 		lock->wanted = 0;
157427e5fc6SMatthew Dillon 		wakeup(lock);
158427e5fc6SMatthew Dillon 	}
1598cd0a023SMatthew Dillon 	crit_exit();
1608cd0a023SMatthew Dillon 	/* XXX memory barrier */
1618cd0a023SMatthew Dillon }
1628cd0a023SMatthew Dillon 
1638cd0a023SMatthew Dillon void
1648cd0a023SMatthew Dillon hammer_unlock(struct hammer_lock *lock)
1658cd0a023SMatthew Dillon {
1668cd0a023SMatthew Dillon 	crit_enter();
1678cd0a023SMatthew Dillon 	KKASSERT(lock->lockcount != 0);
1688cd0a023SMatthew Dillon 	if (lock->lockcount < 0) {
1698cd0a023SMatthew Dillon 		if (++lock->lockcount == 0 && lock->wanted) {
1708cd0a023SMatthew Dillon 			lock->wanted = 0;
1718cd0a023SMatthew Dillon 			wakeup(lock);
1728cd0a023SMatthew Dillon 		}
1738cd0a023SMatthew Dillon 	} else {
1748cd0a023SMatthew Dillon 		KKASSERT(lock->locktd == curthread);
1758cd0a023SMatthew Dillon 		if (--lock->lockcount == 0) {
1768cd0a023SMatthew Dillon 			lock->locktd = NULL;
1778cd0a023SMatthew Dillon 			if (lock->wanted) {
1788cd0a023SMatthew Dillon 				lock->wanted = 0;
1798cd0a023SMatthew Dillon 				wakeup(lock);
1808cd0a023SMatthew Dillon 			}
1818cd0a023SMatthew Dillon 		}
1828cd0a023SMatthew Dillon 
183427e5fc6SMatthew Dillon 	}
18466325755SMatthew Dillon 	crit_exit();
18566325755SMatthew Dillon }
18666325755SMatthew Dillon 
18766325755SMatthew Dillon void
18866325755SMatthew Dillon hammer_ref(struct hammer_lock *lock)
18966325755SMatthew Dillon {
1900b075555SMatthew Dillon 	KKASSERT(lock->refs >= 0);
19166325755SMatthew Dillon 	crit_enter();
19266325755SMatthew Dillon 	++lock->refs;
19366325755SMatthew Dillon 	crit_exit();
19466325755SMatthew Dillon }
19566325755SMatthew Dillon 
19666325755SMatthew Dillon void
19766325755SMatthew Dillon hammer_unref(struct hammer_lock *lock)
19866325755SMatthew Dillon {
199a89aec1bSMatthew Dillon 	KKASSERT(lock->refs > 0);
2000b075555SMatthew Dillon 	crit_enter();
20166325755SMatthew Dillon 	--lock->refs;
20266325755SMatthew Dillon 	crit_exit();
20366325755SMatthew Dillon }
20466325755SMatthew Dillon 
205*2f85fa4dSMatthew Dillon /*
206*2f85fa4dSMatthew Dillon  * The sync_lock must be held when doing any modifying operations on
207*2f85fa4dSMatthew Dillon  * meta-data.  The flusher holds the lock exclusively while the reblocker
208*2f85fa4dSMatthew Dillon  * and pruner use a shared lock.
209*2f85fa4dSMatthew Dillon  *
210*2f85fa4dSMatthew Dillon  * Modifying operations can run in parallel until the flusher needs to
211*2f85fa4dSMatthew Dillon  * sync the disk media.
212*2f85fa4dSMatthew Dillon  */
213*2f85fa4dSMatthew Dillon void
214*2f85fa4dSMatthew Dillon hammer_sync_lock_ex(hammer_transaction_t trans)
215*2f85fa4dSMatthew Dillon {
216*2f85fa4dSMatthew Dillon 	++trans->sync_lock_refs;
217*2f85fa4dSMatthew Dillon 	hammer_lock_sh(&trans->hmp->sync_lock);
218*2f85fa4dSMatthew Dillon }
219*2f85fa4dSMatthew Dillon 
220*2f85fa4dSMatthew Dillon void
221*2f85fa4dSMatthew Dillon hammer_sync_lock_sh(hammer_transaction_t trans)
222*2f85fa4dSMatthew Dillon {
223*2f85fa4dSMatthew Dillon 	++trans->sync_lock_refs;
224*2f85fa4dSMatthew Dillon 	hammer_lock_ex(&trans->hmp->sync_lock);
225*2f85fa4dSMatthew Dillon }
226*2f85fa4dSMatthew Dillon 
227*2f85fa4dSMatthew Dillon void
228*2f85fa4dSMatthew Dillon hammer_sync_unlock(hammer_transaction_t trans)
229*2f85fa4dSMatthew Dillon {
230*2f85fa4dSMatthew Dillon 	--trans->sync_lock_refs;
231*2f85fa4dSMatthew Dillon 	hammer_unlock(&trans->hmp->sync_lock);
232*2f85fa4dSMatthew Dillon }
233*2f85fa4dSMatthew Dillon 
234*2f85fa4dSMatthew Dillon /*
235*2f85fa4dSMatthew Dillon  * Misc
236*2f85fa4dSMatthew Dillon  */
23766325755SMatthew Dillon u_int32_t
23866325755SMatthew Dillon hammer_to_unix_xid(uuid_t *uuid)
23966325755SMatthew Dillon {
24066325755SMatthew Dillon 	return(*(u_int32_t *)&uuid->node[2]);
24166325755SMatthew Dillon }
24266325755SMatthew Dillon 
24366325755SMatthew Dillon void
2448cd0a023SMatthew Dillon hammer_guid_to_uuid(uuid_t *uuid, u_int32_t guid)
24566325755SMatthew Dillon {
2468cd0a023SMatthew Dillon 	bzero(uuid, sizeof(*uuid));
2478cd0a023SMatthew Dillon 	*(u_int32_t *)&uuid->node[2] = guid;
24866325755SMatthew Dillon }
24966325755SMatthew Dillon 
2508cd0a023SMatthew Dillon void
2518cd0a023SMatthew Dillon hammer_to_timespec(hammer_tid_t tid, struct timespec *ts)
2528cd0a023SMatthew Dillon {
2538cd0a023SMatthew Dillon 	ts->tv_sec = tid / 1000000000;
2548cd0a023SMatthew Dillon 	ts->tv_nsec = tid % 1000000000;
2558cd0a023SMatthew Dillon }
2568cd0a023SMatthew Dillon 
2578cd0a023SMatthew Dillon hammer_tid_t
2588cd0a023SMatthew Dillon hammer_timespec_to_transid(struct timespec *ts)
2598cd0a023SMatthew Dillon {
2608cd0a023SMatthew Dillon 	hammer_tid_t tid;
2618cd0a023SMatthew Dillon 
2628cd0a023SMatthew Dillon 	tid = ts->tv_nsec + (unsigned long)ts->tv_sec * 1000000000LL;
2638cd0a023SMatthew Dillon 	return(tid);
2648cd0a023SMatthew Dillon }
2658cd0a023SMatthew Dillon 
2668cd0a023SMatthew Dillon 
26766325755SMatthew Dillon /*
26866325755SMatthew Dillon  * Convert a HAMMER filesystem object type to a vnode type
26966325755SMatthew Dillon  */
27066325755SMatthew Dillon enum vtype
27166325755SMatthew Dillon hammer_get_vnode_type(u_int8_t obj_type)
27266325755SMatthew Dillon {
27366325755SMatthew Dillon 	switch(obj_type) {
27466325755SMatthew Dillon 	case HAMMER_OBJTYPE_DIRECTORY:
27566325755SMatthew Dillon 		return(VDIR);
27666325755SMatthew Dillon 	case HAMMER_OBJTYPE_REGFILE:
27766325755SMatthew Dillon 		return(VREG);
27866325755SMatthew Dillon 	case HAMMER_OBJTYPE_DBFILE:
27966325755SMatthew Dillon 		return(VDATABASE);
28066325755SMatthew Dillon 	case HAMMER_OBJTYPE_FIFO:
28166325755SMatthew Dillon 		return(VFIFO);
28266325755SMatthew Dillon 	case HAMMER_OBJTYPE_CDEV:
28366325755SMatthew Dillon 		return(VCHR);
28466325755SMatthew Dillon 	case HAMMER_OBJTYPE_BDEV:
28566325755SMatthew Dillon 		return(VBLK);
28666325755SMatthew Dillon 	case HAMMER_OBJTYPE_SOFTLINK:
28766325755SMatthew Dillon 		return(VLNK);
28866325755SMatthew Dillon 	default:
28966325755SMatthew Dillon 		return(VBAD);
29066325755SMatthew Dillon 	}
29166325755SMatthew Dillon 	/* not reached */
29266325755SMatthew Dillon }
29366325755SMatthew Dillon 
2946b4f890bSMatthew Dillon int
2956b4f890bSMatthew Dillon hammer_get_dtype(u_int8_t obj_type)
2966b4f890bSMatthew Dillon {
2976b4f890bSMatthew Dillon 	switch(obj_type) {
2986b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_DIRECTORY:
2996b4f890bSMatthew Dillon 		return(DT_DIR);
3006b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_REGFILE:
3016b4f890bSMatthew Dillon 		return(DT_REG);
3026b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_DBFILE:
3036b4f890bSMatthew Dillon 		return(DT_DBF);
3046b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_FIFO:
3056b4f890bSMatthew Dillon 		return(DT_FIFO);
3066b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_CDEV:
3076b4f890bSMatthew Dillon 		return(DT_CHR);
3086b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_BDEV:
3096b4f890bSMatthew Dillon 		return(DT_BLK);
3106b4f890bSMatthew Dillon 	case HAMMER_OBJTYPE_SOFTLINK:
3116b4f890bSMatthew Dillon 		return(DT_LNK);
3126b4f890bSMatthew Dillon 	default:
3136b4f890bSMatthew Dillon 		return(DT_UNKNOWN);
3146b4f890bSMatthew Dillon 	}
3156b4f890bSMatthew Dillon 	/* not reached */
3166b4f890bSMatthew Dillon }
3176b4f890bSMatthew Dillon 
31866325755SMatthew Dillon u_int8_t
31966325755SMatthew Dillon hammer_get_obj_type(enum vtype vtype)
32066325755SMatthew Dillon {
32166325755SMatthew Dillon 	switch(vtype) {
32266325755SMatthew Dillon 	case VDIR:
32366325755SMatthew Dillon 		return(HAMMER_OBJTYPE_DIRECTORY);
32466325755SMatthew Dillon 	case VREG:
32566325755SMatthew Dillon 		return(HAMMER_OBJTYPE_REGFILE);
32666325755SMatthew Dillon 	case VDATABASE:
32766325755SMatthew Dillon 		return(HAMMER_OBJTYPE_DBFILE);
32866325755SMatthew Dillon 	case VFIFO:
32966325755SMatthew Dillon 		return(HAMMER_OBJTYPE_FIFO);
33066325755SMatthew Dillon 	case VCHR:
33166325755SMatthew Dillon 		return(HAMMER_OBJTYPE_CDEV);
33266325755SMatthew Dillon 	case VBLK:
33366325755SMatthew Dillon 		return(HAMMER_OBJTYPE_BDEV);
33466325755SMatthew Dillon 	case VLNK:
33566325755SMatthew Dillon 		return(HAMMER_OBJTYPE_SOFTLINK);
33666325755SMatthew Dillon 	default:
33766325755SMatthew Dillon 		return(HAMMER_OBJTYPE_UNKNOWN);
33866325755SMatthew Dillon 	}
33966325755SMatthew Dillon 	/* not reached */
34066325755SMatthew Dillon }
34166325755SMatthew Dillon 
34266325755SMatthew Dillon /*
34366325755SMatthew Dillon  * Return a namekey hash.   The 64 bit namekey hash consists of a 32 bit
34466325755SMatthew Dillon  * crc in the MSB and 0 in the LSB.  The caller will use the low bits to
34566325755SMatthew Dillon  * generate a unique key and will scan all entries with the same upper
34666325755SMatthew Dillon  * 32 bits when issuing a lookup.
3476b4f890bSMatthew Dillon  *
3486b4f890bSMatthew Dillon  * We strip bit 63 in order to provide a positive key, this way a seek
3496b4f890bSMatthew Dillon  * offset of 0 will represent the base of the directory.
350b3deaf57SMatthew Dillon  *
351b3deaf57SMatthew Dillon  * This function can never return 0.  We use the MSB-0 space to synthesize
352b3deaf57SMatthew Dillon  * artificial directory entries such as "." and "..".
35366325755SMatthew Dillon  */
35466325755SMatthew Dillon int64_t
35566325755SMatthew Dillon hammer_directory_namekey(void *name, int len)
35666325755SMatthew Dillon {
35766325755SMatthew Dillon 	int64_t key;
35866325755SMatthew Dillon 
3596b4f890bSMatthew Dillon 	key = (int64_t)(crc32(name, len) & 0x7FFFFFFF) << 32;
360b3deaf57SMatthew Dillon 	if (key == 0)
361b3deaf57SMatthew Dillon 		key |= 0x100000000LL;
36266325755SMatthew Dillon 	return(key);
363427e5fc6SMatthew Dillon }
364427e5fc6SMatthew Dillon 
3657f7c1f84SMatthew Dillon hammer_tid_t
3667f7c1f84SMatthew Dillon hammer_now_tid(void)
3677f7c1f84SMatthew Dillon {
3687f7c1f84SMatthew Dillon 	struct timespec ts;
3697f7c1f84SMatthew Dillon 	hammer_tid_t tid;
3707f7c1f84SMatthew Dillon 
3717f7c1f84SMatthew Dillon 	getnanotime(&ts);
3727f7c1f84SMatthew Dillon 	tid = ts.tv_sec * 1000000000LL + ts.tv_nsec;
3737f7c1f84SMatthew Dillon 	return(tid);
3747f7c1f84SMatthew Dillon }
3757f7c1f84SMatthew Dillon 
376d113fda1SMatthew Dillon hammer_tid_t
377d113fda1SMatthew Dillon hammer_str_to_tid(const char *str)
378d113fda1SMatthew Dillon {
379d113fda1SMatthew Dillon 	hammer_tid_t tid;
3807dc57964SMatthew Dillon 	int len = strlen(str);
381d113fda1SMatthew Dillon 
3827dc57964SMatthew Dillon 	if (len > 10)
3837dc57964SMatthew Dillon 		tid = strtouq(str, NULL, 0);			/* full TID */
3847dc57964SMatthew Dillon 	else
3857dc57964SMatthew Dillon 		tid = strtouq(str, NULL, 0) * 1000000000LL;	/* time_t */
386d113fda1SMatthew Dillon 	return(tid);
387d113fda1SMatthew Dillon }
388d113fda1SMatthew Dillon 
38919619882SMatthew Dillon void
39019619882SMatthew Dillon hammer_crc_set_blockmap(hammer_blockmap_t blockmap)
39119619882SMatthew Dillon {
39219619882SMatthew Dillon 	blockmap->entry_crc = crc32(blockmap, HAMMER_BLOCKMAP_CRCSIZE);
39319619882SMatthew Dillon }
39419619882SMatthew Dillon 
39519619882SMatthew Dillon void
39619619882SMatthew Dillon hammer_crc_set_volume(hammer_volume_ondisk_t ondisk)
39719619882SMatthew Dillon {
39819619882SMatthew Dillon 	ondisk->vol_crc = crc32(ondisk, HAMMER_VOL_CRCSIZE1) ^
39919619882SMatthew Dillon 			  crc32(&ondisk->vol_crc + 1, HAMMER_VOL_CRCSIZE2);
40019619882SMatthew Dillon }
40119619882SMatthew Dillon 
40219619882SMatthew Dillon int
40319619882SMatthew Dillon hammer_crc_test_blockmap(hammer_blockmap_t blockmap)
40419619882SMatthew Dillon {
40519619882SMatthew Dillon 	hammer_crc_t crc;
40619619882SMatthew Dillon 
40719619882SMatthew Dillon 	crc = crc32(blockmap, HAMMER_BLOCKMAP_CRCSIZE);
40819619882SMatthew Dillon 	return (blockmap->entry_crc == crc);
40919619882SMatthew Dillon }
41019619882SMatthew Dillon 
41119619882SMatthew Dillon int
41219619882SMatthew Dillon hammer_crc_test_volume(hammer_volume_ondisk_t ondisk)
41319619882SMatthew Dillon {
41419619882SMatthew Dillon 	hammer_crc_t crc;
41519619882SMatthew Dillon 
41619619882SMatthew Dillon 	crc = crc32(ondisk, HAMMER_VOL_CRCSIZE1) ^
41719619882SMatthew Dillon 	      crc32(&ondisk->vol_crc + 1, HAMMER_VOL_CRCSIZE2);
41819619882SMatthew Dillon 	return (ondisk->vol_crc == crc);
41919619882SMatthew Dillon }
42019619882SMatthew Dillon 
42119619882SMatthew Dillon int
42219619882SMatthew Dillon hammer_crc_test_btree(hammer_node_ondisk_t ondisk)
42319619882SMatthew Dillon {
42419619882SMatthew Dillon 	hammer_crc_t crc;
42519619882SMatthew Dillon 
42619619882SMatthew Dillon 	crc = crc32(&ondisk->crc + 1, HAMMER_BTREE_CRCSIZE);
42719619882SMatthew Dillon 	return (ondisk->crc == crc);
42819619882SMatthew Dillon }
42919619882SMatthew Dillon 
43077062c8aSMatthew Dillon void
43177062c8aSMatthew Dillon hkprintf(const char *ctl, ...)
43277062c8aSMatthew Dillon {
43377062c8aSMatthew Dillon 	__va_list va;
43477062c8aSMatthew Dillon 
43577062c8aSMatthew Dillon 	if (hammer_debug_debug) {
43677062c8aSMatthew Dillon 		__va_start(va, ctl);
43777062c8aSMatthew Dillon 		kvprintf(ctl, va);
43877062c8aSMatthew Dillon 		__va_end(va);
43977062c8aSMatthew Dillon 	}
44077062c8aSMatthew Dillon }
44177062c8aSMatthew Dillon 
442