Subversion Repositories HelenOS

Rev

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

Rev 2690 Rev 2691
Line 68... Line 68...
68
 
68
 
69
/** Perform a path lookup.
69
/** Perform a path lookup.
70
 *
70
 *
71
 * @param path      Path to be resolved; it needn't be an ASCIIZ string.
71
 * @param path      Path to be resolved; it needn't be an ASCIIZ string.
72
 * @param len       Number of path characters pointed by path.
72
 * @param len       Number of path characters pointed by path.
73
 * @param result    Empty node structure where the result will be stored.
73
 * @param result    Empty structure where the lookup result will be stored.
74
 * @param size      Storage where the size of the node will be stored. Can
-
 
75
 *          be NULL.
-
 
76
 * @param altroot   If non-empty, will be used instead of rootfs as the root
74
 * @param altroot   If non-empty, will be used instead of rootfs as the root
77
 *          of the whole VFS tree.
75
 *          of the whole VFS tree.
78
 *
76
 *
79
 * @return      EOK on success or an error code from errno.h.
77
 * @return      EOK on success or an error code from errno.h.
80
 */
78
 */
81
int vfs_lookup_internal(char *path, size_t len, vfs_triplet_t *result,
79
int vfs_lookup_internal(char *path, size_t len, vfs_lookup_res_t *result,
82
    size_t *size, vfs_pair_t *altroot)
80
    vfs_pair_t *altroot)
83
{
81
{
84
    vfs_pair_t *root;
82
    vfs_pair_t *root;
85
 
83
 
86
    if (!len)
84
    if (!len)
87
        return EINVAL;
85
        return EINVAL;
Line 177... Line 175...
177
    memset(&plb[first], 0, cnt1);
175
    memset(&plb[first], 0, cnt1);
178
    memset(plb, 0, cnt2);
176
    memset(plb, 0, cnt2);
179
    futex_up(&plb_futex);
177
    futex_up(&plb_futex);
180
 
178
 
181
    if (rc == EOK) {
179
    if (rc == EOK) {
182
        result->fs_handle = (int) IPC_GET_ARG1(answer);
180
        result->triplet.fs_handle = (int) IPC_GET_ARG1(answer);
183
        result->dev_handle = (int) IPC_GET_ARG2(answer);
181
        result->triplet.dev_handle = (int) IPC_GET_ARG2(answer);
184
        result->index = (int) IPC_GET_ARG3(answer);
182
        result->triplet.index = (int) IPC_GET_ARG3(answer);
185
        if (size)
-
 
186
            *size = (size_t) IPC_GET_ARG4(answer);
183
        result->size = (size_t) IPC_GET_ARG4(answer);
187
    }
184
    }
188
 
185
 
189
    return rc;
186
    return rc;
190
}
187
}
191
 
188
 
Line 194... Line 191...
194
    .fs_handle = 0,
191
    .fs_handle = 0,
195
    .dev_handle = 0,
192
    .dev_handle = 0,
196
    .index = 0,
193
    .index = 0,
197
};
194
};
198
 
195
 
199
static int lookup_root(int fs_handle, int dev_handle, vfs_triplet_t *root,
196
static int lookup_root(int fs_handle, int dev_handle, vfs_lookup_res_t *result)
200
    size_t *size)
-
 
201
{
197
{
202
    vfs_pair_t altroot = {
198
    vfs_pair_t altroot = {
203
        .fs_handle = fs_handle,
199
        .fs_handle = fs_handle,
204
        .dev_handle = dev_handle,
200
        .dev_handle = dev_handle,
205
    };
201
    };
206
 
202
 
207
    return vfs_lookup_internal("/", strlen("/"), root, size, &altroot);
203
    return vfs_lookup_internal("/", strlen("/"), result, &altroot);
208
}
204
}
209
 
205
 
