1e118c14fSMatthew Dillon /* 28138a154SMatthew Dillon * Copyright (c) 2011-2014 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 { 51*f1c7c224SMatthew 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 { 57*f1c7c224SMatthew 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 { 63*f1c7c224SMatthew 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 726a5f4fe6SMatthew Dillon hammer2_get_dtype(const hammer2_inode_data_t *ipdata) 73e028fa74SMatthew Dillon { 7499535653SMatthew Dillon uint8_t type; 7599535653SMatthew Dillon 76278ab2b2SMatthew Dillon if ((type = ipdata->type) == HAMMER2_OBJTYPE_HARDLINK) 77278ab2b2SMatthew Dillon type = ipdata->target_type; 7899535653SMatthew Dillon 7999535653SMatthew Dillon switch(type) { 80e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_UNKNOWN: 81e028fa74SMatthew Dillon return (DT_UNKNOWN); 82e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_DIRECTORY: 83e028fa74SMatthew Dillon return (DT_DIR); 84e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_REGFILE: 85e028fa74SMatthew Dillon return (DT_REG); 86e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_FIFO: 87e028fa74SMatthew Dillon return (DT_FIFO); 88e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_CDEV: /* not supported */ 89e028fa74SMatthew Dillon return (DT_CHR); 90e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_BDEV: /* not supported */ 91e028fa74SMatthew Dillon return (DT_BLK); 92e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_SOFTLINK: 93e028fa74SMatthew Dillon return (DT_LNK); 94db0c2eb3SMatthew Dillon case HAMMER2_OBJTYPE_HARDLINK: /* (never directly associated w/vp) */ 95e028fa74SMatthew Dillon return (DT_UNKNOWN); 96e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_SOCKET: 97e028fa74SMatthew Dillon return (DT_SOCK); 98e028fa74SMatthew Dillon case HAMMER2_OBJTYPE_WHITEOUT: /* not supported */ 99e028fa74SMatthew Dillon return (DT_UNKNOWN); 100e028fa74SMatthew Dillon default: 101e028fa74SMatthew Dillon return (DT_UNKNOWN); 102e028fa74SMatthew Dillon } 103e028fa74SMatthew Dillon /* not reached */ 104e028fa74SMatthew Dillon } 105e028fa74SMatthew Dillon 106cd4b3d92SMatthew Dillon /* 107cd4b3d92SMatthew Dillon * Return the directory entry type for an inode 108cd4b3d92SMatthew Dillon */ 109cd4b3d92SMatthew Dillon int 1106a5f4fe6SMatthew Dillon hammer2_get_vtype(const hammer2_inode_data_t *ipdata) 111cd4b3d92SMatthew Dillon { 112278ab2b2SMatthew Dillon switch(ipdata->type) { 113cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_UNKNOWN: 114cd4b3d92SMatthew Dillon return (VBAD); 115cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_DIRECTORY: 116cd4b3d92SMatthew Dillon return (VDIR); 117cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_REGFILE: 118cd4b3d92SMatthew Dillon return (VREG); 119cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_FIFO: 120cd4b3d92SMatthew Dillon return (VFIFO); 121cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_CDEV: /* not supported */ 122cd4b3d92SMatthew Dillon return (VCHR); 123cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_BDEV: /* not supported */ 124cd4b3d92SMatthew Dillon return (VBLK); 125cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_SOFTLINK: 126cd4b3d92SMatthew Dillon return (VLNK); 127cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_HARDLINK: /* XXX */ 128cd4b3d92SMatthew Dillon return (VBAD); 129cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_SOCKET: 130cd4b3d92SMatthew Dillon return (VSOCK); 131cd4b3d92SMatthew Dillon case HAMMER2_OBJTYPE_WHITEOUT: /* not supported */ 132cd4b3d92SMatthew Dillon return (DT_UNKNOWN); 133cd4b3d92SMatthew Dillon default: 134cd4b3d92SMatthew Dillon return (DT_UNKNOWN); 135cd4b3d92SMatthew Dillon } 136cd4b3d92SMatthew Dillon /* not reached */ 137cd4b3d92SMatthew Dillon } 138cd4b3d92SMatthew Dillon 13937494cabSMatthew Dillon u_int8_t 14037494cabSMatthew Dillon hammer2_get_obj_type(enum vtype vtype) 14137494cabSMatthew Dillon { 14237494cabSMatthew Dillon switch(vtype) { 14337494cabSMatthew Dillon case VDIR: 14437494cabSMatthew Dillon return(HAMMER2_OBJTYPE_DIRECTORY); 14537494cabSMatthew Dillon case VREG: 14637494cabSMatthew Dillon return(HAMMER2_OBJTYPE_REGFILE); 14737494cabSMatthew Dillon case VFIFO: 14837494cabSMatthew Dillon return(HAMMER2_OBJTYPE_FIFO); 14937494cabSMatthew Dillon case VSOCK: 15037494cabSMatthew Dillon return(HAMMER2_OBJTYPE_SOCKET); 15137494cabSMatthew Dillon case VCHR: 15237494cabSMatthew Dillon return(HAMMER2_OBJTYPE_CDEV); 15337494cabSMatthew Dillon case VBLK: 15437494cabSMatthew Dillon return(HAMMER2_OBJTYPE_BDEV); 15537494cabSMatthew Dillon case VLNK: 15637494cabSMatthew Dillon return(HAMMER2_OBJTYPE_SOFTLINK); 15737494cabSMatthew Dillon default: 15837494cabSMatthew Dillon return(HAMMER2_OBJTYPE_UNKNOWN); 15937494cabSMatthew Dillon } 16037494cabSMatthew Dillon /* not reached */ 16137494cabSMatthew Dillon } 16237494cabSMatthew Dillon 163cd4b3d92SMatthew Dillon /* 164cd4b3d92SMatthew Dillon * Convert a hammer2 64-bit time to a timespec. 165cd4b3d92SMatthew Dillon */ 166cd4b3d92SMatthew Dillon void 167cd4b3d92SMatthew Dillon hammer2_time_to_timespec(u_int64_t xtime, struct timespec *ts) 168cd4b3d92SMatthew Dillon { 169cd4b3d92SMatthew Dillon ts->tv_sec = (unsigned long)(xtime / 1000000); 170cd4b3d92SMatthew Dillon ts->tv_nsec = (unsigned int)(xtime % 1000000) * 1000L; 171cd4b3d92SMatthew Dillon } 172cd4b3d92SMatthew Dillon 173b2b78aaaSMatthew Dillon u_int64_t 1746a5f4fe6SMatthew Dillon hammer2_timespec_to_time(const struct timespec *ts) 175b2b78aaaSMatthew Dillon { 176b2b78aaaSMatthew Dillon u_int64_t xtime; 177b2b78aaaSMatthew Dillon 178b2b78aaaSMatthew Dillon xtime = (unsigned)(ts->tv_nsec / 1000) + 179b2b78aaaSMatthew Dillon (unsigned long)ts->tv_sec * 1000000ULL; 180b2b78aaaSMatthew Dillon return(xtime); 181b2b78aaaSMatthew Dillon } 182b2b78aaaSMatthew Dillon 18337494cabSMatthew Dillon /* 18437494cabSMatthew Dillon * Convert a uuid to a unix uid or gid 18537494cabSMatthew Dillon */ 18637494cabSMatthew Dillon u_int32_t 1876a5f4fe6SMatthew Dillon hammer2_to_unix_xid(const uuid_t *uuid) 18837494cabSMatthew Dillon { 1896a5f4fe6SMatthew Dillon return(*(const u_int32_t *)&uuid->node[2]); 19037494cabSMatthew Dillon } 191e028fa74SMatthew Dillon 192b2b78aaaSMatthew Dillon void 193b2b78aaaSMatthew Dillon hammer2_guid_to_uuid(uuid_t *uuid, u_int32_t guid) 194b2b78aaaSMatthew Dillon { 195b2b78aaaSMatthew Dillon bzero(uuid, sizeof(*uuid)); 196b2b78aaaSMatthew Dillon *(u_int32_t *)&uuid->node[2] = guid; 197b2b78aaaSMatthew Dillon } 198b2b78aaaSMatthew Dillon 199e028fa74SMatthew Dillon /* 20050e4f8f4SMatthew Dillon * Borrow HAMMER1's directory hash algorithm #1 with a few modifications. 20150e4f8f4SMatthew Dillon * The filename is split into fields which are hashed separately and then 20250e4f8f4SMatthew Dillon * added together. 20350e4f8f4SMatthew Dillon * 20450e4f8f4SMatthew Dillon * Differences include: bit 63 must be set to 1 for HAMMER2 (HAMMER1 sets 20550e4f8f4SMatthew Dillon * it to 0), this is because bit63=0 is used for hidden hardlinked inodes. 20650e4f8f4SMatthew Dillon * (This means we do not need to do a 0-check/or-with-0x100000000 either). 20750e4f8f4SMatthew Dillon * 20850e4f8f4SMatthew Dillon * Also, the iscsi crc code is used instead of the old crc32 code. 20950e4f8f4SMatthew Dillon */ 21050e4f8f4SMatthew Dillon hammer2_key_t 21150e4f8f4SMatthew Dillon hammer2_dirhash(const unsigned char *name, size_t len) 21250e4f8f4SMatthew Dillon { 21350e4f8f4SMatthew Dillon const unsigned char *aname = name; 21450e4f8f4SMatthew Dillon uint32_t crcx; 21550e4f8f4SMatthew Dillon uint64_t key; 21650e4f8f4SMatthew Dillon size_t i; 21750e4f8f4SMatthew Dillon size_t j; 21850e4f8f4SMatthew Dillon 21950e4f8f4SMatthew Dillon key = 0; 22050e4f8f4SMatthew Dillon 22150e4f8f4SMatthew Dillon /* 22250e4f8f4SMatthew Dillon * m32 22350e4f8f4SMatthew Dillon */ 22450e4f8f4SMatthew Dillon crcx = 0; 22550e4f8f4SMatthew Dillon for (i = j = 0; i < len; ++i) { 22650e4f8f4SMatthew Dillon if (aname[i] == '.' || 22750e4f8f4SMatthew Dillon aname[i] == '-' || 22850e4f8f4SMatthew Dillon aname[i] == '_' || 22950e4f8f4SMatthew Dillon aname[i] == '~') { 23050e4f8f4SMatthew Dillon if (i != j) 23150e4f8f4SMatthew Dillon crcx += hammer2_icrc32(aname + j, i - j); 23250e4f8f4SMatthew Dillon j = i + 1; 23350e4f8f4SMatthew Dillon } 23450e4f8f4SMatthew Dillon } 23550e4f8f4SMatthew Dillon if (i != j) 23650e4f8f4SMatthew Dillon crcx += hammer2_icrc32(aname + j, i - j); 23750e4f8f4SMatthew Dillon 23850e4f8f4SMatthew Dillon /* 23950e4f8f4SMatthew Dillon * The directory hash utilizes the top 32 bits of the 64-bit key. 24050e4f8f4SMatthew Dillon * Bit 63 must be set to 1. 24150e4f8f4SMatthew Dillon */ 24250e4f8f4SMatthew Dillon crcx |= 0x80000000U; 24350e4f8f4SMatthew Dillon key |= (uint64_t)crcx << 32; 24450e4f8f4SMatthew Dillon 24550e4f8f4SMatthew Dillon /* 24650e4f8f4SMatthew Dillon * l16 - crc of entire filename 24750e4f8f4SMatthew Dillon * 24850e4f8f4SMatthew Dillon * This crc reduces degenerate hash collision conditions 24950e4f8f4SMatthew Dillon */ 25050e4f8f4SMatthew Dillon crcx = hammer2_icrc32(aname, len); 25150e4f8f4SMatthew Dillon crcx = crcx ^ (crcx << 16); 25250e4f8f4SMatthew Dillon key |= crcx & 0xFFFF0000U; 25350e4f8f4SMatthew Dillon 254e028fa74SMatthew Dillon /* 255e028fa74SMatthew Dillon * Set bit 15. This allows readdir to strip bit 63 so a positive 256e028fa74SMatthew Dillon * 64-bit cookie/offset can always be returned, and still guarantee 257e028fa74SMatthew Dillon * that the values 0x0000-0x7FFF are available for artificial entries. 258e028fa74SMatthew Dillon * ('.' and '..'). 259e028fa74SMatthew Dillon */ 260e028fa74SMatthew Dillon key |= 0x8000U; 261e028fa74SMatthew Dillon 26250e4f8f4SMatthew Dillon return (key); 26350e4f8f4SMatthew Dillon } 2646ba3b984SMatthew Dillon 2651a7cfe5aSMatthew Dillon #if 0 2666ba3b984SMatthew Dillon /* 2676ba3b984SMatthew Dillon * Return the power-of-2 radix greater or equal to 2686ba3b984SMatthew Dillon * the specified number of bytes. 2696ba3b984SMatthew Dillon * 2709061bde5SMatthew Dillon * Always returns at least the minimum media allocation 27150456506SMatthew Dillon * size radix, HAMMER2_RADIX_MIN (10), which is 1KB. 2726ba3b984SMatthew Dillon */ 2736ba3b984SMatthew Dillon int 2749061bde5SMatthew Dillon hammer2_allocsize(size_t bytes) 2756ba3b984SMatthew Dillon { 2766ba3b984SMatthew Dillon int radix; 2776ba3b984SMatthew Dillon 27850456506SMatthew Dillon if (bytes < HAMMER2_ALLOC_MIN) 27950456506SMatthew Dillon bytes = HAMMER2_ALLOC_MIN; 2806ba3b984SMatthew Dillon if (bytes == HAMMER2_PBUFSIZE) 2816ba3b984SMatthew Dillon radix = HAMMER2_PBUFRADIX; 2829061bde5SMatthew Dillon else if (bytes >= 16384) 2839061bde5SMatthew Dillon radix = 14; 2846ba3b984SMatthew Dillon else if (bytes >= 1024) 2856ba3b984SMatthew Dillon radix = 10; 2866ba3b984SMatthew Dillon else 28750456506SMatthew Dillon radix = HAMMER2_RADIX_MIN; 2886ba3b984SMatthew Dillon 2896ba3b984SMatthew Dillon while (((size_t)1 << radix) < bytes) 2906ba3b984SMatthew Dillon ++radix; 2916ba3b984SMatthew Dillon return (radix); 2926ba3b984SMatthew Dillon } 2938cce658dSMatthew Dillon 2941a7cfe5aSMatthew Dillon #endif 2951a7cfe5aSMatthew Dillon 2961a7cfe5aSMatthew Dillon /* 2971a7cfe5aSMatthew Dillon * Convert bytes to radix with no limitations 2981a7cfe5aSMatthew Dillon */ 2991a7cfe5aSMatthew Dillon int 3001a7cfe5aSMatthew Dillon hammer2_getradix(size_t bytes) 3011a7cfe5aSMatthew Dillon { 3021a7cfe5aSMatthew Dillon int radix; 3031a7cfe5aSMatthew Dillon 3041a7cfe5aSMatthew Dillon if (bytes == HAMMER2_PBUFSIZE) 3051a7cfe5aSMatthew Dillon radix = HAMMER2_PBUFRADIX; 30693f3933aSMatthew Dillon else if (bytes >= HAMMER2_LBUFSIZE) 30793f3933aSMatthew Dillon radix = HAMMER2_LBUFRADIX; 30850456506SMatthew Dillon else if (bytes >= HAMMER2_ALLOC_MIN) /* clamp */ 30950456506SMatthew Dillon radix = HAMMER2_RADIX_MIN; 3101a7cfe5aSMatthew Dillon else 3111a7cfe5aSMatthew Dillon radix = 0; 3121a7cfe5aSMatthew Dillon 3131a7cfe5aSMatthew Dillon while (((size_t)1 << radix) < bytes) 3141a7cfe5aSMatthew Dillon ++radix; 3151a7cfe5aSMatthew Dillon return (radix); 3161a7cfe5aSMatthew Dillon } 3171a7cfe5aSMatthew Dillon 318476d2aadSMatthew Dillon /* 319476d2aadSMatthew Dillon * ip must be locked sh/ex 320355d67fcSMatthew Dillon * 321355d67fcSMatthew Dillon * Use 16KB logical buffers for file blocks <= 1MB and 64KB logical buffers 322355d67fcSMatthew Dillon * otherwise. The write code may utilize smaller device buffers when 323355d67fcSMatthew Dillon * compressing or handling the EOF case, but is not able to coalesce smaller 324355d67fcSMatthew Dillon * logical buffers into larger device buffers. 325355d67fcSMatthew Dillon * 326355d67fcSMatthew Dillon * For now this means that even large files will have a bunch of 16KB blocks 327355d67fcSMatthew Dillon * at the beginning of the file. On the plus side this tends to cause small 328355d67fcSMatthew Dillon * files to cluster together in the freemap. 329476d2aadSMatthew Dillon */ 3308cce658dSMatthew Dillon int 3318cce658dSMatthew Dillon hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff, 3328cce658dSMatthew Dillon hammer2_key_t *lbasep, hammer2_key_t *leofp) 3338cce658dSMatthew Dillon { 334355d67fcSMatthew Dillon #if 0 335355d67fcSMatthew Dillon if (uoff < (hammer2_off_t)1024 * 1024) { 336355d67fcSMatthew Dillon if (lbasep) 337355d67fcSMatthew Dillon *lbasep = uoff & ~HAMMER2_LBUFMASK64; 338355d67fcSMatthew Dillon if (leofp) { 339355d67fcSMatthew Dillon if (ip->size > (hammer2_key_t)1024 * 1024) 340355d67fcSMatthew Dillon *leofp = (hammer2_key_t)1024 * 1024; 341355d67fcSMatthew Dillon else 342355d67fcSMatthew Dillon *leofp = (ip->size + HAMMER2_LBUFMASK64) & 343355d67fcSMatthew Dillon ~HAMMER2_LBUFMASK64; 3448cce658dSMatthew Dillon } 345355d67fcSMatthew Dillon return (HAMMER2_LBUFSIZE); 346355d67fcSMatthew Dillon } else { 347355d67fcSMatthew Dillon #endif 348355d67fcSMatthew Dillon if (lbasep) 349355d67fcSMatthew Dillon *lbasep = uoff & ~HAMMER2_PBUFMASK64; 350355d67fcSMatthew Dillon if (leofp) { 351355d67fcSMatthew Dillon *leofp = (ip->size + HAMMER2_PBUFMASK64) & 352355d67fcSMatthew Dillon ~HAMMER2_PBUFMASK64; 353355d67fcSMatthew Dillon } 354355d67fcSMatthew Dillon return (HAMMER2_PBUFSIZE); 355355d67fcSMatthew Dillon #if 0 356355d67fcSMatthew Dillon } 357355d67fcSMatthew Dillon #endif 358355d67fcSMatthew Dillon } 359355d67fcSMatthew Dillon 360355d67fcSMatthew Dillon /* 361355d67fcSMatthew Dillon * Calculate the physical block size. pblksize <= lblksize. Primarily 362355d67fcSMatthew Dillon * used to calculate a smaller physical block for the logical block 363355d67fcSMatthew Dillon * containing the file EOF. 364355d67fcSMatthew Dillon * 365355d67fcSMatthew Dillon * Returns 0 if the requested base offset is beyond the file EOF. 366355d67fcSMatthew Dillon */ 367355d67fcSMatthew Dillon int 3686a5f4fe6SMatthew Dillon hammer2_calc_physical(hammer2_inode_t *ip, 3696a5f4fe6SMatthew Dillon const hammer2_inode_data_t *ipdata, 370278ab2b2SMatthew Dillon hammer2_key_t lbase) 371355d67fcSMatthew Dillon { 372355d67fcSMatthew Dillon int lblksize; 373355d67fcSMatthew Dillon int pblksize; 374355d67fcSMatthew Dillon int eofbytes; 375355d67fcSMatthew Dillon 376355d67fcSMatthew Dillon lblksize = hammer2_calc_logical(ip, lbase, NULL, NULL); 377278ab2b2SMatthew Dillon if (lbase + lblksize <= ipdata->size) 378355d67fcSMatthew Dillon return (lblksize); 379278ab2b2SMatthew Dillon if (lbase >= ipdata->size) 380355d67fcSMatthew Dillon return (0); 381278ab2b2SMatthew Dillon eofbytes = (int)(ipdata->size - lbase); 382355d67fcSMatthew Dillon pblksize = lblksize; 38350456506SMatthew Dillon while (pblksize >= eofbytes && pblksize >= HAMMER2_ALLOC_MIN) 384355d67fcSMatthew Dillon pblksize >>= 1; 385355d67fcSMatthew Dillon pblksize <<= 1; 386355d67fcSMatthew Dillon 387355d67fcSMatthew Dillon return (pblksize); 3888cce658dSMatthew Dillon } 389b2b78aaaSMatthew Dillon 390b2b78aaaSMatthew Dillon void 391b2b78aaaSMatthew Dillon hammer2_update_time(uint64_t *timep) 392b2b78aaaSMatthew Dillon { 393b2b78aaaSMatthew Dillon struct timeval tv; 394b2b78aaaSMatthew Dillon 395b2b78aaaSMatthew Dillon getmicrotime(&tv); 396b2b78aaaSMatthew Dillon *timep = (unsigned long)tv.tv_sec * 1000000 + tv.tv_usec; 397b2b78aaaSMatthew Dillon } 398278ab2b2SMatthew Dillon 399278ab2b2SMatthew Dillon void 400278ab2b2SMatthew Dillon hammer2_adjreadcounter(hammer2_blockref_t *bref, size_t bytes) 401278ab2b2SMatthew Dillon { 402278ab2b2SMatthew Dillon long *counterp; 403278ab2b2SMatthew Dillon 404278ab2b2SMatthew Dillon switch(bref->type) { 405278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_DATA: 406278ab2b2SMatthew Dillon counterp = &hammer2_iod_file_read; 407278ab2b2SMatthew Dillon break; 408278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_INODE: 409278ab2b2SMatthew Dillon counterp = &hammer2_iod_meta_read; 410278ab2b2SMatthew Dillon break; 411278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_INDIRECT: 412278ab2b2SMatthew Dillon counterp = &hammer2_iod_indr_read; 413278ab2b2SMatthew Dillon break; 414278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_NODE: 415278ab2b2SMatthew Dillon case HAMMER2_BREF_TYPE_FREEMAP_LEAF: 416278ab2b2SMatthew Dillon counterp = &hammer2_iod_fmap_read; 417278ab2b2SMatthew Dillon break; 418278ab2b2SMatthew Dillon default: 419278ab2b2SMatthew Dillon counterp = &hammer2_iod_volu_read; 420278ab2b2SMatthew Dillon break; 421278ab2b2SMatthew Dillon } 422278ab2b2SMatthew Dillon *counterp += bytes; 423278ab2b2SMatthew Dillon } 424d662271eSMatthew Dillon 425d662271eSMatthew Dillon int 426d662271eSMatthew Dillon hammer2_signal_check(time_t *timep) 427d662271eSMatthew Dillon { 428d662271eSMatthew Dillon int error = 0; 429d662271eSMatthew Dillon 430d662271eSMatthew Dillon lwkt_user_yield(); 431d662271eSMatthew Dillon if (*timep != time_second) { 432d662271eSMatthew Dillon *timep = time_second; 433d662271eSMatthew Dillon if (CURSIG(curthread->td_lwp) != 0) 434d662271eSMatthew Dillon error = EINTR; 435d662271eSMatthew Dillon } 436d662271eSMatthew Dillon return error; 437d662271eSMatthew Dillon } 438b93cc2e0SMatthew Dillon 439b93cc2e0SMatthew Dillon const char * 440b93cc2e0SMatthew Dillon hammer2_error_str(int error) 441b93cc2e0SMatthew Dillon { 442b93cc2e0SMatthew Dillon const char *str; 443b93cc2e0SMatthew Dillon 444b93cc2e0SMatthew Dillon switch(error) { 445b93cc2e0SMatthew Dillon case HAMMER2_ERROR_NONE: 446b93cc2e0SMatthew Dillon str = "0"; 447b93cc2e0SMatthew Dillon break; 448b93cc2e0SMatthew Dillon case HAMMER2_ERROR_IO: 449b93cc2e0SMatthew Dillon str = "I/O"; 450b93cc2e0SMatthew Dillon break; 451b93cc2e0SMatthew Dillon case HAMMER2_ERROR_CHECK: 452b93cc2e0SMatthew Dillon str = "check/crc"; 453b93cc2e0SMatthew Dillon break; 454b93cc2e0SMatthew Dillon case HAMMER2_ERROR_INCOMPLETE: 455b93cc2e0SMatthew Dillon str = "incomplete-node"; 456b93cc2e0SMatthew Dillon break; 457b93cc2e0SMatthew Dillon default: 458b93cc2e0SMatthew Dillon str = "unknown"; 459b93cc2e0SMatthew Dillon break; 460b93cc2e0SMatthew Dillon } 461b93cc2e0SMatthew Dillon return (str); 462b93cc2e0SMatthew Dillon } 463