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