Changeset 5126f80 in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2017-03-08T11:42:17Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0d35511
Parents:
a737667e
git-author:
Jiri Zarevucky <zarevucky.jiri@…> (2017-03-08 11:42:17)
git-committer:
Jakub Jermar <jakub@…> (2017-03-08 11:42:17)
Message:

Merge from lp:~zarevucky-jiri/helenos/vfs-2.5/ revision 1946

Original commit messages:

1946: Jiri Zarevucky 2013-08-06 Relativize mount, add root handle to libc and remove root from VFS server. This wraps up the "relativization" phase.

Breakage:

  • Dynamic builds broken
  • Mount table lookups by name
File:
1 edited

Legend:

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

    ra737667e r5126f80  
    6565static size_t cwd_size = 0;
    6666
     67static FIBRIL_MUTEX_INITIALIZE(root_mutex);
     68static int root_fd = -1;
     69
     70int vfs_root(void)
     71{
     72        fibril_mutex_lock(&root_mutex);
     73        int r;
     74        if (root_fd < 0) {
     75                r = ENOENT;
     76        } else {
     77                r = vfs_clone(root_fd, true);
     78        }
     79        fibril_mutex_unlock(&root_mutex);
     80        return r;
     81}
     82
     83void vfs_root_set(int nroot)
     84{
     85        fibril_mutex_lock(&root_mutex);
     86        if (root_fd >= 0) {
     87                close(root_fd);
     88        }
     89        root_fd = vfs_clone(nroot, true);
     90        fibril_mutex_unlock(&root_mutex);
     91}
     92
    6793/** Start an async exchange on the VFS session.
    6894 *
     
    116142}
    117143
    118 int vfs_lookup(const char *path)
     144int vfs_lookup(const char *path, int flags)
    119145{
    120146        size_t size;
     
    123149                return ENOMEM;
    124150        }
    125         int rc = _vfs_walk(-1, p, 0);
     151        int root = vfs_root();
     152        if (root == -1) {
     153                free(p);
     154                return ENOENT;
     155        }
     156        int rc = _vfs_walk(root, p, flags);
     157        close(root);
    126158        free(p);
    127159        return rc;
     
    187219}
    188220
    189 int vfs_mount(const char *fs_name, const char *mp, const char *fqsn,
     221int vfs_mount(int mp, const char *fs_name, service_id_t serv, const char *opts,
     222unsigned int flags, unsigned int instance, int *mountedfd)
     223{
     224        sysarg_t rc, rc1;
     225       
     226        if (!mountedfd) {
     227                flags |= VFS_MOUNT_NO_REF;
     228        }
     229        if (mp < 0) {
     230                flags |= VFS_MOUNT_CONNECT_ONLY;
     231        }
     232       
     233        ipc_call_t answer;
     234        async_exch_t *exch = vfs_exchange_begin();
     235        aid_t req = async_send_4(exch, VFS_IN_MOUNT, mp, serv, flags, instance, &answer);
     236
     237        rc1 = async_data_write_start(exch, (void *) opts, str_size(opts));
     238       
     239        if (rc1 == EOK) {
     240                rc1 = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
     241        }
     242
     243        vfs_exchange_end(exch);
     244
     245        async_wait_for(req, &rc);
     246
     247        if (mountedfd) {
     248                *mountedfd = (int) IPC_GET_ARG1(answer);
     249        }
     250       
     251        if (rc != EOK) {
     252                return rc;
     253        }
     254        return rc1;
     255}
     256
     257int vfs_unmount(int mp)
     258{
     259        async_exch_t *exch = vfs_exchange_begin();
     260        int rc = async_req_1_0(exch, VFS_IN_UNMOUNT, mp);
     261        vfs_exchange_end(exch);
     262        return rc;
     263}
     264
     265int mount(const char *fs_name, const char *mp, const char *fqsn,
    190266    const char *opts, unsigned int flags, unsigned int instance)
    191267{
     
    205281        }
    206282       
     283        if (flags & IPC_FLAG_BLOCKING) {
     284                flags = VFS_MOUNT_BLOCKING;
     285        } else {
     286                flags = 0;
     287        }
     288       
    207289        service_id_t service_id;
    208290        int res = loc_service_get_id(fqsn, &service_id, flags);
     
    223305        }
    224306       
    225         async_exch_t *exch = vfs_exchange_begin();
    226 
    227         sysarg_t rc_orig;
    228         aid_t req = async_send_3(exch, VFS_IN_MOUNT, service_id, flags,
    229             instance, NULL);
    230         sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size);
    231         if (rc != EOK) {
    232                 vfs_exchange_end(exch);
    233                 free(mpa);
    234                 async_wait_for(req, &rc_orig);
     307        fibril_mutex_lock(&root_mutex);
     308       
     309        int rc;
     310       
     311        if (str_cmp(mpa, "/") == 0) {
     312                /* Mounting root. */
    235313               
    236                 if (null_id != -1)
    237                         loc_null_destroy(null_id);
     314                if (root_fd >= 0) {
     315                        fibril_mutex_unlock(&root_mutex);
     316                        if (null_id != -1) {
     317                                loc_null_destroy(null_id);
     318                        }
     319                        return EBUSY;
     320                }
    238321               
    239                 if (rc_orig == EOK)
    240                         return (int) rc;
    241                 else
    242                         return (int) rc_orig;
    243         }
    244        
    245         rc = async_data_write_start(exch, (void *) opts, str_size(opts));
    246         if (rc != EOK) {
    247                 vfs_exchange_end(exch);
    248                 free(mpa);
    249                 async_wait_for(req, &rc_orig);
     322                int root;
     323                rc = vfs_mount(-1, fs_name, service_id, opts, flags, instance, &root);
     324                if (rc == EOK) {
     325                        root_fd = root;
     326                }
     327        } else {
     328                if (root_fd < 0) {
     329                        fibril_mutex_unlock(&root_mutex);
     330                        if (null_id != -1) {
     331                                loc_null_destroy(null_id);
     332                        }
     333                        return EINVAL;
     334                }
    250335               
    251                 if (null_id != -1)
    252                         loc_null_destroy(null_id);
    253                
    254                 if (rc_orig == EOK)
    255                         return (int) rc;
    256                 else
    257                         return (int) rc_orig;
    258         }
    259        
    260         rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name));
    261         if (rc != EOK) {
    262                 vfs_exchange_end(exch);
    263                 free(mpa);
    264                 async_wait_for(req, &rc_orig);
    265                
    266                 if (null_id != -1)
    267                         loc_null_destroy(null_id);
    268                
    269                 if (rc_orig == EOK)
    270                         return (int) rc;
    271                 else
    272                         return (int) rc_orig;
    273         }
    274        
    275         vfs_exchange_end(exch);
    276         free(mpa);
    277         async_wait_for(req, &rc);
     336                int mpfd = _vfs_walk(root_fd, mpa, WALK_DIRECTORY);
     337                if (mpfd >= 0) {
     338                        rc = vfs_mount(mpfd, fs_name, service_id, opts, flags, instance, NULL);
     339                        close(mpfd);
     340                } else {
     341                        rc = mpfd;
     342                }
     343        }
     344       
     345        fibril_mutex_unlock(&root_mutex);
    278346       
    279347        if ((rc != EOK) && (null_id != -1))
     
    283351}
    284352
    285 int vfs_unmount(const char *mp)
    286 {
    287         sysarg_t rc;
    288         sysarg_t rc_orig;
    289         aid_t req;
    290         size_t mpa_size;
    291         char *mpa;
    292        
    293         mpa = vfs_absolutize(mp, &mpa_size);
    294         if (mpa == NULL)
    295                 return ENOMEM;
    296        
    297         async_exch_t *exch = vfs_exchange_begin();
    298        
    299         req = async_send_0(exch, VFS_IN_UNMOUNT, NULL);
    300         rc = async_data_write_start(exch, (void *) mpa, mpa_size);
    301         if (rc != EOK) {
    302                 vfs_exchange_end(exch);
    303                 free(mpa);
    304                 async_wait_for(req, &rc_orig);
    305                 if (rc_orig == EOK)
    306                         return (int) rc;
    307                 else
    308                         return (int) rc_orig;
    309         }
    310        
    311 
    312         vfs_exchange_end(exch);
    313         free(mpa);
    314         async_wait_for(req, &rc);
    315        
    316         return (int) rc;
     353int unmount(const char *mpp)
     354{
     355        int mp = vfs_lookup(mpp, WALK_MOUNT_POINT | WALK_DIRECTORY);
     356        if (mp < 0) {
     357                return mp;
     358        }
     359       
     360        int rc = vfs_unmount(mp);
     361        close(mp);
     362        return rc;
    317363}
    318364
     
    348394        assert((((oflag & O_RDONLY) != 0) + ((oflag & O_WRONLY) != 0) + ((oflag & O_RDWR) != 0)) == 1);
    349395       
    350         size_t abs_size;
    351         char *abs = vfs_absolutize(path, &abs_size);
    352         if (!abs) {
    353                 return ENOMEM;
    354         }
    355        
    356         int ret = _vfs_walk(-1, abs, walk_flags(oflag) | WALK_REGULAR);
     396        int ret = vfs_lookup(path, walk_flags(oflag) | WALK_REGULAR);
    357397        if (ret < 0) {
    358398                return ret;
     
    680720int stat(const char *path, struct stat *stat)
    681721{
    682         size_t pa_size;
    683         char *pa = vfs_absolutize(path, &pa_size);
    684         if (!pa) {
    685                 return ENOMEM;
    686         }
    687        
    688         int fd = _vfs_walk(-1, pa, 0);
     722        int fd = vfs_lookup(path, 0);
    689723        if (fd < 0) {
    690724                return fd;
     
    710744        }
    711745       
    712         size_t abs_size;
    713         char *abs = vfs_absolutize(dirname, &abs_size);
    714         if (abs == NULL) {
    715                 free(dirp);
    716                 errno = ENOMEM;
    717                 return NULL;
    718         }
    719        
    720         int ret = _vfs_walk(-1, abs, WALK_DIRECTORY);
    721         free(abs);
    722        
    723         if (ret < EOK) {
     746        int ret = vfs_lookup(dirname, WALK_DIRECTORY);
     747        if (ret < 0) {
    724748                free(dirp);
    725749                errno = ret;
     
    793817int mkdir(const char *path, mode_t mode)
    794818{
     819        int ret = vfs_lookup(path, WALK_MUST_CREATE | WALK_DIRECTORY);
     820        if (ret < 0) {
     821                return ret;
     822        }
     823       
     824        close(ret);
     825        return EOK;
     826}
     827
     828static int _vfs_unlink2(int parent, const char *path, int expect, int wflag)
     829{
     830        sysarg_t rc;
     831        aid_t req;
     832       
     833        async_exch_t *exch = vfs_exchange_begin();
     834       
     835        req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL);
     836        rc = async_data_write_start(exch, path, str_size(path));
     837       
     838        vfs_exchange_end(exch);
     839       
     840        sysarg_t rc_orig;
     841        async_wait_for(req, &rc_orig);
     842       
     843        if (rc_orig != EOK) {
     844                return (int) rc_orig;
     845        }
     846        return rc;
     847}
     848
     849/** Unlink file or directory.
     850 *
     851 * @param path Path
     852 * @return EOk on success, error code on error
     853 */
     854int unlink(const char *path)
     855{
    795856        size_t pa_size;
    796857        char *pa = vfs_absolutize(path, &pa_size);
     
    799860        }
    800861       
    801         int ret = _vfs_walk(-1, pa, WALK_MUST_CREATE | WALK_DIRECTORY);
    802         if (ret < 0) {
    803                 return ret;
    804         }
    805        
    806         close(ret);
    807         return EOK;
    808 }
    809 
    810 static int _vfs_unlink2(int parent, const char *path, int expect, int wflag)
    811 {
    812         sysarg_t rc;
    813         aid_t req;
    814        
    815         async_exch_t *exch = vfs_exchange_begin();
    816        
    817         req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL);
    818         rc = async_data_write_start(exch, path, str_size(path));
    819        
    820         vfs_exchange_end(exch);
    821        
    822         sysarg_t rc_orig;
    823         async_wait_for(req, &rc_orig);
    824        
    825         if (rc_orig != EOK) {
    826                 return (int) rc_orig;
    827         }
     862        int root = vfs_root();
     863        if (root < 0) {
     864                free(pa);
     865                return ENOENT;
     866        }
     867       
     868        int rc = _vfs_unlink2(root, pa, -1, 0);
     869       
     870        free(pa);
     871        close(root);
    828872        return rc;
    829873}
    830874
    831 /** Unlink file or directory.
     875/** Remove empty directory.
    832876 *
    833877 * @param path Path
    834  * @return EOk on success, error code on error
    835  */
    836 int unlink(const char *path)
     878 * @return 0 on success. On error returns -1 and sets errno.
     879 */
     880int rmdir(const char *path)
    837881{
    838882        size_t pa_size;
     
    842886        }
    843887       
    844         return _vfs_unlink2(-1, pa, -1, 0);
    845 }
    846 
    847 /** Remove empty directory.
    848  *
    849  * @param path Path
    850  * @return 0 on success. On error returns -1 and sets errno.
    851  */
    852 int rmdir(const char *path)
    853 {
    854         size_t pa_size;
    855         char *pa = vfs_absolutize(path, &pa_size);
    856         if (!pa) {
    857                 return ENOMEM;
    858         }
    859        
    860         return _vfs_unlink2(-1, pa, -1, WALK_DIRECTORY);
     888        int root = vfs_root();
     889        if (root < 0) {
     890                free(pa);
     891                return ENOENT;
     892        }
     893       
     894        int rc = _vfs_unlink2(root, pa, -1, WALK_DIRECTORY);
     895       
     896        free(pa);
     897        close(root);
     898        return rc;
    861899}
    862900
     
    890928       
    891929        async_exch_t *exch = vfs_exchange_begin();
    892        
    893         req = async_send_1(exch, VFS_IN_RENAME, -1, NULL);
     930        int root = vfs_root();
     931        if (root < 0) {
     932                free(olda);
     933                free(newa);
     934                return ENOENT;
     935        }
     936       
     937        req = async_send_1(exch, VFS_IN_RENAME, root, NULL);
    894938        rc = async_data_write_start(exch, olda, olda_size);
    895939        if (rc != EOK) {
     
    897941                free(olda);
    898942                free(newa);
     943                close(root);
    899944                async_wait_for(req, &rc_orig);
    900945                if (rc_orig != EOK)
     
    911956                free(olda);
    912957                free(newa);
     958                close(root);
    913959                async_wait_for(req, &rc_orig);
    914960                if (rc_orig != EOK)
     
    923969        free(olda);
    924970        free(newa);
     971        close(root);
    925972        async_wait_for(req, &rc);
    926973
     
    9551002                return ENOMEM;
    9561003       
    957         int fd = _vfs_walk(-1, abs, WALK_DIRECTORY);
     1004        int fd = vfs_lookup(abs, WALK_DIRECTORY);
    9581005        if (fd < 0) {
    9591006                free(abs);
     
    9641011        fibril_mutex_lock(&cwd_mutex);
    9651012       
    966         if (cwd_fd >= 0)
     1013        if (cwd_fd >= 0) {
    9671014                close(cwd_fd);
    968        
    969         if (cwd_path)
     1015        }
     1016       
     1017        if (cwd_path) {
    9701018                free(cwd_path);
     1019        }
    9711020       
    9721021        cwd_fd = fd;
     
    11241173int statfs(const char *path, struct statfs *st)
    11251174{
    1126         size_t pa_size;
    1127         char *pa = vfs_absolutize(path, &pa_size);
    1128         if (!pa) {
    1129                 errno = ENOMEM;
    1130                 return -1;
    1131         }
    1132        
    1133         int fd = _vfs_walk(-1, pa, 0);
     1175        int fd = vfs_lookup(path, 0);
    11341176        if (fd < 0) {
    1135                 free(pa);
    11361177                errno = fd;
    11371178                return -1;
    11381179        }
    1139 
    1140         free(pa);
    11411180       
    11421181        sysarg_t rc, ret;
Note: See TracChangeset for help on using the changeset viewer.