Rev 2855 | Rev 2857 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2855 | Rev 2856 | ||
---|---|---|---|
Line 44... | Line 44... | ||
44 | #include <string.h> |
44 | #include <string.h> |
45 | #include <byteorder.h> |
45 | #include <byteorder.h> |
46 | #include <libadt/hash_table.h> |
46 | #include <libadt/hash_table.h> |
47 | #include <libadt/list.h> |
47 | #include <libadt/list.h> |
48 | #include <assert.h> |
48 | #include <assert.h> |
- | 49 | #include <futex.h> |
|
49 | 50 | ||
50 | #define BS_BLOCK 0 |
51 | #define BS_BLOCK 0 |
51 | 52 | ||
52 | #define FIN_KEY_DEV_HANDLE 0 |
53 | #define FIN_KEY_DEV_HANDLE 0 |
53 | #define FIN_KEY_INDEX 1 |
54 | #define FIN_KEY_INDEX 1 |
54 | 55 | ||
- | 56 | /** Futex protecting both fin_hash and ffn_head. */ |
|
- | 57 | futex_t fin_futex = FUTEX_INITIALIZER; |
|
- | 58 | ||
55 | /** Hash table of FAT in-core nodes. */ |
59 | /** Hash table of FAT in-core nodes. */ |
56 | hash_table_t fin_hash; |
60 | hash_table_t fin_hash; |
57 | 61 | ||
58 | /** List of free FAT in-core nodes. */ |
62 | /** List of free FAT in-core nodes. */ |
59 | link_t ffn_head; |
63 | link_t ffn_head; |
Line 116... | Line 120... | ||
116 | /* TODO */ |
120 | /* TODO */ |
117 | } |
121 | } |
118 | 122 | ||
119 | static void fat_node_initialize(fat_node_t *node) |
123 | static void fat_node_initialize(fat_node_t *node) |
120 | { |
124 | { |
- | 125 | futex_initialize(&node->lock, 1); |
|
121 | node->type = 0; |
126 | node->type = 0; |
122 | node->index = 0; |
127 | node->index = 0; |
123 | node->pindex = 0; |
128 | node->pindex = 0; |
124 | node->dev_handle = 0; |
129 | node->dev_handle = 0; |
125 | link_initialize(&node->fin_link); |
130 | link_initialize(&node->fin_link); |
Line 198... | Line 203... | ||
198 | unsigned long key[] = { |
203 | unsigned long key[] = { |
199 | [FIN_KEY_DEV_HANDLE] = dev_handle, |
204 | [FIN_KEY_DEV_HANDLE] = dev_handle, |
200 | [FIN_KEY_INDEX] = index |
205 | [FIN_KEY_INDEX] = index |
201 | }; |
206 | }; |
202 | 207 | ||
- | 208 | futex_down(&fin_futex); |
|
203 | lnk = hash_table_find(&fin_hash, key); |
209 | lnk = hash_table_find(&fin_hash, key); |
204 | if (lnk) { |
210 | if (lnk) { |
205 | /* |
211 | /* |
206 | * The in-core node was found in the hash table. |
212 | * The in-core node was found in the hash table. |
207 | */ |
213 | */ |
208 | node = hash_table_get_instance(lnk, fat_node_t, fin_link); |
214 | node = hash_table_get_instance(lnk, fat_node_t, fin_link); |
209 | if (!node->refcnt++) |
215 | if (!node->refcnt++) |
210 | list_remove(&node->ffn_link); |
216 | list_remove(&node->ffn_link); |
- | 217 | futex_up(&fin_futex); |
|
- | 218 | ||
- | 219 | /* Make sure that the node is fully instantiated. */ |
|
- | 220 | futex_down(&node->lock); |
|
- | 221 | futex_up(&node->lock); |
|
- | 222 | ||
211 | return (void *) node; |
223 | return (void *) node; |
212 | } |
224 | } |
213 | 225 | ||
214 | bps = fat_bps_get(dev_handle); |
226 | bps = fat_bps_get(dev_handle); |
215 | dps = bps / sizeof(fat_dentry_t); |
227 | dps = bps / sizeof(fat_dentry_t); |
Line 239... | Line 251... | ||
239 | node->refcnt++; |
251 | node->refcnt++; |
240 | node->lnkcnt++; |
252 | node->lnkcnt++; |
241 | node->dev_handle = dev_handle; |
253 | node->dev_handle = dev_handle; |
242 | node->index = index; |
254 | node->index = index; |
243 | node->pindex = pindex; |
255 | node->pindex = pindex; |
- | 256 | key[FIN_KEY_DEV_HANDLE] = node->dev_handle; |
|
- | 257 | key[FIN_KEY_INDEX] = node->index; |
|
- | 258 | hash_table_insert(&fin_hash, key, &node->fin_link); |
|
- | 259 | ||
- | 260 | /* |
|
- | 261 | * We have already put the node back to fin_hash. |
|
- | 262 | * The node is not yet fully instantiated so we lock it prior to |
|
- | 263 | * unlocking fin_hash. |
|
- | 264 | */ |
|
- | 265 | futex_down(&node->lock); |
|
- | 266 | futex_up(&fin_futex); |
|
244 | 267 | ||
245 | /* |
268 | /* |
246 | * Because of the design of the FAT file system, we have no clue about |
269 | * Because of the design of the FAT file system, we have no clue about |
247 | * how big (i.e. how many directory entries it contains) is the parent |
270 | * how big (i.e. how many directory entries it contains) is the parent |
248 | * of the node we are trying to instantiate. However, we know that it |
271 | * of the node we are trying to instantiate. However, we know that it |
Line 266... | Line 289... | ||
266 | node->type = FAT_DIRECTORY; |
289 | node->type = FAT_DIRECTORY; |
267 | assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY)); |
290 | assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY)); |
268 | 291 | ||
269 | node->size = uint32_t_le2host(d->size); |
292 | node->size = uint32_t_le2host(d->size); |
270 | block_put(b); |
293 | block_put(b); |
271 | - | ||
272 | key[FIN_KEY_DEV_HANDLE] = node->dev_handle; |
- | |
273 | key[FIN_KEY_INDEX] = node->index; |
- | |
274 | hash_table_insert(&fin_hash, key, &node->fin_link); |
- | |
275 | 294 | ||
- | 295 | futex_up(&node->lock); |
|
276 | return node; |
296 | return node; |
277 | } |
297 | } |
278 | 298 | ||
279 | static void fat_node_put(void *node) |
299 | static void fat_node_put(void *node) |
280 | { |
300 | { |
281 | fat_node_t *nodep = (fat_node_t *)node; |
301 | fat_node_t *nodep = (fat_node_t *)node; |
282 | 302 | ||
- | 303 | futex_down(&fin_futex); |
|
283 | if (nodep->refcnt-- == 1) |
304 | if (!--nodep->refcnt) |
284 | list_append(&nodep->ffn_link, &ffn_head); |
305 | list_append(&nodep->ffn_link, &ffn_head); |
- | 306 | futex_up(&fin_futex); |
|
285 | } |
307 | } |
286 | 308 | ||
287 | static void *fat_match(void *prnt, const char *component) |
309 | static void *fat_match(void *prnt, const char *component) |
288 | { |
310 | { |
289 | fat_node_t *parentp = (fat_node_t *)prnt; |
311 | fat_node_t *parentp = (fat_node_t *)prnt; |