Rev 3550 | Rev 3573 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3550 | Rev 3572 | ||
---|---|---|---|
Line 632... | Line 632... | ||
632 | fat_bs_t *bs; |
632 | fat_bs_t *bs; |
633 | size_t bytes; |
633 | size_t bytes; |
634 | block_t *b; |
634 | block_t *b; |
635 | uint16_t bps; |
635 | uint16_t bps; |
636 | unsigned spc; |
636 | unsigned spc; |
- | 637 | unsigned bpc; /* bytes per cluster */ |
|
637 | off_t boundary; |
638 | off_t boundary; |
638 | 639 | ||
639 | if (!nodep) { |
640 | if (!nodep) { |
640 | ipc_answer_0(rid, ENOENT); |
641 | ipc_answer_0(rid, ENOENT); |
641 | return; |
642 | return; |
Line 648... | Line 649... | ||
648 | ipc_answer_0(callid, EINVAL); |
649 | ipc_answer_0(callid, EINVAL); |
649 | ipc_answer_0(rid, EINVAL); |
650 | ipc_answer_0(rid, EINVAL); |
650 | return; |
651 | return; |
651 | } |
652 | } |
652 | 653 | ||
- | 654 | bs = block_bb_get(dev_handle); |
|
- | 655 | bps = uint16_t_le2host(bs->bps); |
|
- | 656 | spc = bs->spc; |
|
- | 657 | bpc = bps * spc; |
|
- | 658 | ||
653 | /* |
659 | /* |
654 | * In all scenarios, we will attempt to write out only one block worth |
660 | * In all scenarios, we will attempt to write out only one block worth |
655 | * of data at maximum. There might be some more efficient approaches, |
661 | * of data at maximum. There might be some more efficient approaches, |
656 | * but this one greatly simplifies fat_write(). Note that we can afford |
662 | * but this one greatly simplifies fat_write(). Note that we can afford |
657 | * to do this because the client must be ready to handle the return |
663 | * to do this because the client must be ready to handle the return |
658 | * value signalizing a smaller number of bytes written. |
664 | * value signalizing a smaller number of bytes written. |
659 | */ |
665 | */ |
660 | bytes = min(len, bps - pos % bps); |
666 | bytes = min(len, bps - pos % bps); |
661 | - | ||
662 | bs = block_bb_get(dev_handle); |
- | |
663 | bps = uint16_t_le2host(bs->bps); |
- | |
664 | spc = bs->spc; |
- | |
665 | 667 | ||
666 | boundary = ROUND_UP(nodep->size, bps * spc); |
668 | boundary = ROUND_UP(nodep->size, bpc); |
667 | if (pos < boundary) { |
669 | if (pos < boundary) { |
668 | /* |
670 | /* |
669 | * This is the easier case - we are either overwriting already |
671 | * This is the easier case - we are either overwriting already |
670 | * existing contents or writing behind the EOF, but still within |
672 | * existing contents or writing behind the EOF, but still within |
671 | * the limits of the last cluster. The node size may grow to the |
673 | * the limits of the last cluster. The node size may grow to the |
Line 691... | Line 693... | ||
691 | */ |
693 | */ |
692 | int status; |
694 | int status; |
693 | unsigned nclsts; |
695 | unsigned nclsts; |
694 | fat_cluster_t mcl, lcl; |
696 | fat_cluster_t mcl, lcl; |
695 | 697 | ||
696 | nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) / |
698 | nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc; |
697 | bps * spc; |
- | |
698 | /* create an independent chain of nclsts clusters in all FATs */ |
699 | /* create an independent chain of nclsts clusters in all FATs */ |
699 | status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, |
700 | status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl); |
700 | &lcl); |
- | |
701 | if (status != EOK) { |
701 | if (status != EOK) { |
702 | /* could not allocate a chain of nclsts clusters */ |
702 | /* could not allocate a chain of nclsts clusters */ |
703 | fat_node_put(nodep); |
703 | fat_node_put(nodep); |
704 | ipc_answer_0(callid, status); |
704 | ipc_answer_0(callid, status); |
705 | ipc_answer_0(rid, status); |
705 | ipc_answer_0(rid, status); |
Line 729... | Line 729... | ||
729 | { |
729 | { |
730 | dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
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); |
731 | fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
732 | size_t size = (off_t)IPC_GET_ARG3(*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); |
733 | fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
- | 734 | fat_bs_t *bs; |
|
- | 735 | uint16_t bps; |
|
- | 736 | uint8_t spc; |
|
- | 737 | unsigned bpc; /* bytes per cluster */ |
|
734 | int rc; |
738 | int rc; |
735 | 739 | ||
736 | if (!nodep) { |
740 | if (!nodep) { |
737 | ipc_answer_0(rid, ENOENT); |
741 | ipc_answer_0(rid, ENOENT); |
738 | return; |
742 | return; |
739 | } |
743 | } |
740 | 744 | ||
- | 745 | bs = block_bb_get(dev_handle); |
|
- | 746 | bps = uint16_t_le2host(bs->bps); |
|
- | 747 | spc = bs->spc; |
|
- | 748 | bpc = bps * spc; |
|
- | 749 | ||
741 | if (nodep->size == size) { |
750 | if (nodep->size == size) { |
742 | rc = EOK; |
751 | rc = EOK; |
743 | } else if (nodep->size < size) { |
752 | } else if (nodep->size < size) { |
744 | /* |
753 | /* |
745 | * TODO: the standard says we have the freedom to grow the file. |
754 | * The standard says we have the freedom to grow the node. |
746 | * For now, we simply return an error. |
755 | * For now, we simply return an error. |
747 | */ |
756 | */ |
748 | rc = EINVAL; |
757 | rc = EINVAL; |
- | 758 | } else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) { |
|
- | 759 | /* |
|
- | 760 | * The node will be shrunk, but no clusters will be deallocated. |
|
- | 761 | */ |
|
- | 762 | nodep->size = size; |
|
- | 763 | nodep->dirty = true; /* need to sync node */ |
|
- | 764 | rc = EOK; |
|
749 | } else { |
765 | } else { |
750 | /* |
766 | /* |
751 | * The file is to be shrunk. |
767 | * The node will be shrunk, clusters will be deallocated. |
752 | */ |
768 | */ |
- | 769 | if (size == 0) { |
|
- | 770 | fat_chop_clusters(bs, nodep, FAT_CLST_RES0); |
|
- | 771 | } else { |
|
- | 772 | fat_cluster_t lastc; |
|
- | 773 | (void) fat_cluster_walk(bs, dev_handle, nodep->firstc, |
|
- | 774 | &lastc, (size - 1) / bpc); |
|
- | 775 | fat_chop_clusters(bs, nodep, lastc); |
|
- | 776 | } |
|
- | 777 | nodep->size = size; |
|
- | 778 | nodep->dirty = true; /* need to sync node */ |
|
753 | rc = ENOTSUP; /* XXX */ |
779 | rc = EOK; |
754 | } |
780 | } |
755 | fat_node_put(nodep); |
781 | fat_node_put(nodep); |
756 | ipc_answer_0(rid, rc); |
782 | ipc_answer_0(rid, rc); |
757 | return; |
783 | return; |
758 | - | ||
759 | } |
784 | } |
760 | 785 | ||
761 | /** |
786 | /** |
762 | * @} |
787 | * @} |
763 | */ |
788 | */ |