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


Ignore:
Timestamp:
2011-04-15T19:38:07Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9dd730d1
Parents:
6b9e85b (diff), b2fb47f (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

    r6b9e85b r8b655705  
    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);
    370         rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371         if (rc != EOK) {
     380        rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
     381            IPC_XF_RESTRICT);
     382        if (rc != EOK) {
     383                vfs_exchange_end(vfs_phone);
     384
    372385                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     386                async_wait_for(req, &rc_orig);
     387
    377388                if (rc_orig == EOK)
    378389                        return (ssize_t) rc;
     
    380391                        return (ssize_t) rc_orig;
    381392        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     393        vfs_exchange_end(vfs_phone);
     394        async_wait_for(req, &rc);
    385395        if (rc == EOK)
    386396                return (ssize_t) IPC_GET_ARG1(answer);
     
    395405        aid_t req;
    396406
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     407        int vfs_phone = vfs_exchange_begin();
    400408       
    401409        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402         rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403         if (rc != EOK) {
     410        rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
     411            IPC_XF_RESTRICT);
     412        if (rc != EOK) {
     413                vfs_exchange_end(vfs_phone);
     414
    404415                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     416                async_wait_for(req, &rc_orig);
     417
    409418                if (rc_orig == EOK)
    410419                        return (ssize_t) rc;
     
    412421                        return (ssize_t) rc_orig;
    413422        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     423        vfs_exchange_end(vfs_phone);
     424        async_wait_for(req, &rc);
    417425        if (rc == EOK)
    418426                return (ssize_t) IPC_GET_ARG1(answer);
     
    423431int fsync(int fildes)
    424432{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     433        int vfs_phone = vfs_exchange_begin();
    428434       
    429435        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430436       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     437        vfs_exchange_end(vfs_phone);
    433438       
    434439        return (int) rc;
     
    437442off64_t lseek(int fildes, off64_t offset, int whence)
    438443{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     444        int vfs_phone = vfs_exchange_begin();
    442445       
    443446        sysarg_t newoff_lo;
     
    447450            &newoff_lo, &newoff_hi);
    448451       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     452        vfs_exchange_end(vfs_phone);
    451453       
    452454        if (rc != EOK)
     
    460462        sysarg_t rc;
    461463       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     464        int vfs_phone = vfs_exchange_begin();
    465465       
    466466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467467            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     468        vfs_exchange_end(vfs_phone);
    470469       
    471470        return (int) rc;
     
    477476        aid_t req;
    478477
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     478        int vfs_phone = vfs_exchange_begin();
    482479       
    483480        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484481        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485482        if (rc != EOK) {
     483                vfs_exchange_end(vfs_phone);
     484
    486485                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     486                async_wait_for(req, &rc_orig);
     487
    491488                if (rc_orig == EOK)
    492489                        return (ssize_t) rc;
     
    494491                        return (ssize_t) rc_orig;
    495492        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     493        vfs_exchange_end(vfs_phone);
     494        async_wait_for(req, &rc);
    499495
    500496        return rc;
     
    512508                return ENOMEM;
    513509       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     510        int vfs_phone = vfs_exchange_begin();
    517511       
    518512        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519513        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520514        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     515                vfs_exchange_end(vfs_phone);
    524516                free(pa);
     517                async_wait_for(req, &rc_orig);
    525518                if (rc_orig == EOK)
    526519                        return (int) rc;
     
    530523        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531524        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     525                vfs_exchange_end(vfs_phone);
    535526                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);
     527                async_wait_for(req, &rc_orig);
     528                if (rc_orig == EOK)
     529                        return (int) rc;
     530                else
     531                        return (int) rc_orig;
     532        }
     533        vfs_exchange_end(vfs_phone);
    544534        free(pa);
     535        async_wait_for(req, &rc);
    545536        return rc;
    546537}
     
    601592                return ENOMEM;
    602593       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     594        int vfs_phone = vfs_exchange_begin();
    606595       
    607596        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608597        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609598        if (rc != EOK) {
     599                vfs_exchange_end(vfs_phone);
     600                free(pa);
     601
    610602                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);
     603                async_wait_for(req, &rc_orig);
     604
     605                if (rc_orig == EOK)
     606                        return (int) rc;
     607                else
     608                        return (int) rc_orig;
     609        }
     610        vfs_exchange_end(vfs_phone);
    624611        free(pa);
     612        async_wait_for(req, &rc);
    625613        return rc;
    626614}
     
    636624                return ENOMEM;
    637625
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     626        int vfs_phone = vfs_exchange_begin();
    641627       
    642628        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643629        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644630        if (rc != EOK) {
     631                vfs_exchange_end(vfs_phone);
     632                free(pa);
     633
    645634                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);
     635                async_wait_for(req, &rc_orig);
     636
     637                if (rc_orig == EOK)
     638                        return (int) rc;
     639                else
     640                        return (int) rc_orig;
     641        }
     642        vfs_exchange_end(vfs_phone);
    659643        free(pa);
     644        async_wait_for(req, &rc);
    660645        return rc;
    661646}
     
    689674        }
    690675
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     676        int vfs_phone = vfs_exchange_begin();
    694677       
    695678        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696679        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697680        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     681                vfs_exchange_end(vfs_phone);
    701682                free(olda);
    702683                free(newa);
     684                async_wait_for(req, &rc_orig);
    703685                if (rc_orig == EOK)
    704686                        return (int) rc;
     
    708690        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709691        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     692                vfs_exchange_end(vfs_phone);
    713693                free(olda);
    714694                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);
     695                async_wait_for(req, &rc_orig);
     696                if (rc_orig == EOK)
     697                        return (int) rc;
     698                else
     699                        return (int) rc_orig;
     700        }
     701        vfs_exchange_end(vfs_phone);
    723702        free(olda);
    724703        free(newa);
     704        async_wait_for(req, &rc);
    725705        return rc;
    726706}
     
    740720        }
    741721       
    742         futex_down(&cwd_futex);
     722        fibril_mutex_lock(&cwd_mutex);
    743723       
    744724        if (cwd_fd >= 0)
     
    753733        cwd_size = abs_size;
    754734       
    755         futex_up(&cwd_futex);
     735        fibril_mutex_unlock(&cwd_mutex);
    756736        return EOK;
    757737}
     
    762742                return NULL;
    763743       
    764         futex_down(&cwd_futex);
     744        fibril_mutex_lock(&cwd_mutex);
    765745       
    766746        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     747                fibril_mutex_unlock(&cwd_mutex);
    768748                return NULL;
    769749        }
    770750       
    771751        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     752        fibril_mutex_unlock(&cwd_mutex);
    773753       
    774754        return buf;
     
    778758{
    779759        struct stat stat;
    780         int rc;
    781 
    782         rc = fstat(fildes, &stat);
    783 
     760       
     761        int rc = fstat(fildes, &stat);
     762        if (rc != 0)
     763                return rc;
     764       
    784765        if (!stat.device)
    785766                return -1;
     
    806787int dup2(int oldfd, int newfd)
    807788{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     789        int vfs_phone = vfs_exchange_begin();
    811790       
    812791        sysarg_t ret;
    813792        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814793       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     794        vfs_exchange_end(vfs_phone);
    817795       
    818796        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.