Subversion Repositories HelenOS

Rev

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
 */