Changeset 97bc3ee in mainline for uspace/srv/fs/fat/fat_fat.c
- Timestamp:
- 2011-04-09T19:23:12Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d260a95
- Parents:
- fc35e98
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_fat.c
rfc35e98 r97bc3ee 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 53 53 * primitive boot sector members. 54 54 */ 55 #define RDS(bs) ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \56 (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0)57 #define SSA(bs) (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs))58 59 55 #define CLBN2PBN(bs, cl, bn) \ 60 56 (SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs))) … … 64 60 * during allocation of clusters. The lock does not have to be held durring 65 61 * deallocation of clusters. 66 */ 62 */ 67 63 static FIBRIL_MUTEX_INITIALIZE(fat_alloc_lock); 68 64 … … 76 72 * @param numc If non-NULL, output argument holding the number of 77 73 * clusters seen during the walk. 78 * @param max_clusters Maximum number of clusters to visit. 74 * @param max_clusters Maximum number of clusters to visit. 79 75 * 80 76 * @return EOK on success or a negative error code. 81 77 */ 82 int 78 int 83 79 fat_cluster_walk(fat_bs_t *bs, devmap_handle_t devmap_handle, fat_cluster_t firstc, 84 80 fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters) … … 105 101 106 102 /* read FAT1 */ 107 /* We should use fat_get_cluster instead */108 103 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &clst); 109 104 if (rc != EOK) … … 145 140 return ELIMIT; 146 141 147 if (nodep->firstc == FAT_CLST_ROOT) 142 if (nodep->firstc == FAT_CLST_ROOT) 148 143 goto fall_through; 149 144 … … 172 167 if (rc != EOK) 173 168 return rc; 174 169 175 170 /* 176 171 * Update the "current" cluster cache. … … 192 187 * @param clp If not NULL, address where the cluster containing bn 193 188 * will be stored. 194 * stored 189 * stored 195 190 * @param bn Block number. 196 191 * @param flags Flags passed to libblock. … … 269 264 return rc; 270 265 } 271 266 272 267 if (o >= pos) 273 268 return EOK; 274 269 275 270 /* zero out the initial part of the new cluster chain */ 276 271 for (o = boundary; o < pos; o += BPS(bs)) { … … 302 297 fat_cluster_t clst, fat_cluster_t *value) 303 298 { 304 block_t *b; 305 fat_cluster_t *cp; 306 aoff64_t fsec; /* sector offset relative to FAT */ 307 unsigned fidx; /* entry index */ 299 block_t *b, *b1; 300 aoff64_t offset; 308 301 int rc; 309 302 310 303 assert(fatno < FATCNT(bs)); 311 304 312 313 305 if (FATTYPE(bs) == 16) 314 { 315 fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs); 316 fidx = clst % (BPS(bs) / sizeof(fat_cluster_t)); 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 } 317 343 } 318 344 else 319 { 320 fsec = (clst + clst/2) / BPS(bs); 321 fidx = clst % (2 * BPS(bs) / 3 ); 322 } 323 324 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno + 325 fsec, BLOCK_FLAGS_NONE); 326 if (rc != EOK) 327 return rc; 328 329 if (FATTYPE(bs) == 16) 330 cp = &((fat_cluster_t *)b->data)[fidx]; 331 else 332 cp = (fat_cluster_t *)(b->data + fidx); 333 334 *value = *cp; 335 336 if (FATTYPE(bs) == 12) 337 { 345 *value = *(fat_cluster_t *)(b->data + offset % BPS(bs)); 346 347 if (FATTYPE(bs) == 12) { 338 348 if (clst & 0x0001) 339 349 *value = (*value) >> 4; … … 344 354 *value = uint16_t_le2host(*value); 345 355 rc = block_put(b); 346 356 347 357 return rc; 348 358 } … … 362 372 fat_cluster_t clst, fat_cluster_t value) 363 373 { 364 block_t *b ;365 fat_cluster_t *cp;366 int rc;367 aoff64_t fsec; /* sector offset relative to FAT */ 368 unsigned fidx; /* entry index */374 block_t *b, *b1; 375 aoff64_t offset; 376 fat_cluster_t *cp, temp; 377 int rc; 378 int spans = 0; 369 379 370 380 assert(fatno < FATCNT(bs)); 371 381 372 382 if (FATTYPE(bs) == 16) 373 { 374 fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs); 375 fidx = clst % (BPS(bs) / sizeof(fat_cluster_t)); 383 offset = (clst * sizeof(fat_cluster_t)); 384 else 385 offset = (clst + clst/2); 386 387 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno + 388 offset / BPS(bs), BLOCK_FLAGS_NONE); 389 if (rc != EOK) 390 return rc; 391 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 } 376 416 } 377 417 else 378 {379 fsec = (clst + clst/2) / BPS(bs); 380 fidx = clst % (2 * BPS(bs) / 3);381 }382 383 rc = block_get(&b, devmap_handle, RSCNT(bs) + SF(bs) * fatno +384 fsec, BLOCK_FLAGS_NONE);385 if (rc != EOK) 386 return rc; 387 388 if (FATTYPE(bs) == 12)389 {390 cp = (fat_cluster_t *)(b->data + fidx); 391 if ( clst & 0x0001)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) 392 432 { 393 *cp &= 0x000f; 394 *cp |= host2uint16_t_le(value) << 4; 395 } 396 else 397 { 398 *cp &= 0xf000; 399 *cp |= host2uint16_t_le(value) & 0x0fff; 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 } 400 442 } 401 443 } 402 444 else 403 { 404 cp = &((fat_cluster_t *)b->data)[fidx]; 405 *cp = host2uint16_t_le(value); 406 } 445 *cp = value; 407 446 408 447 b->dirty = true; /* need to sync block */ … … 464 503 fat_cluster_t *lifo; /* stack for storing free cluster numbers */ 465 504 unsigned found = 0; /* top of the free cluster number stack */ 466 fat_cluster_t clst, max_clst,value;505 fat_cluster_t clst, value; 467 506 int rc = EOK; 468 507 uint16_t clst_last1 = FATTYPE(bs) == 16 ? FAT16_CLST_LAST1 : 469 508 FAT12_CLST_LAST1; 470 509 471 472 510 lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t)); 473 511 if (!lifo) 474 512 return ENOMEM; 475 476 513 /* 477 514 * Search FAT1 for unused clusters. 478 515 */ 479 480 if (FATTYPE(bs) == 16)481 max_clst = SF(bs) * BPS(bs) / sizeof(fat_cluster_t);482 else483 max_clst = 2 *SF(bs) * BPS(bs) / 3;484 485 516 fibril_mutex_lock(&fat_alloc_lock); 486 for (clst=0; clst < max_clst && found < nclsts; clst++) 487 { 517 for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) { 488 518 rc = fat_get_cluster(bs, devmap_handle, FAT1, clst, &value); 489 519 if (rc != EOK) 490 520 break; 491 /* 492 * Check if the entire cluster is physically there. 493 * This check becomes necessary when the file system is 494 * created with fewer total sectors than how many is 495 * inferred from the size of the file allocation table 496 * or when the last cluster ends beyond the end of the 497 * device. 498 */ 499 if ((clst >= FAT_CLST_FIRST) && 500 CLBN2PBN(bs, clst, SPC(bs) - 1) >= TS(bs)) { 501 rc = EIO; 502 break; 503 } 521 504 522 if (value == FAT_CLST_RES0) { 505 523 /* … … 518 536 } 519 537 520 if (rc == EOK && found == nclsts) 521 { 538 if (rc == EOK && found == nclsts) { 522 539 rc = fat_alloc_shadow_clusters(bs, devmap_handle, lifo, nclsts); 523 if (rc == EOK) 524 { 540 if (rc == EOK) { 525 541 *mcl = lifo[found - 1]; 526 542 *lcl = lifo[0]; … … 532 548 533 549 /* If something wrong - free the clusters */ 534 if (found > 0) 535 { 550 if (found > 0) { 536 551 while (found--) { 537 552 rc = fat_set_cluster(bs, devmap_handle, FAT1, lifo[found], … … 735 750 736 751 if (bs->totsec16 != 0 && bs->totsec32 != 0 && 737 bs->totsec16 != bs->totsec32) 752 bs->totsec16 != bs->totsec32) 738 753 return ENOTSUP; 739 754 … … 775 790 * set to one. 776 791 */ 777 /* Disabled for testing FAT12 778 if ((e0 >> 8) != 0xff || e1 != 0xffff) 792 if (FATTYPE(bs)!=12 && ((e0 >> 8) != 0xff || e1 != 0xffff)) 779 793 return ENOTSUP; 780 */781 794 } 782 795 … … 786 799 /** 787 800 * @} 788 */ 801 */
Note:
See TracChangeset
for help on using the changeset viewer.