Changeset d260a95 in mainline
- Timestamp:
- 2011-04-19T08:03:45Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3dbe4ca2
- Parents:
- 97bc3ee
- Location:
- uspace/srv/fs/fat
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_fat.c
r97bc3ee rd260a95 81 81 { 82 82 uint16_t clusters = 0; 83 fat_cluster_t clst = firstc; 84 int rc; 85 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 : FAT12_CLST_LAST1; 86 uint16_t clst_bad = FATTYPE(bs) == 16 ? FAT16_CLST_BAD : FAT12_CLST_BAD; 83 fat_cluster_t clst = firstc, clst_last1 = FAT_CLST_LAST1(bs); 84 fat_cluster_t clst_bad = FAT_CLST_BAD(bs); 85 int rc; 87 86 88 87 if (firstc == FAT_CLST_RES0) { … … 100 99 *lastc = clst; /* remember the last cluster number */ 101 100 102 /* read FAT1 */ 103 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &clst); 104 if (rc != EOK) 105 return rc; 106 107 assert(clst != clst_bad); 108 109 clusters++; 101 /* read FAT1 */ 102 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &clst); 103 if (rc != EOK) 104 return rc; 105 106 assert(clst != clst_bad); 107 clusters++; 110 108 } 111 109 … … 298 296 { 299 297 block_t *b, *b1; 300 aoff64_t offset; 301 int rc; 302 303 assert(fatno < FATCNT(bs)); 304 305 if (FATTYPE(bs) == 16) 306 offset = (clst * 2); 307 else 308 offset = (clst + clst/2); 309 310 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno + 311 offset / BPS(bs), BLOCK_FLAGS_NONE); 312 if (rc != EOK) 313 return rc; 314 315 /* This cluster access spans a sector boundary. Check only for FAT12 */ 316 if (FATTYPE(bs) == 12 && (offset % BPS(bs)+1 == BPS(bs))) { 317 /* Is it last sector of FAT? */ 318 if (offset / BPS(bs) < SF(bs)) { /* NO */ 319 /* Reading next sector */ 320 rc = block_get(&b1, devmap_handle, 1+RSCNT(bs)+SF(bs)*fatno + 321 offset / BPS(bs), BLOCK_FLAGS_NONE); 322 if (rc != EOK) { 323 block_put(b); 324 return rc; 325 } 326 /* 327 * Combining value with last byte of current sector and 328 * first byte of next sector 329 */ 330 *value = *(uint8_t *)(b->data + BPS(bs) - 1); 331 *value |= *(uint8_t *)(b1->data); 332 333 rc = block_put(b1); 334 if (rc != EOK) { 335 block_put(b); 336 return rc; 337 } 338 } 339 else { /* YES */ 340 block_put(b); 341 return ERANGE; 342 } 343 } 344 else 345 *value = *(fat_cluster_t *)(b->data + offset % BPS(bs)); 346 347 if (FATTYPE(bs) == 12) { 348 if (clst & 0x0001) 349 *value = (*value) >> 4; 350 else 351 *value = (*value) & 0x0fff; 352 } 353 354 *value = uint16_t_le2host(*value); 298 aoff64_t offset; 299 int rc; 300 301 assert(fatno < FATCNT(bs)); 302 303 if (FAT_IS_FAT12(bs)) 304 offset = (clst + clst/2); 305 else 306 offset = (clst * sizeof(fat_cluster_t)); 307 308 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno + 309 offset / BPS(bs), BLOCK_FLAGS_NONE); 310 if (rc != EOK) 311 return rc; 312 313 /* This cluster access spans a sector boundary. Check only for FAT12 */ 314 if (FAT_IS_FAT12(bs) && (offset % BPS(bs)+1 == BPS(bs))) { 315 /* Is it last sector of FAT? */ 316 if (offset / BPS(bs) < SF(bs)) { 317 /* No. Reading next sector */ 318 rc = block_get(&b1, devmap_handle, 1 + RSCNT(bs) + 319 SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); 320 if (rc != EOK) { 321 block_put(b); 322 return rc; 323 } 324 /* 325 * Combining value with last byte of current sector and 326 * first byte of next sector 327 */ 328 *value = *(uint8_t *)(b->data + BPS(bs) - 1); 329 *value |= *(uint8_t *)(b1->data); 330 331 rc = block_put(b1); 332 if (rc != EOK) { 333 block_put(b); 334 return rc; 335 } 336 } 337 else { 338 /* Yes. It is last sector of FAT */ 339 block_put(b); 340 return ERANGE; 341 } 342 } 343 else 344 *value = *(fat_cluster_t *)(b->data + offset % BPS(bs)); 345 346 if (FAT_IS_FAT12(bs)) { 347 if (clst & 0x0001) 348 *value = (*value) >> 4; 349 else 350 *value = (*value) & 0x0fff; 351 } 352 353 *value = uint16_t_le2host(*value); 355 354 rc = block_put(b); 356 355 … … 373 372 { 374 373 block_t *b, *b1; 375 376 377 int rc; 378 379 380 381 382 if (FATTYPE(bs) == 16)383 offset = (clst * sizeof(fat_cluster_t));384 385 offset = (clst + clst/2);386 387 388 374 aoff64_t offset; 375 fat_cluster_t *cp, temp; 376 int rc; 377 int spans = 0; 378 379 assert(fatno < FATCNT(bs)); 380 381 if (FAT_IS_FAT12(bs)) 382 offset = (clst + clst/2); 383 else 384 offset = (clst * sizeof(fat_cluster_t)); 385 386 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno + 387 offset / BPS(bs), BLOCK_FLAGS_NONE); 389 388 if (rc != EOK) 390 389 return rc; 391 390 392 /* This cluster access spans a sector boundary. Check only for FAT12 */ 393 if (FATTYPE(bs) == 12 && (offset % BPS(bs)+1 == BPS(bs))) { 394 /* Is it last sector of FAT? */ 395 if (offset / BPS(bs) < SF(bs)) { /* NO */ 396 /* Reading next sector */ 397 rc = block_get(&b1, devmap_handle, 1+RSCNT(bs)+SF(bs)*fatno + 398 offset / BPS(bs), BLOCK_FLAGS_NONE); 399 if (rc != EOK) { 400 block_put(b); 401 return rc; 402 } 403 /* 404 * Combining value with last byte of current sector and 405 * first byte of next sector 406 */ 407 spans=1; 408 cp = &temp; 409 *cp = *(uint8_t *)(b->data + BPS(bs) - 1); 410 *cp |= *(uint8_t *)(b1->data); 411 } 412 else { /* YES */ 413 block_put(b); 414 return ERANGE; 415 } 416 } 417 else 418 cp = (fat_cluster_t *)(b->data + offset % BPS(bs)); 419 420 value = host2uint16_t_le(value); 421 if (FATTYPE(bs) == 12) { 422 if (clst & 0x0001) { 423 *cp &= 0x000f; 424 *cp |= value << 4; 425 } 426 else { 427 *cp &= 0xf000; 428 *cp |= value & 0x0fff; 429 } 430 431 if (spans) 432 { 433 *(uint8_t *)(b->data + BPS(bs) - 1) = cp[0]; 434 *(uint8_t *)(b1->data) = cp[1]; 435 436 b1->dirty = true; 437 rc = block_put(b1); 438 if (rc != EOK) { 439 block_put(b); 440 return rc; 441 } 442 } 443 } 444 else 445 *cp = value; 446 447 b->dirty = true; /* need to sync block */ 391 /* This cluster access spans a sector boundary. Check only for FAT12 */ 392 if (FAT_IS_FAT12(bs) && (offset % BPS(bs)+1 == BPS(bs))) { 393 /* Is it last sector of FAT? */ 394 if (offset / BPS(bs) < SF(bs)) { 395 /* No. Reading next sector */ 396 rc = block_get(&b1, devmap_handle, 1 + RSCNT(bs) + 397 SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE); 398 if (rc != EOK) { 399 block_put(b); 400 return rc; 401 } 402 /* 403 * Combining value with last byte of current sector and 404 * first byte of next sector 405 */ 406 spans=1; 407 cp = &temp; 408 *cp = *(uint8_t *)(b->data + BPS(bs) - 1); 409 *cp |= *(uint8_t *)(b1->data); 410 } 411 else { 412 /* Yes. It is last sector of fat */ 413 block_put(b); 414 return ERANGE; 415 } 416 } 417 else 418 cp = (fat_cluster_t *)(b->data + offset % BPS(bs)); 419 420 value = host2uint16_t_le(value); 421 if (FAT_IS_FAT12(bs)) { 422 if (clst & 0x0001) { 423 *cp &= 0x000f; 424 *cp |= value << 4; 425 } 426 else { 427 *cp &= 0xf000; 428 *cp |= value & 0x0fff; 429 } 430 431 if (spans) 432 { 433 *(uint8_t *)(b->data + BPS(bs) - 1) = cp[0]; 434 *(uint8_t *)(b1->data) = cp[1]; 435 436 b1->dirty = true; 437 rc = block_put(b1); 438 if (rc != EOK) { 439 block_put(b); 440 return rc; 441 } 442 } 443 } 444 else 445 *cp = value; 446 447 b->dirty = true; /* need to sync block */ 448 448 rc = block_put(b); 449 449 return rc; … … 464 464 uint8_t fatno; 465 465 unsigned c; 466 int rc; 467 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 : 468 FAT12_CLST_LAST1; 466 fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs); 467 int rc; 469 468 470 469 for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) { … … 501 500 fat_cluster_t *mcl, fat_cluster_t *lcl) 502 501 { 503 fat_cluster_t *lifo; /* stack for storing free cluster numbers */ 504 unsigned found = 0; /* top of the free cluster number stack */ 505 fat_cluster_t clst, value; 506 int rc = EOK; 507 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 : 508 FAT12_CLST_LAST1; 509 510 lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t)); 511 if (!lifo) 512 return ENOMEM; 513 /* 514 * Search FAT1 for unused clusters. 515 */ 516 fibril_mutex_lock(&fat_alloc_lock); 517 for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) { 518 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &value); 519 if (rc != EOK) 520 break; 521 522 if (value == FAT_CLST_RES0) { 523 /* 524 * The cluster is free. Put it into our stack 525 * of found clusters and mark it as non-free. 526 */ 527 lifo[found] = clst; 528 rc = fat_set_cluster(bs, devmap_handle, FAT1, clst, 529 (found == 0) ? clst_last1 : 530 lifo[found - 1]); 531 if (rc != EOK) 532 break; 533 534 found++; 535 } 536 } 537 538 if (rc == EOK && found == nclsts) { 539 rc = fat_alloc_shadow_clusters(bs, devmap_handle, lifo, nclsts); 540 if (rc == EOK) { 541 *mcl = lifo[found - 1]; 542 *lcl = lifo[0]; 543 free(lifo); 544 fibril_mutex_unlock(&fat_alloc_lock); 545 return EOK; 546 } 547 } 548 549 /* If something wrong - free the clusters */ 550 if (found > 0) { 551 while (found--) { 552 rc = fat_set_cluster(bs, devmap_handle, FAT1, lifo[found], 553 FAT_CLST_RES0); 554 } 555 } 556 557 free(lifo); 558 fibril_mutex_unlock(&fat_alloc_lock); 559 return ENOSPC; 502 fat_cluster_t *lifo; /* stack for storing free cluster numbers */ 503 unsigned found = 0; /* top of the free cluster number stack */ 504 fat_cluster_t clst, value, clst_last1 = FAT_CLST_LAST1(bs); 505 int rc = EOK; 506 507 lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t)); 508 if (!lifo) 509 return ENOMEM; 510 /* 511 * Search FAT1 for unused clusters. 512 */ 513 fibril_mutex_lock(&fat_alloc_lock); 514 for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) { 515 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &value); 516 if (rc != EOK) 517 break; 518 519 if (value == FAT_CLST_RES0) { 520 /* 521 * The cluster is free. Put it into our stack 522 * of found clusters and mark it as non-free. 523 */ 524 lifo[found] = clst; 525 rc = fat_set_cluster(bs, devmap_handle, FAT1, clst, 526 (found == 0) ? clst_last1 : lifo[found - 1]); 527 if (rc != EOK) 528 break; 529 530 found++; 531 } 532 } 533 534 if (rc == EOK && found == nclsts) { 535 rc = fat_alloc_shadow_clusters(bs, devmap_handle, lifo, nclsts); 536 if (rc == EOK) { 537 *mcl = lifo[found - 1]; 538 *lcl = lifo[0]; 539 free(lifo); 540 fibril_mutex_unlock(&fat_alloc_lock); 541 return EOK; 542 } 543 } 544 545 /* If something wrong - free the clusters */ 546 if (found > 0) { 547 while (found--) { 548 rc = fat_set_cluster(bs, devmap_handle, FAT1, lifo[found], 549 FAT_CLST_RES0); 550 } 551 } 552 553 free(lifo); 554 fibril_mutex_unlock(&fat_alloc_lock); 555 return ENOSPC; 560 556 } 561 557 … … 572 568 { 573 569 unsigned fatno; 574 fat_cluster_t nextc; 575 int rc; 576 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 : 577 FAT12_CLST_LAST1; 578 uint16_t clst_bad = FATTYPE(bs) == 16 ? FAT16_CLST_BAD : 579 FAT12_CLST_BAD; 570 fat_cluster_t nextc, clst_bad = FAT_CLST_BAD(bs); 571 int rc; 580 572 581 573 /* Mark all clusters in the chain as free in all copies of FAT. */ 582 while (firstc < clst_last1) {574 while (firstc < FAT_CLST_LAST1(bs)) { 583 575 assert(firstc >= FAT_CLST_FIRST && firstc < clst_bad); 584 576 rc = fat_get_cluster(bs, devmap_handle, FAT1, firstc, &nextc); … … 632 624 633 625 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 634 rc = fat_set_cluster(bs, nodep->idx->devmap_handle, fatno,635 lastc, mcl);626 rc = fat_set_cluster(bs, nodep->idx->devmap_handle, 627 fatno, lastc, mcl); 636 628 if (rc != EOK) 637 629 return rc; … … 657 649 int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lcl) 658 650 { 651 fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs); 659 652 int rc; 660 653 devmap_handle_t devmap_handle = nodep->idx->devmap_handle; 661 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 :662 FAT12_CLST_LAST1;663 654 664 655 /* … … 790 781 * set to one. 791 782 */ 792 if ( FATTYPE(bs)!=12&& ((e0 >> 8) != 0xff || e1 != 0xffff))783 if (!FAT_IS_FAT12(bs) && ((e0 >> 8) != 0xff || e1 != 0xffff)) 793 784 return ENOTSUP; 794 785 } -
uspace/srv/fs/fat/fat_fat.h
r97bc3ee rd260a95 51 51 #define FAT16_CLST_LAST8 0xffff 52 52 53 #define FAT12_CLST_MAX 4085 54 #define FAT16_CLST_MAX 65525 55 53 56 /* internally used to mark root directory's parent */ 54 57 #define FAT_CLST_ROOTPAR FAT_CLST_RES0 … … 60 63 * primitive boot sector members. 61 64 */ 62 #define RDS(bs) ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \ 63 (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0) 64 #define SSA(bs) (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs)) 65 #define DS(bs) (TS(bs) - SSA(bs)) 66 #define CC(bs) (DS(bs) / SPC(bs)) 67 #define FATTYPE(bs) (bs)->reserved 65 #define RDS(bs) ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \ 66 (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0) 67 #define SSA(bs) (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs)) 68 #define DS(bs) (TS(bs) - SSA(bs)) 69 #define CC(bs) (DS(bs) / SPC(bs)) 70 71 #define FAT_IS_FAT12(bs) (CC(bs) < FAT12_CLST_MAX) 72 #define FAT_IS_FAT16(bs) \ 73 ((CC(bs) >= FAT12_CLST_MAX) && (CC(bs) < FAT16_CLST_MAX)) 74 75 #define FAT_CLST_LAST1(bs) \ 76 (FAT_IS_FAT12(bs) ? FAT12_CLST_LAST1 : FAT16_CLST_LAST1) 77 #define FAT_CLST_LAST8(bs) \ 78 (FAT_IS_FAT12(bs) ? FAT12_CLST_LAST8 : FAT16_CLST_LAST8) 79 #define FAT_CLST_BAD(bs) \ 80 (FAT_IS_FAT12(bs) ? FAT12_CLST_BAD : FAT16_CLST_BAD) 68 81 69 82 /* forward declarations */ -
uspace/srv/fs/fat/fat_ops.c
r97bc3ee rd260a95 1002 1002 } 1003 1003 1004 /* Storing FAT type (12, 16, 32) in reserved field (bs->reserved) */ 1005 if (CC(bs) < 4085) { 1006 /* Volume is FAT12 */ 1007 printf("Found FAT12 filesystem\n"); 1008 (bs)->reserved = 12; 1009 } else if (CC(bs) < 65525) { 1010 /* Volume is FAT16 */ 1011 printf("Found FAT16 filesystem\n"); 1012 (bs)->reserved = 16; 1013 } else { 1014 /* Volume is FAT32 */ 1015 printf("FAT32 filesystem is not supported by FAT server. Sorry.\n"); 1016 block_fini(devmap_handle); 1017 async_answer_0(rid, ENOTSUP); 1018 return; 1019 1020 } 1004 /* Determining type of FAT */ 1005 if (FAT_IS_FAT12(bs)) { 1006 printf("Found FAT12 filesystem\n"); 1007 } else if (FAT_IS_FAT16(bs)) { 1008 printf("Found FAT16 filesystem\n"); 1009 } else { 1010 printf("FAT32 filesystem is not supported by FAT server.\n"); 1011 block_fini(devmap_handle); 1012 async_answer_0(rid, ENOTSUP); 1013 return; 1014 } 1021 1015 1022 1016 /* Do some simple sanity checks on the file system. */
Note:
See TracChangeset
for help on using the changeset viewer.