uboot/fs/ubifs/key.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * This file is part of UBIFS.
   4 *
   5 * Copyright (C) 2006-2008 Nokia Corporation.
   6 *
   7 * Authors: Artem Bityutskiy (Битюцкий Артём)
   8 *          Adrian Hunter
   9 */
  10
  11/*
  12 * This header contains various key-related definitions and helper function.
  13 * UBIFS allows several key schemes, so we access key fields only via these
  14 * helpers. At the moment only one key scheme is supported.
  15 *
  16 * Simple key scheme
  17 * ~~~~~~~~~~~~~~~~~
  18 *
  19 * Keys are 64-bits long. First 32-bits are inode number (parent inode number
  20 * in case of direntry key). Next 3 bits are node type. The last 29 bits are
  21 * 4KiB offset in case of inode node, and direntry hash in case of a direntry
  22 * node. We use "r5" hash borrowed from reiserfs.
  23 */
  24
  25#ifndef __UBIFS_KEY_H__
  26#define __UBIFS_KEY_H__
  27
  28/**
  29 * key_mask_hash - mask a valid hash value.
  30 * @val: value to be masked
  31 *
  32 * We use hash values as offset in directories, so values %0 and %1 are
  33 * reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
  34 * function makes sure the reserved values are not used.
  35 */
  36static inline uint32_t key_mask_hash(uint32_t hash)
  37{
  38        hash &= UBIFS_S_KEY_HASH_MASK;
  39        if (unlikely(hash <= 2))
  40                hash += 3;
  41        return hash;
  42}
  43
  44/**
  45 * key_r5_hash - R5 hash function (borrowed from reiserfs).
  46 * @s: direntry name
  47 * @len: name length
  48 */
  49static inline uint32_t key_r5_hash(const char *s, int len)
  50{
  51        uint32_t a = 0;
  52        const signed char *str = (const signed char *)s;
  53
  54        while (*str) {
  55                a += *str << 4;
  56                a += *str >> 4;
  57                a *= 11;
  58                str++;
  59        }
  60
  61        return key_mask_hash(a);
  62}
  63
  64/**
  65 * key_test_hash - testing hash function.
  66 * @str: direntry name
  67 * @len: name length
  68 */
  69static inline uint32_t key_test_hash(const char *str, int len)
  70{
  71        uint32_t a = 0;
  72
  73        len = min_t(uint32_t, len, 4);
  74        memcpy(&a, str, len);
  75        return key_mask_hash(a);
  76}
  77
  78/**
  79 * ino_key_init - initialize inode key.
  80 * @c: UBIFS file-system description object
  81 * @key: key to initialize
  82 * @inum: inode number
  83 */
  84static inline void ino_key_init(const struct ubifs_info *c,
  85                                union ubifs_key *key, ino_t inum)
  86{
  87        key->u32[0] = inum;
  88        key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS;
  89}
  90
  91/**
  92 * ino_key_init_flash - initialize on-flash inode key.
  93 * @c: UBIFS file-system description object
  94 * @k: key to initialize
  95 * @inum: inode number
  96 */
  97static inline void ino_key_init_flash(const struct ubifs_info *c, void *k,
  98                                      ino_t inum)
  99{
 100        union ubifs_key *key = k;
 101
 102        key->j32[0] = cpu_to_le32(inum);
 103        key->j32[1] = cpu_to_le32(UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS);
 104        memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
 105}
 106
 107/**
 108 * lowest_ino_key - get the lowest possible inode key.
 109 * @c: UBIFS file-system description object
 110 * @key: key to initialize
 111 * @inum: inode number
 112 */
 113static inline void lowest_ino_key(const struct ubifs_info *c,
 114                                union ubifs_key *key, ino_t inum)
 115{
 116        key->u32[0] = inum;
 117        key->u32[1] = 0;
 118}
 119
 120/**
 121 * highest_ino_key - get the highest possible inode key.
 122 * @c: UBIFS file-system description object
 123 * @key: key to initialize
 124 * @inum: inode number
 125 */
 126static inline void highest_ino_key(const struct ubifs_info *c,
 127                                union ubifs_key *key, ino_t inum)
 128{
 129        key->u32[0] = inum;
 130        key->u32[1] = 0xffffffff;
 131}
 132
 133/**
 134 * dent_key_init - initialize directory entry key.
 135 * @c: UBIFS file-system description object
 136 * @key: key to initialize
 137 * @inum: parent inode number
 138 * @nm: direntry name and length
 139 */
 140static inline void dent_key_init(const struct ubifs_info *c,
 141                                 union ubifs_key *key, ino_t inum,
 142                                 const struct qstr *nm)
 143{
 144        uint32_t hash = c->key_hash(nm->name, nm->len);
 145
 146        ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 147        key->u32[0] = inum;
 148        key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
 149}
 150
 151/**
 152 * dent_key_init_hash - initialize directory entry key without re-calculating
 153 *                      hash function.
 154 * @c: UBIFS file-system description object
 155 * @key: key to initialize
 156 * @inum: parent inode number
 157 * @hash: direntry name hash
 158 */
 159static inline void dent_key_init_hash(const struct ubifs_info *c,
 160                                      union ubifs_key *key, ino_t inum,
 161                                      uint32_t hash)
 162{
 163        ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 164        key->u32[0] = inum;
 165        key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
 166}
 167
 168/**
 169 * dent_key_init_flash - initialize on-flash directory entry key.
 170 * @c: UBIFS file-system description object
 171 * @k: key to initialize
 172 * @inum: parent inode number
 173 * @nm: direntry name and length
 174 */
 175static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
 176                                       ino_t inum, const struct qstr *nm)
 177{
 178        union ubifs_key *key = k;
 179        uint32_t hash = c->key_hash(nm->name, nm->len);
 180
 181        ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 182        key->j32[0] = cpu_to_le32(inum);
 183        key->j32[1] = cpu_to_le32(hash |
 184                                  (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS));
 185        memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
 186}
 187
 188/**
 189 * lowest_dent_key - get the lowest possible directory entry key.
 190 * @c: UBIFS file-system description object
 191 * @key: where to store the lowest key
 192 * @inum: parent inode number
 193 */
 194static inline void lowest_dent_key(const struct ubifs_info *c,
 195                                   union ubifs_key *key, ino_t inum)
 196{
 197        key->u32[0] = inum;
 198        key->u32[1] = UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS;
 199}
 200
 201/**
 202 * xent_key_init - initialize extended attribute entry key.
 203 * @c: UBIFS file-system description object
 204 * @key: key to initialize
 205 * @inum: host inode number
 206 * @nm: extended attribute entry name and length
 207 */
 208static inline void xent_key_init(const struct ubifs_info *c,
 209                                 union ubifs_key *key, ino_t inum,
 210                                 const struct qstr *nm)
 211{
 212        uint32_t hash = c->key_hash(nm->name, nm->len);
 213
 214        ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 215        key->u32[0] = inum;
 216        key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
 217}
 218
 219/**
 220 * xent_key_init_flash - initialize on-flash extended attribute entry key.
 221 * @c: UBIFS file-system description object
 222 * @k: key to initialize
 223 * @inum: host inode number
 224 * @nm: extended attribute entry name and length
 225 */
 226static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
 227                                       ino_t inum, const struct qstr *nm)
 228{
 229        union ubifs_key *key = k;
 230        uint32_t hash = c->key_hash(nm->name, nm->len);
 231
 232        ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 233        key->j32[0] = cpu_to_le32(inum);
 234        key->j32[1] = cpu_to_le32(hash |
 235                                  (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS));
 236        memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
 237}
 238
 239/**
 240 * lowest_xent_key - get the lowest possible extended attribute entry key.
 241 * @c: UBIFS file-system description object
 242 * @key: where to store the lowest key
 243 * @inum: host inode number
 244 */
 245static inline void lowest_xent_key(const struct ubifs_info *c,
 246                                   union ubifs_key *key, ino_t inum)
 247{
 248        key->u32[0] = inum;
 249        key->u32[1] = UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS;
 250}
 251
 252/**
 253 * data_key_init - initialize data key.
 254 * @c: UBIFS file-system description object
 255 * @key: key to initialize
 256 * @inum: inode number
 257 * @block: block number
 258 */
 259static inline void data_key_init(const struct ubifs_info *c,
 260                                 union ubifs_key *key, ino_t inum,
 261                                 unsigned int block)
 262{
 263        ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
 264        key->u32[0] = inum;
 265        key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
 266}
 267
 268/**
 269 * highest_data_key - get the highest possible data key for an inode.
 270 * @c: UBIFS file-system description object
 271 * @key: key to initialize
 272 * @inum: inode number
 273 */
 274static inline void highest_data_key(const struct ubifs_info *c,
 275                                   union ubifs_key *key, ino_t inum)
 276{
 277        data_key_init(c, key, inum, UBIFS_S_KEY_BLOCK_MASK);
 278}
 279
 280/**
 281 * trun_key_init - initialize truncation node key.
 282 * @c: UBIFS file-system description object
 283 * @key: key to initialize
 284 * @inum: inode number
 285 *
 286 * Note, UBIFS does not have truncation keys on the media and this function is
 287 * only used for purposes of replay.
 288 */
 289static inline void trun_key_init(const struct ubifs_info *c,
 290                                 union ubifs_key *key, ino_t inum)
 291{
 292        key->u32[0] = inum;
 293        key->u32[1] = UBIFS_TRUN_KEY << UBIFS_S_KEY_BLOCK_BITS;
 294}
 295
 296/**
 297 * invalid_key_init - initialize invalid node key.
 298 * @c: UBIFS file-system description object
 299 * @key: key to initialize
 300 *
 301 * This is a helper function which marks a @key object as invalid.
 302 */
 303static inline void invalid_key_init(const struct ubifs_info *c,
 304                                    union ubifs_key *key)
 305{
 306        key->u32[0] = 0xDEADBEAF;
 307        key->u32[1] = UBIFS_INVALID_KEY;
 308}
 309
 310/**
 311 * key_type - get key type.
 312 * @c: UBIFS file-system description object
 313 * @key: key to get type of
 314 */
 315static inline int key_type(const struct ubifs_info *c,
 316                           const union ubifs_key *key)
 317{
 318        return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
 319}
 320
 321/**
 322 * key_type_flash - get type of a on-flash formatted key.
 323 * @c: UBIFS file-system description object
 324 * @k: key to get type of
 325 */
 326static inline int key_type_flash(const struct ubifs_info *c, const void *k)
 327{
 328        const union ubifs_key *key = k;
 329
 330        return le32_to_cpu(key->j32[1]) >> UBIFS_S_KEY_BLOCK_BITS;
 331}
 332
 333/**
 334 * key_inum - fetch inode number from key.
 335 * @c: UBIFS file-system description object
 336 * @k: key to fetch inode number from
 337 */
 338static inline ino_t key_inum(const struct ubifs_info *c, const void *k)
 339{
 340        const union ubifs_key *key = k;
 341
 342        return key->u32[0];
 343}
 344
 345/**
 346 * key_inum_flash - fetch inode number from an on-flash formatted key.
 347 * @c: UBIFS file-system description object
 348 * @k: key to fetch inode number from
 349 */
 350static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k)
 351{
 352        const union ubifs_key *key = k;
 353
 354        return le32_to_cpu(key->j32[0]);
 355}
 356
 357/**
 358 * key_hash - get directory entry hash.
 359 * @c: UBIFS file-system description object
 360 * @key: the key to get hash from
 361 */
 362static inline uint32_t key_hash(const struct ubifs_info *c,
 363                                const union ubifs_key *key)
 364{
 365        return key->u32[1] & UBIFS_S_KEY_HASH_MASK;
 366}
 367
 368/**
 369 * key_hash_flash - get directory entry hash from an on-flash formatted key.
 370 * @c: UBIFS file-system description object
 371 * @k: the key to get hash from
 372 */
 373static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k)
 374{
 375        const union ubifs_key *key = k;
 376
 377        return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_HASH_MASK;
 378}
 379
 380/**
 381 * key_block - get data block number.
 382 * @c: UBIFS file-system description object
 383 * @key: the key to get the block number from
 384 */
 385static inline unsigned int key_block(const struct ubifs_info *c,
 386                                     const union ubifs_key *key)
 387{
 388        return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK;
 389}
 390
 391/**
 392 * key_block_flash - get data block number from an on-flash formatted key.
 393 * @c: UBIFS file-system description object
 394 * @k: the key to get the block number from
 395 */
 396static inline unsigned int key_block_flash(const struct ubifs_info *c,
 397                                           const void *k)
 398{
 399        const union ubifs_key *key = k;
 400
 401        return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_BLOCK_MASK;
 402}
 403
 404/**
 405 * key_read - transform a key to in-memory format.
 406 * @c: UBIFS file-system description object
 407 * @from: the key to transform
 408 * @to: the key to store the result
 409 */
 410static inline void key_read(const struct ubifs_info *c, const void *from,
 411                            union ubifs_key *to)
 412{
 413        const union ubifs_key *f = from;
 414
 415        to->u32[0] = le32_to_cpu(f->j32[0]);
 416        to->u32[1] = le32_to_cpu(f->j32[1]);
 417}
 418
 419/**
 420 * key_write - transform a key from in-memory format.
 421 * @c: UBIFS file-system description object
 422 * @from: the key to transform
 423 * @to: the key to store the result
 424 */
 425static inline void key_write(const struct ubifs_info *c,
 426                             const union ubifs_key *from, void *to)
 427{
 428        union ubifs_key *t = to;
 429
 430        t->j32[0] = cpu_to_le32(from->u32[0]);
 431        t->j32[1] = cpu_to_le32(from->u32[1]);
 432        memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8);
 433}
 434
 435/**
 436 * key_write_idx - transform a key from in-memory format for the index.
 437 * @c: UBIFS file-system description object
 438 * @from: the key to transform
 439 * @to: the key to store the result
 440 */
 441static inline void key_write_idx(const struct ubifs_info *c,
 442                                 const union ubifs_key *from, void *to)
 443{
 444        union ubifs_key *t = to;
 445
 446        t->j32[0] = cpu_to_le32(from->u32[0]);
 447        t->j32[1] = cpu_to_le32(from->u32[1]);
 448}
 449
 450/**
 451 * key_copy - copy a key.
 452 * @c: UBIFS file-system description object
 453 * @from: the key to copy from
 454 * @to: the key to copy to
 455 */
 456static inline void key_copy(const struct ubifs_info *c,
 457                            const union ubifs_key *from, union ubifs_key *to)
 458{
 459        to->u64[0] = from->u64[0];
 460}
 461
 462/**
 463 * keys_cmp - compare keys.
 464 * @c: UBIFS file-system description object
 465 * @key1: the first key to compare
 466 * @key2: the second key to compare
 467 *
 468 * This function compares 2 keys and returns %-1 if @key1 is less than
 469 * @key2, %0 if the keys are equivalent and %1 if @key1 is greater than @key2.
 470 */
 471static inline int keys_cmp(const struct ubifs_info *c,
 472                           const union ubifs_key *key1,
 473                           const union ubifs_key *key2)
 474{
 475        if (key1->u32[0] < key2->u32[0])
 476                return -1;
 477        if (key1->u32[0] > key2->u32[0])
 478                return 1;
 479        if (key1->u32[1] < key2->u32[1])
 480                return -1;
 481        if (key1->u32[1] > key2->u32[1])
 482                return 1;
 483
 484        return 0;
 485}
 486
 487/**
 488 * keys_eq - determine if keys are equivalent.
 489 * @c: UBIFS file-system description object
 490 * @key1: the first key to compare
 491 * @key2: the second key to compare
 492 *
 493 * This function compares 2 keys and returns %1 if @key1 is equal to @key2 and
 494 * %0 if not.
 495 */
 496static inline int keys_eq(const struct ubifs_info *c,
 497                          const union ubifs_key *key1,
 498                          const union ubifs_key *key2)
 499{
 500        if (key1->u32[0] != key2->u32[0])
 501                return 0;
 502        if (key1->u32[1] != key2->u32[1])
 503                return 0;
 504        return 1;
 505}
 506
 507/**
 508 * is_hash_key - is a key vulnerable to hash collisions.
 509 * @c: UBIFS file-system description object
 510 * @key: key
 511 *
 512 * This function returns %1 if @key is a hashed key or %0 otherwise.
 513 */
 514static inline int is_hash_key(const struct ubifs_info *c,
 515                              const union ubifs_key *key)
 516{
 517        int type = key_type(c, key);
 518
 519        return type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY;
 520}
 521
 522/**
 523 * key_max_inode_size - get maximum file size allowed by current key format.
 524 * @c: UBIFS file-system description object
 525 */
 526static inline unsigned long long key_max_inode_size(const struct ubifs_info *c)
 527{
 528        switch (c->key_fmt) {
 529        case UBIFS_SIMPLE_KEY_FMT:
 530                return (1ULL << UBIFS_S_KEY_BLOCK_BITS) * UBIFS_BLOCK_SIZE;
 531        default:
 532                return 0;
 533        }
 534}
 535
 536#endif /* !__UBIFS_KEY_H__ */
 537