xref: /dragonfly/sys/vfs/hammer2/hammer2_subr.c (revision a4cea70e)
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/uuid.h>
40e028fa74SMatthew Dillon #include <sys/dirent.h>
41703720e4SMatthew Dillon 
42703720e4SMatthew Dillon #include "hammer2.h"
43703720e4SMatthew Dillon 
44703720e4SMatthew Dillon /*
45476d2aadSMatthew Dillon  * Return the directory entry type for an inode.
46e028fa74SMatthew Dillon  */
47e028fa74SMatthew Dillon int
hammer2_get_dtype(uint8_t type)48da0cdd33SMatthew Dillon hammer2_get_dtype(uint8_t type)
49e028fa74SMatthew Dillon {
5099535653SMatthew Dillon 	switch(type) {
51e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_UNKNOWN:
52e028fa74SMatthew Dillon 		return (DT_UNKNOWN);
53e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_DIRECTORY:
54e028fa74SMatthew Dillon 		return (DT_DIR);
55e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_REGFILE:
56e028fa74SMatthew Dillon 		return (DT_REG);
57e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_FIFO:
58e028fa74SMatthew Dillon 		return (DT_FIFO);
59fae39a28STomohiro Kusumi 	case HAMMER2_OBJTYPE_CDEV:
60e028fa74SMatthew Dillon 		return (DT_CHR);
61fae39a28STomohiro Kusumi 	case HAMMER2_OBJTYPE_BDEV:
62e028fa74SMatthew Dillon 		return (DT_BLK);
63e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_SOFTLINK:
64e028fa74SMatthew Dillon 		return (DT_LNK);
65e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_SOCKET:
66e028fa74SMatthew Dillon 		return (DT_SOCK);
67e028fa74SMatthew Dillon 	case HAMMER2_OBJTYPE_WHITEOUT:	/* not supported */
68e028fa74SMatthew Dillon 		return (DT_UNKNOWN);
69e028fa74SMatthew Dillon 	default:
70e028fa74SMatthew Dillon 		return (DT_UNKNOWN);
71e028fa74SMatthew Dillon 	}
72e028fa74SMatthew Dillon 	/* not reached */
73e028fa74SMatthew Dillon }
74e028fa74SMatthew Dillon 
75cd4b3d92SMatthew Dillon /*
76cd4b3d92SMatthew Dillon  * Return the directory entry type for an inode
77cd4b3d92SMatthew Dillon  */
78cd4b3d92SMatthew Dillon int
hammer2_get_vtype(uint8_t type)79159c3ca2SMatthew Dillon hammer2_get_vtype(uint8_t type)
80cd4b3d92SMatthew Dillon {
81159c3ca2SMatthew Dillon 	switch(type) {
82cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_UNKNOWN:
83cd4b3d92SMatthew Dillon 		return (VBAD);
84cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_DIRECTORY:
85cd4b3d92SMatthew Dillon 		return (VDIR);
86cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_REGFILE:
87cd4b3d92SMatthew Dillon 		return (VREG);
88cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_FIFO:
89cd4b3d92SMatthew Dillon 		return (VFIFO);
90fae39a28STomohiro Kusumi 	case HAMMER2_OBJTYPE_CDEV:
91cd4b3d92SMatthew Dillon 		return (VCHR);
92fae39a28STomohiro Kusumi 	case HAMMER2_OBJTYPE_BDEV:
93cd4b3d92SMatthew Dillon 		return (VBLK);
94cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_SOFTLINK:
95cd4b3d92SMatthew Dillon 		return (VLNK);
96cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_SOCKET:
97cd4b3d92SMatthew Dillon 		return (VSOCK);
98cd4b3d92SMatthew Dillon 	case HAMMER2_OBJTYPE_WHITEOUT:	/* not supported */
99fae39a28STomohiro Kusumi 		return (VBAD);
100cd4b3d92SMatthew Dillon 	default:
101fae39a28STomohiro Kusumi 		return (VBAD);
102cd4b3d92SMatthew Dillon 	}
103cd4b3d92SMatthew Dillon 	/* not reached */
104cd4b3d92SMatthew Dillon }
105cd4b3d92SMatthew Dillon 
1062f70512bSTomohiro Kusumi uint8_t
hammer2_get_obj_type(enum vtype vtype)10737494cabSMatthew Dillon hammer2_get_obj_type(enum vtype vtype)
10837494cabSMatthew Dillon {
10937494cabSMatthew Dillon 	switch(vtype) {
11037494cabSMatthew Dillon 	case VDIR:
11137494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_DIRECTORY);
11237494cabSMatthew Dillon 	case VREG:
11337494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_REGFILE);
11437494cabSMatthew Dillon 	case VFIFO:
11537494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_FIFO);
11637494cabSMatthew Dillon 	case VSOCK:
11737494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_SOCKET);
11837494cabSMatthew Dillon 	case VCHR:
11937494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_CDEV);
12037494cabSMatthew Dillon 	case VBLK:
12137494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_BDEV);
12237494cabSMatthew Dillon 	case VLNK:
12337494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_SOFTLINK);
12437494cabSMatthew Dillon 	default:
12537494cabSMatthew Dillon 		return(HAMMER2_OBJTYPE_UNKNOWN);
12637494cabSMatthew Dillon 	}
12737494cabSMatthew Dillon 	/* not reached */
12837494cabSMatthew Dillon }
12937494cabSMatthew Dillon 
130cd4b3d92SMatthew Dillon /*
131cd4b3d92SMatthew Dillon  * Convert a hammer2 64-bit time to a timespec.
132cd4b3d92SMatthew Dillon  */
133cd4b3d92SMatthew Dillon void
hammer2_time_to_timespec(uint64_t xtime,struct timespec * ts)1342f70512bSTomohiro Kusumi hammer2_time_to_timespec(uint64_t xtime, struct timespec *ts)
135cd4b3d92SMatthew Dillon {
136cd4b3d92SMatthew Dillon 	ts->tv_sec = (unsigned long)(xtime / 1000000);
137cd4b3d92SMatthew Dillon 	ts->tv_nsec = (unsigned int)(xtime % 1000000) * 1000L;
138cd4b3d92SMatthew Dillon }
139cd4b3d92SMatthew Dillon 
1402f70512bSTomohiro Kusumi uint64_t
hammer2_timespec_to_time(const struct timespec * ts)1416a5f4fe6SMatthew Dillon hammer2_timespec_to_time(const struct timespec *ts)
142b2b78aaaSMatthew Dillon {
1432f70512bSTomohiro Kusumi 	uint64_t xtime;
144b2b78aaaSMatthew Dillon 
145b2b78aaaSMatthew Dillon 	xtime = (unsigned)(ts->tv_nsec / 1000) +
146b2b78aaaSMatthew Dillon 		(unsigned long)ts->tv_sec * 1000000ULL;
147b2b78aaaSMatthew Dillon 	return(xtime);
148b2b78aaaSMatthew Dillon }
149b2b78aaaSMatthew Dillon 
15037494cabSMatthew Dillon /*
15137494cabSMatthew Dillon  * Convert a uuid to a unix uid or gid
15237494cabSMatthew Dillon  */
1532f70512bSTomohiro Kusumi uint32_t
hammer2_to_unix_xid(const uuid_t * uuid)1546a5f4fe6SMatthew Dillon hammer2_to_unix_xid(const uuid_t *uuid)
15537494cabSMatthew Dillon {
1562f70512bSTomohiro Kusumi 	return(*(const uint32_t *)&uuid->node[2]);
15737494cabSMatthew Dillon }
158e028fa74SMatthew Dillon 
159b2b78aaaSMatthew Dillon void
hammer2_guid_to_uuid(uuid_t * uuid,uint32_t guid)1602f70512bSTomohiro Kusumi hammer2_guid_to_uuid(uuid_t *uuid, uint32_t guid)
161b2b78aaaSMatthew Dillon {
162b2b78aaaSMatthew Dillon 	bzero(uuid, sizeof(*uuid));
1632f70512bSTomohiro Kusumi 	*(uint32_t *)&uuid->node[2] = guid;
164b2b78aaaSMatthew Dillon }
165b2b78aaaSMatthew Dillon 
166e028fa74SMatthew Dillon /*
16750e4f8f4SMatthew Dillon  * Borrow HAMMER1's directory hash algorithm #1 with a few modifications.
16850e4f8f4SMatthew Dillon  * The filename is split into fields which are hashed separately and then
16950e4f8f4SMatthew Dillon  * added together.
17050e4f8f4SMatthew Dillon  *
17150e4f8f4SMatthew Dillon  * Differences include: bit 63 must be set to 1 for HAMMER2 (HAMMER1 sets
17250e4f8f4SMatthew Dillon  * it to 0), this is because bit63=0 is used for hidden hardlinked inodes.
17350e4f8f4SMatthew Dillon  * (This means we do not need to do a 0-check/or-with-0x100000000 either).
17450e4f8f4SMatthew Dillon  *
17550e4f8f4SMatthew Dillon  * Also, the iscsi crc code is used instead of the old crc32 code.
17650e4f8f4SMatthew Dillon  */
17750e4f8f4SMatthew Dillon hammer2_key_t
hammer2_dirhash(const char * aname,size_t len)1781d5238a4STomohiro Kusumi hammer2_dirhash(const char *aname, size_t len)
17950e4f8f4SMatthew Dillon {
18050e4f8f4SMatthew Dillon 	uint32_t crcx;
18150e4f8f4SMatthew Dillon 	uint64_t key;
18250e4f8f4SMatthew Dillon 	size_t i;
18350e4f8f4SMatthew Dillon 	size_t j;
18450e4f8f4SMatthew Dillon 
18550e4f8f4SMatthew Dillon 	key = 0;
18650e4f8f4SMatthew Dillon 
18750e4f8f4SMatthew Dillon 	/*
18850e4f8f4SMatthew Dillon 	 * m32
18950e4f8f4SMatthew Dillon 	 */
19050e4f8f4SMatthew Dillon 	crcx = 0;
19150e4f8f4SMatthew Dillon 	for (i = j = 0; i < len; ++i) {
19250e4f8f4SMatthew Dillon 		if (aname[i] == '.' ||
19350e4f8f4SMatthew Dillon 		    aname[i] == '-' ||
19450e4f8f4SMatthew Dillon 		    aname[i] == '_' ||
19550e4f8f4SMatthew Dillon 		    aname[i] == '~') {
19650e4f8f4SMatthew Dillon 			if (i != j)
19750e4f8f4SMatthew Dillon 				crcx += hammer2_icrc32(aname + j, i - j);
19850e4f8f4SMatthew Dillon 			j = i + 1;
19950e4f8f4SMatthew Dillon 		}
20050e4f8f4SMatthew Dillon 	}
20150e4f8f4SMatthew Dillon 	if (i != j)
20250e4f8f4SMatthew Dillon 		crcx += hammer2_icrc32(aname + j, i - j);
20350e4f8f4SMatthew Dillon 
20450e4f8f4SMatthew Dillon 	/*
20550e4f8f4SMatthew Dillon 	 * The directory hash utilizes the top 32 bits of the 64-bit key.
20650e4f8f4SMatthew Dillon 	 * Bit 63 must be set to 1.
20750e4f8f4SMatthew Dillon 	 */
20850e4f8f4SMatthew Dillon 	crcx |= 0x80000000U;
20950e4f8f4SMatthew Dillon 	key |= (uint64_t)crcx << 32;
21050e4f8f4SMatthew Dillon 
21150e4f8f4SMatthew Dillon 	/*
21250e4f8f4SMatthew Dillon 	 * l16 - crc of entire filename
21350e4f8f4SMatthew Dillon 	 *
214bc7ea12eSTomohiro Kusumi 	 * This crc reduces degenerate hash collision conditions.
21550e4f8f4SMatthew Dillon 	 */
21650e4f8f4SMatthew Dillon 	crcx = hammer2_icrc32(aname, len);
21750e4f8f4SMatthew Dillon 	crcx = crcx ^ (crcx << 16);
21850e4f8f4SMatthew Dillon 	key |= crcx & 0xFFFF0000U;
21950e4f8f4SMatthew Dillon 
220e028fa74SMatthew Dillon 	/*
221e028fa74SMatthew Dillon 	 * Set bit 15.  This allows readdir to strip bit 63 so a positive
222e028fa74SMatthew Dillon 	 * 64-bit cookie/offset can always be returned, and still guarantee
223e028fa74SMatthew Dillon 	 * that the values 0x0000-0x7FFF are available for artificial entries.
224e028fa74SMatthew Dillon 	 * ('.' and '..').
225e028fa74SMatthew Dillon 	 */
226e028fa74SMatthew Dillon 	key |= 0x8000U;
227e028fa74SMatthew Dillon 
22850e4f8f4SMatthew Dillon 	return (key);
22950e4f8f4SMatthew Dillon }
2306ba3b984SMatthew Dillon 
2311a7cfe5aSMatthew Dillon /*
232da0cdd33SMatthew Dillon  * Convert bytes to radix with no limitations.
233da0cdd33SMatthew Dillon  *
234da0cdd33SMatthew Dillon  * 0 bytes is special-cased to a radix of zero (which would normally
235da0cdd33SMatthew Dillon  * translate to (1 << 0) == 1).
2361a7cfe5aSMatthew Dillon  */
2371a7cfe5aSMatthew Dillon int
hammer2_getradix(size_t bytes)2381a7cfe5aSMatthew Dillon hammer2_getradix(size_t bytes)
2391a7cfe5aSMatthew Dillon {
2401a7cfe5aSMatthew Dillon 	int radix;
2411a7cfe5aSMatthew Dillon 
242da0cdd33SMatthew Dillon 	/*
243*a4cea70eSTomohiro Kusumi 	 * Optimize the iteration by pre-checking commonly used radixes.
244da0cdd33SMatthew Dillon 	 */
2451a7cfe5aSMatthew Dillon 	if (bytes == HAMMER2_PBUFSIZE)
2461a7cfe5aSMatthew Dillon 		radix = HAMMER2_PBUFRADIX;
24793f3933aSMatthew Dillon 	else if (bytes >= HAMMER2_LBUFSIZE)
24893f3933aSMatthew Dillon 		radix = HAMMER2_LBUFRADIX;
24950456506SMatthew Dillon 	else if (bytes >= HAMMER2_ALLOC_MIN)	/* clamp */
25050456506SMatthew Dillon 		radix = HAMMER2_RADIX_MIN;
2511a7cfe5aSMatthew Dillon 	else
2521a7cfe5aSMatthew Dillon 		radix = 0;
2531a7cfe5aSMatthew Dillon 
254da0cdd33SMatthew Dillon 	/*
255da0cdd33SMatthew Dillon 	 * Iterate as needed.  Note that bytes == 0 is expected to return
256da0cdd33SMatthew Dillon 	 * a radix of 0 as a special case.
257da0cdd33SMatthew Dillon 	 */
2581a7cfe5aSMatthew Dillon 	while (((size_t)1 << radix) < bytes)
2591a7cfe5aSMatthew Dillon 		++radix;
2601a7cfe5aSMatthew Dillon 	return (radix);
2611a7cfe5aSMatthew Dillon }
2621a7cfe5aSMatthew Dillon 
263476d2aadSMatthew Dillon /*
2647a9b14a0SMatthew Dillon  * The logical block size is currently always PBUFSIZE.
265476d2aadSMatthew Dillon  */
2668cce658dSMatthew Dillon int
hammer2_calc_logical(hammer2_inode_t * ip,hammer2_off_t uoff,hammer2_key_t * lbasep,hammer2_key_t * leofp)2678cce658dSMatthew Dillon hammer2_calc_logical(hammer2_inode_t *ip, hammer2_off_t uoff,
2688cce658dSMatthew Dillon 		     hammer2_key_t *lbasep, hammer2_key_t *leofp)
2698cce658dSMatthew Dillon {
270355d67fcSMatthew Dillon 	if (lbasep)
271355d67fcSMatthew Dillon 		*lbasep = uoff & ~HAMMER2_PBUFMASK64;
272355d67fcSMatthew Dillon 	if (leofp) {
2737a9b14a0SMatthew Dillon 		*leofp = (ip->meta.size + HAMMER2_PBUFMASK64) &
274355d67fcSMatthew Dillon 			 ~HAMMER2_PBUFMASK64;
275355d67fcSMatthew Dillon 	}
276355d67fcSMatthew Dillon 	return (HAMMER2_PBUFSIZE);
277355d67fcSMatthew Dillon }
278355d67fcSMatthew Dillon 
279355d67fcSMatthew Dillon /*
280355d67fcSMatthew Dillon  * Calculate the physical block size.  pblksize <= lblksize.  Primarily
281355d67fcSMatthew Dillon  * used to calculate a smaller physical block for the logical block
282355d67fcSMatthew Dillon  * containing the file EOF.
283355d67fcSMatthew Dillon  *
284355d67fcSMatthew Dillon  * Returns 0 if the requested base offset is beyond the file EOF.
285355d67fcSMatthew Dillon  */
286355d67fcSMatthew Dillon int
hammer2_calc_physical(hammer2_inode_t * ip,hammer2_key_t lbase)2877a9b14a0SMatthew Dillon hammer2_calc_physical(hammer2_inode_t *ip, hammer2_key_t lbase)
288355d67fcSMatthew Dillon {
289355d67fcSMatthew Dillon 	int lblksize;
290355d67fcSMatthew Dillon 	int pblksize;
291355d67fcSMatthew Dillon 	int eofbytes;
292355d67fcSMatthew Dillon 
293355d67fcSMatthew Dillon 	lblksize = hammer2_calc_logical(ip, lbase, NULL, NULL);
2947a9b14a0SMatthew Dillon 	if (lbase + lblksize <= ip->meta.size)
295355d67fcSMatthew Dillon 		return (lblksize);
2967a9b14a0SMatthew Dillon 	if (lbase >= ip->meta.size)
297355d67fcSMatthew Dillon 		return (0);
2987a9b14a0SMatthew Dillon 	eofbytes = (int)(ip->meta.size - lbase);
299355d67fcSMatthew Dillon 	pblksize = lblksize;
30050456506SMatthew Dillon 	while (pblksize >= eofbytes && pblksize >= HAMMER2_ALLOC_MIN)
301355d67fcSMatthew Dillon 		pblksize >>= 1;
302355d67fcSMatthew Dillon 	pblksize <<= 1;
303355d67fcSMatthew Dillon 
304355d67fcSMatthew Dillon 	return (pblksize);
3058cce658dSMatthew Dillon }
306b2b78aaaSMatthew Dillon 
307b2b78aaaSMatthew Dillon void
hammer2_update_time(uint64_t * timep)308b2b78aaaSMatthew Dillon hammer2_update_time(uint64_t *timep)
309b2b78aaaSMatthew Dillon {
310d489a79aSMatthew Dillon 	struct timespec ts;
311b2b78aaaSMatthew Dillon 
312d489a79aSMatthew Dillon 	vfs_timestamp(&ts);
313d489a79aSMatthew Dillon 	*timep = (unsigned long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
314b2b78aaaSMatthew Dillon }
315278ab2b2SMatthew Dillon 
316278ab2b2SMatthew Dillon void
hammer2_adjreadcounter(int btype,size_t bytes)317a552887fSTomohiro Kusumi hammer2_adjreadcounter(int btype, size_t bytes)
318278ab2b2SMatthew Dillon {
319278ab2b2SMatthew Dillon 	long *counterp;
320278ab2b2SMatthew Dillon 
321a552887fSTomohiro Kusumi 	switch(btype) {
322278ab2b2SMatthew Dillon 	case HAMMER2_BREF_TYPE_DATA:
323278ab2b2SMatthew Dillon 		counterp = &hammer2_iod_file_read;
324278ab2b2SMatthew Dillon 		break;
325da0cdd33SMatthew Dillon 	case HAMMER2_BREF_TYPE_DIRENT:
326278ab2b2SMatthew Dillon 	case HAMMER2_BREF_TYPE_INODE:
327278ab2b2SMatthew Dillon 		counterp = &hammer2_iod_meta_read;
328278ab2b2SMatthew Dillon 		break;
329278ab2b2SMatthew Dillon 	case HAMMER2_BREF_TYPE_INDIRECT:
330278ab2b2SMatthew Dillon 		counterp = &hammer2_iod_indr_read;
331278ab2b2SMatthew Dillon 		break;
332278ab2b2SMatthew Dillon 	case HAMMER2_BREF_TYPE_FREEMAP_NODE:
333278ab2b2SMatthew Dillon 	case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
334278ab2b2SMatthew Dillon 		counterp = &hammer2_iod_fmap_read;
335278ab2b2SMatthew Dillon 		break;
3361de4fc15STomohiro Kusumi 	case HAMMER2_BREF_TYPE_FREEMAP:
3371de4fc15STomohiro Kusumi 	case HAMMER2_BREF_TYPE_VOLUME:
338278ab2b2SMatthew Dillon 		counterp = &hammer2_iod_volu_read;
339278ab2b2SMatthew Dillon 		break;
3401de4fc15STomohiro Kusumi 	case HAMMER2_BREF_TYPE_EMPTY:
3411de4fc15STomohiro Kusumi 	default:
3421de4fc15STomohiro Kusumi 		return;
343278ab2b2SMatthew Dillon 	}
344278ab2b2SMatthew Dillon 	*counterp += bytes;
345278ab2b2SMatthew Dillon }
346d662271eSMatthew Dillon 
347a552887fSTomohiro Kusumi void
hammer2_adjwritecounter(int btype,size_t bytes)348a552887fSTomohiro Kusumi hammer2_adjwritecounter(int btype, size_t bytes)
349a552887fSTomohiro Kusumi {
350a552887fSTomohiro Kusumi 	long *counterp;
351a552887fSTomohiro Kusumi 
352a552887fSTomohiro Kusumi 	switch(btype) {
353a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_DATA:
354a552887fSTomohiro Kusumi 		counterp = &hammer2_iod_file_write;
355a552887fSTomohiro Kusumi 		break;
356a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_DIRENT:
357a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_INODE:
358a552887fSTomohiro Kusumi 		counterp = &hammer2_iod_meta_write;
359a552887fSTomohiro Kusumi 		break;
360a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_INDIRECT:
361a552887fSTomohiro Kusumi 		counterp = &hammer2_iod_indr_write;
362a552887fSTomohiro Kusumi 		break;
363a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_FREEMAP_NODE:
364a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
365a552887fSTomohiro Kusumi 		counterp = &hammer2_iod_fmap_write;
366a552887fSTomohiro Kusumi 		break;
367a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_FREEMAP:
368a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_VOLUME:
369a552887fSTomohiro Kusumi 		counterp = &hammer2_iod_volu_write;
370a552887fSTomohiro Kusumi 		break;
371a552887fSTomohiro Kusumi 	case HAMMER2_BREF_TYPE_EMPTY:
372a552887fSTomohiro Kusumi 	default:
373a552887fSTomohiro Kusumi 		return;
374a552887fSTomohiro Kusumi 	}
375a552887fSTomohiro Kusumi 	*counterp += bytes;
376a552887fSTomohiro Kusumi }
377a552887fSTomohiro Kusumi 
3789dca9515SMatthew Dillon /*
3799dca9515SMatthew Dillon  * Check for pending signal to allow interruption.  This function will
3809dca9515SMatthew Dillon  * return immediately if the calling thread is a kernel thread and not
3819dca9515SMatthew Dillon  * a user thread.
3829dca9515SMatthew Dillon  */
383d662271eSMatthew Dillon int
hammer2_signal_check(time_t * timep)384d662271eSMatthew Dillon hammer2_signal_check(time_t *timep)
385d662271eSMatthew Dillon {
3869dca9515SMatthew Dillon 	thread_t td = curthread;
387d662271eSMatthew Dillon 	int error = 0;
388d662271eSMatthew Dillon 
3899dca9515SMatthew Dillon 	if (td->td_lwp) {
390d662271eSMatthew Dillon 		lwkt_user_yield();
391d662271eSMatthew Dillon 		if (*timep != time_second) {
392d662271eSMatthew Dillon 			*timep = time_second;
3932d7e662fSMatthew Dillon 			if (CURSIG_NOBLOCK(curthread->td_lwp) != 0)
3941e2c8208SMatthew Dillon 				error = HAMMER2_ERROR_ABORTED;
395d662271eSMatthew Dillon 		}
3964ff0b408SMatthew Dillon 	} else {
3974ff0b408SMatthew Dillon 		lwkt_yield();
3989dca9515SMatthew Dillon 	}
399d662271eSMatthew Dillon 	return error;
400d662271eSMatthew Dillon }
401b93cc2e0SMatthew Dillon 
402b93cc2e0SMatthew Dillon const char *
hammer2_error_str(int error)403b93cc2e0SMatthew Dillon hammer2_error_str(int error)
404b93cc2e0SMatthew Dillon {
40565cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EIO)
40665cacacfSMatthew Dillon 		return("I/O Error");
40765cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_CHECK)
40865cacacfSMatthew Dillon 		return("Check Error");
40965cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_INCOMPLETE)
41065cacacfSMatthew Dillon 		return("Cluster Quorum Error");
41165cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_DEPTH)
41265cacacfSMatthew Dillon 		return("Chain Depth Error");
41365cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_BADBREF)
41465cacacfSMatthew Dillon 		return("Bad Blockref Error");
41565cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ENOSPC)
41665cacacfSMatthew Dillon 		return("No Space on Device");
41765cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ENOENT)
41865cacacfSMatthew Dillon 		return("Entry Not Found");
41965cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ENOTEMPTY)
42065cacacfSMatthew Dillon 		return("Directory Not Empty");
42165cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EAGAIN)
42265cacacfSMatthew Dillon 		return("EAGAIN");
42365cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ENOTDIR)
42465cacacfSMatthew Dillon 		return("Not a Directory");
42565cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EISDIR)
42665cacacfSMatthew Dillon 		return("Is a Directory");
42765cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EINPROGRESS)
42865cacacfSMatthew Dillon 		return("Operation in Progress");
42965cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ABORTED)
43065cacacfSMatthew Dillon 		return("Operation Aborted");
43165cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EOF)
43265cacacfSMatthew Dillon 		return("Operation Complete");
43365cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EINVAL)
43465cacacfSMatthew Dillon 		return("Invalid Operation");
43565cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EEXIST)
43665cacacfSMatthew Dillon 		return("Object Exists");
43765cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_EDEADLK)
43865cacacfSMatthew Dillon 		return("Deadlock Detected");
43965cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ESRCH)
44065cacacfSMatthew Dillon 		return("Object Not Found");
44165cacacfSMatthew Dillon 	if (error & HAMMER2_ERROR_ETIMEDOUT)
44265cacacfSMatthew Dillon 		return("Timeout");
44365cacacfSMatthew Dillon 	return("Unknown Error");
444b93cc2e0SMatthew Dillon }
4457ac04587SMatthew Dillon 
4467ac04587SMatthew Dillon const char *
hammer2_bref_type_str(int btype)4476341ed55STomohiro Kusumi hammer2_bref_type_str(int btype)
4487ac04587SMatthew Dillon {
4496341ed55STomohiro Kusumi 	switch(btype) {
4507ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_EMPTY:
45189f4490dSTomohiro Kusumi 		return("empty");
4527ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_INODE:
45389f4490dSTomohiro Kusumi 		return("inode");
4547ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_INDIRECT:
45589f4490dSTomohiro Kusumi 		return("indirect");
4567ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_DATA:
45789f4490dSTomohiro Kusumi 		return("data");
4587ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_DIRENT:
45989f4490dSTomohiro Kusumi 		return("dirent");
4607ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_FREEMAP_NODE:
46189f4490dSTomohiro Kusumi 		return("freemap_node");
4627ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
46389f4490dSTomohiro Kusumi 		return("freemap_leaf");
4640b738157STomohiro Kusumi 	case HAMMER2_BREF_TYPE_INVALID:
4650b738157STomohiro Kusumi 		return("invalid");
4667ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_FREEMAP:
46789f4490dSTomohiro Kusumi 		return("freemap");
4687ac04587SMatthew Dillon 	case HAMMER2_BREF_TYPE_VOLUME:
46989f4490dSTomohiro Kusumi 		return("volume");
4707ac04587SMatthew Dillon 	default:
47189f4490dSTomohiro Kusumi 		return("unknown");
4727ac04587SMatthew Dillon 	}
4737ac04587SMatthew Dillon }
474