Changeset 7a51d75 in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2011-01-28T15:30:42Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ea991e84
Parents:
c5c003c (diff), 2b96463 (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 development/ changes

File:
1 edited

Legend:

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

    rc5c003c r7a51d75  
    4646#include <ipc/services.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{
    116         while (vfs_phone < 0)
    117                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
     120        while (vfs_phone < 0) {
     121                vfs_phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_VFS,
     122                    0, 0);
     123        }
     124       
     125        async_session_create(&vfs_session, vfs_phone, 0);
     126}
     127
     128/** Start an async exchange on the VFS session.
     129 *
     130 * @return              New phone to be used during the exchange.
     131 */
     132static int vfs_exchange_begin(void)
     133{
     134        fibril_mutex_lock(&vfs_phone_mutex);
     135        if (vfs_phone < 0)
     136                vfs_connect();
     137        fibril_mutex_unlock(&vfs_phone_mutex);
     138
     139        return async_exchange_begin(&vfs_session);
     140}
     141
     142/** End an async exchange on the VFS session.
     143 *
     144 * @param phone         Phone used during the exchange.
     145 */
     146static void vfs_exchange_end(int phone)
     147{
     148        async_exchange_end(&vfs_session, phone);
    118149}
    119150
     
    154185        }
    155186       
    156         futex_down(&vfs_phone_futex);
    157         async_serialize_start();
    158         vfs_connect();
    159        
     187        int vfs_phone = vfs_exchange_begin();
     188
    160189        sysarg_t rc_orig;
    161190        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    162191        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    163192        if (rc != EOK) {
    164                 async_wait_for(req, &rc_orig);
    165                 async_serialize_end();
    166                 futex_up(&vfs_phone_futex);
     193                vfs_exchange_end(vfs_phone);
    167194                free(mpa);
     195                async_wait_for(req, &rc_orig);
    168196               
    169197                if (null_id != -1)
     
    178206        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    179207        if (rc != EOK) {
    180                 async_wait_for(req, &rc_orig);
    181                 async_serialize_end();
    182                 futex_up(&vfs_phone_futex);
     208                vfs_exchange_end(vfs_phone);
    183209                free(mpa);
     210                async_wait_for(req, &rc_orig);
    184211               
    185212                if (null_id != -1)
     
    194221        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    195222        if (rc != EOK) {
    196                 async_wait_for(req, &rc_orig);
    197                 async_serialize_end();
    198                 futex_up(&vfs_phone_futex);
     223                vfs_exchange_end(vfs_phone);
    199224                free(mpa);
     225                async_wait_for(req, &rc_orig);
    200226               
    201227                if (null_id != -1)
     
    211237        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    212238        if (rc != EOK) {
    213                 async_wait_for(req, &rc_orig);
    214                 async_serialize_end();
    215                 futex_up(&vfs_phone_futex);
     239                vfs_exchange_end(vfs_phone);
    216240                free(mpa);
     241                async_wait_for(req, &rc_orig);
    217242               
    218243                if (null_id != -1)
     
    225250        }
    226251       
    227         async_wait_for(req, &rc);
    228         async_serialize_end();
    229         futex_up(&vfs_phone_futex);
     252        vfs_exchange_end(vfs_phone);
    230253        free(mpa);
     254        async_wait_for(req, &rc);
    231255       
    232256        if ((rc != EOK) && (null_id != -1))
     
    248272                return ENOMEM;
    249273       
    250         futex_down(&vfs_phone_futex);
    251         async_serialize_start();
    252         vfs_connect();
     274        int vfs_phone = vfs_exchange_begin();
    253275       
    254276        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    255277        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    256278        if (rc != EOK) {
    257                 async_wait_for(req, &rc_orig);
    258                 async_serialize_end();
    259                 futex_up(&vfs_phone_futex);
     279                vfs_exchange_end(vfs_phone);
    260280                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);
     281                async_wait_for(req, &rc_orig);
     282                if (rc_orig == EOK)
     283                        return (int) rc;
     284                else
     285                        return (int) rc_orig;
     286        }
     287       
     288
     289        vfs_exchange_end(vfs_phone);
    271290        free(mpa);
     291        async_wait_for(req, &rc);
    272292       
    273293        return (int) rc;
     
    276296static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    277297{
    278         futex_down(&vfs_phone_futex);
    279         async_serialize_start();
    280         vfs_connect();
     298        int vfs_phone = vfs_exchange_begin();
    281299       
    282300        ipc_call_t answer;
     
    285303       
    286304        if (rc != EOK) {
     305                vfs_exchange_end(vfs_phone);
     306
    287307                sysarg_t rc_orig;
    288308                async_wait_for(req, &rc_orig);
    289309               
    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);
     310                if (rc_orig == EOK)
     311                        return (int) rc;
     312                else
     313                        return (int) rc_orig;
     314        }
     315       
     316        vfs_exchange_end(vfs_phone);
     317        async_wait_for(req, &rc);
    302318       
    303319        if (rc != EOK)
     
    322338int open_node(fdi_node_t *node, int oflag)
    323339{
    324         futex_down(&vfs_phone_futex);
    325         async_serialize_start();
    326         vfs_connect();
     340        int vfs_phone = vfs_exchange_begin();
    327341       
    328342        ipc_call_t answer;
     
    330344            node->devmap_handle, node->index, oflag, &answer);
    331345       
    332         sysarg_t rc;
    333         async_wait_for(req, &rc);
    334         async_serialize_end();
    335         futex_up(&vfs_phone_futex);
     346        vfs_exchange_end(vfs_phone);
     347
     348        sysarg_t rc;
     349        async_wait_for(req, &rc);
    336350       
    337351        if (rc != EOK)
     
    345359        sysarg_t rc;
    346360       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
     361        int vfs_phone = vfs_exchange_begin();
    350362       
    351363        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    352364       
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
     365        vfs_exchange_end(vfs_phone);
    355366       
    356367        return (int)rc;
     
    363374        aid_t req;
    364375
    365         futex_down(&vfs_phone_futex);
    366         async_serialize_start();
    367         vfs_connect();
     376        int vfs_phone = vfs_exchange_begin();
    368377       
    369378        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    370379        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371380        if (rc != EOK) {
     381                vfs_exchange_end(vfs_phone);
     382
    372383                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     384                async_wait_for(req, &rc_orig);
     385
    377386                if (rc_orig == EOK)
    378387                        return (ssize_t) rc;
     
    380389                        return (ssize_t) rc_orig;
    381390        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     391        vfs_exchange_end(vfs_phone);
     392        async_wait_for(req, &rc);
    385393        if (rc == EOK)
    386394                return (ssize_t) IPC_GET_ARG1(answer);
     
    395403        aid_t req;
    396404
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     405        int vfs_phone = vfs_exchange_begin();
    400406       
    401407        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402408        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403409        if (rc != EOK) {
     410                vfs_exchange_end(vfs_phone);
     411
    404412                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     413                async_wait_for(req, &rc_orig);
     414
    409415                if (rc_orig == EOK)
    410416                        return (ssize_t) rc;
     
    412418                        return (ssize_t) rc_orig;
    413419        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     420        vfs_exchange_end(vfs_phone);
     421        async_wait_for(req, &rc);
    417422        if (rc == EOK)
    418423                return (ssize_t) IPC_GET_ARG1(answer);
     
    423428int fsync(int fildes)
    424429{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     430        int vfs_phone = vfs_exchange_begin();
    428431       
    429432        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430433       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     434        vfs_exchange_end(vfs_phone);
    433435       
    434436        return (int) rc;
     
    437439off64_t lseek(int fildes, off64_t offset, int whence)
    438440{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     441        int vfs_phone = vfs_exchange_begin();
    442442       
    443443        sysarg_t newoff_lo;
     
    447447            &newoff_lo, &newoff_hi);
    448448       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     449        vfs_exchange_end(vfs_phone);
    451450       
    452451        if (rc != EOK)
     
    460459        sysarg_t rc;
    461460       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     461        int vfs_phone = vfs_exchange_begin();
    465462       
    466463        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467464            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     465        vfs_exchange_end(vfs_phone);
    470466       
    471467        return (int) rc;
     
    477473        aid_t req;
    478474
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     475        int vfs_phone = vfs_exchange_begin();
    482476       
    483477        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484478        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485479        if (rc != EOK) {
     480                vfs_exchange_end(vfs_phone);
     481
    486482                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     483                async_wait_for(req, &rc_orig);
     484
    491485                if (rc_orig == EOK)
    492486                        return (ssize_t) rc;
     
    494488                        return (ssize_t) rc_orig;
    495489        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     490        vfs_exchange_end(vfs_phone);
     491        async_wait_for(req, &rc);
    499492
    500493        return rc;
     
    512505                return ENOMEM;
    513506       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     507        int vfs_phone = vfs_exchange_begin();
    517508       
    518509        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519510        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520511        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     512                vfs_exchange_end(vfs_phone);
    524513                free(pa);
     514                async_wait_for(req, &rc_orig);
    525515                if (rc_orig == EOK)
    526516                        return (int) rc;
     
    530520        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531521        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     522                vfs_exchange_end(vfs_phone);
    535523                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);
     524                async_wait_for(req, &rc_orig);
     525                if (rc_orig == EOK)
     526                        return (int) rc;
     527                else
     528                        return (int) rc_orig;
     529        }
     530        vfs_exchange_end(vfs_phone);
    544531        free(pa);
     532        async_wait_for(req, &rc);
    545533        return rc;
    546534}
     
    601589                return ENOMEM;
    602590       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     591        int vfs_phone = vfs_exchange_begin();
    606592       
    607593        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608594        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609595        if (rc != EOK) {
     596                vfs_exchange_end(vfs_phone);
     597                free(pa);
     598
    610599                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);
     600                async_wait_for(req, &rc_orig);
     601
     602                if (rc_orig == EOK)
     603                        return (int) rc;
     604                else
     605                        return (int) rc_orig;
     606        }
     607        vfs_exchange_end(vfs_phone);
    624608        free(pa);
     609        async_wait_for(req, &rc);
    625610        return rc;
    626611}
     
    636621                return ENOMEM;
    637622
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     623        int vfs_phone = vfs_exchange_begin();
    641624       
    642625        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643626        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644627        if (rc != EOK) {
     628                vfs_exchange_end(vfs_phone);
     629                free(pa);
     630
    645631                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);
     632                async_wait_for(req, &rc_orig);
     633
     634                if (rc_orig == EOK)
     635                        return (int) rc;
     636                else
     637                        return (int) rc_orig;
     638        }
     639        vfs_exchange_end(vfs_phone);
    659640        free(pa);
     641        async_wait_for(req, &rc);
    660642        return rc;
    661643}
     
    689671        }
    690672
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     673        int vfs_phone = vfs_exchange_begin();
    694674       
    695675        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696676        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697677        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     678                vfs_exchange_end(vfs_phone);
    701679                free(olda);
    702680                free(newa);
     681                async_wait_for(req, &rc_orig);
    703682                if (rc_orig == EOK)
    704683                        return (int) rc;
     
    708687        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709688        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     689                vfs_exchange_end(vfs_phone);
    713690                free(olda);
    714691                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);
     692                async_wait_for(req, &rc_orig);
     693                if (rc_orig == EOK)
     694                        return (int) rc;
     695                else
     696                        return (int) rc_orig;
     697        }
     698        vfs_exchange_end(vfs_phone);
    723699        free(olda);
    724700        free(newa);
     701        async_wait_for(req, &rc);
    725702        return rc;
    726703}
     
    740717        }
    741718       
    742         futex_down(&cwd_futex);
     719        fibril_mutex_lock(&cwd_mutex);
    743720       
    744721        if (cwd_fd >= 0)
     
    753730        cwd_size = abs_size;
    754731       
    755         futex_up(&cwd_futex);
     732        fibril_mutex_unlock(&cwd_mutex);
    756733        return EOK;
    757734}
     
    762739                return NULL;
    763740       
    764         futex_down(&cwd_futex);
     741        fibril_mutex_lock(&cwd_mutex);
    765742       
    766743        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     744                fibril_mutex_unlock(&cwd_mutex);
    768745                return NULL;
    769746        }
    770747       
    771748        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     749        fibril_mutex_unlock(&cwd_mutex);
    773750       
    774751        return buf;
     
    806783int dup2(int oldfd, int newfd)
    807784{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     785        int vfs_phone = vfs_exchange_begin();
    811786       
    812787        sysarg_t ret;
    813788        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814789       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     790        vfs_exchange_end(vfs_phone);
    817791       
    818792        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.