Changeset ee257b2 in mainline
- Timestamp:
- 2011-07-27T21:37:13Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9530d94
- Parents:
- 4bf0052a
- Location:
- uspace/srv/fs/minixfs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/minixfs/mfs.c
r4bf0052a ree257b2 157 157 } 158 158 159 rc = mfs_global_init(); 160 if (rc != EOK) { 161 printf(NAME ": Failed global initialization\n"); 162 goto err; 163 } 164 159 165 rc = fs_register(vfs_sess, &mfs_reg, &mfs_vfs_info, mfs_connection); 160 166 if (rc != EOK) -
uspace/srv/fs/minixfs/mfs.h
r4bf0052a ree257b2 146 146 devmap_handle_t handle; 147 147 struct mfs_sb_info *sbi; 148 unsigned open_nodes_cnt; 148 149 }; 149 150 … … 152 153 struct mfs_ino_info *ino_i; 153 154 struct mfs_instance *instance; 155 unsigned refcnt; 156 fs_node_t *fsnode; 157 link_t link; 154 158 }; 155 159 … … 186 190 mfs_sync(ipc_callid_t rid, ipc_call_t *request); 187 191 192 extern int 193 mfs_global_init(void); 194 188 195 /*mfs_inode.c*/ 189 196 extern int -
uspace/srv/fs/minixfs/mfs_ops.c
r4bf0052a ree257b2 34 34 #include <fibril_synch.h> 35 35 #include <align.h> 36 #include <adt/hash_table.h> 36 37 #include "mfs.h" 38 39 #define OPEN_NODES_KEYS 2 40 #define OPEN_NODES_DEV_HANDLE_KEY 0 41 #define OPEN_NODES_INODE_KEY 1 42 #define OPEN_NODES_BUCKETS 256 37 43 38 44 static bool check_magic_number(uint16_t magic, bool *native, … … 57 63 static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name); 58 64 static int mfs_destroy_node(fs_node_t *fn); 65 static hash_index_t open_nodes_hash(unsigned long key[]); 66 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 67 link_t *item); 68 static void open_nodes_remove_cb(link_t *link); 59 69 60 70 static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, … … 64 74 static LIST_INITIALIZE(inst_list); 65 75 static FIBRIL_MUTEX_INITIALIZE(inst_list_mutex); 76 static hash_table_t open_nodes; 77 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 66 78 67 79 libfs_ops_t mfs_libfs_ops = { … … 85 97 }; 86 98 99 /* Hash table interface for open nodes hash table */ 100 static hash_index_t open_nodes_hash(unsigned long key[]) 101 { 102 /* TODO: This is very simple and probably can be improved */ 103 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS; 104 } 105 106 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 107 link_t *item) 108 { 109 struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link); 110 assert(keys > 0); 111 if (mnode->instance->handle != 112 ((devmap_handle_t) key[OPEN_NODES_DEV_HANDLE_KEY])) { 113 return false; 114 } 115 if (keys == 1) { 116 return true; 117 } 118 assert(keys == 2); 119 return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]); 120 } 121 122 static void open_nodes_remove_cb(link_t *link) 123 { 124 /* We don't use remove callback for this hash table */ 125 } 126 127 static hash_table_operations_t open_nodes_ops = { 128 .hash = open_nodes_hash, 129 .compare = open_nodes_compare, 130 .remove_callback = open_nodes_remove_cb, 131 }; 132 133 int mfs_global_init(void) 134 { 135 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 136 OPEN_NODES_KEYS, &open_nodes_ops)) { 137 return ENOMEM; 138 } 139 return EOK; 140 } 141 87 142 void mfs_mounted(ipc_callid_t rid, ipc_call_t *request) 88 143 { … … 138 193 return; 139 194 } 195 196 instance->open_nodes_cnt = 0; 140 197 141 198 sb = malloc(MFS_SUPERBLOCK_SIZE); … … 265 322 } 266 323 324 if (inst->open_nodes_cnt != 0) { 325 async_answer_0(rid, EBUSY); 326 return; 327 } 328 267 329 (void) block_cache_fini(devmap); 268 330 block_fini(devmap); … … 292 354 fs_node_t *fsnode; 293 355 uint32_t inum; 356 357 mfsdebug("%s()\n", __FUNCTION__); 294 358 295 359 r = mfs_instance_get(handle, &inst); … … 342 406 mnode->ino_i = ino_i; 343 407 mnode->instance = inst; 344 345 r = put_inode(mnode); 346 on_error(r, goto out_err_2); 408 mnode->refcnt = 1; 409 410 link_initialize(&mnode->link); 411 412 unsigned long key[] = { 413 [OPEN_NODES_DEV_HANDLE_KEY] = inst->handle, 414 [OPEN_NODES_INODE_KEY] = inum, 415 }; 416 417 fibril_mutex_lock(&open_nodes_lock); 418 hash_table_insert(&open_nodes, key, &mnode->link); 419 fibril_mutex_unlock(&open_nodes_lock); 420 inst->open_nodes_cnt++; 421 422 mnode->ino_i->dirty = true; 347 423 348 424 fs_node_initialize(fsnode); 349 425 fsnode->data = mnode; 426 mnode->fsnode = fsnode; 350 427 *rfn = fsnode; 351 428 … … 366 443 struct mfs_dentry_info d_info; 367 444 int r; 445 446 mfsdebug("%s()\n", __FUNCTION__); 368 447 369 448 if (!S_ISDIR(ino_i->i_mode)) … … 420 499 struct mfs_instance *instance; 421 500 501 mfsdebug("%s()\n", __FUNCTION__); 502 422 503 rc = mfs_instance_get(devmap_handle, &instance); 423 504 on_error(rc, return rc); … … 428 509 static int mfs_node_put(fs_node_t *fsnode) 429 510 { 511 int rc = EOK; 430 512 struct mfs_node *mnode = fsnode->data; 431 513 432 put_inode(mnode); 433 free(mnode->ino_i); 434 free(mnode); 435 free(fsnode); 436 437 return EOK; 514 mfsdebug("%s()\n", __FUNCTION__); 515 516 fibril_mutex_lock(&open_nodes_lock); 517 518 assert(mnode->refcnt > 0); 519 mnode->refcnt--; 520 if (mnode->refcnt == 0) { 521 unsigned long key[] = { 522 [OPEN_NODES_DEV_HANDLE_KEY] = mnode->instance->handle, 523 [OPEN_NODES_INODE_KEY] = mnode->ino_i->index 524 }; 525 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 526 assert(mnode->instance->open_nodes_cnt > 0); 527 mnode->instance->open_nodes_cnt--; 528 rc = put_inode(mnode); 529 free(mnode->ino_i); 530 free(mnode); 531 free(fsnode); 532 } 533 534 fibril_mutex_unlock(&open_nodes_lock); 535 return rc; 438 536 } 439 537 … … 459 557 struct mfs_node *mnode = fsnode->data; 460 558 559 mfsdebug("%s()\n", __FUNCTION__); 560 461 561 assert(mnode); 462 562 assert(mnode->ino_i); 463 563 464 return mnode->ino_i->i_nlinks; ;564 return mnode->ino_i->i_nlinks; 465 565 } 466 566 … … 471 571 struct mfs_node *mnode = NULL; 472 572 int rc; 573 574 mfsdebug("%s()\n", __FUNCTION__); 575 576 fibril_mutex_lock(&open_nodes_lock); 577 578 /* Check if the node is not already open */ 579 unsigned long key[] = { 580 [OPEN_NODES_DEV_HANDLE_KEY] = inst->handle, 581 [OPEN_NODES_INODE_KEY] = index, 582 }; 583 link_t *already_open = hash_table_find(&open_nodes, key); 584 585 if (already_open) { 586 mnode = hash_table_get_instance(already_open, struct mfs_node, link); 587 *rfn = mnode->fsnode; 588 mnode->refcnt++; 589 590 fibril_mutex_unlock(&open_nodes_lock); 591 return EOK; 592 } 473 593 474 594 node = malloc(sizeof(fs_node_t)); … … 493 613 ino_i->index = index; 494 614 mnode->ino_i = ino_i; 615 mnode->refcnt = 1; 616 link_initialize(&mnode->link); 495 617 496 618 mnode->instance = inst; 497 619 node->data = mnode; 620 mnode->fsnode = node; 498 621 *rfn = node; 622 623 hash_table_insert(&open_nodes, key, &mnode->link); 624 inst->open_nodes_cnt++; 625 626 fibril_mutex_unlock(&open_nodes_lock); 499 627 500 628 return EOK; … … 505 633 if (mnode) 506 634 free(mnode); 635 fibril_mutex_unlock(&open_nodes_lock); 507 636 return rc; 508 637 } … … 542 671 struct mfs_sb_info *sbi = parent->instance->sbi; 543 672 673 mfsdebug("%s()\n", __FUNCTION__); 674 544 675 if (str_size(name) > sbi->max_name_len) 545 676 return ENAMETOOLONG; … … 551 682 r = insert_dentry(child, ".", child->ino_i->index); 552 683 on_error(r, goto exit_error); 684 child->ino_i->i_nlinks++; 685 child->ino_i->dirty = true; 553 686 r = insert_dentry(child, "..", parent->ino_i->index); 687 on_error(r, goto exit_error); 688 parent->ino_i->i_nlinks++; 689 parent->ino_i->dirty = true; 554 690 } 555 691 … … 566 702 int r; 567 703 704 mfsdebug("%s()\n", __FUNCTION__); 705 568 706 if (!parent) 569 707 return EBUSY; … … 583 721 --chino->i_nlinks; 584 722 723 if (chino->i_nlinks == 0 && S_ISDIR(chino->i_mode)) { 724 parent->ino_i->i_nlinks--; 725 parent->ino_i->dirty = true; 726 } 727 585 728 chino->dirty = true; 586 729 587 return EOK;730 return r; 588 731 } 589 732
Note:
See TracChangeset
for help on using the changeset viewer.