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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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)); 1536eb61d58SRichard Weinberger ubifs_assert(c, !nm->hash && !nm->minor_hash); 1541e51764aSArtem Bityutskiy key->u32[0] = inum; 1551e51764aSArtem Bityutskiy key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); 1561e51764aSArtem Bityutskiy } 1571e51764aSArtem Bityutskiy 1581e51764aSArtem Bityutskiy /** 1591e51764aSArtem Bityutskiy * dent_key_init_hash - initialize directory entry key without re-calculating 1601e51764aSArtem Bityutskiy * hash function. 1611e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1621e51764aSArtem Bityutskiy * @key: key to initialize 1631e51764aSArtem Bityutskiy * @inum: parent inode number 1641e51764aSArtem Bityutskiy * @hash: direntry name hash 1651e51764aSArtem Bityutskiy */ 1661e51764aSArtem Bityutskiy static inline void dent_key_init_hash(const struct ubifs_info *c, 1671e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum, 1681e51764aSArtem Bityutskiy uint32_t hash) 1691e51764aSArtem Bityutskiy { 1706eb61d58SRichard Weinberger ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); 1711e51764aSArtem Bityutskiy key->u32[0] = inum; 1721e51764aSArtem Bityutskiy key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); 1731e51764aSArtem Bityutskiy } 1741e51764aSArtem Bityutskiy 1751e51764aSArtem Bityutskiy /** 1761e51764aSArtem Bityutskiy * dent_key_init_flash - initialize on-flash directory entry key. 1771e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1781e51764aSArtem Bityutskiy * @k: key to initialize 1791e51764aSArtem Bityutskiy * @inum: parent inode number 1801e51764aSArtem Bityutskiy * @nm: direntry name and length 1811e51764aSArtem Bityutskiy */ 1821e51764aSArtem Bityutskiy static inline void dent_key_init_flash(const struct ubifs_info *c, void *k, 183f4f61d2cSRichard Weinberger ino_t inum, 184f4f61d2cSRichard Weinberger const struct fscrypt_name *nm) 1851e51764aSArtem Bityutskiy { 1861e51764aSArtem Bityutskiy union ubifs_key *key = k; 187f4f61d2cSRichard Weinberger uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); 1881e51764aSArtem Bityutskiy 1896eb61d58SRichard Weinberger ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); 1901e51764aSArtem Bityutskiy key->j32[0] = cpu_to_le32(inum); 1911e51764aSArtem Bityutskiy key->j32[1] = cpu_to_le32(hash | 1921e51764aSArtem Bityutskiy (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS)); 1931e51764aSArtem Bityutskiy memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); 1941e51764aSArtem Bityutskiy } 1951e51764aSArtem Bityutskiy 1961e51764aSArtem Bityutskiy /** 1971e51764aSArtem Bityutskiy * lowest_dent_key - get the lowest possible directory entry key. 1981e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 1991e51764aSArtem Bityutskiy * @key: where to store the lowest key 2001e51764aSArtem Bityutskiy * @inum: parent inode number 2011e51764aSArtem Bityutskiy */ 2021e51764aSArtem Bityutskiy static inline void lowest_dent_key(const struct ubifs_info *c, 2031e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum) 2041e51764aSArtem Bityutskiy { 2051e51764aSArtem Bityutskiy key->u32[0] = inum; 2061e51764aSArtem Bityutskiy key->u32[1] = UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS; 2071e51764aSArtem Bityutskiy } 2081e51764aSArtem Bityutskiy 2091e51764aSArtem Bityutskiy /** 2101e51764aSArtem Bityutskiy * xent_key_init - initialize extended attribute entry key. 2111e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2121e51764aSArtem Bityutskiy * @key: key to initialize 2131e51764aSArtem Bityutskiy * @inum: host inode number 2141e51764aSArtem Bityutskiy * @nm: extended attribute entry name and length 2151e51764aSArtem Bityutskiy */ 2161e51764aSArtem Bityutskiy static inline void xent_key_init(const struct ubifs_info *c, 2171e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum, 218f4f61d2cSRichard Weinberger const struct fscrypt_name *nm) 2191e51764aSArtem Bityutskiy { 220f4f61d2cSRichard Weinberger uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); 2211e51764aSArtem Bityutskiy 2226eb61d58SRichard Weinberger ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); 2231e51764aSArtem Bityutskiy key->u32[0] = inum; 2241e51764aSArtem Bityutskiy key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); 2251e51764aSArtem Bityutskiy } 2261e51764aSArtem Bityutskiy 2271e51764aSArtem Bityutskiy /** 2281e51764aSArtem Bityutskiy * xent_key_init_flash - initialize on-flash extended attribute entry key. 2291e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2301e51764aSArtem Bityutskiy * @k: key to initialize 2311e51764aSArtem Bityutskiy * @inum: host inode number 2321e51764aSArtem Bityutskiy * @nm: extended attribute entry name and length 2331e51764aSArtem Bityutskiy */ 2341e51764aSArtem Bityutskiy static inline void xent_key_init_flash(const struct ubifs_info *c, void *k, 235f4f61d2cSRichard Weinberger ino_t inum, const struct fscrypt_name *nm) 2361e51764aSArtem Bityutskiy { 2371e51764aSArtem Bityutskiy union ubifs_key *key = k; 238f4f61d2cSRichard Weinberger uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); 2391e51764aSArtem Bityutskiy 2406eb61d58SRichard Weinberger ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); 2411e51764aSArtem Bityutskiy key->j32[0] = cpu_to_le32(inum); 2421e51764aSArtem Bityutskiy key->j32[1] = cpu_to_le32(hash | 2431e51764aSArtem Bityutskiy (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS)); 2441e51764aSArtem Bityutskiy memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); 2451e51764aSArtem Bityutskiy } 2461e51764aSArtem Bityutskiy 2471e51764aSArtem Bityutskiy /** 2481e51764aSArtem Bityutskiy * lowest_xent_key - get the lowest possible extended attribute entry key. 2491e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2501e51764aSArtem Bityutskiy * @key: where to store the lowest key 2511e51764aSArtem Bityutskiy * @inum: host inode number 2521e51764aSArtem Bityutskiy */ 2531e51764aSArtem Bityutskiy static inline void lowest_xent_key(const struct ubifs_info *c, 2541e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum) 2551e51764aSArtem Bityutskiy { 2561e51764aSArtem Bityutskiy key->u32[0] = inum; 2571e51764aSArtem Bityutskiy key->u32[1] = UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS; 2581e51764aSArtem Bityutskiy } 2591e51764aSArtem Bityutskiy 2601e51764aSArtem Bityutskiy /** 2611e51764aSArtem Bityutskiy * data_key_init - initialize data key. 2621e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2631e51764aSArtem Bityutskiy * @key: key to initialize 2641e51764aSArtem Bityutskiy * @inum: inode number 2651e51764aSArtem Bityutskiy * @block: block number 2661e51764aSArtem Bityutskiy */ 2671e51764aSArtem Bityutskiy static inline void data_key_init(const struct ubifs_info *c, 2681e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum, 2691e51764aSArtem Bityutskiy unsigned int block) 2701e51764aSArtem Bityutskiy { 2716eb61d58SRichard Weinberger ubifs_assert(c, !(block & ~UBIFS_S_KEY_BLOCK_MASK)); 2721e51764aSArtem Bityutskiy key->u32[0] = inum; 2731e51764aSArtem Bityutskiy key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS); 2741e51764aSArtem Bityutskiy } 2751e51764aSArtem Bityutskiy 2761e51764aSArtem Bityutskiy /** 277e3c3efc2SArtem Bityutskiy * highest_data_key - get the highest possible data key for an inode. 278e3c3efc2SArtem Bityutskiy * @c: UBIFS file-system description object 279e3c3efc2SArtem Bityutskiy * @key: key to initialize 280e3c3efc2SArtem Bityutskiy * @inum: inode number 281e3c3efc2SArtem Bityutskiy */ 282e3c3efc2SArtem Bityutskiy static inline void highest_data_key(const struct ubifs_info *c, 283e3c3efc2SArtem Bityutskiy union ubifs_key *key, ino_t inum) 284e3c3efc2SArtem Bityutskiy { 285e3c3efc2SArtem Bityutskiy data_key_init(c, key, inum, UBIFS_S_KEY_BLOCK_MASK); 286e3c3efc2SArtem Bityutskiy } 287e3c3efc2SArtem Bityutskiy 288e3c3efc2SArtem Bityutskiy /** 2891e51764aSArtem Bityutskiy * trun_key_init - initialize truncation node key. 2901e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 2911e51764aSArtem Bityutskiy * @key: key to initialize 2921e51764aSArtem Bityutskiy * @inum: inode number 2931e51764aSArtem Bityutskiy * 2941e51764aSArtem Bityutskiy * Note, UBIFS does not have truncation keys on the media and this function is 2951e51764aSArtem Bityutskiy * only used for purposes of replay. 2961e51764aSArtem Bityutskiy */ 2971e51764aSArtem Bityutskiy static inline void trun_key_init(const struct ubifs_info *c, 2981e51764aSArtem Bityutskiy union ubifs_key *key, ino_t inum) 2991e51764aSArtem Bityutskiy { 3001e51764aSArtem Bityutskiy key->u32[0] = inum; 3011e51764aSArtem Bityutskiy key->u32[1] = UBIFS_TRUN_KEY << UBIFS_S_KEY_BLOCK_BITS; 3021e51764aSArtem Bityutskiy } 3031e51764aSArtem Bityutskiy 3041e51764aSArtem Bityutskiy /** 305ba2f48f7SArtem Bityutskiy * invalid_key_init - initialize invalid node key. 306ba2f48f7SArtem Bityutskiy * @c: UBIFS file-system description object 307ba2f48f7SArtem Bityutskiy * @key: key to initialize 308ba2f48f7SArtem Bityutskiy * 309ba2f48f7SArtem Bityutskiy * This is a helper function which marks a @key object as invalid. 310ba2f48f7SArtem Bityutskiy */ 311ba2f48f7SArtem Bityutskiy static inline void invalid_key_init(const struct ubifs_info *c, 312ba2f48f7SArtem Bityutskiy union ubifs_key *key) 313ba2f48f7SArtem Bityutskiy { 314ba2f48f7SArtem Bityutskiy key->u32[0] = 0xDEADBEAF; 315ba2f48f7SArtem Bityutskiy key->u32[1] = UBIFS_INVALID_KEY; 316ba2f48f7SArtem Bityutskiy } 317ba2f48f7SArtem Bityutskiy 318ba2f48f7SArtem Bityutskiy /** 3191e51764aSArtem Bityutskiy * key_type - get key type. 3201e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3211e51764aSArtem Bityutskiy * @key: key to get type of 3221e51764aSArtem Bityutskiy */ 3231e51764aSArtem Bityutskiy static inline int key_type(const struct ubifs_info *c, 3241e51764aSArtem Bityutskiy const union ubifs_key *key) 3251e51764aSArtem Bityutskiy { 3261e51764aSArtem Bityutskiy return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS; 3271e51764aSArtem Bityutskiy } 3281e51764aSArtem Bityutskiy 3291e51764aSArtem Bityutskiy /** 3301e51764aSArtem Bityutskiy * key_type_flash - get type of a on-flash formatted key. 3311e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3321e51764aSArtem Bityutskiy * @k: key to get type of 3331e51764aSArtem Bityutskiy */ 3341e51764aSArtem Bityutskiy static inline int key_type_flash(const struct ubifs_info *c, const void *k) 3351e51764aSArtem Bityutskiy { 3361e51764aSArtem Bityutskiy const union ubifs_key *key = k; 3371e51764aSArtem Bityutskiy 3380ecb9529SHarvey Harrison return le32_to_cpu(key->j32[1]) >> UBIFS_S_KEY_BLOCK_BITS; 3391e51764aSArtem Bityutskiy } 3401e51764aSArtem Bityutskiy 3411e51764aSArtem Bityutskiy /** 3421e51764aSArtem Bityutskiy * key_inum - fetch inode number from key. 3431e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3441e51764aSArtem Bityutskiy * @k: key to fetch inode number from 3451e51764aSArtem Bityutskiy */ 3461e51764aSArtem Bityutskiy static inline ino_t key_inum(const struct ubifs_info *c, const void *k) 3471e51764aSArtem Bityutskiy { 3481e51764aSArtem Bityutskiy const union ubifs_key *key = k; 3491e51764aSArtem Bityutskiy 3501e51764aSArtem Bityutskiy return key->u32[0]; 3511e51764aSArtem Bityutskiy } 3521e51764aSArtem Bityutskiy 3531e51764aSArtem Bityutskiy /** 3541e51764aSArtem Bityutskiy * key_inum_flash - fetch inode number from an on-flash formatted key. 3551e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3561e51764aSArtem Bityutskiy * @k: key to fetch inode number from 3571e51764aSArtem Bityutskiy */ 3581e51764aSArtem Bityutskiy static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k) 3591e51764aSArtem Bityutskiy { 3601e51764aSArtem Bityutskiy const union ubifs_key *key = k; 3611e51764aSArtem Bityutskiy 3621e51764aSArtem Bityutskiy return le32_to_cpu(key->j32[0]); 3631e51764aSArtem Bityutskiy } 3641e51764aSArtem Bityutskiy 3651e51764aSArtem Bityutskiy /** 3661e51764aSArtem Bityutskiy * key_hash - get directory entry hash. 3671e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3681e51764aSArtem Bityutskiy * @key: the key to get hash from 3691e51764aSArtem Bityutskiy */ 370cb4f952dSArtem Bityutskiy static inline uint32_t key_hash(const struct ubifs_info *c, 3711e51764aSArtem Bityutskiy const union ubifs_key *key) 3721e51764aSArtem Bityutskiy { 3731e51764aSArtem Bityutskiy return key->u32[1] & UBIFS_S_KEY_HASH_MASK; 3741e51764aSArtem Bityutskiy } 3751e51764aSArtem Bityutskiy 3761e51764aSArtem Bityutskiy /** 3771e51764aSArtem Bityutskiy * key_hash_flash - get directory entry hash from an on-flash formatted key. 3781e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3791e51764aSArtem Bityutskiy * @k: the key to get hash from 3801e51764aSArtem Bityutskiy */ 381cb4f952dSArtem Bityutskiy static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k) 3821e51764aSArtem Bityutskiy { 3831e51764aSArtem Bityutskiy const union ubifs_key *key = k; 3841e51764aSArtem Bityutskiy 3851e51764aSArtem Bityutskiy return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_HASH_MASK; 3861e51764aSArtem Bityutskiy } 3871e51764aSArtem Bityutskiy 3881e51764aSArtem Bityutskiy /** 3891e51764aSArtem Bityutskiy * key_block - get data block number. 3901e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 3911e51764aSArtem Bityutskiy * @key: the key to get the block number from 3921e51764aSArtem Bityutskiy */ 3931e51764aSArtem Bityutskiy static inline unsigned int key_block(const struct ubifs_info *c, 3941e51764aSArtem Bityutskiy const union ubifs_key *key) 3951e51764aSArtem Bityutskiy { 3961e51764aSArtem Bityutskiy return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK; 3971e51764aSArtem Bityutskiy } 3981e51764aSArtem Bityutskiy 3991e51764aSArtem Bityutskiy /** 4001e51764aSArtem Bityutskiy * key_block_flash - get data block number from an on-flash formatted key. 4011e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4021e51764aSArtem Bityutskiy * @k: the key to get the block number from 4031e51764aSArtem Bityutskiy */ 4041e51764aSArtem Bityutskiy static inline unsigned int key_block_flash(const struct ubifs_info *c, 4051e51764aSArtem Bityutskiy const void *k) 4061e51764aSArtem Bityutskiy { 4071e51764aSArtem Bityutskiy const union ubifs_key *key = k; 4081e51764aSArtem Bityutskiy 4090ecb9529SHarvey Harrison return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_BLOCK_MASK; 4101e51764aSArtem Bityutskiy } 4111e51764aSArtem Bityutskiy 4121e51764aSArtem Bityutskiy /** 4131e51764aSArtem Bityutskiy * key_read - transform a key to in-memory format. 4141e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4151e51764aSArtem Bityutskiy * @from: the key to transform 4161e51764aSArtem Bityutskiy * @to: the key to store the result 4171e51764aSArtem Bityutskiy */ 4181e51764aSArtem Bityutskiy static inline void key_read(const struct ubifs_info *c, const void *from, 4191e51764aSArtem Bityutskiy union ubifs_key *to) 4201e51764aSArtem Bityutskiy { 4211e51764aSArtem Bityutskiy const union ubifs_key *f = from; 4221e51764aSArtem Bityutskiy 4231e51764aSArtem Bityutskiy to->u32[0] = le32_to_cpu(f->j32[0]); 4241e51764aSArtem Bityutskiy to->u32[1] = le32_to_cpu(f->j32[1]); 4251e51764aSArtem Bityutskiy } 4261e51764aSArtem Bityutskiy 4271e51764aSArtem Bityutskiy /** 4281e51764aSArtem Bityutskiy * key_write - transform a key from in-memory format. 4291e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4301e51764aSArtem Bityutskiy * @from: the key to transform 4311e51764aSArtem Bityutskiy * @to: the key to store the result 4321e51764aSArtem Bityutskiy */ 4331e51764aSArtem Bityutskiy static inline void key_write(const struct ubifs_info *c, 4341e51764aSArtem Bityutskiy const union ubifs_key *from, void *to) 4351e51764aSArtem Bityutskiy { 4361e51764aSArtem Bityutskiy union ubifs_key *t = to; 4371e51764aSArtem Bityutskiy 4381e51764aSArtem Bityutskiy t->j32[0] = cpu_to_le32(from->u32[0]); 4391e51764aSArtem Bityutskiy t->j32[1] = cpu_to_le32(from->u32[1]); 4401e51764aSArtem Bityutskiy memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8); 4411e51764aSArtem Bityutskiy } 4421e51764aSArtem Bityutskiy 4431e51764aSArtem Bityutskiy /** 4441e51764aSArtem Bityutskiy * key_write_idx - transform a key from in-memory format for the index. 4451e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4461e51764aSArtem Bityutskiy * @from: the key to transform 4471e51764aSArtem Bityutskiy * @to: the key to store the result 4481e51764aSArtem Bityutskiy */ 4491e51764aSArtem Bityutskiy static inline void key_write_idx(const struct ubifs_info *c, 4501e51764aSArtem Bityutskiy const union ubifs_key *from, void *to) 4511e51764aSArtem Bityutskiy { 4521e51764aSArtem Bityutskiy union ubifs_key *t = to; 4531e51764aSArtem Bityutskiy 4541e51764aSArtem Bityutskiy t->j32[0] = cpu_to_le32(from->u32[0]); 4551e51764aSArtem Bityutskiy t->j32[1] = cpu_to_le32(from->u32[1]); 4561e51764aSArtem Bityutskiy } 4571e51764aSArtem Bityutskiy 4581e51764aSArtem Bityutskiy /** 4591e51764aSArtem Bityutskiy * key_copy - copy a key. 4601e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4611e51764aSArtem Bityutskiy * @from: the key to copy from 4621e51764aSArtem Bityutskiy * @to: the key to copy to 4631e51764aSArtem Bityutskiy */ 4641e51764aSArtem Bityutskiy static inline void key_copy(const struct ubifs_info *c, 4651e51764aSArtem Bityutskiy const union ubifs_key *from, union ubifs_key *to) 4661e51764aSArtem Bityutskiy { 4671e51764aSArtem Bityutskiy to->u64[0] = from->u64[0]; 4681e51764aSArtem Bityutskiy } 4691e51764aSArtem Bityutskiy 4701e51764aSArtem Bityutskiy /** 4711e51764aSArtem Bityutskiy * keys_cmp - compare keys. 4721e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 4731e51764aSArtem Bityutskiy * @key1: the first key to compare 4741e51764aSArtem Bityutskiy * @key2: the second key to compare 4751e51764aSArtem Bityutskiy * 4761e51764aSArtem Bityutskiy * This function compares 2 keys and returns %-1 if @key1 is less than 4774793e7c5SAdrian Hunter * @key2, %0 if the keys are equivalent and %1 if @key1 is greater than @key2. 4781e51764aSArtem Bityutskiy */ 4791e51764aSArtem Bityutskiy static inline int keys_cmp(const struct ubifs_info *c, 4801e51764aSArtem Bityutskiy const union ubifs_key *key1, 4811e51764aSArtem Bityutskiy const union ubifs_key *key2) 4821e51764aSArtem Bityutskiy { 4831e51764aSArtem Bityutskiy if (key1->u32[0] < key2->u32[0]) 4841e51764aSArtem Bityutskiy return -1; 4851e51764aSArtem Bityutskiy if (key1->u32[0] > key2->u32[0]) 4861e51764aSArtem Bityutskiy return 1; 4871e51764aSArtem Bityutskiy if (key1->u32[1] < key2->u32[1]) 4881e51764aSArtem Bityutskiy return -1; 4891e51764aSArtem Bityutskiy if (key1->u32[1] > key2->u32[1]) 4901e51764aSArtem Bityutskiy return 1; 4911e51764aSArtem Bityutskiy 4921e51764aSArtem Bityutskiy return 0; 4931e51764aSArtem Bityutskiy } 4941e51764aSArtem Bityutskiy 4951e51764aSArtem Bityutskiy /** 4964793e7c5SAdrian Hunter * keys_eq - determine if keys are equivalent. 4974793e7c5SAdrian Hunter * @c: UBIFS file-system description object 4984793e7c5SAdrian Hunter * @key1: the first key to compare 4994793e7c5SAdrian Hunter * @key2: the second key to compare 5004793e7c5SAdrian Hunter * 5014793e7c5SAdrian Hunter * This function compares 2 keys and returns %1 if @key1 is equal to @key2 and 5024793e7c5SAdrian Hunter * %0 if not. 5034793e7c5SAdrian Hunter */ 5044793e7c5SAdrian Hunter static inline int keys_eq(const struct ubifs_info *c, 5054793e7c5SAdrian Hunter const union ubifs_key *key1, 5064793e7c5SAdrian Hunter const union ubifs_key *key2) 5074793e7c5SAdrian Hunter { 5084793e7c5SAdrian Hunter if (key1->u32[0] != key2->u32[0]) 5094793e7c5SAdrian Hunter return 0; 5104793e7c5SAdrian Hunter if (key1->u32[1] != key2->u32[1]) 5114793e7c5SAdrian Hunter return 0; 5124793e7c5SAdrian Hunter return 1; 5134793e7c5SAdrian Hunter } 5144793e7c5SAdrian Hunter 5154793e7c5SAdrian Hunter /** 5161e51764aSArtem Bityutskiy * is_hash_key - is a key vulnerable to hash collisions. 5171e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 5181e51764aSArtem Bityutskiy * @key: key 5191e51764aSArtem Bityutskiy * 5201e51764aSArtem Bityutskiy * This function returns %1 if @key is a hashed key or %0 otherwise. 5211e51764aSArtem Bityutskiy */ 5221e51764aSArtem Bityutskiy static inline int is_hash_key(const struct ubifs_info *c, 5231e51764aSArtem Bityutskiy const union ubifs_key *key) 5241e51764aSArtem Bityutskiy { 5251e51764aSArtem Bityutskiy int type = key_type(c, key); 5261e51764aSArtem Bityutskiy 5271e51764aSArtem Bityutskiy return type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY; 5281e51764aSArtem Bityutskiy } 5291e51764aSArtem Bityutskiy 5301e51764aSArtem Bityutskiy /** 5311e51764aSArtem Bityutskiy * key_max_inode_size - get maximum file size allowed by current key format. 5321e51764aSArtem Bityutskiy * @c: UBIFS file-system description object 5331e51764aSArtem Bityutskiy */ 5341e51764aSArtem Bityutskiy static inline unsigned long long key_max_inode_size(const struct ubifs_info *c) 5351e51764aSArtem Bityutskiy { 5361e51764aSArtem Bityutskiy switch (c->key_fmt) { 5371e51764aSArtem Bityutskiy case UBIFS_SIMPLE_KEY_FMT: 5381e51764aSArtem Bityutskiy return (1ULL << UBIFS_S_KEY_BLOCK_BITS) * UBIFS_BLOCK_SIZE; 5391e51764aSArtem Bityutskiy default: 5401e51764aSArtem Bityutskiy return 0; 5411e51764aSArtem Bityutskiy } 5421e51764aSArtem Bityutskiy } 543e3c3efc2SArtem Bityutskiy 5441e51764aSArtem Bityutskiy #endif /* !__UBIFS_KEY_H__ */ 545