Changeset ad4b32c in mainline for uspace/srv/fs/fat/fat_fat.c
- Timestamp:
- 2009-09-04T21:50:59Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 309ede1
- Parents:
- 7e266ff (diff), 40240b1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_fat.c
r7e266ff rad4b32c 61 61 * @param dev_handle Device handle of the device with the file. 62 62 * @param firstc First cluster to start the walk with. 63 * @param lastc If non-NULL, output argument hodling the last cluster number visited. 63 * @param lastc If non-NULL, output argument hodling the last cluster 64 * number visited. 65 * @param numc If non-NULL, output argument holding the number of 66 * clusters seen during the walk. 64 67 * @param max_clusters Maximum number of clusters to visit. 65 68 * 66 * @return Number of clusters seen during the walk.67 */ 68 uint16_t69 * @return EOK on success or a negative error code. 70 */ 71 int 69 72 fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 70 fat_cluster_t *lastc, uint16_t max_clusters)73 fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters) 71 74 { 72 75 block_t *b; … … 84 87 if (lastc) 85 88 *lastc = firstc; 86 return 0; 89 if (numc) 90 *numc = 0; 91 return EOK; 87 92 } 88 93 … … 98 103 /* read FAT1 */ 99 104 rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); 100 assert(rc == EOK); 105 if (rc != EOK) 106 return rc; 101 107 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); 102 108 assert(clst != FAT_CLST_BAD); 103 109 rc = block_put(b); 104 assert(rc == EOK); 110 if (rc != EOK) 111 return rc; 105 112 clusters++; 106 113 } … … 108 115 if (lastc && clst < FAT_CLST_LAST1) 109 116 *lastc = clst; 110 111 return clusters; 117 if (numc) 118 *numc = clusters; 119 120 return EOK; 112 121 } 113 122 114 123 /** Read block from file located on a FAT file system. 115 124 * 125 * @param block Pointer to a block pointer for storing result. 116 126 * @param bs Buffer holding the boot sector of the file system. 117 127 * @param dev_handle Device handle of the file system. … … 121 131 * @param flags Flags passed to libblock. 122 132 * 123 * @return Block structure holding the requested block. 124 */ 125 block_t * 126 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 127 bn_t bn, int flags) 128 { 129 block_t *b; 133 * @return EOK on success or a negative error code. 134 */ 135 int 136 _fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle, 137 fat_cluster_t firstc, bn_t bn, int flags) 138 { 130 139 unsigned bps; 131 140 unsigned rscnt; /* block address of the first FAT */ … … 134 143 unsigned sf; 135 144 unsigned ssa; /* size of the system area */ 136 unsigned clusters, max_clusters; 145 uint16_t clusters; 146 unsigned max_clusters; 137 147 fat_cluster_t lastc; 138 148 int rc; … … 150 160 /* root directory special case */ 151 161 assert(bn < rds); 152 rc = block_get( &b, dev_handle, rscnt + bs->fatcnt * sf + bn,162 rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn, 153 163 flags); 154 assert(rc == EOK); 155 return b; 164 return rc; 156 165 } 157 166 158 167 max_clusters = bn / bs->spc; 159 clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,168 rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters, 160 169 max_clusters); 170 if (rc != EOK) 171 return rc; 161 172 assert(clusters == max_clusters); 162 173 163 rc = block_get(&b, dev_handle, ssa + 164 (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 165 assert(rc == EOK); 166 167 return b; 174 rc = block_get(block, dev_handle, 175 ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 176 177 return rc; 168 178 } 169 179 … … 177 187 * this argument is ignored. 178 188 * @param pos Position in the last node block. 179 */ 180 void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 189 * 190 * @return EOK on success or a negative error code. 191 */ 192 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 181 193 { 182 194 uint16_t bps; … … 196 208 int flags = (o % bps == 0) ? 197 209 BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE; 198 b = fat_block_get(bs, nodep, o / bps, flags); 210 rc = fat_block_get(&b, bs, nodep, o / bps, flags); 211 if (rc != EOK) 212 return rc; 199 213 memset(b->data + o % bps, 0, bps - o % bps); 200 214 b->dirty = true; /* need to sync node */ 201 215 rc = block_put(b); 202 assert(rc == EOK); 216 if (rc != EOK) 217 return rc; 203 218 } 204 219 205 220 if (o >= pos) 206 return ;221 return EOK; 207 222 208 223 /* zero out the initial part of the new cluster chain */ 209 224 for (o = boundary; o < pos; o += bps) { 210 b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,225 rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl, 211 226 (o - boundary) / bps, BLOCK_FLAGS_NOREAD); 227 if (rc != EOK) 228 return rc; 212 229 memset(b->data, 0, min(bps, pos - o)); 213 230 b->dirty = true; /* need to sync node */ 214 231 rc = block_put(b); 215 assert(rc == EOK); 216 } 232 if (rc != EOK) 233 return rc; 234 } 235 236 return EOK; 217 237 } 218 238 … … 222 242 * @param dev_handle Device handle for the file system. 223 243 * @param clst Cluster which to get. 224 * 225 * @return Value found in the cluster. 226 */ 227 fat_cluster_t 228 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst) 244 * @param value Output argument holding the value of the cluster. 245 * 246 * @return EOK or a negative error code. 247 */ 248 int 249 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst, 250 fat_cluster_t *value) 229 251 { 230 252 block_t *b; 231 253 uint16_t bps; 232 254 uint16_t rscnt; 233 fat_cluster_t *cp , value;255 fat_cluster_t *cp; 234 256 int rc; 235 257 … … 239 261 rc = block_get(&b, dev_handle, rscnt + 240 262 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 241 assert(rc == EOK); 263 if (rc != EOK) 264 return rc; 242 265 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 243 value = uint16_t_le2host(*cp);266 *value = uint16_t_le2host(*cp); 244 267 rc = block_put(b); 245 assert(rc == EOK); 246 247 return value; 268 269 return rc; 248 270 } 249 271 … … 255 277 * @param clst Cluster which is to be set. 256 278 * @param value Value to set the cluster with. 257 */ 258 void 279 * 280 * @return EOK on success or a negative error code. 281 */ 282 int 259 283 fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno, 260 284 fat_cluster_t clst, fat_cluster_t value) … … 274 298 rc = block_get(&b, dev_handle, rscnt + sf * fatno + 275 299 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 276 assert(rc == EOK); 300 if (rc != EOK) 301 return rc; 277 302 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 278 303 *cp = host2uint16_t_le(value); 279 304 b->dirty = true; /* need to sync block */ 280 305 rc = block_put(b); 281 assert(rc == EOK);306 return rc; 282 307 } 283 308 … … 288 313 * @param lifo Chain of allocated clusters. 289 314 * @param nclsts Number of clusters in the lifo chain. 290 */ 291 void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 315 * 316 * @return EOK on success or a negative error code. 317 */ 318 int fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 292 319 fat_cluster_t *lifo, unsigned nclsts) 293 320 { 294 321 uint8_t fatno; 295 322 unsigned c; 323 int rc; 296 324 297 325 for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) { 298 326 for (c = 0; c < nclsts; c++) { 299 fat_set_cluster(bs, dev_handle, fatno, lifo[c],327 rc = fat_set_cluster(bs, dev_handle, fatno, lifo[c], 300 328 c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]); 329 if (rc != EOK) 330 return rc; 301 331 } 302 332 } 333 334 return EOK; 303 335 } 304 336 … … 347 379 for (b = 0, cl = 0; b < sf; b++) { 348 380 rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE); 381 if (rc != EOK) 382 goto error; 349 383 for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) { 350 384 fat_cluster_t *clst = (fat_cluster_t *)blk->data + c; … … 362 396 /* we are almost done */ 363 397 rc = block_put(blk); 364 assert(rc == EOK); 398 if (rc != EOK) 399 goto error; 365 400 /* update the shadow copies of FAT */ 366 fat_alloc_shadow_clusters(bs,401 rc = fat_alloc_shadow_clusters(bs, 367 402 dev_handle, lifo, nclsts); 403 if (rc != EOK) 404 goto error; 368 405 *mcl = lifo[found - 1]; 369 406 *lcl = lifo[0]; … … 375 412 } 376 413 rc = block_put(blk); 377 assert(rc == EOK); 414 if (rc != EOK) { 415 error: 416 fibril_mutex_unlock(&fat_alloc_lock); 417 free(lifo); 418 return rc; 419 } 378 420 } 379 421 fibril_mutex_unlock(&fat_alloc_lock); … … 384 426 */ 385 427 while (found--) { 386 fat_set_cluster(bs, dev_handle, FAT1, lifo[found],428 rc = fat_set_cluster(bs, dev_handle, FAT1, lifo[found], 387 429 FAT_CLST_RES0); 430 if (rc != EOK) { 431 free(lifo); 432 return rc; 433 } 388 434 } 389 435 … … 397 443 * @param dev_handle Device handle of the file system. 398 444 * @param firstc First cluster in the chain which is to be freed. 399 */ 400 void 445 * 446 * @return EOK on success or a negative return code. 447 */ 448 int 401 449 fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc) 402 450 { 403 451 unsigned fatno; 404 452 fat_cluster_t nextc; 453 int rc; 405 454 406 455 /* Mark all clusters in the chain as free in all copies of FAT. */ 407 456 while (firstc < FAT_CLST_LAST1) { 408 457 assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD); 409 nextc = fat_get_cluster(bs, dev_handle, firstc); 410 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 411 fat_set_cluster(bs, dev_handle, fatno, firstc, 458 rc = fat_get_cluster(bs, dev_handle, firstc, &nextc); 459 if (rc != EOK) 460 return rc; 461 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 462 rc = fat_set_cluster(bs, dev_handle, fatno, firstc, 412 463 FAT_CLST_RES0); 464 if (rc != EOK) 465 return rc; 466 } 467 413 468 firstc = nextc; 414 469 } 470 471 return EOK; 415 472 } 416 473 … … 420 477 * @param nodep Node representing the file. 421 478 * @param mcl First cluster of the cluster chain to append. 422 */ 423 void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 479 * 480 * @return EOK on success or a negative error code. 481 */ 482 int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 424 483 { 425 484 dev_handle_t dev_handle = nodep->idx->dev_handle; 426 485 fat_cluster_t lcl; 486 uint16_t numc; 427 487 uint8_t fatno; 428 429 if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, 430 (uint16_t) -1) == 0) { 488 int rc; 489 490 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc, 491 (uint16_t) -1); 492 if (rc != EOK) 493 return rc; 494 495 if (numc == 0) { 431 496 /* No clusters allocated to the node yet. */ 432 497 nodep->firstc = mcl; 433 498 nodep->dirty = true; /* need to sync node */ 434 return; 435 } 436 437 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 438 fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl); 499 return EOK; 500 } 501 502 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 503 rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, 504 mcl); 505 if (rc != EOK) 506 return rc; 507 } 508 509 return EOK; 439 510 } 440 511 … … 446 517 * argument is FAT_CLST_RES0, then all clusters will 447 518 * be chopped off. 448 */ 449 void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 450 { 519 * 520 * @return EOK on success or a negative return code. 521 */ 522 int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 523 { 524 int rc; 525 451 526 dev_handle_t dev_handle = nodep->idx->dev_handle; 452 527 if (lastc == FAT_CLST_RES0) { 453 528 /* The node will have zero size and no clusters allocated. */ 454 fat_free_clusters(bs, dev_handle, nodep->firstc); 529 rc = fat_free_clusters(bs, dev_handle, nodep->firstc); 530 if (rc != EOK) 531 return rc; 455 532 nodep->firstc = FAT_CLST_RES0; 456 533 nodep->dirty = true; /* need to sync node */ … … 459 536 unsigned fatno; 460 537 461 nextc = fat_get_cluster(bs, dev_handle, lastc); 538 rc = fat_get_cluster(bs, dev_handle, lastc, &nextc); 539 if (rc != EOK) 540 return rc; 462 541 463 542 /* Terminate the cluster chain in all copies of FAT. */ 464 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 465 fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1); 543 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 544 rc = fat_set_cluster(bs, dev_handle, fatno, lastc, 545 FAT_CLST_LAST1); 546 if (rc != EOK) 547 return rc; 548 } 466 549 467 550 /* Free all following clusters. */ 468 fat_free_clusters(bs, dev_handle, nextc); 469 } 470 } 471 472 void 551 rc = fat_free_clusters(bs, dev_handle, nextc); 552 if (rc != EOK) 553 return rc; 554 } 555 556 return EOK; 557 } 558 559 int 473 560 fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c) 474 561 { … … 481 568 482 569 for (i = 0; i < bs->spc; i++) { 483 b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD); 570 rc = _fat_block_get(&b, bs, dev_handle, c, i, 571 BLOCK_FLAGS_NOREAD); 572 if (rc != EOK) 573 return rc; 484 574 memset(b->data, 0, bps); 485 575 b->dirty = true; 486 576 rc = block_put(b); 487 assert(rc == EOK); 488 } 577 if (rc != EOK) 578 return rc; 579 } 580 581 return EOK; 489 582 } 490 583
Note:
See TracChangeset
for help on using the changeset viewer.