Changeset 83937ccd in mainline for uspace/lib/libfs/libfs.c


Ignore:
Timestamp:
2009-05-19T21:49:05Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
854c564
Parents:
27fd651
Message:

Rudimentary support for non-root mounts.

File:
1 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 */
Note: See TracChangeset for help on using the changeset viewer.