Ignore:
File:
1 edited

Legend:

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

    r8fd04ba9 r8e80d3f  
    3333 */
    3434
     35#include <vfs/vfs.h>
    3536#include <vfs/canonify.h>
    36 #include <vfs/vfs.h>
    37 #include <vfs/vfs_sess.h>
    3837#include <macros.h>
    3938#include <stdlib.h>
     
    4544#include <sys/types.h>
    4645#include <ipc/services.h>
    47 #include <ns.h>
     46#include <ipc/ns.h>
    4847#include <async.h>
    4948#include <fibril_synch.h>
     
    5554#include <ipc/devmap.h>
    5655
    57 static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
    58 static async_sess_t *vfs_sess = NULL;
     56static async_sess_t vfs_session;
     57
     58static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
     59static int vfs_phone = -1;
    5960
    6061static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     
    6465static size_t cwd_size = 0;
    6566
    66 /** Start an async exchange on the VFS session.
    67  *
    68  * @return New exchange.
    69  *
    70  */
    71 static async_exch_t *vfs_exchange_begin(void)
    72 {
    73         fibril_mutex_lock(&vfs_mutex);
    74        
    75         while (vfs_sess == NULL)
    76                 vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS,
    77                     0, 0);
    78        
    79         fibril_mutex_unlock(&vfs_mutex);
    80        
    81         return async_exchange_begin(vfs_sess);
    82 }
    83 
    84 /** Finish an async exchange on the VFS session.
    85  *
    86  * @param exch Exchange to be finished.
    87  *
    88  */
    89 static void vfs_exchange_end(async_exch_t *exch)
    90 {
    91         async_exchange_end(exch);
    92 }
    93 
    9467char *absolutize(const char *path, size_t *retlen)
    9568{
    9669        char *ncwd_path;
    9770        char *ncwd_path_nc;
     71        size_t total_size;
    9872
    9973        fibril_mutex_lock(&cwd_mutex);
     
    10478                        return NULL;
    10579                }
    106                 ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
     80                total_size = cwd_size + 1 + size + 1;
     81                ncwd_path_nc = malloc(total_size);
    10782                if (!ncwd_path_nc) {
    10883                        fibril_mutex_unlock(&cwd_mutex);
    10984                        return NULL;
    11085                }
    111                 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
     86                str_cpy(ncwd_path_nc, total_size, cwd_path);
    11287                ncwd_path_nc[cwd_size] = '/';
    11388                ncwd_path_nc[cwd_size + 1] = '\0';
    11489        } else {
    115                 ncwd_path_nc = malloc(size + 1);
     90                total_size = size + 1;
     91                ncwd_path_nc = malloc(total_size);
    11692                if (!ncwd_path_nc) {
    11793                        fibril_mutex_unlock(&cwd_mutex);
     
    12096                ncwd_path_nc[0] = '\0';
    12197        }
    122         str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
     98        str_append(ncwd_path_nc, total_size, path);
    12399        ncwd_path = canonify(ncwd_path_nc, retlen);
    124100        if (!ncwd_path) {
     
    142118}
    143119
     120/** Connect to VFS service and create session. */
     121static void vfs_connect(void)
     122{
     123        while (vfs_phone < 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);
     150}
     151
    144152int mount(const char *fs_name, const char *mp, const char *fqdn,
    145153    const char *opts, unsigned int flags)
     
    178186        }
    179187       
    180         async_exch_t *exch = vfs_exchange_begin();
     188        int vfs_phone = vfs_exchange_begin();
    181189
    182190        sysarg_t rc_orig;
    183         aid_t req = async_send_2(exch, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    184         sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
    185         if (rc != EOK) {
    186                 vfs_exchange_end(exch);
     191        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
     192        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     193        if (rc != EOK) {
     194                vfs_exchange_end(vfs_phone);
    187195                free(mpa);
    188196                async_wait_for(req, &rc_orig);
     
    197205        }
    198206       
    199         rc = async_data_write_start(exch, (void *) opts, str_size(opts));
    200         if (rc != EOK) {
    201                 vfs_exchange_end(exch);
     207        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
     208        if (rc != EOK) {
     209                vfs_exchange_end(vfs_phone);
    202210                free(mpa);
    203211                async_wait_for(req, &rc_orig);
     
    212220        }
    213221       
    214         rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
    215         if (rc != EOK) {
    216                 vfs_exchange_end(exch);
     222        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
     223        if (rc != EOK) {
     224                vfs_exchange_end(vfs_phone);
    217225                free(mpa);
    218226                async_wait_for(req, &rc_orig);
     
    228236       
    229237        /* Ask VFS whether it likes fs_name. */
    230         rc = async_req_0_0(exch, VFS_IN_PING);
    231         if (rc != EOK) {
    232                 vfs_exchange_end(exch);
     238        rc = async_req_0_0(vfs_phone, IPC_M_PING);
     239        if (rc != EOK) {
     240                vfs_exchange_end(vfs_phone);
    233241                free(mpa);
    234242                async_wait_for(req, &rc_orig);
     
    243251        }
    244252       
    245         vfs_exchange_end(exch);
     253        vfs_exchange_end(vfs_phone);
    246254        free(mpa);
    247255        async_wait_for(req, &rc);
     
    265273                return ENOMEM;
    266274       
    267         async_exch_t *exch = vfs_exchange_begin();
    268        
    269         req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
    270         rc = async_data_write_start(exch, (void *) mpa, mpa_size);
    271         if (rc != EOK) {
    272                 vfs_exchange_end(exch);
     275        int vfs_phone = vfs_exchange_begin();
     276       
     277        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
     278        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     279        if (rc != EOK) {
     280                vfs_exchange_end(vfs_phone);
    273281                free(mpa);
    274282                async_wait_for(req, &rc_orig);
     
    280288       
    281289
    282         vfs_exchange_end(exch);
     290        vfs_exchange_end(vfs_phone);
    283291        free(mpa);
    284292        async_wait_for(req, &rc);
     
    289297static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    290298{
    291         async_exch_t *exch = vfs_exchange_begin();
     299        int vfs_phone = vfs_exchange_begin();
    292300       
    293301        ipc_call_t answer;
    294         aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
    295         sysarg_t rc = async_data_write_start(exch, abs, abs_size);
    296        
    297         if (rc != EOK) {
    298                 vfs_exchange_end(exch);
     302        aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     303        sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
     304       
     305        if (rc != EOK) {
     306                vfs_exchange_end(vfs_phone);
    299307
    300308                sysarg_t rc_orig;
     
    307315        }
    308316       
    309         vfs_exchange_end(exch);
     317        vfs_exchange_end(vfs_phone);
    310318        async_wait_for(req, &rc);
    311319       
     
    331339int open_node(fdi_node_t *node, int oflag)
    332340{
    333         async_exch_t *exch = vfs_exchange_begin();
     341        int vfs_phone = vfs_exchange_begin();
    334342       
    335343        ipc_call_t answer;
    336         aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
     344        aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
    337345            node->devmap_handle, node->index, oflag, &answer);
    338346       
    339         vfs_exchange_end(exch);
     347        vfs_exchange_end(vfs_phone);
    340348
    341349        sysarg_t rc;
     
    352360        sysarg_t rc;
    353361       
    354         async_exch_t *exch = vfs_exchange_begin();
    355         rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
    356         vfs_exchange_end(exch);
    357        
    358         return (int) rc;
     362        int vfs_phone = vfs_exchange_begin();
     363       
     364        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
     365       
     366        vfs_exchange_end(vfs_phone);
     367       
     368        return (int)rc;
    359369}
    360370
     
    364374        ipc_call_t answer;
    365375        aid_t req;
    366        
    367         async_exch_t *exch = vfs_exchange_begin();
    368        
    369         req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
    370         rc = async_data_read_start(exch, (void *)buf, nbyte);
    371         if (rc != EOK) {
    372                 vfs_exchange_end(exch);
     376
     377        int vfs_phone = vfs_exchange_begin();
     378       
     379        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
     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);
    373384
    374385                sysarg_t rc_orig;
     
    380391                        return (ssize_t) rc_orig;
    381392        }
    382         vfs_exchange_end(exch);
     393        vfs_exchange_end(vfs_phone);
    383394        async_wait_for(req, &rc);
    384395        if (rc == EOK)
     
    393404        ipc_call_t answer;
    394405        aid_t req;
    395        
    396         async_exch_t *exch = vfs_exchange_begin();
    397        
    398         req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
    399         rc = async_data_write_start(exch, (void *)buf, nbyte);
    400         if (rc != EOK) {
    401                 vfs_exchange_end(exch);
     406
     407        int vfs_phone = vfs_exchange_begin();
     408       
     409        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
     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);
    402414
    403415                sysarg_t rc_orig;
     
    409421                        return (ssize_t) rc_orig;
    410422        }
    411         vfs_exchange_end(exch);
     423        vfs_exchange_end(vfs_phone);
    412424        async_wait_for(req, &rc);
    413425        if (rc == EOK)
     
    417429}
    418430
    419 /** Read entire buffer.
    420  *
    421  * In face of short reads this function continues reading until either
    422  * the entire buffer is read or no more data is available (at end of file).
    423  *
    424  * @param fildes        File descriptor
    425  * @param buf           Buffer, @a nbytes bytes long
    426  * @param nbytes        Number of bytes to read
    427  *
    428  * @return              On success, positive number of bytes read.
    429  *                      On failure, negative error code from read().
    430  */
    431 ssize_t read_all(int fildes, void *buf, size_t nbyte)
    432 {
    433         ssize_t cnt = 0;
    434         size_t nread = 0;
    435         uint8_t *bp = (uint8_t *) buf;
    436 
    437         do {
    438                 bp += cnt;
    439                 nread += cnt;
    440                 cnt = read(fildes, bp, nbyte - nread);
    441         } while (cnt > 0 && (nbyte - nread - cnt) > 0);
    442 
    443         if (cnt < 0)
    444                 return cnt;
    445 
    446         return nread + cnt;
    447 }
    448 
    449 /** Write entire buffer.
    450  *
    451  * This function fails if it cannot write exactly @a len bytes to the file.
    452  *
    453  * @param fildes        File descriptor
    454  * @param buf           Data, @a nbytes bytes long
    455  * @param nbytes        Number of bytes to write
    456  *
    457  * @return              EOK on error, return value from write() if writing
    458  *                      failed.
    459  */
    460 ssize_t write_all(int fildes, const void *buf, size_t nbyte)
    461 {
    462         ssize_t cnt = 0;
    463         ssize_t nwritten = 0;
    464         const uint8_t *bp = (uint8_t *) buf;
    465 
    466         do {
    467                 bp += cnt;
    468                 nwritten += cnt;
    469                 cnt = write(fildes, bp, nbyte - nwritten);
    470         } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
    471 
    472         if (cnt < 0)
    473                 return cnt;
    474 
    475         if ((ssize_t)nbyte - nwritten - cnt > 0)
    476                 return EIO;
    477 
    478         return nbyte;
    479 }
    480 
    481431int fsync(int fildes)
    482432{
    483         async_exch_t *exch = vfs_exchange_begin();
    484         sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
    485         vfs_exchange_end(exch);
     433        int vfs_phone = vfs_exchange_begin();
     434       
     435        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
     436       
     437        vfs_exchange_end(vfs_phone);
    486438       
    487439        return (int) rc;
     
    490442off64_t lseek(int fildes, off64_t offset, int whence)
    491443{
    492         async_exch_t *exch = vfs_exchange_begin();
     444        int vfs_phone = vfs_exchange_begin();
    493445       
    494446        sysarg_t newoff_lo;
    495447        sysarg_t newoff_hi;
    496         sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
     448        sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
    497449            LOWER32(offset), UPPER32(offset), whence,
    498450            &newoff_lo, &newoff_hi);
    499451       
    500         vfs_exchange_end(exch);
     452        vfs_exchange_end(vfs_phone);
    501453       
    502454        if (rc != EOK)
     
    510462        sysarg_t rc;
    511463       
    512         async_exch_t *exch = vfs_exchange_begin();
    513         rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
     464        int vfs_phone = vfs_exchange_begin();
     465       
     466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    514467            LOWER32(length), UPPER32(length));
    515         vfs_exchange_end(exch);
     468        vfs_exchange_end(vfs_phone);
    516469       
    517470        return (int) rc;
     
    522475        sysarg_t rc;
    523476        aid_t req;
    524        
    525         async_exch_t *exch = vfs_exchange_begin();
    526        
    527         req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
    528         rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
    529         if (rc != EOK) {
    530                 vfs_exchange_end(exch);
     477
     478        int vfs_phone = vfs_exchange_begin();
     479       
     480        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
     481        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
     482        if (rc != EOK) {
     483                vfs_exchange_end(vfs_phone);
    531484
    532485                sysarg_t rc_orig;
     
    538491                        return (ssize_t) rc_orig;
    539492        }
    540         vfs_exchange_end(exch);
     493        vfs_exchange_end(vfs_phone);
    541494        async_wait_for(req, &rc);
    542495
     
    555508                return ENOMEM;
    556509       
    557         async_exch_t *exch = vfs_exchange_begin();
    558        
    559         req = async_send_0(exch, VFS_IN_STAT, NULL);
    560         rc = async_data_write_start(exch, pa, pa_size);
    561         if (rc != EOK) {
    562                 vfs_exchange_end(exch);
     510        int vfs_phone = vfs_exchange_begin();
     511       
     512        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
     513        rc = async_data_write_start(vfs_phone, pa, pa_size);
     514        if (rc != EOK) {
     515                vfs_exchange_end(vfs_phone);
    563516                free(pa);
    564517                async_wait_for(req, &rc_orig);
     
    568521                        return (int) rc_orig;
    569522        }
    570         rc = async_data_read_start(exch, stat, sizeof(struct stat));
    571         if (rc != EOK) {
    572                 vfs_exchange_end(exch);
     523        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
     524        if (rc != EOK) {
     525                vfs_exchange_end(vfs_phone);
    573526                free(pa);
    574527                async_wait_for(req, &rc_orig);
     
    578531                        return (int) rc_orig;
    579532        }
    580         vfs_exchange_end(exch);
     533        vfs_exchange_end(vfs_phone);
    581534        free(pa);
    582535        async_wait_for(req, &rc);
     
    639592                return ENOMEM;
    640593       
    641         async_exch_t *exch = vfs_exchange_begin();
    642        
    643         req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
    644         rc = async_data_write_start(exch, pa, pa_size);
    645         if (rc != EOK) {
    646                 vfs_exchange_end(exch);
     594        int vfs_phone = vfs_exchange_begin();
     595       
     596        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
     597        rc = async_data_write_start(vfs_phone, pa, pa_size);
     598        if (rc != EOK) {
     599                vfs_exchange_end(vfs_phone);
    647600                free(pa);
    648601
     
    655608                        return (int) rc_orig;
    656609        }
    657         vfs_exchange_end(exch);
     610        vfs_exchange_end(vfs_phone);
    658611        free(pa);
    659612        async_wait_for(req, &rc);
     
    670623        if (!pa)
    671624                return ENOMEM;
    672        
    673         async_exch_t *exch = vfs_exchange_begin();
    674        
    675         req = async_send_0(exch, VFS_IN_UNLINK, NULL);
    676         rc = async_data_write_start(exch, pa, pa_size);
    677         if (rc != EOK) {
    678                 vfs_exchange_end(exch);
     625
     626        int vfs_phone = vfs_exchange_begin();
     627       
     628        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
     629        rc = async_data_write_start(vfs_phone, pa, pa_size);
     630        if (rc != EOK) {
     631                vfs_exchange_end(vfs_phone);
    679632                free(pa);
    680633
     
    687640                        return (int) rc_orig;
    688641        }
    689         vfs_exchange_end(exch);
     642        vfs_exchange_end(vfs_phone);
    690643        free(pa);
    691644        async_wait_for(req, &rc);
     
    720673                return ENOMEM;
    721674        }
    722        
    723         async_exch_t *exch = vfs_exchange_begin();
    724        
    725         req = async_send_0(exch, VFS_IN_RENAME, NULL);
    726         rc = async_data_write_start(exch, olda, olda_size);
    727         if (rc != EOK) {
    728                 vfs_exchange_end(exch);
     675
     676        int vfs_phone = vfs_exchange_begin();
     677       
     678        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
     679        rc = async_data_write_start(vfs_phone, olda, olda_size);
     680        if (rc != EOK) {
     681                vfs_exchange_end(vfs_phone);
    729682                free(olda);
    730683                free(newa);
     
    735688                        return (int) rc_orig;
    736689        }
    737         rc = async_data_write_start(exch, newa, newa_size);
    738         if (rc != EOK) {
    739                 vfs_exchange_end(exch);
     690        rc = async_data_write_start(vfs_phone, newa, newa_size);
     691        if (rc != EOK) {
     692                vfs_exchange_end(vfs_phone);
    740693                free(olda);
    741694                free(newa);
     
    746699                        return (int) rc_orig;
    747700        }
    748         vfs_exchange_end(exch);
     701        vfs_exchange_end(vfs_phone);
    749702        free(olda);
    750703        free(newa);
     
    802755}
    803756
    804 async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
     757int fd_phone(int fildes)
    805758{
    806759        struct stat stat;
     760       
    807761        int rc = fstat(fildes, &stat);
    808         if (rc != 0) {
    809                 errno = rc;
    810                 return NULL;
    811         }
    812        
    813         if (!stat.device) {
    814                 errno = ENOENT;
    815                 return NULL;
    816         }
    817        
    818         return devmap_device_connect(mgmt, stat.device, 0);
     762        if (rc != 0)
     763                return rc;
     764       
     765        if (!stat.device)
     766                return -1;
     767       
     768        return devmap_device_connect(stat.device, 0);
    819769}
    820770
     
    822772{
    823773        struct stat stat;
    824         int rc = fstat(fildes, &stat);
     774        int rc;
     775
     776        rc = fstat(fildes, &stat);
    825777       
    826778        if (rc == EOK) {
     
    835787int dup2(int oldfd, int newfd)
    836788{
    837         async_exch_t *exch = vfs_exchange_begin();
     789        int vfs_phone = vfs_exchange_begin();
    838790       
    839791        sysarg_t ret;
    840         sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
    841        
    842         vfs_exchange_end(exch);
     792        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
     793       
     794        vfs_exchange_end(vfs_phone);
    843795       
    844796        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.