Changes in uspace/srv/fs/mfs/mfs_ops.c [4c3ad56:36cb22f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/mfs/mfs_ops.c
r4c3ad56 r36cb22f 43 43 44 44 static bool check_magic_number(uint16_t magic, bool *native, 45 mfs_version_t *version, bool *longfilenames);45 mfs_version_t *version, bool *longfilenames); 46 46 static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst, 47 fs_index_t index); 47 fs_index_t index); 48 48 49 static int mfs_node_put(fs_node_t *fsnode); 49 50 static int mfs_node_open(fs_node_t *fsnode); … … 63 64 static hash_index_t open_nodes_hash(unsigned long key[]); 64 65 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 65 66 link_t *item); 66 67 static void open_nodes_remove_cb(link_t *link); 68 67 69 static int mfs_node_get(fs_node_t **rfn, service_id_t service_id, 68 fs_index_t index); 69 static int mfs_instance_get(service_id_t service_id, 70 struct mfs_instance **instance); 71 static int mfs_check_sanity(struct mfs_sb_info *sbi); 72 static bool is_power_of_two(uint32_t n); 70 fs_index_t index); 71 static int 72 mfs_instance_get(service_id_t service_id, struct mfs_instance **instance); 73 73 74 74 75 static hash_table_t open_nodes; … … 95 96 96 97 /* Hash table interface for open nodes hash table */ 97 static hash_index_t 98 open_nodes_hash(unsigned long key[]) 98 static hash_index_t open_nodes_hash(unsigned long key[]) 99 99 { 100 100 /* TODO: This is very simple and probably can be improved */ … … 102 102 } 103 103 104 static int 105 open_nodes_compare(unsigned long key[], hash_count_t keys, 106 link_t *item) 104 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 105 link_t *item) 107 106 { 108 107 struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link); … … 119 118 } 120 119 121 static void 122 open_nodes_remove_cb(link_t *link) 120 static void open_nodes_remove_cb(link_t *link) 123 121 { 124 122 /* We don't use remove callback for this hash table */ … … 131 129 }; 132 130 133 int 134 mfs_global_init(void) 131 int mfs_global_init(void) 135 132 { 136 133 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 137 134 OPEN_NODES_KEYS, &open_nodes_ops)) { 138 135 return ENOMEM; 139 136 } … … 143 140 static int 144 141 mfs_mounted(service_id_t service_id, const char *opts, fs_index_t *index, 145 142 aoff64_t *size, unsigned *linkcnt) 146 143 { 147 144 enum cache_mode cmode; … … 166 163 return rc; 167 164 168 /* Allocate space for generic MFS superblock*/165 /*Allocate space for generic MFS superblock*/ 169 166 sbi = malloc(sizeof(*sbi)); 170 167 if (!sbi) { … … 173 170 } 174 171 175 /* Allocate space for filesystem instance*/172 /*Allocate space for filesystem instance*/ 176 173 instance = malloc(sizeof(*instance)); 177 174 if (!instance) { … … 194 191 195 192 if (check_magic_number(sb->s_magic, &native, &version, &longnames)) { 196 /* This is a V1 or V2 Minix filesystem*/193 /*This is a V1 or V2 Minix filesystem*/ 197 194 magic = sb->s_magic; 198 195 } else if (check_magic_number(sb3->s_magic, &native, &version, &longnames)) { 199 /* This is a V3 Minix filesystem*/196 /*This is a V3 Minix filesystem*/ 200 197 magic = sb3->s_magic; 201 198 } else { 202 /* Not recognized*/199 /*Not recognized*/ 203 200 mfsdebug("magic number not recognized\n"); 204 201 rc = ENOTSUP; … … 208 205 mfsdebug("magic number recognized = %04x\n", magic); 209 206 210 /* Fill superblock info structure*/207 /*Fill superblock info structure*/ 211 208 212 209 sbi->fs_version = version; … … 246 243 sbi->dirsize = longnames ? MFSL_DIRSIZE : MFS_DIRSIZE; 247 244 sbi->max_name_len = longnames ? MFS_L_MAX_NAME_LEN : 248 MFS_MAX_NAME_LEN;245 MFS_MAX_NAME_LEN; 249 246 } 250 247 … … 262 259 263 260 sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks; 264 if ((rc = mfs_check_sanity(sbi)) != EOK) {265 fprintf(stderr, "Filesystem corrupted, invalid superblock");266 goto out_error;267 }268 261 269 262 rc = block_cache_init(service_id, sbi->block_size, 0, cmode); … … 274 267 } 275 268 276 /* Initialize the instance structure and remember it*/269 /*Initialize the instance structure and remember it*/ 277 270 instance->service_id = service_id; 278 271 instance->sbi = sbi; … … 280 273 rc = fs_instance_create(service_id, instance); 281 274 if (rc != EOK) { 275 free(instance); 276 free(sbi); 282 277 block_cache_fini(service_id); 278 block_fini(service_id); 283 279 mfsdebug("fs instance creation failed\n"); 284 goto out_error;280 return rc; 285 281 } 286 282 … … 335 331 } 336 332 337 service_id_t 338 mfs_service_get(fs_node_t *fsnode) 333 service_id_t mfs_service_get(fs_node_t *fsnode) 339 334 { 340 335 struct mfs_node *node = fsnode->data; … … 342 337 } 343 338 344 static int 345 mfs_create_node(fs_node_t **rfn, service_id_t service_id, int flags) 339 static int mfs_create_node(fs_node_t **rfn, service_id_t service_id, int flags) 346 340 { 347 341 int r; … … 357 351 return r; 358 352 359 /* Alloc a new inode*/353 /*Alloc a new inode*/ 360 354 r = mfs_alloc_inode(inst, &inum); 361 355 if (r != EOK) … … 384 378 if (flags & L_DIRECTORY) { 385 379 ino_i->i_mode = S_IFDIR; 386 ino_i->i_nlinks = 1; /* This accounts for the '.' dentry*/387 } else 380 ino_i->i_nlinks = 2; /*This accounts for the '.' dentry*/ 381 } else { 388 382 ino_i->i_mode = S_IFREG; 383 ino_i->i_nlinks = 1; 384 } 389 385 390 386 ino_i->i_uid = 0; … … 435 431 } 436 432 437 static int 438 mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 433 static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 439 434 { 440 435 struct mfs_node *mnode = pfn->data; … … 458 453 459 454 if (!d_info.d_inum) { 460 /* This entry is not used*/455 /*This entry is not used*/ 461 456 continue; 462 457 } … … 465 460 466 461 if (comp_size == dentry_name_size && 467 468 /* Hit!*/462 !bcmp(component, d_info.d_name, dentry_name_size)) { 463 /*Hit!*/ 469 464 mfs_node_core_get(rfn, mnode->instance, 470 465 d_info.d_inum); 471 466 goto found; 472 467 } … … 477 472 } 478 473 479 static aoff64_t 480 mfs_size_get(fs_node_t *node) 474 static aoff64_t mfs_size_get(fs_node_t *node) 481 475 { 482 476 const struct mfs_node *mnode = node->data; … … 486 480 static int 487 481 mfs_node_get(fs_node_t **rfn, service_id_t service_id, 488 482 fs_index_t index) 489 483 { 490 484 int rc; … … 530 524 } 531 525 532 static int 533 mfs_node_open(fs_node_t *fsnode) 526 static int mfs_node_open(fs_node_t *fsnode) 534 527 { 535 528 /* … … 540 533 } 541 534 542 static fs_index_t 543 mfs_index_get(fs_node_t *fsnode) 535 static fs_index_t mfs_index_get(fs_node_t *fsnode) 544 536 { 545 537 struct mfs_node *mnode = fsnode->data; … … 547 539 } 548 540 549 static unsigned 550 mfs_lnkcnt_get(fs_node_t *fsnode) 541 static unsigned mfs_lnkcnt_get(fs_node_t *fsnode) 551 542 { 552 543 struct mfs_node *mnode = fsnode->data; … … 563 554 } 564 555 565 static int 566 mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst, 567 fs_index_t index) 556 static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst, 557 fs_index_t index) 568 558 { 569 559 fs_node_t *node = NULL; … … 637 627 } 638 628 639 static bool 640 mfs_is_directory(fs_node_t *fsnode) 629 static bool mfs_is_directory(fs_node_t *fsnode) 641 630 { 642 631 const struct mfs_node *node = fsnode->data; … … 644 633 } 645 634 646 static bool 647 mfs_is_file(fs_node_t *fsnode) 635 static bool mfs_is_file(fs_node_t *fsnode) 648 636 { 649 637 struct mfs_node *node = fsnode->data; … … 651 639 } 652 640 653 static int 654 mfs_root_get(fs_node_t **rfn, service_id_t service_id) 641 static int mfs_root_get(fs_node_t **rfn, service_id_t service_id) 655 642 { 656 643 int rc = mfs_node_get(rfn, service_id, MFS_ROOT_INO); … … 658 645 } 659 646 660 static int 661 mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 647 static int mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 662 648 { 663 649 struct mfs_node *parent = pfn->data; … … 673 659 if (r != EOK) 674 660 goto exit_error; 675 676 child->ino_i->i_nlinks++;677 child->ino_i->dirty = true;678 661 679 662 if (S_ISDIR(child->ino_i->i_mode)) { … … 737 720 } 738 721 739 static int 740 mfs_has_children(bool *has_children, fs_node_t *fsnode) 722 static int mfs_has_children(bool *has_children, fs_node_t *fsnode) 741 723 { 742 724 struct mfs_node *mnode = fsnode->data; … … 759 741 760 742 if (d_info.d_inum) { 761 /* A valid entry has been found*/743 /*A valid entry has been found*/ 762 744 *has_children = true; 763 745 break; … … 771 753 static int 772 754 mfs_read(service_id_t service_id, fs_index_t index, aoff64_t pos, 773 755 size_t *rbytes) 774 756 { 775 757 int rc; … … 801 783 802 784 if (pos < 2) { 803 /* Skip the first two dentries ('.' and '..')*/785 /*Skip the first two dentries ('.' and '..')*/ 804 786 pos = 2; 805 787 } … … 811 793 812 794 if (d_info.d_inum) { 813 /* Dentry found!*/795 /*Dentry found!*/ 814 796 goto found; 815 797 } … … 827 809 828 810 if (pos >= (size_t) ino_i->i_size) { 829 /* Trying to read beyond the end of file*/811 /*Trying to read beyond the end of file*/ 830 812 bytes = 0; 831 813 (void) async_data_read_finalize(callid, NULL, 0); … … 844 826 845 827 if (zone == 0) { 846 /* sparse file*/828 /*sparse file*/ 847 829 uint8_t *buf = malloc(sbi->block_size); 848 830 if (!buf) { … … 852 834 memset(buf, 0, sizeof(sbi->block_size)); 853 835 async_data_read_finalize(callid, 854 836 buf + pos % sbi->block_size, bytes); 855 837 free(buf); 856 838 goto out_success; … … 862 844 863 845 async_data_read_finalize(callid, b->data + 864 846 pos % sbi->block_size, bytes); 865 847 866 848 rc = block_put(b); … … 883 865 static int 884 866 mfs_write(service_id_t service_id, fs_index_t index, aoff64_t pos, 885 867 size_t *wbytes, aoff64_t *nsize) 886 868 { 887 869 fs_node_t *fn; … … 918 900 919 901 if (block == 0) { 902 /*Writing in a sparse block*/ 920 903 uint32_t dummy; 921 904 … … 975 958 return ENOENT; 976 959 977 /* Destroy the inode*/960 /*Destroy the inode*/ 978 961 return mfs_destroy_node(fn); 979 962 } … … 994 977 assert(!has_children); 995 978 996 /* Free the entire inode content*/979 /*Free the entire inode content*/ 997 980 r = mfs_inode_shrink(mnode, mnode->ino_i->i_size); 998 981 if (r != EOK) 999 982 goto out; 1000 983 1001 /* Mark the inode as free in the bitmap*/984 /*Mark the inode as free in the bitmap*/ 1002 985 r = mfs_free_inode(mnode->instance, mnode->ino_i->index); 1003 986 … … 1038 1021 1039 1022 rc = fs_instance_get(service_id, &data); 1040 if (rc == EOK) 1023 if (rc == EOK) { 1041 1024 *instance = (struct mfs_instance *) data; 1042 else {1025 } else { 1043 1026 mfsdebug("instance not found\n"); 1044 1027 } … … 1047 1030 } 1048 1031 1049 static bool 1050 check_magic_number(uint16_t magic, bool *native, 1051 mfs_version_t *version, bool *longfilenames) 1032 static bool check_magic_number(uint16_t magic, bool *native, 1033 mfs_version_t *version, bool *longfilenames) 1052 1034 { 1053 1035 bool rc = true; … … 1077 1059 } 1078 1060 1079 /** Filesystem sanity check1080 *1081 * @param Pointer to the MFS superblock.1082 *1083 * @return EOK on success, ENOTSUP otherwise.1084 */1085 static int1086 mfs_check_sanity(struct mfs_sb_info *sbi)1087 {1088 if (!is_power_of_two(sbi->block_size) ||1089 sbi->block_size < MFS_MIN_BLOCKSIZE ||1090 sbi->block_size > MFS_MAX_BLOCKSIZE)1091 return ENOTSUP;1092 else if (sbi->ibmap_blocks == 0 || sbi->zbmap_blocks == 0)1093 return ENOTSUP;1094 else if (sbi->ninodes == 0 || sbi->nzones == 0)1095 return ENOTSUP;1096 else if (sbi->firstdatazone == 0)1097 return ENOTSUP;1098 1099 return EOK;1100 }1101 1102 1061 static int 1103 1062 mfs_close(service_id_t service_id, fs_index_t index) … … 1120 1079 1121 1080 return mfs_node_put(fn); 1122 }1123 1124 /** Check if a given number is a power of two.1125 *1126 * @param n The number to check.1127 *1128 * @return true if it is a power of two, false otherwise.1129 */1130 static bool1131 is_power_of_two(uint32_t n)1132 {1133 if (n == 0)1134 return false;1135 1136 return (n & (n - 1)) == 0;1137 1081 } 1138 1082
Note:
See TracChangeset
for help on using the changeset viewer.