Changeset e22632a9 in mainline


Ignore:
Timestamp:
2008-04-12T21:38:59Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
74ea3c6
Parents:
e1e3b26
Message:

Somewhat complete implementation of fat_node_get().

File:
1 edited

Legend:

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

    re1e3b26 re22632a9  
    4848#include <assert.h>
    4949
     50#define BS_BLOCK                0
     51
     52#define FIN_KEY_DEV_HANDLE      0
     53#define FIN_KEY_INDEX           1
     54
    5055/** Hash table of FAT in-core nodes. */
    5156hash_table_t fin_hash;
     
    126131}
    127132
     133static uint16_t fat_bps_get(dev_handle_t dev_handle)
     134{
     135        block_t *bb;
     136        uint16_t bps;
     137       
     138        bb = block_get(dev_handle, BS_BLOCK);
     139        assert(bb != NULL);
     140        bps = uint16_t_le2host(((fat_bs_t *)bb->data)->bps);
     141        block_put(bb);
     142
     143        return bps;
     144}
     145
    128146static void fat_sync_node(fat_node_t *node)
    129147{
     
    131149}
    132150
     151/** Instantiate a FAT in-core node.
     152 *
     153 * FAT stores the info necessary for instantiation of a node in the parent of
     154 * that node.  This design necessitated the addition of the parent node index
     155 * parameter to this otherwise generic libfs API.
     156 */
    133157static void *
    134158fat_node_get(dev_handle_t dev_handle, fs_index_t index, fs_index_t pindex)
     
    136160        link_t *lnk;
    137161        fat_node_t *node = NULL;
    138         block_t *bb;
    139162        block_t *b;
     163        unsigned bps;
     164        unsigned dps;
    140165        fat_dentry_t *d;
    141         unsigned bps;           /* bytes per sector */
    142         unsigned dps;           /* dentries per sector */
     166        unsigned i, j;
    143167
    144168        unsigned long key[] = {
    145                 dev_handle,
    146                 index
     169                [FIN_KEY_DEV_HANDLE] = dev_handle,
     170                [FIN_KEY_INDEX] = index
    147171        };
    148172
     
    158182        }
    159183
     184        bps = fat_bps_get(dev_handle);
     185        dps = bps / sizeof(fat_dentry_t);
     186       
    160187        if (!list_empty(&ffn_head)) {
    161188                /*
     
    168195                if (node->dirty)
    169196                        fat_sync_node(node);
     197                key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
     198                key[FIN_KEY_INDEX] = node->index;
     199                hash_table_remove(&fin_hash, key, sizeof(key)/sizeof(*key));
    170200        } else {
    171201                /*
     
    177207        }
    178208        fat_node_initialize(node);
    179 
    180         if (!pindex) {
    181                
    182         } else {
    183         }
    184 
    185 }
    186 
    187 #define BS_BLOCK        0
     209        node->refcnt++;
     210        node->lnkcnt++;
     211        node->dev_handle = dev_handle;
     212        node->index = index;
     213        node->pindex = pindex;
     214
     215        /*
     216         * Because of the design of the FAT file system, we have no clue about
     217         * how big (i.e. how many directory entries it contains) is the parent
     218         * of the node we are trying to instantiate.  However, we know that it
     219         * must contain a directory entry for our node of interest.  We simply
     220         * scan the parent until we find it.
     221         */
     222        for (i = 0; ; i++) {
     223                b = fat_block_get(node->dev_handle, node->pindex, i);
     224                if (!b) {
     225                        node->refcnt--;
     226                        list_append(&node->ffn_link, &ffn_head);
     227                        return NULL;
     228                }
     229                for (j = 0; j < dps; j++) {
     230                        d = ((fat_dentry_t *)b->data) + j;
     231                        if (d->firstc == node->index)
     232                                goto found;
     233                }
     234                block_put(b);
     235        }
     236       
     237found:
     238        if (!(d->attr & (FAT_ATTR_SUBDIR | FAT_ATTR_VOLLABEL)))
     239                node->type = FAT_FILE;
     240        if ((d->attr & FAT_ATTR_SUBDIR) || !pindex)
     241                node->type = FAT_DIRECTORY;
     242        assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY));
     243       
     244        node->size = uint32_t_le2host(d->size);
     245        block_put(b);
     246       
     247        key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
     248        key[FIN_KEY_INDEX] = node->index;
     249        hash_table_insert(&fin_hash, key, &node->fin_link);
     250
     251        return node;
     252}
    188253
    189254static void *fat_match(void *prnt, const char *component)
     
    196261        unsigned blocks;
    197262        fat_dentry_t *d;
    198         block_t *bb;
    199263        block_t *b;
    200264
    201         bb = block_get(parentp->dev_handle, BS_BLOCK);
    202         if (!bb)
    203                 return NULL;
    204         bps = uint16_t_le2host(((fat_bs_t *)bb->data)->bps);
    205         block_put(bb);
     265        bps = fat_bps_get(parentp->dev_handle);
    206266        dps = bps / sizeof(fat_dentry_t);
    207267        blocks = parentp->size / bps + (parentp->size % bps != 0);
Note: See TracChangeset for help on using the changeset viewer.