Subversion Repositories HelenOS

Rev

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

Rev 2739 Rev 2742
Line 59... Line 59...
59
#define DENTRIES_BUCKETS    256
59
#define DENTRIES_BUCKETS    256
60
 
60
 
61
#define TMPFS_GET_INDEX(x)  (((tmpfs_dentry_t *)(x))->index)
61
#define TMPFS_GET_INDEX(x)  (((tmpfs_dentry_t *)(x))->index)
62
#define TMPFS_GET_LNKCNT(x) 1
62
#define TMPFS_GET_LNKCNT(x) 1
63
 
63
 
-
 
64
/* Forward declarations of static functions. */
-
 
65
static void *create_node(int);
-
 
66
static bool link_node(void *, void *, const char *);
-
 
67
static int unlink_node(void *);
-
 
68
static void destroy_node(void *);
64
/*
69
 
65
 * Hash table of all directory entries.
70
/** Hash table of all directory entries. */
66
 */
-
 
67
hash_table_t dentries;
71
hash_table_t dentries;
68
 
72
 
69
static hash_index_t dentries_hash(unsigned long *key)
73
static hash_index_t dentries_hash(unsigned long *key)
70
{
74
{
71
    return *key % DENTRIES_BUCKETS;
75
    return *key % DENTRIES_BUCKETS;
Line 113... Line 117...
113
 
117
 
114
static bool tmpfs_init(void)
118
static bool tmpfs_init(void)
115
{
119
{
116
    if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
120
    if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
117
        return false;
121
        return false;
118
 
-
 
119
    root = (tmpfs_dentry_t *) malloc(sizeof(tmpfs_dentry_t));
122
    root = (tmpfs_dentry_t *) create_node(L_DIRECTORY);
120
    if (!root)
-
 
121
        return false;
-
 
122
    tmpfs_dentry_initialize(root);
-
 
123
    root->index = tmpfs_next_index++;
-
 
124
    root->name = "";
-
 
125
    root->type = TMPFS_DIRECTORY;
-
 
126
    hash_table_insert(&dentries, &root->index, &root->dh_link);
-
 
127
 
-
 
128
    return true;
123
    return root != NULL;
129
}
124
}
130
 
125
 
131
/** Compare one component of path to a directory entry.
126
/** Compare one component of path to a directory entry.
132
 *
127
 *
133
 * @param nodep     Node to compare the path component with.
128
 * @param nodep     Node to compare the path component with.
Line 140... Line 135...
140
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
135
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
141
 
136
 
142
    return !strcmp(dentry->name, component);
137
    return !strcmp(dentry->name, component);
143
}
138
}
144
 
139
 
145
static void *create_node(void *nodep,
140
void *create_node(int lflag)
146
    const char *component, int lflag)
-
 
147
{
141
{
148
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
-
 
149
 
-
 
150
    assert(dentry->type == TMPFS_DIRECTORY);
-
 
151
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
142
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
152
 
143
 
153
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
144
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
154
    if (!node)
145
    if (!node)
155
        return NULL;
146
        return NULL;
156
    size_t len = strlen(component);
-
 
157
    char *name = malloc(len + 1);
-
 
158
    if (!name) {
-
 
159
        free(node);
-
 
160
        return NULL;
-
 
161
    }
-
 
162
    strcpy(name, component);
-
 
163
 
147
 
164
    tmpfs_dentry_initialize(node);
148
    tmpfs_dentry_initialize(node);
165
    node->index = tmpfs_next_index++;
149
    node->index = tmpfs_next_index++;
166
    node->name = name;
-
 
167
    node->parent = dentry;
-
 
168
    if (lflag & L_DIRECTORY)
150
    if (lflag & L_DIRECTORY)
169
        node->type = TMPFS_DIRECTORY;
151
        node->type = TMPFS_DIRECTORY;
170
    else
152
    else
171
        node->type = TMPFS_FILE;
153
        node->type = TMPFS_FILE;
172
 
154
 
-
 
155
    /* Insert the new node into the dentry hash table. */
-
 
156
    hash_table_insert(&dentries, &node->index, &node->dh_link);
-
 
157
    return (void *) node;
-
 
158
}
-
 
159
 
-
 
160
bool link_node(void *prnt, void *chld, const char *nm)
-
 
161
{
-
 
162
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
-
 
163
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
-
 
164
 
-
 
165
    assert(parentp->type == TMPFS_DIRECTORY);
-
 
166
 
-
 
167
    size_t len = strlen(nm);
-
 
168
    char *name = malloc(len + 1);
-
 
169
    if (!name)
-
 
170
        return false;
-
 
171
    strcpy(name, nm);
-
 
172
    childp->name = name;
-
 
173
 
173
    /* Insert the new node into the namespace. */
174
    /* Insert the new node into the namespace. */
174
    if (dentry->child) {
175
    if (parentp->child) {
175
        tmpfs_dentry_t *tmp = dentry->child;
176
        tmpfs_dentry_t *tmp = parentp->child;
176
        while (tmp->sibling)
177
        while (tmp->sibling)
177
            tmp = tmp->sibling;
178
            tmp = tmp->sibling;
178
        tmp->sibling = node;
179
        tmp->sibling = childp;
179
    } else {
180
    } else {
180
        dentry->child = node;
181
        parentp->child = childp;
181
    }
182
    }
-
 
183
    childp->parent = parentp;
182
 
184
 
183
    /* Insert the new node into the dentry hash table. */
-
 
184
    hash_table_insert(&dentries, &node->index, &node->dh_link);
-
 
185
    return (void *) node;
185
    return true;
186
}
186
}
187
 
