Subversion Repositories HelenOS

Rev

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

Rev 2828 Rev 2831
Line 41... Line 41...
41
#include <ipc/ipc.h>
41
#include <ipc/ipc.h>
42
#include <async.h>
42
#include <async.h>
43
#include <errno.h>
43
#include <errno.h>
44
#include <string.h>
44
#include <string.h>
45
#include <byteorder.h>
45
#include <byteorder.h>
-
 
46
#include <libadt/hash_table.h>
-
 
47
#include <libadt/list.h>
-
 
48
#include <assert.h>
-
 
49
 
-
 
50
/** Hash table of FAT in-core nodes. */
-
 
51
hash_table_t fin_hash;
-
 
52
 
-
 
53
/** List of free FAT in-core nodes. */
-
 
54
link_t ffn_head;
46
 
55
 
47
#define FAT_NAME_LEN        8
56
#define FAT_NAME_LEN        8
48
#define FAT_EXT_LEN     3
57
#define FAT_EXT_LEN     3
49
 
58
 
50
#define FAT_PAD         ' ' 
59
#define FAT_PAD         ' ' 
Line 90... Line 99...
90
static block_t *block_get(dev_handle_t dev_handle, off_t offset)
99
static block_t *block_get(dev_handle_t dev_handle, off_t offset)
91
{
100
{
92
    return NULL;    /* TODO */
101
    return NULL;    /* TODO */
93
}
102
}
94
 
103
 
95
static block_t *fat_block_get(fat_node_t *node, off_t offset) {
104
static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index,
-
 
105
    off_t offset) {
96
    return NULL;    /* TODO */
106
    return NULL;    /* TODO */
97
}
107
}
98
 
108
 
99
static void block_put(block_t *block)
109
static void block_put(block_t *block)
100
{
110
{
101
    /* TODO */
111
    /* TODO */
102
}
112
}
103
 
113
 
104
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
114
static void fat_node_initialize(fat_node_t *node)
105
{
115
{
-
 
116
    node->type = 0;
-
 
117
    node->index = 0;
-
 
118
    node->pindex = 0;
-
 
119
    node->dev_handle = 0;
-
 
120
    link_initialize(&node->fin_link);
-
 
121
    link_initialize(&node->ffn_link);
-
 
122
    node->size = 0;
-
 
123
    node->lnkcnt = 0;
-
 
124
    node->refcnt = 0;
-
 
125
    node->dirty = false;
-
 
126
}
-
 
127
 
-
 
128
static void fat_sync_node(fat_node_t *node)
-
 
129
{
-
 
130
    /* TODO */
-
 
131
}
-
 
132
 
-
 
133
static void *
-
 
134
fat_node_get(dev_handle_t dev_handle, fs_index_t index, fs_index_t pindex)
-
 
135
{
-
 
136
    link_t *lnk;
-
 
137
    fat_node_t *node = NULL;
-
 
138
    block_t *bb;
-
 
139
    block_t *b;
-
 
140
    fat_dentry_t *d;
-
 
141
    unsigned bps;       /* bytes per sector */
-
 
142
    unsigned dps;       /* dentries per sector */
-
 
143
 
-
 
144
    unsigned long key[] = {
-
 
145
        dev_handle,
-
 
146
        index
-
 
147
    };
-
 
148
 
-
 
149
    lnk = hash_table_find(&fin_hash, key);
-
 
150
    if (lnk) {
-
 
151
        /*
-
 
152
         * The in-core node was found in the hash table.
-
 
153
         */
-
 
154
        node = hash_table_get_instance(lnk, fat_node_t, fin_link);
-
 
155
        if (!node->refcnt++)
-
 
156
            list_remove(&node->ffn_link);
-
 
157
        return (void *) node;  
-
 
158
    }
-
 
159
 
-
 
160
    if (!list_empty(&ffn_head)) {
-
 
161
        /*
-
 
162
         * We are going to reuse a node from the free list.
-
 
163
         */
-
 
164
        lnk = ffn_head.next;
-
 
165
        list_remove(lnk);
-
 
166
        node = list_get_instance(lnk, fat_node_t, ffn_link);
-
 
167
        assert(!node->refcnt);
-
 
168
        if (node->dirty)
-
 
169
            fat_sync_node(node);
-
 
170
    } else {
-
 
171
        /*
-
 
172
         * We need to allocate a new node.
-
 
173
         */
-
 
174
        node = malloc(sizeof(fat_node_t));
-
 
175
        if (!node)
106
    return NULL;    /* TODO */
176
            return NULL;
-
 
177
    }
-
 
178
    fat_node_initialize(node);
-
 
179
 
-
 
180
    if (!pindex) {
-
 
181
       
-
 
182
    } else {
-
 
183
    }
-
 
184
 
107
}
185
}
108
 
