Ignore:
File:
1 edited

Legend:

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

    r286286c rffa2c8ef  
    5252#include "vfs.h"
    5353
    54 FIBRIL_CONDVAR_INITIALIZE(fs_list_cv);
    55 FIBRIL_MUTEX_INITIALIZE(fs_list_lock);
    56 LIST_INITIALIZE(fs_list);
     54FIBRIL_CONDVAR_INITIALIZE(fs_head_cv);
     55FIBRIL_MUTEX_INITIALIZE(fs_head_lock);
     56LIST_INITIALIZE(fs_head);
    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.
    67  *
     64 * @param info          Info structure to be verified.
     65 *
     66 * @return              Non-zero if the info structure is sane, zero otherwise.
    6867 */
    6968static bool vfs_info_sane(vfs_info_t *info)
    7069{
    7170        int i;
    72        
     71
    7372        /*
    7473         * Check if the name is non-empty and is composed solely of ASCII
     
    7978                return false;
    8079        }
    81        
    8280        for (i = 1; i < FS_NAME_MAXLEN; i++) {
    8381                if (!(islower(info->name[i]) || isdigit(info->name[i])) &&
     
    9290                }
    9391        }
    94        
    9592        /*
    9693         * This check is not redundant. It ensures that the name is
     
    107104/** VFS_REGISTER protocol function.
    108105 *
    109  * @param rid     Hash of the call with the request.
    110  * @param request Call structure with the request.
    111  *
     106 * @param rid           Hash of the call with the request.
     107 * @param request       Call structure with the request.
    112108 */
    113109void vfs_register(ipc_callid_t rid, ipc_call_t *request)
    114110{
     111        int phone;
     112       
    115113        dprintf("Processing VFS_REGISTER request received from %p.\n",
    116114            request->in_phone_hash);
     
    149147        }
    150148       
    151         fibril_mutex_lock(&fs_list_lock);
     149        fibril_mutex_lock(&fs_head_lock);
    152150       
    153151        /*
    154152         * Check for duplicit registrations.
    155153         */
    156         if (fs_name_to_handle(fs_info->vfs_info.instance,
    157             fs_info->vfs_info.name, false)) {
     154        if (fs_name_to_handle(fs_info->vfs_info.name, false)) {
    158155                /*
    159156                 * We already register a fs like this.
    160157                 */
    161158                dprintf("FS is already registered.\n");
    162                 fibril_mutex_unlock(&fs_list_lock);
     159                fibril_mutex_unlock(&fs_head_lock);
    163160                free(fs_info);
    164161                async_answer_0(rid, EEXISTS);
     
    170167         */
    171168        dprintf("Inserting FS into the list of registered file systems.\n");
    172         list_append(&fs_info->fs_link, &fs_list);
     169        list_append(&fs_info->fs_link, &fs_head);
    173170       
    174171        /*
     
    177174         * which to forward VFS requests to it.
    178175         */
    179         fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
    180         if (!fs_info->sess) {
    181                 dprintf("Callback connection expected\n");
     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));
    182180                list_remove(&fs_info->fs_link);
    183                 fibril_mutex_unlock(&fs_list_lock);
    184                 free(fs_info);
     181                fibril_mutex_unlock(&fs_head_lock);
     182                free(fs_info);
     183                async_answer_0(callid, EINVAL);
    185184                async_answer_0(rid, EINVAL);
    186185                return;
    187186        }
    188187       
     188        phone = IPC_GET_ARG5(call);
     189        async_session_create(&fs_info->session, phone, 0);
     190        async_answer_0(callid, EOK);
     191       
    189192        dprintf("Callback connection to FS created.\n");
    190193       
     
    194197       
    195198        size_t size;
    196         ipc_callid_t callid;
    197199        if (!async_share_in_receive(&callid, &size)) {
    198200                dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
    199201                list_remove(&fs_info->fs_link);
    200                 fibril_mutex_unlock(&fs_list_lock);
    201                 async_hangup(fs_info->sess);
     202                fibril_mutex_unlock(&fs_head_lock);
     203                async_session_destroy(&fs_info->session);
     204                async_hangup(phone);
    202205                free(fs_info);
    203206                async_answer_0(callid, EINVAL);
     
    212215                dprintf("Client suggests wrong size of PFB, size = %d\n", size);
    213216                list_remove(&fs_info->fs_link);
    214                 fibril_mutex_unlock(&fs_list_lock);
    215                 async_hangup(fs_info->sess);
     217                fibril_mutex_unlock(&fs_head_lock);
     218                async_session_destroy(&fs_info->session);
     219                async_hangup(phone);
    216220                free(fs_info);
    217221                async_answer_0(callid, EINVAL);
     
    236240        async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle);
    237241       
    238         fibril_condvar_broadcast(&fs_list_cv);
    239         fibril_mutex_unlock(&fs_list_lock);
     242        fibril_condvar_broadcast(&fs_head_cv);
     243        fibril_mutex_unlock(&fs_head_lock);
    240244       
    241245        dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n",
     
    243247}
    244248
    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  */
    253 async_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) {
     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 */
     256int 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);
     272                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;
     278                }
     279        }
     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 */
     288void 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);
     305}
     306
     307/** Convert file system name to its handle.
     308 *
     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 */
     315fs_handle_t fs_name_to_handle(char *name, bool lock)
     316{
     317        int handle = 0;
     318       
     319        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) {
    263323                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    264                
    265                 if (fs->fs_handle == handle) {
    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;
    273                 }
    274         }
    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  */
    286 void vfs_exchange_release(async_exch_t *exch)
    287 {
    288         async_exchange_end(exch);
    289 }
    290 
    291 /** Convert file system name to its handle.
    292  *
    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  */
    300 fs_handle_t fs_name_to_handle(unsigned int instance, char *name, bool lock)
    301 {
    302         int handle = 0;
    303        
    304         if (lock)
    305                 fibril_mutex_lock(&fs_list_lock);
    306        
    307         list_foreach(fs_list, cur) {
    308                 fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    309                 if (str_cmp(fs->vfs_info.name, name) == 0 &&
    310                     instance == fs->vfs_info.instance) {
     324                if (str_cmp(fs->vfs_info.name, name) == 0) {
    311325                        handle = fs->fs_handle;
    312326                        break;
    313327                }
    314328        }
    315        
    316329        if (lock)
    317                 fibril_mutex_unlock(&fs_list_lock);
    318        
     330                fibril_mutex_unlock(&fs_head_lock);
    319331        return handle;
    320332}
     
    322334/** Find the VFS info structure.
    323335 *
    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  *
     336 * @param handle        FS handle for which the VFS info structure is sought.
     337 * @return              VFS info structure on success or NULL otherwise.
    328338 */
    329339vfs_info_t *fs_handle_to_info(fs_handle_t handle)
    330340{
    331341        vfs_info_t *info = NULL;
    332        
    333         fibril_mutex_lock(&fs_list_lock);
    334         list_foreach(fs_list, cur) {
     342        link_t *cur;
     343
     344        fibril_mutex_lock(&fs_head_lock);
     345        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
    335346                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
    336347                if (fs->fs_handle == handle) {
     
    339350                }
    340351        }
    341         fibril_mutex_unlock(&fs_list_lock);
    342        
     352        fibril_mutex_unlock(&fs_head_lock);
     353
    343354        return info;
    344355}
     
    346357/**
    347358 * @}
    348  */
     359 */ 
Note: See TracChangeset for help on using the changeset viewer.