Ignore:
File:
1 edited

Legend:

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

    r89e780d r27b76ca  
    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 */
     71async_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 */
     89void 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       
     
    337329}
    338330
    339 int open_node(fdi_node_t *node, int oflag)
    340 {
    341         int vfs_phone = vfs_exchange_begin();
    342        
    343         ipc_call_t answer;
    344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
    345             node->devmap_handle, node->index, oflag, &answer);
    346        
    347         vfs_exchange_end(vfs_phone);
    348 
    349         sysarg_t rc;
    350         async_wait_for(req, &rc);
    351        
    352         if (rc != EOK)
    353                 return (int) rc;
    354        
    355         return (int) IPC_GET_ARG1(answer);
    356 }
    357 
    358331int close(int fildes)
    359332{
    360333        sysarg_t rc;
    361334       
    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;
     335        async_exch_t *exch = vfs_exchange_begin();
     336        rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes);
     337        vfs_exchange_end(exch);
     338       
     339        return (int) rc;
    369340}
    370341
     
    374345        ipc_call_t answer;
    375346        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(vfs_phone, (void *)buf, nbyte);
    381         if (rc != EOK) {
    382                 vfs_exchange_end(vfs_phone);
     347       
     348        async_exch_t *exch = vfs_exchange_begin();
     349       
     350        req = async_send_1(exch, VFS_IN_READ, fildes, &answer);
     351        rc = async_data_read_start(exch, (void *)buf, nbyte);
     352        if (rc != EOK) {
     353                vfs_exchange_end(exch);
    383354
    384355                sysarg_t rc_orig;
     
    390361                        return (ssize_t) rc_orig;
    391362        }
    392         vfs_exchange_end(vfs_phone);
     363        vfs_exchange_end(exch);
    393364        async_wait_for(req, &rc);
    394365        if (rc == EOK)
     
    403374        ipc_call_t answer;
    404375        aid_t req;
    405 
    406         int vfs_phone = vfs_exchange_begin();
    407        
    408         req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    409         rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    410         if (rc != EOK) {
    411                 vfs_exchange_end(vfs_phone);
     376       
     377        async_exch_t *exch = vfs_exchange_begin();
     378       
     379        req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer);
     380        rc = async_data_write_start(exch, (void *)buf, nbyte);
     381        if (rc != EOK) {
     382                vfs_exchange_end(exch);
    412383
    413384                sysarg_t rc_orig;
     
    419390                        return (ssize_t) rc_orig;
    420391        }
    421         vfs_exchange_end(vfs_phone);
     392        vfs_exchange_end(exch);
    422393        async_wait_for(req, &rc);
    423394        if (rc == EOK)
     
    427398}
    428399
     400/** Read entire buffer.
     401 *
     402 * In face of short reads this function continues reading until either
     403 * the entire buffer is read or no more data is available (at end of file).
     404 *
     405 * @param fildes        File descriptor
     406 * @param buf           Buffer, @a nbytes bytes long
     407 * @param nbytes        Number of bytes to read
     408 *
     409 * @return              On success, positive number of bytes read.
     410 *                      On failure, negative error code from read().
     411 */
     412ssize_t read_all(int fildes, void *buf, size_t nbyte)
     413{
     414        ssize_t cnt = 0;
     415        size_t nread = 0;
     416        uint8_t *bp = (uint8_t *) buf;
     417
     418        do {
     419                bp += cnt;
     420                nread += cnt;
     421                cnt = read(fildes, bp, nbyte - nread);
     422        } while (cnt > 0 && (nbyte - nread - cnt) > 0);
     423
     424        if (cnt < 0)
     425                return cnt;
     426
     427        return nread + cnt;
     428}
     429
     430/** Write entire buffer.
     431 *
     432 * This function fails if it cannot write exactly @a len bytes to the file.
     433 *
     434 * @param fildes        File descriptor
     435 * @param buf           Data, @a nbytes bytes long
     436 * @param nbytes        Number of bytes to write
     437 *
     438 * @return              EOK on error, return value from write() if writing
     439 *                      failed.
     440 */
     441ssize_t write_all(int fildes, const void *buf, size_t nbyte)
     442{
     443        ssize_t cnt = 0;
     444        ssize_t nwritten = 0;
     445        const uint8_t *bp = (uint8_t *) buf;
     446
     447        do {
     448                bp += cnt;
     449                nwritten += cnt;
     450                cnt = write(fildes, bp, nbyte - nwritten);
     451        } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
     452
     453        if (cnt < 0)
     454                return cnt;
     455
     456        if ((ssize_t)nbyte - nwritten - cnt > 0)
     457                return EIO;
     458
     459        return nbyte;
     460}
     461
    429462int fsync(int fildes)
    430463{
    431         int vfs_phone = vfs_exchange_begin();
    432        
    433         sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    434        
    435         vfs_exchange_end(vfs_phone);
     464        async_exch_t *exch = vfs_exchange_begin();
     465        sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
     466        vfs_exchange_end(exch);
    436467       
    437468        return (int) rc;
     
    440471off64_t lseek(int fildes, off64_t offset, int whence)
    441472{
    442         int vfs_phone = vfs_exchange_begin();
     473        async_exch_t *exch = vfs_exchange_begin();
    443474       
    444475        sysarg_t newoff_lo;
    445476        sysarg_t newoff_hi;
    446         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     477        sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes,
    447478            LOWER32(offset), UPPER32(offset), whence,
    448479            &newoff_lo, &newoff_hi);
    449480       
    450         vfs_exchange_end(vfs_phone);
     481        vfs_exchange_end(exch);
    451482       
    452483        if (rc != EOK)
     
    460491        sysarg_t rc;
    461492       
    462         int vfs_phone = vfs_exchange_begin();
    463        
    464         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     493        async_exch_t *exch = vfs_exchange_begin();
     494        rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes,
    465495            LOWER32(length), UPPER32(length));
    466         vfs_exchange_end(vfs_phone);
     496        vfs_exchange_end(exch);
    467497       
    468498        return (int) rc;
     
    473503        sysarg_t rc;
    474504        aid_t req;
    475 
    476         int vfs_phone = vfs_exchange_begin();
    477        
    478         req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    479         rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    480         if (rc != EOK) {
    481                 vfs_exchange_end(vfs_phone);
     505       
     506        async_exch_t *exch = vfs_exchange_begin();
     507       
     508        req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
     509        rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
     510        if (rc != EOK) {
     511                vfs_exchange_end(exch);
    482512
    483513                sysarg_t rc_orig;
     
    489519                        return (ssize_t) rc_orig;
    490520        }
    491         vfs_exchange_end(vfs_phone);
     521        vfs_exchange_end(exch);
    492522        async_wait_for(req, &rc);
    493523
     
    506536                return ENOMEM;
    507537       
    508         int vfs_phone = vfs_exchange_begin();
    509        
    510         req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    511         rc = async_data_write_start(vfs_phone, pa, pa_size);
    512         if (rc != EOK) {
    513                 vfs_exchange_end(vfs_phone);
     538        async_exch_t *exch = vfs_exchange_begin();
     539       
     540        req = async_send_0(exch, VFS_IN_STAT, NULL);
     541        rc = async_data_write_start(exch, pa, pa_size);
     542        if (rc != EOK) {
     543                vfs_exchange_end(exch);
    514544                free(pa);
    515545                async_wait_for(req, &rc_orig);
     
    519549                        return (int) rc_orig;
    520550        }
    521         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    522         if (rc != EOK) {
    523                 vfs_exchange_end(vfs_phone);
     551        rc = async_data_read_start(exch, stat, sizeof(struct stat));
     552        if (rc != EOK) {
     553                vfs_exchange_end(exch);
    524554                free(pa);
    525555                async_wait_for(req, &rc_orig);
     
    529559                        return (int) rc_orig;
    530560        }
    531         vfs_exchange_end(vfs_phone);
     561        vfs_exchange_end(exch);
    532562        free(pa);
    533563        async_wait_for(req, &rc);
     
    590620                return ENOMEM;
    591621       
    592         int vfs_phone = vfs_exchange_begin();
    593        
    594         req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    595         rc = async_data_write_start(vfs_phone, pa, pa_size);
    596         if (rc != EOK) {
    597                 vfs_exchange_end(vfs_phone);
     622        async_exch_t *exch = vfs_exchange_begin();
     623       
     624        req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
     625        rc = async_data_write_start(exch, pa, pa_size);
     626        if (rc != EOK) {
     627                vfs_exchange_end(exch);
    598628                free(pa);
    599629
     
    606636                        return (int) rc_orig;
    607637        }
    608         vfs_exchange_end(vfs_phone);
     638        vfs_exchange_end(exch);
    609639        free(pa);
    610640        async_wait_for(req, &rc);
     
    621651        if (!pa)
    622652                return ENOMEM;
    623 
    624         int vfs_phone = vfs_exchange_begin();
    625        
    626         req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    627         rc = async_data_write_start(vfs_phone, pa, pa_size);
    628         if (rc != EOK) {
    629                 vfs_exchange_end(vfs_phone);
     653       
     654        async_exch_t *exch = vfs_exchange_begin();
     655       
     656        req = async_send_0(exch, VFS_IN_UNLINK, NULL);
     657        rc = async_data_write_start(exch, pa, pa_size);
     658        if (rc != EOK) {
     659                vfs_exchange_end(exch);
    630660                free(pa);
    631661
     
    638668                        return (int) rc_orig;
    639669        }
    640         vfs_exchange_end(vfs_phone);
     670        vfs_exchange_end(exch);
    641671        free(pa);
    642672        async_wait_for(req, &rc);
     
    671701                return ENOMEM;
    672702        }
    673 
    674         int vfs_phone = vfs_exchange_begin();
    675        
    676         req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    677         rc = async_data_write_start(vfs_phone, olda, olda_size);
    678         if (rc != EOK) {
    679                 vfs_exchange_end(vfs_phone);
     703       
     704        async_exch_t *exch = vfs_exchange_begin();
     705       
     706        req = async_send_0(exch, VFS_IN_RENAME, NULL);
     707        rc = async_data_write_start(exch, olda, olda_size);
     708        if (rc != EOK) {
     709                vfs_exchange_end(exch);
    680710                free(olda);
    681711                free(newa);
     
    686716                        return (int) rc_orig;
    687717        }
    688         rc = async_data_write_start(vfs_phone, newa, newa_size);
    689         if (rc != EOK) {
    690                 vfs_exchange_end(vfs_phone);
     718        rc = async_data_write_start(exch, newa, newa_size);
     719        if (rc != EOK) {
     720                vfs_exchange_end(exch);
    691721                free(olda);
    692722                free(newa);
     
    697727                        return (int) rc_orig;
    698728        }
    699         vfs_exchange_end(vfs_phone);
     729        vfs_exchange_end(exch);
    700730        free(olda);
    701731        free(newa);
     
    753783}
    754784
    755 int fd_phone(int fildes)
     785async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
    756786{
    757787        struct stat stat;
    758         int rc;
    759 
    760         rc = fstat(fildes, &stat);
    761 
    762         if (!stat.device)
    763                 return -1;
    764        
    765         return devmap_device_connect(stat.device, 0);
    766 }
    767 
    768 int fd_node(int fildes, fdi_node_t *node)
    769 {
    770         struct stat stat;
    771         int rc;
    772 
    773         rc = fstat(fildes, &stat);
    774        
    775         if (rc == EOK) {
    776                 node->fs_handle = stat.fs_handle;
    777                 node->devmap_handle = stat.devmap_handle;
    778                 node->index = stat.index;
    779         }
    780        
    781         return rc;
     788        int rc = fstat(fildes, &stat);
     789        if (rc != 0) {
     790                errno = rc;
     791                return NULL;
     792        }
     793       
     794        if (!stat.device) {
     795                errno = ENOENT;
     796                return NULL;
     797        }
     798       
     799        return devmap_device_connect(mgmt, stat.device, 0);
    782800}
    783801
    784802int dup2(int oldfd, int newfd)
    785803{
    786         int vfs_phone = vfs_exchange_begin();
     804        async_exch_t *exch = vfs_exchange_begin();
    787805       
    788806        sysarg_t ret;
    789         sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    790        
    791         vfs_exchange_end(vfs_phone);
     807        sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
     808       
     809        vfs_exchange_end(exch);
    792810       
    793811        if (rc == EOK)
     
    797815}
    798816
     817int fd_wait(void)
     818{
     819        async_exch_t *exch = vfs_exchange_begin();
     820       
     821        sysarg_t ret;
     822        sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret);
     823       
     824        vfs_exchange_end(exch);
     825       
     826        if (rc == EOK)
     827                return (int) ret;
     828       
     829        return (int) rc;
     830}
     831
    799832/** @}
    800833 */
Note: See TracChangeset for help on using the changeset viewer.