Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 83937ccd in mainline


Ignore:
Timestamp:
2009-05-19T21:49:05Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial
Children:
854c564
Parents:
27fd651
Message:

Rudimentary support for non-root mounts.

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libfs/libfs.c

    r27fd651 r83937ccd  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    123123}
    124124
     125void fs_node_initialize(fs_node_t *fn)
     126{
     127        memset(fn, 0, sizeof(fs_node_t));
     128}
     129
     130void libfs_mount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
     131{
     132        dev_handle_t mp_dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
     133        fs_index_t mp_fs_index = (fs_index_t)IPC_GET_ARG2(*request);
     134        fs_handle_t mr_fs_handle = (fs_handle_t)IPC_GET_ARG3(*request);
     135        dev_handle_t mr_dev_handle = (dev_handle_t)IPC_GET_ARG4(*request);
     136        int res;
     137        ipcarg_t rc;
     138
     139        ipc_call_t call;
     140        ipc_callid_t callid;
     141
     142        /* accept the phone */
     143        callid = async_get_call(&call);
     144        int mountee_phone = (int)IPC_GET_ARG1(call);
     145        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
     146            mountee_phone < 0) {
     147                ipc_answer_0(callid, EINVAL);
     148                ipc_answer_0(rid, EINVAL);
     149                return;
     150        }
     151        ipc_answer_0(callid, EOK);      /* acknowledge the mountee_phone */
     152       
     153        res = ipc_data_write_receive(&callid, NULL);
     154        if (!res) {
     155                ipc_hangup(mountee_phone);
     156                ipc_answer_0(callid, EINVAL);
     157                ipc_answer_0(rid, EINVAL);
     158                return;
     159        }
     160
     161        fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
     162        if (!fn) {
     163                ipc_hangup(mountee_phone);
     164                ipc_answer_0(callid, ENOENT);
     165                ipc_answer_0(rid, ENOENT);
     166                return;
     167        }
     168
     169        if (fn->mp_data.mp_active) {
     170                ipc_hangup(mountee_phone);
     171                ops->node_put(fn);
     172                ipc_answer_0(callid, EBUSY);
     173                ipc_answer_0(rid, EBUSY);
     174                return;
     175        }
     176
     177        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
     178        if (rc != 0) {
     179                ipc_hangup(mountee_phone);
     180                ops->node_put(fn);
     181                ipc_answer_0(callid, rc);
     182                ipc_answer_0(rid, rc);
     183                return;
     184        }
     185       
     186        ipc_call_t answer;
     187        aid_t msg = async_send_1(mountee_phone, VFS_MOUNTED, mr_dev_handle,
     188            &answer);
     189        ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     190        async_wait_for(msg, &rc);
     191       
     192        if (rc == EOK) {
     193                fn->mp_data.mp_active = true;
     194                fn->mp_data.fs_handle = mr_fs_handle;
     195                fn->mp_data.dev_handle = mr_dev_handle;
     196                fn->mp_data.phone = mountee_phone;
     197        }
     198        /*
     199         * Do not release the FS node so that it stays in memory.
     200         */
     201        ipc_answer_0(rid, rc);
     202}
     203
    125204/** Lookup VFS triplet by name in the file system name space.
    126205 *
     
    138217    ipc_call_t *request)
    139218{
    140         unsigned next = IPC_GET_ARG1(*request);
     219        unsigned first = IPC_GET_ARG1(*request);
    141220        unsigned last = IPC_GET_ARG2(*request);
     221        unsigned next = first;
    142222        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    143223        int lflag = IPC_GET_ARG4(*request);
     
    152232        fs_node_t *cur = ops->root_get(dev_handle);
    153233        fs_node_t *tmp = NULL;
     234
     235        if (cur->mp_data.mp_active) {
     236                ipc_forward_slow(rid, cur->mp_data.phone, VFS_LOOKUP,
     237                    next, last, cur->mp_data.dev_handle, lflag, index,
     238                    IPC_FF_ROUTE_FROM_ME);
     239                ops->node_put(cur);
     240                return;
     241        }
    154242
    155243        if (ops->plb_get_char(next) == '/')
     
    175263                /* match the component */
    176264                tmp = ops->match(cur, component);
     265                if (tmp && tmp->mp_data.mp_active) {
     266                        if (next > last)
     267                                next = last = first;
     268                        else
     269                                next--;
     270                               
     271                        ipc_forward_slow(rid, tmp->mp_data.phone, VFS_LOOKUP,
     272                            next, last, tmp->mp_data.dev_handle, lflag, index,
     273                            IPC_FF_ROUTE_FROM_ME);
     274                        ops->node_put(cur);
     275                        ops->node_put(tmp);
     276                        if (par)
     277                                ops->node_put(par);
     278                        return;
     279                }
    177280
    178281                /* handle miss: match amongst siblings */
  • uspace/lib/libfs/libfs.h

    r27fd651 r83937ccd  
    11/*
    2  * Copyright (c) 2007 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    4343
    4444typedef struct {
    45         void *data;     /**< Data of the file system implementation. */
     45        bool mp_active;
     46        int phone;
     47        fs_handle_t fs_handle;
     48        dev_handle_t dev_handle;
     49} mp_data_t;
     50
     51typedef struct {
     52        mp_data_t mp_data;      /**< Mount point info. */
     53        void *data;             /**< Data of the file system implementation. */
    4654} fs_node_t;
    4755
     
    7280extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
    7381
     82extern void fs_node_initialize(fs_node_t *);
     83
     84extern void libfs_mount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    7485extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    7586
  • uspace/srv/fs/fat/fat_ops.c

    r27fd651 r83937ccd  
    150150        }
    151151        fat_node_initialize(nodep);
     152        fs_node_initialize(fn);
    152153        fn->data = nodep;
    153154        nodep->bp = fn;
     
    848849                return;
    849850        }
     851        fs_node_initialize(rfn);
    850852        fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
    851853        if (!rootp) {
     
    887889void fat_mount(ipc_callid_t rid, ipc_call_t *request)
    888890{
    889         ipc_answer_0(rid, ENOTSUP);
     891        libfs_mount(&fat_libfs_ops, rid, request);
    890892}
    891893
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r27fd651 r83937ccd  
    251251                return NULL;
    252252        }
     253        fs_node_initialize(nodep->bp);
    253254        nodep->bp->data = nodep;        /* link the FS and TMPFS nodes */
    254255        if (!tmpfs_root_get(dev_handle))
  • uspace/srv/vfs/vfs_ops.c

    r27fd651 r83937ccd  
    8585{
    8686        vfs_lookup_res_t mp_res;
     87        vfs_lookup_res_t mr_res;
    8788        vfs_node_t *mp_node = NULL;
     89        vfs_node_t *mr_node;
     90        fs_index_t rindex;
     91        size_t rsize;
     92        unsigned rlnkcnt;
    8893        ipcarg_t rc;
    8994        int phone;
    9095        aid_t msg;
    9196        ipc_call_t answer;
     97                       
    9298
    9399        /* Resolve the path to the mountpoint. */
     
    130136                /* We still don't have the root file system mounted. */
    131137                if (str_cmp(mp, "/") == 0) {
    132                         vfs_lookup_res_t mr_res;
    133                         vfs_node_t *mr_node;
    134                         fs_index_t rindex;
    135                         size_t rsize;
    136                         unsigned rlnkcnt;
    137                        
    138138                        /*
    139139                         * For this simple, but important case,
     
    202202         */
    203203       
     204        int mountee_phone = vfs_grab_phone(fs_handle);
     205        assert(mountee_phone >= 0);
     206        vfs_release_phone(mountee_phone);
     207
    204208        phone = vfs_grab_phone(mp_res.triplet.fs_handle);
    205209        msg = async_send_4(phone, VFS_MOUNT,
     
    208212            (ipcarg_t) fs_handle,
    209213            (ipcarg_t) dev_handle, &answer);
     214       
     215        /* send connection */
     216        rc = async_req_1_0(phone, IPC_M_CONNECTION_CLONE, mountee_phone);
     217        if (rc != EOK) {
     218                async_wait_for(msg, NULL);
     219                vfs_release_phone(phone);
     220                /* Mount failed, drop reference to mp_node. */
     221                if (mp_node)
     222                        vfs_node_put(mp_node);
     223                ipc_answer_0(rid, rc);
     224                return;
     225        }
     226       
    210227        /* send the mount options */
    211228        rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
     
    228245        }
    229246       
     247        rindex = (fs_index_t) IPC_GET_ARG1(answer);
     248        rsize = (size_t) IPC_GET_ARG2(answer);
     249        rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
     250       
     251        mr_res.triplet.fs_handle = fs_handle;
     252        mr_res.triplet.dev_handle = dev_handle;
     253        mr_res.triplet.index = rindex;
     254        mr_res.size = rsize;
     255        mr_res.lnkcnt = rlnkcnt;
     256        mr_res.type = VFS_NODE_DIRECTORY;
     257       
     258        /* Add reference to the mounted root. */
     259        mr_node = vfs_node_get(&mr_res);
     260        assert(mr_node);
     261
    230262        ipc_answer_0(rid, rc);
    231263}
Note: See TracChangeset for help on using the changeset viewer.