xref: /linux/fs/ubifs/key.h (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
1*2b27bdccSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
21e51764aSArtem Bityutskiy /*
31e51764aSArtem Bityutskiy  * This file is part of UBIFS.
41e51764aSArtem Bityutskiy  *
51e51764aSArtem Bityutskiy  * Copyright (C) 2006-2008 Nokia Corporation.
61e51764aSArtem Bityutskiy  *
71e51764aSArtem Bityutskiy  * Authors: Artem Bityutskiy (Битюцкий Артём)
81e51764aSArtem Bityutskiy  *          Adrian Hunter
91e51764aSArtem Bityutskiy  */
101e51764aSArtem Bityutskiy 
111e51764aSArtem Bityutskiy /*
121e51764aSArtem Bityutskiy  * This header contains various key-related definitions and helper function.
131e51764aSArtem Bityutskiy  * UBIFS allows several key schemes, so we access key fields only via these
141e51764aSArtem Bityutskiy  * helpers. At the moment only one key scheme is supported.
151e51764aSArtem Bityutskiy  *
161e51764aSArtem Bityutskiy  * Simple key scheme
171e51764aSArtem Bityutskiy  * ~~~~~~~~~~~~~~~~~
181e51764aSArtem Bityutskiy  *
191e51764aSArtem Bityutskiy  * Keys are 64-bits long. First 32-bits are inode number (parent inode number
201e51764aSArtem Bityutskiy  * in case of direntry key). Next 3 bits are node type. The last 29 bits are
211e51764aSArtem Bityutskiy  * 4KiB offset in case of inode node, and direntry hash in case of a direntry
221e51764aSArtem Bityutskiy  * node. We use "r5" hash borrowed from reiserfs.
231e51764aSArtem Bityutskiy  */
241e51764aSArtem Bityutskiy 
25170eb55fSDongsheng Yang /*
26170eb55fSDongsheng Yang  * Lot's of the key helpers require a struct ubifs_info *c as the first parameter.
27170eb55fSDongsheng Yang  * But we are not using it at all currently. That's designed for future extensions of
28170eb55fSDongsheng Yang  * different c->key_format. But right now, there is only one key type, UBIFS_SIMPLE_KEY_FMT.
29170eb55fSDongsheng Yang  */
30170eb55fSDongsheng Yang 
311e51764aSArtem Bityutskiy #ifndef __UBIFS_KEY_H__
321e51764aSArtem Bityutskiy #define __UBIFS_KEY_H__
331e51764aSArtem Bityutskiy 
341e51764aSArtem Bityutskiy /**
355dd7cbc0SKukkonen Mika  * key_mask_hash - mask a valid hash value.
365dd7cbc0SKukkonen Mika  * @val: value to be masked
375dd7cbc0SKukkonen Mika  *
385dd7cbc0SKukkonen Mika  * We use hash values as offset in directories, so values %0 and %1 are
395dd7cbc0SKukkonen Mika  * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
405dd7cbc0SKukkonen Mika  * function makes sure the reserved values are not used.
415dd7cbc0SKukkonen Mika  */
key_mask_hash(uint32_t hash)425dd7cbc0SKukkonen Mika static inline uint32_t key_mask_hash(uint32_t hash)
435dd7cbc0SKukkonen Mika {
445dd7cbc0SKukkonen Mika 	hash &= UBIFS_S_KEY_HASH_MASK;
455dd7cbc0SKukkonen Mika 	if (unlikely(hash <= 2))
465dd7cbc0SKukkonen Mika 		hash += 3;
475dd7cbc0SKukkonen Mika 	return hash;
485dd7cbc0SKukkonen Mika }
495dd7cbc0SKukkonen Mika 
505dd7cbc0SKukkonen Mika /**
511e51764aSArtem Bityutskiy  * key_r5_hash - R5 hash function (borrowed from reiserfs).
521e51764aSArtem Bityutskiy  * @s: direntry name
531e51764aSArtem Bityutskiy  * @len: name length
541e51764aSArtem Bityutskiy  */
key_r5_hash(const char * s,int len)551e51764aSArtem Bityutskiy static inline uint32_t key_r5_hash(const char *s, int len)
561e51764aSArtem Bityutskiy {
571e51764aSArtem Bityutskiy 	uint32_t a = 0;
581e51764aSArtem Bityutskiy 	const signed char *str = (const signed char *)s;
591e51764aSArtem Bityutskiy 
60b9bc8c7bSRichard Weinberger 	while (len--) {
611e51764aSArtem Bityutskiy 		a += *str << 4;
621e51764aSArtem Bityutskiy 		a += *str >> 4;
631e51764aSArtem Bityutskiy 		a *= 11;
641e51764aSArtem Bityutskiy 		str++;
651e51764aSArtem Bityutskiy 	}
661e51764aSArtem Bityutskiy 
675dd7cbc0SKukkonen Mika 	return key_mask_hash(a);
681e51764aSArtem Bityutskiy }
691e51764aSArtem Bityutskiy 
701e51764aSArtem Bityutskiy /**
711e51764aSArtem Bityutskiy  * key_test_hash - testing hash function.
721e51764aSArtem Bityutskiy  * @str: direntry name
731e51764aSArtem Bityutskiy  * @len: name length
741e51764aSArtem Bityutskiy  */
key_test_hash(const char * str,int len)751e51764aSArtem Bityutskiy static inline uint32_t key_test_hash(const char *str, int len)
761e51764aSArtem Bityutskiy {
771e51764aSArtem Bityutskiy 	uint32_t a = 0;
781e51764aSArtem Bityutskiy 
791e51764aSArtem Bityutskiy 	len = min_t(uint32_t, len, 4);
801e51764aSArtem Bityutskiy 	memcpy(&a, str, len);
815dd7cbc0SKukkonen Mika 	return key_mask_hash(a);
821e51764aSArtem Bityutskiy }
831e51764aSArtem Bityutskiy 
841e51764aSArtem Bityutskiy /**
851e51764aSArtem Bityutskiy  * ino_key_init - initialize inode key.
861e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
871e51764aSArtem Bityutskiy  * @key: key to initialize
881e51764aSArtem Bityutskiy  * @inum: inode number
891e51764aSArtem Bityutskiy  */
ino_key_init(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)901e51764aSArtem Bityutskiy static inline void ino_key_init(const struct ubifs_info *c,
911e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
921e51764aSArtem Bityutskiy {
931e51764aSArtem Bityutskiy 	key->u32[0] = inum;
941e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
951e51764aSArtem Bityutskiy }
961e51764aSArtem Bityutskiy 
971e51764aSArtem Bityutskiy /**
981e51764aSArtem Bityutskiy  * ino_key_init_flash - initialize on-flash inode key.
991e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1001e51764aSArtem Bityutskiy  * @k: key to initialize
1011e51764aSArtem Bityutskiy  * @inum: inode number
1021e51764aSArtem Bityutskiy  */
ino_key_init_flash(const struct ubifs_info * c,void * k,ino_t inum)1031e51764aSArtem Bityutskiy static inline void ino_key_init_flash(const struct ubifs_info *c, void *k,
1041e51764aSArtem Bityutskiy 				      ino_t inum)
1051e51764aSArtem Bityutskiy {
1061e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
1071e51764aSArtem Bityutskiy 
1081e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
1091e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS);
1101e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
1111e51764aSArtem Bityutskiy }
1121e51764aSArtem Bityutskiy 
1131e51764aSArtem Bityutskiy /**
1141e51764aSArtem Bityutskiy  * lowest_ino_key - get the lowest possible inode key.
1151e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1161e51764aSArtem Bityutskiy  * @key: key to initialize
1171e51764aSArtem Bityutskiy  * @inum: inode number
1181e51764aSArtem Bityutskiy  */
lowest_ino_key(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)1191e51764aSArtem Bityutskiy static inline void lowest_ino_key(const struct ubifs_info *c,
1201e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
1211e51764aSArtem Bityutskiy {
1221e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1231e51764aSArtem Bityutskiy 	key->u32[1] = 0;
1241e51764aSArtem Bityutskiy }
1251e51764aSArtem Bityutskiy 
1261e51764aSArtem Bityutskiy /**
1271e51764aSArtem Bityutskiy  * highest_ino_key - get the highest possible inode key.
1281e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1291e51764aSArtem Bityutskiy  * @key: key to initialize
1301e51764aSArtem Bityutskiy  * @inum: inode number
1311e51764aSArtem Bityutskiy  */
highest_ino_key(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)1321e51764aSArtem Bityutskiy static inline void highest_ino_key(const struct ubifs_info *c,
1331e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
1341e51764aSArtem Bityutskiy {
1351e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1361e51764aSArtem Bityutskiy 	key->u32[1] = 0xffffffff;
1371e51764aSArtem Bityutskiy }
1381e51764aSArtem Bityutskiy 
1391e51764aSArtem Bityutskiy /**
1401e51764aSArtem Bityutskiy  * dent_key_init - initialize directory entry key.
1411e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1421e51764aSArtem Bityutskiy  * @key: key to initialize
1431e51764aSArtem Bityutskiy  * @inum: parent inode number
144f4f61d2cSRichard Weinberger  * @nm: direntry name and length. Not a string when encrypted!
1451e51764aSArtem Bityutskiy  */
dent_key_init(const struct ubifs_info * c,union ubifs_key * key,ino_t inum,const struct fscrypt_name * nm)1461e51764aSArtem Bityutskiy static inline void dent_key_init(const struct ubifs_info *c,
1471e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
148f4f61d2cSRichard Weinberger 				 const struct fscrypt_name *nm)
1491e51764aSArtem Bityutskiy {
150f4f61d2cSRichard Weinberger 	uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
1511e51764aSArtem Bityutskiy 
1526eb61d58SRichard Weinberger 	ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
1531e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1541e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
1551e51764aSArtem Bityutskiy }
1561e51764aSArtem Bityutskiy 
1571e51764aSArtem Bityutskiy /**
1581e51764aSArtem Bityutskiy  * dent_key_init_hash - initialize directory entry key without re-calculating
1591e51764aSArtem Bityutskiy  *                      hash function.
1601e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1611e51764aSArtem Bityutskiy  * @key: key to initialize
1621e51764aSArtem Bityutskiy  * @inum: parent inode number
1631e51764aSArtem Bityutskiy  * @hash: direntry name hash
1641e51764aSArtem Bityutskiy  */
dent_key_init_hash(const struct ubifs_info * c,union ubifs_key * key,ino_t inum,uint32_t hash)1651e51764aSArtem Bityutskiy static inline void dent_key_init_hash(const struct ubifs_info *c,
1661e51764aSArtem Bityutskiy 				      union ubifs_key *key, ino_t inum,
1671e51764aSArtem Bityutskiy 				      uint32_t hash)
1681e51764aSArtem Bityutskiy {
1696eb61d58SRichard Weinberger 	ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
1701e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1711e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
1721e51764aSArtem Bityutskiy }
1731e51764aSArtem Bityutskiy 
1741e51764aSArtem Bityutskiy /**
1751e51764aSArtem Bityutskiy  * dent_key_init_flash - initialize on-flash directory entry key.
1761e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1771e51764aSArtem Bityutskiy  * @k: key to initialize
1781e51764aSArtem Bityutskiy  * @inum: parent inode number
1791e51764aSArtem Bityutskiy  * @nm: direntry name and length
1801e51764aSArtem Bityutskiy  */
dent_key_init_flash(const struct ubifs_info * c,void * k,ino_t inum,const struct fscrypt_name * nm)1811e51764aSArtem Bityutskiy static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
182f4f61d2cSRichard Weinberger 				       ino_t inum,
183f4f61d2cSRichard Weinberger 				       const struct fscrypt_name *nm)
1841e51764aSArtem Bityutskiy {
1851e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
186f4f61d2cSRichard Weinberger 	uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
1871e51764aSArtem Bityutskiy 
1886eb61d58SRichard Weinberger 	ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
1891e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
1901e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(hash |
1911e51764aSArtem Bityutskiy 				  (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS));
1921e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
1931e51764aSArtem Bityutskiy }
1941e51764aSArtem Bityutskiy 
1951e51764aSArtem Bityutskiy /**
1961e51764aSArtem Bityutskiy  * lowest_dent_key - get the lowest possible directory entry key.
1971e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1981e51764aSArtem Bityutskiy  * @key: where to store the lowest key
1991e51764aSArtem Bityutskiy  * @inum: parent inode number
2001e51764aSArtem Bityutskiy  */
lowest_dent_key(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)2011e51764aSArtem Bityutskiy static inline void lowest_dent_key(const struct ubifs_info *c,
2021e51764aSArtem Bityutskiy 				   union ubifs_key *key, ino_t inum)
2031e51764aSArtem Bityutskiy {
2041e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2051e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS;
2061e51764aSArtem Bityutskiy }
2071e51764aSArtem Bityutskiy 
2081e51764aSArtem Bityutskiy /**
2091e51764aSArtem Bityutskiy  * xent_key_init - initialize extended attribute entry key.
2101e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2111e51764aSArtem Bityutskiy  * @key: key to initialize
2121e51764aSArtem Bityutskiy  * @inum: host inode number
2131e51764aSArtem Bityutskiy  * @nm: extended attribute entry name and length
2141e51764aSArtem Bityutskiy  */
xent_key_init(const struct ubifs_info * c,union ubifs_key * key,ino_t inum,const struct fscrypt_name * nm)2151e51764aSArtem Bityutskiy static inline void xent_key_init(const struct ubifs_info *c,
2161e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
217f4f61d2cSRichard Weinberger 				 const struct fscrypt_name *nm)
2181e51764aSArtem Bityutskiy {
219f4f61d2cSRichard Weinberger 	uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
2201e51764aSArtem Bityutskiy 
2216eb61d58SRichard Weinberger 	ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
2221e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2231e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
2241e51764aSArtem Bityutskiy }
2251e51764aSArtem Bityutskiy 
2261e51764aSArtem Bityutskiy /**
2271e51764aSArtem Bityutskiy  * xent_key_init_flash - initialize on-flash extended attribute entry key.
2281e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2291e51764aSArtem Bityutskiy  * @k: key to initialize
2301e51764aSArtem Bityutskiy  * @inum: host inode number
2311e51764aSArtem Bityutskiy  * @nm: extended attribute entry name and length
2321e51764aSArtem Bityutskiy  */
xent_key_init_flash(const struct ubifs_info * c,void * k,ino_t inum,const struct fscrypt_name * nm)2331e51764aSArtem Bityutskiy static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
234f4f61d2cSRichard Weinberger 				       ino_t inum, const struct fscrypt_name *nm)
2351e51764aSArtem Bityutskiy {
2361e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
237f4f61d2cSRichard Weinberger 	uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
2381e51764aSArtem Bityutskiy 
2396eb61d58SRichard Weinberger 	ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
2401e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
2411e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(hash |
2421e51764aSArtem Bityutskiy 				  (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS));
2431e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
2441e51764aSArtem Bityutskiy }
2451e51764aSArtem Bityutskiy 
2461e51764aSArtem Bityutskiy /**
2471e51764aSArtem Bityutskiy  * lowest_xent_key - get the lowest possible extended attribute entry key.
2481e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2491e51764aSArtem Bityutskiy  * @key: where to store the lowest key
2501e51764aSArtem Bityutskiy  * @inum: host inode number
2511e51764aSArtem Bityutskiy  */
lowest_xent_key(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)2521e51764aSArtem Bityutskiy static inline void lowest_xent_key(const struct ubifs_info *c,
2531e51764aSArtem Bityutskiy 				   union ubifs_key *key, ino_t inum)
2541e51764aSArtem Bityutskiy {
2551e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2561e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS;
2571e51764aSArtem Bityutskiy }
2581e51764aSArtem Bityutskiy 
2591e51764aSArtem Bityutskiy /**
2601e51764aSArtem Bityutskiy  * data_key_init - initialize data key.
2611e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2621e51764aSArtem Bityutskiy  * @key: key to initialize
2631e51764aSArtem Bityutskiy  * @inum: inode number
2641e51764aSArtem Bityutskiy  * @block: block number
2651e51764aSArtem Bityutskiy  */
data_key_init(const struct ubifs_info * c,union ubifs_key * key,ino_t inum,unsigned int block)2661e51764aSArtem Bityutskiy static inline void data_key_init(const struct ubifs_info *c,
2671e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
2681e51764aSArtem Bityutskiy 				 unsigned int block)
2691e51764aSArtem Bityutskiy {
2706eb61d58SRichard Weinberger 	ubifs_assert(c, !(block & ~UBIFS_S_KEY_BLOCK_MASK));
2711e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2721e51764aSArtem Bityutskiy 	key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
2731e51764aSArtem Bityutskiy }
2741e51764aSArtem Bityutskiy 
2751e51764aSArtem Bityutskiy /**
276e3c3efc2SArtem Bityutskiy  * highest_data_key - get the highest possible data key for an inode.
277e3c3efc2SArtem Bityutskiy  * @c: UBIFS file-system description object
278e3c3efc2SArtem Bityutskiy  * @key: key to initialize
279e3c3efc2SArtem Bityutskiy  * @inum: inode number
280e3c3efc2SArtem Bityutskiy  */
highest_data_key(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)281e3c3efc2SArtem Bityutskiy static inline void highest_data_key(const struct ubifs_info *c,
282e3c3efc2SArtem Bityutskiy 				   union ubifs_key *key, ino_t inum)
283e3c3efc2SArtem Bityutskiy {
284e3c3efc2SArtem Bityutskiy 	data_key_init(c, key, inum, UBIFS_S_KEY_BLOCK_MASK);
285e3c3efc2SArtem Bityutskiy }
286e3c3efc2SArtem Bityutskiy 
287e3c3efc2SArtem Bityutskiy /**
2881e51764aSArtem Bityutskiy  * trun_key_init - initialize truncation node key.
2891e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2901e51764aSArtem Bityutskiy  * @key: key to initialize
2911e51764aSArtem Bityutskiy  * @inum: inode number
2921e51764aSArtem Bityutskiy  *
2931e51764aSArtem Bityutskiy  * Note, UBIFS does not have truncation keys on the media and this function is
2941e51764aSArtem Bityutskiy  * only used for purposes of replay.
2951e51764aSArtem Bityutskiy  */
trun_key_init(const struct ubifs_info * c,union ubifs_key * key,ino_t inum)2961e51764aSArtem Bityutskiy static inline void trun_key_init(const struct ubifs_info *c,
2971e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum)
2981e51764aSArtem Bityutskiy {
2991e51764aSArtem Bityutskiy 	key->u32[0] = inum;
3001e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_TRUN_KEY << UBIFS_S_KEY_BLOCK_BITS;
3011e51764aSArtem Bityutskiy }
3021e51764aSArtem Bityutskiy 
3031e51764aSArtem Bityutskiy /**
304ba2f48f7SArtem Bityutskiy  * invalid_key_init - initialize invalid node key.
305ba2f48f7SArtem Bityutskiy  * @c: UBIFS file-system description object
306ba2f48f7SArtem Bityutskiy  * @key: key to initialize
307ba2f48f7SArtem Bityutskiy  *
308ba2f48f7SArtem Bityutskiy  * This is a helper function which marks a @key object as invalid.
309ba2f48f7SArtem Bityutskiy  */
invalid_key_init(const struct ubifs_info * c,union ubifs_key * key)310ba2f48f7SArtem Bityutskiy static inline void invalid_key_init(const struct ubifs_info *c,
311ba2f48f7SArtem Bityutskiy 				    union ubifs_key *key)
312ba2f48f7SArtem Bityutskiy {
313ba2f48f7SArtem Bityutskiy 	key->u32[0] = 0xDEADBEAF;
314ba2f48f7SArtem Bityutskiy 	key->u32[1] = UBIFS_INVALID_KEY;
315ba2f48f7SArtem Bityutskiy }
316ba2f48f7SArtem Bityutskiy 
317ba2f48f7SArtem Bityutskiy /**
3181e51764aSArtem Bityutskiy  * key_type - get key type.
3191e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3201e51764aSArtem Bityutskiy  * @key: key to get type of
3211e51764aSArtem Bityutskiy  */
key_type(const struct ubifs_info * c,const union ubifs_key * key)3221e51764aSArtem Bityutskiy static inline int key_type(const struct ubifs_info *c,
3231e51764aSArtem Bityutskiy 			   const union ubifs_key *key)
3241e51764aSArtem Bityutskiy {
3251e51764aSArtem Bityutskiy 	return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
3261e51764aSArtem Bityutskiy }
3271e51764aSArtem Bityutskiy 
3281e51764aSArtem Bityutskiy /**
3291e51764aSArtem Bityutskiy  * key_type_flash - get type of a on-flash formatted key.
3301e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3311e51764aSArtem Bityutskiy  * @k: key to get type of
3321e51764aSArtem Bityutskiy  */
key_type_flash(const struct ubifs_info * c,const void * k)3331e51764aSArtem Bityutskiy static inline int key_type_flash(const struct ubifs_info *c, const void *k)
3341e51764aSArtem Bityutskiy {
3351e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3361e51764aSArtem Bityutskiy 
3370ecb9529SHarvey Harrison 	return le32_to_cpu(key->j32[1]) >> UBIFS_S_KEY_BLOCK_BITS;
3381e51764aSArtem Bityutskiy }
3391e51764aSArtem Bityutskiy 
3401e51764aSArtem Bityutskiy /**
3411e51764aSArtem Bityutskiy  * key_inum - fetch inode number from key.
3421e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3431e51764aSArtem Bityutskiy  * @k: key to fetch inode number from
3441e51764aSArtem Bityutskiy  */
key_inum(const struct ubifs_info * c,const void * k)3451e51764aSArtem Bityutskiy static inline ino_t key_inum(const struct ubifs_info *c, const void *k)
3461e51764aSArtem Bityutskiy {
3471e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3481e51764aSArtem Bityutskiy 
3491e51764aSArtem Bityutskiy 	return key->u32[0];
3501e51764aSArtem Bityutskiy }
3511e51764aSArtem Bityutskiy 
3521e51764aSArtem Bityutskiy /**
3531e51764aSArtem Bityutskiy  * key_inum_flash - fetch inode number from an on-flash formatted key.
3541e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3551e51764aSArtem Bityutskiy  * @k: key to fetch inode number from
3561e51764aSArtem Bityutskiy  */
key_inum_flash(const struct ubifs_info * c,const void * k)3571e51764aSArtem Bityutskiy static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k)
3581e51764aSArtem Bityutskiy {
3591e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3601e51764aSArtem Bityutskiy 
3611e51764aSArtem Bityutskiy 	return le32_to_cpu(key->j32[0]);
3621e51764aSArtem Bityutskiy }
3631e51764aSArtem Bityutskiy 
3641e51764aSArtem Bityutskiy /**
3651e51764aSArtem Bityutskiy  * key_hash - get directory entry hash.
3661e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3671e51764aSArtem Bityutskiy  * @key: the key to get hash from
3681e51764aSArtem Bityutskiy  */
key_hash(const struct ubifs_info * c,const union ubifs_key * key)369cb4f952dSArtem Bityutskiy static inline uint32_t key_hash(const struct ubifs_info *c,
3701e51764aSArtem Bityutskiy 				const union ubifs_key *key)
3711e51764aSArtem Bityutskiy {
3721e51764aSArtem Bityutskiy 	return key->u32[1] & UBIFS_S_KEY_HASH_MASK;
3731e51764aSArtem Bityutskiy }
3741e51764aSArtem Bityutskiy 
3751e51764aSArtem Bityutskiy /**
3761e51764aSArtem Bityutskiy  * key_hash_flash - get directory entry hash from an on-flash formatted key.
3771e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3781e51764aSArtem Bityutskiy  * @k: the key to get hash from
3791e51764aSArtem Bityutskiy  */
key_hash_flash(const struct ubifs_info * c,const void * k)380cb4f952dSArtem Bityutskiy static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k)
3811e51764aSArtem Bityutskiy {
3821e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3831e51764aSArtem Bityutskiy 
3841e51764aSArtem Bityutskiy 	return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_HASH_MASK;
3851e51764aSArtem Bityutskiy }
3861e51764aSArtem Bityutskiy 
3871e51764aSArtem Bityutskiy /**
3881e51764aSArtem Bityutskiy  * key_block - get data block number.
3891e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3901e51764aSArtem Bityutskiy  * @key: the key to get the block number from
3911e51764aSArtem Bityutskiy  */
key_block(const struct ubifs_info * c,const union ubifs_key * key)3921e51764aSArtem Bityutskiy static inline unsigned int key_block(const struct ubifs_info *c,
3931e51764aSArtem Bityutskiy 				     const union ubifs_key *key)
3941e51764aSArtem Bityutskiy {
3951e51764aSArtem Bityutskiy 	return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK;
3961e51764aSArtem Bityutskiy }
3971e51764aSArtem Bityutskiy 
3981e51764aSArtem Bityutskiy /**
3991e51764aSArtem Bityutskiy  * key_block_flash - get data block number from an on-flash formatted key.
4001e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4011e51764aSArtem Bityutskiy  * @k: the key to get the block number from
4021e51764aSArtem Bityutskiy  */
key_block_flash(const struct ubifs_info * c,const void * k)4031e51764aSArtem Bityutskiy static inline unsigned int key_block_flash(const struct ubifs_info *c,
4041e51764aSArtem Bityutskiy 					   const void *k)
4051e51764aSArtem Bityutskiy {
4061e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
4071e51764aSArtem Bityutskiy 
4080ecb9529SHarvey Harrison 	return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_BLOCK_MASK;
4091e51764aSArtem Bityutskiy }
4101e51764aSArtem Bityutskiy 
4111e51764aSArtem Bityutskiy /**
4121e51764aSArtem Bityutskiy  * key_read - transform a key to in-memory format.
4131e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4141e51764aSArtem Bityutskiy  * @from: the key to transform
4151e51764aSArtem Bityutskiy  * @to: the key to store the result
4161e51764aSArtem Bityutskiy  */
key_read(const struct ubifs_info * c,const void * from,union ubifs_key * to)4171e51764aSArtem Bityutskiy static inline void key_read(const struct ubifs_info *c, const void *from,
4181e51764aSArtem Bityutskiy 			    union ubifs_key *to)
4191e51764aSArtem Bityutskiy {
4201e51764aSArtem Bityutskiy 	const union ubifs_key *f = from;
4211e51764aSArtem Bityutskiy 
4221e51764aSArtem Bityutskiy 	to->u32[0] = le32_to_cpu(f->j32[0]);
4231e51764aSArtem Bityutskiy 	to->u32[1] = le32_to_cpu(f->j32[1]);
4241e51764aSArtem Bityutskiy }
4251e51764aSArtem Bityutskiy 
4261e51764aSArtem Bityutskiy /**
4271e51764aSArtem Bityutskiy  * key_write - transform a key from in-memory format.
4281e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4291e51764aSArtem Bityutskiy  * @from: the key to transform
4301e51764aSArtem Bityutskiy  * @to: the key to store the result
4311e51764aSArtem Bityutskiy  */
key_write(const struct ubifs_info * c,const union ubifs_key * from,void * to)4321e51764aSArtem Bityutskiy static inline void key_write(const struct ubifs_info *c,
4331e51764aSArtem Bityutskiy 			     const union ubifs_key *from, void *to)
4341e51764aSArtem Bityutskiy {
4351e51764aSArtem Bityutskiy 	union ubifs_key *t = to;
4361e51764aSArtem Bityutskiy 
4371e51764aSArtem Bityutskiy 	t->j32[0] = cpu_to_le32(from->u32[0]);
4381e51764aSArtem Bityutskiy 	t->j32[1] = cpu_to_le32(from->u32[1]);
4391e51764aSArtem Bityutskiy 	memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
4401e51764aSArtem Bityutskiy }
4411e51764aSArtem Bityutskiy 
4421e51764aSArtem Bityutskiy /**
4431e51764aSArtem Bityutskiy  * key_write_idx - transform a key from in-memory format for the index.
4441e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4451e51764aSArtem Bityutskiy  * @from: the key to transform
4461e51764aSArtem Bityutskiy  * @to: the key to store the result
4471e51764aSArtem Bityutskiy  */
key_write_idx(const struct ubifs_info * c,const union ubifs_key * from,void * to)4481e51764aSArtem Bityutskiy static inline void key_write_idx(const struct ubifs_info *c,
4491e51764aSArtem Bityutskiy 				 const union ubifs_key *from, void *to)
4501e51764aSArtem Bityutskiy {
4511e51764aSArtem Bityutskiy 	union ubifs_key *t = to;
4521e51764aSArtem Bityutskiy 
4531e51764aSArtem Bityutskiy 	t->j32[0] = cpu_to_le32(from->u32[0]);
4541e51764aSArtem Bityutskiy 	t->j32[1] = cpu_to_le32(from->u32[1]);
4551e51764aSArtem Bityutskiy }
4561e51764aSArtem Bityutskiy 
4571e51764aSArtem Bityutskiy /**
4581e51764aSArtem Bityutskiy  * key_copy - copy a key.
4591e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4601e51764aSArtem Bityutskiy  * @from: the key to copy from
4611e51764aSArtem Bityutskiy  * @to: the key to copy to
4621e51764aSArtem Bityutskiy  */
key_copy(const struct ubifs_info * c,const union ubifs_key * from,union ubifs_key * to)4631e51764aSArtem Bityutskiy static inline void key_copy(const struct ubifs_info *c,
4641e51764aSArtem Bityutskiy 			    const union ubifs_key *from, union ubifs_key *to)
4651e51764aSArtem Bityutskiy {
4661e51764aSArtem Bityutskiy 	to->u64[0] = from->u64[0];
4671e51764aSArtem Bityutskiy }
4681e51764aSArtem Bityutskiy 
4691e51764aSArtem Bityutskiy /**
4701e51764aSArtem Bityutskiy  * keys_cmp - compare keys.
4711e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4721e51764aSArtem Bityutskiy  * @key1: the first key to compare
4731e51764aSArtem Bityutskiy  * @key2: the second key to compare
4741e51764aSArtem Bityutskiy  *
4751e51764aSArtem Bityutskiy  * This function compares 2 keys and returns %-1 if @key1 is less than
4764793e7c5SAdrian Hunter  * @key2, %0 if the keys are equivalent and %1 if @key1 is greater than @key2.
4771e51764aSArtem Bityutskiy  */
keys_cmp(const struct ubifs_info * c,const union ubifs_key * key1,const union ubifs_key * key2)4781e51764aSArtem Bityutskiy static inline int keys_cmp(const struct ubifs_info *c,
4791e51764aSArtem Bityutskiy 			   const union ubifs_key *key1,
4801e51764aSArtem Bityutskiy 			   const union ubifs_key *key2)
4811e51764aSArtem Bityutskiy {
4821e51764aSArtem Bityutskiy 	if (key1->u32[0] < key2->u32[0])
4831e51764aSArtem Bityutskiy 		return -1;
4841e51764aSArtem Bityutskiy 	if (key1->u32[0] > key2->u32[0])
4851e51764aSArtem Bityutskiy 		return 1;
4861e51764aSArtem Bityutskiy 	if (key1->u32[1] < key2->u32[1])
4871e51764aSArtem Bityutskiy 		return -1;
4881e51764aSArtem Bityutskiy 	if (key1->u32[1] > key2->u32[1])
4891e51764aSArtem Bityutskiy 		return 1;
4901e51764aSArtem Bityutskiy 
4911e51764aSArtem Bityutskiy 	return 0;
4921e51764aSArtem Bityutskiy }
4931e51764aSArtem Bityutskiy 
4941e51764aSArtem Bityutskiy /**
4954793e7c5SAdrian Hunter  * keys_eq - determine if keys are equivalent.
4964793e7c5SAdrian Hunter  * @c: UBIFS file-system description object
4974793e7c5SAdrian Hunter  * @key1: the first key to compare
4984793e7c5SAdrian Hunter  * @key2: the second key to compare
4994793e7c5SAdrian Hunter  *
5004793e7c5SAdrian Hunter  * This function compares 2 keys and returns %1 if @key1 is equal to @key2 and
5014793e7c5SAdrian Hunter  * %0 if not.
5024793e7c5SAdrian Hunter  */
keys_eq(const struct ubifs_info * c,const union ubifs_key * key1,const union ubifs_key * key2)5034793e7c5SAdrian Hunter static inline int keys_eq(const struct ubifs_info *c,
5044793e7c5SAdrian Hunter 			  const union ubifs_key *key1,
5054793e7c5SAdrian Hunter 			  const union ubifs_key *key2)
5064793e7c5SAdrian Hunter {
5074793e7c5SAdrian Hunter 	if (key1->u32[0] != key2->u32[0])
5084793e7c5SAdrian Hunter 		return 0;
5094793e7c5SAdrian Hunter 	if (key1->u32[1] != key2->u32[1])
5104793e7c5SAdrian Hunter 		return 0;
5114793e7c5SAdrian Hunter 	return 1;
5124793e7c5SAdrian Hunter }
5134793e7c5SAdrian Hunter 
5144793e7c5SAdrian Hunter /**
5151e51764aSArtem Bityutskiy  * is_hash_key - is a key vulnerable to hash collisions.
5161e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
5171e51764aSArtem Bityutskiy  * @key: key
5181e51764aSArtem Bityutskiy  *
5191e51764aSArtem Bityutskiy  * This function returns %1 if @key is a hashed key or %0 otherwise.
5201e51764aSArtem Bityutskiy  */
is_hash_key(const struct ubifs_info * c,const union ubifs_key * key)5211e51764aSArtem Bityutskiy static inline int is_hash_key(const struct ubifs_info *c,
5221e51764aSArtem Bityutskiy 			      const union ubifs_key *key)
5231e51764aSArtem Bityutskiy {
5241e51764aSArtem Bityutskiy 	int type = key_type(c, key);
5251e51764aSArtem Bityutskiy 
5261e51764aSArtem Bityutskiy 	return type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY;
5271e51764aSArtem Bityutskiy }
5281e51764aSArtem Bityutskiy 
5291e51764aSArtem Bityutskiy /**
5301e51764aSArtem Bityutskiy  * key_max_inode_size - get maximum file size allowed by current key format.
5311e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
5321e51764aSArtem Bityutskiy  */
key_max_inode_size(const struct ubifs_info * c)5331e51764aSArtem Bityutskiy static inline unsigned long long key_max_inode_size(const struct ubifs_info *c)
5341e51764aSArtem Bityutskiy {
5351e51764aSArtem Bityutskiy 	switch (c->key_fmt) {
5361e51764aSArtem Bityutskiy 	case UBIFS_SIMPLE_KEY_FMT:
5371e51764aSArtem Bityutskiy 		return (1ULL << UBIFS_S_KEY_BLOCK_BITS) * UBIFS_BLOCK_SIZE;
5381e51764aSArtem Bityutskiy 	default:
5391e51764aSArtem Bityutskiy 		return 0;
5401e51764aSArtem Bityutskiy 	}
5411e51764aSArtem Bityutskiy }
542e3c3efc2SArtem Bityutskiy 
5431e51764aSArtem Bityutskiy #endif /* !__UBIFS_KEY_H__ */
544