Ignore:
File:
1 edited

Legend:

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

    r79ae36dd 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)
     
    419431int fsync(int fildes)
    420432{
    421         async_exch_t *exch = vfs_exchange_begin();
    422         sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes);
    423         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);
    424438       
    425439        return (int) rc;
     
    428442off64_t lseek(int fildes, off64_t offset, int whence)
    429443{
    430         async_exch_t *exch = vfs_exchange_begin();
     444        int vfs_phone = vfs_exchange_begin();
    431445       
    432446        sysarg_t newoff_lo;
    433447        sysarg_t newoff_hi;
    434         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,
    435449            LOWER32(offset), UPPER32(offset), whence,
    436450            &newoff_lo, &newoff_hi);
    437451       
    438         vfs_exchange_end(exch);
     452        vfs_exchange_end(vfs_phone);
    439453       
    440454        if (rc != EOK)
     
    448462        sysarg_t rc;
    449463       
    450         async_exch_t *exch = vfs_exchange_begin();
    451         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,
    452467            LOWER32(length), UPPER32(length));
    453         vfs_exchange_end(exch);
     468        vfs_exchange_end(vfs_phone);
    454469       
    455470        return (int) rc;
     
    460475        sysarg_t rc;
    461476        aid_t req;
    462        
    463         async_exch_t *exch = vfs_exchange_begin();
    464        
    465         req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL);
    466         rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat));
    467         if (rc != EOK) {
    468                 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);
    469484
    470485                sysarg_t rc_orig;
     
    476491                        return (ssize_t) rc_orig;
    477492        }
    478         vfs_exchange_end(exch);
     493        vfs_exchange_end(vfs_phone);
    479494        async_wait_for(req, &rc);
    480495
     
    493508                return ENOMEM;
    494509       
    495         async_exch_t *exch = vfs_exchange_begin();
    496        
    497         req = async_send_0(exch, VFS_IN_STAT, NULL);
    498         rc = async_data_write_start(exch, pa, pa_size);
    499         if (rc != EOK) {
    500                 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);
    501516                free(pa);
    502517                async_wait_for(req, &rc_orig);
     
    506521                        return (int) rc_orig;
    507522        }
    508         rc = async_data_read_start(exch, stat, sizeof(struct stat));
    509         if (rc != EOK) {
    510                 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);
    511526                free(pa);
    512527                async_wait_for(req, &rc_orig);
     
    516531                        return (int) rc_orig;
    517532        }
    518         vfs_exchange_end(exch);
     533        vfs_exchange_end(vfs_phone);
    519534        free(pa);
    520535        async_wait_for(req, &rc);
     
    577592                return ENOMEM;
    578593       
    579         async_exch_t *exch = vfs_exchange_begin();
    580        
    581         req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
    582         rc = async_data_write_start(exch, pa, pa_size);
    583         if (rc != EOK) {
    584                 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);
    585600                free(pa);
    586601
     
    593608                        return (int) rc_orig;
    594609        }
    595         vfs_exchange_end(exch);
     610        vfs_exchange_end(vfs_phone);
    596611        free(pa);
    597612        async_wait_for(req, &rc);
     
    608623        if (!pa)
    609624                return ENOMEM;
    610        
    611         async_exch_t *exch = vfs_exchange_begin();
    612        
    613         req = async_send_0(exch, VFS_IN_UNLINK, NULL);
    614         rc = async_data_write_start(exch, pa, pa_size);
    615         if (rc != EOK) {
    616                 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);
    617632                free(pa);
    618633
     
    625640                        return (int) rc_orig;
    626641        }
    627         vfs_exchange_end(exch);
     642        vfs_exchange_end(vfs_phone);
    628643        free(pa);
    629644        async_wait_for(req, &rc);
     
    658673                return ENOMEM;
    659674        }
    660        
    661         async_exch_t *exch = vfs_exchange_begin();
    662        
    663         req = async_send_0(exch, VFS_IN_RENAME, NULL);
    664         rc = async_data_write_start(exch, olda, olda_size);
    665         if (rc != EOK) {
    666                 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);
    667682                free(olda);
    668683                free(newa);
     
    673688                        return (int) rc_orig;
    674689        }
    675         rc = async_data_write_start(exch, newa, newa_size);
    676         if (rc != EOK) {
    677                 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);
    678693                free(olda);
    679694                free(newa);
     
    684699                        return (int) rc_orig;
    685700        }
    686         vfs_exchange_end(exch);
     701        vfs_exchange_end(vfs_phone);
    687702        free(olda);
    688703        free(newa);
     
    740755}
    741756
    742 async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes)
     757int fd_phone(int fildes)
    743758{
    744759        struct stat stat;
     760       
    745761        int rc = fstat(fildes, &stat);
    746         if (rc != 0) {
    747                 errno = rc;
    748                 return NULL;
    749         }
    750        
    751         if (!stat.device) {
    752                 errno = ENOENT;
    753                 return NULL;
    754         }
    755        
    756         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);
    757769}
    758770
     
    760772{
    761773        struct stat stat;
    762         int rc = fstat(fildes, &stat);
     774        int rc;
     775
     776        rc = fstat(fildes, &stat);
    763777       
    764778        if (rc == EOK) {
     
    773787int dup2(int oldfd, int newfd)
    774788{
    775         async_exch_t *exch = vfs_exchange_begin();
     789        int vfs_phone = vfs_exchange_begin();
    776790       
    777791        sysarg_t ret;
    778         sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret);
    779        
    780         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);
    781795       
    782796        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.