186
 
109
#define BS_BLOCK    0
187
#define BS_BLOCK    0
110
 
188
 
111
static void *fat_match(void *prnt, const char *component)
189
static void *fat_match(void *prnt, const char *component)
Line 128... Line 206...
128
    dps = bps / sizeof(fat_dentry_t);
206
    dps = bps / sizeof(fat_dentry_t);
129
    blocks = parentp->size / bps + (parentp->size % bps != 0);
207
    blocks = parentp->size / bps + (parentp->size % bps != 0);
130
    for (i = 0; i < blocks; i++) {
208
    for (i = 0; i < blocks; i++) {
131
        unsigned dentries;
209
        unsigned dentries;
132
       
210
       
133
        b = fat_block_get(parentp, i);
211
        b = fat_block_get(parentp->dev_handle, parentp->index, i);
134
        if (!b)
212
        if (!b)
135
            return NULL;
213
            return NULL;
136
 
214
 
137
        dentries = (i == blocks - 1) ?
215
        dentries = (i == blocks - 1) ?
138
            parentp->size % sizeof(fat_dentry_t) :
216
            parentp->size % sizeof(fat_dentry_t) :
Line 162... Line 240...
162
       
240
       
163
            dentry_name_canonify(d, name);
241
            dentry_name_canonify(d, name);
164
            if (strcmp(name, component) == 0) {
242
            if (strcmp(name, component) == 0) {
165
                /* hit */
243
                /* hit */
166
                void *node = fat_node_get(parentp->dev_handle,
244
                void *node = fat_node_get(parentp->dev_handle,
167
                    (fs_index_t)uint16_t_le2host(d->firstc));
245
                    (fs_index_t)uint16_t_le2host(d->firstc),
-
 
246
                    parentp->index);
168
                block_put(b);
247
                block_put(b);
169
                return node;
248
                return node;
170
            }
249
            }
171
        }
250
        }
172
        block_put(b);
251
        block_put(b);
173
    }
252
    }
174
 
253
 
175
    return NULL;
254
    return NULL;
176
}
255
}
177
 
256
 
-
 
257
static fs_index_t fat_index_get(void *node)
-
 
258
{
-
 
259
    fat_node_t *fnodep = (fat_node_t *)node;
-
 
260
    if (!fnodep)
-
 
261
        return 0;
-
 
262
    return fnodep->index;
-
 
263
}
-
 
264
 
-
 
265
static size_t fat_size_get(void *node)
-
 
266
{
-
 
267
    return ((fat_node_t *)node)->size;
-
 
268
}
-
 
269
 
-
 
270
static unsigned fat_lnkcnt_get(void *node)
-
 
271
{
-
 
272
    return ((fat_node_t *)node)->lnkcnt;
-
 
273
}
-
 
274
 
-
 
275
static bool fat_is_directory(void *node)
-
 
276
{
-
 
277
    return ((fat_node_t *)node)->type == FAT_DIRECTORY;
-
 
278
}
-
 
279
 
-
 
280
static bool fat_is_file(void *node)
-
 
281
{
-
 
282
    return ((fat_node_t *)node)->type == FAT_FILE;
-
 
283
}
-
 
284
 
178
/** libfs operations */
285
/** libfs operations */
179
libfs_ops_t fat_libfs_ops = {
286
libfs_ops_t fat_libfs_ops = {
180
    .match = fat_match,
287
    .match = fat_match,
181
    .node_get = fat_node_get,
288
    .node_get = fat_node_get,
182
    .create = NULL,
289
    .create = NULL,
183
    .destroy = NULL,
290
    .destroy = NULL,
184
    .link = NULL,
291
    .link = NULL,
185
    .unlink = NULL,
292
    .unlink = NULL,
186
    .index_get = NULL,
293
    .index_get = fat_index_get,
187
    .size_get = NULL,
294
    .size_get = fat_size_get,
188
    .lnkcnt_get = NULL,
295
    .lnkcnt_get = fat_lnkcnt_get,
189
    .has_children = NULL,
296
    .has_children = NULL,
190
    .root_get = NULL,
297
    .root_get = NULL,
191
    .plb_get_char = NULL,
298
    .plb_get_char = NULL,
192
    .is_directory = NULL,
299
    .is_directory = fat_is_directory,
193
    .is_file = NULL
300
    .is_file = fat_is_file
194
};
301
};
195
 
302
 
196
void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
303
void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
197
{
304
{
198
    libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
305
    libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);