xref: /linux/fs/ubifs/key.h (revision cb4f952db3a01a2d56eb17e0eb00ce99ae5f0f50)
11e51764aSArtem Bityutskiy /*
21e51764aSArtem Bityutskiy  * This file is part of UBIFS.
31e51764aSArtem Bityutskiy  *
41e51764aSArtem Bityutskiy  * Copyright (C) 2006-2008 Nokia Corporation.
51e51764aSArtem Bityutskiy  *
61e51764aSArtem Bityutskiy  * This program is free software; you can redistribute it and/or modify it
71e51764aSArtem Bityutskiy  * under the terms of the GNU General Public License version 2 as published by
81e51764aSArtem Bityutskiy  * the Free Software Foundation.
91e51764aSArtem Bityutskiy  *
101e51764aSArtem Bityutskiy  * This program is distributed in the hope that it will be useful, but WITHOUT
111e51764aSArtem Bityutskiy  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
121e51764aSArtem Bityutskiy  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
131e51764aSArtem Bityutskiy  * more details.
141e51764aSArtem Bityutskiy  *
151e51764aSArtem Bityutskiy  * You should have received a copy of the GNU General Public License along with
161e51764aSArtem Bityutskiy  * this program; if not, write to the Free Software Foundation, Inc., 51
171e51764aSArtem Bityutskiy  * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
181e51764aSArtem Bityutskiy  *
191e51764aSArtem Bityutskiy  * Authors: Artem Bityutskiy (Битюцкий Артём)
201e51764aSArtem Bityutskiy  *          Adrian Hunter
211e51764aSArtem Bityutskiy  */
221e51764aSArtem Bityutskiy 
231e51764aSArtem Bityutskiy /*
241e51764aSArtem Bityutskiy  * This header contains various key-related definitions and helper function.
251e51764aSArtem Bityutskiy  * UBIFS allows several key schemes, so we access key fields only via these
261e51764aSArtem Bityutskiy  * helpers. At the moment only one key scheme is supported.
271e51764aSArtem Bityutskiy  *
281e51764aSArtem Bityutskiy  * Simple key scheme
291e51764aSArtem Bityutskiy  * ~~~~~~~~~~~~~~~~~
301e51764aSArtem Bityutskiy  *
311e51764aSArtem Bityutskiy  * Keys are 64-bits long. First 32-bits are inode number (parent inode number
321e51764aSArtem Bityutskiy  * in case of direntry key). Next 3 bits are node type. The last 29 bits are
331e51764aSArtem Bityutskiy  * 4KiB offset in case of inode node, and direntry hash in case of a direntry
341e51764aSArtem Bityutskiy  * node. We use "r5" hash borrowed from reiserfs.
351e51764aSArtem Bityutskiy  */
361e51764aSArtem Bityutskiy 
371e51764aSArtem Bityutskiy #ifndef __UBIFS_KEY_H__
381e51764aSArtem Bityutskiy #define __UBIFS_KEY_H__
391e51764aSArtem Bityutskiy 
401e51764aSArtem Bityutskiy /**
415dd7cbc0SKukkonen Mika  * key_mask_hash - mask a valid hash value.
425dd7cbc0SKukkonen Mika  * @val: value to be masked
435dd7cbc0SKukkonen Mika  *
445dd7cbc0SKukkonen Mika  * We use hash values as offset in directories, so values %0 and %1 are
455dd7cbc0SKukkonen Mika  * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
465dd7cbc0SKukkonen Mika  * function makes sure the reserved values are not used.
475dd7cbc0SKukkonen Mika  */
485dd7cbc0SKukkonen Mika static inline uint32_t key_mask_hash(uint32_t hash)
495dd7cbc0SKukkonen Mika {
505dd7cbc0SKukkonen Mika 	hash &= UBIFS_S_KEY_HASH_MASK;
515dd7cbc0SKukkonen Mika 	if (unlikely(hash <= 2))
525dd7cbc0SKukkonen Mika 		hash += 3;
535dd7cbc0SKukkonen Mika 	return hash;
545dd7cbc0SKukkonen Mika }
555dd7cbc0SKukkonen Mika 
565dd7cbc0SKukkonen Mika /**
571e51764aSArtem Bityutskiy  * key_r5_hash - R5 hash function (borrowed from reiserfs).
581e51764aSArtem Bityutskiy  * @s: direntry name
591e51764aSArtem Bityutskiy  * @len: name length
601e51764aSArtem Bityutskiy  */
611e51764aSArtem Bityutskiy static inline uint32_t key_r5_hash(const char *s, int len)
621e51764aSArtem Bityutskiy {
631e51764aSArtem Bityutskiy 	uint32_t a = 0;
641e51764aSArtem Bityutskiy 	const signed char *str = (const signed char *)s;
651e51764aSArtem Bityutskiy 
661e51764aSArtem Bityutskiy 	while (*str) {
671e51764aSArtem Bityutskiy 		a += *str << 4;
681e51764aSArtem Bityutskiy 		a += *str >> 4;
691e51764aSArtem Bityutskiy 		a *= 11;
701e51764aSArtem Bityutskiy 		str++;
711e51764aSArtem Bityutskiy 	}
721e51764aSArtem Bityutskiy 
735dd7cbc0SKukkonen Mika 	return key_mask_hash(a);
741e51764aSArtem Bityutskiy }
751e51764aSArtem Bityutskiy 
761e51764aSArtem Bityutskiy /**
771e51764aSArtem Bityutskiy  * key_test_hash - testing hash function.
781e51764aSArtem Bityutskiy  * @str: direntry name
791e51764aSArtem Bityutskiy  * @len: name length
801e51764aSArtem Bityutskiy  */
811e51764aSArtem Bityutskiy static inline uint32_t key_test_hash(const char *str, int len)
821e51764aSArtem Bityutskiy {
831e51764aSArtem Bityutskiy 	uint32_t a = 0;
841e51764aSArtem Bityutskiy 
851e51764aSArtem Bityutskiy 	len = min_t(uint32_t, len, 4);
861e51764aSArtem Bityutskiy 	memcpy(&a, str, len);
875dd7cbc0SKukkonen Mika 	return key_mask_hash(a);
881e51764aSArtem Bityutskiy }
891e51764aSArtem Bityutskiy 
901e51764aSArtem Bityutskiy /**
911e51764aSArtem Bityutskiy  * ino_key_init - initialize inode key.
921e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
931e51764aSArtem Bityutskiy  * @key: key to initialize
941e51764aSArtem Bityutskiy  * @inum: inode number
951e51764aSArtem Bityutskiy  */
961e51764aSArtem Bityutskiy static inline void ino_key_init(const struct ubifs_info *c,
971e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
981e51764aSArtem Bityutskiy {
991e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1001e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
1011e51764aSArtem Bityutskiy }
1021e51764aSArtem Bityutskiy 
1031e51764aSArtem Bityutskiy /**
1041e51764aSArtem Bityutskiy  * ino_key_init_flash - initialize on-flash inode key.
1051e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1061e51764aSArtem Bityutskiy  * @k: key to initialize
1071e51764aSArtem Bityutskiy  * @inum: inode number
1081e51764aSArtem Bityutskiy  */
1091e51764aSArtem Bityutskiy static inline void ino_key_init_flash(const struct ubifs_info *c, void *k,
1101e51764aSArtem Bityutskiy 				      ino_t inum)
1111e51764aSArtem Bityutskiy {
1121e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
1131e51764aSArtem Bityutskiy 
1141e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
1151e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS);
1161e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
1171e51764aSArtem Bityutskiy }
1181e51764aSArtem Bityutskiy 
1191e51764aSArtem Bityutskiy /**
1201e51764aSArtem Bityutskiy  * lowest_ino_key - get the lowest possible inode key.
1211e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1221e51764aSArtem Bityutskiy  * @key: key to initialize
1231e51764aSArtem Bityutskiy  * @inum: inode number
1241e51764aSArtem Bityutskiy  */
1251e51764aSArtem Bityutskiy static inline void lowest_ino_key(const struct ubifs_info *c,
1261e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
1271e51764aSArtem Bityutskiy {
1281e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1291e51764aSArtem Bityutskiy 	key->u32[1] = 0;
1301e51764aSArtem Bityutskiy }
1311e51764aSArtem Bityutskiy 
1321e51764aSArtem Bityutskiy /**
1331e51764aSArtem Bityutskiy  * highest_ino_key - get the highest possible inode key.
1341e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1351e51764aSArtem Bityutskiy  * @key: key to initialize
1361e51764aSArtem Bityutskiy  * @inum: inode number
1371e51764aSArtem Bityutskiy  */
1381e51764aSArtem Bityutskiy static inline void highest_ino_key(const struct ubifs_info *c,
1391e51764aSArtem Bityutskiy 				union ubifs_key *key, ino_t inum)
1401e51764aSArtem Bityutskiy {
1411e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1421e51764aSArtem Bityutskiy 	key->u32[1] = 0xffffffff;
1431e51764aSArtem Bityutskiy }
1441e51764aSArtem Bityutskiy 
1451e51764aSArtem Bityutskiy /**
1461e51764aSArtem Bityutskiy  * dent_key_init - initialize directory entry key.
1471e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1481e51764aSArtem Bityutskiy  * @key: key to initialize
1491e51764aSArtem Bityutskiy  * @inum: parent inode number
1501e51764aSArtem Bityutskiy  * @nm: direntry name and length
1511e51764aSArtem Bityutskiy  */
1521e51764aSArtem Bityutskiy static inline void dent_key_init(const struct ubifs_info *c,
1531e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
1541e51764aSArtem Bityutskiy 				 const struct qstr *nm)
1551e51764aSArtem Bityutskiy {
1561e51764aSArtem Bityutskiy 	uint32_t hash = c->key_hash(nm->name, nm->len);
1571e51764aSArtem Bityutskiy 
1581e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
1591e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1601e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
1611e51764aSArtem Bityutskiy }
1621e51764aSArtem Bityutskiy 
1631e51764aSArtem Bityutskiy /**
1641e51764aSArtem Bityutskiy  * dent_key_init_hash - initialize directory entry key without re-calculating
1651e51764aSArtem Bityutskiy  *                      hash function.
1661e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1671e51764aSArtem Bityutskiy  * @key: key to initialize
1681e51764aSArtem Bityutskiy  * @inum: parent inode number
1691e51764aSArtem Bityutskiy  * @hash: direntry name hash
1701e51764aSArtem Bityutskiy  */
1711e51764aSArtem Bityutskiy static inline void dent_key_init_hash(const struct ubifs_info *c,
1721e51764aSArtem Bityutskiy 				      union ubifs_key *key, ino_t inum,
1731e51764aSArtem Bityutskiy 				      uint32_t hash)
1741e51764aSArtem Bityutskiy {
1751e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
1761e51764aSArtem Bityutskiy 	key->u32[0] = inum;
1771e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
1781e51764aSArtem Bityutskiy }
1791e51764aSArtem Bityutskiy 
1801e51764aSArtem Bityutskiy /**
1811e51764aSArtem Bityutskiy  * dent_key_init_flash - initialize on-flash directory entry key.
1821e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
1831e51764aSArtem Bityutskiy  * @k: key to initialize
1841e51764aSArtem Bityutskiy  * @inum: parent inode number
1851e51764aSArtem Bityutskiy  * @nm: direntry name and length
1861e51764aSArtem Bityutskiy  */
1871e51764aSArtem Bityutskiy static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
1881e51764aSArtem Bityutskiy 				       ino_t inum, const struct qstr *nm)
1891e51764aSArtem Bityutskiy {
1901e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
1911e51764aSArtem Bityutskiy 	uint32_t hash = c->key_hash(nm->name, nm->len);
1921e51764aSArtem Bityutskiy 
1931e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
1941e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
1951e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(hash |
1961e51764aSArtem Bityutskiy 				  (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS));
1971e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
1981e51764aSArtem Bityutskiy }
1991e51764aSArtem Bityutskiy 
2001e51764aSArtem Bityutskiy /**
2011e51764aSArtem Bityutskiy  * lowest_dent_key - get the lowest possible directory entry key.
2021e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2031e51764aSArtem Bityutskiy  * @key: where to store the lowest key
2041e51764aSArtem Bityutskiy  * @inum: parent inode number
2051e51764aSArtem Bityutskiy  */
2061e51764aSArtem Bityutskiy static inline void lowest_dent_key(const struct ubifs_info *c,
2071e51764aSArtem Bityutskiy 				   union ubifs_key *key, ino_t inum)
2081e51764aSArtem Bityutskiy {
2091e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2101e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS;
2111e51764aSArtem Bityutskiy }
2121e51764aSArtem Bityutskiy 
2131e51764aSArtem Bityutskiy /**
2141e51764aSArtem Bityutskiy  * xent_key_init - initialize extended attribute entry key.
2151e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2161e51764aSArtem Bityutskiy  * @key: key to initialize
2171e51764aSArtem Bityutskiy  * @inum: host inode number
2181e51764aSArtem Bityutskiy  * @nm: extended attribute entry name and length
2191e51764aSArtem Bityutskiy  */
2201e51764aSArtem Bityutskiy static inline void xent_key_init(const struct ubifs_info *c,
2211e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
2221e51764aSArtem Bityutskiy 				 const struct qstr *nm)
2231e51764aSArtem Bityutskiy {
2241e51764aSArtem Bityutskiy 	uint32_t hash = c->key_hash(nm->name, nm->len);
2251e51764aSArtem Bityutskiy 
2261e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
2271e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2281e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
2291e51764aSArtem Bityutskiy }
2301e51764aSArtem Bityutskiy 
2311e51764aSArtem Bityutskiy /**
2321e51764aSArtem Bityutskiy  * xent_key_init_hash - initialize extended attribute entry key without
2331e51764aSArtem Bityutskiy  *                      re-calculating hash function.
2341e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2351e51764aSArtem Bityutskiy  * @key: key to initialize
2361e51764aSArtem Bityutskiy  * @inum: host inode number
2371e51764aSArtem Bityutskiy  * @hash: extended attribute entry name hash
2381e51764aSArtem Bityutskiy  */
2391e51764aSArtem Bityutskiy static inline void xent_key_init_hash(const struct ubifs_info *c,
2401e51764aSArtem Bityutskiy 				      union ubifs_key *key, ino_t inum,
2411e51764aSArtem Bityutskiy 				      uint32_t hash)
2421e51764aSArtem Bityutskiy {
2431e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
2441e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2451e51764aSArtem Bityutskiy 	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
2461e51764aSArtem Bityutskiy }
2471e51764aSArtem Bityutskiy 
2481e51764aSArtem Bityutskiy /**
2491e51764aSArtem Bityutskiy  * xent_key_init_flash - initialize on-flash extended attribute entry key.
2501e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2511e51764aSArtem Bityutskiy  * @k: key to initialize
2521e51764aSArtem Bityutskiy  * @inum: host inode number
2531e51764aSArtem Bityutskiy  * @nm: extended attribute entry name and length
2541e51764aSArtem Bityutskiy  */
2551e51764aSArtem Bityutskiy static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
2561e51764aSArtem Bityutskiy 				       ino_t inum, const struct qstr *nm)
2571e51764aSArtem Bityutskiy {
2581e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
2591e51764aSArtem Bityutskiy 	uint32_t hash = c->key_hash(nm->name, nm->len);
2601e51764aSArtem Bityutskiy 
2611e51764aSArtem Bityutskiy 	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
2621e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
2631e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(hash |
2641e51764aSArtem Bityutskiy 				  (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS));
2651e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
2661e51764aSArtem Bityutskiy }
2671e51764aSArtem Bityutskiy 
2681e51764aSArtem Bityutskiy /**
2691e51764aSArtem Bityutskiy  * lowest_xent_key - get the lowest possible extended attribute entry key.
2701e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2711e51764aSArtem Bityutskiy  * @key: where to store the lowest key
2721e51764aSArtem Bityutskiy  * @inum: host inode number
2731e51764aSArtem Bityutskiy  */
2741e51764aSArtem Bityutskiy static inline void lowest_xent_key(const struct ubifs_info *c,
2751e51764aSArtem Bityutskiy 				   union ubifs_key *key, ino_t inum)
2761e51764aSArtem Bityutskiy {
2771e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2781e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS;
2791e51764aSArtem Bityutskiy }
2801e51764aSArtem Bityutskiy 
2811e51764aSArtem Bityutskiy /**
2821e51764aSArtem Bityutskiy  * data_key_init - initialize data key.
2831e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
2841e51764aSArtem Bityutskiy  * @key: key to initialize
2851e51764aSArtem Bityutskiy  * @inum: inode number
2861e51764aSArtem Bityutskiy  * @block: block number
2871e51764aSArtem Bityutskiy  */
2881e51764aSArtem Bityutskiy static inline void data_key_init(const struct ubifs_info *c,
2891e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum,
2901e51764aSArtem Bityutskiy 				 unsigned int block)
2911e51764aSArtem Bityutskiy {
2921e51764aSArtem Bityutskiy 	ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
2931e51764aSArtem Bityutskiy 	key->u32[0] = inum;
2941e51764aSArtem Bityutskiy 	key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
2951e51764aSArtem Bityutskiy }
2961e51764aSArtem Bityutskiy 
2971e51764aSArtem Bityutskiy /**
2981e51764aSArtem Bityutskiy  * data_key_init_flash - initialize on-flash data key.
2991e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3001e51764aSArtem Bityutskiy  * @k: key to initialize
3011e51764aSArtem Bityutskiy  * @inum: inode number
3021e51764aSArtem Bityutskiy  * @block: block number
3031e51764aSArtem Bityutskiy  */
3041e51764aSArtem Bityutskiy static inline void data_key_init_flash(const struct ubifs_info *c, void *k,
3051e51764aSArtem Bityutskiy 				       ino_t inum, unsigned int block)
3061e51764aSArtem Bityutskiy {
3071e51764aSArtem Bityutskiy 	union ubifs_key *key = k;
3081e51764aSArtem Bityutskiy 
3091e51764aSArtem Bityutskiy 	ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
3101e51764aSArtem Bityutskiy 	key->j32[0] = cpu_to_le32(inum);
3111e51764aSArtem Bityutskiy 	key->j32[1] = cpu_to_le32(block |
3121e51764aSArtem Bityutskiy 				  (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS));
3131e51764aSArtem Bityutskiy 	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
3141e51764aSArtem Bityutskiy }
3151e51764aSArtem Bityutskiy 
3161e51764aSArtem Bityutskiy /**
3171e51764aSArtem Bityutskiy  * trun_key_init - initialize truncation node key.
3181e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3191e51764aSArtem Bityutskiy  * @key: key to initialize
3201e51764aSArtem Bityutskiy  * @inum: inode number
3211e51764aSArtem Bityutskiy  *
3221e51764aSArtem Bityutskiy  * Note, UBIFS does not have truncation keys on the media and this function is
3231e51764aSArtem Bityutskiy  * only used for purposes of replay.
3241e51764aSArtem Bityutskiy  */
3251e51764aSArtem Bityutskiy static inline void trun_key_init(const struct ubifs_info *c,
3261e51764aSArtem Bityutskiy 				 union ubifs_key *key, ino_t inum)
3271e51764aSArtem Bityutskiy {
3281e51764aSArtem Bityutskiy 	key->u32[0] = inum;
3291e51764aSArtem Bityutskiy 	key->u32[1] = UBIFS_TRUN_KEY << UBIFS_S_KEY_BLOCK_BITS;
3301e51764aSArtem Bityutskiy }
3311e51764aSArtem Bityutskiy 
3321e51764aSArtem Bityutskiy /**
3331e51764aSArtem Bityutskiy  * key_type - get key type.
3341e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3351e51764aSArtem Bityutskiy  * @key: key to get type of
3361e51764aSArtem Bityutskiy  */
3371e51764aSArtem Bityutskiy static inline int key_type(const struct ubifs_info *c,
3381e51764aSArtem Bityutskiy 			   const union ubifs_key *key)
3391e51764aSArtem Bityutskiy {
3401e51764aSArtem Bityutskiy 	return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
3411e51764aSArtem Bityutskiy }
3421e51764aSArtem Bityutskiy 
3431e51764aSArtem Bityutskiy /**
3441e51764aSArtem Bityutskiy  * key_type_flash - get type of a on-flash formatted key.
3451e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3461e51764aSArtem Bityutskiy  * @k: key to get type of
3471e51764aSArtem Bityutskiy  */
3481e51764aSArtem Bityutskiy static inline int key_type_flash(const struct ubifs_info *c, const void *k)
3491e51764aSArtem Bityutskiy {
3501e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3511e51764aSArtem Bityutskiy 
3520ecb9529SHarvey Harrison 	return le32_to_cpu(key->j32[1]) >> UBIFS_S_KEY_BLOCK_BITS;
3531e51764aSArtem Bityutskiy }
3541e51764aSArtem Bityutskiy 
3551e51764aSArtem Bityutskiy /**
3561e51764aSArtem Bityutskiy  * key_inum - fetch inode number from key.
3571e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3581e51764aSArtem Bityutskiy  * @k: key to fetch inode number from
3591e51764aSArtem Bityutskiy  */
3601e51764aSArtem Bityutskiy static inline ino_t key_inum(const struct ubifs_info *c, const void *k)
3611e51764aSArtem Bityutskiy {
3621e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3631e51764aSArtem Bityutskiy 
3641e51764aSArtem Bityutskiy 	return key->u32[0];
3651e51764aSArtem Bityutskiy }
3661e51764aSArtem Bityutskiy 
3671e51764aSArtem Bityutskiy /**
3681e51764aSArtem Bityutskiy  * key_inum_flash - fetch inode number from an on-flash formatted key.
3691e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3701e51764aSArtem Bityutskiy  * @k: key to fetch inode number from
3711e51764aSArtem Bityutskiy  */
3721e51764aSArtem Bityutskiy static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k)
3731e51764aSArtem Bityutskiy {
3741e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3751e51764aSArtem Bityutskiy 
3761e51764aSArtem Bityutskiy 	return le32_to_cpu(key->j32[0]);
3771e51764aSArtem Bityutskiy }
3781e51764aSArtem Bityutskiy 
3791e51764aSArtem Bityutskiy /**
3801e51764aSArtem Bityutskiy  * key_hash - get directory entry hash.
3811e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3821e51764aSArtem Bityutskiy  * @key: the key to get hash from
3831e51764aSArtem Bityutskiy  */
384*cb4f952dSArtem Bityutskiy static inline uint32_t key_hash(const struct ubifs_info *c,
3851e51764aSArtem Bityutskiy 				const union ubifs_key *key)
3861e51764aSArtem Bityutskiy {
3871e51764aSArtem Bityutskiy 	return key->u32[1] & UBIFS_S_KEY_HASH_MASK;
3881e51764aSArtem Bityutskiy }
3891e51764aSArtem Bityutskiy 
3901e51764aSArtem Bityutskiy /**
3911e51764aSArtem Bityutskiy  * key_hash_flash - get directory entry hash from an on-flash formatted key.
3921e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
3931e51764aSArtem Bityutskiy  * @k: the key to get hash from
3941e51764aSArtem Bityutskiy  */
395*cb4f952dSArtem Bityutskiy static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k)
3961e51764aSArtem Bityutskiy {
3971e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
3981e51764aSArtem Bityutskiy 
3991e51764aSArtem Bityutskiy 	return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_HASH_MASK;
4001e51764aSArtem Bityutskiy }
4011e51764aSArtem Bityutskiy 
4021e51764aSArtem Bityutskiy /**
4031e51764aSArtem Bityutskiy  * key_block - get data block number.
4041e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4051e51764aSArtem Bityutskiy  * @key: the key to get the block number from
4061e51764aSArtem Bityutskiy  */
4071e51764aSArtem Bityutskiy static inline unsigned int key_block(const struct ubifs_info *c,
4081e51764aSArtem Bityutskiy 				     const union ubifs_key *key)
4091e51764aSArtem Bityutskiy {
4101e51764aSArtem Bityutskiy 	return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK;
4111e51764aSArtem Bityutskiy }
4121e51764aSArtem Bityutskiy 
4131e51764aSArtem Bityutskiy /**
4141e51764aSArtem Bityutskiy  * key_block_flash - get data block number from an on-flash formatted key.
4151e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4161e51764aSArtem Bityutskiy  * @k: the key to get the block number from
4171e51764aSArtem Bityutskiy  */
4181e51764aSArtem Bityutskiy static inline unsigned int key_block_flash(const struct ubifs_info *c,
4191e51764aSArtem Bityutskiy 					   const void *k)
4201e51764aSArtem Bityutskiy {
4211e51764aSArtem Bityutskiy 	const union ubifs_key *key = k;
4221e51764aSArtem Bityutskiy 
4230ecb9529SHarvey Harrison 	return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_BLOCK_MASK;
4241e51764aSArtem Bityutskiy }
4251e51764aSArtem Bityutskiy 
4261e51764aSArtem Bityutskiy /**
4271e51764aSArtem Bityutskiy  * key_read - transform a key to 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  */
4321e51764aSArtem Bityutskiy static inline void key_read(const struct ubifs_info *c, const void *from,
4331e51764aSArtem Bityutskiy 			    union ubifs_key *to)
4341e51764aSArtem Bityutskiy {
4351e51764aSArtem Bityutskiy 	const union ubifs_key *f = from;
4361e51764aSArtem Bityutskiy 
4371e51764aSArtem Bityutskiy 	to->u32[0] = le32_to_cpu(f->j32[0]);
4381e51764aSArtem Bityutskiy 	to->u32[1] = le32_to_cpu(f->j32[1]);
4391e51764aSArtem Bityutskiy }
4401e51764aSArtem Bityutskiy 
4411e51764aSArtem Bityutskiy /**
4421e51764aSArtem Bityutskiy  * key_write - transform a key from in-memory format.
4431e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4441e51764aSArtem Bityutskiy  * @from: the key to transform
4451e51764aSArtem Bityutskiy  * @to: the key to store the result
4461e51764aSArtem Bityutskiy  */
4471e51764aSArtem Bityutskiy static inline void key_write(const struct ubifs_info *c,
4481e51764aSArtem Bityutskiy 			     const union ubifs_key *from, void *to)
4491e51764aSArtem Bityutskiy {
4501e51764aSArtem Bityutskiy 	union ubifs_key *t = to;
4511e51764aSArtem Bityutskiy 
4521e51764aSArtem Bityutskiy 	t->j32[0] = cpu_to_le32(from->u32[0]);
4531e51764aSArtem Bityutskiy 	t->j32[1] = cpu_to_le32(from->u32[1]);
4541e51764aSArtem Bityutskiy 	memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
4551e51764aSArtem Bityutskiy }
4561e51764aSArtem Bityutskiy 
4571e51764aSArtem Bityutskiy /**
4581e51764aSArtem Bityutskiy  * key_write_idx - transform a key from in-memory format for the index.
4591e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4601e51764aSArtem Bityutskiy  * @from: the key to transform
4611e51764aSArtem Bityutskiy  * @to: the key to store the result
4621e51764aSArtem Bityutskiy  */
4631e51764aSArtem Bityutskiy static inline void key_write_idx(const struct ubifs_info *c,
4641e51764aSArtem Bityutskiy 				 const union ubifs_key *from, void *to)
4651e51764aSArtem Bityutskiy {
4661e51764aSArtem Bityutskiy 	union ubifs_key *t = to;
4671e51764aSArtem Bityutskiy 
4681e51764aSArtem Bityutskiy 	t->j32[0] = cpu_to_le32(from->u32[0]);
4691e51764aSArtem Bityutskiy 	t->j32[1] = cpu_to_le32(from->u32[1]);
4701e51764aSArtem Bityutskiy }
4711e51764aSArtem Bityutskiy 
4721e51764aSArtem Bityutskiy /**
4731e51764aSArtem Bityutskiy  * key_copy - copy a key.
4741e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4751e51764aSArtem Bityutskiy  * @from: the key to copy from
4761e51764aSArtem Bityutskiy  * @to: the key to copy to
4771e51764aSArtem Bityutskiy  */
4781e51764aSArtem Bityutskiy static inline void key_copy(const struct ubifs_info *c,
4791e51764aSArtem Bityutskiy 			    const union ubifs_key *from, union ubifs_key *to)
4801e51764aSArtem Bityutskiy {
4811e51764aSArtem Bityutskiy 	to->u64[0] = from->u64[0];
4821e51764aSArtem Bityutskiy }
4831e51764aSArtem Bityutskiy 
4841e51764aSArtem Bityutskiy /**
4851e51764aSArtem Bityutskiy  * keys_cmp - compare keys.
4861e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
4871e51764aSArtem Bityutskiy  * @key1: the first key to compare
4881e51764aSArtem Bityutskiy  * @key2: the second key to compare
4891e51764aSArtem Bityutskiy  *
4901e51764aSArtem Bityutskiy  * This function compares 2 keys and returns %-1 if @key1 is less than
4914793e7c5SAdrian Hunter  * @key2, %0 if the keys are equivalent and %1 if @key1 is greater than @key2.
4921e51764aSArtem Bityutskiy  */
4931e51764aSArtem Bityutskiy static inline int keys_cmp(const struct ubifs_info *c,
4941e51764aSArtem Bityutskiy 			   const union ubifs_key *key1,
4951e51764aSArtem Bityutskiy 			   const union ubifs_key *key2)
4961e51764aSArtem Bityutskiy {
4971e51764aSArtem Bityutskiy 	if (key1->u32[0] < key2->u32[0])
4981e51764aSArtem Bityutskiy 		return -1;
4991e51764aSArtem Bityutskiy 	if (key1->u32[0] > key2->u32[0])
5001e51764aSArtem Bityutskiy 		return 1;
5011e51764aSArtem Bityutskiy 	if (key1->u32[1] < key2->u32[1])
5021e51764aSArtem Bityutskiy 		return -1;
5031e51764aSArtem Bityutskiy 	if (key1->u32[1] > key2->u32[1])
5041e51764aSArtem Bityutskiy 		return 1;
5051e51764aSArtem Bityutskiy 
5061e51764aSArtem Bityutskiy 	return 0;
5071e51764aSArtem Bityutskiy }
5081e51764aSArtem Bityutskiy 
5091e51764aSArtem Bityutskiy /**
5104793e7c5SAdrian Hunter  * keys_eq - determine if keys are equivalent.
5114793e7c5SAdrian Hunter  * @c: UBIFS file-system description object
5124793e7c5SAdrian Hunter  * @key1: the first key to compare
5134793e7c5SAdrian Hunter  * @key2: the second key to compare
5144793e7c5SAdrian Hunter  *
5154793e7c5SAdrian Hunter  * This function compares 2 keys and returns %1 if @key1 is equal to @key2 and
5164793e7c5SAdrian Hunter  * %0 if not.
5174793e7c5SAdrian Hunter  */
5184793e7c5SAdrian Hunter static inline int keys_eq(const struct ubifs_info *c,
5194793e7c5SAdrian Hunter 			  const union ubifs_key *key1,
5204793e7c5SAdrian Hunter 			  const union ubifs_key *key2)
5214793e7c5SAdrian Hunter {
5224793e7c5SAdrian Hunter 	if (key1->u32[0] != key2->u32[0])
5234793e7c5SAdrian Hunter 		return 0;
5244793e7c5SAdrian Hunter 	if (key1->u32[1] != key2->u32[1])
5254793e7c5SAdrian Hunter 		return 0;
5264793e7c5SAdrian Hunter 	return 1;
5274793e7c5SAdrian Hunter }
5284793e7c5SAdrian Hunter 
5294793e7c5SAdrian Hunter /**
5301e51764aSArtem Bityutskiy  * is_hash_key - is a key vulnerable to hash collisions.
5311e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
5321e51764aSArtem Bityutskiy  * @key: key
5331e51764aSArtem Bityutskiy  *
5341e51764aSArtem Bityutskiy  * This function returns %1 if @key is a hashed key or %0 otherwise.
5351e51764aSArtem Bityutskiy  */
5361e51764aSArtem Bityutskiy static inline int is_hash_key(const struct ubifs_info *c,
5371e51764aSArtem Bityutskiy 			      const union ubifs_key *key)
5381e51764aSArtem Bityutskiy {
5391e51764aSArtem Bityutskiy 	int type = key_type(c, key);
5401e51764aSArtem Bityutskiy 
5411e51764aSArtem Bityutskiy 	return type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY;
5421e51764aSArtem Bityutskiy }
5431e51764aSArtem Bityutskiy 
5441e51764aSArtem Bityutskiy /**
5451e51764aSArtem Bityutskiy  * key_max_inode_size - get maximum file size allowed by current key format.
5461e51764aSArtem Bityutskiy  * @c: UBIFS file-system description object
5471e51764aSArtem Bityutskiy  */
5481e51764aSArtem Bityutskiy static inline unsigned long long key_max_inode_size(const struct ubifs_info *c)
5491e51764aSArtem Bityutskiy {
5501e51764aSArtem Bityutskiy 	switch (c->key_fmt) {
5511e51764aSArtem Bityutskiy 	case UBIFS_SIMPLE_KEY_FMT:
5521e51764aSArtem Bityutskiy 		return (1ULL << UBIFS_S_KEY_BLOCK_BITS) * UBIFS_BLOCK_SIZE;
5531e51764aSArtem Bityutskiy 	default:
5541e51764aSArtem Bityutskiy 		return 0;
5551e51764aSArtem Bityutskiy 	}
5561e51764aSArtem Bityutskiy }
5571e51764aSArtem Bityutskiy #endif /* !__UBIFS_KEY_H__ */
558