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