Changeset a2aa1dec in mainline for uspace/srv/fs/fat/fat_ops.c


Ignore:
Timestamp:
2008-04-02T19:46:57Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0f718ab
Parents:
94b0b63
Message:

First untested bits of FAT lookup support.

File:
1 edited

Legend:

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

    r94b0b63 ra2aa1dec  
    11/*
    2  * Copyright (c) 2007 Jakub Jermar
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3838#include "fat.h"
    3939#include "../../vfs/vfs.h"
     40#include <libfs.h>
    4041#include <ipc/ipc.h>
    4142#include <async.h>
    4243#include <errno.h>
    43 
    44 #define PLB_GET_CHAR(i)         (fat_reg.plb_ro[(i) % PLB_SIZE])
     44#include <string.h>
    4545
    4646#define FAT_NAME_LEN            8
     
    5454#define FAT_DENTRY_ERASED       0xe5
    5555
    56 /** Compare one component of path to a directory entry.
    57  *
    58  * @param dentry        Directory entry to compare the path component with.
    59  * @param start         Index into PLB where the path component starts.
    60  * @param last          Index of the last character of the path in PLB.
    61  *
    62  * @return              Zero on failure or delta such that (index + delta) %
    63  *                      PLB_SIZE points to a new path component in PLB.
    64  */
    65 static unsigned match_path_component(fat_dentry_t *dentry, unsigned start,
    66     unsigned last)
     56static void dentry_name_canonify(fat_dentry_t *d, char *buf)
    6757{
    68         unsigned cur;   /* current position in PLB */
    69         int pos;        /* current position in dentry->name or dentry->ext */
    70         bool name_processed = false;
    71         bool dot_processed = false;
    72         bool ext_processed = false;
     58        int i;
    7359
    74         if (last < start)
    75                 last += PLB_SIZE;
    76         for (pos = 0, cur = start; (cur <= last) && (PLB_GET_CHAR(cur) != '/');
    77             pos++, cur++) {
    78                 if (!name_processed) {
    79                         if ((pos == FAT_NAME_LEN - 1) ||
    80                             (dentry->name[pos + 1] == FAT_PAD)) {
    81                                 /* this is the last character in name */
    82                                 name_processed = true;
    83                         }
    84                         if (dentry->name[0] == FAT_PAD) {
    85                                 /* name is empty */
    86                                 name_processed = true;
    87                         } else if ((pos == 0) && (dentry->name[pos] ==
    88                             FAT_DENTRY_E5_ESC)) {
    89                                 if (PLB_GET_CHAR(cur) == 0xe5)
    90                                         continue;
    91                                 else
    92                                         return 0;       /* character mismatch */
    93                         } else {
    94                                 if (PLB_GET_CHAR(cur) == dentry->name[pos])
    95                                         continue;
    96                                 else
    97                                         return 0;       /* character mismatch */
    98                         }
     60        for (i = 0; i < FAT_NAME_LEN; i++) {
     61                if (d->name[i] == FAT_PAD) {
     62                        buf++;
     63                        break;
    9964                }
    100                 if (!dot_processed) {
    101                         dot_processed = true;
    102                         pos = -1;
    103                         if (PLB_GET_CHAR(cur) != '.')
    104                                 return 0;
     65                if (d->name[i] == FAT_DENTRY_E5_ESC)
     66                        *buf++ = 0xe5;
     67                else
     68                        *buf++ = d->name[i];
     69        }
     70        if (d->ext[0] != FAT_PAD)
     71                *buf++ = '.';
     72        for (i = 0; i < FAT_EXT_LEN; i++) {
     73                if (d->ext[i] == FAT_PAD) {
     74                        *buf = '\0';
     75                        return;
     76                }
     77                if (d->ext[i] == FAT_DENTRY_E5_ESC)
     78                        *buf++ = 0xe5;
     79                else
     80                        *buf++ = d->ext[i];
     81        }
     82}
     83
     84static fat_dentry_t *fat_dentry_get(fat_node_t *dirnode, unsigned idx)
     85{
     86        return NULL;    /* TODO */
     87}
     88
     89static void fat_dentry_put(fat_dentry_t *dentry)
     90{
     91        /* TODO */
     92}
     93
     94static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
     95{
     96        return NULL;    /* TODO */
     97}
     98
     99static void *fat_match(void *prnt, const char *component)
     100{
     101        fat_node_t *parentp = (fat_node_t *)prnt;
     102        char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
     103        unsigned i;
     104        unsigned dentries;
     105        fat_dentry_t *d;
     106
     107        dentries = parentp->size / sizeof(fat_dentry_t);
     108        for (i = 0; i < dentries; i++) {
     109                d = fat_dentry_get(parentp, i);
     110                if (d->attr & FAT_ATTR_VOLLABEL) {
     111                        /* volume label entry */
     112                        fat_dentry_put(d);
    105113                        continue;
    106114                }
    107                 if (!ext_processed) {
    108                         if ((pos == FAT_EXT_LEN - 1) ||
    109                             (dentry->ext[pos + 1] == FAT_PAD)) {
    110                                 /* this is the last character in ext */
    111                                 ext_processed = true;
    112                         }
    113                         if (dentry->ext[0] == FAT_PAD) {
    114                                 /* ext is empty; the match will fail */
    115                                 ext_processed = true;
    116                         } else if (PLB_GET_CHAR(cur) == dentry->ext[pos]) {
    117                                 continue;
    118                         } else {
    119                                 /* character mismatch */
    120                                 return 0;
    121                         }
     115                if (d->name[0] == FAT_DENTRY_ERASED) {
     116                        /* not-currently-used entry */
     117                        fat_dentry_put(d);
     118                        continue;
    122119                }
    123                 return 0;       /* extra characters in the component */
     120                if (d->name[0] == FAT_DENTRY_UNUSED) {
     121                        /* never used entry */
     122                        fat_dentry_put(d);
     123                        break;
     124                }
     125                if (d->name[0] == FAT_DENTRY_DOT) {
     126                        /*
     127                         * Most likely '.' or '..'.
     128                         * It cannot occur in a regular file name.
     129                         */
     130                        fat_dentry_put(d);
     131                        continue;
     132                }
     133               
     134                dentry_name_canonify(d, name);
     135                if (strcmp(name, component) == 0) {
     136                        /* hit */
     137                        void *node = fat_node_get(parentp->dev_handle,
     138                            (fs_index_t)d->firstc);
     139                        fat_dentry_put(d);
     140                        return node;
     141
     142                } else {
     143                        /* miss */
     144                        fat_dentry_put(d);
     145                }
    124146        }
    125         if (ext_processed || (name_processed && dentry->ext[0] == FAT_PAD))
    126                 return cur - start;
    127         else
    128                 return 0;
     147
     148        return NULL;
    129149}
     150
     151/** libfs operations */
     152libfs_ops_t fat_libfs_ops = {
     153        .match = fat_match,
     154        .node_get = fat_node_get,
     155        .create = NULL,
     156        .destroy = NULL,
     157        .link = NULL,
     158        .unlink = NULL,
     159        .index_get = NULL,
     160        .size_get = NULL,
     161        .lnkcnt_get = NULL,
     162        .has_children = NULL,
     163        .root_get = NULL,
     164        .plb_get_char = NULL,
     165        .is_directory = NULL,
     166        .is_file = NULL
     167};
    130168
    131169void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    132170{
    133         int first = IPC_GET_ARG1(*request);
    134         int second = IPC_GET_ARG2(*request);
    135         int dev_handle = IPC_GET_ARG3(*request);
    136 
    137        
     171        libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    138172}
    139173
Note: See TracChangeset for help on using the changeset viewer.