Changes in uspace/srv/fs/fat/fat_ops.c [19f857a:a93d79a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r19f857a ra93d79a 60 60 #define FS_NODE(node) ((node) ? (node)->bp : NULL) 61 61 62 #define DPS(bs) (BPS((bs)) / sizeof(fat_dentry_t)) 63 #define BPC(bs) (BPS((bs)) * SPC((bs))) 64 62 65 /** Mutex protecting the list of cached free FAT nodes. */ 63 66 static FIBRIL_MUTEX_INITIALIZE(ffn_mutex); … … 101 104 node->refcnt = 0; 102 105 node->dirty = false; 106 node->lastc_cached_valid = false; 107 node->lastc_cached_value = FAT_CLST_LAST1; 108 node->currc_cached_valid = false; 109 node->currc_cached_bn = 0; 110 node->currc_cached_value = FAT_CLST_LAST1; 103 111 } 104 112 … … 108 116 fat_bs_t *bs; 109 117 fat_dentry_t *d; 110 uint16_t bps;111 unsigned dps;112 118 int rc; 113 119 … … 115 121 116 122 bs = block_bb_get(node->idx->dev_handle); 117 bps = uint16_t_le2host(bs->bps);118 dps = bps / sizeof(fat_dentry_t);119 123 120 124 /* Read the block that contains the dentry of interest. */ 121 125 rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc, 122 (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); 126 NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs), 127 BLOCK_FLAGS_NONE); 123 128 if (rc != EOK) 124 129 return rc; 125 130 126 d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);131 d = ((fat_dentry_t *)b->data) + (node->idx->pdi % DPS(bs)); 127 132 128 133 d->firstc = host2uint16_t_le(node->firstc); … … 266 271 fat_dentry_t *d; 267 272 fat_node_t *nodep = NULL; 268 unsigned bps;269 unsigned spc;270 unsigned dps;271 273 int rc; 272 274 … … 298 300 299 301 bs = block_bb_get(idxp->dev_handle); 300 bps = uint16_t_le2host(bs->bps);301 spc = bs->spc;302 dps = bps / sizeof(fat_dentry_t);303 302 304 303 /* Read the block that contains the dentry of interest. */ 305 rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, 306 (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);304 rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, NULL, 305 (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE); 307 306 if (rc != EOK) { 308 307 (void) fat_node_put(FS_NODE(nodep)); … … 310 309 } 311 310 312 d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);311 d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs)); 313 312 if (d->attr & FAT_ATTR_SUBDIR) { 314 313 /* … … 330 329 return rc; 331 330 } 332 nodep->size = bps * spc* clusters;331 nodep->size = BPS(bs) * SPC(bs) * clusters; 333 332 } else { 334 333 nodep->type = FAT_FILE; … … 368 367 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; 369 368 unsigned i, j; 370 unsigned bps; /* bytes per sector */371 unsigned dps; /* dentries per sector */372 369 unsigned blocks; 373 370 fat_dentry_t *d; 371 dev_handle_t dev_handle; 374 372 block_t *b; 375 373 int rc; 376 374 377 375 fibril_mutex_lock(&parentp->idx->lock); 378 bs = block_bb_get(parentp->idx->dev_handle); 379 bps = uint16_t_le2host(bs->bps); 380 dps = bps / sizeof(fat_dentry_t); 381 blocks = parentp->size / bps; 376 dev_handle = parentp->idx->dev_handle; 377 fibril_mutex_unlock(&parentp->idx->lock); 378 379 bs = block_bb_get(dev_handle); 380 blocks = parentp->size / BPS(bs); 382 381 for (i = 0; i < blocks; i++) { 383 382 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 384 if (rc != EOK) { 385 fibril_mutex_unlock(&parentp->idx->lock); 383 if (rc != EOK) 386 384 return rc; 387 } 388 for (j = 0; j < dps; j++) { 385 for (j = 0; j < DPS(bs); j++) { 389 386 d = ((fat_dentry_t *)b->data) + j; 390 387 switch (fat_classify_dentry(d)) { … … 395 392 /* miss */ 396 393 rc = block_put(b); 397 fibril_mutex_unlock(&parentp->idx->lock);398 394 *rfn = NULL; 399 395 return rc; … … 406 402 /* hit */ 407 403 fat_node_t *nodep; 408 /* 409 * Assume tree hierarchy for locking. We 410 * already have the parent and now we are going 411 * to lock the child. Never lock in the oposite 412 * order. 413 */ 414 fat_idx_t *idx = fat_idx_get_by_pos( 415 parentp->idx->dev_handle, parentp->firstc, 416 i * dps + j); 417 fibril_mutex_unlock(&parentp->idx->lock); 404 fat_idx_t *idx = fat_idx_get_by_pos(dev_handle, 405 parentp->firstc, i * DPS(bs) + j); 418 406 if (!idx) { 419 407 /* … … 438 426 } 439 427 rc = block_put(b); 440 if (rc != EOK) { 441 fibril_mutex_unlock(&parentp->idx->lock); 428 if (rc != EOK) 442 429 return rc; 443 } 444 } 445 446 fibril_mutex_unlock(&parentp->idx->lock); 430 } 431 447 432 *rfn = NULL; 448 433 return EOK; … … 513 498 fat_bs_t *bs; 514 499 fat_cluster_t mcl, lcl; 515 uint16_t bps;516 500 int rc; 517 501 518 502 bs = block_bb_get(dev_handle); 519 bps = uint16_t_le2host(bs->bps);520 503 if (flags & L_DIRECTORY) { 521 504 /* allocate a cluster */ … … 546 529 nodep->type = FAT_DIRECTORY; 547 530 nodep->firstc = mcl; 548 nodep->size = bps * bs->spc;531 nodep->size = BPS(bs) * SPC(bs); 549 532 } else { 550 533 nodep->type = FAT_FILE; … … 609 592 block_t *b; 610 593 unsigned i, j; 611 uint16_t bps;612 unsigned dps;613 594 unsigned blocks; 614 595 fat_cluster_t mcl, lcl; … … 640 621 fibril_mutex_lock(&parentp->idx->lock); 641 622 bs = block_bb_get(parentp->idx->dev_handle); 642 bps = uint16_t_le2host(bs->bps); 643 dps = bps / sizeof(fat_dentry_t); 644 645 blocks = parentp->size / bps; 623 624 blocks = parentp->size / BPS(bs); 646 625 647 626 for (i = 0; i < blocks; i++) { … … 651 630 return rc; 652 631 } 653 for (j = 0; j < dps; j++) {632 for (j = 0; j < DPS(bs); j++) { 654 633 d = ((fat_dentry_t *)b->data) + j; 655 634 switch (fat_classify_dentry(d)) { … … 691 670 return rc; 692 671 } 693 rc = fat_append_clusters(bs, parentp, mcl );672 rc = fat_append_clusters(bs, parentp, mcl, lcl); 694 673 if (rc != EOK) { 695 674 (void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl); … … 697 676 return rc; 698 677 } 699 parentp->size += bps * bs->spc;678 parentp->size += BPS(bs) * SPC(bs); 700 679 parentp->dirty = true; /* need to sync node */ 701 680 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); … … 771 750 772 751 childp->idx->pfc = parentp->firstc; 773 childp->idx->pdi = i * dps+ j;752 childp->idx->pdi = i * DPS(bs) + j; 774 753 fibril_mutex_unlock(&childp->idx->lock); 775 754 … … 793 772 fat_bs_t *bs; 794 773 fat_dentry_t *d; 795 uint16_t bps;796 774 block_t *b; 797 775 bool has_children; … … 812 790 fibril_mutex_lock(&childp->idx->lock); 813 791 bs = block_bb_get(childp->idx->dev_handle); 814 bps = uint16_t_le2host(bs->bps);815 792 816 793 rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc, 817 (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,794 NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs), 818 795 BLOCK_FLAGS_NONE); 819 796 if (rc != EOK) 820 797 goto error; 821 798 d = (fat_dentry_t *)b->data + 822 (childp->idx->pdi % ( bps/ sizeof(fat_dentry_t)));799 (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t))); 823 800 /* mark the dentry as not-currently-used */ 824 801 d->name[0] = FAT_DENTRY_ERASED; … … 852 829 fat_bs_t *bs; 853 830 fat_node_t *nodep = FAT_NODE(fn); 854 unsigned bps;855 unsigned dps;856 831 unsigned blocks; 857 832 block_t *b; … … 866 841 fibril_mutex_lock(&nodep->idx->lock); 867 842 bs = block_bb_get(nodep->idx->dev_handle); 868 bps = uint16_t_le2host(bs->bps); 869 dps = bps / sizeof(fat_dentry_t); 870 871 blocks = nodep->size / bps; 843 844 blocks = nodep->size / BPS(bs); 872 845 873 846 for (i = 0; i < blocks; i++) { … … 879 852 return rc; 880 853 } 881 for (j = 0; j < dps; j++) {854 for (j = 0; j < DPS(bs); j++) { 882 855 d = ((fat_dentry_t *)b->data) + j; 883 856 switch (fat_classify_dentry(d)) { … … 976 949 enum cache_mode cmode; 977 950 fat_bs_t *bs; 978 uint16_t bps;979 uint16_t rde;980 951 981 952 /* Accept the mount options */ … … 1014 985 bs = block_bb_get(dev_handle); 1015 986 1016 /* Read the number of root directory entries. */ 1017 bps = uint16_t_le2host(bs->bps); 1018 rde = uint16_t_le2host(bs->root_ent_max); 1019 1020 if (bps != BS_SIZE) { 987 if (BPS(bs) != BS_SIZE) { 1021 988 block_fini(dev_handle); 1022 989 ipc_answer_0(rid, ENOTSUP); … … 1025 992 1026 993 /* Initialize the block cache */ 1027 rc = block_cache_init(dev_handle, bps, 0 /* XXX */, cmode);994 rc = block_cache_init(dev_handle, BPS(bs), 0 /* XXX */, cmode); 1028 995 if (rc != EOK) { 1029 996 block_fini(dev_handle); … … 1087 1054 rootp->refcnt = 1; 1088 1055 rootp->lnkcnt = 0; /* FS root is not linked */ 1089 rootp->size = rde* sizeof(fat_dentry_t);1056 rootp->size = RDE(bs) * sizeof(fat_dentry_t); 1090 1057 rootp->idx = ridxp; 1091 1058 ridxp->nodep = rootp; … … 1165 1132 fat_node_t *nodep; 1166 1133 fat_bs_t *bs; 1167 uint16_t bps;1168 1134 size_t bytes; 1169 1135 block_t *b; … … 1191 1157 1192 1158 bs = block_bb_get(dev_handle); 1193 bps = uint16_t_le2host(bs->bps);1194 1159 1195 1160 if (nodep->type == FAT_FILE) { … … 1204 1169 (void) async_data_read_finalize(callid, NULL, 0); 1205 1170 } else { 1206 bytes = min(len, bps - pos % bps);1171 bytes = min(len, BPS(bs) - pos % BPS(bs)); 1207 1172 bytes = min(bytes, nodep->size - pos); 1208 rc = fat_block_get(&b, bs, nodep, pos / bps,1173 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), 1209 1174 BLOCK_FLAGS_NONE); 1210 1175 if (rc != EOK) { … … 1214 1179 return; 1215 1180 } 1216 (void) async_data_read_finalize(callid, b->data + pos % bps,1217 b ytes);1181 (void) async_data_read_finalize(callid, 1182 b->data + pos % BPS(bs), bytes); 1218 1183 rc = block_put(b); 1219 1184 if (rc != EOK) { … … 1230 1195 1231 1196 assert(nodep->type == FAT_DIRECTORY); 1232 assert(nodep->size % bps== 0);1233 assert( bps% sizeof(fat_dentry_t) == 0);1197 assert(nodep->size % BPS(bs) == 0); 1198 assert(BPS(bs) % sizeof(fat_dentry_t) == 0); 1234 1199 1235 1200 /* … … 1239 1204 * the position pointer accordingly. 1240 1205 */ 1241 bnum = (pos * sizeof(fat_dentry_t)) / bps;1242 while (bnum < nodep->size / bps) {1206 bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs); 1207 while (bnum < nodep->size / BPS(bs)) { 1243 1208 aoff64_t o; 1244 1209 … … 1247 1212 if (rc != EOK) 1248 1213 goto err; 1249 for (o = pos % ( bps/ sizeof(fat_dentry_t));1250 o < bps/ sizeof(fat_dentry_t);1214 for (o = pos % (BPS(bs) / sizeof(fat_dentry_t)); 1215 o < BPS(bs) / sizeof(fat_dentry_t); 1251 1216 o++, pos++) { 1252 1217 d = ((fat_dentry_t *)b->data) + o; … … 1306 1271 size_t bytes, size; 1307 1272 block_t *b; 1308 uint16_t bps;1309 unsigned spc;1310 unsigned bpc; /* bytes per cluster */1311 1273 aoff64_t boundary; 1312 1274 int flags = BLOCK_FLAGS_NONE; … … 1334 1296 1335 1297 bs = block_bb_get(dev_handle); 1336 bps = uint16_t_le2host(bs->bps);1337 spc = bs->spc;1338 bpc = bps * spc;1339 1298 1340 1299 /* … … 1345 1304 * value signalizing a smaller number of bytes written. 1346 1305 */ 1347 bytes = min(len, bps - pos % bps);1348 if (bytes == bps)1306 bytes = min(len, BPS(bs) - pos % BPS(bs)); 1307 if (bytes == BPS(bs)) 1349 1308 flags |= BLOCK_FLAGS_NOREAD; 1350 1309 1351 boundary = ROUND_UP(nodep->size, bpc);1310 boundary = ROUND_UP(nodep->size, BPC(bs)); 1352 1311 if (pos < boundary) { 1353 1312 /* … … 1364 1323 return; 1365 1324 } 1366 rc = fat_block_get(&b, bs, nodep, pos / bps, flags);1325 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags); 1367 1326 if (rc != EOK) { 1368 1327 (void) fat_node_put(fn); … … 1371 1330 return; 1372 1331 } 1373 (void) async_data_write_finalize(callid, b->data + pos % bps,1374 b ytes);1332 (void) async_data_write_finalize(callid, 1333 b->data + pos % BPS(bs), bytes); 1375 1334 b->dirty = true; /* need to sync block */ 1376 1335 rc = block_put(b); … … 1396 1355 fat_cluster_t mcl, lcl; 1397 1356 1398 nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;1357 nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs); 1399 1358 /* create an independent chain of nclsts clusters in all FATs */ 1400 1359 rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl); … … 1415 1374 return; 1416 1375 } 1417 rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,1418 flags);1376 rc = _fat_block_get(&b, bs, dev_handle, lcl, NULL, 1377 (pos / BPS(bs)) % SPC(bs), flags); 1419 1378 if (rc != EOK) { 1420 1379 (void) fat_free_clusters(bs, dev_handle, mcl); … … 1424 1383 return; 1425 1384 } 1426 (void) async_data_write_finalize(callid, b->data + pos % bps,1427 b ytes);1385 (void) async_data_write_finalize(callid, 1386 b->data + pos % BPS(bs), bytes); 1428 1387 b->dirty = true; /* need to sync block */ 1429 1388 rc = block_put(b); … … 1438 1397 * node's cluster chain. 1439 1398 */ 1440 rc = fat_append_clusters(bs, nodep, mcl );1399 rc = fat_append_clusters(bs, nodep, mcl, lcl); 1441 1400 if (rc != EOK) { 1442 1401 (void) fat_free_clusters(bs, dev_handle, mcl); … … 1462 1421 fat_node_t *nodep; 1463 1422 fat_bs_t *bs; 1464 uint16_t bps;1465 uint8_t spc;1466 unsigned bpc; /* bytes per cluster */1467 1423 int rc; 1468 1424 … … 1479 1435 1480 1436 bs = block_bb_get(dev_handle); 1481 bps = uint16_t_le2host(bs->bps);1482 spc = bs->spc;1483 bpc = bps * spc;1484 1437 1485 1438 if (nodep->size == size) { … … 1491 1444 */ 1492 1445 rc = EINVAL; 1493 } else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {1446 } else if (ROUND_UP(nodep->size, BPC(bs)) == ROUND_UP(size, BPC(bs))) { 1494 1447 /* 1495 1448 * The node will be shrunk, but no clusters will be deallocated. … … 1509 1462 fat_cluster_t lastc; 1510 1463 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, 1511 &lastc, NULL, (size - 1) / bpc);1464 &lastc, NULL, (size - 1) / BPC(bs)); 1512 1465 if (rc != EOK) 1513 1466 goto out; … … 1564 1517 void fat_sync(ipc_callid_t rid, ipc_call_t *request) 1565 1518 { 1566 /* Dummy implementation */ 1567 ipc_answer_0(rid, EOK); 1519 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 1520 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1521 1522 fs_node_t *fn; 1523 int rc = fat_node_get(&fn, dev_handle, index); 1524 if (rc != EOK) { 1525 ipc_answer_0(rid, rc); 1526 return; 1527 } 1528 if (!fn) { 1529 ipc_answer_0(rid, ENOENT); 1530 return; 1531 } 1532 1533 fat_node_t *nodep = FAT_NODE(fn); 1534 1535 nodep->dirty = true; 1536 rc = fat_node_sync(nodep); 1537 1538 fat_node_put(fn); 1539 ipc_answer_0(rid, rc); 1568 1540 } 1569 1541
Note:
See TracChangeset
for help on using the changeset viewer.