Changeset a35b458 in mainline for uspace/srv/fs
- Timestamp:
- 2018-03-02T20:10:49Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/srv/fs
- Files:
-
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/cdfs/cdfs.c
r3061bc1 ra35b458 60 60 { 61 61 printf("%s: HelenOS cdfs file system server\n", NAME); 62 62 63 63 if (argc == 3) { 64 64 if (!str_cmp(argv[1], "--instance")) … … 74 74 return -1; 75 75 } 76 76 77 77 async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS, 78 78 INTERFACE_VFS_DRIVER, 0); … … 81 81 return -1; 82 82 } 83 83 84 84 errno_t rc = fs_register(vfs_sess, &cdfs_vfs_info, &cdfs_ops, 85 85 &cdfs_libfs_ops); … … 88 88 return rc; 89 89 } 90 90 91 91 printf("%s: Accepting connections\n", NAME); 92 92 task_retval(0); 93 93 async_manager(); 94 94 95 95 /* Not reached */ 96 96 return 0; -
uspace/srv/fs/cdfs/cdfs_ops.c
r3061bc1 ra35b458 92 92 uint8_t mon[2]; 93 93 uint8_t day[2]; 94 94 95 95 uint8_t hour[2]; 96 96 uint8_t min[2]; 97 97 uint8_t sec[2]; 98 98 uint8_t msec[2]; 99 99 100 100 uint8_t offset; 101 101 } __attribute__((packed)) cdfs_datetime_t; … … 105 105 uint8_t mon; 106 106 uint8_t day; 107 107 108 108 uint8_t hour; 109 109 uint8_t min; 110 110 uint8_t sec; 111 111 112 112 uint8_t offset; 113 113 } __attribute__((packed)) cdfs_timestamp_t; … … 121 121 uint8_t length; 122 122 uint8_t ea_length; 123 123 124 124 uint32_t_lb lba; 125 125 uint32_t_lb size; 126 126 127 127 cdfs_timestamp_t timestamp; 128 128 uint8_t flags; … … 130 130 uint8_t gap_size; 131 131 uint16_t_lb sequence_nr; 132 132 133 133 uint8_t name_length; 134 134 uint8_t name[]; … … 139 139 uint8_t length; 140 140 uint8_t ea_length; 141 141 142 142 uint32_t_lb lba; 143 143 uint32_t_lb size; 144 144 145 145 cdfs_timestamp_t timestamp; 146 146 uint8_t flags; … … 148 148 uint8_t gap_size; 149 149 uint16_t_lb sequence_nr; 150 150 151 151 uint8_t name_length; 152 152 uint8_t name[1]; … … 155 155 typedef struct { 156 156 uint8_t flags; /* reserved in primary */ 157 157 158 158 uint8_t system_ident[32]; 159 159 uint8_t ident[32]; 160 160 161 161 uint64_t res1; 162 162 uint32_t_lb lba_size; 163 163 164 164 uint8_t esc_seq[32]; /* reserved in primary */ 165 165 uint16_t_lb set_size; 166 166 uint16_t_lb sequence_nr; 167 167 168 168 uint16_t_lb block_size; 169 169 uint32_t_lb path_table_size; 170 170 171 171 uint32_t path_table_lsb; 172 172 uint32_t opt_path_table_lsb; 173 173 uint32_t path_table_msb; 174 174 uint32_t opt_path_table_msb; 175 175 176 176 cdfs_root_dir_t root_dir; 177 177 uint8_t pad0; 178 178 179 179 uint8_t set_ident[128]; 180 180 uint8_t publisher_ident[128]; 181 181 uint8_t preparer_ident[128]; 182 182 uint8_t app_ident[128]; 183 183 184 184 uint8_t copyright_file_ident[37]; 185 185 uint8_t abstract_file_ident[37]; 186 186 uint8_t biblio_file_ident[37]; 187 187 188 188 cdfs_datetime_t creation; 189 189 cdfs_datetime_t modification; 190 190 cdfs_datetime_t expiration; 191 191 cdfs_datetime_t effective; 192 192 193 193 uint8_t fs_version; 194 194 } __attribute__((packed)) cdfs_vol_desc_prisec_t; … … 236 236 fs_index_t index; /**< Node index */ 237 237 cdfs_t *fs; /**< File system */ 238 238 239 239 ht_link_t nh_link; /**< Nodes hash table link */ 240 240 cdfs_dentry_type_t type; /**< Dentry type */ 241 241 242 242 unsigned int lnkcnt; /**< Link count */ 243 243 uint32_t size; /**< File size if type is CDFS_FILE */ 244 244 245 245 list_t cs_list; /**< Child's siblings list */ 246 246 cdfs_lba_t lba; /**< LBA of data on disk */ … … 301 301 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 302 302 ht_key_t *key = (ht_key_t*)k; 303 303 304 304 return key->service_id == node->fs->service_id && key->index == node->index; 305 305 } … … 308 308 { 309 309 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 310 310 311 311 if (node->type == CDFS_DIRECTORY) { 312 312 link_t *link; … … 317 317 } 318 318 } 319 319 320 320 free(node->fs_node); 321 321 free(node); … … 338 338 .service_id = service_id 339 339 }; 340 340 341 341 ht_link_t *link = hash_table_find(&nodes, &key); 342 342 if (link) { 343 343 cdfs_node_t *node = 344 344 hash_table_get_inst(link, cdfs_node_t, nh_link); 345 345 346 346 *rfn = FS_NODE(node); 347 347 } else 348 348 *rfn = NULL; 349 349 350 350 return EOK; 351 351 } … … 367 367 node->processed = false; 368 368 node->opened = 0; 369 369 370 370 list_initialize(&node->cs_list); 371 371 } … … 375 375 { 376 376 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); 377 377 378 378 cdfs_node_t *node = malloc(sizeof(cdfs_node_t)); 379 379 if (!node) 380 380 return ENOMEM; 381 381 382 382 cdfs_node_initialize(node); 383 383 384 384 node->fs_node = malloc(sizeof(fs_node_t)); 385 385 if (!node->fs_node) { … … 387 387 return ENOMEM; 388 388 } 389 389 390 390 fs_node_initialize(node->fs_node); 391 391 node->fs_node->data = node; 392 392 393 393 fs_node_t *rootfn; 394 394 errno_t rc = cdfs_root_get(&rootfn, fs->service_id); 395 395 396 396 assert(rc == EOK); 397 397 398 398 if (!rootfn) 399 399 node->index = CDFS_SOME_ROOT; 400 400 else 401 401 node->index = index; 402 402 403 403 node->fs = fs; 404 404 405 405 if (lflag & L_DIRECTORY) 406 406 node->type = CDFS_DIRECTORY; 407 407 else 408 408 node->type = CDFS_FILE; 409 409 410 410 /* Insert the new node into the nodes hash table. */ 411 411 hash_table_insert(&nodes, &node->nh_link); 412 412 413 413 *rfn = FS_NODE(node); 414 414 nodes_cached++; 415 415 416 416 return EOK; 417 417 } … … 421 421 cdfs_node_t *parent = CDFS_NODE(pfn); 422 422 cdfs_node_t *node = CDFS_NODE(fn); 423 423 424 424 assert(parent->type == CDFS_DIRECTORY); 425 425 426 426 /* Check for duplicate entries */ 427 427 list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) { … … 429 429 return EEXIST; 430 430 } 431 431 432 432 /* Allocate and initialize the dentry */ 433 433 cdfs_dentry_t *dentry = malloc(sizeof(cdfs_dentry_t)); 434 434 if (!dentry) 435 435 return ENOMEM; 436 436 437 437 /* Populate and link the new dentry */ 438 438 dentry->name = str_dup(name); … … 441 441 return ENOMEM; 442 442 } 443 443 444 444 link_initialize(&dentry->link); 445 445 dentry->index = node->index; 446 446 447 447 node->lnkcnt++; 448 448 list_append(&dentry->link, &parent->cs_list); 449 449 450 450 return EOK; 451 451 } … … 463 463 char *str; 464 464 uint16_t *buf; 465 465 466 466 switch (enc) { 467 467 case enc_ascii: … … 476 476 if (buf == NULL) 477 477 return NULL; 478 478 479 479 size_t i; 480 480 for (i = 0; i < dsize / sizeof(uint16_t); i++) { … … 482 482 ((unaligned_uint16_t *)data)[i]); 483 483 } 484 484 485 485 size_t dstr_size = dsize / sizeof(uint16_t) * 4 + 1; 486 486 str = malloc(dstr_size); 487 487 if (str == NULL) 488 488 return NULL; 489 489 490 490 rc = utf16_to_str(str, dstr_size, buf); 491 491 free(buf); 492 492 493 493 if (rc != EOK) 494 494 return NULL; … … 498 498 str = NULL; 499 499 } 500 500 501 501 return str; 502 502 } … … 516 516 char *dot; 517 517 char *scolon; 518 518 519 519 name = cdfs_decode_str(data, dsize, enc); 520 520 if (name == NULL) 521 521 return NULL; 522 522 523 523 if (dtype == CDFS_DIRECTORY) 524 524 return name; 525 525 526 526 dot = str_chr(name, '.'); 527 527 528 528 if (dot != NULL) { 529 529 scolon = str_chr(dot, ';'); … … 532 532 *scolon = '\0'; 533 533 } 534 534 535 535 /* If the extension is an empty string, trim the dot separator. */ 536 536 if (dot[1] == '\0') 537 537 *dot = '\0'; 538 538 } 539 539 540 540 return name; 541 541 } … … 552 552 char *ident; 553 553 size_t i; 554 554 555 555 ident = cdfs_decode_str(data, dsize, enc); 556 556 if (ident == NULL) 557 557 return NULL; 558 558 559 559 /* Trim trailing spaces */ 560 560 i = str_size(ident); … … 562 562 --i; 563 563 ident[i] = '\0'; 564 564 565 565 return ident; 566 566 } … … 570 570 cdfs_node_t *node = CDFS_NODE(fs_node); 571 571 assert(node); 572 572 573 573 if (node->processed) 574 574 return EOK; 575 575 576 576 uint32_t blocks = node->size / BLOCK_SIZE; 577 577 if ((node->size % BLOCK_SIZE) != 0) 578 578 blocks++; 579 579 580 580 for (uint32_t i = 0; i < blocks; i++) { 581 581 block_t *block; … … 583 583 if (rc != EOK) 584 584 return rc; 585 585 586 586 cdfs_dir_t *dir; 587 587 588 588 for (size_t offset = 0; offset < BLOCK_SIZE; 589 589 offset += dir->length) { … … 595 595 break; 596 596 } 597 597 598 598 cdfs_dentry_type_t dentry_type; 599 599 if (dir->flags & DIR_FLAG_DIRECTORY) … … 601 601 else 602 602 dentry_type = CDFS_FILE; 603 603 604 604 /* Skip special entries */ 605 605 606 606 if (dir->name_length == 1 && 607 607 dir->name[0] == CDFS_NAME_CURDIR) … … 610 610 dir->name[0] == CDFS_NAME_PARENTDIR) 611 611 continue; 612 612 613 613 // FIXME: hack - indexing by dentry byte offset on disc 614 614 615 615 fs_node_t *fn; 616 616 errno_t rc = create_node(&fn, fs, dentry_type, … … 620 620 621 621 assert(fn != NULL); 622 622 623 623 cdfs_node_t *cur = CDFS_NODE(fn); 624 624 cur->lba = uint32_lb(dir->lba); 625 625 cur->size = uint32_lb(dir->size); 626 626 627 627 char *name = cdfs_decode_name(dir->name, 628 628 dir->name_length, node->fs->enc, dentry_type); 629 629 if (name == NULL) 630 630 return EIO; 631 631 632 632 // FIXME: check return value 633 633 634 634 link_node(fs_node, fn, name); 635 635 free(name); 636 636 637 637 if (dentry_type == CDFS_FILE) 638 638 cur->processed = true; 639 639 } 640 640 641 641 block_put(block); 642 642 } 643 643 644 644 node->processed = true; 645 645 return EOK; … … 650 650 cdfs_lba_t lba = index / BLOCK_SIZE; 651 651 size_t offset = index % BLOCK_SIZE; 652 652 653 653 block_t *block; 654 654 errno_t rc = block_get(&block, fs->service_id, lba, BLOCK_FLAGS_NONE); 655 655 if (rc != EOK) 656 656 return NULL; 657 657 658 658 cdfs_dir_t *dir = (cdfs_dir_t *) (block->data + offset); 659 659 660 660 cdfs_dentry_type_t dentry_type; 661 661 if (dir->flags & DIR_FLAG_DIRECTORY) … … 663 663 else 664 664 dentry_type = CDFS_FILE; 665 665 666 666 fs_node_t *fn; 667 667 rc = create_node(&fn, fs, dentry_type, index); 668 668 if ((rc != EOK) || (fn == NULL)) 669 669 return NULL; 670 670 671 671 cdfs_node_t *node = CDFS_NODE(fn); 672 672 node->lba = uint32_lb(dir->lba); 673 673 node->size = uint32_lb(dir->size); 674 674 node->lnkcnt = 1; 675 675 676 676 if (dentry_type == CDFS_FILE) 677 677 node->processed = true; 678 678 679 679 block_put(block); 680 680 return fn; … … 687 687 .service_id = fs->service_id 688 688 }; 689 689 690 690 ht_link_t *link = hash_table_find(&nodes, &key); 691 691 if (link) { … … 694 694 return FS_NODE(node); 695 695 } 696 696 697 697 return get_uncached_node(fs, index); 698 698 } … … 701 701 { 702 702 cdfs_node_t *parent = CDFS_NODE(pfn); 703 703 704 704 if (!parent->processed) { 705 705 errno_t rc = cdfs_readdir(parent->fs, pfn); … … 707 707 return rc; 708 708 } 709 709 710 710 list_foreach(parent->cs_list, link, cdfs_dentry_t, dentry) { 711 711 if (str_cmp(dentry->name, component) == 0) { … … 714 714 } 715 715 } 716 716 717 717 *fn = NULL; 718 718 return EOK; … … 722 722 { 723 723 cdfs_node_t *node = CDFS_NODE(fn); 724 724 725 725 if (!node->processed) 726 726 cdfs_readdir(node->fs, fn); 727 727 728 728 node->opened++; 729 729 return EOK; … … 763 763 { 764 764 cdfs_node_t *node = CDFS_NODE(fn); 765 765 766 766 if ((node->type == CDFS_DIRECTORY) && (!node->processed)) 767 767 cdfs_readdir(node->fs, fn); 768 768 769 769 *has_children = !list_empty(&node->cs_list); 770 770 return EOK; … … 809 809 { 810 810 *size = BLOCK_SIZE; 811 811 812 812 return EOK; 813 813 } … … 816 816 { 817 817 *count = 0; 818 818 819 819 return EOK; 820 820 } … … 823 823 { 824 824 *count = 0; 825 825 826 826 return EOK; 827 827 } … … 855 855 size_t i, j, k; 856 856 bool match; 857 857 858 858 i = 0; 859 859 while (i + ucs2_esc_seq_len <= 32) { 860 860 if (seq[i] == 0) 861 861 break; 862 862 863 863 for (j = 0; j < ucs2_esc_seq_no; j++) { 864 864 match = true; … … 870 870 } 871 871 } 872 872 873 873 if (!match) 874 874 return EINVAL; 875 875 876 876 i += ucs2_esc_seq_len; 877 877 } 878 878 879 879 while (i < 32) { 880 880 if (seq[i] != 0) … … 882 882 ++i; 883 883 } 884 884 885 885 return EOK; 886 886 } … … 905 905 if (rc != EOK) 906 906 break; 907 907 908 908 cdfs_vol_desc_t *vol_desc = (cdfs_vol_desc_t *) block->data; 909 909 910 910 if (vol_desc->type == VOL_DESC_SET_TERMINATOR) { 911 911 block_put(block); 912 912 break; 913 913 } 914 914 915 915 if ((vol_desc->type != VOL_DESC_SUPPLEMENTARY) || 916 916 (memcmp(vol_desc->standard_ident, CDFS_STANDARD_IDENT, 5) != 0) || … … 919 919 continue; 920 920 } 921 921 922 922 uint16_t set_size = uint16_lb(vol_desc->data.prisec.set_size); 923 923 if (set_size > 1) { … … 929 929 */ 930 930 } 931 931 932 932 uint16_t sequence_nr = uint16_lb(vol_desc->data.prisec.sequence_nr); 933 933 if (sequence_nr != 1) { … … 939 939 continue; 940 940 } 941 941 942 942 uint16_t block_size = uint16_lb(vol_desc->data.prisec.block_size); 943 943 if (block_size != BLOCK_SIZE) { … … 945 945 continue; 946 946 } 947 947 948 948 rc = cdfs_verify_joliet_esc_seq(vol_desc->data.prisec.esc_seq); 949 949 if (rc != EOK) … … 958 958 return EOK; 959 959 } 960 960 961 961 return ENOENT; 962 962 } … … 971 971 if (rc != EOK) 972 972 return rc; 973 973 974 974 cdfs_vol_desc_t *vol_desc = (cdfs_vol_desc_t *) block->data; 975 975 976 976 /* 977 977 * Test for primary volume descriptor … … 984 984 return ENOTSUP; 985 985 } 986 986 987 987 uint16_t set_size = uint16_lb(vol_desc->data.prisec.set_size); 988 988 if (set_size > 1) { … … 994 994 */ 995 995 } 996 996 997 997 uint16_t sequence_nr = uint16_lb(vol_desc->data.prisec.sequence_nr); 998 998 if (sequence_nr != 1) { … … 1004 1004 return ENOTSUP; 1005 1005 } 1006 1006 1007 1007 uint16_t block_size = uint16_lb(vol_desc->data.prisec.block_size); 1008 1008 if (block_size != BLOCK_SIZE) { … … 1010 1010 return ENOTSUP; 1011 1011 } 1012 1012 1013 1013 // TODO: implement path table support 1014 1014 1015 1015 /* Search for Joliet SVD */ 1016 1016 1017 1017 uint32_t jrlba; 1018 1018 uint32_t jrsize; 1019 1019 1020 1020 rc = cdfs_find_joliet_svd(sid, altroot, &jrlba, &jrsize, vol_ident); 1021 1021 if (rc == EOK) { … … 1031 1031 32, enc_ascii); 1032 1032 } 1033 1033 1034 1034 block_put(block); 1035 1035 return EOK; … … 1040 1040 { 1041 1041 cdfs_node_t *node = CDFS_NODE(rfn); 1042 1042 1043 1043 errno_t rc = iso_read_vol_desc(fs->service_id, altroot, &node->lba, 1044 1044 &node->size, &fs->enc, &fs->vol_ident); 1045 1045 if (rc != EOK) 1046 1046 return rc; 1047 1047 1048 1048 return cdfs_readdir(fs, rfn); 1049 1049 } … … 1060 1060 if (fs == NULL) 1061 1061 goto error; 1062 1062 1063 1063 fs->service_id = sid; 1064 1064 1065 1065 /* Create root node */ 1066 1066 errno_t rc = create_node(&rfn, fs, L_DIRECTORY, cdfs_index++); 1067 1067 1068 1068 if ((rc != EOK) || (!rfn)) 1069 1069 goto error; 1070 1070 1071 1071 /* FS root is not linked */ 1072 1072 CDFS_NODE(rfn)->lnkcnt = 0; 1073 1073 CDFS_NODE(rfn)->lba = 0; 1074 1074 CDFS_NODE(rfn)->processed = false; 1075 1075 1076 1076 /* Check if there is cdfs in given session */ 1077 1077 if (iso_readfs(fs, rfn, altroot) != EOK) 1078 1078 goto error; 1079 1079 1080 1080 list_append(&fs->link, &cdfs_instances); 1081 1081 return fs; … … 1094 1094 if (rc != EOK) 1095 1095 return rc; 1096 1096 1097 1097 cdfs_lba_t altroot = 0; 1098 1098 1099 1099 /* 1100 1100 * Read TOC multisession information and get the start address … … 1106 1106 if (rc == EOK && (uint16_t_be2host(toc.toc_len) == 10)) 1107 1107 altroot = uint32_t_be2host(toc.ftrack_lsess.start_addr); 1108 1108 1109 1109 /* Initialize the block cache */ 1110 1110 rc = block_cache_init(service_id, BLOCK_SIZE, 0, CACHE_MODE_WT); … … 1113 1113 return rc; 1114 1114 } 1115 1115 1116 1116 /* Check if this device is not already mounted */ 1117 1117 fs_node_t *rootfn; … … 1123 1123 return EOK; 1124 1124 } 1125 1125 1126 1126 /* Read volume descriptors */ 1127 1127 uint32_t rlba; … … 1135 1135 return rc; 1136 1136 } 1137 1137 1138 1138 str_cpy(info->label, FS_LABEL_MAXLEN + 1, vol_ident); 1139 1139 free(vol_ident); 1140 1140 1141 1141 block_cache_fini(service_id); 1142 1142 block_fini(service_id); … … 1151 1151 if (rc != EOK) 1152 1152 return rc; 1153 1153 1154 1154 cdfs_lba_t altroot = 0; 1155 1155 1156 1156 if (str_lcmp(opts, "altroot=", 8) == 0) { 1157 1157 /* User-defined alternative root on a multi-session disk */ … … 1169 1169 altroot = uint32_t_be2host(toc.ftrack_lsess.start_addr); 1170 1170 } 1171 1171 1172 1172 /* Initialize the block cache */ 1173 1173 rc = block_cache_init(service_id, BLOCK_SIZE, 0, CACHE_MODE_WT); … … 1176 1176 return rc; 1177 1177 } 1178 1178 1179 1179 /* Check if this device is not already mounted */ 1180 1180 fs_node_t *rootfn; … … 1184 1184 block_cache_fini(service_id); 1185 1185 block_fini(service_id); 1186 1186 1187 1187 return EEXIST; 1188 1188 } 1189 1189 1190 1190 /* Create cdfs instance */ 1191 1191 if (cdfs_fs_create(service_id, altroot) == NULL) { 1192 1192 block_cache_fini(service_id); 1193 1193 block_fini(service_id); 1194 1194 1195 1195 return ENOMEM; 1196 1196 } 1197 1197 1198 1198 rc = cdfs_root_get(&rootfn, service_id); 1199 1199 assert(rc == EOK); 1200 1200 1201 1201 cdfs_node_t *root = CDFS_NODE(rootfn); 1202 1202 *index = root->index; 1203 1203 *size = root->size; 1204 1204 1205 1205 return EOK; 1206 1206 } … … 1210 1210 service_id_t service_id = *(service_id_t*)arg; 1211 1211 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 1212 1212 1213 1213 if (node->fs->service_id == service_id) { 1214 1214 hash_table_remove_item(&nodes, &node->nh_link); 1215 1215 } 1216 1216 1217 1217 return true; 1218 1218 } … … 1234 1234 return fs; 1235 1235 } 1236 1236 1237 1237 return NULL; 1238 1238 } … … 1245 1245 if (fs == NULL) 1246 1246 return ENOENT; 1247 1247 1248 1248 cdfs_fs_destroy(fs); 1249 1249 return EOK; … … 1257 1257 .service_id = service_id 1258 1258 }; 1259 1259 1260 1260 ht_link_t *link = hash_table_find(&nodes, &key); 1261 1261 if (link == NULL) 1262 1262 return ENOENT; 1263 1263 1264 1264 cdfs_node_t *node = 1265 1265 hash_table_get_inst(link, cdfs_node_t, nh_link); 1266 1266 1267 1267 if (!node->processed) { 1268 1268 errno_t rc = cdfs_readdir(node->fs, FS_NODE(node)); … … 1270 1270 return rc; 1271 1271 } 1272 1272 1273 1273 ipc_callid_t callid; 1274 1274 size_t len; … … 1277 1277 return EINVAL; 1278 1278 } 1279 1279 1280 1280 if (node->type == CDFS_FILE) { 1281 1281 if (pos >= node->size) { … … 1285 1285 cdfs_lba_t lba = pos / BLOCK_SIZE; 1286 1286 size_t offset = pos % BLOCK_SIZE; 1287 1287 1288 1288 *rbytes = min(len, BLOCK_SIZE - offset); 1289 1289 *rbytes = min(*rbytes, node->size - pos); 1290 1290 1291 1291 block_t *block; 1292 1292 errno_t rc = block_get(&block, service_id, node->lba + lba, … … 1296 1296 return rc; 1297 1297 } 1298 1298 1299 1299 async_data_read_finalize(callid, block->data + offset, 1300 1300 *rbytes); … … 1309 1309 return ENOENT; 1310 1310 } 1311 1311 1312 1312 cdfs_dentry_t *dentry = 1313 1313 list_get_instance(link, cdfs_dentry_t, link); 1314 1314 1315 1315 *rbytes = 1; 1316 1316 async_data_read_finalize(callid, dentry->name, 1317 1317 str_size(dentry->name) + 1); 1318 1318 } 1319 1319 1320 1320 return EOK; 1321 1321 } … … 1328 1328 * the operation is not supported. 1329 1329 */ 1330 1330 1331 1331 return ENOTSUP; 1332 1332 } … … 1339 1339 * the operation is not supported. 1340 1340 */ 1341 1341 1342 1342 return ENOTSUP; 1343 1343 } … … 1346 1346 { 1347 1347 size_t *premove_cnt = (size_t*)arg; 1348 1348 1349 1349 /* Some nodes were requested to be removed from the cache. */ 1350 1350 if (0 < *premove_cnt) { … … 1353 1353 if (!node->opened) { 1354 1354 hash_table_remove_item(&nodes, item); 1355 1355 1356 1356 --nodes_cached; 1357 1357 --*premove_cnt; 1358 1358 } 1359 1359 } 1360 1360 1361 1361 /* Only continue if more nodes were requested to be removed. */ 1362 1362 return 0 < *premove_cnt; … … 1367 1367 if (nodes_cached > NODE_CACHE_SIZE) { 1368 1368 size_t remove_cnt = nodes_cached - NODE_CACHE_SIZE; 1369 1369 1370 1370 if (0 < remove_cnt) 1371 1371 hash_table_apply(&nodes, cache_remove_closed, &remove_cnt); … … 1378 1378 if (index == 0) 1379 1379 return EOK; 1380 1380 1381 1381 ht_key_t key = { 1382 1382 .index = index, 1383 1383 .service_id = service_id 1384 1384 }; 1385 1385 1386 1386 ht_link_t *link = hash_table_find(&nodes, &key); 1387 1387 if (link == 0) 1388 1388 return ENOENT; 1389 1389 1390 1390 cdfs_node_t *node = 1391 1391 hash_table_get_inst(link, cdfs_node_t, nh_link); 1392 1392 1393 1393 assert(node->opened > 0); 1394 1394 1395 1395 node->opened--; 1396 1396 cleanup_cache(service_id); 1397 1397 1398 1398 return EOK; 1399 1399 } … … 1405 1405 * the operation is not supported. 1406 1406 */ 1407 1407 1408 1408 return ENOTSUP; 1409 1409 } … … 1415 1415 * the sync operation is a no-op. 1416 1416 */ 1417 1417 1418 1418 return EOK; 1419 1419 } … … 1438 1438 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 1439 1439 return false; 1440 1440 1441 1441 return true; 1442 1442 } -
uspace/srv/fs/exfat/exfat.c
r3061bc1 ra35b458 82 82 return -1; 83 83 } 84 84 85 85 rc = fs_register(vfs_sess, &exfat_vfs_info, &exfat_ops, &exfat_libfs_ops); 86 86 if (rc != EOK) { … … 88 88 goto err; 89 89 } 90 90 91 91 printf(NAME ": Accepting connections\n"); 92 92 task_retval(0); -
uspace/srv/fs/exfat/exfat.h
r3061bc1 ra35b458 133 133 /** Back pointer to the FS node. */ 134 134 fs_node_t *bp; 135 135 136 136 fibril_mutex_t lock; 137 137 exfat_node_type_t type; -
uspace/srv/fs/exfat/exfat_bitmap.c
r3061bc1 ra35b458 59 59 60 60 clst -= EXFAT_CLST_FIRST; 61 61 62 62 rc = exfat_bitmap_get(&fn, service_id); 63 63 if (rc != EOK) 64 64 return rc; 65 65 bitmapp = EXFAT_NODE(fn); 66 66 67 67 aoff64_t offset = clst / 8; 68 68 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE); … … 99 99 100 100 clst -= EXFAT_CLST_FIRST; 101 101 102 102 rc = exfat_bitmap_get(&fn, service_id); 103 103 if (rc != EOK) 104 104 return rc; 105 105 bitmapp = EXFAT_NODE(fn); 106 106 107 107 aoff64_t offset = clst / 8; 108 108 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE); … … 120 120 return rc; 121 121 } 122 122 123 123 return exfat_node_put(fn); 124 124 } … … 134 134 135 135 clst -= EXFAT_CLST_FIRST; 136 136 137 137 rc = exfat_bitmap_get(&fn, service_id); 138 138 if (rc != EOK) 139 139 return rc; 140 140 bitmapp = EXFAT_NODE(fn); 141 141 142 142 aoff64_t offset = clst / 8; 143 143 rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), … … 156 156 return rc; 157 157 } 158 158 159 159 return exfat_node_put(fn); 160 160 } -
uspace/srv/fs/exfat/exfat_directory.c
r3061bc1 ra35b458 91 91 { 92 92 errno_t rc = EOK; 93 93 94 94 if (di->b) { 95 95 rc = block_put(di->b); 96 96 di->b = NULL; 97 97 } 98 98 99 99 return rc; 100 100 } … … 141 141 if (rc != EOK) 142 142 di->pos -= 1; 143 143 144 144 return rc; 145 145 } … … 148 148 { 149 149 errno_t rc = EOK; 150 150 151 151 if (di->pos > 0) { 152 152 di->pos -= 1; … … 154 154 } else 155 155 return ENOENT; 156 156 157 157 if (rc != EOK) 158 158 di->pos += 1; 159 159 160 160 return rc; 161 161 } … … 170 170 if (rc != EOK) 171 171 di->pos = _pos; 172 172 173 173 return rc; 174 174 } … … 177 177 { 178 178 errno_t rc; 179 179 180 180 rc = exfat_directory_block_load(di); 181 181 if (rc == EOK) { … … 183 183 *d = ((exfat_dentry_t *)di->b->data) + o; 184 184 } 185 185 186 186 return rc; 187 187 } … … 197 197 return ENOENT; 198 198 } while (exfat_directory_next(di) == EOK); 199 199 200 200 return ENOENT; 201 201 } … … 222 222 size_t offset = 0; 223 223 aoff64_t start_pos = 0; 224 224 225 225 rc = exfat_directory_find(di, EXFAT_DENTRY_FILE, &d); 226 226 if (rc != EOK) … … 238 238 return ENOENT; 239 239 *ds = d->stream; 240 240 241 241 if (ds->name_size > size) 242 242 return EOVERFLOW; … … 470 470 di->b->dirty = true; 471 471 } 472 472 473 473 return exfat_directory_seek(di, pos); 474 474 } … … 486 486 return rc; 487 487 count = de->file.count + 1; 488 488 489 489 while (count) { 490 490 rc = exfat_directory_get(di, &de); … … 517 517 di->nodep->dirty = true; /* need to sync node */ 518 518 di->blocks = di->nodep->size / BPS(di->bs); 519 519 520 520 return EOK; 521 521 } -
uspace/srv/fs/exfat/exfat_fat.c
r3061bc1 ra35b458 516 516 blocks = ROUND_UP(nodep->size, BPS(bs))/BPS(bs); 517 517 count = BPS(bs); 518 518 519 519 for (i = 0; i < blocks; i++) { 520 520 rc = exfat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NOREAD); -
uspace/srv/fs/exfat/exfat_idx.c
r3061bc1 ra35b458 120 120 { 121 121 pos_key_t *pos = (pos_key_t*)key; 122 122 123 123 size_t hash = 0; 124 124 hash = hash_combine(pos->pfc, pos->pdi); … … 129 129 { 130 130 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 131 131 132 132 pos_key_t pkey = { 133 133 .service_id = fidx->service_id, … … 135 135 .pdi = fidx->pdi, 136 136 }; 137 137 138 138 return pos_key_hash(&pkey); 139 139 } … … 143 143 pos_key_t *pos = (pos_key_t*)key; 144 144 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 145 145 146 146 return pos->service_id == fidx->service_id 147 147 && pos->pdi == fidx->pdi … … 184 184 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 185 185 idx_key_t *key = (idx_key_t*)key_arg; 186 186 187 187 return key->index == fidx->index && key->service_id == fidx->service_id; 188 188 } … … 207 207 { 208 208 unused_t *u; 209 209 210 210 assert(index); 211 211 u = unused_find(service_id, true); … … 339 339 return ENOSPC; 340 340 } 341 341 342 342 fibril_mutex_initialize(&fidx->lock); 343 343 fidx->service_id = service_id; … … 361 361 return rc; 362 362 } 363 363 364 364 hash_table_insert(&ui_hash, &fidx->uih_link); 365 365 fibril_mutex_lock(&fidx->lock); … … 374 374 { 375 375 exfat_idx_t *fidx; 376 376 377 377 pos_key_t pos_key = { 378 378 .service_id = service_id, … … 393 393 return NULL; 394 394 } 395 395 396 396 fidx->pfc = pfc; 397 397 fidx->pdi = pdi; … … 515 515 hash_table_remove_item(&up_hash, item); 516 516 } 517 517 518 518 return true; 519 519 } … … 527 527 hash_table_remove_item(&ui_hash, item); 528 528 } 529 529 530 530 return true; 531 531 } -
uspace/srv/fs/exfat/exfat_ops.c
r3061bc1 ra35b458 519 519 service_id = parentp->idx->service_id; 520 520 fibril_mutex_unlock(&parentp->idx->lock); 521 521 522 522 exfat_directory_t di; 523 523 rc = exfat_directory_open(parentp, &di); … … 803 803 assert(childp->lnkcnt == 1); 804 804 fibril_mutex_lock(&childp->idx->lock); 805 805 806 806 exfat_directory_t di; 807 807 rc = exfat_directory_open(parentp,&di); … … 929 929 bs = block_bb_get(service_id); 930 930 *count = DATA_CNT(bs); 931 931 932 932 return EOK; 933 933 } -
uspace/srv/fs/ext4fs/ext4fs.c
r3061bc1 ra35b458 56 56 { 57 57 printf("%s: HelenOS ext4 file system server\n", NAME); 58 58 59 59 if (argc == 3) { 60 60 if (!str_cmp(argv[1], "--instance")) … … 65 65 } 66 66 } 67 67 68 68 async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS, 69 69 INTERFACE_VFS_DRIVER, 0); … … 72 72 return 2; 73 73 } 74 74 75 75 errno_t rc = ext4_global_init(); 76 76 if (rc != EOK) { … … 78 78 return rc; 79 79 } 80 80 81 81 rc = fs_register(vfs_sess, &ext4fs_vfs_info, &ext4_ops, 82 82 &ext4_libfs_ops); … … 85 85 return rc; 86 86 } 87 87 88 88 printf("%s: Accepting connections\n", NAME); 89 89 task_retval(0); 90 90 async_manager(); 91 91 92 92 /* Not reached */ 93 93 return 0; -
uspace/srv/fs/fat/fat.c
r3061bc1 ra35b458 62 62 { 63 63 printf(NAME ": HelenOS FAT file system server\n"); 64 64 65 65 if (argc == 3) { 66 66 if (!str_cmp(argv[1], "--instance")) … … 75 75 if (rc != EOK) 76 76 goto err; 77 77 78 78 async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS, 79 79 INTERFACE_VFS_DRIVER, 0); … … 82 82 return -1; 83 83 } 84 84 85 85 rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops); 86 86 if (rc != EOK) { … … 88 88 goto err; 89 89 } 90 90 91 91 printf(NAME ": Accepting connections\n"); 92 92 task_retval(0); 93 93 async_manager(); 94 94 95 95 /* Not reached */ 96 96 return 0; 97 97 98 98 err: 99 99 printf(NAME ": Failed to register file system: %s\n", str_error(rc)); -
uspace/srv/fs/fat/fat.h
r3061bc1 ra35b458 213 213 /** Back pointer to the FS node. */ 214 214 fs_node_t *bp; 215 215 216 216 fibril_mutex_t lock; 217 217 fat_node_type_t type; -
uspace/srv/fs/fat/fat_dentry.c
r3061bc1 ra35b458 81 81 { 82 82 unsigned int i; 83 83 84 84 for (i = 0; i < FAT_NAME_LEN; i++) { 85 85 if (d->name[i] == FAT_PAD) 86 86 break; 87 87 88 88 if (d->name[i] == FAT_DENTRY_E5_ESC) 89 89 *buf++ = 0xe5; … … 95 95 } 96 96 } 97 97 98 98 if (d->ext[0] != FAT_PAD) 99 99 *buf++ = '.'; 100 100 101 101 for (i = 0; i < FAT_EXT_LEN; i++) { 102 102 if (d->ext[i] == FAT_PAD) { … … 104 104 return; 105 105 } 106 106 107 107 if (d->ext[i] == FAT_DENTRY_E5_ESC) 108 108 *buf++ = 0xe5; … … 114 114 } 115 115 } 116 116 117 117 *buf = '\0'; 118 118 } … … 124 124 bool lower_name = true; 125 125 bool lower_ext = true; 126 126 127 127 for (i = 0; i < FAT_NAME_LEN; i++) { 128 128 switch ((uint8_t) *name) { … … 140 140 lower_name = false; 141 141 } 142 142 143 143 d->name[i] = toupper(*name++); 144 144 break; 145 145 } 146 146 } 147 147 148 148 if (*name++ != '.') 149 149 name = fake_ext; 150 150 151 151 for (i = 0; i < FAT_EXT_LEN; i++) { 152 152 switch ((uint8_t) *name) { … … 163 163 lower_ext = false; 164 164 } 165 165 166 166 d->ext[i] = toupper(*name++); 167 167 break; 168 168 } 169 169 } 170 170 171 171 if (lower_name) 172 172 d->lcase |= FAT_LCASE_LOWER_NAME; 173 173 else 174 174 d->lcase &= ~FAT_LCASE_LOWER_NAME; 175 175 176 176 if (lower_ext) 177 177 d->lcase |= FAT_LCASE_LOWER_EXT; … … 183 183 { 184 184 unsigned int i; 185 185 186 186 for (i = 0; i < FAT_NAME_LEN; i++) { 187 187 if (d->name[i] == FAT_PAD) 188 188 break; 189 189 190 190 if (d->name[i] == FAT_DENTRY_E5_ESC) 191 191 *buf++ = 0xe5; … … 193 193 *buf++ = d->name[i]; 194 194 } 195 195 196 196 for (i = 0; i < FAT_EXT_LEN; i++) { 197 197 if (d->ext[i] == FAT_PAD) { … … 199 199 return; 200 200 } 201 201 202 202 if (d->ext[i] == FAT_DENTRY_E5_ESC) 203 203 *buf++ = 0xe5; … … 205 205 *buf++ = d->ext[i]; 206 206 } 207 207 208 208 *buf = '\0'; 209 209 } … … 291 291 { 292 292 size_t size = 0; 293 293 294 294 size += fat_lfn_str_nlength(FAT_LFN_PART1(d), FAT_LFN_PART1_SIZE); 295 295 size += fat_lfn_str_nlength(FAT_LFN_PART2(d), FAT_LFN_PART2_SIZE); 296 296 size += fat_lfn_str_nlength(FAT_LFN_PART3(d), FAT_LFN_PART3_SIZE); 297 297 298 298 return size; 299 299 } … … 354 354 d->lfn.type = 0; 355 355 d->lfn.firstc_lo = 0; 356 356 357 357 return *offset; 358 358 } … … 363 363 size_t off = 0; 364 364 size_t i = 0; 365 365 366 366 while (i < count) { 367 367 if ((ch = str_decode(src, &off, STR_NO_LIMIT)) != 0) { … … 384 384 size_t offset=0; 385 385 bool result = true; 386 386 387 387 while ((ch = str_decode(name, &offset, STR_NO_LIMIT)) != 0) { 388 388 if (str_chr(FAT_STOP_CHARS, ch) != NULL) { -
uspace/srv/fs/fat/fat_dentry.h
r3061bc1 ra35b458 60 60 #define FAT_ATTR_LFN \ 61 61 (FAT_ATTR_RDONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLLABEL) 62 62 63 63 #define FAT_LCASE_LOWER_NAME 0x08 64 64 #define FAT_LCASE_LOWER_EXT 0x10 -
uspace/srv/fs/fat/fat_directory.c
r3061bc1 ra35b458 65 65 { 66 66 errno_t rc = EOK; 67 67 68 68 if (di->b) 69 69 rc = block_put(di->b); 70 70 71 71 return rc; 72 72 } … … 106 106 if (rc != EOK) 107 107 di->pos -= 1; 108 108 109 109 return rc; 110 110 } … … 113 113 { 114 114 errno_t rc = EOK; 115 115 116 116 if (di->pos > 0) { 117 117 di->pos -= 1; … … 119 119 } else 120 120 return ENOENT; 121 121 122 122 if (rc != EOK) 123 123 di->pos += 1; 124 124 125 125 return rc; 126 126 } … … 135 135 if (rc != EOK) 136 136 di->pos = _pos; 137 137 138 138 return rc; 139 139 } … … 142 142 { 143 143 errno_t rc; 144 144 145 145 rc = fat_directory_block_load(di); 146 146 if (rc == EOK) { … … 148 148 *d = ((fat_dentry_t *)di->b->data) + o; 149 149 } 150 150 151 151 return rc; 152 152 } … … 168 168 assert(rc == EOK); 169 169 instance = (fat_instance_t *) data; 170 170 171 171 do { 172 172 rc = fat_directory_get(di, &d); … … 220 220 } else 221 221 fat_dentry_name_get(d, name); 222 222 223 223 *de = d; 224 224 return EOK; … … 232 232 } 233 233 } while (fat_directory_next(di) == EOK); 234 234 235 235 return ENOENT; 236 236 } … … 250 250 d->name[0] = FAT_DENTRY_ERASED; 251 251 di->b->dirty = true; 252 252 253 253 while (!flag && fat_directory_prev(di) == EOK) { 254 254 if (fat_directory_get(di, &d) == EOK && … … 276 276 assert(rc == EOK); 277 277 instance = (fat_instance_t *) data; 278 278 279 279 if (fat_valid_short_name(name)) { 280 280 /* … … 296 296 uint16_t wname[FAT_LFN_NAME_LEN]; 297 297 size_t lfn_size, lfn_offset; 298 298 299 299 rc = str_to_utf16(wname, FAT_LFN_NAME_LEN, name); 300 300 if (rc != EOK) 301 301 return rc; 302 302 303 303 lfn_size = utf16_wsize(wname); 304 304 long_entry_count = lfn_size / FAT_LFN_ENTRY_SIZE; … … 440 440 di->nodep->dirty = true; /* need to sync node */ 441 441 di->blocks = di->nodep->size / BPS(di->bs); 442 442 443 443 return EOK; 444 444 } … … 450 450 aoff64_t pos; 451 451 errno_t rc; 452 452 453 453 do { 454 454 found = 0; -
uspace/srv/fs/fat/fat_fat.c
r3061bc1 ra35b458 344 344 else 345 345 *value = (*value) & FAT12_MASK; 346 346 347 347 rc = block_put(b); 348 348 … … 463 463 if (offset / BPS(bs) >= SF(bs)) 464 464 return ERANGE; 465 465 466 466 rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno + 467 467 offset / BPS(bs), BLOCK_FLAGS_NONE); … … 687 687 if (!lifo) 688 688 return ENOMEM; 689 689 690 690 /* 691 691 * Search FAT1 for unused clusters. -
uspace/srv/fs/fat/fat_idx.c
r3061bc1 ra35b458 120 120 { 121 121 pos_key_t *pos = (pos_key_t*)key; 122 122 123 123 size_t hash = 0; 124 124 hash = hash_combine(pos->pfc, pos->pdi); … … 129 129 { 130 130 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 131 131 132 132 pos_key_t pkey = { 133 133 .service_id = fidx->service_id, … … 135 135 .pdi = fidx->pdi, 136 136 }; 137 137 138 138 return pos_key_hash(&pkey); 139 139 } … … 143 143 pos_key_t *pos = (pos_key_t*)key; 144 144 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 145 145 146 146 return pos->service_id == fidx->service_id 147 147 && pos->pdi == fidx->pdi … … 184 184 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 185 185 idx_key_t *key = (idx_key_t*)key_arg; 186 186 187 187 return key->index == fidx->index && key->service_id == fidx->service_id; 188 188 } … … 207 207 { 208 208 unused_t *u; 209 209 210 210 assert(index); 211 211 u = unused_find(service_id, true); … … 339 339 return ENOSPC; 340 340 } 341 341 342 342 fibril_mutex_initialize(&fidx->lock); 343 343 fidx->service_id = service_id; … … 361 361 return rc; 362 362 } 363 363 364 364 hash_table_insert(&ui_hash, &fidx->uih_link); 365 365 fibril_mutex_lock(&fidx->lock); … … 393 393 return NULL; 394 394 } 395 395 396 396 fidx->pfc = pfc; 397 397 fidx->pdi = pdi; … … 514 514 hash_table_remove_item(&up_hash, item); 515 515 } 516 516 517 517 return true; 518 518 } … … 526 526 hash_table_remove_item(&ui_hash, item); 527 527 } 528 528 529 529 return true; 530 530 } -
uspace/srv/fs/fat/fat_ops.c
r3061bc1 ra35b458 381 381 service_id = parentp->idx->service_id; 382 382 fibril_mutex_unlock(&parentp->idx->lock); 383 383 384 384 fat_directory_t di; 385 385 rc = fat_directory_open(parentp, &di); … … 716 716 assert(childp->lnkcnt == 1); 717 717 fibril_mutex_lock(&childp->idx->lock); 718 718 719 719 fat_directory_t di; 720 720 rc = fat_directory_open(parentp, &di); … … 856 856 { 857 857 fat_bs_t *bs; 858 858 859 859 bs = block_bb_get(service_id); 860 860 *count = (SPC(bs)) ? TS(bs) / SPC(bs) : 0; … … 883 883 } 884 884 *count = block_count; 885 885 886 886 return EOK; 887 887 } … … 1330 1330 int flags = BLOCK_FLAGS_NONE; 1331 1331 errno_t rc; 1332 1332 1333 1333 rc = fat_node_get(&fn, service_id, index); 1334 1334 if (rc != EOK) -
uspace/srv/fs/locfs/locfs.c
r3061bc1 ra35b458 63 63 { 64 64 printf("%s: HelenOS Device Filesystem\n", NAME); 65 65 66 66 if (argc == 3) { 67 67 if (!str_cmp(argv[1], "--instance")) … … 78 78 return -1; 79 79 } 80 80 81 81 async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS, 82 82 INTERFACE_VFS_DRIVER, 0); … … 85 85 return -1; 86 86 } 87 87 88 88 errno_t rc = fs_register(vfs_sess, &locfs_vfs_info, &locfs_ops, 89 89 &locfs_libfs_ops); … … 92 92 return rc; 93 93 } 94 94 95 95 printf("%s: Accepting connections\n", NAME); 96 96 task_retval(0); 97 97 async_manager(); 98 98 99 99 /* Not reached */ 100 100 return 0; -
uspace/srv/fs/locfs/locfs_ops.c
r3061bc1 ra35b458 109 109 return ENOMEM; 110 110 } 111 111 112 112 *rfn = (fs_node_t *) malloc(sizeof(fs_node_t)); 113 113 if (*rfn == NULL) { … … 116 116 return ENOMEM; 117 117 } 118 118 119 119 fs_node_initialize(*rfn); 120 120 node->type = type; 121 121 node->service_id = service_id; 122 122 123 123 (*rfn)->data = node; 124 124 return EOK; … … 134 134 locfs_node_t *node = (locfs_node_t *) pfn->data; 135 135 errno_t ret; 136 136 137 137 if (node->service_id == 0) { 138 138 /* Root directory */ 139 139 140 140 loc_sdesc_t *nspaces; 141 141 size_t count = loc_get_namespaces(&nspaces); 142 142 143 143 if (count > 0) { 144 144 size_t pos; … … 147 147 if (str_cmp(nspaces[pos].name, "") == 0) 148 148 continue; 149 149 150 150 if (str_cmp(nspaces[pos].name, component) == 0) { 151 151 ret = locfs_node_get_internal(rfn, LOC_OBJECT_NAMESPACE, nspaces[pos].id); … … 154 154 } 155 155 } 156 156 157 157 free(nspaces); 158 158 } 159 159 160 160 /* Search root namespace */ 161 161 service_id_t namespace; … … 163 163 if (loc_namespace_get_id("", &namespace, 0) == EOK) { 164 164 count = loc_get_services(namespace, &svcs); 165 165 166 166 if (count > 0) { 167 167 size_t pos; … … 173 173 } 174 174 } 175 175 176 176 free(svcs); 177 177 } 178 178 } 179 179 180 180 *rfn = NULL; 181 181 return EOK; 182 182 } 183 183 184 184 if (node->type == LOC_OBJECT_NAMESPACE) { 185 185 /* Namespace directory */ 186 186 187 187 loc_sdesc_t *svcs; 188 188 size_t count = loc_get_services(node->service_id, &svcs); … … 196 196 } 197 197 } 198 198 199 199 free(svcs); 200 200 } 201 201 202 202 *rfn = NULL; 203 203 return EOK; 204 204 } 205 205 206 206 *rfn = NULL; 207 207 return EOK; … … 216 216 { 217 217 locfs_node_t *node = (locfs_node_t *) fn->data; 218 218 219 219 if (node->service_id == 0) { 220 220 /* Root directory */ 221 221 return EOK; 222 222 } 223 223 224 224 loc_object_type_t type = loc_id_probe(node->service_id); 225 225 226 226 if (type == LOC_OBJECT_NAMESPACE) { 227 227 /* Namespace directory */ 228 228 return EOK; 229 229 } 230 230 231 231 if (type == LOC_OBJECT_SERVICE) { 232 232 /* Device node */ 233 233 234 234 fibril_mutex_lock(&services_mutex); 235 235 ht_link_t *lnk; … … 242 242 return ENOMEM; 243 243 } 244 244 245 245 dev->service_id = node->service_id; 246 246 247 247 /* Mark as incomplete */ 248 248 dev->sess = NULL; 249 249 dev->refcount = 1; 250 250 fibril_condvar_initialize(&dev->cv); 251 251 252 252 /* 253 253 * Insert the incomplete device structure so that other … … 256 256 */ 257 257 hash_table_insert(&services, &dev->link); 258 258 259 259 /* 260 260 * Drop the mutex to allow recursive locfs requests. 261 261 */ 262 262 fibril_mutex_unlock(&services_mutex); 263 263 264 264 async_sess_t *sess = loc_service_connect(node->service_id, 265 265 INTERFACE_FS, 0); 266 266 267 267 fibril_mutex_lock(&services_mutex); 268 268 269 269 /* 270 270 * Notify possible waiters about this device structure … … 272 272 */ 273 273 fibril_condvar_broadcast(&dev->cv); 274 274 275 275 if (!sess) { 276 276 /* … … 280 280 hash_table_remove(&services, &node->service_id); 281 281 fibril_mutex_unlock(&services_mutex); 282 282 283 283 return ENOENT; 284 284 } 285 285 286 286 /* Set the correct session. */ 287 287 dev->sess = sess; 288 288 } else { 289 289 service_t *dev = hash_table_get_inst(lnk, service_t, link); 290 290 291 291 if (!dev->sess) { 292 292 /* … … 303 303 dev->refcount++; 304 304 } 305 305 306 306 fibril_mutex_unlock(&services_mutex); 307 308 return EOK; 309 } 310 307 308 return EOK; 309 } 310 311 311 return ENOENT; 312 312 } … … 322 322 { 323 323 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); 324 324 325 325 *rfn = NULL; 326 326 return ENOTSUP; … … 345 345 { 346 346 locfs_node_t *node = (locfs_node_t *) fn->data; 347 347 348 348 if (node->service_id == 0) { 349 349 size_t count = loc_count_namespaces(); … … 352 352 return EOK; 353 353 } 354 354 355 355 /* Root namespace */ 356 356 service_id_t namespace; … … 362 362 } 363 363 } 364 364 365 365 *has_children = false; 366 366 return EOK; 367 367 } 368 368 369 369 if (node->type == LOC_OBJECT_NAMESPACE) { 370 370 size_t count = loc_count_services(node->service_id); … … 373 373 return EOK; 374 374 } 375 375 376 376 *has_children = false; 377 377 return EOK; 378 378 } 379 379 380 380 *has_children = false; 381 381 return EOK; … … 396 396 { 397 397 locfs_node_t *node = (locfs_node_t *) fn->data; 398 398 399 399 if (node->service_id == 0) 400 400 return 0; 401 401 402 402 return 1; 403 403 } … … 406 406 { 407 407 locfs_node_t *node = (locfs_node_t *) fn->data; 408 408 409 409 return ((node->type == LOC_OBJECT_NONE) || (node->type == LOC_OBJECT_NAMESPACE)); 410 410 } … … 413 413 { 414 414 locfs_node_t *node = (locfs_node_t *) fn->data; 415 415 416 416 return (node->type == LOC_OBJECT_SERVICE); 417 417 } … … 420 420 { 421 421 locfs_node_t *node = (locfs_node_t *) fn->data; 422 422 423 423 if (node->type == LOC_OBJECT_SERVICE) 424 424 return node->service_id; 425 425 426 426 return 0; 427 427 } … … 451 451 if (!hash_table_create(&services, 0, 0, &services_ops)) 452 452 return false; 453 453 454 454 return true; 455 455 } … … 484 484 return EINVAL; 485 485 } 486 486 487 487 loc_sdesc_t *desc; 488 488 size_t count = loc_get_namespaces(&desc); 489 489 490 490 /* Get rid of root namespace */ 491 491 size_t i; … … 494 494 if (pos >= i) 495 495 pos++; 496 496 497 497 break; 498 498 } 499 499 } 500 500 501 501 if (pos < count) { 502 502 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); … … 505 505 return EOK; 506 506 } 507 507 508 508 free(desc); 509 509 pos -= count; 510 510 511 511 /* Search root namespace */ 512 512 service_id_t namespace; 513 513 if (loc_namespace_get_id("", &namespace, 0) == EOK) { 514 514 count = loc_get_services(namespace, &desc); 515 515 516 516 if (pos < count) { 517 517 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); … … 520 520 return EOK; 521 521 } 522 522 523 523 free(desc); 524 524 } 525 525 526 526 async_answer_0(callid, ENOENT); 527 527 return ENOENT; 528 528 } 529 529 530 530 loc_object_type_t type = loc_id_probe(index); 531 531 532 532 if (type == LOC_OBJECT_NAMESPACE) { 533 533 /* Namespace directory */ … … 538 538 return EINVAL; 539 539 } 540 540 541 541 loc_sdesc_t *desc; 542 542 size_t count = loc_get_services(index, &desc); 543 543 544 544 if (pos < count) { 545 545 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); … … 548 548 return EOK; 549 549 } 550 550 551 551 free(desc); 552 552 async_answer_0(callid, ENOENT); 553 553 return ENOENT; 554 554 } 555 555 556 556 if (type == LOC_OBJECT_SERVICE) { 557 557 /* Device node */ 558 558 559 559 fibril_mutex_lock(&services_mutex); 560 560 service_id_t service_index = index; … … 564 564 return ENOENT; 565 565 } 566 566 567 567 service_t *dev = hash_table_get_inst(lnk, service_t, link); 568 568 assert(dev->sess); 569 569 570 570 ipc_callid_t callid; 571 571 if (!async_data_read_receive(&callid, NULL)) { … … 574 574 return EINVAL; 575 575 } 576 576 577 577 /* Make a request at the driver */ 578 578 async_exch_t *exch = async_exchange_begin(dev->sess); 579 579 580 580 ipc_call_t answer; 581 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, service_id, 582 582 index, LOWER32(pos), UPPER32(pos), &answer); 583 583 584 584 /* Forward the IPC_M_DATA_READ request to the driver */ 585 585 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 586 586 587 587 async_exchange_end(exch); 588 588 589 589 fibril_mutex_unlock(&services_mutex); 590 590 591 591 /* Wait for reply from the driver. */ 592 592 errno_t rc; … … 596 596 if ((errno_t) rc == EHANGUP) 597 597 rc = ENOTSUP; 598 598 599 599 *rbytes = IPC_GET_ARG1(answer); 600 600 return rc; 601 601 } 602 602 603 603 return ENOENT; 604 604 } … … 610 610 if (index == 0) 611 611 return ENOTSUP; 612 612 613 613 loc_object_type_t type = loc_id_probe(index); 614 614 615 615 if (type == LOC_OBJECT_NAMESPACE) { 616 616 /* Namespace directory */ 617 617 return ENOTSUP; 618 618 } 619 619 620 620 if (type == LOC_OBJECT_SERVICE) { 621 621 /* Device node */ 622 622 623 623 fibril_mutex_lock(&services_mutex); 624 624 service_id_t service_index = index; … … 628 628 return ENOENT; 629 629 } 630 630 631 631 service_t *dev = hash_table_get_inst(lnk, service_t, link); 632 632 assert(dev->sess); 633 633 634 634 ipc_callid_t callid; 635 635 if (!async_data_write_receive(&callid, NULL)) { … … 638 638 return EINVAL; 639 639 } 640 640 641 641 /* Make a request at the driver */ 642 642 async_exch_t *exch = async_exchange_begin(dev->sess); 643 643 644 644 ipc_call_t answer; 645 645 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, service_id, 646 646 index, LOWER32(pos), UPPER32(pos), &answer); 647 647 648 648 /* Forward the IPC_M_DATA_WRITE request to the driver */ 649 649 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 650 650 651 651 async_exchange_end(exch); 652 652 653 653 fibril_mutex_unlock(&services_mutex); 654 654 655 655 /* Wait for reply from the driver. */ 656 656 errno_t rc; … … 660 660 if ((errno_t) rc == EHANGUP) 661 661 rc = ENOTSUP; 662 662 663 663 *wbytes = IPC_GET_ARG1(answer); 664 664 *nsize = 0; 665 665 return rc; 666 666 } 667 667 668 668 return ENOENT; 669 669 } … … 679 679 if (index == 0) 680 680 return EOK; 681 681 682 682 loc_object_type_t type = loc_id_probe(index); 683 683 684 684 if (type == LOC_OBJECT_NAMESPACE) { 685 685 /* Namespace directory */ 686 686 return EOK; 687 687 } 688 688 689 689 if (type == LOC_OBJECT_SERVICE) { 690 690 691 691 fibril_mutex_lock(&services_mutex); 692 692 service_id_t service_index = index; … … 696 696 return ENOENT; 697 697 } 698 698 699 699 service_t *dev = hash_table_get_inst(lnk, service_t, link); 700 700 assert(dev->sess); 701 701 dev->refcount--; 702 702 703 703 if (dev->refcount == 0) { 704 704 async_hangup(dev->sess); … … 706 706 hash_table_remove(&services, &service_index); 707 707 } 708 708 709 709 fibril_mutex_unlock(&services_mutex); 710 711 return EOK; 712 } 713 710 711 return EOK; 712 } 713 714 714 return ENOENT; 715 715 } … … 719 719 if (index == 0) 720 720 return EOK; 721 721 722 722 loc_object_type_t type = loc_id_probe(index); 723 723 724 724 if (type == LOC_OBJECT_NAMESPACE) { 725 725 /* Namespace directory */ 726 726 return EOK; 727 727 } 728 728 729 729 if (type == LOC_OBJECT_SERVICE) { 730 730 … … 736 736 return ENOENT; 737 737 } 738 738 739 739 service_t *dev = hash_table_get_inst(lnk, service_t, link); 740 740 assert(dev->sess); 741 741 742 742 /* Make a request at the driver */ 743 743 async_exch_t *exch = async_exchange_begin(dev->sess); 744 744 745 745 ipc_call_t answer; 746 746 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, service_id, 747 747 index, &answer); 748 748 749 749 async_exchange_end(exch); 750 750 751 751 fibril_mutex_unlock(&services_mutex); 752 752 753 753 /* Wait for reply from the driver */ 754 754 errno_t rc; 755 755 async_wait_for(msg, &rc); 756 756 757 757 return rc; 758 758 } 759 759 760 760 return ENOENT; 761 761 } -
uspace/srv/fs/mfs/mfs_ops.c
r3061bc1 ra35b458 617 617 .index = index 618 618 }; 619 619 620 620 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 621 621 … … 974 974 if (r != EOK) 975 975 goto out_err; 976 976 977 977 r = mfs_write_map(mnode, pos, block, &dummy); 978 978 if (r != EOK) { … … 1202 1202 if (NULL == inst) 1203 1203 return ENOENT; 1204 1204 1205 1205 *size = inst->sbi->block_size; 1206 1206 … … 1213 1213 struct mfs_instance *inst; 1214 1214 errno_t rc; 1215 1215 1216 1216 rc = mfs_instance_get(service_id, &inst); 1217 1217 if (rc != EOK) … … 1220 1220 if (NULL == inst) 1221 1221 return ENOENT; 1222 1222 1223 1223 *count = (uint64_t) MFS_BMAP_SIZE_BITS(inst->sbi, BMAP_ZONE); 1224 1224 … … 1230 1230 { 1231 1231 uint32_t block_free; 1232 1232 1233 1233 struct mfs_instance *inst; 1234 1234 errno_t rc = mfs_instance_get(service_id, &inst); -
uspace/srv/fs/mfs/mfs_rw.c
r3061bc1 ra35b458 249 249 250 250 mfs_version_t fs_version = sbi->fs_version; 251 251 252 252 assert(new_size <= ino_i->i_size); 253 253 -
uspace/srv/fs/tmpfs/tmpfs.c
r3061bc1 ra35b458 75 75 } 76 76 } 77 77 78 78 if (!tmpfs_init()) { 79 79 printf(NAME ": failed to initialize TMPFS\n"); 80 80 return -1; 81 81 } 82 82 83 83 async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS, 84 84 INTERFACE_VFS_DRIVER, 0); … … 87 87 return -1; 88 88 } 89 89 90 90 errno_t rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops, 91 91 &tmpfs_libfs_ops); … … 94 94 return rc; 95 95 } 96 96 97 97 printf(NAME ": Accepting connections\n"); 98 98 task_retval(0); 99 99 async_manager(); 100 100 101 101 /* Not reached */ 102 102 return 0; -
uspace/srv/fs/tmpfs/tmpfs_dump.c
r3061bc1 ra35b458 64 64 libfs_ops_t *ops = &tmpfs_libfs_ops; 65 65 errno_t rc; 66 66 67 67 do { 68 68 char *fname; … … 70 70 tmpfs_node_t *nodep; 71 71 uint32_t size; 72 72 73 73 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &entry, 74 74 sizeof(entry)) != EOK) 75 75 return false; 76 76 77 77 entry.len = uint32_t_le2host(entry.len); 78 78 79 79 switch (entry.type) { 80 80 case TMPFS_NONE: … … 84 84 if (fname == NULL) 85 85 return false; 86 86 87 87 rc = ops->create(&fn, dsid, L_FILE); 88 88 if (rc != EOK || fn == NULL) { … … 90 90 return false; 91 91 } 92 92 93 93 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname, 94 94 entry.len) != EOK) { … … 98 98 } 99 99 fname[entry.len] = 0; 100 100 101 101 rc = ops->link(pfn, fn, fname); 102 102 if (rc != EOK) { … … 106 106 } 107 107 free(fname); 108 108 109 109 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, &size, 110 110 sizeof(size)) != EOK) 111 111 return false; 112 112 113 113 size = uint32_t_le2host(size); 114 114 115 115 nodep = TMPFS_NODE(fn); 116 116 nodep->data = malloc(size); 117 117 if (nodep->data == NULL) 118 118 return false; 119 119 120 120 nodep->size = size; 121 121 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, nodep->data, 122 122 size) != EOK) 123 123 return false; 124 124 125 125 break; 126 126 case TMPFS_DIRECTORY: … … 128 128 if (fname == NULL) 129 129 return false; 130 130 131 131 rc = ops->create(&fn, dsid, L_DIRECTORY); 132 132 if (rc != EOK || fn == NULL) { … … 134 134 return false; 135 135 } 136 136 137 137 if (block_seqread(dsid, tmpfs_buf, bufpos, buflen, pos, fname, 138 138 entry.len) != EOK) { … … 150 150 } 151 151 free(fname); 152 152 153 153 if (!tmpfs_restore_recursion(dsid, bufpos, buflen, pos, 154 154 fn)) 155 155 return false; 156 156 157 157 break; 158 158 default: … … 160 160 } 161 161 } while (entry.type != TMPFS_NONE); 162 162 163 163 return true; 164 164 } … … 173 173 if (rc != EOK) 174 174 return false; 175 175 176 176 size_t bufpos = 0; 177 177 size_t buflen = 0; 178 178 aoff64_t pos = 0; 179 179 180 180 char tag[6]; 181 181 if (block_seqread(dsid, tmpfs_buf, &bufpos, &buflen, &pos, tag, 5) != EOK) 182 182 goto error; 183 183 184 184 tag[5] = 0; 185 185 if (str_cmp(tag, "TMPFS") != 0) 186 186 goto error; 187 187 188 188 rc = ops->root_get(&fn, dsid); 189 189 if (rc != EOK) … … 192 192 if (!tmpfs_restore_recursion(dsid, &bufpos, &buflen, &pos, fn)) 193 193 goto error; 194 194 195 195 block_fini(dsid); 196 196 return true; 197 197 198 198 error: 199 199 block_fini(dsid); -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r3061bc1 ra35b458 163 163 tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link); 164 164 node_key_t *key = (node_key_t *)key_arg; 165 165 166 166 return key->service_id == node->service_id && key->index == node->index; 167 167 } … … 220 220 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 221 221 return false; 222 222 223 223 return true; 224 224 } … … 228 228 fs_node_t *rfn; 229 229 errno_t rc; 230 230 231 231 rc = tmpfs_create_node(&rfn, service_id, L_DIRECTORY); 232 232 if (rc != EOK || !rfn) … … 240 240 service_id_t sid = *(service_id_t*)arg; 241 241 tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link); 242 242 243 243 if (node->service_id == sid) { 244 244 hash_table_remove_item(&nodes, &node->nh_link); … … 273 273 .index = index 274 274 }; 275 275 276 276 ht_link_t *lnk = hash_table_find(&nodes, &key); 277 277 278 278 if (lnk) { 279 279 tmpfs_node_t *nodep; … … 338 338 { 339 339 tmpfs_node_t *nodep = TMPFS_NODE(fn); 340 340 341 341 assert(!nodep->lnkcnt); 342 342 assert(list_empty(&nodep->cs_list)); 343 343 344 344 hash_table_remove_item(&nodes, &nodep->nh_link); 345 345 … … 406 406 if (!childp) 407 407 return ENOENT; 408 408 409 409 if ((childp->lnkcnt == 1) && !list_empty(&childp->cs_list)) 410 410 return ENOTEMPTY; … … 432 432 fs_node_t *rootfn; 433 433 errno_t rc; 434 434 435 435 /* Check if this device is not already mounted. */ 436 436 rc = tmpfs_root_get(&rootfn, service_id); … … 474 474 .index = index 475 475 }; 476 476 477 477 ht_link_t *hlp = hash_table_find(&nodes, &key); 478 478 if (!hlp) 479 479 return ENOENT; 480 480 481 481 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 482 482 483 483 /* 484 484 * Receive the read request. … … 499 499 tmpfs_dentry_t *dentryp; 500 500 link_t *lnk; 501 501 502 502 assert(nodep->type == TMPFS_DIRECTORY); 503 503 504 504 /* 505 505 * Yes, we really use O(n) algorithm here. … … 508 508 */ 509 509 lnk = list_nth(&nodep->cs_list, pos); 510 510 511 511 if (lnk == NULL) { 512 512 async_answer_0(callid, ENOENT); … … 536 536 .index = index 537 537 }; 538 538 539 539 ht_link_t *hlp = hash_table_find(&nodes, &key); 540 540 541 541 if (!hlp) 542 542 return ENOENT; 543 543 544 544 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 545 545 … … 599 599 .index = index 600 600 }; 601 601 602 602 ht_link_t *hlp = hash_table_find(&nodes, &key); 603 603 604 604 if (!hlp) 605 605 return ENOENT; 606 606 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 607 607 608 608 if (size == nodep->size) 609 609 return EOK; 610 610 611 611 if (size > SIZE_MAX) 612 612 return ENOMEM; 613 613 614 614 void *newdata = realloc(nodep->data, size); 615 615 if (!newdata) 616 616 return ENOMEM; 617 617 618 618 if (size > nodep->size) { 619 619 size_t delta = size - nodep->size; 620 620 memset(newdata + nodep->size, 0, delta); 621 621 } 622 622 623 623 nodep->size = size; 624 624 nodep->data = newdata; … … 637 637 .index = index 638 638 }; 639 639 640 640 ht_link_t *hlp = hash_table_find(&nodes, &key); 641 641 if (!hlp) -
uspace/srv/fs/udf/udf.c
r3061bc1 ra35b458 63 63 log_init(NAME); 64 64 log_msg(LOG_DEFAULT, LVL_NOTE, "HelenOS UDF 1.02 file system server"); 65 65 66 66 if (argc == 3) { 67 67 if (!str_cmp(argv[1], "--instance")) … … 72 72 } 73 73 } 74 74 75 75 async_sess_t *vfs_sess = 76 76 service_connect_blocking(SERVICE_VFS, INTERFACE_VFS_DRIVER, 0); … … 79 79 return 2; 80 80 } 81 81 82 82 errno_t rc = fs_register(vfs_sess, &udf_vfs_info, &udf_ops, 83 83 &udf_libfs_ops); 84 84 if (rc != EOK) 85 85 goto err; 86 86 87 87 rc = udf_idx_init(); 88 88 if (rc != EOK) 89 89 goto err; 90 90 91 91 log_msg(LOG_DEFAULT, LVL_NOTE, "Accepting connections"); 92 92 task_retval(0); 93 93 async_manager(); 94 94 95 95 /* Not reached */ 96 96 return 0; 97 97 98 98 err: 99 99 log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to register file system: %s", str_error(rc)); -
uspace/srv/fs/udf/udf.h
r3061bc1 ra35b458 85 85 size_t open_nodes_count; 86 86 udf_charspec_t charset; 87 87 88 88 uint32_t sector_size; 89 89 udf_lvolume_t *volumes; … … 105 105 fs_node_t *fs_node; 106 106 fibril_mutex_t lock; 107 107 108 108 fs_index_t index; /* FID logical block */ 109 109 ht_link_t link; 110 110 size_t ref_cnt; 111 111 size_t link_cnt; 112 112 113 113 uint8_t type; /* 1 - file, 0 - directory */ 114 114 uint64_t data_size; -
uspace/srv/fs/udf/udf_cksum.c
r3061bc1 ra35b458 79 79 { 80 80 uint16_t crc = 0; 81 81 82 82 while (len-- > 0) { 83 83 /* … … 88 88 crc = crc_table[(crc >> 8 ^ (*buf++ & 0xff)) & 0xff] ^ (crc << 8); 89 89 } 90 90 91 91 return crc; 92 92 } … … 98 98 { 99 99 uint8_t result = 0; 100 100 101 101 for (size_t i = 0; i < UDF_TAG_SIZE; i++) { 102 102 if (i == 4) 103 103 continue; 104 104 105 105 result = (result + tag[i]) % 256; 106 106 } 107 107 108 108 return result; 109 109 } -
uspace/srv/fs/udf/udf_file.c
r3061bc1 ra35b458 65 65 if (rc != EOK) 66 66 return rc; 67 67 68 68 udf_ext_ad_t *exd = (udf_ext_ad_t *) block->data; 69 69 uint32_t start = node->instance->partitions[ 70 70 FLE16(exd->extent_location.partition_num)].start + 71 71 FLE32(exd->extent_location.lblock_num); 72 72 73 73 log_msg(LOG_DEFAULT, LVL_DEBUG, 74 74 "Extended allocator: start=%d, block_num=%d, len=%d", start, 75 75 FLE32(exd->extent_location.lblock_num), FLE32(exd->info_length)); 76 76 77 77 uint32_t len = FLE32(exd->info_length); 78 78 block_put(block); 79 79 80 80 return udf_read_allocation_sequence(node, NULL, icb_flag, start, len); 81 81 } … … 97 97 { 98 98 node->alloc_size = 0; 99 99 100 100 switch (icb_flag) { 101 101 case UDF_SHORT_AD: 102 102 log_msg(LOG_DEFAULT, LVL_DEBUG, 103 103 "ICB: sequence of allocation descriptors - icbflag = short_ad_t"); 104 104 105 105 /* 106 106 * Identify number of current partition. Virtual partition … … 110 110 size_t pd_num = (size_t) -1; 111 111 size_t min_start = 0; 112 112 113 113 for (size_t i = 0; i < node->instance->partition_cnt; i++) { 114 114 if ((node->index >= node->instance->partitions[i].start) && … … 121 121 } 122 122 } 123 123 124 124 if (pd_num == (size_t) -1) 125 125 return ENOENT; 126 126 127 127 /* 128 128 * According to doc, in this we should stop our loop if pass … … 133 133 * which we check inside of loop. 134 134 */ 135 135 136 136 while (true) { 137 137 udf_short_ad_t *short_d = 138 138 (udf_short_ad_t *) (af + start_alloc + 139 139 node->alloc_size * sizeof(udf_short_ad_t)); 140 140 141 141 if (FLE32(short_d->length) == 0) 142 142 break; 143 143 144 144 /* 145 145 * ECMA 167 4/12 - next sequence of allocation descriptors … … 152 152 break; 153 153 } 154 154 155 155 node->allocators = realloc(node->allocators, 156 156 (node->alloc_size + 1) * sizeof(udf_allocator_t)); … … 161 161 node->alloc_size++; 162 162 } 163 163 164 164 node->allocators = realloc(node->allocators, 165 165 node->alloc_size * sizeof(udf_allocator_t)); 166 166 break; 167 167 168 168 case UDF_LONG_AD: 169 169 log_msg(LOG_DEFAULT, LVL_DEBUG, 170 170 "ICB: sequence of allocation descriptors - icbflag = long_ad_t"); 171 171 172 172 while (true) { 173 173 udf_long_ad_t *long_d = 174 174 (udf_long_ad_t *) (af + start_alloc + 175 175 node->alloc_size * sizeof(udf_long_ad_t)); 176 176 177 177 if (FLE32(long_d->length) == 0) 178 178 break; 179 179 180 180 uint32_t pos_long_ad = udf_long_ad_to_pos(node->instance, long_d); 181 181 182 182 /* 183 183 * ECMA 167 4/12 - next sequence of allocation descriptors … … 188 188 break; 189 189 } 190 190 191 191 node->allocators = realloc(node->allocators, 192 192 (node->alloc_size + 1) * sizeof(udf_allocator_t)); … … 194 194 EXT_LENGTH(FLE32(long_d->length)); 195 195 node->allocators[node->alloc_size].position = pos_long_ad; 196 196 197 197 node->alloc_size++; 198 198 } 199 199 200 200 node->allocators = realloc(node->allocators, 201 201 node->alloc_size * sizeof(udf_allocator_t)); 202 202 break; 203 203 204 204 case UDF_EXTENDED_AD: 205 205 log_msg(LOG_DEFAULT, LVL_DEBUG, 206 206 "ICB: sequence of allocation descriptors - icbflag = extended_ad_t"); 207 207 break; 208 208 209 209 case UDF_DATA_AD: 210 210 log_msg(LOG_DEFAULT, LVL_DEBUG, 211 211 "ICB: sequence of allocation descriptors - icbflag = 3, node contains data itself"); 212 212 213 213 node->data = malloc(node->data_size); 214 214 if (!node->data) 215 215 return ENOMEM; 216 216 217 217 memcpy(node->data, (af + start_alloc), node->data_size); 218 218 node->alloc_size = 0; 219 219 break; 220 220 } 221 221 222 222 return EOK; 223 223 } … … 237 237 while (true) { 238 238 fs_index_t pos = node->index; 239 239 240 240 block_t *block = NULL; 241 241 errno_t rc = block_get(&block, node->instance->service_id, pos, … … 243 243 if (rc != EOK) 244 244 return rc; 245 245 246 246 udf_descriptor_tag_t *data = (udf_descriptor_tag_t *) block->data; 247 247 if (data->checksum != udf_tag_checksum((uint8_t *) data)) { … … 249 249 return EINVAL; 250 250 } 251 251 252 252 /* One sector size descriptors */ 253 253 switch (FLE16(data->id)) { 254 254 case UDF_FILE_ENTRY: 255 255 log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: File entry descriptor found"); 256 256 257 257 udf_file_entry_descriptor_t *file = 258 258 (udf_file_entry_descriptor_t *) block->data; … … 260 260 node->data_size = FLE64(file->info_lenght); 261 261 node->type = (file->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE; 262 262 263 263 rc = udf_read_allocation_sequence(node, (uint8_t *) file, icb_flag, 264 264 FLE32(file->ea_lenght) + UDF_FE_OFFSET, FLE32(file->ad_lenght)); 265 265 block_put(block); 266 266 return rc; 267 267 268 268 case UDF_EFILE_ENTRY: 269 269 log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Extended file entry descriptor found"); 270 270 271 271 udf_extended_file_entry_descriptor_t *efile = 272 272 (udf_extended_file_entry_descriptor_t *) block->data; … … 274 274 node->data_size = FLE64(efile->info_lenght); 275 275 node->type = (efile->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE; 276 276 277 277 rc = udf_read_allocation_sequence(node, (uint8_t *) efile, icb_flag, 278 278 FLE32(efile->ea_lenght) + UDF_EFE_OFFSET, FLE32(efile->ad_lenght)); 279 279 block_put(block); 280 280 return rc; 281 281 282 282 case UDF_ICB_TERMINAL: 283 283 log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Terminal entry descriptor found"); … … 285 285 return EOK; 286 286 } 287 287 288 288 pos++; 289 289 290 290 rc = block_put(block); 291 291 if (rc != EOK) 292 292 return rc; 293 293 } 294 294 295 295 return EOK; 296 296 } … … 323 323 size_t fid_sum = 0; 324 324 size_t n = 0; 325 325 326 326 while (node->data_size - fid_sum >= MIN_FID_LEN) { 327 327 udf_descriptor_tag_t *desc = … … 333 333 return ENOENT; 334 334 } 335 335 336 336 *fid = (udf_file_identifier_descriptor_t *) 337 337 (node->data + fid_sum); 338 338 339 339 /* According to ECMA 167 4/14.4.9 */ 340 340 size_t padding = 4 * (((*fid)->lenght_file_id + … … 343 343 size_t size_fid = (*fid)->lenght_file_id + 344 344 FLE16((*fid)->lenght_iu) + padding + 38; 345 345 346 346 fid_sum += size_fid; 347 347 348 348 /* aAcording to ECMA 167 4/8.6 */ 349 349 if (((*fid)->lenght_file_id != 0) && 350 350 (((*fid)->file_characteristics & 4) == 0)) { 351 351 n++; 352 352 353 353 if (n == pos + 1) 354 354 return EOK; 355 355 } 356 356 } 357 357 358 358 return ENOENT; 359 359 } … … 374 374 if (node->data == NULL) 375 375 return udf_get_fid_in_allocator(fid, block, node, pos); 376 376 377 377 return udf_get_fid_in_data(fid, node, pos); 378 378 } … … 392 392 { 393 393 void *buf = malloc(node->instance->sector_size); 394 394 395 395 // FIXME: Check for NULL return value 396 396 397 397 size_t j = 0; 398 398 size_t n = 0; 399 399 size_t len = 0; 400 400 401 401 while (j < node->alloc_size) { 402 402 size_t i = 0; … … 408 408 return rc; 409 409 } 410 410 411 411 /* 412 412 * Last item in allocator is a part of sector. We take … … 422 422 break; 423 423 } 424 424 425 425 rc = udf_get_fid_in_sector(fid, block, node, pos, &n, &buf, &len); 426 426 if (rc == EOK) { … … 428 428 return EOK; 429 429 } 430 430 431 431 if (rc == EINVAL) { 432 432 // FIXME: Memory leak 433 433 return ENOENT; 434 434 } 435 435 436 436 if (rc == ENOENT) { 437 437 if (block) { 438 438 rc = block_put(*block); 439 439 *block = NULL; 440 440 441 441 if (rc != EOK) 442 442 return rc; 443 443 } 444 444 } 445 445 446 446 i++; 447 447 } 448 448 449 449 j++; 450 450 } 451 451 452 452 if (buf) 453 453 free(buf); 454 454 455 455 return ENOENT; 456 456 } … … 474 474 { 475 475 void *fidbuf = malloc(node->instance->sector_size); 476 476 477 477 // FIXME: Check for NULL return value 478 478 479 479 bool buf_flag; 480 480 481 481 if (*len > 0) { 482 482 memcpy(fidbuf, *buf, *len); … … 484 484 } else 485 485 buf_flag = false; 486 486 487 487 size_t fid_sum = 0; 488 488 while (node->instance->sector_size - fid_sum > 0) { 489 489 if (node->instance->sector_size - fid_sum >= MIN_FID_LEN) { 490 490 void *fid_data; 491 491 492 492 if (buf_flag) { 493 493 memcpy((fidbuf + *len), (*block)->data, … … 496 496 } else 497 497 fid_data = (*block)->data + fid_sum; 498 498 499 499 udf_descriptor_tag_t *desc = 500 500 (udf_descriptor_tag_t *) fid_data; 501 501 502 502 if (desc->checksum != udf_tag_checksum((uint8_t *) desc)) { 503 503 if (fidbuf) 504 504 free(fidbuf); 505 505 506 506 if (*buf) { 507 507 free(*buf); … … 509 509 *len = 0; 510 510 } 511 511 512 512 return EINVAL; 513 513 } 514 514 515 515 *fid = (udf_file_identifier_descriptor_t *) fid_data; 516 516 517 517 /* According to ECMA 167 4/14.4.9 */ 518 518 size_t padding = 4 * (((*fid)->lenght_file_id + … … 525 525 else 526 526 fid_sum += size_fid; 527 527 528 528 /* According to ECMA 167 4/8.6 */ 529 529 if (((*fid)->lenght_file_id != 0) && … … 533 533 if (fidbuf) 534 534 free(fidbuf); 535 535 536 536 return EOK; 537 537 } 538 538 } 539 539 540 540 if (fidbuf) { 541 541 buf_flag = false; … … 543 543 fidbuf = NULL; 544 544 } 545 545 546 546 if (*buf) { 547 547 free(*buf); … … 552 552 if (*buf) 553 553 free(*buf); 554 554 555 555 *len = node->instance->sector_size - fid_sum; 556 556 *buf = malloc(*len); 557 557 buf_flag = false; 558 558 memcpy(*buf, ((*block)->data + fid_sum), *len); 559 559 560 560 return ENOENT; 561 561 } 562 562 } 563 563 564 564 return ENOENT; 565 565 } … … 581 581 size_t i = 0; 582 582 size_t l = 0; 583 583 584 584 while (i < node->alloc_size) { 585 585 if (pos >= l + node->allocators[i].length) { … … 589 589 break; 590 590 } 591 591 592 592 size_t sector_cnt = ALL_UP(l, node->instance->sector_size); 593 593 size_t sector_num = pos / node->instance->sector_size; 594 594 595 595 block_t *block = NULL; 596 596 errno_t rc = block_get(&block, node->instance->service_id, … … 601 601 return rc; 602 602 } 603 603 604 604 size_t sector_pos = pos % node->instance->sector_size; 605 605 606 606 if (sector_pos + len < node->instance->sector_size) 607 607 *read_len = len; 608 608 else 609 609 *read_len = node->instance->sector_size - sector_pos; 610 610 611 611 if (ALL_UP(node->allocators[i].length, node->instance->sector_size) == 612 612 sector_num - sector_cnt + 1) { … … 618 618 *read_len = len; 619 619 } 620 620 621 621 async_data_read_finalize(callid, block->data + sector_pos, *read_len); 622 622 return block_put(block); -
uspace/srv/fs/udf/udf_idx.c
r3061bc1 ra35b458 95 95 if (!hash_table_create(&udf_idx, 0, 0, &udf_idx_ops)) 96 96 return ENOMEM; 97 97 98 98 return EOK; 99 99 } … … 127 127 .index = index 128 128 }; 129 129 130 130 ht_link_t *already_open = hash_table_find(&udf_idx, &key); 131 131 if (already_open) { … … 133 133 udf_node_t, link); 134 134 node->ref_cnt++; 135 135 136 136 *udfn = node; 137 137 138 138 fibril_mutex_unlock(&udf_idx_lock); 139 139 return EOK; 140 140 } 141 141 142 142 fibril_mutex_unlock(&udf_idx_lock); 143 143 return ENOENT; … … 156 156 { 157 157 fibril_mutex_lock(&udf_idx_lock); 158 158 159 159 udf_node_t *udf_node = malloc(sizeof(udf_node_t)); 160 160 if (udf_node == NULL) { … … 162 162 return ENOMEM; 163 163 } 164 164 165 165 fs_node_t *fs_node = malloc(sizeof(fs_node_t)); 166 166 if (fs_node == NULL) { … … 169 169 return ENOMEM; 170 170 } 171 171 172 172 fs_node_initialize(fs_node); 173 173 174 174 udf_node->index = index; 175 175 udf_node->instance = instance; … … 179 179 udf_node->data = NULL; 180 180 udf_node->allocators = NULL; 181 181 182 182 fibril_mutex_initialize(&udf_node->lock); 183 183 fs_node->data = udf_node; 184 184 185 185 hash_table_insert(&udf_idx, &udf_node->link); 186 186 instance->open_nodes_count++; 187 187 188 188 *udfn = udf_node; 189 189 190 190 fibril_mutex_unlock(&udf_idx_lock); 191 191 return EOK; … … 202 202 { 203 203 assert(node->ref_cnt == 0); 204 204 205 205 fibril_mutex_lock(&udf_idx_lock); 206 206 207 207 hash_table_remove_item(&udf_idx, &node->link); 208 208 209 209 assert(node->instance->open_nodes_count > 0); 210 210 node->instance->open_nodes_count--; 211 211 212 212 free(node->fs_node); 213 213 free(node); 214 214 215 215 fibril_mutex_unlock(&udf_idx_lock); 216 216 return EOK; -
uspace/srv/fs/udf/udf_ops.c
r3061bc1 ra35b458 75 75 if (rc != EOK) 76 76 return rc; 77 77 78 78 udf_node_t *node; 79 79 rc = udf_idx_get(&node, instance, index); … … 82 82 if (rc != EOK) 83 83 return rc; 84 84 85 85 rc = udf_node_get_core(node); 86 86 if (rc != EOK) { … … 89 89 } 90 90 } 91 91 92 92 *rfn = FS_NODE(node); 93 93 return EOK; … … 100 100 if (rc != EOK) 101 101 return rc; 102 102 103 103 return udf_node_get(rfn, service_id, 104 104 instance->volumes[DEFAULT_VOL].root_dir); … … 110 110 if (udfn) 111 111 return udfn->instance->service_id; 112 112 113 113 return 0; 114 114 } … … 119 119 if (name == NULL) 120 120 return ENOMEM; 121 121 122 122 block_t *block = NULL; 123 123 udf_file_identifier_descriptor_t *fid = NULL; 124 124 size_t pos = 0; 125 125 126 126 while (udf_get_fid(&fid, &block, UDF_NODE(pfn), pos) == EOK) { 127 127 udf_long_ad_t long_ad = fid->icb; 128 128 129 129 udf_to_unix_name(name, MAX_FILE_NAME_LEN, 130 130 (char *) fid->implementation_use + FLE16(fid->lenght_iu), 131 131 fid->lenght_file_id, &UDF_NODE(pfn)->instance->charset); 132 132 133 133 if (str_casecmp(name, component) == 0) { 134 134 errno_t rc = udf_node_get(rfn, udf_service_get(pfn), 135 135 udf_long_ad_to_pos(UDF_NODE(pfn)->instance, &long_ad)); 136 136 137 137 if (block != NULL) 138 138 block_put(block); 139 139 140 140 free(name); 141 141 return rc; 142 142 } 143 143 144 144 if (block != NULL) { 145 145 errno_t rc = block_put(block); … … 147 147 return rc; 148 148 } 149 149 150 150 pos++; 151 151 } 152 152 153 153 free(name); 154 154 return ENOENT; … … 165 165 if (!node) 166 166 return EINVAL; 167 167 168 168 fibril_mutex_lock(&node->lock); 169 169 node->ref_cnt--; 170 170 fibril_mutex_unlock(&node->lock); 171 171 172 172 /* Delete node from hash table and memory */ 173 173 if (!node->ref_cnt) 174 174 udf_idx_del(node); 175 175 176 176 return EOK; 177 177 } … … 208 208 if (node) 209 209 return node->index; 210 210 211 211 return 0; 212 212 } … … 217 217 if (node) 218 218 return node->data_size; 219 219 220 220 return 0; 221 221 } … … 226 226 if (node) 227 227 return node->link_cnt; 228 228 229 229 return 0; 230 230 } … … 235 235 if (node) 236 236 return node->type == NODE_DIR; 237 237 238 238 return false; 239 239 } … … 244 244 if (node) 245 245 return node->type == NODE_FILE; 246 246 247 247 return false; 248 248 } … … 257 257 if (NULL == instance) 258 258 return ENOENT; 259 259 260 260 *size = instance->volumes[DEFAULT_VOL].logical_block_size; 261 261 262 262 return EOK; 263 263 } … … 266 266 { 267 267 *count = 0; 268 268 269 269 return EOK; 270 270 } … … 273 273 { 274 274 *count = 0; 275 275 276 276 return EOK; 277 277 } … … 308 308 { 309 309 enum cache_mode cmode; 310 310 311 311 /* Check for option enabling write through. */ 312 312 if (str_cmp(opts, "wtcache") == 0) … … 314 314 else 315 315 cmode = CACHE_MODE_WB; 316 316 317 317 udf_instance_t *instance = malloc(sizeof(udf_instance_t)); 318 318 if (!instance) 319 319 return ENOMEM; 320 320 321 321 instance->sector_size = 0; 322 322 323 323 /* Check for block size. Will be enhanced later */ 324 324 if (str_cmp(opts, "bs=512") == 0) … … 328 328 else if (str_cmp(opts, "bs=2048") == 0) 329 329 instance->sector_size = 2048; 330 330 331 331 /* initialize block cache */ 332 332 errno_t rc = block_init(service_id, MAX_SIZE); 333 333 if (rc != EOK) 334 334 return rc; 335 335 336 336 rc = fs_instance_create(service_id, instance); 337 337 if (rc != EOK) { … … 340 340 return rc; 341 341 } 342 342 343 343 instance->service_id = service_id; 344 344 instance->open_nodes_count = 0; 345 345 346 346 /* Check Volume Recognition Sequence */ 347 347 rc = udf_volume_recongnition(service_id); … … 353 353 return rc; 354 354 } 355 355 356 356 /* Search for Anchor Volume Descriptor */ 357 357 udf_anchor_volume_descriptor_t avd; … … 364 364 return rc; 365 365 } 366 366 367 367 log_msg(LOG_DEFAULT, LVL_DEBUG, 368 368 "Volume: Anchor volume descriptor found. Sector size=%" PRIu32, … … 376 376 PRIu32 " (sector)]", avd.reserve_extent.length, 377 377 avd.reserve_extent.location); 378 378 379 379 /* Initialize the block cache */ 380 380 rc = block_cache_init(service_id, instance->sector_size, 0, cmode); … … 385 385 return rc; 386 386 } 387 387 388 388 /* Read Volume Descriptor Sequence */ 389 389 rc = udf_read_volume_descriptor_sequence(service_id, avd.main_extent); … … 396 396 return rc; 397 397 } 398 398 399 399 fs_node_t *rfn; 400 400 rc = udf_node_get(&rfn, service_id, instance->volumes[DEFAULT_VOL].root_dir); … … 407 407 return rc; 408 408 } 409 409 410 410 udf_node_t *node = UDF_NODE(rfn); 411 411 *index = instance->volumes[DEFAULT_VOL].root_dir; 412 412 *size = node->data_size; 413 413 414 414 return EOK; 415 415 } … … 421 421 if (rc != EOK) 422 422 return rc; 423 423 424 424 udf_node_t *nodep = UDF_NODE(fn); 425 425 udf_instance_t *instance = nodep->instance; 426 426 427 427 /* 428 428 * We expect exactly two references on the root node. … … 434 434 return EBUSY; 435 435 } 436 436 437 437 /* 438 438 * Put the root node twice. … … 440 440 udf_node_put(fn); 441 441 udf_node_put(fn); 442 442 443 443 fs_instance_destroy(service_id); 444 444 free(instance); 445 445 block_cache_fini(service_id); 446 446 block_fini(service_id); 447 447 448 448 return EOK; 449 449 } … … 456 456 if (rc != EOK) 457 457 return rc; 458 458 459 459 fs_node_t *rfn; 460 460 rc = udf_node_get(&rfn, service_id, index); 461 461 if (rc != EOK) 462 462 return rc; 463 463 464 464 udf_node_t *node = UDF_NODE(rfn); 465 465 466 466 ipc_callid_t callid; 467 467 size_t len = 0; … … 471 471 return EINVAL; 472 472 } 473 473 474 474 if (node->type == NODE_FILE) { 475 475 if (pos >= node->data_size) { … … 479 479 return EOK; 480 480 } 481 481 482 482 size_t read_len = 0; 483 483 if (node->data == NULL) … … 489 489 rc = EOK; 490 490 } 491 491 492 492 *rbytes = read_len; 493 493 (void) udf_node_put(rfn); … … 498 498 if (udf_get_fid(&fid, &block, node, pos) == EOK) { 499 499 char *name = malloc(MAX_FILE_NAME_LEN + 1); 500 500 501 501 // FIXME: Check for NULL return value 502 502 503 503 udf_to_unix_name(name, MAX_FILE_NAME_LEN, 504 504 (char *) fid->implementation_use + FLE16(fid->lenght_iu), 505 505 fid->lenght_file_id, &node->instance->charset); 506 506 507 507 async_data_read_finalize(callid, name, str_size(name) + 1); 508 508 *rbytes = 1; 509 509 free(name); 510 510 udf_node_put(rfn); 511 511 512 512 if (block != NULL) 513 513 return block_put(block); 514 514 515 515 return EOK; 516 516 } else { -
uspace/srv/fs/udf/udf_osta.c
r3061bc1 ra35b458 59 59 if ((ch == 0x0000) || (ch == 0x002F)) 60 60 return false; 61 61 62 62 return true; 63 63 } … … 85 85 /* Use udf_compressed to store current byte being read. */ 86 86 uint8_t comp_id = udf_compressed[0]; 87 87 88 88 /* First check for valid compID. */ 89 89 if ((comp_id != 8) && (comp_id != 16)) 90 90 return 0; 91 91 92 92 size_t unicode_idx = 0; 93 93 size_t byte_idx = 1; 94 94 95 95 /* Loop through all the bytes. */ 96 96 while ((byte_idx < number_of_bytes) && (unicode_idx < unicode_max_len)) { … … 103 103 } else 104 104 unicode[unicode_idx] = 0; 105 105 106 106 if (byte_idx < number_of_bytes) { 107 107 /* Then the next byte to the low bits. */ 108 108 unicode[unicode_idx] |= udf_compressed[byte_idx++]; 109 109 } 110 110 111 111 unicode_idx++; 112 112 } 113 113 114 114 return unicode_idx; 115 115 } … … 136 136 size_t new_idx = 0; 137 137 size_t new_ext_idx = 0; 138 138 139 139 for (size_t idx = 0; idx < udf_len; idx++) { 140 140 uint16_t current = udf_name[idx]; 141 141 142 142 if ((!legal_check(current)) || (!ascii_check(current))) { 143 143 needs_crc = true; 144 144 145 145 /* 146 146 * Replace Illegal and non-displayable chars with … … 148 148 */ 149 149 current = ILLEGAL_CHAR_MARK; 150 150 151 151 /* 152 152 * Skip any other illegal or non-displayable … … 158 158 idx++; 159 159 } 160 160 161 161 /* Record position of extension, if one is found. */ 162 162 if ((current == PERIOD) && ((udf_len - idx - 1) <= EXT_SIZE)) { … … 170 170 } 171 171 } 172 172 173 173 if (new_idx < MAXLEN) 174 174 new_name[new_idx++] = current; … … 176 176 needs_crc = true; 177 177 } 178 178 179 179 if (needs_crc) { 180 180 uint16_t ext[EXT_SIZE]; 181 181 size_t local_ext_idx = 0; 182 182 183 183 if (has_ext) { 184 184 size_t max_filename_len; 185 185 186 186 /* Translate extension, and store it in ext. */ 187 187 for (size_t idx = 0; (idx < EXT_SIZE) && 188 188 (ext_idx + idx + 1 < udf_len); idx++) { 189 189 uint16_t current = udf_name[ext_idx + idx + 1]; 190 190 191 191 if ((!legal_check(current)) || (!ascii_check(current))) { 192 192 needs_crc = true; 193 193 194 194 /* 195 195 * Replace Illegal and non-displayable … … 197 197 */ 198 198 current = ILLEGAL_CHAR_MARK; 199 199 200 200 /* 201 201 * Skip any other illegal or … … 207 207 idx++; 208 208 } 209 209 210 210 ext[local_ext_idx++] = current; 211 211 } 212 212 213 213 /* 214 214 * Truncate filename to leave room for extension and … … 224 224 new_idx = MAXLEN - 5; 225 225 } 226 226 227 227 /* Add mark for CRC. */ 228 228 new_name[new_idx++] = CRC_MARK; 229 229 230 230 /* Calculate CRC from original filename. */ 231 231 uint16_t value_crc = udf_unicode_cksum(udf_name, udf_len); 232 232 233 233 /* Convert 16-bits of CRC to hex characters. */ 234 234 const char hex_char[] = "0123456789ABCDEF"; 235 235 236 236 new_name[new_idx++] = hex_char[(value_crc & 0xf000) >> 12]; 237 237 new_name[new_idx++] = hex_char[(value_crc & 0x0f00) >> 8]; 238 238 new_name[new_idx++] = hex_char[(value_crc & 0x00f0) >> 4]; 239 239 new_name[new_idx++] = hex_char[(value_crc & 0x000f)]; 240 240 241 241 /* Place a translated extension at end, if found. */ 242 242 if (has_ext) { 243 243 new_name[new_idx++] = PERIOD; 244 244 245 245 for (size_t idx = 0; idx < local_ext_idx; idx++) 246 246 new_name[new_idx++] = ext[idx]; 247 247 } 248 248 } 249 249 250 250 return new_idx; 251 251 } … … 265 265 const char *osta_id = "OSTA Compressed Unicode"; 266 266 size_t ucode_chars, nice_uchars; 267 267 268 268 uint16_t *raw_name = malloc(MAX_BUF * sizeof(uint16_t)); 269 269 uint16_t *unix_name = malloc(MAX_BUF * sizeof(uint16_t)); 270 270 271 271 // FIXME: Check for malloc returning NULL 272 272 273 273 bool is_osta_typ0 = (chsp->type == 0) && 274 274 (str_cmp((char *) chsp->info, osta_id) == 0); 275 275 276 276 if (is_osta_typ0) { 277 277 *raw_name = 0; 278 278 *unix_name = 0; 279 279 280 280 ucode_chars = 281 281 udf_uncompress_unicode(len, (uint8_t *) id, raw_name, MAX_BUF); … … 283 283 nice_uchars = 284 284 udf_translate_name(unix_name, raw_name, ucode_chars); 285 285 286 286 /* Output UTF-8 */ 287 287 unix_name[nice_uchars] = 0; … … 292 292 str_size((char *) (id + 1))); 293 293 } 294 294 295 295 free(raw_name); 296 296 free(unix_name); -
uspace/srv/fs/udf/udf_volume.c
r3061bc1 ra35b458 67 67 FLE16(long_ad->location.partition_num), 68 68 FLE32(long_ad->location.lblock_num)); 69 69 70 70 return instance->partitions[ 71 71 FLE16(long_ad->location.partition_num)].start + … … 108 108 if (!vd) 109 109 return ENOMEM; 110 110 111 111 errno_t rc = udf_volume_recongnition_structure_test(service_id, addr, vd); 112 112 if (rc != EOK) { … … 114 114 return rc; 115 115 } 116 116 117 117 for (size_t i = 0; i < VRS_DEPTH; i++) { 118 118 addr += sizeof(udf_vrs_descriptor_t); 119 119 120 120 rc = udf_volume_recongnition_structure_test(service_id, addr, vd); 121 121 if (rc != EOK) { … … 123 123 return rc; 124 124 } 125 125 126 126 /* 127 127 * UDF standard identifier. According to ECMA 167 2/9.1.2 … … 133 133 continue; 134 134 } 135 135 136 136 if (str_lcmp(VRS_END, (char *) vd->identifier, VRS_ID_LEN) == 0) { 137 137 log_msg(LOG_DEFAULT, LVL_DEBUG, "VRS: end found"); … … 139 139 } 140 140 } 141 141 142 142 free(vd); 143 143 144 144 if (nsr_found) 145 145 return EOK; … … 178 178 if (rc != EOK) 179 179 return rc; 180 180 181 181 if (avd->tag.checksum != udf_tag_checksum((uint8_t *) &avd->tag)) 182 182 return EINVAL; 183 183 184 184 // TODO: Should be tested in big-endian mode 185 185 udf_prepare_tag(&avd->tag); 186 186 187 187 if (avd->tag.id != UDF_TAG_AVDP) 188 188 return EINVAL; 189 189 190 190 GET_LE32(avd->main_extent.length); 191 191 GET_LE32(avd->main_extent.location); 192 192 GET_LE32(avd->reserve_extent.length); 193 193 GET_LE32(avd->reserve_extent.location); 194 194 195 195 return EOK; 196 196 } … … 211 211 { 212 212 uint32_t default_sector_size[] = {512, 1024, 2048, 4096, 8192, 0}; 213 213 214 214 udf_instance_t *instance; 215 215 errno_t rc = fs_instance_get(service_id, (void **) &instance); 216 216 if (rc != EOK) 217 217 return rc; 218 218 219 219 if (instance->sector_size) { 220 220 return udf_get_anchor_volume_descriptor_by_ssize(service_id, avd, … … 229 229 return EOK; 230 230 } 231 231 232 232 i++; 233 233 } 234 234 } 235 235 236 236 return EINVAL; 237 237 } … … 273 273 } 274 274 } 275 275 276 276 return false; 277 277 } … … 310 310 } 311 311 } 312 312 313 313 return false; 314 314 } … … 343 343 } 344 344 } 345 345 346 346 return false; 347 347 } … … 368 368 if (rc != EOK) 369 369 return rc; 370 370 371 371 udf_descriptor_tag_t *desc = (udf_descriptor_tag_t *) (block->data); 372 372 if (desc->checksum != udf_tag_checksum((uint8_t *) desc)) { … … 374 374 return EINVAL; 375 375 } 376 376 377 377 /* 378 378 * We think that we have only one allocator. It is means that virtual … … 383 383 case UDF_FILE_ENTRY: 384 384 log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: File entry descriptor found"); 385 385 386 386 udf_file_entry_descriptor_t *fed = 387 387 (udf_file_entry_descriptor_t *) block->data; … … 392 392 instance->partitions[id].lenght = FLE32(short_d->length); 393 393 break; 394 394 395 395 case UDF_EFILE_ENTRY: 396 396 log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Extended file entry descriptor found"); 397 397 398 398 udf_extended_file_entry_descriptor_t *efed = 399 399 (udf_extended_file_entry_descriptor_t *) block->data; … … 404 404 break; 405 405 } 406 406 407 407 return block_put(block); 408 408 } … … 426 426 return i; 427 427 } 428 428 429 429 return (size_t) -1; 430 430 } … … 448 448 if (instance->volumes == NULL) 449 449 return ENOMEM; 450 450 451 451 instance->partitions = calloc(pd_cnt, sizeof(udf_partition_t)); 452 452 if (instance->partitions == NULL) { … … 454 454 return ENOMEM; 455 455 } 456 456 457 457 instance->partition_cnt = pd_cnt; 458 458 459 459 /* 460 460 * Fill information about logical volumes. We will save 461 461 * information about all partitions placed inside each volumes. 462 462 */ 463 463 464 464 size_t vir_pd_cnt = 0; 465 465 for (size_t i = 0; i < lvd_cnt; i++) { … … 471 471 return ENOMEM; 472 472 } 473 473 474 474 instance->volumes[i].partition_cnt = 0; 475 475 instance->volumes[i].logical_block_size = 476 476 FLE32(lvd[i].logical_block_size); 477 477 478 478 /* 479 479 * In theory we could have more than 1 logical volume. But now … … 481 481 * partitions from array pd belong to only first lvd 482 482 */ 483 483 484 484 uint8_t *idx = lvd[i].partition_map; 485 485 for (size_t j = 0; j < FLE32(lvd[i].number_of_partitions_maps); … … 487 487 udf_type1_partition_map_t *pm1 = 488 488 (udf_type1_partition_map_t *) idx; 489 489 490 490 if (pm1->partition_map_type == 1) { 491 491 size_t pd_num = udf_find_partition(pd, pd_cnt, … … 495 495 return ENOENT; 496 496 } 497 497 498 498 /* 499 499 * Fill information about physical partitions. We will save all … … 509 509 instance->partitions[j].start = 510 510 FLE32(pd[pd_num].starting_location); 511 511 512 512 instance->volumes[i].partitions[ 513 513 instance->volumes[i].partition_cnt] = 514 514 &instance->partitions[j]; 515 515 516 516 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] " 517 517 "found and filled", i, pm1->partition_map_type); 518 518 519 519 instance->volumes[i].partition_cnt++; 520 520 idx += pm1->partition_map_lenght; 521 521 continue; 522 522 } 523 523 524 524 udf_type2_partition_map_t *pm2 = 525 525 (udf_type2_partition_map_t *) idx; 526 526 527 527 if (pm2->partition_map_type == 2) { 528 528 // TODO: check partition_ident for metadata_partition_map 529 529 530 530 udf_metadata_partition_map_t *metadata = 531 531 (udf_metadata_partition_map_t *) idx; 532 532 533 533 log_msg(LOG_DEFAULT, LVL_DEBUG, "Metadata file location=%u", 534 534 FLE32(metadata->metadata_fileloc)); 535 535 536 536 vir_pd_cnt++; 537 537 instance->partitions = realloc(instance->partitions, … … 541 541 return ENOMEM; 542 542 } 543 543 544 544 instance->partition_cnt++; 545 545 546 546 size_t pd_num = udf_find_partition(pd, pd_cnt, 547 547 FLE16(metadata->partition_number)); … … 550 550 return ENOENT; 551 551 } 552 552 553 553 instance->partitions[j].number = 554 554 FLE16(metadata->partition_number); … … 560 560 return rc; 561 561 } 562 562 563 563 /* Virtual partition placed inside physical */ 564 564 instance->partitions[j].start += 565 565 FLE32(pd[pd_num].starting_location); 566 566 567 567 instance->volumes[i].partitions[ 568 568 instance->volumes[i].partition_cnt] = 569 569 &instance->partitions[j]; 570 570 571 571 log_msg(LOG_DEFAULT, LVL_DEBUG, "Virtual partition: num=%d, start=%d", 572 572 instance->partitions[j].number, … … 574 574 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] " 575 575 "found and filled", i, pm2->partition_map_type); 576 576 577 577 instance->volumes[i].partition_cnt++; 578 578 idx += metadata->partition_map_length; 579 579 continue; 580 580 } 581 581 582 582 /* Not type 1 nor type 2 */ 583 583 udf_general_type_t *pm = (udf_general_type_t *) idx; 584 584 585 585 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] " 586 586 "found and skipped", i, pm->partition_map_type); 587 587 588 588 idx += pm->partition_map_lenght; 589 589 } 590 590 } 591 591 592 592 return EOK; 593 593 } … … 608 608 if (rc != EOK) 609 609 return rc; 610 610 611 611 aoff64_t pos = addr.location; 612 612 aoff64_t end = pos + (addr.length / instance->sector_size) - 1; 613 613 614 614 if (pos == end) 615 615 return EINVAL; 616 616 617 617 size_t max_descriptors = ALL_UP(addr.length, instance->sector_size); 618 618 619 619 udf_primary_volume_descriptor_t *pvd = calloc(max_descriptors, 620 620 sizeof(udf_primary_volume_descriptor_t)); 621 621 if (pvd == NULL) 622 622 return ENOMEM; 623 623 624 624 udf_logical_volume_descriptor_t *lvd = calloc(max_descriptors, 625 625 instance->sector_size); … … 628 628 return ENOMEM; 629 629 } 630 630 631 631 udf_partition_descriptor_t *pd = calloc(max_descriptors, 632 632 sizeof(udf_partition_descriptor_t)); … … 636 636 return ENOMEM; 637 637 } 638 638 639 639 size_t pvd_cnt = 0; 640 640 size_t lvd_cnt = 0; 641 641 size_t pd_cnt = 0; 642 642 643 643 while (pos <= end) { 644 644 block_t *block = NULL; … … 650 650 return rc; 651 651 } 652 652 653 653 udf_volume_descriptor_t *vol = 654 654 (udf_volume_descriptor_t *) block->data; 655 655 656 656 switch (FLE16(vol->common.tag.id)) { 657 657 /* One sector size descriptors */ 658 658 case UDF_TAG_PVD: 659 659 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Primary volume descriptor found"); 660 660 661 661 if (!udf_check_prevailing_pvd(pvd, pvd_cnt, &vol->volume)) { 662 662 memcpy(&pvd[pvd_cnt], &vol->volume, … … 664 664 pvd_cnt++; 665 665 } 666 666 667 667 pos++; 668 668 break; 669 669 670 670 case UDF_TAG_VDP: 671 671 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Volume descriptor pointer found"); 672 672 pos++; 673 673 break; 674 674 675 675 case UDF_TAG_IUVD: 676 676 log_msg(LOG_DEFAULT, LVL_DEBUG, … … 678 678 pos++; 679 679 break; 680 680 681 681 case UDF_TAG_PD: 682 682 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Partition descriptor found"); … … 688 688 FLE32(vol->partition.starting_location), 689 689 FLE32(vol->partition.length)); 690 690 691 691 if (!udf_check_prevailing_pd(pd, pd_cnt, &vol->partition)) { 692 692 memcpy(&pd[pd_cnt], &vol->partition, … … 694 694 pd_cnt++; 695 695 } 696 696 697 697 udf_partition_header_descriptor_t *phd = 698 698 (udf_partition_header_descriptor_t *) vol->partition.contents_use; … … 702 702 FLE32(phd->unallocated_space_table.length), 703 703 FLE32(phd->unallocated_space_table.position)); 704 704 705 705 instance->space_type = SPACE_TABLE; 706 706 instance->uaspace_start = … … 710 710 FLE32(phd->unallocated_space_table.length); 711 711 } 712 712 713 713 if (FLE32(phd->unallocated_space_bitmap.length)) { 714 714 log_msg(LOG_DEFAULT, LVL_DEBUG, … … 716 716 FLE32(phd->unallocated_space_bitmap.length), 717 717 FLE32(phd->unallocated_space_bitmap.position)); 718 718 719 719 instance->space_type = SPACE_BITMAP; 720 720 instance->uaspace_start = … … 724 724 FLE32(phd->unallocated_space_bitmap.length); 725 725 } 726 726 727 727 pos++; 728 728 break; 729 729 730 730 /* Relative size descriptors */ 731 731 case UDF_TAG_LVD: 732 732 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Logical volume descriptor found"); 733 733 734 734 aoff64_t sct = 735 735 ALL_UP((sizeof(udf_logical_volume_descriptor_t) + … … 738 738 pos += sct; 739 739 char tmp[130]; 740 740 741 741 udf_to_unix_name(tmp, 129, 742 742 (char *) vol->logical.logical_volume_id, 128, 743 743 &vol->logical.charset); 744 744 745 745 log_msg(LOG_DEFAULT, LVL_DEBUG, "Logical Volume ID: '%s', " 746 746 "logical block size: %" PRIu32 " (bytes)", tmp, … … 750 750 FLE32(vol->logical.map_table_length), 751 751 FLE32(vol->logical.number_of_partitions_maps)); 752 752 753 753 if (!udf_check_prevailing_lvd(lvd, lvd_cnt, &vol->logical)) { 754 754 memcpy(&lvd[lvd_cnt], &vol->logical, … … 757 757 lvd_cnt++; 758 758 } 759 759 760 760 break; 761 761 762 762 case UDF_TAG_USD: 763 763 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Unallocated space descriptor found"); 764 764 765 765 sct = ALL_UP((sizeof(udf_unallocated_space_descriptor_t) + 766 766 FLE32(vol->unallocated.allocation_descriptors_num)* … … 774 774 return ENOMEM; 775 775 } 776 776 777 777 memcpy(instance->uasd, block->data, instance->sector_size); 778 778 pos += sct; 779 779 break; 780 780 781 781 case UDF_TAG_LVID: 782 782 log_msg(LOG_DEFAULT, LVL_DEBUG, 783 783 "Volume: Logical volume integrity descriptor found"); 784 784 785 785 pos++; 786 786 break; 787 787 788 788 case UDF_TAG_TD: 789 789 log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Terminating descriptor found"); 790 790 791 791 /* Found terminating descriptor. Exiting */ 792 792 pos = end + 1; 793 793 break; 794 794 795 795 default: 796 796 pos++; 797 797 } 798 798 799 799 rc = block_put(block); 800 800 if (rc != EOK) { … … 805 805 } 806 806 } 807 807 808 808 /* Fill the instance */ 809 809 udf_fill_volume_info(lvd, lvd_cnt, pd, pd_cnt, instance); 810 810 811 811 for (size_t i = 0; i < lvd_cnt; i++) { 812 812 pos = udf_long_ad_to_pos(instance, 813 813 (udf_long_ad_t *) &lvd[i].logical_volume_conents_use); 814 814 815 815 block_t *block = NULL; 816 816 rc = block_get(&block, instance->service_id, pos, … … 820 820 return rc; 821 821 } 822 822 823 823 udf_descriptor_tag_t *desc = block->data; 824 824 825 825 log_msg(LOG_DEFAULT, LVL_DEBUG, "First tag ID=%" PRIu16, desc->id); 826 826 827 827 if (desc->checksum != udf_tag_checksum((uint8_t *) desc)) { 828 828 // FIXME: Memory leak, cleanup missing 829 829 return EINVAL; 830 830 } 831 831 832 832 udf_prepare_tag(desc); 833 833 834 834 udf_fileset_descriptor_t *fd = block->data; 835 835 memcpy((uint8_t *) &instance->charset, 836 836 (uint8_t *) &fd->fileset_charset, sizeof(fd->fileset_charset)); 837 837 838 838 instance->volumes[i].root_dir = udf_long_ad_to_pos(instance, 839 839 &fd->root_dir_icb); 840 840 } 841 841 842 842 free(pvd); 843 843 free(lvd);
Note:
See TracChangeset
for help on using the changeset viewer.