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 | * @} |