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