Changeset 8b5690f in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2011-02-03T05:11:01Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ba38f72c
Parents:
22027b6e (diff), 86d7bfa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/vfs/vfs.c

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar 
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    4343#include <sys/stat.h>
    4444#include <sys/types.h>
    45 #include <ipc/ipc.h>
    4645#include <ipc/services.h>
     46#include <ipc/ns.h>
    4747#include <async.h>
    48 #include <atomic.h>
    49 #include <futex.h>
     48#include <fibril_synch.h>
    5049#include <errno.h>
     50#include <assert.h>
    5151#include <str.h>
    5252#include <devmap.h>
     
    5454#include <ipc/devmap.h>
    5555
     56static async_sess_t vfs_session;
     57
     58static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    5659static int vfs_phone = -1;
    57 static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
    58 static futex_t cwd_futex = FUTEX_INITIALIZER;
     60
     61static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
    5962
    6063static int cwd_fd = -1;
     
    6770        char *ncwd_path_nc;
    6871
    69         futex_down(&cwd_futex);
     72        fibril_mutex_lock(&cwd_mutex);
    7073        size_t size = str_size(path);
    7174        if (*path != '/') {
    7275                if (!cwd_path) {
    73                         futex_up(&cwd_futex);
     76                        fibril_mutex_unlock(&cwd_mutex);
    7477                        return NULL;
    7578                }
    7679                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    7780                if (!ncwd_path_nc) {
    78                         futex_up(&cwd_futex);
     81                        fibril_mutex_unlock(&cwd_mutex);
    7982                        return NULL;
    8083                }
     
    8588                ncwd_path_nc = malloc(size + 1);
    8689                if (!ncwd_path_nc) {
    87                         futex_up(&cwd_futex);
     90                        fibril_mutex_unlock(&cwd_mutex);
    8891                        return NULL;
    8992                }
     
    9396        ncwd_path = canonify(ncwd_path_nc, retlen);
    9497        if (!ncwd_path) {
    95                 futex_up(&cwd_futex);
     98                fibril_mutex_unlock(&cwd_mutex);
    9699                free(ncwd_path_nc);
    97100                return NULL;
     
    105108        free(ncwd_path_nc);
    106109        if (!ncwd_path) {
    107                 futex_up(&cwd_futex);
     110                fibril_mutex_unlock(&cwd_mutex);
    108111                return NULL;
    109112        }
    110         futex_up(&cwd_futex);
     113        fibril_mutex_unlock(&cwd_mutex);
    111114        return ncwd_path;
    112115}
    113116
     117/** Connect to VFS service and create session. */
    114118static void vfs_connect(void)
    115119{
    116120        while (vfs_phone < 0)
    117                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
     121                vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
     122       
     123        async_session_create(&vfs_session, vfs_phone, 0);
     124}
     125
     126/** Start an async exchange on the VFS session.
     127 *
     128 * @return              New phone to be used during the exchange.
     129 */
     130static int vfs_exchange_begin(void)
     131{
     132        fibril_mutex_lock(&vfs_phone_mutex);
     133        if (vfs_phone < 0)
     134                vfs_connect();
     135        fibril_mutex_unlock(&vfs_phone_mutex);
     136
     137        return async_exchange_begin(&vfs_session);
     138}
     139
     140/** End an async exchange on the VFS session.
     141 *
     142 * @param phone         Phone used during the exchange.
     143 */
     144static void vfs_exchange_end(int phone)
     145{
     146        async_exchange_end(&vfs_session, phone);
    118147}
    119148
     
    154183        }
    155184       
    156         futex_down(&vfs_phone_futex);
    157         async_serialize_start();
    158         vfs_connect();
    159        
     185        int vfs_phone = vfs_exchange_begin();
     186
    160187        sysarg_t rc_orig;
    161188        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    162189        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    163190        if (rc != EOK) {
    164                 async_wait_for(req, &rc_orig);
    165                 async_serialize_end();
    166                 futex_up(&vfs_phone_futex);
     191                vfs_exchange_end(vfs_phone);
    167192                free(mpa);
     193                async_wait_for(req, &rc_orig);
    168194               
    169195                if (null_id != -1)
     
    178204        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    179205        if (rc != EOK) {
    180                 async_wait_for(req, &rc_orig);
    181                 async_serialize_end();
    182                 futex_up(&vfs_phone_futex);
     206                vfs_exchange_end(vfs_phone);
    183207                free(mpa);
     208                async_wait_for(req, &rc_orig);
    184209               
    185210                if (null_id != -1)
     
    194219        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    195220        if (rc != EOK) {
    196                 async_wait_for(req, &rc_orig);
    197                 async_serialize_end();
    198                 futex_up(&vfs_phone_futex);
     221                vfs_exchange_end(vfs_phone);
    199222                free(mpa);
     223                async_wait_for(req, &rc_orig);
    200224               
    201225                if (null_id != -1)
     
    211235        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    212236        if (rc != EOK) {
    213                 async_wait_for(req, &rc_orig);
    214                 async_serialize_end();
    215                 futex_up(&vfs_phone_futex);
     237                vfs_exchange_end(vfs_phone);
    216238                free(mpa);
     239                async_wait_for(req, &rc_orig);
    217240               
    218241                if (null_id != -1)
     
    225248        }
    226249       
    227         async_wait_for(req, &rc);
    228         async_serialize_end();
    229         futex_up(&vfs_phone_futex);
     250        vfs_exchange_end(vfs_phone);
    230251        free(mpa);
     252        async_wait_for(req, &rc);
    231253       
    232254        if ((rc != EOK) && (null_id != -1))
     
    248270                return ENOMEM;
    249271       
    250         futex_down(&vfs_phone_futex);
    251         async_serialize_start();
    252         vfs_connect();
     272        int vfs_phone = vfs_exchange_begin();
    253273       
    254274        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    255275        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    256276        if (rc != EOK) {
    257                 async_wait_for(req, &rc_orig);
    258                 async_serialize_end();
    259                 futex_up(&vfs_phone_futex);
     277                vfs_exchange_end(vfs_phone);
    260278                free(mpa);
    261                 if (rc_orig == EOK)
    262                         return (int) rc;
    263                 else
    264                         return (int) rc_orig;
    265         }
    266        
    267 
    268         async_wait_for(req, &rc);
    269         async_serialize_end();
    270         futex_up(&vfs_phone_futex);
     279                async_wait_for(req, &rc_orig);
     280                if (rc_orig == EOK)
     281                        return (int) rc;
     282                else
     283                        return (int) rc_orig;
     284        }
     285       
     286
     287        vfs_exchange_end(vfs_phone);
    271288        free(mpa);
     289        async_wait_for(req, &rc);
    272290       
    273291        return (int) rc;
     
    276294static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    277295{
    278         futex_down(&vfs_phone_futex);
    279         async_serialize_start();
    280         vfs_connect();
     296        int vfs_phone = vfs_exchange_begin();
    281297       
    282298        ipc_call_t answer;
     
    285301       
    286302        if (rc != EOK) {
     303                vfs_exchange_end(vfs_phone);
     304
    287305                sysarg_t rc_orig;
    288306                async_wait_for(req, &rc_orig);
    289307               
    290                 async_serialize_end();
    291                 futex_up(&vfs_phone_futex);
    292                
    293                 if (rc_orig == EOK)
    294                         return (int) rc;
    295                 else
    296                         return (int) rc_orig;
    297         }
    298        
    299         async_wait_for(req, &rc);
    300         async_serialize_end();
    301         futex_up(&vfs_phone_futex);
     308                if (rc_orig == EOK)
     309                        return (int) rc;
     310                else
     311                        return (int) rc_orig;
     312        }
     313       
     314        vfs_exchange_end(vfs_phone);
     315        async_wait_for(req, &rc);
    302316       
    303317        if (rc != EOK)
     
    322336int open_node(fdi_node_t *node, int oflag)
    323337{
    324         futex_down(&vfs_phone_futex);
    325         async_serialize_start();
    326         vfs_connect();
     338        int vfs_phone = vfs_exchange_begin();
    327339       
    328340        ipc_call_t answer;
     
    330342            node->devmap_handle, node->index, oflag, &answer);
    331343       
    332         sysarg_t rc;
    333         async_wait_for(req, &rc);
    334         async_serialize_end();
    335         futex_up(&vfs_phone_futex);
     344        vfs_exchange_end(vfs_phone);
     345
     346        sysarg_t rc;
     347        async_wait_for(req, &rc);
    336348       
    337349        if (rc != EOK)
     
    345357        sysarg_t rc;
    346358       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
     359        int vfs_phone = vfs_exchange_begin();
    350360       
    351361        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    352362       
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
     363        vfs_exchange_end(vfs_phone);
    355364       
    356365        return (int)rc;
     
    363372        aid_t req;
    364373
    365         futex_down(&vfs_phone_futex);
    366         async_serialize_start();
    367         vfs_connect();
     374        int vfs_phone = vfs_exchange_begin();
    368375       
    369376        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    370377        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371378        if (rc != EOK) {
     379                vfs_exchange_end(vfs_phone);
     380
    372381                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     382                async_wait_for(req, &rc_orig);
     383
    377384                if (rc_orig == EOK)
    378385                        return (ssize_t) rc;
     
    380387                        return (ssize_t) rc_orig;
    381388        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     389        vfs_exchange_end(vfs_phone);
     390        async_wait_for(req, &rc);
    385391        if (rc == EOK)
    386392                return (ssize_t) IPC_GET_ARG1(answer);
     
    395401        aid_t req;
    396402
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     403        int vfs_phone = vfs_exchange_begin();
    400404       
    401405        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402406        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403407        if (rc != EOK) {
     408                vfs_exchange_end(vfs_phone);
     409
    404410                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     411                async_wait_for(req, &rc_orig);
     412
    409413                if (rc_orig == EOK)
    410414                        return (ssize_t) rc;
     
    412416                        return (ssize_t) rc_orig;
    413417        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     418        vfs_exchange_end(vfs_phone);
     419        async_wait_for(req, &rc);
    417420        if (rc == EOK)
    418421                return (ssize_t) IPC_GET_ARG1(answer);
     
    423426int fsync(int fildes)
    424427{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     428        int vfs_phone = vfs_exchange_begin();
    428429       
    429430        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430431       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     432        vfs_exchange_end(vfs_phone);
    433433       
    434434        return (int) rc;
     
    437437off64_t lseek(int fildes, off64_t offset, int whence)
    438438{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     439        int vfs_phone = vfs_exchange_begin();
    442440       
    443441        sysarg_t newoff_lo;
     
    447445            &newoff_lo, &newoff_hi);
    448446       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     447        vfs_exchange_end(vfs_phone);
    451448       
    452449        if (rc != EOK)
     
    460457        sysarg_t rc;
    461458       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     459        int vfs_phone = vfs_exchange_begin();
    465460       
    466461        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467462            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     463        vfs_exchange_end(vfs_phone);
    470464       
    471465        return (int) rc;
     
    477471        aid_t req;
    478472
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     473        int vfs_phone = vfs_exchange_begin();
    482474       
    483475        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484476        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485477        if (rc != EOK) {
     478                vfs_exchange_end(vfs_phone);
     479
    486480                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     481                async_wait_for(req, &rc_orig);
     482
    491483                if (rc_orig == EOK)
    492484                        return (ssize_t) rc;
     
    494486                        return (ssize_t) rc_orig;
    495487        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     488        vfs_exchange_end(vfs_phone);
     489        async_wait_for(req, &rc);
    499490
    500491        return rc;
     
    512503                return ENOMEM;
    513504       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     505        int vfs_phone = vfs_exchange_begin();
    517506       
    518507        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519508        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520509        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     510                vfs_exchange_end(vfs_phone);
    524511                free(pa);
     512                async_wait_for(req, &rc_orig);
    525513                if (rc_orig == EOK)
    526514                        return (int) rc;
     
    530518        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531519        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     520                vfs_exchange_end(vfs_phone);
    535521                free(pa);
    536                 if (rc_orig == EOK)
    537                         return (int) rc;
    538                 else
    539                         return (int) rc_orig;
    540         }
    541         async_wait_for(req, &rc);
    542         async_serialize_end();
    543         futex_up(&vfs_phone_futex);
     522                async_wait_for(req, &rc_orig);
     523                if (rc_orig == EOK)
     524                        return (int) rc;
     525                else
     526                        return (int) rc_orig;
     527        }
     528        vfs_exchange_end(vfs_phone);
    544529        free(pa);
     530        async_wait_for(req, &rc);
    545531        return rc;
    546532}
     
    601587                return ENOMEM;
    602588       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     589        int vfs_phone = vfs_exchange_begin();
    606590       
    607591        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608592        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609593        if (rc != EOK) {
     594                vfs_exchange_end(vfs_phone);
     595                free(pa);
     596
    610597                sysarg_t rc_orig;
    611        
    612                 async_wait_for(req, &rc_orig);
    613                 async_serialize_end();
    614                 futex_up(&vfs_phone_futex);
    615                 free(pa);
    616                 if (rc_orig == EOK)
    617                         return (int) rc;
    618                 else
    619                         return (int) rc_orig;
    620         }
    621         async_wait_for(req, &rc);
    622         async_serialize_end();
    623         futex_up(&vfs_phone_futex);
     598                async_wait_for(req, &rc_orig);
     599
     600                if (rc_orig == EOK)
     601                        return (int) rc;
     602                else
     603                        return (int) rc_orig;
     604        }
     605        vfs_exchange_end(vfs_phone);
    624606        free(pa);
     607        async_wait_for(req, &rc);
    625608        return rc;
    626609}
     
    636619                return ENOMEM;
    637620
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     621        int vfs_phone = vfs_exchange_begin();
    641622       
    642623        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643624        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644625        if (rc != EOK) {
     626                vfs_exchange_end(vfs_phone);
     627                free(pa);
     628
    645629                sysarg_t rc_orig;
    646 
    647                 async_wait_for(req, &rc_orig);
    648                 async_serialize_end();
    649                 futex_up(&vfs_phone_futex);
    650                 free(pa);
    651                 if (rc_orig == EOK)
    652                         return (int) rc;
    653                 else
    654                         return (int) rc_orig;
    655         }
    656         async_wait_for(req, &rc);
    657         async_serialize_end();
    658         futex_up(&vfs_phone_futex);
     630                async_wait_for(req, &rc_orig);
     631
     632                if (rc_orig == EOK)
     633                        return (int) rc;
     634                else
     635                        return (int) rc_orig;
     636        }
     637        vfs_exchange_end(vfs_phone);
    659638        free(pa);
     639        async_wait_for(req, &rc);
    660640        return rc;
    661641}
     
    689669        }
    690670
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     671        int vfs_phone = vfs_exchange_begin();
    694672       
    695673        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696674        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697675        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     676                vfs_exchange_end(vfs_phone);
    701677                free(olda);
    702678                free(newa);
     679                async_wait_for(req, &rc_orig);
    703680                if (rc_orig == EOK)
    704681                        return (int) rc;
     
    708685        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709686        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     687                vfs_exchange_end(vfs_phone);
    713688                free(olda);
    714689                free(newa);
    715                 if (rc_orig == EOK)
    716                         return (int) rc;
    717                 else
    718                         return (int) rc_orig;
    719         }
    720         async_wait_for(req, &rc);
    721         async_serialize_end();
    722         futex_up(&vfs_phone_futex);
     690                async_wait_for(req, &rc_orig);
     691                if (rc_orig == EOK)
     692                        return (int) rc;
     693                else
     694                        return (int) rc_orig;
     695        }
     696        vfs_exchange_end(vfs_phone);
    723697        free(olda);
    724698        free(newa);
     699        async_wait_for(req, &rc);
    725700        return rc;
    726701}
     
    740715        }
    741716       
    742         futex_down(&cwd_futex);
     717        fibril_mutex_lock(&cwd_mutex);
    743718       
    744719        if (cwd_fd >= 0)
     
    753728        cwd_size = abs_size;
    754729       
    755         futex_up(&cwd_futex);
     730        fibril_mutex_unlock(&cwd_mutex);
    756731        return EOK;
    757732}
     
    762737                return NULL;
    763738       
    764         futex_down(&cwd_futex);
     739        fibril_mutex_lock(&cwd_mutex);
    765740       
    766741        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     742                fibril_mutex_unlock(&cwd_mutex);
    768743                return NULL;
    769744        }
    770745       
    771746        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     747        fibril_mutex_unlock(&cwd_mutex);
    773748       
    774749        return buf;
     
    806781int dup2(int oldfd, int newfd)
    807782{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     783        int vfs_phone = vfs_exchange_begin();
    811784       
    812785        sysarg_t ret;
    813786        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814787       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     788        vfs_exchange_end(vfs_phone);
    817789       
    818790        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.