187
 
188
static int destroy_component(void *nodeptr)
188
int unlink_node(void *nodeptr)
189
{
189
{
190
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *)nodeptr;
190
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *)nodeptr;
191
 
191
 
192
    if (dentry->child)
192
    if (dentry->child)
193
        return ENOTEMPTY;
193
        return ENOTEMPTY;
Line 205... Line 205...
205
        tmp->sibling = dentry->sibling;
205
        tmp->sibling = dentry->sibling;
206
    }
206
    }
207
    dentry->sibling = NULL;
207
    dentry->sibling = NULL;
208
    dentry->parent = NULL;
208
    dentry->parent = NULL;
209
 
209
 
-
 
210
    free(dentry->name);
-
 
211
    dentry->name = NULL;
-
 
212
 
210
    return EOK;
213
    return EOK;
211
}
214
}
212
 
215
 
-
 
216
void destroy_node(void *nodep)
-
 
217
{
-
 
218
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
-
 
219
   
-
 
220
    assert(!dentry->child);
-
 
221
    assert(!dentry->sibling);
-
 
222
 
-
 
223
    unsigned long index = dentry->index;
-
 
224
    hash_table_remove(&dentries, &index, 1);
-
 
225
 
-
 
226
    if (dentry->type == TMPFS_FILE)
-
 
227
        free(dentry->data);
-
 
228
    free(dentry);
-
 
229
}
-
 
230
 
213
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
231
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
214
{
232
{
215
    unsigned next = IPC_GET_ARG1(*request);
233
    unsigned next = IPC_GET_ARG1(*request);
216
    unsigned last = IPC_GET_ARG2(*request);
234
    unsigned last = IPC_GET_ARG2(*request);
217
    int dev_handle = IPC_GET_ARG3(*request);
235
    int dev_handle = IPC_GET_ARG3(*request);
Line 266... Line 284...
266
                /* no components left and L_CREATE specified */
284
                /* no components left and L_CREATE specified */
267
                if (dcur->type != TMPFS_DIRECTORY) {
285
                if (dcur->type != TMPFS_DIRECTORY) {
268
                    ipc_answer_0(rid, ENOTDIR);
286
                    ipc_answer_0(rid, ENOTDIR);
269
                    return;
287
                    return;
270
                }
288
                }
271
                void *nodep = create_node(dcur,
289
                void *nodep = create_node(lflag);
272
                    component, lflag);
-
 
273
                if (nodep) {
290
                if (nodep) {
-
 
291
                    if (!link_node(dcur, nodep,
-
 
292
                        component)) {
-
 
293
                        destroy_node(nodep);
-
 
294
                        ipc_answer_0(rid, ENOSPC);
-
 
295
                    } else {
274
                    ipc_answer_5(rid, EOK,
296
                        ipc_answer_5(rid, EOK,
275
                        tmpfs_reg.fs_handle, dev_handle,
297
                            tmpfs_reg.fs_handle,
-
 
298
                            dev_handle,
276
                        TMPFS_GET_INDEX(nodep), 0,
299
                            TMPFS_GET_INDEX(nodep), 0,
277
                        TMPFS_GET_LNKCNT(nodep));
300
                            TMPFS_GET_LNKCNT(nodep));
-
 
301
                    }
278
                } else {
302
                } else {
279
                    ipc_answer_0(rid, ENOSPC);
303
                    ipc_answer_0(rid, ENOSPC);
280
                }
304
                }
281
                return;
305
                return;
282
            }
306
            }
