Changeset a35b458 in mainline for uspace/srv/fs/udf
- 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/udf
- Files:
-
- 8 edited
-
udf.c (modified) (3 diffs)
-
udf.h (modified) (2 diffs)
-
udf_cksum.c (modified) (3 diffs)
-
udf_file.c (modified) (35 diffs)
-
udf_idx.c (modified) (8 diffs)
-
udf_ops.c (modified) (34 diffs)
-
udf_osta.c (modified) (14 diffs)
-
udf_volume.c (modified) (47 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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.
