Subversion Repositories HelenOS

Rev

Rev 3325 | Rev 3352 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3325 Rev 3335
Line 762... Line 762...
762
    fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
762
    fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
763
    off_t pos = (off_t)IPC_GET_ARG3(*request);
763
    off_t pos = (off_t)IPC_GET_ARG3(*request);
764
    fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
764
    fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
765
    uint16_t bps = fat_bps_get(dev_handle);
765
    uint16_t bps = fat_bps_get(dev_handle);
766
    size_t bytes;
766
    size_t bytes;
-
 
767
    block_t *b;
767
 
768
 
768
    if (!nodep) {
769
    if (!nodep) {
769
        ipc_answer_0(rid, ENOENT);
770
        ipc_answer_0(rid, ENOENT);
770
        return;
771
        return;
771
    }
772
    }
Line 778... Line 779...
778
        ipc_answer_0(rid, EINVAL);
779
        ipc_answer_0(rid, EINVAL);
779
        return;
780
        return;
780
    }
781
    }
781
 
782
 
782
    if (nodep->type == FAT_FILE) {
783
    if (nodep->type == FAT_FILE) {
783
        block_t *b;
784
        /*
-
 
785
         * Our strategy for regular file reads is to read one block at
-
 
786
         * most and make use of the possibility to return less data than
-
 
787
         * requested. This keeps the code very simple.
784
 
788
         */
785
        bytes = min(len, bps - pos % bps);
789
        bytes = min(len, bps - pos % bps);
786
        b = fat_block_get(nodep, pos / bps);
790
        b = fat_block_get(nodep, pos / bps);
787
        (void) ipc_data_read_finalize(callid, b->data + pos % bps,
791
        (void) ipc_data_read_finalize(callid, b->data + pos % bps,
788
            bytes);
792
            bytes);
789
        block_put(b);
793
        block_put(b);
790
    } else {
794
    } else {
-
 
795
        unsigned bnum;
-
 
796
        off_t spos = pos;
-
 
797
        char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
-
 
798
        fat_dentry_t *d;
-
 
799
 
791
        assert(nodep->type == FAT_DIRECTORY);
800
        assert(nodep->type == FAT_DIRECTORY);
-
 
801
        assert(nodep->size % bps == 0);
-
 
802
        assert(bps % sizeof(fat_dentry_t) == 0);
-
 
803
 
-
 
804
        /*
-
 
805
         * Our strategy for readdir() is to use the position pointer as
-
 
806
         * an index into the array of all dentries. On entry, it points
-
 
807
         * to the first unread dentry. If we skip any dentries, we bump
-
 
808
         * the position pointer accordingly.
792
        /* TODO */
809
         */
-
 
810
        bnum = (pos * sizeof(fat_dentry_t)) / bps;
-
 
811
        while (bnum < nodep->size / bps) {
-
 
812
            off_t o;
-
 
813
 
-
 
814
            b = fat_block_get(nodep, bnum);
-
 
815
            for (o = pos % (bps / sizeof(fat_dentry_t));
-
 
816
                o < bps / sizeof(fat_dentry_t);
-
 
817
                o++, pos++) {
-
 
818
                d = ((fat_dentry_t *)b->data) + o;
-
 
819
                switch (fat_classify_dentry(d)) {
-
 
820
                case FAT_DENTRY_SKIP:
-
 
821
                    continue;
-
 
822
                case FAT_DENTRY_LAST:
-
 
823
                    block_put(b);
-
 
824
                    goto miss;
-
 
825
                default:
-
 
826
                case FAT_DENTRY_VALID:
-
 
827
                    dentry_name_canonify(d, name);
-
 
828
                    block_put(b);
-
 
829
                    goto hit;
-
 
830
                }
-
 
831
            }
-
 
832
            block_put(b);
-
 
833
            bnum++;
-
 
834
        }
-
 
835
miss:
793
        fat_node_put(nodep);
836
        fat_node_put(nodep);
794
        ipc_answer_0(callid, ENOTSUP);
837
        ipc_answer_0(callid, ENOENT);
795
        ipc_answer_0(rid, ENOTSUP);
838
        ipc_answer_1(rid, ENOENT, 0);
796
        return;
839
        return;
-
 
840
hit:
-
 
841
        (void) ipc_data_read_finalize(callid, name, strlen(name) + 1);
-
 
842
        bytes = (pos - spos) + 1;
797
    }
843
    }
798
 
844
 
799
    fat_node_put(nodep);
845
    fat_node_put(nodep);
800
    ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
846
    ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
801
}
847
}