Ignore:
File:
1 edited

Legend:

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

    r8e80d3f r8fd04ba9  
    3333 */
    3434
     35#include <vfs/canonify.h>
    3536#include <vfs/vfs.h>
    36 #include <vfs/canonify.h>
     37#include <vfs/vfs_sess.h>
    3738#include <macros.h>
    3839#include <stdlib.h>
     
    4445#include <sys/types.h>
    4546#include <ipc/services.h>
    46 #include <ipc/ns.h>
     47#include <ns.h>
    4748#include <async.h>
    4849#include <fibril_synch.h>
     
    5455#include <ipc/devmap.h>
    5556
    56 static async_sess_t vfs_session;
    57 
    58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    59 static int vfs_phone = -1;
     57static FIBRIL_MUTEX_INITIALIZE(vfs_mutex);
     58static async_sess_t *vfs_sess = NULL;
    6059
    6160static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     
    6564static size_t cwd_size = 0;
    6665
     66/** Start an async exchange on the VFS session.
     67 *
     68 * @return New exchange.
     69 *
     70 */
     71static 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 */
     89static void vfs_exchange_end(async_exch_t *exch)
     90{
     91        async_exchange_end(exch);
     92}
     93
    6794char *absolutize(const char *path, size_t *retlen)
    6895{
    6996        char *ncwd_path;
    7097        char *ncwd_path_nc;
    71         size_t total_size;
    7298
    7399        fibril_mutex_lock(&cwd_mutex);
     
    78104                        return NULL;
    79105                }
    80                 total_size = cwd_size + 1 + size + 1;
    81                 ncwd_path_nc = malloc(total_size);
     106                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    82107                if (!ncwd_path_nc) {
    83108                        fibril_mutex_unlock(&cwd_mutex);
    84109                        return NULL;
    85110                }
    86                 str_cpy(ncwd_path_nc, total_size, cwd_path);
     111                str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
    87112                ncwd_path_nc[cwd_size] = '/';
    88113                ncwd_path_nc[cwd_size + 1] = '\0';
    89114        } else {
    90                 total_size = size + 1;
    91                 ncwd_path_nc = malloc(total_size);
     115                ncwd_path_nc = malloc(size + 1);
    92116                if (!ncwd_path_nc) {
    93117                        fibril_mutex_unlock(&cwd_mutex);
     
    96120                ncwd_path_nc[0] = '\0';
    97121        }
    98         str_append(ncwd_path_nc, total_size, path);
     122        str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
    99123        ncwd_path = canonify(ncwd_path_nc, retlen);
    100124        if (!ncwd_path) {
     
    118142}
    119143
    120 /** Connect to VFS service and create session. */
    121 static 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  */
    133 static 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  */
    147 static void vfs_exchange_end(int phone)
    148 {
    149         async_exchange_end(&vfs_session, phone);
    150 }
    151 
    152144int mount(const char *fs_name, const char *mp, const char *fqdn,
    153145    const char *opts, unsigned int flags)
     
    186178        }
    187179       
    188         int vfs_phone = vfs_exchange_begin();
     180        async_exch_t *exch = vfs_exchange_begin();
    189181
    190182        sysarg_t rc_orig;
    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);
     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);
    195187                free(mpa);
    196188                async_wait_for(req, &rc_orig);
     
    205197        }
    206198       
    207         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    208         if (rc != EOK) {
    209                 vfs_exchange_end(vfs_phone);
     199        rc = async_data_write_start(exch, (void *) opts, str_size(opts));
     200        if (rc != EOK) {
     201                vfs_exchange_end(exch);
    210202                free(mpa);
    211203                async_wait_for(req, &rc_orig);
     
    220212        }
    221213       
    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);
     214        rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
     215        if (rc != EOK) {
     216                vfs_exchange_end(exch);
    225217                free(mpa);
    226218                async_wait_for(req, &rc_orig);
     
    236228       
    237229        /* Ask VFS whether it likes fs_name. */
    238         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    239         if (rc != EOK) {
    240                 vfs_exchange_end(vfs_phone);
     230        rc = async_req_0_0(exch, VFS_IN_PING);
     231        if (rc != EOK) {
     232                vfs_exchange_end(exch);
    241233                free(mpa);
    242234                async_wait_for(req, &rc_orig);
     
    251243        }
    252244       
    253         vfs_exchange_end(vfs_phone);
     245        vfs_exchange_end(exch);
    254246        free(mpa);
    255247        async_wait_for(req, &rc);
     
    273265                return ENOMEM;
    274266       
    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);
     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);
    281273                free(mpa);
    282274                async_wait_for(req, &rc_orig);
     
    288280       
    289281
    290         vfs_exchange_end(vfs_phone);
     282        vfs_exchange_end(exch);
    291283        free(mpa);
    292284        async_wait_for(req, &rc);
     
    297289static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    298290{
    299         int vfs_phone = vfs_exchange_begin();
     291        async_exch_t *exch = vfs_exchange_begin();
    300292       
    301293        ipc_call_t answer;
    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);
     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);
    307299
    308300                sysarg_t rc_orig;
     
    315307        }
    316308       
    317         vfs_exchange_end(vfs_phone);
     309        vfs_exchange_end(exch);
    318310        async_wait_for(req, &rc);
    319311       
     
    339331int open_node(fdi_node_t *node, int oflag)
    340332{
    341         int vfs_phone = vfs_exchange_begin();
     333        async_exch_t *exch = vfs_exchange_begin();
    342334       
    343335        ipc_call_t answer;
    344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
     336        aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,
    345337            node->devmap_handle, node->index, oflag, &answer);
    346338       
    347         vfs_exchange_end(vfs_phone);
     339        vfs_exchange_end(exch);
    348340
    349341        sysarg_t rc;
     
    360352        sysarg_t rc;
    361353       
    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;
     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;
    369359}
    370360
     
    374364        ipc_call_t answer;
    375365        aid_t req;
    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);
     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);
    384373
    385374                sysarg_t rc_orig;
     
    391380                        return (ssize_t) rc_orig;
    392381        }
    393         vfs_exchange_end(vfs_phone);
     382        vfs_exchange_end(exch);
    394383        async_wait_for(req, &rc);
    395384        if (rc == EOK)
     
    404393        ipc_call_t answer;
    405394        aid_t req;
    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);
     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);
    414402
    415403                sysarg_t rc_orig;
     
    421409                        return (ssize_t) rc_orig;
    422410        }
    423         vfs_exchange_end(vfs_phone);
     411        vfs_exchange_end(exch);
    424412        async_wait_for(req, &rc);
    425413        if (rc == EOK)
     
    429417}
    430418
     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 */
     431ssize_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 */
     460ssize_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
    431481int fsync(int fildes)
    432482{
    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);
     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);
    438486       
    439487        return (int) rc;
     
    442490off64_t lseek(int fildes, off64_t offset, int whence)
    443491{
    444         int vfs_phone = vfs_exchange_begin();
     492        async_exch_t *exch = vfs_exchange_begin();
    445493       
    446494        sysarg_t newoff_lo;
    447495        sysarg_t newoff_hi;
    448         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     496        sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
    449497            LOWER32(offset), UPPER32(offset), whence,
    450498            &newoff_lo, &newoff_hi);
    451499       
    452         vfs_exchange_end(vfs_phone);
     500        vfs_exchange_end(exch);
    453501       
    454502        if (rc != EOK)
     
    462510        sysarg_t rc;
    463511       
    464         int vfs_phone = vfs_exchange_begin();
    465        
    466         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     512        async_exch_t *exch = vfs_exchange_begin();
     513        rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
    467514            LOWER32(length), UPPER32(length));
    468         vfs_exchange_end(vfs_phone);
     515        vfs_exchange_end(exch);
    469516       
    470517        return (int) rc;
     
    475522        sysarg_t rc;
    476523        aid_t req;
    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);
     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);
    484531
    485532                sysarg_t rc_orig;
     
    491538                        return (ssize_t) rc_orig;
    492539        }
    493         vfs_exchange_end(vfs_phone);
     540        vfs_exchange_end(exch);
    494541        async_wait_for(req, &rc);
    495542
     
    508555                return ENOMEM;
    509556       
    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);
     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);
    516563                free(pa);
    517564                async_wait_for(req, &rc_orig);
     
    521568                        return (int) rc_orig;
    522569        }
    523         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    524         if (rc != EOK) {
    525                 vfs_exchange_end(vfs_phone);
     570        rc = async_data_read_start(exch, stat, sizeof(struct stat));
     571        if (rc != EOK) {
     572                vfs_exchange_end(exch);
    526573                free(pa);
    527574                async_wait_for(req, &rc_orig);
     
    531578                        return (int) rc_orig;
    532579        }
    533         vfs_exchange_end(vfs_phone);
     580        vfs_exchange_end(exch);
    534581        free(pa);
    535582        async_wait_for(req, &rc);
     
    592639                return ENOMEM;
    593640       
    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);
     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);
    600647                free(pa);
    601648
     
    608655                        return (int) rc_orig;
    609656        }
    610         vfs_exchange_end(vfs_phone);
     657        vfs_exchange_end(exch);
    611658        free(pa);
    612659        async_wait_for(req, &rc);
     
    623670        if (!pa)
    624671                return ENOMEM;
    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);
     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);
    632679                free(pa);
    633680
     
    640687                        return (int) rc_orig;
    641688        }
    642         vfs_exchange_end(vfs_phone);
     689        vfs_exchange_end(exch);
    643690        free(pa);
    644691        async_wait_for(req, &rc);
     
    673720                return ENOMEM;
    674721        }
    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);
     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);
    682729                free(olda);
    683730                free(newa);
     
    688735                        return (int) rc_orig;
    689736        }
    690         rc = async_data_write_start(vfs_phone, newa, newa_size);
    691         if (rc != EOK) {
    692                 vfs_exchange_end(vfs_phone);
     737        rc = async_data_write_start(exch, newa, newa_size);
     738        if (rc != EOK) {
     739                vfs_exchange_end(exch);
    693740                free(olda);
    694741                free(newa);
     
    699746                        return (int) rc_orig;
    700747        }
    701         vfs_exchange_end(vfs_phone);
     748        vfs_exchange_end(exch);
    702749        free(olda);
    703750        free(newa);
     
    755802}
    756803
    757 int fd_phone(int fildes)
     804async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
    758805{
    759806        struct stat stat;
    760        
    761807        int rc = fstat(fildes, &stat);
    762         if (rc != 0)
    763                 return rc;
    764        
    765         if (!stat.device)
    766                 return -1;
    767        
    768         return devmap_device_connect(stat.device, 0);
     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);
    769819}
    770820
     
    772822{
    773823        struct stat stat;
    774         int rc;
    775 
    776         rc = fstat(fildes, &stat);
     824        int rc = fstat(fildes, &stat);
    777825       
    778826        if (rc == EOK) {
     
    787835int dup2(int oldfd, int newfd)
    788836{
    789         int vfs_phone = vfs_exchange_begin();
     837        async_exch_t *exch = vfs_exchange_begin();
    790838       
    791839        sysarg_t ret;
    792         sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    793        
    794         vfs_exchange_end(vfs_phone);
     840        sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
     841       
     842        vfs_exchange_end(exch);
    795843       
    796844        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.