source: MondoRescue/branches/3.3/mindi-busybox/libbb/inode_hash.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 2.4 KB
Line 
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 source tree.
9 */
10
11#include "libbb.h"
12
13typedef struct ino_dev_hash_bucket_struct {
14 ino_t ino;
15 dev_t dev;
16 /*
17 * Above fields can be 64-bit, while pointer may be 32-bit.
18 * Putting "next" field here may reduce size of this struct:
19 */
20 struct ino_dev_hash_bucket_struct *next;
21 /*
22 * Reportedly, on cramfs a file and a dir can have same ino.
23 * Need to also remember "file/dir" bit:
24 */
25 char isdir; /* bool */
26 char name[1];
27} ino_dev_hashtable_bucket_t;
28
29#define HASH_SIZE 311u /* Should be prime */
30#define hash_inode(i) ((unsigned)(i) % HASH_SIZE)
31
32/* array of [HASH_SIZE] elements */
33static ino_dev_hashtable_bucket_t **ino_dev_hashtable;
34
35/*
36 * Return name if statbuf->st_ino && statbuf->st_dev are recorded in
37 * ino_dev_hashtable, else return NULL
38 */
39char* FAST_FUNC is_in_ino_dev_hashtable(const struct stat *statbuf)
40{
41 ino_dev_hashtable_bucket_t *bucket;
42
43 if (!ino_dev_hashtable)
44 return NULL;
45
46 bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
47 while (bucket != NULL) {
48 if ((bucket->ino == statbuf->st_ino)
49 && (bucket->dev == statbuf->st_dev)
50 && (bucket->isdir == !!S_ISDIR(statbuf->st_mode))
51 ) {
52 return bucket->name;
53 }
54 bucket = bucket->next;
55 }
56 return NULL;
57}
58
59/* Add statbuf to statbuf hash table */
60void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
61{
62 int i;
63 ino_dev_hashtable_bucket_t *bucket;
64
65 if (!name)
66 name = "";
67 bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name));
68 bucket->ino = statbuf->st_ino;
69 bucket->dev = statbuf->st_dev;
70 bucket->isdir = !!S_ISDIR(statbuf->st_mode);
71 strcpy(bucket->name, name);
72
73 if (!ino_dev_hashtable)
74 ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable));
75
76 i = hash_inode(statbuf->st_ino);
77 bucket->next = ino_dev_hashtable[i];
78 ino_dev_hashtable[i] = bucket;
79}
80
81#if ENABLE_DU || ENABLE_FEATURE_CLEAN_UP
82/* Clear statbuf hash table */
83void FAST_FUNC reset_ino_dev_hashtable(void)
84{
85 int i;
86 ino_dev_hashtable_bucket_t *bucket, *next;
87
88 if (!ino_dev_hashtable)
89 return;
90
91 for (i = 0; i < HASH_SIZE; i++) {
92 bucket = ino_dev_hashtable[i];
93
94 while (bucket != NULL) {
95 next = bucket->next;
96 free(bucket);
97 bucket = next;
98 }
99 }
100 free(ino_dev_hashtable);
101 ino_dev_hashtable = NULL;
102}
103#endif
Note: See TracBrowser for help on using the repository browser.