Changeset ad7a6c9 in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2011-03-30T13:10:24Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4ae90f9
Parents:
6e50466 (diff), d6b81941 (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

    r6e50466 rad7a6c9  
    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;
     
    6669        char *ncwd_path;
    6770        char *ncwd_path_nc;
    68 
    69         futex_down(&cwd_futex);
     71        size_t total_size;
     72
     73        fibril_mutex_lock(&cwd_mutex);
    7074        size_t size = str_size(path);
    7175        if (*path != '/') {
    7276                if (!cwd_path) {
    73                         futex_up(&cwd_futex);
     77                        fibril_mutex_unlock(&cwd_mutex);
    7478                        return NULL;
    7579                }
    76                 ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
     80                total_size = cwd_size + 1 + size + 1;
     81                ncwd_path_nc = malloc(total_size);
    7782                if (!ncwd_path_nc) {
    78                         futex_up(&cwd_futex);
     83                        fibril_mutex_unlock(&cwd_mutex);
    7984                        return NULL;
    8085                }
    81                 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
     86                str_cpy(ncwd_path_nc, total_size, cwd_path);
    8287                ncwd_path_nc[cwd_size] = '/';
    8388                ncwd_path_nc[cwd_size + 1] = '\0';
    8489        } else {
    85                 ncwd_path_nc = malloc(size + 1);
     90                total_size = size + 1;
     91                ncwd_path_nc = malloc(total_size);
    8692                if (!ncwd_path_nc) {
    87                         futex_up(&cwd_futex);
     93                        fibril_mutex_unlock(&cwd_mutex);
    8894                        return NULL;
    8995                }
    9096                ncwd_path_nc[0] = '\0';
    9197        }
    92         str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
     98        str_append(ncwd_path_nc, total_size, path);
    9399        ncwd_path = canonify(ncwd_path_nc, retlen);
    94100        if (!ncwd_path) {
    95                 futex_up(&cwd_futex);
     101                fibril_mutex_unlock(&cwd_mutex);
    96102                free(ncwd_path_nc);
    97103                return NULL;
     
    105111        free(ncwd_path_nc);
    106112        if (!ncwd_path) {
    107                 futex_up(&cwd_futex);
     113                fibril_mutex_unlock(&cwd_mutex);
    108114                return NULL;
    109115        }
    110         futex_up(&cwd_futex);
     116        fibril_mutex_unlock(&cwd_mutex);
    111117        return ncwd_path;
    112118}
    113119
     120/** Connect to VFS service and create session. */
    114121static void vfs_connect(void)
    115122{
    116123        while (vfs_phone < 0)
    117                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
     124                vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
     125       
     126        async_session_create(&vfs_session, vfs_phone, 0);
     127}
     128
     129/** Start an async exchange on the VFS session.
     130 *
     131 * @return              New phone to be used during the exchange.
     132 */
     133static int vfs_exchange_begin(void)
     134{
     135        fibril_mutex_lock(&vfs_phone_mutex);
     136        if (vfs_phone < 0)
     137                vfs_connect();
     138        fibril_mutex_unlock(&vfs_phone_mutex);
     139
     140        return async_exchange_begin(&vfs_session);
     141}
     142
     143/** End an async exchange on the VFS session.
     144 *
     145 * @param phone         Phone used during the exchange.
     146 */
     147static void vfs_exchange_end(int phone)
     148{
     149        async_exchange_end(&vfs_session, phone);
    118150}
    119151
     
    154186        }
    155187       
    156         futex_down(&vfs_phone_futex);
    157         async_serialize_start();
    158         vfs_connect();
    159        
     188        int vfs_phone = vfs_exchange_begin();
     189
    160190        sysarg_t rc_orig;
    161191        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    162192        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    163193        if (rc != EOK) {
    164                 async_wait_for(req, &rc_orig);
    165                 async_serialize_end();
    166                 futex_up(&vfs_phone_futex);
     194                vfs_exchange_end(vfs_phone);
    167195                free(mpa);
     196                async_wait_for(req, &rc_orig);
    168197               
    169198                if (null_id != -1)
     
    178207        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    179208        if (rc != EOK) {
    180                 async_wait_for(req, &rc_orig);
    181                 async_serialize_end();
    182                 futex_up(&vfs_phone_futex);
     209                vfs_exchange_end(vfs_phone);
    183210                free(mpa);
     211                async_wait_for(req, &rc_orig);
    184212               
    185213                if (null_id != -1)
     
    194222        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    195223        if (rc != EOK) {
    196                 async_wait_for(req, &rc_orig);
    197                 async_serialize_end();
    198                 futex_up(&vfs_phone_futex);
     224                vfs_exchange_end(vfs_phone);
    199225                free(mpa);
     226                async_wait_for(req, &rc_orig);
    200227               
    201228                if (null_id != -1)
     
    211238        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    212239        if (rc != EOK) {
    213                 async_wait_for(req, &rc_orig);
    214                 async_serialize_end();
    215                 futex_up(&vfs_phone_futex);
     240                vfs_exchange_end(vfs_phone);
    216241                free(mpa);
     242                async_wait_for(req, &rc_orig);
    217243               
    218244                if (null_id != -1)
     
    225251        }
    226252       
    227         async_wait_for(req, &rc);
    228         async_serialize_end();
    229         futex_up(&vfs_phone_futex);
     253        vfs_exchange_end(vfs_phone);
    230254        free(mpa);
     255        async_wait_for(req, &rc);
    231256       
    232257        if ((rc != EOK) && (null_id != -1))
     
    248273                return ENOMEM;
    249274       
    250         futex_down(&vfs_phone_futex);
    251         async_serialize_start();
    252         vfs_connect();
     275        int vfs_phone = vfs_exchange_begin();
    253276       
    254277        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    255278        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    256279        if (rc != EOK) {
    257                 async_wait_for(req, &rc_orig);
    258                 async_serialize_end();
    259                 futex_up(&vfs_phone_futex);
     280                vfs_exchange_end(vfs_phone);
    260281                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);
     282                async_wait_for(req, &rc_orig);
     283                if (rc_orig == EOK)
     284                        return (int) rc;
     285                else
     286                        return (int) rc_orig;
     287        }
     288       
     289
     290        vfs_exchange_end(vfs_phone);
    271291        free(mpa);
     292        async_wait_for(req, &rc);
    272293       
    273294        return (int) rc;
     
    276297static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    277298{
    278         futex_down(&vfs_phone_futex);
    279         async_serialize_start();
    280         vfs_connect();
     299        int vfs_phone = vfs_exchange_begin();
    281300       
    282301        ipc_call_t answer;
     
    285304       
    286305        if (rc != EOK) {
     306                vfs_exchange_end(vfs_phone);
     307
    287308                sysarg_t rc_orig;
    288309                async_wait_for(req, &rc_orig);
    289310               
    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);
     311                if (rc_orig == EOK)
     312                        return (int) rc;
     313                else
     314                        return (int) rc_orig;
     315        }
     316       
     317        vfs_exchange_end(vfs_phone);
     318        async_wait_for(req, &rc);
    302319       
    303320        if (rc != EOK)
     
    322339int open_node(fdi_node_t *node, int oflag)
    323340{
    324         futex_down(&vfs_phone_futex);
    325         async_serialize_start();
    326         vfs_connect();
     341        int vfs_phone = vfs_exchange_begin();
    327342       
    328343        ipc_call_t answer;
     
    330345            node->devmap_handle, node->index, oflag, &answer);
    331346       
    332         sysarg_t rc;
    333         async_wait_for(req, &rc);
    334         async_serialize_end();
    335         futex_up(&vfs_phone_futex);
     347        vfs_exchange_end(vfs_phone);
     348
     349        sysarg_t rc;
     350        async_wait_for(req, &rc);
    336351       
    337352        if (rc != EOK)
     
    345360        sysarg_t rc;
    346361       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
     362        int vfs_phone = vfs_exchange_begin();
    350363       
    351364        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    352365       
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
     366        vfs_exchange_end(vfs_phone);
    355367       
    356368        return (int)rc;
     
    363375        aid_t req;
    364376
    365         futex_down(&vfs_phone_futex);
    366         async_serialize_start();
    367         vfs_connect();
     377        int vfs_phone = vfs_exchange_begin();
    368378       
    369379        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    370380        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371381        if (rc != EOK) {
     382                vfs_exchange_end(vfs_phone);
     383
    372384                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     385                async_wait_for(req, &rc_orig);
     386
    377387                if (rc_orig == EOK)
    378388                        return (ssize_t) rc;
     
    380390                        return (ssize_t) rc_orig;
    381391        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     392        vfs_exchange_end(vfs_phone);
     393        async_wait_for(req, &rc);
    385394        if (rc == EOK)
    386395                return (ssize_t) IPC_GET_ARG1(answer);
     
    395404        aid_t req;
    396405
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     406        int vfs_phone = vfs_exchange_begin();
    400407       
    401408        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402409        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403410        if (rc != EOK) {
     411                vfs_exchange_end(vfs_phone);
     412
    404413                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     414                async_wait_for(req, &rc_orig);
     415
    409416                if (rc_orig == EOK)
    410417                        return (ssize_t) rc;
     
    412419                        return (ssize_t) rc_orig;
    413420        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     421        vfs_exchange_end(vfs_phone);
     422        async_wait_for(req, &rc);
    417423        if (rc == EOK)
    418424                return (ssize_t) IPC_GET_ARG1(answer);
     
    423429int fsync(int fildes)
    424430{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     431        int vfs_phone = vfs_exchange_begin();
    428432       
    429433        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430434       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     435        vfs_exchange_end(vfs_phone);
    433436       
    434437        return (int) rc;
     
    437440off64_t lseek(int fildes, off64_t offset, int whence)
    438441{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     442        int vfs_phone = vfs_exchange_begin();
    442443       
    443444        sysarg_t newoff_lo;
     
    447448            &newoff_lo, &newoff_hi);
    448449       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     450        vfs_exchange_end(vfs_phone);
    451451       
    452452        if (rc != EOK)
     
    460460        sysarg_t rc;
    461461       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     462        int vfs_phone = vfs_exchange_begin();
    465463       
    466464        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467465            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     466        vfs_exchange_end(vfs_phone);
    470467       
    471468        return (int) rc;
     
    477474        aid_t req;
    478475
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     476        int vfs_phone = vfs_exchange_begin();
    482477       
    483478        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484479        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485480        if (rc != EOK) {
     481                vfs_exchange_end(vfs_phone);
     482
    486483                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     484                async_wait_for(req, &rc_orig);
     485
    491486                if (rc_orig == EOK)
    492487                        return (ssize_t) rc;
     
    494489                        return (ssize_t) rc_orig;
    495490        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     491        vfs_exchange_end(vfs_phone);
     492        async_wait_for(req, &rc);
    499493
    500494        return rc;
     
    512506                return ENOMEM;
    513507       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     508        int vfs_phone = vfs_exchange_begin();
    517509       
    518510        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519511        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520512        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     513                vfs_exchange_end(vfs_phone);
    524514                free(pa);
     515                async_wait_for(req, &rc_orig);
    525516                if (rc_orig == EOK)
    526517                        return (int) rc;
     
    530521        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531522        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     523                vfs_exchange_end(vfs_phone);
    535524                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);
     525                async_wait_for(req, &rc_orig);
     526                if (rc_orig == EOK)
     527                        return (int) rc;
     528                else
     529                        return (int) rc_orig;
     530        }
     531        vfs_exchange_end(vfs_phone);
    544532        free(pa);
     533        async_wait_for(req, &rc);
    545534        return rc;
    546535}
     
    601590                return ENOMEM;
    602591       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     592        int vfs_phone = vfs_exchange_begin();
    606593       
    607594        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608595        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609596        if (rc != EOK) {
     597                vfs_exchange_end(vfs_phone);
     598                free(pa);
     599
    610600                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);
     601                async_wait_for(req, &rc_orig);
     602
     603                if (rc_orig == EOK)
     604                        return (int) rc;
     605                else
     606                        return (int) rc_orig;
     607        }
     608        vfs_exchange_end(vfs_phone);
    624609        free(pa);
     610        async_wait_for(req, &rc);
    625611        return rc;
    626612}
     
    636622                return ENOMEM;
    637623
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     624        int vfs_phone = vfs_exchange_begin();
    641625       
    642626        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643627        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644628        if (rc != EOK) {
     629                vfs_exchange_end(vfs_phone);
     630                free(pa);
     631
    645632                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);
     633                async_wait_for(req, &rc_orig);
     634
     635                if (rc_orig == EOK)
     636                        return (int) rc;
     637                else
     638                        return (int) rc_orig;
     639        }
     640        vfs_exchange_end(vfs_phone);
    659641        free(pa);
     642        async_wait_for(req, &rc);
    660643        return rc;
    661644}
     
    689672        }
    690673
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     674        int vfs_phone = vfs_exchange_begin();
    694675       
    695676        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696677        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697678        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     679                vfs_exchange_end(vfs_phone);
    701680                free(olda);
    702681                free(newa);
     682                async_wait_for(req, &rc_orig);
    703683                if (rc_orig == EOK)
    704684                        return (int) rc;
     
    708688        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709689        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     690                vfs_exchange_end(vfs_phone);
    713691                free(olda);
    714692                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);
     693                async_wait_for(req, &rc_orig);
     694                if (rc_orig == EOK)
     695                        return (int) rc;
     696                else
     697                        return (int) rc_orig;
     698        }
     699        vfs_exchange_end(vfs_phone);
    723700        free(olda);
    724701        free(newa);
     702        async_wait_for(req, &rc);
    725703        return rc;
    726704}
     
    740718        }
    741719       
    742         futex_down(&cwd_futex);
     720        fibril_mutex_lock(&cwd_mutex);
    743721       
    744722        if (cwd_fd >= 0)
     
    753731        cwd_size = abs_size;
    754732       
    755         futex_up(&cwd_futex);
     733        fibril_mutex_unlock(&cwd_mutex);
    756734        return EOK;
    757735}
     
    762740                return NULL;
    763741       
    764         futex_down(&cwd_futex);
     742        fibril_mutex_lock(&cwd_mutex);
    765743       
    766744        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     745                fibril_mutex_unlock(&cwd_mutex);
    768746                return NULL;
    769747        }
    770748       
    771749        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     750        fibril_mutex_unlock(&cwd_mutex);
    773751       
    774752        return buf;
     
    778756{
    779757        struct stat stat;
    780         int rc;
    781 
    782         rc = fstat(fildes, &stat);
    783 
     758       
     759        int rc = fstat(fildes, &stat);
     760        if (rc != 0)
     761                return rc;
     762       
    784763        if (!stat.device)
    785764                return -1;
     
    806785int dup2(int oldfd, int newfd)
    807786{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     787        int vfs_phone = vfs_exchange_begin();
    811788       
    812789        sysarg_t ret;
    813790        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814791       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     792        vfs_exchange_end(vfs_phone);
    817793       
    818794        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.