Changeset ddd1219 in mainline


Ignore:
Timestamp:
2008-08-18T21:17:51Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fa81b5f
Parents:
6c2f4e91
Message:

Support for readdir() on FAT.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_ops.c

    r6c2f4e91 rddd1219  
    765765        uint16_t bps = fat_bps_get(dev_handle);
    766766        size_t bytes;
     767        block_t *b;
    767768
    768769        if (!nodep) {
     
    781782
    782783        if (nodep->type == FAT_FILE) {
    783                 block_t *b;
    784 
     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.
     788                 */
    785789                bytes = min(len, bps - pos % bps);
    786790                b = fat_block_get(nodep, pos / bps);
     
    789793                block_put(b);
    790794        } 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
    791800                assert(nodep->type == FAT_DIRECTORY);
    792                 /* TODO */
     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.
     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                }
     835miss:
    793836                fat_node_put(nodep);
    794                 ipc_answer_0(callid, ENOTSUP);
    795                 ipc_answer_0(rid, ENOTSUP);
    796                 return;
     837                ipc_answer_0(callid, ENOENT);
     838                ipc_answer_1(rid, ENOENT, 0);
     839                return;
     840hit:
     841                (void) ipc_data_read_finalize(callid, name, strlen(name) + 1);
     842                bytes = (pos - spos) + 1;
    797843        }
    798844
Note: See TracChangeset for help on using the changeset viewer.