Changeset 7313e7a in mainline


Ignore:
Timestamp:
2007-09-28T20:11:02Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2c2e0c6
Parents:
0e0476ad
Message:

VFS work.
This is a checkpoint commit.
It introduces initial, still incomplete, code for VFS-side VFS_MOUNT request.

Location:
uspace/srv/vfs
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs.c

    r0e0476ad r7313e7a  
    4545#include <as.h>
    4646#include <libadt/list.h>
     47#include <atomic.h>
    4748#include "vfs.h"
    4849
  • uspace/srv/vfs/vfs.h

    r0e0476ad r7313e7a  
    129129extern link_t fs_head;          /**< List of registered file systems. */
    130130
    131 extern vfs_node_t *rootfs;      /**< Root node of the root file system. */
     131extern vfs_node_t rootfs;       /**< Root node of the root file system. */
    132132
    133133#define MAX_PATH_LEN            (64 * 1024)
     
    149149extern void vfs_release_phone(int);
    150150
    151 extern int fs_name_to_handle(char *name, bool lock);
     151extern int fs_name_to_handle(char *, bool);
    152152
    153 extern int vfs_lookup_internal(char *path, size_t len, vfs_node_t *result,
    154     vfs_node_t *altroot);
     153extern int vfs_lookup_internal(char *, size_t, vfs_node_t *, vfs_node_t *);
    155154
    156155extern void vfs_register(ipc_callid_t, ipc_call_t *);
  • uspace/srv/vfs/vfs_lookup.c

    r0e0476ad r7313e7a  
    7373                root = altroot;
    7474        else
    75                 root = rootfs;
     75                root = &rootfs;
    7676
    77         if (!root)
     77        if (!root->fs_handle)
    7878                return ENOENT;
    7979       
  • uspace/srv/vfs/vfs_mount.c

    r0e0476ad r7313e7a  
    4646#include "vfs.h"
    4747
    48 vfs_node_t *rootfs = NULL;
     48vfs_node_t rootfs = { 0 };
     49
     50static int lookup_root(int fs_handle, int dev_handle, vfs_node_t *root)
     51{
     52        vfs_node_t altroot = {
     53                .fs_handle = fs_handle,
     54                .dev_handle = dev_handle,
     55                /*
     56                 * At this point, we don't know what is the index of the root
     57                 * node. Finally, that's what this function is about.
     58                 */
     59        };
     60
     61        return vfs_lookup_internal("/", 1, root, &altroot);
     62}
    4963
    5064void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
    5165{
     66        int dev_handle;
     67
     68        /*
     69         * We expect the library to do the device-name to device-handle
     70         * translation for us, thus the device handle will arrive as ARG1
     71         * in the request.
     72         */
     73        dev_handle = IPC_GET_ARG1(*request);
     74
     75        /*
     76         * For now, don't make use of ARG2 and ARG3, but they can be used to
     77         * carry mount options in the future.
     78         */
     79
     80        /*
     81         * Now, we expect the client to send us data with the name of the file
     82         * system and the path of the mountpoint.
     83         */
     84        ipc_callid_t callid;
     85        ipc_call_t call;
     86        size_t size;
     87        if (!ipc_data_receive(&callid, &call, NULL, &size)) {
     88                ipc_answer_fast(callid, EINVAL, 0, 0);
     89                ipc_answer_fast(rid, EINVAL, 0, 0);
     90                return;
     91        }
     92
     93        /*
     94         * There is no sense in receiving data that can't hold a single
     95         * character of path. We won't accept data that exceed certain limits
     96         * either.
     97         */
     98        if ((size < FS_NAME_MAXLEN + 1) ||
     99            (size > FS_NAME_MAXLEN + MAX_PATH_LEN)) {
     100                ipc_answer_fast(callid, EINVAL, 0, 0);
     101                ipc_answer_fast(rid, EINVAL, 0, 0);
     102                return;
     103        }
     104
     105        /*
     106         * Allocate buffer for the data being received.
     107         */
     108        uint8_t *buf;
     109        buf = malloc(size);
     110        if (!buf) {
     111                ipc_answer_fast(callid, ENOMEM, 0, 0);
     112                ipc_answer_fast(rid, ENOMEM, 0, 0);
     113                return;
     114        }
     115
     116        /*
     117         * Deliver the data.
     118         */
     119        (void) ipc_data_deliver(callid, &call, buf, size);
     120
     121        char fs_name[FS_NAME_MAXLEN + 1];
     122        memcpy(fs_name, buf, FS_NAME_MAXLEN);
     123        fs_name[FS_NAME_MAXLEN] = '\0';
     124
     125        /*
     126         * Check if we know a file system with the same name as is in fs_name.
     127         * This will also give us its file system handle.
     128         */
     129        int fs_handle = fs_name_to_handle(fs_name, true);
     130        if (!fs_handle) {
     131                free(buf);
     132                ipc_answer_fast(rid, ENOENT, 0, 0);
     133                return;
     134        }
     135
     136        /*
     137         * Lookup the root node of the filesystem being mounted.
     138         */
     139        int rc;
     140        vfs_node_t mounted_root;
     141        rc = lookup_root(fs_handle, dev_handle, &mounted_root);
     142        if (rc != EOK) {
     143                free(buf);
     144                ipc_answer_fast(rid, rc, 0, 0);
     145                return;
     146        }
     147
     148        /*
     149         * Finally, we need to resolve the path to the mountpoint.
     150         */
     151        vfs_node_t mp;
     152        if (rootfs.fs_handle) {
     153                /*
     154                 * We already have the root FS.
     155                 */
     156                rc = vfs_lookup_internal((char *) (buf + FS_NAME_MAXLEN),
     157                    size - FS_NAME_MAXLEN, &mp, NULL);
     158                if (rc != EOK) {
     159                        /*
     160                         * The lookup failed for some reason.
     161                         */
     162                        free(buf);
     163                        ipc_answer_fast(rid, rc, 0, 0);
     164                        return;
     165                }
     166        } else {
     167                /*
     168                 * We still don't have the root file system mounted.
     169                 */
     170                if ((size - FS_NAME_MAXLEN == 1) &&
     171                    (buf[FS_NAME_MAXLEN] == '/')) {
     172                        /*
     173                         * For this simple, but important case, we are done.
     174                         */
     175                        rootfs = mounted_root;
     176                        free(buf);
     177                        ipc_answer_fast(rid, EOK, 0, 0);
     178                        return;
     179                } else {
     180                        /*
     181                         * We can't resolve this without the root filesystem
     182                         * being mounted first.
     183                         */
     184                        free(buf);
     185                        ipc_answer_fast(rid, ENOENT, 0, 0);
     186                        return;
     187                }
     188        }
     189               
     190        /*
     191         * At this point, we have all necessary pieces: file system and device
     192         * handles, and we know the mount point VFS node and also the root node
     193         * of the file system being mounted.
     194         */
     195       
    52196}
    53197
Note: See TracChangeset for help on using the changeset viewer.