Subversion Repositories HelenOS

Rev

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

Rev 2855 Rev 2856
Line 44... Line 44...
44
#include <string.h>
44
#include <string.h>
45
#include <byteorder.h>
45
#include <byteorder.h>
46
#include <libadt/hash_table.h>
46
#include <libadt/hash_table.h>
47
#include <libadt/list.h>
47
#include <libadt/list.h>
48
#include <assert.h>
48
#include <assert.h>
-
 
49
#include <futex.h>
49
 
50
 
50
#define BS_BLOCK        0
51
#define BS_BLOCK        0
51
 
52
 
52
#define FIN_KEY_DEV_HANDLE  0
53
#define FIN_KEY_DEV_HANDLE  0
53
#define FIN_KEY_INDEX       1
54
#define FIN_KEY_INDEX       1
54
 
55
 
-
 
56
/** Futex protecting both fin_hash and ffn_head. */
-
 
57
futex_t fin_futex = FUTEX_INITIALIZER;
-
 
58
 
55
/** Hash table of FAT in-core nodes. */
59
/** Hash table of FAT in-core nodes. */
56
hash_table_t fin_hash;
60
hash_table_t fin_hash;
57
 
61
 
58
/** List of free FAT in-core nodes. */
62
/** List of free FAT in-core nodes. */
59
link_t ffn_head;
63
link_t ffn_head;
Line 116... Line 120...
116
    /* TODO */
120
    /* TODO */
117
}
121
}
118
 
122
 
119
static void fat_node_initialize(fat_node_t *node)
123
static void fat_node_initialize(fat_node_t *node)
120
{
124
{
-
 
125
    futex_initialize(&node->lock, 1);
121
    node->type = 0;
126
    node->type = 0;
122
    node->index = 0;
127
    node->index = 0;
123
    node->pindex = 0;
128
    node->pindex = 0;
124
    node->dev_handle = 0;
129
    node->dev_handle = 0;
125
    link_initialize(&node->fin_link);
130
    link_initialize(&node->fin_link);
Line 198... Line 203...
198
    unsigned long key[] = {
203
    unsigned long key[] = {
199
        [FIN_KEY_DEV_HANDLE] = dev_handle,
204
        [FIN_KEY_DEV_HANDLE] = dev_handle,
200
        [FIN_KEY_INDEX] = index
205
        [FIN_KEY_INDEX] = index
201
    };
206
    };
202
 
207
 
-
 
208
    futex_down(&fin_futex);
203
    lnk = hash_table_find(&fin_hash, key);
209
    lnk = hash_table_find(&fin_hash, key);
204
    if (lnk) {
210
    if (lnk) {
205
        /*
211
        /*
206
         * The in-core node was found in the hash table.
212
         * The in-core node was found in the hash table.
207
         */
213
         */
208
        node = hash_table_get_instance(lnk, fat_node_t, fin_link);
214
        node = hash_table_get_instance(lnk, fat_node_t, fin_link);
209
        if (!node->refcnt++)
215
        if (!node->refcnt++)
210
            list_remove(&node->ffn_link);
216
            list_remove(&node->ffn_link);
-
 
217
        futex_up(&fin_futex);
-
 
218
       
-
 
219
        /* Make sure that the node is fully instantiated. */
-
 
220
        futex_down(&node->lock);
-
 
221
        futex_up(&node->lock);
-
 
222
       
211
        return (void *) node;  
223
        return (void *) node;  
212
    }
224
    }
213
 
225
 
214
    bps = fat_bps_get(dev_handle);
226
    bps = fat_bps_get(dev_handle);
215
    dps = bps / sizeof(fat_dentry_t);
227
    dps = bps / sizeof(fat_dentry_t);
Line 239... Line 251...
239
    node->refcnt++;
251
    node->refcnt++;
240
    node->lnkcnt++;
252
    node->lnkcnt++;
241
    node->dev_handle = dev_handle;
253
    node->dev_handle = dev_handle;
242
    node->index = index;
254
    node->index = index;
243
    node->pindex = pindex;
255
    node->pindex = pindex;
-
 
256
    key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
-
 
257
    key[FIN_KEY_INDEX] = node->index;
-
 
258
    hash_table_insert(&fin_hash, key, &node->fin_link);
-
 
259
 
-
 
260
    /*
-
 
261
     * We have already put the node back to fin_hash.
-
 
262
     * The node is not yet fully instantiated so we lock it prior to
-
 
263
     * unlocking fin_hash.
-
 
264
     */
-
 
265
    futex_down(&node->lock);
-
 
266
    futex_up(&fin_futex);
244
 
267
 
245
    /*
268
    /*
246
     * Because of the design of the FAT file system, we have no clue about
269
     * Because of the design of the FAT file system, we have no clue about
247
     * how big (i.e. how many directory entries it contains) is the parent
270
     * how big (i.e. how many directory entries it contains) is the parent
248
     * of the node we are trying to instantiate.  However, we know that it
271
     * of the node we are trying to instantiate.  However, we know that it
Line 266... Line 289...
266
        node->type = FAT_DIRECTORY;
289
        node->type = FAT_DIRECTORY;
267
    assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY));
290
    assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY));
268
   
291
   
269
    node->size = uint32_t_le2host(d->size);
292
    node->size = uint32_t_le2host(d->size);
270
    block_put(b);
293
    block_put(b);
271
   
-
 
272
    key[FIN_KEY_DEV_HANDLE] = node->dev_handle;
-
 
273
    key[FIN_KEY_INDEX] = node->index;
-
 
274
    hash_table_insert(&fin_hash, key, &node->fin_link);
-
 
275
 
294
 
-
 
295
    futex_up(&node->lock);
276
    return node;
296
    return node;
277
}
297
}
278
 
298
 
279
static void fat_node_put(void *node)
299
static void fat_node_put(void *node)
280
{
300
{
281
    fat_node_t *nodep = (fat_node_t *)node;
301
    fat_node_t *nodep = (fat_node_t *)node;
282
 
302
 
-
 
303
    futex_down(&fin_futex);
283
    if (nodep->refcnt-- == 1)
304
    if (!--nodep->refcnt)
284
        list_append(&nodep->ffn_link, &ffn_head);
305
        list_append(&nodep->ffn_link, &ffn_head);
-
 
306
    futex_up(&fin_futex);
285
}
307
}
286
 
308
 
287
static void *fat_match(void *prnt, const char *component)
309
static void *fat_match(void *prnt, const char *component)
288
{
310
{
289
    fat_node_t *parentp = (fat_node_t *)prnt;
311
    fat_node_t *parentp = (fat_node_t *)prnt;