Rev 3535 | Rev 3588 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3535 | Rev 3561 | ||
---|---|---|---|
Line 111... | Line 111... | ||
111 | block_t *b; |
111 | block_t *b; |
112 | fat_bs_t *bs; |
112 | fat_bs_t *bs; |
113 | fat_dentry_t *d; |
113 | fat_dentry_t *d; |
114 | fat_node_t *nodep = NULL; |
114 | fat_node_t *nodep = NULL; |
115 | unsigned bps; |
115 | unsigned bps; |
- | 116 | unsigned spc; |
|
116 | unsigned dps; |
117 | unsigned dps; |
117 | 118 | ||
118 | if (idxp->nodep) { |
119 | if (idxp->nodep) { |
119 | /* |
120 | /* |
120 | * We are lucky. |
121 | * We are lucky. |
Line 162... | Line 163... | ||
162 | } |
163 | } |
163 | fat_node_initialize(nodep); |
164 | fat_node_initialize(nodep); |
164 | 165 | ||
165 | bs = block_bb_get(idxp->dev_handle); |
166 | bs = block_bb_get(idxp->dev_handle); |
166 | bps = uint16_t_le2host(bs->bps); |
167 | bps = uint16_t_le2host(bs->bps); |
- | 168 | spc = bs->spc; |
|
167 | dps = bps / sizeof(fat_dentry_t); |
169 | dps = bps / sizeof(fat_dentry_t); |
168 | 170 | ||
169 | /* Read the block that contains the dentry of interest. */ |
171 | /* Read the block that contains the dentry of interest. */ |
170 | b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc, |
172 | b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc, |
171 | (idxp->pdi * sizeof(fat_dentry_t)) / bps); |
173 | (idxp->pdi * sizeof(fat_dentry_t)) / bps); |
Line 182... | Line 184... | ||
182 | /* |
184 | /* |
183 | * Unfortunately, the 'size' field of the FAT dentry is not |
185 | * Unfortunately, the 'size' field of the FAT dentry is not |
184 | * defined for the directory entry type. We must determine the |
186 | * defined for the directory entry type. We must determine the |
185 | * size of the directory by walking the FAT. |
187 | * size of the directory by walking the FAT. |
186 | */ |
188 | */ |
187 | nodep->size = bps * _fat_blcks_get(bs, idxp->dev_handle, |
189 | nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle, |
188 | uint16_t_le2host(d->firstc), NULL); |
190 | uint16_t_le2host(d->firstc)); |
189 | } else { |
191 | } else { |
190 | nodep->type = FAT_FILE; |
192 | nodep->type = FAT_FILE; |
191 | nodep->size = uint32_t_le2host(d->size); |
193 | nodep->size = uint32_t_le2host(d->size); |
192 | } |
194 | } |
193 | nodep->firstc = uint16_t_le2host(d->firstc); |
195 | nodep->firstc = uint16_t_le2host(d->firstc); |
Line 432... | Line 434... | ||
432 | uint16_t bps; |
434 | uint16_t bps; |
433 | uint16_t rde; |
435 | uint16_t rde; |
434 | int rc; |
436 | int rc; |
435 | 437 | ||
436 | /* initialize libblock */ |
438 | /* initialize libblock */ |
437 | rc = block_init(dev_handle, BS_SIZE, BS_BLOCK * BS_SIZE, BS_SIZE); |
439 | rc = block_init(dev_handle, BS_SIZE); |
438 | if (rc != EOK) { |
440 | if (rc != EOK) { |
439 | ipc_answer_0(rid, 0); |
441 | ipc_answer_0(rid, rc); |
- | 442 | return; |
|
- | 443 | } |
|
- | 444 | ||
- | 445 | /* prepare the boot block */ |
|
- | 446 | rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE); |
|
- | 447 | if (rc != EOK) { |
|
- | 448 | block_fini(dev_handle); |
|
- | 449 | ipc_answer_0(rid, rc); |
|
440 | return; |
450 | return; |
441 | } |
451 | } |
442 | 452 | ||
443 | /* get the buffer with the boot sector */ |
453 | /* get the buffer with the boot sector */ |
444 | bs = block_bb_get(dev_handle); |
454 | bs = block_bb_get(dev_handle); |
Line 451... | Line 461... | ||
451 | block_fini(dev_handle); |
461 | block_fini(dev_handle); |
452 | ipc_answer_0(rid, ENOTSUP); |
462 | ipc_answer_0(rid, ENOTSUP); |
453 | return; |
463 | return; |
454 | } |
464 | } |
455 | 465 | ||
- | 466 | /* Initialize the block cache */ |
|
- | 467 | rc = block_cache_init(dev_handle, bps, 0 /* XXX */); |
|
- | 468 | if (rc != EOK) { |
|
- | 469 | block_fini(dev_handle); |
|
- | 470 | ipc_answer_0(rid, rc); |
|
- | 471 | return; |
|
- | 472 | } |
|
- | 473 | ||
456 | rc = fat_idx_init_by_dev_handle(dev_handle); |
474 | rc = fat_idx_init_by_dev_handle(dev_handle); |
457 | if (rc != EOK) { |
475 | if (rc != EOK) { |
458 | block_fini(dev_handle); |
476 | block_fini(dev_handle); |
459 | ipc_answer_0(rid, rc); |
477 | ipc_answer_0(rid, rc); |
460 | return; |
478 | return; |
Line 621... | Line 639... | ||
621 | if (!nodep) { |
639 | if (!nodep) { |
622 | ipc_answer_0(rid, ENOENT); |
640 | ipc_answer_0(rid, ENOENT); |
623 | return; |
641 | return; |
624 | } |
642 | } |
625 | 643 | ||
626 | /* XXX remove me when you are ready */ |
- | |
627 | { |
- | |
628 | ipc_answer_0(rid, ENOTSUP); |
- | |
629 | fat_node_put(nodep); |
- | |
630 | return; |
- | |
631 | } |
- | |
632 | - | ||
633 | ipc_callid_t callid; |
644 | ipc_callid_t callid; |
634 | size_t len; |
645 | size_t len; |
635 | if (!ipc_data_write_receive(&callid, &len)) { |
646 | if (!ipc_data_write_receive(&callid, &len)) { |
636 | fat_node_put(nodep); |
647 | fat_node_put(nodep); |
637 | ipc_answer_0(callid, EINVAL); |
648 | ipc_answer_0(callid, EINVAL); |
Line 678... | Line 689... | ||
678 | * This is the more difficult case. We must allocate new |
689 | * This is the more difficult case. We must allocate new |
679 | * clusters for the node and zero them out. |
690 | * clusters for the node and zero them out. |
680 | */ |
691 | */ |
681 | int status; |
692 | int status; |
682 | unsigned nclsts; |
693 | unsigned nclsts; |
683 | fat_cluster_t mcl, lcl; |
694 | fat_cluster_t mcl, lcl; |
684 | 695 | ||
685 | nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) / |
696 | nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) / |
686 | bps * spc; |
697 | bps * spc; |
687 | /* create an independent chain of nclsts clusters in all FATs */ |
698 | /* create an independent chain of nclsts clusters in all FATs */ |
688 | status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, |
699 | status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, |
689 | &lcl); |
700 | &lcl); |
Line 694... | Line 705... | ||
694 | ipc_answer_0(rid, status); |
705 | ipc_answer_0(rid, status); |
695 | return; |
706 | return; |
696 | } |
707 | } |
697 | /* zero fill any gaps */ |
708 | /* zero fill any gaps */ |
698 | fat_fill_gap(bs, nodep, mcl, pos); |
709 | fat_fill_gap(bs, nodep, mcl, pos); |
699 | b = _fat_block_get(bs, dev_handle, lcl, |
710 | b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc); |
700 | (pos / bps) % spc); |
- | |
701 | (void) ipc_data_write_finalize(callid, b->data + pos % bps, |
711 | (void) ipc_data_write_finalize(callid, b->data + pos % bps, |
702 | bytes); |
712 | bytes); |
703 | b->dirty = true; /* need to sync block */ |
713 | b->dirty = true; /* need to sync block */ |
704 | block_put(b); |
714 | block_put(b); |
705 | /* |
715 | /* |
Line 713... | Line 723... | ||
713 | ipc_answer_1(rid, EOK, bytes); |
723 | ipc_answer_1(rid, EOK, bytes); |
714 | return; |
724 | return; |
715 | } |
725 | } |
716 | } |
726 | } |
717 | 727 | ||
- | 728 | void fat_truncate(ipc_callid_t rid, ipc_call_t *request) |
|
- | 729 | { |
|
- | 730 | dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
|
- | 731 | fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
|
- | 732 | size_t size = (off_t)IPC_GET_ARG3(*request); |
|
- | 733 | fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
|
- | 734 | int rc; |
|
- | 735 | ||
- | 736 | if (!nodep) { |
|
- | 737 | ipc_answer_0(rid, ENOENT); |
|
- | 738 | return; |
|
- | 739 | } |
|
- | 740 | ||
- | 741 | if (nodep->size == size) { |
|
- | 742 | rc = EOK; |
|
- | 743 | } else if (nodep->size < size) { |
|
- | 744 | /* |
|
- | 745 | * TODO: the standard says we have the freedom to grow the file. |
|
- | 746 | * For now, we simply return an error. |
|
- | 747 | */ |
|
- | 748 | rc = EINVAL; |
|
- | 749 | } else { |
|
- | 750 | /* |
|
- | 751 | * The file is to be shrunk. |
|
- | 752 | */ |
|
- | 753 | rc = ENOTSUP; /* XXX */ |
|
- | 754 | } |
|
- | 755 | fat_node_put(nodep); |
|
- | 756 | ipc_answer_0(rid, rc); |
|
- | 757 | return; |
|
- | 758 | ||
- | 759 | } |
|
- | 760 | ||
718 | /** |
761 | /** |
719 | * @} |
762 | * @} |
720 | */ |
763 | */ |