xref: /dragonfly/sys/vfs/hammer2/hammer2_subr.c (revision f1c7c224)
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