Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r9593bc8  
    3636 */
    3737
     38#include <ipc/ipc.h>
    3839#include <ipc/services.h>
    3940#include <async.h>
    4041#include <fibril.h>
    41 #include <fibril_synch.h>
    4242#include <errno.h>
    4343#include <stdio.h>
    4444#include <stdlib.h>
    45 #include <str.h>
     45#include <string.h>
    4646#include <ctype.h>
    4747#include <bool.h>
     48#include <fibril_sync.h>
    4849#include <adt/list.h>
    4950#include <as.h>
     
    109110void vfs_register(ipc_callid_t rid, ipc_call_t *request)
    110111{
    111         int phone;
    112        
     112        ipc_callid_t callid;
     113        ipc_call_t call;
     114        int rc;
     115        size_t size;
     116
    113117        dprintf("Processing VFS_REGISTER request received from %p.\n",
    114118            request->in_phone_hash);
    115        
    116         vfs_info_t *vfs_info;
    117         int rc = async_data_write_accept((void **) &vfs_info, false,
    118             sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL);
    119        
     119
     120        /*
     121         * The first call has to be IPC_M_DATA_SEND in which we receive the
     122         * VFS info structure from the client FS.
     123         */
     124        if (!ipc_data_write_receive(&callid, &size)) {
     125                /*
     126                 * The client doesn't obey the same protocol as we do.
     127                 */
     128                dprintf("Receiving of VFS info failed.\n");
     129                ipc_answer_0(callid, EINVAL);
     130                ipc_answer_0(rid, EINVAL);
     131                return;
     132        }
     133       
     134        dprintf("VFS info received, size = %d\n", size);
     135       
     136        /*
     137         * We know the size of the VFS info structure. See if the client
     138         * understands this easy concept too.
     139         */
     140        if (size != sizeof(vfs_info_t)) {
     141                /*
     142                 * The client is sending us something, which cannot be
     143                 * the info structure.
     144                 */
     145                dprintf("Received VFS info has bad size.\n");
     146                ipc_answer_0(callid, EINVAL);
     147                ipc_answer_0(rid, EINVAL);
     148                return;
     149        }
     150
     151        /*
     152         * Allocate and initialize a buffer for the fs_info structure.
     153         */
     154        fs_info_t *fs_info;
     155        fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
     156        if (!fs_info) {
     157                dprintf("Could not allocate memory for FS info.\n");
     158                ipc_answer_0(callid, ENOMEM);
     159                ipc_answer_0(rid, ENOMEM);
     160                return;
     161        }
     162        link_initialize(&fs_info->fs_link);
     163        fibril_mutex_initialize(&fs_info->phone_lock);
     164               
     165        rc = ipc_data_write_finalize(callid, &fs_info->vfs_info, size);
    120166        if (rc != EOK) {
    121167                dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",
    122168                    rc);
    123                 async_answer_0(rid, rc);
    124                 return;
    125         }
    126        
    127         /*
    128          * Allocate and initialize a buffer for the fs_info structure.
    129          */
    130         fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
    131         if (!fs_info) {
    132                 dprintf("Could not allocate memory for FS info.\n");
    133                 async_answer_0(rid, ENOMEM);
    134                 return;
    135         }
    136        
    137         link_initialize(&fs_info->fs_link);
    138         fs_info->vfs_info = *vfs_info;
    139         free(vfs_info);
    140        
     169                free(fs_info);
     170                ipc_answer_0(callid, rc);
     171                ipc_answer_0(rid, rc);
     172                return;
     173        }
     174
    141175        dprintf("VFS info delivered.\n");
    142        
     176               
    143177        if (!vfs_info_sane(&fs_info->vfs_info)) {
    144178                free(fs_info);
    145                 async_answer_0(rid, EINVAL);
    146                 return;
    147         }
    148        
     179                ipc_answer_0(callid, EINVAL);
     180                ipc_answer_0(rid, EINVAL);
     181                return;
     182        }
     183               
    149184        fibril_mutex_lock(&fs_head_lock);
    150        
     185
    151186        /*
    152187         * Check for duplicit registrations.
     
    159194                fibril_mutex_unlock(&fs_head_lock);
    160195                free(fs_info);
    161                 async_answer_0(rid, EEXISTS);
    162                 return;
    163         }
    164        
     196                ipc_answer_0(callid, EEXISTS);
     197                ipc_answer_0(rid, EEXISTS);
     198                return;
     199        }
     200
    165201        /*
    166202         * Add fs_info to the list of registered FS's.
     
    174210         * which to forward VFS requests to it.
    175211         */
    176         ipc_call_t call;
    177         ipc_callid_t callid = async_get_call(&call);
    178         if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
    179                 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
     212        callid = async_get_call(&call);
     213        if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
     214                dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
    180215                list_remove(&fs_info->fs_link);
    181216                fibril_mutex_unlock(&fs_head_lock);
    182217                free(fs_info);
    183                 async_answer_0(callid, EINVAL);
    184                 async_answer_0(rid, EINVAL);
    185                 return;
    186         }
    187        
    188         phone = IPC_GET_ARG5(call);
    189         async_session_create(&fs_info->session, phone, 0);
    190         async_answer_0(callid, EOK);
    191        
     218                ipc_answer_0(callid, EINVAL);
     219                ipc_answer_0(rid, EINVAL);
     220                return;
     221        }
     222        fs_info->phone = IPC_GET_ARG5(call);
     223        ipc_answer_0(callid, EOK);
     224
    192225        dprintf("Callback connection to FS created.\n");
    193        
     226
    194227        /*
    195228         * The client will want us to send him the address space area with PLB.
    196229         */
    197        
    198         size_t size;
    199         if (!async_share_in_receive(&callid, &size)) {
    200                 dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
     230
     231        if (!ipc_share_in_receive(&callid, &size)) {
     232                dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
    201233                list_remove(&fs_info->fs_link);
    202234                fibril_mutex_unlock(&fs_head_lock);
    203                 async_session_destroy(&fs_info->session);
    204                 async_hangup(phone);
    205                 free(fs_info);
    206                 async_answer_0(callid, EINVAL);
    207                 async_answer_0(rid, EINVAL);
     235                ipc_hangup(fs_info->phone);
     236                free(fs_info);
     237                ipc_answer_0(callid, EINVAL);
     238                ipc_answer_0(rid, EINVAL);
    208239                return;
    209240        }
     
    216247                list_remove(&fs_info->fs_link);
    217248                fibril_mutex_unlock(&fs_head_lock);
    218                 async_session_destroy(&fs_info->session);
    219                 async_hangup(phone);
    220                 free(fs_info);
    221                 async_answer_0(callid, EINVAL);
    222                 async_answer_0(rid, EINVAL);
    223                 return;
    224         }
    225        
     249                ipc_hangup(fs_info->phone);
     250                free(fs_info);
     251                ipc_answer_0(callid, EINVAL);
     252                ipc_answer_0(rid, EINVAL);
     253                return;
     254        }
     255
    226256        /*
    227257         * Commit to read-only sharing the PLB with the client.
    228258         */
    229         (void) async_share_in_finalize(callid, plb,
     259        (void) ipc_share_in_finalize(callid, plb,
    230260            AS_AREA_READ | AS_AREA_CACHEABLE);
    231        
     261
    232262        dprintf("Sharing PLB.\n");
    233        
     263
    234264        /*
    235265         * That was it. The FS has been registered.
     
    238268         */
    239269        fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next);
    240         async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle);
     270        ipc_answer_1(rid, EOK, (ipcarg_t) fs_info->fs_handle);
    241271       
    242272        fibril_condvar_broadcast(&fs_head_cv);
     
    256286int vfs_grab_phone(fs_handle_t handle)
    257287{
    258         link_t *cur;
    259         fs_info_t *fs;
    260288        int phone;
    261289
     
    268296         */
    269297        fibril_mutex_lock(&fs_head_lock);
     298        link_t *cur;
     299        fs_info_t *fs;
    270300        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    271301                fs = list_get_instance(cur, fs_info_t, fs_link);
    272302                if (fs->fs_handle == handle) {
    273303                        fibril_mutex_unlock(&fs_head_lock);
    274                         phone = async_exchange_begin(&fs->session);
     304                        fibril_mutex_lock(&fs->phone_lock);
     305                        phone = ipc_connect_me_to(fs->phone, 0, 0, 0);
     306                        fibril_mutex_unlock(&fs->phone_lock);
    275307
    276308                        assert(phone > 0);
     
    286318 * @param phone         Phone to FS task.
    287319 */
    288 void vfs_release_phone(fs_handle_t handle, int phone)
    289 {
    290         link_t *cur;
    291         fs_info_t *fs;
    292 
    293         fibril_mutex_lock(&fs_head_lock);
    294         for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    295                 fs = list_get_instance(cur, fs_info_t, fs_link);
    296                 if (fs->fs_handle == handle) {
    297                         fibril_mutex_unlock(&fs_head_lock);
    298                         async_exchange_end(&fs->session, phone);
    299                         return;
    300                 }
    301         }
    302         /* should not really get here */
    303         abort();
    304         fibril_mutex_unlock(&fs_head_lock);
     320void vfs_release_phone(int phone)
     321{
     322        /* TODO: implement connection caching */
     323        ipc_hangup(phone);
    305324}
    306325
     
    332351}
    333352
    334 /** Find the VFS info structure.
    335  *
    336  * @param handle        FS handle for which the VFS info structure is sought.
    337  * @return              VFS info structure on success or NULL otherwise.
    338  */
    339 vfs_info_t *fs_handle_to_info(fs_handle_t handle)
    340 {
    341         vfs_info_t *info = NULL;
    342         link_t *cur;
    343 
    344         fibril_mutex_lock(&fs_head_lock);
    345         for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    346                 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    347                 if (fs->fs_handle == handle) {
    348                         info = &fs->vfs_info;
    349                         break;
    350                 }
    351         }
    352         fibril_mutex_unlock(&fs_head_lock);
    353 
    354         return info;
    355 }
    356 
    357353/**
    358354 * @}
Note: See TracChangeset for help on using the changeset viewer.