Rev 2884 | Rev 2890 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2884 | Rev 2889 | ||
---|---|---|---|
Line 68... | Line 68... | ||
68 | link_t freed_head; |
68 | link_t freed_head; |
69 | } unused_t; |
69 | } unused_t; |
70 | 70 | ||
71 | static LIST_INITIALIZE(unused_head); |
71 | static LIST_INITIALIZE(unused_head); |
72 | 72 | ||
- | 73 | /** Global hash table of all used fat_idx_t structures. */ |
|
- | 74 | static hash_table_t used_hash; |
|
- | 75 | ||
- | 76 | #define USED_HASH_BUCKETS_LOG 12 |
|
- | 77 | #define USED_HASH_BUCKETS (1 << USED_HASH_BUCKETS_LOG) |
|
- | 78 | ||
- | 79 | #define USED_HASH_DH_KEY 0 |
|
- | 80 | #define USED_HASH_PFC_KEY 1 |
|
- | 81 | #define USED_HASH_PDI_KEY 2 |
|
- | 82 | ||
- | 83 | static hash_index_t idx_hash(unsigned long key[]) |
|
- | 84 | { |
|
- | 85 | dev_handle_t dev_handle = (dev_handle_t)key[USED_HASH_DH_KEY]; |
|
- | 86 | fat_cluster_t pfc = (fat_cluster_t)key[USED_HASH_PFC_KEY]; |
|
- | 87 | unsigned pdi = (unsigned)key[USED_HASH_PDI_KEY]; |
|
- | 88 | ||
- | 89 | hash_index_t h; |
|
- | 90 | ||
- | 91 | /* |
|
- | 92 | * The least significant half of all bits are the least significant bits |
|
- | 93 | * of the parent node's first cluster. |
|
- | 94 | * |
|
- | 95 | * The least significant half of the most significant half of all bits |
|
- | 96 | * are the least significant bits of the node's dentry index within the |
|
- | 97 | * parent directory node. |
|
- | 98 | * |
|
- | 99 | * The most significant half of the most significant half of all bits |
|
- | 100 | * are the least significant bits of the device handle. |
|
- | 101 | */ |
|
- | 102 | h = pfc & ((USED_HASH_BUCKETS_LOG / 2) - 1); |
|
- | 103 | h |= (pdi & ((USED_HASH_BUCKETS_LOG / 4) - 1)) << |
|
- | 104 | (USED_HASH_BUCKETS_LOG / 2); |
|
- | 105 | h |= (dev_handle & ((USED_HASH_BUCKETS_LOG / 4) - 1)) << |
|
- | 106 | (3 * (USED_HASH_BUCKETS_LOG / 4)); |
|
- | 107 | ||
- | 108 | return h; |
|
- | 109 | } |
|
- | 110 | ||
- | 111 | static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) |
|
- | 112 | { |
|
- | 113 | dev_handle_t dev_handle = (dev_handle_t)key[USED_HASH_DH_KEY]; |
|
- | 114 | fat_cluster_t pfc = (fat_cluster_t)key[USED_HASH_PFC_KEY]; |
|
- | 115 | unsigned pdi = (unsigned)key[USED_HASH_PDI_KEY]; |
|
- | 116 | fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uh_link); |
|
- | 117 | ||
- | 118 | return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) && |
|
- | 119 | (pdi == fidx->pdi); |
|
- | 120 | } |
|
- | 121 | ||
- | 122 | static void idx_remove_callback(link_t *item) |
|
- | 123 | { |
|
- | 124 | /* nothing to do */ |
|
- | 125 | } |
|
- | 126 | ||
- | 127 | static hash_table_operations_t used_idx_ops = { |
|
- | 128 | .hash = idx_hash, |
|
- | 129 | .compare = idx_compare, |
|
- | 130 | .remove_callback = idx_remove_callback, |
|
- | 131 | }; |
|
- | 132 | ||
73 | /** Allocate a VFS index which is not currently in use. */ |
133 | /** Allocate a VFS index which is not currently in use. */ |
74 | static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
134 | static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
75 | { |
135 | { |
76 | link_t *l; |
136 | link_t *l; |
77 | unused_t *u; |
137 | unused_t *u; |
Line 204... | Line 264... | ||
204 | } |
264 | } |
205 | } |
265 | } |
206 | 266 | ||
207 | fat_idx_t *fat_idx_map(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi) |
267 | fat_idx_t *fat_idx_map(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi) |
208 | { |
268 | { |
- | 269 | fat_idx_t *fidx; |
|
- | 270 | link_t *l; |
|
- | 271 | unsigned long key[] = { |
|
- | 272 | [USED_HASH_DH_KEY] = dev_handle, |
|
- | 273 | [USED_HASH_PFC_KEY] = pfc, |
|
- | 274 | [USED_HASH_PDI_KEY] = pdi, |
|
- | 275 | }; |
|
- | 276 | ||
- | 277 | l = hash_table_find(&used_hash, key); |
|
- | 278 | if (l) { |
|
- | 279 | fidx = hash_table_get_instance(l, fat_idx_t, uh_link); |
|
- | 280 | } else { |
|
- | 281 | fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); |
|
- | 282 | if (!fidx) { |
|
209 | return NULL; /* TODO */ |
283 | return NULL; |
- | 284 | } |
|
- | 285 | if (!fat_idx_alloc(dev_handle, &fidx->index)) { |
|
- | 286 | free(fidx); |
|
- | 287 | return NULL; |
|
- | 288 | } |
|
- | 289 | link_initialize(&fidx->uh_link); |
|
- | 290 | fidx->dev_handle = dev_handle; |
|
- | 291 | fidx->pfc = pfc; |
|
- | 292 | fidx->pdi = pdi; |
|
- | 293 | fidx->nodep = NULL; |
|
- | 294 | hash_table_insert(&used_hash, key, &fidx->uh_link); |
|
- | 295 | } |
|
- | 296 | ||
- | 297 | return fidx; |
|
210 | } |
298 | } |
- | 299 |