Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r286286c  
    5252#include "vfs.h"
    5353
    54 FIBRIL_CONDVAR_INITIALIZE(fs_head_cv);
    55 FIBRIL_MUTEX_INITIALIZE(fs_head_lock);
    56 LIST_INITIALIZE(fs_head);
     54FIBRIL_CONDVAR_INITIALIZE(fs_list_cv);
     55FIBRIL_MUTEX_INITIALIZE(fs_list_lock);
     56LIST_INITIALIZE(fs_list);
    5757
    5858atomic_t fs_handle_next = {
     
    6262/** Verify the VFS info structure.
    6363 *
    64  * @param info          Info structure to be verified.
    65  *
    66  * @return              Non-zero if the info structure is sane, zero otherwise.
     64 * @param info Info structure to be verified.
     65 *
     66 * @return Non-zero if the info structure is sane, zero otherwise.
     67 *
    6768 */
    6869static bool vfs_info_sane(vfs_info_t *info)
    6970{
    7071        int i;
    71 
     72       
    7273        /*
    7374         * Check if the name is non-empty and is composed solely of ASCII
     
    7879                return false;
    7980        }
     81       
    8082        for (i = 1; i < FS_NAME_MAXLEN; i++) {
    8183                if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
     
    9092                }
    9193        }
     94       
    9295        /*
    9396         * This check is not redundant. It ensures that the name is
     
    104107/** VFS_REGISTER protocol function.
    105108 *
    106  * @param rid           Hash of the call with the request.
    107  * @param request       Call structure with the request.
     109 * @param rid     Hash of the call with the request.
     110 * @param request Call structure with the request.
     111 *
    108112 */
    109113void vfs_register(ipc_callid_t rid, ipc_call_t *request)
    110114{
    111         int phone;
    112        
    113115        dprintf("Processing VFS_REGISTER request received from %p.\n",
    114116            request->in_phone_hash);
     
    147149        }
    148150       
    149         fibril_mutex_lock(&fs_head_lock);
     151        fibril_mutex_lock(&fs_list_lock);
    150152       
    151153        /*
    152154         * Check for duplicit registrations.
    153155         */
    154         if (fs_name_to_handle(fs_info->vfs_info.name, false)) {
     156        if (fs_name_to_handle(fs_info->vfs_info.instance,
     157            fs_info->vfs_info.name, false)) {
    155158                /*
    156159                 * We already register a fs like this.
    157160                 */
    158161                dprintf("FS is already registered.\n");
    159                 fibril_mutex_unlock(&fs_head_lock);
     162                fibril_mutex_unlock(&fs_list_lock);
    160163                free(fs_info);
    161164                async_answer_0(rid, EEXISTS);
     
    167170         */
    168171        dprintf("Inserting FS into the list of registered file systems.\n");
    169         list_append(&fs_info->fs_link, &fs_head);
     172        list_append(&fs_info->fs_link, &fs_list);
    170173       
    171174        /*
     
    174177         * which to forward VFS requests to it.
    175178         */
    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));
     179        fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
     180        if (!fs_info->sess) {
     181                dprintf("Callback connection expected\n");
    180182                list_remove(&fs_info->fs_link);
    181                 fibril_mutex_unlock(&fs_head_lock);
    182                 free(fs_info);
    183                 async_answer_0(callid, EINVAL);
     183                fibril_mutex_unlock(&fs_list_lock);
     184                free(fs_info);
    184185                async_answer_0(rid, EINVAL);
    185186                return;
    186187        }
    187188       
    188         phone = IPC_GET_ARG5(call);
    189         async_session_create(&fs_info->session, phone, 0);
    190         async_answer_0(callid, EOK);
    191        
    192189        dprintf("Callback connection to FS created.\n");
    193190       
     
    197194       
    198195        size_t size;
     196        ipc_callid_t callid;
    199197        if (!async_share_in_receive(&callid, &size)) {
    200198                dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
    201199                list_remove(&fs_info->fs_link);
    202                 fibril_mutex_unlock(&fs_head_lock);
    203                 async_session_destroy(&fs_info->session);
    204                 async_hangup(phone);
     200                fibril_mutex_unlock(&fs_list_lock);
     201                async_hangup(fs_info->sess);
    205202                free(fs_info);
    206203                async_answer_0(callid, EINVAL);
     
    215212                dprintf("Client suggests wrong size of PFB, size = %d\n", size);
    216213                list_remove(&fs_info->fs_link);
    217                 fibril_mutex_unlock(&fs_head_lock);
    218                 async_session_destroy(&fs_info->session);
    219                 async_hangup(phone);
     214                fibril_mutex_unlock(&fs_list_lock);
     215                async_hangup(fs_info->sess);
    220216                free(fs_info);
    221217                async_answer_0(callid, EINVAL);
     
    240236        async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle);
    241237       
    242         fibril_condvar_broadcast(&fs_head_cv);
    243         fibril_mutex_unlock(&fs_head_lock);
     238        fibril_condvar_broadcast(&fs_list_cv);
     239        fibril_mutex_unlock(&fs_list_lock);
    244240       
    245241        dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n",
     
    247243}
    248244
    249 /** For a given file system handle, implement policy for allocating a phone.
    250  *
    251  * @param handle        File system handle.
    252  *
    253  * @return              Phone over which a multi-call request can be safely
    254  *                      sent. Return 0 if no phone was found.
    255  */
    256 int vfs_grab_phone(fs_handle_t handle)
    257 {
    258         link_t *cur;
    259         fs_info_t *fs;
    260         int phone;
    261 
    262         /*
    263          * For now, we don't try to be very clever and very fast.  We simply
    264          * lookup the phone in the fs_head list and duplicate it.  The duplicate
    265          * phone will be returned to the client and the client will use it for
    266          * communication.  In the future, we should cache the connections so
    267          * that they do not have to be reestablished over and over again.
    268          */
    269         fibril_mutex_lock(&fs_head_lock);
    270         for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    271                 fs = list_get_instance(cur, fs_info_t, fs_link);
     245/** Begin an exchange for a given file system handle
     246 *
     247 * @param handle File system handle.
     248 *
     249 * @return Exchange for a multi-call request.
     250 * @return NULL if no such file exists.
     251 *
     252 */
     253async_exch_t *vfs_exchange_grab(fs_handle_t handle)
     254{
     255        /*
     256         * For now, we don't try to be very clever and very fast.
     257         * We simply lookup the session in fs_list and
     258         * begin an exchange.
     259         */
     260        fibril_mutex_lock(&fs_list_lock);
     261       
     262        list_foreach(fs_list, cur) {
     263                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
     264               
    272265                if (fs->fs_handle == handle) {
    273                         fibril_mutex_unlock(&fs_head_lock);
    274                         phone = async_exchange_begin(&fs->session);
    275 
    276                         assert(phone > 0);
    277                         return phone;
     266                        fibril_mutex_unlock(&fs_list_lock);
     267                       
     268                        assert(fs->sess);
     269                        async_exch_t *exch = async_exchange_begin(fs->sess);
     270                       
     271                        assert(exch);
     272                        return exch;
    278273                }
    279274        }
    280         fibril_mutex_unlock(&fs_head_lock);
    281         return 0;
    282 }
    283 
    284 /** Tell VFS that the phone is not needed anymore.
    285  *
    286  * @param phone         Phone to FS task.
    287  */
    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);
     275       
     276        fibril_mutex_unlock(&fs_list_lock);
     277       
     278        return NULL;
     279}
     280
     281/** End VFS server exchange.
     282 *
     283 * @param exch   VFS server exchange.
     284 *
     285 */
     286void vfs_exchange_release(async_exch_t *exch)
     287{
     288        async_exchange_end(exch);
    305289}
    306290
    307291/** Convert file system name to its handle.
    308292 *
    309  * @param name          File system name.
    310  * @param lock          If true, the function will lock and unlock the
    311  *                      fs_head_lock.
    312  *
    313  * @return              File system handle or zero if file system not found.
    314  */
    315 fs_handle_t fs_name_to_handle(char *name, bool lock)
     293 * @param name File system name.
     294 * @param lock If true, the function will lock and unlock the
     295 *             fs_list_lock.
     296 *
     297 * @return File system handle or zero if file system not found.
     298 *
     299 */
     300fs_handle_t fs_name_to_handle(unsigned int instance, char *name, bool lock)
    316301{
    317302        int handle = 0;
    318303       
    319304        if (lock)
    320                 fibril_mutex_lock(&fs_head_lock);
    321         link_t *cur;
    322         for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     305                fibril_mutex_lock(&fs_list_lock);
     306       
     307        list_foreach(fs_list, cur) {
    323308                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    324                 if (str_cmp(fs->vfs_info.name, name) == 0) {
     309                if (str_cmp(fs->vfs_info.name, name) == 0 &&
     310                    instance == fs->vfs_info.instance) {
    325311                        handle = fs->fs_handle;
    326312                        break;
    327313                }
    328314        }
     315       
    329316        if (lock)
    330                 fibril_mutex_unlock(&fs_head_lock);
     317                fibril_mutex_unlock(&fs_list_lock);
     318       
    331319        return handle;
    332320}
     
    334322/** Find the VFS info structure.
    335323 *
    336  * @param handle        FS handle for which the VFS info structure is sought.
    337  * @return              VFS info structure on success or NULL otherwise.
     324 * @param handle FS handle for which the VFS info structure is sought.
     325 *
     326 * @return VFS info structure on success or NULL otherwise.
     327 *
    338328 */
    339329vfs_info_t *fs_handle_to_info(fs_handle_t handle)
    340330{
    341331        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) {
     332       
     333        fibril_mutex_lock(&fs_list_lock);
     334        list_foreach(fs_list, cur) {
    346335                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    347336                if (fs->fs_handle == handle) {
     
    350339                }
    351340        }
    352         fibril_mutex_unlock(&fs_head_lock);
    353 
     341        fibril_mutex_unlock(&fs_list_lock);
     342       
    354343        return info;
    355344}
     
    357346/**
    358347 * @}
    359  */ 
     348 */
Note: See TracChangeset for help on using the changeset viewer.