Rev 4306 | Rev 4370 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4306 | Rev 4357 | ||
|---|---|---|---|
| Line 66... | Line 66... | ||
| 66 | /* |
66 | /* |
| 67 | * Implementation of the libfs interface. |
67 | * Implementation of the libfs interface. |
| 68 | */ |
68 | */ |
| 69 | 69 | ||
| 70 | /* Forward declarations of static functions. */ |
70 | /* Forward declarations of static functions. */ |
| 71 | static void *tmpfs_match(void *, const char *); |
71 | static fs_node_t *tmpfs_match(fs_node_t *, const char *); |
| 72 | static void *tmpfs_node_get(dev_handle_t, fs_index_t); |
72 | static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t); |
| 73 | static void tmpfs_node_put(void *); |
73 | static void tmpfs_node_put(fs_node_t *); |
| 74 | static void *tmpfs_create_node(dev_handle_t, int); |
74 | static fs_node_t *tmpfs_create_node(dev_handle_t, int); |
| 75 | static int tmpfs_link_node(void *, void *, const char *); |
75 | static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *); |
| 76 | static int tmpfs_unlink_node(void *, void *); |
76 | static int tmpfs_unlink_node(fs_node_t *, fs_node_t *); |
| 77 | static int tmpfs_destroy_node(void *); |
77 | static int tmpfs_destroy_node(fs_node_t *); |
| 78 | 78 | ||
| 79 | /* Implementation of helper functions. */ |
79 | /* Implementation of helper functions. */ |
| 80 | static fs_index_t tmpfs_index_get(void *nodep) |
80 | static fs_index_t tmpfs_index_get(fs_node_t *fn) |
| 81 | { |
81 | { |
| 82 | return ((tmpfs_dentry_t *) nodep)->index; |
82 | return TMPFS_NODE(fn)->index; |
| 83 | } |
83 | } |
| 84 | 84 | ||
| 85 | static size_t tmpfs_size_get(void *nodep) |
85 | static size_t tmpfs_size_get(fs_node_t *fn) |
| 86 | { |
86 | { |
| 87 | return ((tmpfs_dentry_t *) nodep)->size; |
87 | return TMPFS_NODE(fn)->size; |
| 88 | } |
88 | } |
| 89 | 89 | ||
| 90 | static unsigned tmpfs_lnkcnt_get(void *nodep) |
90 | static unsigned tmpfs_lnkcnt_get(fs_node_t *fn) |
| 91 | { |
91 | { |
| 92 | return ((tmpfs_dentry_t *) nodep)->lnkcnt; |
92 | return TMPFS_NODE(fn)->lnkcnt; |
| 93 | } |
93 | } |
| 94 | 94 | ||
| 95 | static bool tmpfs_has_children(void *nodep) |
95 | static bool tmpfs_has_children(fs_node_t *fn) |
| 96 | { |
96 | { |
| 97 | return ((tmpfs_dentry_t *) nodep)->child != NULL; |
97 | return TMPFS_NODE(fn)->child != NULL; |
| 98 | } |
98 | } |
| 99 | 99 | ||
| 100 | static void *tmpfs_root_get(dev_handle_t dev_handle) |
100 | static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle) |
| 101 | { |
101 | { |
| 102 | return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT); |
102 | return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT); |
| 103 | } |
103 | } |
| 104 | 104 | ||
| 105 | static char tmpfs_plb_get_char(unsigned pos) |
105 | static char tmpfs_plb_get_char(unsigned pos) |
| 106 | { |
106 | { |
| 107 | return tmpfs_reg.plb_ro[pos % PLB_SIZE]; |
107 | return tmpfs_reg.plb_ro[pos % PLB_SIZE]; |
| 108 | } |
108 | } |
| 109 | 109 | ||
| 110 | static bool tmpfs_is_directory(void *nodep) |
110 | static bool tmpfs_is_directory(fs_node_t *fn) |
| 111 | { |
111 | { |
| 112 | return ((tmpfs_dentry_t *) nodep)->type == TMPFS_DIRECTORY; |
112 | return TMPFS_NODE(fn)->type == TMPFS_DIRECTORY; |
| 113 | } |
113 | } |
| 114 | 114 | ||
| 115 | static bool tmpfs_is_file(void *nodep) |
115 | static bool tmpfs_is_file(fs_node_t *fn) |
| 116 | { |
116 | { |
| 117 | return ((tmpfs_dentry_t *) nodep)->type == TMPFS_FILE; |
117 | return TMPFS_NODE(fn)->type == TMPFS_FILE; |
| 118 | } |
118 | } |
| 119 | 119 | ||
| 120 | /** libfs operations */ |
120 | /** libfs operations */ |
| 121 | libfs_ops_t tmpfs_libfs_ops = { |
121 | libfs_ops_t tmpfs_libfs_ops = { |
| 122 | .match = tmpfs_match, |
122 | .match = tmpfs_match, |
| Line 211... | Line 211... | ||
| 211 | link_initialize(&namep->link); |
211 | link_initialize(&namep->link); |
| 212 | } |
212 | } |
| 213 | 213 | ||
| 214 | static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry) |
214 | static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry) |
| 215 | { |
215 | { |
| - | 216 | dentry->bp = NULL; |
|
| 216 | dentry->index = 0; |
217 | dentry->index = 0; |
| 217 | dentry->dev_handle = 0; |
218 | dentry->dev_handle = 0; |
| 218 | dentry->sibling = NULL; |
219 | dentry->sibling = NULL; |
| 219 | dentry->child = NULL; |
220 | dentry->child = NULL; |
| 220 | dentry->type = TMPFS_NONE; |
221 | dentry->type = TMPFS_NONE; |
| Line 234... | Line 235... | ||
| 234 | return true; |
235 | return true; |
| 235 | } |
236 | } |
| 236 | 237 | ||
| 237 | static bool tmpfs_instance_init(dev_handle_t dev_handle) |
238 | static bool tmpfs_instance_init(dev_handle_t dev_handle) |
| 238 | { |
239 | { |
| 239 | tmpfs_dentry_t *root; |
240 | fs_node_t *rfn; |
| 240 | 241 | ||
| 241 | root = (tmpfs_dentry_t *) tmpfs_create_node(dev_handle, L_DIRECTORY); |
242 | rfn = tmpfs_create_node(dev_handle, L_DIRECTORY); |
| 242 | if (!root) |
243 | if (!rfn) |
| 243 | return false; |
244 | return false; |
| 244 | root->lnkcnt = 0; /* FS root is not linked */ |
245 | TMPFS_NODE(rfn)->lnkcnt = 0; /* FS root is not linked */ |
| 245 | return true; |
246 | return true; |
| 246 | } |
247 | } |
| 247 | 248 | ||
| 248 | /** Compare one component of path to a directory entry. |
249 | /** Compare one component of path to a directory entry. |
| 249 | * |
250 | * |
| Line 262... | Line 263... | ||
| 262 | assert(hlp); |
263 | assert(hlp); |
| 263 | tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link); |
264 | tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link); |
| 264 | return !str_cmp(namep->name, component); |
265 | return !str_cmp(namep->name, component); |
| 265 | } |
266 | } |
| 266 | 267 | ||
| 267 | void *tmpfs_match(void *prnt, const char *component) |
268 | fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component) |
| 268 | { |
269 | { |
| 269 | tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt; |
270 | tmpfs_dentry_t *parentp = TMPFS_NODE(pfn); |
| 270 | tmpfs_dentry_t *childp = parentp->child; |
271 | tmpfs_dentry_t *childp = parentp->child; |
| 271 | 272 | ||
| 272 | while (childp && !tmpfs_match_one(parentp, childp, component)) |
273 | while (childp && !tmpfs_match_one(parentp, childp, component)) |
| 273 | childp = childp->sibling; |
274 | childp = childp->sibling; |
| 274 | 275 | ||
| 275 | return (void *) childp; |
276 | return FS_NODE(childp); |
| 276 | } |
277 | } |
| 277 | 278 | ||
| 278 | void * |
- | |
| 279 | tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index) |
279 | fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index) |
| 280 | { |
280 | { |
| 281 | unsigned long key[] = { |
281 | unsigned long key[] = { |
| 282 | [DENTRIES_KEY_INDEX] = index, |
282 | [DENTRIES_KEY_INDEX] = index, |
| 283 | [DENTRIES_KEY_DEV] = dev_handle |
283 | [DENTRIES_KEY_DEV] = dev_handle |
| 284 | }; |
284 | }; |
| 285 | link_t *lnk = hash_table_find(&dentries, key); |
285 | link_t *lnk = hash_table_find(&dentries, key); |
| 286 | if (!lnk) |
286 | if (!lnk) |
| 287 | return NULL; |
287 | return NULL; |
| 288 | return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link); |
288 | return FS_NODE(hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link)); |
| 289 | } |
289 | } |
| 290 | 290 | ||
| 291 | void tmpfs_node_put(void *node) |
291 | void tmpfs_node_put(fs_node_t *fn) |
| 292 | { |
292 | { |
| 293 | /* nothing to do */ |
293 | /* nothing to do */ |
| 294 | } |
294 | } |
| 295 | 295 | ||
| 296 | void *tmpfs_create_node(dev_handle_t dev_handle, int lflag) |
296 | fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag) |
| 297 | { |
297 | { |
| 298 | assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); |
298 | assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); |
| 299 | 299 | ||
| - | 300 | fs_node_t *fn = malloc(sizeof(fs_node_t)); |
|
| - | 301 | if (!fn) |
|
| - | 302 | return NULL; |
|
| - | 303 | ||
| 300 | tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t)); |
304 | tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t)); |
| 301 | if (!node) |
305 | if (!node) { |
| - | 306 | free(fn); |
|
| 302 | return NULL; |
307 | return NULL; |
| 303 | 308 | } |
|
| 304 | if (!tmpfs_dentry_initialize(node)) { |
309 | if (!tmpfs_dentry_initialize(node)) { |
| - | 310 | free(fn); |
|
| 305 | free(node); |
311 | free(node); |
| 306 | return NULL; |
312 | return NULL; |
| 307 | } |
313 | } |
| - | 314 | fn->data = node; |
|
| - | 315 | node->bp = fn; /* establish the back pointer */ |
|
| 308 | if (!tmpfs_root_get(dev_handle)) |
316 | if (!tmpfs_root_get(dev_handle)) |
| 309 | node->index = TMPFS_SOME_ROOT; |
317 | node->index = TMPFS_SOME_ROOT; |
| 310 | else |
318 | else |
| 311 | node->index = tmpfs_next_index++; |
319 | node->index = tmpfs_next_index++; |
| 312 | node->dev_handle = dev_handle; |
320 | node->dev_handle = dev_handle; |
| Line 319... | Line 327... | ||
| 319 | unsigned long key[] = { |
327 | unsigned long key[] = { |
| 320 | [DENTRIES_KEY_INDEX] = node->index, |
328 | [DENTRIES_KEY_INDEX] = node->index, |
| 321 | [DENTRIES_KEY_DEV] = node->dev_handle |
329 | [DENTRIES_KEY_DEV] = node->dev_handle |
| 322 | }; |
330 | }; |
| 323 | hash_table_insert(&dentries, key, &node->dh_link); |
331 | hash_table_insert(&dentries, key, &node->dh_link); |
| 324 | return (void *) node; |
332 | return fn; |
| 325 | } |
333 | } |
| 326 | 334 | ||
| 327 | int tmpfs_link_node(void *prnt, void *chld, const char *nm) |
335 | int tmpfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm) |
| 328 | { |
336 | { |
| 329 | tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt; |
337 | tmpfs_dentry_t *parentp = TMPFS_NODE(pfn); |
| 330 | tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld; |
338 | tmpfs_dentry_t *childp = TMPFS_NODE(cfn); |
| 331 | 339 | ||
| 332 | assert(parentp->type == TMPFS_DIRECTORY); |
340 | assert(parentp->type == TMPFS_DIRECTORY); |
| 333 | 341 | ||
| 334 | tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t)); |
342 | tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t)); |
| 335 | if (!namep) |
343 | if (!namep) |
| Line 360... | Line 368... | ||
| 360 | } |
368 | } |
| 361 | 369 | ||
| 362 | return EOK; |
370 | return EOK; |
| 363 | } |
371 | } |
| 364 | 372 | ||
| 365 | int tmpfs_unlink_node(void *prnt, void *chld) |
373 | int tmpfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn) |
| 366 | { |
374 | { |
| 367 | tmpfs_dentry_t *parentp = (tmpfs_dentry_t *)prnt; |
375 | tmpfs_dentry_t *parentp = TMPFS_NODE(pfn); |
| 368 | tmpfs_dentry_t *childp = (tmpfs_dentry_t *)chld; |
376 | tmpfs_dentry_t *childp = TMPFS_NODE(cfn); |
| 369 | 377 | ||
| 370 | if (!parentp) |
378 | if (!parentp) |
| 371 | return EBUSY; |
379 | return EBUSY; |
| 372 | 380 | ||
| 373 | if (childp->child) |
381 | if (childp->child) |
| Line 390... | Line 398... | ||
| 390 | childp->lnkcnt--; |
398 | childp->lnkcnt--; |
| 391 | 399 | ||
| 392 | return EOK; |
400 | return EOK; |
| 393 | } |
401 | } |
| 394 | 402 | ||
| 395 | int tmpfs_destroy_node(void *nodep) |
403 | int tmpfs_destroy_node(fs_node_t *fn) |
| 396 | { |
404 | { |
| 397 | tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep; |
405 | tmpfs_dentry_t *dentry = TMPFS_NODE(fn); |
| 398 | 406 | ||
| 399 | assert(!dentry->lnkcnt); |
407 | assert(!dentry->lnkcnt); |
| 400 | assert(!dentry->child); |
408 | assert(!dentry->child); |
| 401 | assert(!dentry->sibling); |
409 | assert(!dentry->sibling); |
| 402 | 410 | ||
| Line 408... | Line 416... | ||
| 408 | 416 | ||
| 409 | hash_table_destroy(&dentry->names); |
417 | hash_table_destroy(&dentry->names); |
| 410 | 418 | ||
| 411 | if (dentry->type == TMPFS_FILE) |
419 | if (dentry->type == TMPFS_FILE) |
| 412 | free(dentry->data); |
420 | free(dentry->data); |
| - | 421 | free(dentry->bp); |
|
| 413 | free(dentry); |
422 | free(dentry); |
| 414 | return EOK; |
423 | return EOK; |
| 415 | } |
424 | } |
| 416 | 425 | ||
| 417 | void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) |
426 | void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) |
| Line 444... | Line 453... | ||
| 444 | if (!tmpfs_instance_init(dev_handle)) { |
453 | if (!tmpfs_instance_init(dev_handle)) { |
| 445 | ipc_answer_0(rid, ENOMEM); |
454 | ipc_answer_0(rid, ENOMEM); |
| 446 | return; |
455 | return; |
| 447 | } |
456 | } |
| 448 | 457 | ||
| 449 | tmpfs_dentry_t *root = tmpfs_root_get(dev_handle); |
458 | tmpfs_dentry_t *root = TMPFS_NODE(tmpfs_root_get(dev_handle)); |
| 450 | if (str_cmp(opts, "restore") == 0) { |
459 | if (str_cmp(opts, "restore") == 0) { |
| 451 | if (tmpfs_restore(dev_handle)) |
460 | if (tmpfs_restore(dev_handle)) |
| 452 | ipc_answer_3(rid, EOK, root->index, root->size, |
461 | ipc_answer_3(rid, EOK, root->index, root->size, |
| 453 | root->lnkcnt); |
462 | root->lnkcnt); |
| 454 | else |
463 | else |
| Line 670... | Line 679... | ||
| 670 | ipc_answer_0(rid, ENOENT); |
679 | ipc_answer_0(rid, ENOENT); |
| 671 | return; |
680 | return; |
| 672 | } |
681 | } |
| 673 | tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t, |
682 | tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t, |
| 674 | dh_link); |
683 | dh_link); |
| 675 | rc = tmpfs_destroy_node(dentry); |
684 | rc = tmpfs_destroy_node(FS_NODE(dentry)); |
| 676 | ipc_answer_0(rid, rc); |
685 | ipc_answer_0(rid, rc); |
| 677 | } |
686 | } |
| 678 | 687 | ||
| 679 | /** |
688 | /** |
| 680 | * @} |
689 | * @} |