1e118c14fSMatthew Dillon /* 268b321c1SMatthew Dillon * Copyright (c) 2011-2018 The DragonFly Project. All rights reserved. 3e118c14fSMatthew Dillon * 4e118c14fSMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5e118c14fSMatthew Dillon * by Matthew Dillon <dillon@dragonflybsd.org> 6e118c14fSMatthew Dillon * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> 7e118c14fSMatthew Dillon * 8e118c14fSMatthew Dillon * Redistribution and use in source and binary forms, with or without 9e118c14fSMatthew Dillon * modification, are permitted provided that the following conditions 10e118c14fSMatthew Dillon * are met: 11e118c14fSMatthew Dillon * 12e118c14fSMatthew Dillon * 1. Redistributions of source code must retain the above copyright 13e118c14fSMatthew Dillon * notice, this list of conditions and the following disclaimer. 14e118c14fSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 15e118c14fSMatthew Dillon * notice, this list of conditions and the following disclaimer in 16e118c14fSMatthew Dillon * the documentation and/or other materials provided with the 17e118c14fSMatthew Dillon * distribution. 18e118c14fSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 19e118c14fSMatthew Dillon * contributors may be used to endorse or promote products derived 20e118c14fSMatthew Dillon * from this software without specific, prior written permission. 21e118c14fSMatthew Dillon * 22e118c14fSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23e118c14fSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24e118c14fSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25e118c14fSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26e118c14fSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27e118c14fSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28e118c14fSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29e118c14fSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30e118c14fSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31e118c14fSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32e118c14fSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33e118c14fSMatthew Dillon * SUCH DAMAGE. 34e118c14fSMatthew Dillon */ 35703720e4SMatthew Dillon #include <sys/cdefs.h> 36703720e4SMatthew Dillon #include <sys/param.h> 37703720e4SMatthew Dillon #include <sys/systm.h> 38703720e4SMatthew Dillon #include <sys/types.h> 39703720e4SMatthew Dillon #include <sys/lock.h> 40703720e4SMatthew Dillon #include <sys/uuid.h> 41e028fa74SMatthew Dillon #include <sys/dirent.h> 42703720e4SMatthew Dillon 43703720e4SMatthew Dillon #include "hammer2.h" 44703720e4SMatthew Dillon 45703720e4SMatthew Dillon /* 46703720e4SMatthew Dillon * Mount-wide locks 47703720e4SMatthew Dillon */ 48703720e4SMatthew Dillon void 49506bd6d1SMatthew Dillon hammer2_dev_exlock(hammer2_dev_t *hmp) 50703720e4SMatthew Dillon { 51f1c7c224SMatthew Dillon hammer2_mtx_ex(&hmp->vchain.lock); 52703720e4SMatthew Dillon } 53703720e4SMatthew Dillon 54703720e4SMatthew Dillon void 55506bd6d1SMatthew Dillon hammer2_dev_shlock(hammer2_dev_t *hmp) 56703720e4SMatthew Dillon { 57f1c7c224SMatthew Dillon hammer2_mtx_sh(&hmp->vchain.lock); 58703720e4SMatthew Dillon } 59703720e4SMatthew Dillon 60703720e4SMatthew Dillon void 61506bd6d1SMatthew Dillon hammer2_dev_unlock(hammer2_dev_t *hmp) 62703720e4SMatthew Dillon { 63f1c7c224SMatthew Dillon hammer2_mtx_unlock(&hmp->vchain.lock); 64703720e4SMatthew Dillon } 65703720e4SMatthew Dillon 66703720e4SMatthew Dillon /* 67476d2aadSMatthew Dillon * Return the directory entry type for an inode. 68476d2aadSMatthew Dillon * 69476d2aadSMatthew Dillon * ip must be locked sh/ex. 70e028fa74SMatthew Dillon */ 71e028fa74SMatthew Dillon int 72da0cdd33SMatthew Dillon hammer2_get_dtype(uint8_t type) 73e028fa74SMatthew Dillon { 7499535653SMatthew Dillon switch(type) { 75e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_UNKNOWN: 76e028fa74SMatthew Dillon return (DT_UNKNOWN); 77e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_DIRECTORY: 78e028fa74SMatthew Dillon return (DT_DIR); 79e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_REGFILE: 80e028fa74SMatthew Dillon return (DT_REG); 81e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_FIFO: 82e028fa74SMatthew Dillon return (DT_FIFO); 83e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_CDEV: /* not supported */ 84e028fa74SMatthew Dillon return (DT_CHR); 85e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_BDEV: /* not supported */ 86e028fa74SMatthew Dillon return (DT_BLK); 87e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_SOFTLINK: 88e028fa74SMatthew Dillon return (DT_LNK); 89e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_SOCKET: 90e028fa74SMatthew Dillon return (DT_SOCK); 91e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_WHITEOUT: /* not supported */ 92e028fa74SMatthew Dillon return (DT_UNKNOWN); 93e028fa74SMatthew Dillon default: 94e028fa74SMatthew Dillon return (DT_UNKNOWN); 95e028fa74SMatthew Dillon } 96e028fa74SMatthew Dillon /* not reached */ 97e028fa74SMatthew Dillon } 98e028fa74SMatthew Dillon 99cd4b3d92SMatthew Dillon /* 100cd4b3d92SMatthew Dillon * Return the directory entry type for an inode 101cd4b3d92SMatthew Dillon */ 102cd4b3d92SMatthew Dillon int 103159c3ca2SMatthew Dillon hammer2_get_vtype(uint8_t type) 104cd4b3d92SMatthew Dillon { 105159c3ca2SMatthew Dillon switch(type) { 106cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_UNKNOWN: 107cd4b3d92SMatthew Dillon return (VBAD); 108cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_DIRECTORY: 109cd4b3d92SMatthew Dillon return (VDIR); 110cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_REGFILE: 111cd4b3d92SMatthew Dillon return (VREG); 112cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_FIFO: 113cd4b3d92SMatthew Dillon return (VFIFO); 114cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_CDEV: /* not supported */ 115cd4b3d92SMatthew Dillon return (VCHR); 116cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_BDEV: /* not supported */ 117cd4b3d92SMatthew Dillon return (VBLK); 118cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_SOFTLINK: 119cd4b3d92SMatthew Dillon return (VLNK); 120cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_SOCKET: 121cd4b3d92SMatthew Dillon return (VSOCK); 122cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_WHITEOUT: /* not supported */ 123cd4b3d92SMatthew Dillon return (DT_UNKNOWN); 124cd4b3d92SMatthew Dillon default: 125cd4b3d92SMatthew Dillon return (DT_UNKNOWN); 126cd4b3d92SMatthew Dillon } 127cd4b3d92SMatthew Dillon /* not reached */ 128cd4b3d92SMatthew Dillon } 129cd4b3d92SMatthew Dillon 1302f70512bSTomohiro Kusumi uint8_t 13137494cabSMatthew Dillon hammer2_get_obj_type(enum vtype vtype) 13237494cabSMatthew Dillon { 13337494cabSMatthew Dillon switch(vtype) { 13437494cabSMatthew Dillon case VDIR: 13537494cabSMatthew Dillon return(HAMMER2_OBJTYPE_DIRECTORY); 13637494cabSMatthew Dillon case VREG: 13737494cabSMatthew Dillon return(HAMMER2_OBJTYPE_REGFILE); 13837494cabSMatthew Dillon case VFIFO: 13937494cabSMatthew Dillon return(HAMMER2_OBJTYPE_FIFO); 14037494cabSMatthew Dillon case VSOCK: 14137494cabSMatthew Dillon return(HAMMER2_OBJTYPE_SOCKET); 14237494cabSMatthew Dillon case VCHR: 14337494cabSMatthew Dillon return(HAMMER2_OBJTYPE_CDEV); 14437494cabSMatthew Dillon case VBLK: 14537494cabSMatthew Dillon return(HAMMER2_OBJTYPE_BDEV); 14637494cabSMatthew Dillon case VLNK: 14737494cabSMatthew Dillon return(HAMMER2_OBJTYPE_SOFTLINK); 14837494cabSMatthew Dillon default: 14937494cabSMatthew Dillon return(HAMMER2_OBJTYPE_UNKNOWN); 15037494cabSMatthew Dillon } 15137494cabSMatthew Dillon /* not reached */ 15237494cabSMatthew Dillon } 15337494cabSMatthew Dillon 154cd4b3d92SMatthew Dillon /* 155cd4b3d92SMatthew Dillon * Convert a hammer2 64-bit time to a timespec. 156cd4b3d92SMatthew Dillon */ 157cd4b3d92SMatthew Dillon void 1582f70512bSTomohiro Kusumi hammer2_time_to_timespec(uint64_t xtime, struct timespec *ts) 159cd4b3d92SMatthew Dillon { 160cd4b3d92SMatthew Dillon ts->tv_sec = (unsigned long)(xtime / 1000000); 161cd4b3d92SMatthew Dillon ts->tv_nsec = (unsigned int)(xtime % 1000000) * 1000L; 162cd4b3d92SMatthew Dillon } 163cd4b3d92SMatthew Dillon 1642f70512bSTomohiro Kusumi uint64_t 1656a5f4fe6SMatthew Dillon hammer2_timespec_to_time(const struct timespec *ts) 166b2b78aaaSMatthew Dillon { 1672f70512bSTomohiro Kusumi uint64_t xtime; 168b2b78aaaSMatthew Dillon 169b2b78aaaSMatthew Dillon xtime = (unsigned)(ts->tv_nsec / 1000) + 170b2b78aaaSMatthew Dillon (unsigned long)ts->tv_sec * 1000000ULL; 171b2b78aaaSMatthew Dillon return(xtime); 172b2b78aaaSMatthew Dillon } 173b2b78aaaSMatthew Dillon 17437494cabSMatthew Dillon /* 17537494cabSMatthew Dillon * Convert a uuid to a unix uid or gid 17637494cabSMatthew Dillon */ 1772f70512bSTomohiro Kusumi uint32_t 1786a5f4fe6SMatthew Dillon hammer2_to_unix_xid(const uuid_t *uuid) 17937494cabSMatthew Dillon { 1802f70512bSTomohiro Kusumi return(*(const uint32_t *)&uuid->node[2]); 18137494cabSMatthew Dillon } 182e028fa74SMatthew Dillon 183b2b78aaaSMatthew Dillon void 1842f70512bSTomohiro Kusumi hammer2_guid_to_uuid(uuid_t *uuid, uint32_t guid) 185b2b78aaaSMatthew Dillon { 186b2b78aaaSMatthew Dillon bzero(uuid, sizeof(*uuid)); 1872f70512bSTomohiro Kusumi *(uint32_t *)&uuid->node[2] = guid; 188b2b78aaaSMatthew Dillon } 189b2b78aaaSMatthew Dillon 190e028fa74SMatthew Dillon /* 19150e4f8f4SMatthew Dillon * Borrow HAMMER1's directory hash algorithm #1 with a few modifications. 19250e4f8f4SMatthew Dillon * The filename is split into fields which are hashed separately and then 19350e4f8f4SMatthew Dillon * added together. 19450e4f8f4SMatthew Dillon * 19550e4f8f4SMatthew Dillon * Differences include: bit 63 must be set to 1 for HAMMER2 (HAMMER1 sets 19650e4f8f4SMatthew Dillon * it to 0), this is because bit63=0 is used for hidden hardlinked inodes. 19750e4f8f4SMatthew Dillon * (This means we do not need to do a 0-check/or-with-0x100000000 either). 19850e4f8f4SMatthew Dillon * 19950e4f8f4SMatthew Dillon * Also, the iscsi crc code is used instead of the old crc32 code. 20050e4f8f4SMatthew Dillon */ 20150e4f8f4SMatthew Dillon hammer2_key_t 20250e4f8f4SMatthew Dillon hammer2_dirhash(const unsigned char *name, size_t len) 20350e4f8f4SMatthew Dillon { 20450e4f8f4SMatthew Dillon const unsigned char *aname = name; 20550e4f8f4SMatthew Dillon uint32_t crcx; 20650e4f8f4SMatthew Dillon uint64_t key; 20750e4f8f4SMatthew Dillon size_t i; 20850e4f8f4SMatthew Dillon size_t j; 20950e4f8f4SMatthew Dillon 21050e4f8f4SMatthew Dillon key = 0; 21150e4f8f4SMatthew Dillon 21250e4f8f4SMatthew Dillon /* 21350e4f8f4SMatthew Dillon * m32 21450e4f8f4SMatthew Dillon */ 21550e4f8f4SMatthew Dillon crcx = 0; 21650e4f8f4SMatthew Dillon for (i = j = 0; i < len; ++i) { 21750e4f8f4SMatthew Dillon if (aname[i] == '.' || 21850e4f8f4SMatthew Dillon aname[i] == '-' || 21950e4f8f4SMatthew Dillon aname[i] == '_' || 22050e4f8f4SMatthew Dillon aname[i] == '~') { 22150e4f8f4SMatthew Dillon if (i != j) 22250e4f8f4SMatthew Dillon crcx += hammer2_icrc32(aname + j, i - j); 22350e4f8f4SMatthew Dillon j = i + 1; 22450e4f8f4SMatthew Dillon } 22550e4f8f4SMatthew Dillon } 22650e4f8f4SMatthew Dillon if (i != j) 22750e4f8f4SMatthew Dillon crcx += hammer2_icrc32(aname + j, i - j); 22850e4f8f4SMatthew Dillon 22950e4f8f4SMatthew Dillon /* 23050e4f8f4SMatthew Dillon * The directory hash utilizes the top 32 bits of the 64-bit key. 23150e4f8f4SMatthew Dillon * Bit 63 must be set to 1. 23250e4f8f4SMatthew Dillon */ 23350e4f8f4SMatthew Dillon crcx |= 0x80000000U; 23450e4f8f4SMatthew Dillon key |= (uint64_t)crcx << 32; 23550e4f8f4SMatthew Dillon 23650e4f8f4SMatthew Dillon /* 23750e4f8f4SMatthew Dillon * l16 - crc of entire filename 23850e4f8f4SMatthew Dillon * 23950e4f8f4SMatthew Dillon * This crc reduces degenerate hash collision conditions 24050e4f8f4SMatthew Dillon */ 24150e4f8f4SMatthew Dillon crcx = hammer2_icrc32(aname, len); 24250e4f8f4SMatthew Dillon crcx = crcx ^ (crcx << 16); 24350e4f8f4SMatthew Dillon key |= crcx & 0xFFFF0000U; 24450e4f8f4SMatthew Dillon 245e028fa74SMatthew Dillon /* 246e028fa74SMatthew Dillon * Set bit 15. This allows readdir to strip bit 63 so a positive 247e028fa74SMatthew Dillon * 64-bit cookie/offset can always be returned, and still guarantee 248e028fa74SMatthew Dillon * that the values 0x0000-0x7FFF are available for artificial entries. 249e028fa74SMatthew Dillon * ('.' and '..'). 250e028fa74SMatthew Dillon */ 251e028fa74SMatthew Dillon key |= 0x8000U; 252e028fa74SMatthew Dillon 25350e4f8f4SMatthew Dillon return (key); 25450e4f8f4SMatthew Dillon } 2556ba3b984SMatthew Dillon 2561a7cfe5aSMatthew Dillon /* 257da0cdd33SMatthew Dillon * Convert bytes to radix with no limitations. 258da0cdd33SMatthew Dillon * 259da0cdd33SMatthew Dillon * 0 bytes is special-cased to a radix of zero (which would normally 260da0cdd33SMatthew Dillon * translate to (1 << 0) == 1). 2611a7cfe5aSMatthew Dillon */ 2621a7cfe5aSMatthew Dillon int 2631a7cfe5aSMatthew Dillon hammer2_getradix(size_t bytes) 2641a7cfe5aSMatthew Dillon { 2651a7cfe5aSMatthew Dillon int radix; 2661a7cfe5aSMatthew Dillon 267da0cdd33SMatthew Dillon /* 268da0cdd33SMatthew Dillon * Optimize the iteration by pre-checking commonly used radii. 269da0cdd33SMatthew Dillon */ 2701a7cfe5aSMatthew Dillon if (bytes == HAMMER2_PBUFSIZE) 2711a7cfe5aSMatthew Dillon radix = HAMMER2_PBUFRADIX; 27293f3933aSMatthew Dillon else if (bytes >= HAMMER2_LBUFSIZE) 27393f3933aSMatthew Dillon radix = HAMMER2_LBUFRADIX; 27450456506SMatthew Dillon else if (bytes >= HAMMER2_ALLOC_MIN) /* clamp */ 27550456506SMatthew Dillon radix = HAMMER2_RADIX_MIN; 2761a7cfe5aSMatthew Dillon else 2771a7cfe5aSMatthew Dillon radix = 0; 2781a7cfe5aSMatthew Dillon 279da0cdd33SMatthew Dillon /* 280da0cdd33SMatthew Dillon * Iterate as needed. Note that bytes == 0 is expected to return 281da0cdd33SMatthew Dillon * a radix of 0 as a special case. 282da0cdd33SMatthew Dillon */ 2831a7cfe5aSMatthew Dillon while (((size_t)1 << radix) < bytes) 2841a7cfe5aSMatthew Dillon ++radix; 2851a7cfe5aSMatthew Dillon return (radix); 2861a7cfe5aSMatthew Dillon } 2871a7cfe5aSMatthew Dillon 288476d2aadSMatthew Dillon /* 2897a9b14a0SMatthew Dillon * The logical block size is currently always PBUFSIZE. 290476d2aadSMatthew Dillon */ 2918cce658dSMatthew Dillon int 2928cce658dSMatthew Dillon hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff, 2938cce658dSMatthew Dillon hammer2_key_t *lbasep, hammer2_key_t *leofp) 2948cce658dSMatthew Dillon { 2957a9b14a0SMatthew Dillon KKASSERT(ip->flags & HAMMER2_INODE_METAGOOD); 296355d67fcSMatthew Dillon if (lbasep) 297355d67fcSMatthew Dillon *lbasep = uoff & ~HAMMER2_PBUFMASK64; 298355d67fcSMatthew Dillon if (leofp) { 2997a9b14a0SMatthew Dillon *leofp = (ip->meta.size + HAMMER2_PBUFMASK64) & 300355d67fcSMatthew Dillon ~HAMMER2_PBUFMASK64; 301355d67fcSMatthew Dillon } 302355d67fcSMatthew Dillon return (HAMMER2_PBUFSIZE); 303355d67fcSMatthew Dillon } 304355d67fcSMatthew Dillon 305355d67fcSMatthew Dillon /* 306355d67fcSMatthew Dillon * Calculate the physical block size. pblksize <= lblksize. Primarily 307355d67fcSMatthew Dillon * used to calculate a smaller physical block for the logical block 308355d67fcSMatthew Dillon * containing the file EOF. 309355d67fcSMatthew Dillon * 310355d67fcSMatthew Dillon * Returns 0 if the requested base offset is beyond the file EOF. 311355d67fcSMatthew Dillon */ 312355d67fcSMatthew Dillon int 3137a9b14a0SMatthew Dillon hammer2_calc_physical(hammer2_inode_t *ip, hammer2_key_t lbase) 314355d67fcSMatthew Dillon { 315355d67fcSMatthew Dillon int lblksize; 316355d67fcSMatthew Dillon int pblksize; 317355d67fcSMatthew Dillon int eofbytes; 318355d67fcSMatthew Dillon 3197a9b14a0SMatthew Dillon KKASSERT(ip->flags & HAMMER2_INODE_METAGOOD); 320355d67fcSMatthew Dillon lblksize = hammer2_calc_logical(ip, lbase, NULL, NULL); 3217a9b14a0SMatthew Dillon if (lbase + lblksize <= ip->meta.size) 322355d67fcSMatthew Dillon return (lblksize); 3237a9b14a0SMatthew Dillon if (lbase >= ip->meta.size) 324355d67fcSMatthew Dillon return (0); 3257a9b14a0SMatthew Dillon eofbytes = (int)(ip->meta.size - lbase); 326355d67fcSMatthew Dillon pblksize = lblksize; 32750456506SMatthew Dillon while (pblksize >= eofbytes && pblksize >= HAMMER2_ALLOC_MIN) 328355d67fcSMatthew Dillon pblksize >>= 1; 329355d67fcSMatthew Dillon pblksize <<= 1; 330355d67fcSMatthew Dillon 331355d67fcSMatthew Dillon return (pblksize); 3328cce658dSMatthew Dillon } 333b2b78aaaSMatthew Dillon 334b2b78aaaSMatthew Dillon void 335b2b78aaaSMatthew Dillon hammer2_update_time(uint64_t *timep) 336b2b78aaaSMatthew Dillon { 337d489a79aSMatthew Dillon struct timespec ts; 338b2b78aaaSMatthew Dillon 339d489a79aSMatthew Dillon vfs_timestamp(&ts); 340d489a79aSMatthew Dillon *timep = (unsigned long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; 341b2b78aaaSMatthew Dillon } 342278ab2b2SMatthew Dillon 343278ab2b2SMatthew Dillon void 344*a552887fSTomohiro Kusumi hammer2_adjreadcounter(int btype, size_t bytes) 345278ab2b2SMatthew Dillon { 346278ab2b2SMatthew Dillon long *counterp; 347278ab2b2SMatthew Dillon 348*a552887fSTomohiro Kusumi switch(btype) { 349278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_DATA: 350278ab2b2SMatthew Dillon counterp = &hammer2_iod_file_read; 351278ab2b2SMatthew Dillon break; 352da0cdd33SMatthew Dillon case HAMMER2_BREF_TYPE_DIRENT: 353278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_INODE: 354278ab2b2SMatthew Dillon counterp = &hammer2_iod_meta_read; 355278ab2b2SMatthew Dillon break; 356278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_INDIRECT: 357278ab2b2SMatthew Dillon counterp = &hammer2_iod_indr_read; 358278ab2b2SMatthew Dillon break; 359278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_NODE: 360278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_LEAF: 361278ab2b2SMatthew Dillon counterp = &hammer2_iod_fmap_read; 362278ab2b2SMatthew Dillon break; 3631de4fc15STomohiro Kusumi case HAMMER2_BREF_TYPE_FREEMAP: 3641de4fc15STomohiro Kusumi case HAMMER2_BREF_TYPE_VOLUME: 365278ab2b2SMatthew Dillon counterp = &hammer2_iod_volu_read; 366278ab2b2SMatthew Dillon break; 3671de4fc15STomohiro Kusumi case HAMMER2_BREF_TYPE_EMPTY: 3681de4fc15STomohiro Kusumi default: 3691de4fc15STomohiro Kusumi return; 370278ab2b2SMatthew Dillon } 371278ab2b2SMatthew Dillon *counterp += bytes; 372278ab2b2SMatthew Dillon } 373d662271eSMatthew Dillon 374*a552887fSTomohiro Kusumi void 375*a552887fSTomohiro Kusumi hammer2_adjwritecounter(int btype, size_t bytes) 376*a552887fSTomohiro Kusumi { 377*a552887fSTomohiro Kusumi long *counterp; 378*a552887fSTomohiro Kusumi 379*a552887fSTomohiro Kusumi switch(btype) { 380*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_DATA: 381*a552887fSTomohiro Kusumi counterp = &hammer2_iod_file_write; 382*a552887fSTomohiro Kusumi break; 383*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_DIRENT: 384*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_INODE: 385*a552887fSTomohiro Kusumi counterp = &hammer2_iod_meta_write; 386*a552887fSTomohiro Kusumi break; 387*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_INDIRECT: 388*a552887fSTomohiro Kusumi counterp = &hammer2_iod_indr_write; 389*a552887fSTomohiro Kusumi break; 390*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_FREEMAP_NODE: 391*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_FREEMAP_LEAF: 392*a552887fSTomohiro Kusumi counterp = &hammer2_iod_fmap_write; 393*a552887fSTomohiro Kusumi break; 394*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_FREEMAP: 395*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_VOLUME: 396*a552887fSTomohiro Kusumi counterp = &hammer2_iod_volu_write; 397*a552887fSTomohiro Kusumi break; 398*a552887fSTomohiro Kusumi case HAMMER2_BREF_TYPE_EMPTY: 399*a552887fSTomohiro Kusumi default: 400*a552887fSTomohiro Kusumi return; 401*a552887fSTomohiro Kusumi } 402*a552887fSTomohiro Kusumi *counterp += bytes; 403*a552887fSTomohiro Kusumi } 404*a552887fSTomohiro Kusumi 4059dca9515SMatthew Dillon /* 4069dca9515SMatthew Dillon * Check for pending signal to allow interruption. This function will 4079dca9515SMatthew Dillon * return immediately if the calling thread is a kernel thread and not 4089dca9515SMatthew Dillon * a user thread. 4099dca9515SMatthew Dillon */ 410d662271eSMatthew Dillon int 411d662271eSMatthew Dillon hammer2_signal_check(time_t *timep) 412d662271eSMatthew Dillon { 4139dca9515SMatthew Dillon thread_t td = curthread; 414d662271eSMatthew Dillon int error = 0; 415d662271eSMatthew Dillon 4169dca9515SMatthew Dillon if (td->td_lwp) { 417d662271eSMatthew Dillon lwkt_user_yield(); 418d662271eSMatthew Dillon if (*timep != time_second) { 419d662271eSMatthew Dillon *timep = time_second; 4202d7e662fSMatthew Dillon if (CURSIG_NOBLOCK(curthread->td_lwp) != 0) 4211e2c8208SMatthew Dillon error = HAMMER2_ERROR_ABORTED; 422d662271eSMatthew Dillon } 4234ff0b408SMatthew Dillon } else { 4244ff0b408SMatthew Dillon lwkt_yield(); 4259dca9515SMatthew Dillon } 426d662271eSMatthew Dillon return error; 427d662271eSMatthew Dillon } 428b93cc2e0SMatthew Dillon 429b93cc2e0SMatthew Dillon const char * 430b93cc2e0SMatthew Dillon hammer2_error_str(int error) 431b93cc2e0SMatthew Dillon { 43265cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EIO) 43365cacacfSMatthew Dillon return("I/O Error"); 43465cacacfSMatthew Dillon if (error & HAMMER2_ERROR_CHECK) 43565cacacfSMatthew Dillon return("Check Error"); 43665cacacfSMatthew Dillon if (error & HAMMER2_ERROR_INCOMPLETE) 43765cacacfSMatthew Dillon return("Cluster Quorum Error"); 43865cacacfSMatthew Dillon if (error & HAMMER2_ERROR_DEPTH) 43965cacacfSMatthew Dillon return("Chain Depth Error"); 44065cacacfSMatthew Dillon if (error & HAMMER2_ERROR_BADBREF) 44165cacacfSMatthew Dillon return("Bad Blockref Error"); 44265cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ENOSPC) 44365cacacfSMatthew Dillon return("No Space on Device"); 44465cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ENOENT) 44565cacacfSMatthew Dillon return("Entry Not Found"); 44665cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ENOTEMPTY) 44765cacacfSMatthew Dillon return("Directory Not Empty"); 44865cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EAGAIN) 44965cacacfSMatthew Dillon return("EAGAIN"); 45065cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ENOTDIR) 45165cacacfSMatthew Dillon return("Not a Directory"); 45265cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EISDIR) 45365cacacfSMatthew Dillon return("Is a Directory"); 45465cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EINPROGRESS) 45565cacacfSMatthew Dillon return("Operation in Progress"); 45665cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ABORTED) 45765cacacfSMatthew Dillon return("Operation Aborted"); 45865cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EOF) 45965cacacfSMatthew Dillon return("Operation Complete"); 46065cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EINVAL) 46165cacacfSMatthew Dillon return("Invalid Operation"); 46265cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EEXIST) 46365cacacfSMatthew Dillon return("Object Exists"); 46465cacacfSMatthew Dillon if (error & HAMMER2_ERROR_EDEADLK) 46565cacacfSMatthew Dillon return("Deadlock Detected"); 46665cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ESRCH) 46765cacacfSMatthew Dillon return("Object Not Found"); 46865cacacfSMatthew Dillon if (error & HAMMER2_ERROR_ETIMEDOUT) 46965cacacfSMatthew Dillon return("Timeout"); 47065cacacfSMatthew Dillon return("Unknown Error"); 471b93cc2e0SMatthew Dillon } 4727ac04587SMatthew Dillon 4737ac04587SMatthew Dillon const char * 4747ac04587SMatthew Dillon hammer2_bref_type_str(hammer2_blockref_t *bref) 4757ac04587SMatthew Dillon { 4767ac04587SMatthew Dillon switch(bref->type) { 4777ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_EMPTY: 4787ac04587SMatthew Dillon return("Unknown-zero'd field"); 4797ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_INODE: 4807ac04587SMatthew Dillon return("Inode"); 4817ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_INDIRECT: 4827ac04587SMatthew Dillon return("Indirect-Block"); 4837ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_DATA: 4847ac04587SMatthew Dillon return("Data-Block"); 4857ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_DIRENT: 4867ac04587SMatthew Dillon return("Directory-Entry"); 4877ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_NODE: 4887ac04587SMatthew Dillon return("Freemap-Node"); 4897ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_LEAF: 4907ac04587SMatthew Dillon return("Freemap-Leaf"); 4917ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP: 4927ac04587SMatthew Dillon return("Freemap-Header"); 4937ac04587SMatthew Dillon case HAMMER2_BREF_TYPE_VOLUME: 4947ac04587SMatthew Dillon return("Volume-Header"); 4957ac04587SMatthew Dillon default: 4967ac04587SMatthew Dillon break; 4977ac04587SMatthew Dillon } 4987ac04587SMatthew Dillon return("Unknown"); 4997ac04587SMatthew Dillon } 500