Changeset f3d4cd35 in mainline
- Timestamp:
- 2011-08-14T07:06:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 998a78f
- Parents:
- 7f0c08c
- Location:
- uspace/srv/fs/exfat
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/exfat/exfat_fat.c
r7f0c08c rf3d4cd35 56 56 * deallocation of clusters. 57 57 */ 58 static FIBRIL_MUTEX_INITIALIZE( fat_alloc_lock);58 static FIBRIL_MUTEX_INITIALIZE(exfat_alloc_lock); 59 59 60 60 /** Walk the cluster chain. … … 72 72 */ 73 73 int 74 fat_cluster_walk(exfat_bs_t *bs, devmap_handle_t devmap_handle,74 exfat_cluster_walk(exfat_bs_t *bs, devmap_handle_t devmap_handle, 75 75 exfat_cluster_t firstc, exfat_cluster_t *lastc, uint32_t *numc, 76 76 uint32_t max_clusters) … … 89 89 } 90 90 91 while (clst <= EXFAT_CLST_LAST&& clusters < max_clusters) {91 while (clst != EXFAT_CLST_EOF && clusters < max_clusters) { 92 92 assert(clst >= EXFAT_CLST_FIRST); 93 93 if (lastc) 94 94 *lastc = clst; /* remember the last cluster number */ 95 95 96 rc = fat_get_cluster(bs, devmap_handle, clst, &clst);96 rc = exfat_get_cluster(bs, devmap_handle, clst, &clst); 97 97 if (rc != EOK) 98 98 return rc; … … 102 102 } 103 103 104 if (lastc && clst <= EXFAT_CLST_LAST)104 if (lastc && clst != EXFAT_CLST_EOF) 105 105 *lastc = clst; 106 106 if (numc) … … 202 202 } else { 203 203 max_clusters = bn / SPC(bs); 204 rc = fat_cluster_walk(bs, devmap_handle, fcl, &c, &clusters, max_clusters);204 rc = exfat_cluster_walk(bs, devmap_handle, fcl, &c, &clusters, max_clusters); 205 205 if (rc != EOK) 206 206 return rc; … … 228 228 */ 229 229 int 230 fat_get_cluster(exfat_bs_t *bs, devmap_handle_t devmap_handle,230 exfat_get_cluster(exfat_bs_t *bs, devmap_handle_t devmap_handle, 231 231 exfat_cluster_t clst, exfat_cluster_t *value) 232 232 { … … 258 258 */ 259 259 int 260 fat_set_cluster(exfat_bs_t *bs, devmap_handle_t devmap_handle,260 exfat_set_cluster(exfat_bs_t *bs, devmap_handle_t devmap_handle, 261 261 exfat_cluster_t clst, exfat_cluster_t value) 262 262 { … … 278 278 } 279 279 280 /** Allocate clusters in FAT. 281 * 282 * This function will attempt to allocate the requested number of clusters in 283 * the FAT. The FAT will be altered so that the allocated 284 * clusters form an independent chain (i.e. a chain which does not belong to any 285 * file yet). 286 * 287 * @param bs Buffer holding the boot sector of the file system. 288 * @param devmap_handle Device handle of the file system. 289 * @param nclsts Number of clusters to allocate. 290 * @param mcl Output parameter where the first cluster in the chain 291 * will be returned. 292 * @param lcl Output parameter where the last cluster in the chain 293 * will be returned. 294 * 295 * @return EOK on success, a negative error code otherwise. 296 */ 297 int 298 exfat_alloc_clusters(exfat_bs_t *bs, devmap_handle_t devmap_handle, unsigned nclsts, 299 exfat_cluster_t *mcl, exfat_cluster_t *lcl) 300 { 301 exfat_cluster_t *lifo; /* stack for storing free cluster numbers */ 302 unsigned found = 0; /* top of the free cluster number stack */ 303 exfat_cluster_t clst, value; 304 int rc = EOK; 305 306 lifo = (exfat_cluster_t *) malloc(nclsts * sizeof(exfat_cluster_t)); 307 if (!lifo) 308 return ENOMEM; 309 310 fibril_mutex_lock(&exfat_alloc_lock); 311 for (clst=EXFAT_CLST_FIRST; clst < DATA_CNT(bs)+2 && found < nclsts; clst++) { 312 rc = exfat_get_cluster(bs, devmap_handle, clst, &value); 313 if (rc != EOK) 314 break; 315 316 if (value == 0) { 317 /* 318 * The cluster is free. Put it into our stack 319 * of found clusters and mark it as non-free. 320 */ 321 lifo[found] = clst; 322 rc = exfat_set_cluster(bs, devmap_handle, clst, 323 (found == 0) ? EXFAT_CLST_EOF : lifo[found - 1]); 324 if (rc != EOK) 325 break; 326 327 found++; 328 } 329 } 330 331 if (rc == EOK && found == nclsts) { 332 *mcl = lifo[found - 1]; 333 *lcl = lifo[0]; 334 free(lifo); 335 fibril_mutex_unlock(&exfat_alloc_lock); 336 return EOK; 337 } 338 339 /* If something wrong - free the clusters */ 340 if (found > 0) { 341 while (found--) 342 rc = exfat_set_cluster(bs, devmap_handle, lifo[found], 0); 343 } 344 345 free(lifo); 346 fibril_mutex_unlock(&exfat_alloc_lock); 347 return ENOSPC; 348 } 349 350 /** Free clusters forming a cluster chain in FAT. 351 * 352 * @param bs Buffer hodling the boot sector of the file system. 353 * @param devmap_handle Device handle of the file system. 354 * @param firstc First cluster in the chain which is to be freed. 355 * 356 * @return EOK on success or a negative return code. 357 */ 358 int 359 exfat_free_clusters(exfat_bs_t *bs, devmap_handle_t devmap_handle, exfat_cluster_t firstc) 360 { 361 exfat_cluster_t nextc; 362 int rc; 363 364 /* Mark all clusters in the chain as free */ 365 while (firstc != EXFAT_CLST_EOF) { 366 assert(firstc >= EXFAT_CLST_FIRST && firstc < EXFAT_CLST_BAD); 367 rc = exfat_get_cluster(bs, devmap_handle, firstc, &nextc); 368 if (rc != EOK) 369 return rc; 370 rc = exfat_set_cluster(bs, devmap_handle, firstc, 0); 371 if (rc != EOK) 372 return rc; 373 firstc = nextc; 374 } 375 376 return EOK; 377 } 378 379 /** Append a cluster chain to the last file cluster in FAT. 380 * 381 * @param bs Buffer holding the boot sector of the file system. 382 * @param nodep Node representing the file. 383 * @param mcl First cluster of the cluster chain to append. 384 * @param lcl Last cluster of the cluster chain to append. 385 * 386 * @return EOK on success or a negative error code. 387 */ 388 int 389 exfat_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, exfat_cluster_t mcl, 390 exfat_cluster_t lcl) 391 { 392 devmap_handle_t devmap_handle = nodep->idx->devmap_handle; 393 exfat_cluster_t lastc; 394 int rc; 395 396 if (nodep->firstc == 0) { 397 /* No clusters allocated to the node yet. */ 398 nodep->firstc = mcl; 399 nodep->dirty = true; /* need to sync node */ 400 } else { 401 if (nodep->lastc_cached_valid) { 402 lastc = nodep->lastc_cached_value; 403 nodep->lastc_cached_valid = false; 404 } else { 405 rc = exfat_cluster_walk(bs, devmap_handle, nodep->firstc, 406 &lastc, NULL, (uint16_t) -1); 407 if (rc != EOK) 408 return rc; 409 } 410 411 rc = exfat_set_cluster(bs, nodep->idx->devmap_handle, lastc, mcl); 412 if (rc != EOK) 413 return rc; 414 } 415 416 nodep->lastc_cached_valid = true; 417 nodep->lastc_cached_value = lcl; 418 419 return EOK; 420 } 421 422 /** Chop off node clusters in FAT. 423 * 424 * @param bs Buffer holding the boot sector of the file system. 425 * @param nodep FAT node where the chopping will take place. 426 * @param lcl Last cluster which will remain in the node. If this 427 * argument is FAT_CLST_RES0, then all clusters will 428 * be chopped off. 429 * 430 * @return EOK on success or a negative return code. 431 */ 432 int exfat_chop_clusters(exfat_bs_t *bs, exfat_node_t *nodep, exfat_cluster_t lcl) 433 { 434 int rc; 435 devmap_handle_t devmap_handle = nodep->idx->devmap_handle; 436 437 /* 438 * Invalidate cached cluster numbers. 439 */ 440 nodep->lastc_cached_valid = false; 441 if (nodep->currc_cached_value != lcl) 442 nodep->currc_cached_valid = false; 443 444 if (lcl == 0) { 445 /* The node will have zero size and no clusters allocated. */ 446 rc = exfat_free_clusters(bs, devmap_handle, nodep->firstc); 447 if (rc != EOK) 448 return rc; 449 nodep->firstc = 0; 450 nodep->dirty = true; /* need to sync node */ 451 } else { 452 exfat_cluster_t nextc; 453 454 rc = exfat_get_cluster(bs, devmap_handle, lcl, &nextc); 455 if (rc != EOK) 456 return rc; 457 458 /* Terminate the cluster chain */ 459 rc = exfat_set_cluster(bs, devmap_handle, lcl, EXFAT_CLST_EOF); 460 if (rc != EOK) 461 return rc; 462 463 /* Free all following clusters. */ 464 rc = exfat_free_clusters(bs, devmap_handle, nextc); 465 if (rc != EOK) 466 return rc; 467 } 468 469 /* 470 * Update and re-enable the last cluster cache. 471 */ 472 nodep->lastc_cached_valid = true; 473 nodep->lastc_cached_value = lcl; 474 475 return EOK; 476 } 477 478 int bitmap_alloc_clusters(exfat_bs_t *bs, devmap_handle_t devmap_handle, 479 exfat_cluster_t *firstc, exfat_cluster_t count) 480 { 481 /* TODO */ 482 return EOK; 483 } 484 485 486 int bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 487 exfat_cluster_t count) 488 { 489 /* TODO */ 490 return EOK; 491 } 492 493 494 int bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 495 exfat_cluster_t count) 496 { 497 /* TODO */ 498 return EOK; 499 } 500 501 502 int bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep) 503 { 504 /* TODO */ 505 return EOK; 506 } 507 508 509 280 510 /** Perform basic sanity checks on the file system. 281 511 * -
uspace/srv/fs/exfat/exfat_fat.h
r7f0c08c rf3d4cd35 59 59 60 60 61 #define fat_clusters_get(numc, bs, dh, fc) \62 fat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint32_t) -1)63 extern int fat_cluster_walk(struct exfat_bs *bs, devmap_handle_t devmap_handle,61 #define exfat_clusters_get(numc, bs, dh, fc) \ 62 exfat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint32_t) -1) 63 extern int exfat_cluster_walk(struct exfat_bs *bs, devmap_handle_t devmap_handle, 64 64 exfat_cluster_t firstc, exfat_cluster_t *lastc, uint32_t *numc, 65 65 uint32_t max_clusters); … … 70 70 exfat_cluster_t *clp, aoff64_t bn, int flags); 71 71 72 extern int fat_get_cluster(struct exfat_bs *bs, devmap_handle_t devmap_handle,72 extern int exfat_get_cluster(struct exfat_bs *bs, devmap_handle_t devmap_handle, 73 73 exfat_cluster_t clst, exfat_cluster_t *value); 74 extern int fat_set_cluster(struct exfat_bs *bs, devmap_handle_t devmap_handle,74 extern int exfat_set_cluster(struct exfat_bs *bs, devmap_handle_t devmap_handle, 75 75 exfat_cluster_t clst, exfat_cluster_t value); 76 76 extern int exfat_sanity_check(struct exfat_bs *, devmap_handle_t); 77 77 78 extern int bitmap_alloc_clusters(struct exfat_bs *bs, devmap_handle_t devmap_handle, 79 exfat_cluster_t *firstc, exfat_cluster_t count); 80 extern int bitmap_append_clusters(struct exfat_bs *bs, struct exfat_node *nodep, 81 exfat_cluster_t count); 82 extern int bitmap_free_clusters(struct exfat_bs *bs, struct exfat_node *nodep, 83 exfat_cluster_t count); 84 extern int bitmap_replicate_clusters(struct exfat_bs *bs, struct exfat_node *nodep); 85 86 extern int exfat_append_clusters(struct exfat_bs *, struct exfat_node *, 87 exfat_cluster_t, exfat_cluster_t); 88 extern int exfat_chop_clusters(struct exfat_bs *, struct exfat_node *, 89 exfat_cluster_t); 90 extern int exfat_alloc_clusters(struct exfat_bs *, devmap_handle_t, unsigned, 91 exfat_cluster_t *, exfat_cluster_t *); 92 extern int exfat_free_clusters(struct exfat_bs *, devmap_handle_t, exfat_cluster_t); 78 93 79 94
Note:
See TracChangeset
for help on using the changeset viewer.