inode_hash.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) many different people.
  6. * If you wrote this, please acknowledge your work.
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "libbb.h"
  14. #define HASH_SIZE 311 /* Should be prime */
  15. #define hash_inode(i) ((i) % HASH_SIZE)
  16. typedef struct ino_dev_hash_bucket_struct {
  17. struct ino_dev_hash_bucket_struct *next;
  18. ino_t ino;
  19. dev_t dev;
  20. char name[1];
  21. } ino_dev_hashtable_bucket_t;
  22. static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
  23. /*
  24. * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
  25. * `ino_dev_hashtable', else return 0
  26. *
  27. * If NAME is a non-NULL pointer to a character pointer, and there is
  28. * a match, then set *NAME to the value of the name slot in that
  29. * bucket.
  30. */
  31. int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
  32. {
  33. ino_dev_hashtable_bucket_t *bucket;
  34. bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
  35. while (bucket != NULL) {
  36. if ((bucket->ino == statbuf->st_ino) &&
  37. (bucket->dev == statbuf->st_dev))
  38. {
  39. if (name) *name = bucket->name;
  40. return 1;
  41. }
  42. bucket = bucket->next;
  43. }
  44. return 0;
  45. }
  46. /* Add statbuf to statbuf hash table */
  47. void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
  48. {
  49. int i;
  50. size_t s;
  51. ino_dev_hashtable_bucket_t *bucket;
  52. i = hash_inode(statbuf->st_ino);
  53. s = name ? strlen(name) : 0;
  54. bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s);
  55. bucket->ino = statbuf->st_ino;
  56. bucket->dev = statbuf->st_dev;
  57. if (name)
  58. strcpy(bucket->name, name);
  59. else
  60. bucket->name[0] = '\0';
  61. bucket->next = ino_dev_hashtable[i];
  62. ino_dev_hashtable[i] = bucket;
  63. }
  64. #ifdef CONFIG_FEATURE_CLEAN_UP
  65. /* Clear statbuf hash table */
  66. void reset_ino_dev_hashtable(void)
  67. {
  68. int i;
  69. ino_dev_hashtable_bucket_t *bucket;
  70. for (i = 0; i < HASH_SIZE; i++) {
  71. while (ino_dev_hashtable[i] != NULL) {
  72. bucket = ino_dev_hashtable[i]->next;
  73. free(ino_dev_hashtable[i]);
  74. ino_dev_hashtable[i] = bucket;
  75. }
  76. }
  77. }
  78. #endif