Line 314... Line 338...
314
            }
338
            }
315
            assert(len);
339
            assert(len);
316
            component[len] = '\0';
340
            component[len] = '\0';
317
            len = 0;
341
            len = 0;
318
               
342
               
319
            void *nodep = create_node(dcur, component, lflag);
343
            void *nodep = create_node(lflag);
320
            if (nodep) {
344
            if (nodep) {
-
 
345
                if (!link_node(dcur, nodep, component)) {
-
 
346
                    destroy_node(nodep);
-
 
347
                    ipc_answer_0(rid, ENOSPC);
-
 
348
                } else {
-
 
349
                    ipc_answer_5(rid, EOK,
321
                ipc_answer_5(rid, EOK, tmpfs_reg.fs_handle,
350
                        tmpfs_reg.fs_handle,
322
                    dev_handle, TMPFS_GET_INDEX(nodep), 0,
351
                        dev_handle, TMPFS_GET_INDEX(nodep),
323
                    TMPFS_GET_LNKCNT(nodep));
352
                        0, TMPFS_GET_LNKCNT(nodep));
-
 
353
                }
324
            } else {
354
            } else {
325
                ipc_answer_0(rid, ENOSPC);
355
                ipc_answer_0(rid, ENOSPC);
326
            }
356
            }
327
            return;
357
            return;
328
        }
358
        }
Line 331... Line 361...
331
    }
361
    }
332
 
362
 
333
    /* handle hit */
363
    /* handle hit */
334
    if (lflag & L_DESTROY) {
364
    if (lflag & L_DESTROY) {
335
        unsigned old_lnkcnt = TMPFS_GET_LNKCNT(dcur);
365
        unsigned old_lnkcnt = TMPFS_GET_LNKCNT(dcur);
336
        int res = destroy_component(dcur);
366
        int res = unlink_node(dcur);
337
        ipc_answer_5(rid, (ipcarg_t)res, tmpfs_reg.fs_handle,
367
        ipc_answer_5(rid, (ipcarg_t)res, tmpfs_reg.fs_handle,
338
            dev_handle, dcur->index, dcur->size, old_lnkcnt);
368
            dev_handle, dcur->index, dcur->size, old_lnkcnt);
339
        return;
369
        return;
340
    }
370
    }
341
    if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
371
    if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
Line 516... Line 546...
516
    dentry->size = size;
546
    dentry->size = size;
517
    dentry->data = newdata;
547
    dentry->data = newdata;
518
    ipc_answer_0(rid, EOK);
548
    ipc_answer_0(rid, EOK);
519
}
549
}
520
 
550
 
521
void tmpfs_free(ipc_callid_t rid, ipc_call_t *request)
551
void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
522
{
552
{
523
    int dev_handle = IPC_GET_ARG1(*request);
553
    int dev_handle = IPC_GET_ARG1(*request);
524
    unsigned long index = IPC_GET_ARG2(*request);
554
    unsigned long index = IPC_GET_ARG2(*request);
525
 
555
 
526
    link_t *hlp;
556
    link_t *hlp;
Line 529... Line 559...
529
        ipc_answer_0(rid, ENOENT);
559
        ipc_answer_0(rid, ENOENT);
530
        return;
560
        return;
531
    }
561
    }
532
    tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
562
    tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
533
        dh_link);
563
        dh_link);
534
   
-
 
535
    assert(!dentry->parent);
-
 
536
    assert(!dentry->child);
-
 
537
    assert(!dentry->sibling);
-
 
538
 
-
 
539
    hash_table_remove(&dentries, &index, 1);
-
 
540
 
-
 
541
    if (dentry->type == TMPFS_FILE)
-
 
542
        free(dentry->data);
-
 
543
    free(dentry->name);
-
 
544
    free(dentry);
564
    destroy_node(dentry);
545
 
-
 
546
    ipc_answer_0(rid, EOK);
565
    ipc_answer_0(rid, EOK);
547
}
566
}
548
 
567
 
549
/**
568
/**
550
 * @}
569
 * @}