210
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
206
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
211
{
207
{
212
    int dev_handle;
208
    int dev_handle;
Line 302... Line 298...
302
     * In this case, we don't need to take the namespace_futex as the root
298
     * In this case, we don't need to take the namespace_futex as the root
303
     * node cannot be removed. However, we do take a reference to it so
299
     * node cannot be removed. However, we do take a reference to it so
304
     * that we can track how many times it has been mounted.
300
     * that we can track how many times it has been mounted.
305
     */
301
     */
306
    int rc;
302
    int rc;
307
    vfs_triplet_t mounted_root;
303
    vfs_lookup_res_t mr_res;
308
    size_t mrsz;
-
 
309
    rc = lookup_root(fs_handle, dev_handle, &mounted_root, &mrsz);
304
    rc = lookup_root(fs_handle, dev_handle, &mr_res);
310
    if (rc != EOK) {
305
    if (rc != EOK) {
311
        free(buf);
306
        free(buf);
312
        ipc_answer_0(rid, rc);
307
        ipc_answer_0(rid, rc);
313
        return;
308
        return;
314
    }
309
    }
315
    vfs_node_t *mr_node = vfs_node_get(&mounted_root, mrsz);
310
    vfs_node_t *mr_node = vfs_node_get(&mr_res);
316
    if (!mr_node) {
311
    if (!mr_node) {
317
        free(buf);
312
        free(buf);
318
        ipc_answer_0(rid, ENOMEM);
313
        ipc_answer_0(rid, ENOMEM);
319
        return;
314
        return;
320
    }
315
    }
321
 
316
 
322
    /*
317
    /*
323
     * Finally, we need to resolve the path to the mountpoint.
318
     * Finally, we need to resolve the path to the mountpoint.
324
     */
319
     */
325
    vfs_triplet_t mp;
320
    vfs_lookup_res_t mp_res;
326
    size_t mpsz;
-
 
327
    futex_down(&rootfs_futex);
321
    futex_down(&rootfs_futex);
328
    if (rootfs.fs_handle) {
322
    if (rootfs.fs_handle) {
329
        /*
323
        /*
330
         * We already have the root FS.
324
         * We already have the root FS.
331
         */
325
         */
332
        rwlock_write_lock(&namespace_rwlock);
326
        rwlock_write_lock(&namespace_rwlock);
333
        rc = vfs_lookup_internal(buf, size, &mp, &mpsz, NULL);
327
        rc = vfs_lookup_internal(buf, size, &mp_res, NULL);
334
        if (rc != EOK) {
328
        if (rc != EOK) {
335
            /*
329
            /*
336
             * The lookup failed for some reason.
330
             * The lookup failed for some reason.
337
             */
331
             */
338
            rwlock_write_unlock(&namespace_rwlock);
332
            rwlock_write_unlock(&namespace_rwlock);
Line 340... Line 334...
340
            vfs_node_put(mr_node);  /* failed -> drop reference */
334
            vfs_node_put(mr_node);  /* failed -> drop reference */
341
            free(buf);
335
            free(buf);
342
            ipc_answer_0(rid, rc);
336
            ipc_answer_0(rid, rc);
343
            return;
337
            return;
344
        }
338
        }
345
        mp_node = vfs_node_get(&mp, mpsz);
339
        mp_node = vfs_node_get(&mp_res);
346
        if (!mp_node) {
340
        if (!mp_node) {
347
            rwlock_write_unlock(&namespace_rwlock);
341
            rwlock_write_unlock(&namespace_rwlock);
348
            futex_up(&rootfs_futex);
342
            futex_up(&rootfs_futex);
349
            vfs_node_put(mr_node);  /* failed -> drop reference */
343
            vfs_node_put(mr_node);  /* failed -> drop reference */
350
            free(buf);
344
            free(buf);
Line 363... Line 357...
363
         */
357
         */
364
        if ((size == 1) && (buf[0] == '/')) {
358
        if ((size == 1) && (buf[0] == '/')) {
365
            /*
359
            /*
366
             * For this simple, but important case, we are done.
360
             * For this simple, but important case, we are done.
367
             */
361
             */
368
            rootfs = mounted_root;
362
            rootfs = mr_res.triplet;
369
            futex_up(&rootfs_futex);
363
            futex_up(&rootfs_futex);
370
            free(buf);
364
            free(buf);
371
            ipc_answer_0(rid, EOK);
365
            ipc_answer_0(rid, EOK);
372
            return;
366
            return;
373
        } else {
367
        } else {
Line 390... Line 384...
390
     * At this point, we have all necessary pieces: file system and device
384
     * At this point, we have all necessary pieces: file system and device
391
     * handles, and we know the mount point VFS node and also the root node
385
     * handles, and we know the mount point VFS node and also the root node
392
     * of the file system being mounted.
386
     * of the file system being mounted.
393
     */
387
     */
394
 
388
 
395
    int phone = vfs_grab_phone(mp.fs_handle);
389
    int phone = vfs_grab_phone(mp_res.triplet.fs_handle);
396
    /* Later we can use ARG3 to pass mode/flags. */
390
    /* Later we can use ARG3 to pass mode/flags. */
397
    aid_t req1 = async_send_3(phone, VFS_MOUNT, (ipcarg_t) mp.dev_handle,
391
    aid_t req1 = async_send_3(phone, VFS_MOUNT,
-
 
392
        (ipcarg_t) mp_res.triplet.dev_handle,
398
        (ipcarg_t) mp.index, 0, NULL);
393
        (ipcarg_t) mp_res.triplet.index, 0, NULL);
399
    /* The second call uses the same method. */
394
    /* The second call uses the same method. */
400
    aid_t req2 = async_send_3(phone, VFS_MOUNT,
395
    aid_t req2 = async_send_3(phone, VFS_MOUNT,
401
        (ipcarg_t) mounted_root.fs_handle,
396
        (ipcarg_t) mr_res.triplet.fs_handle,
402
        (ipcarg_t) mounted_root.dev_handle, (ipcarg_t) mounted_root.index,
397
        (ipcarg_t) mr_res.triplet.dev_handle,
403
        NULL);
398
        (ipcarg_t) mr_res.triplet.index, NULL);
404
    vfs_release_phone(phone);
399
    vfs_release_phone(phone);
405
 
400
 
406
    ipcarg_t rc1;
401
    ipcarg_t rc1;
407
    ipcarg_t rc2;
402
    ipcarg_t rc2;
408
    async_wait_for(req1, &rc1);
403
    async_wait_for(req1, &rc1);
Line 476... Line 471...
476
    rwlock_read_lock(&namespace_rwlock);
471
    rwlock_read_lock(&namespace_rwlock);
477
 
472
 
478
    /*
473
    /*
479
     * The path is now populated and we can call vfs_lookup_internal().
474
     * The path is now populated and we can call vfs_lookup_internal().
480
     */
475
     */
481
    vfs_triplet_t triplet;
476
    vfs_lookup_res_t lr;
482
    size_t size;
-
 
483
    rc = vfs_lookup_internal(path, len, &triplet, &size, NULL);
477
    rc = vfs_lookup_internal(path, len, &lr, NULL);
484
    if (rc) {
478
    if (rc) {
485
        rwlock_read_unlock(&namespace_rwlock);
479
        rwlock_read_unlock(&namespace_rwlock);
486
        ipc_answer_0(rid, rc);
480
        ipc_answer_0(rid, rc);
487
        free(path);
481
        free(path);
488
        return;
482
        return;
Line 491... Line 485...
491
    /*
485
    /*
492
     * Path is no longer needed.
486
     * Path is no longer needed.
493
     */
487
     */
494
    free(path);
488
    free(path);
495
 
489
 
496
    vfs_node_t *node = vfs_node_get(&triplet, size);
490
    vfs_node_t *node = vfs_node_get(&lr);
497
    rwlock_read_unlock(&namespace_rwlock);
491
    rwlock_read_unlock(&namespace_rwlock);
498
 
492
 
499
    /*
493
    /*
500
     * Get ourselves a file descriptor and the corresponding vfs_file_t
494
     * Get ourselves a file descriptor and the corresponding vfs_file_t
501
     * structure.
495
     * structure.