Changeset 5126f80 in mainline


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
Location:
uspace
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/mount/mount.c

    ra737667e r5126f80  
    151151                mopts = t_argv[4];
    152152
    153         rc = vfs_mount(t_argv[1], t_argv[2], dev, mopts, 0, instance);
     153        rc = mount(t_argv[1], t_argv[2], dev, mopts, 0, instance);
    154154        if (rc != EOK) {
    155155                printf("Unable to mount %s filesystem to %s on %s (rc=%s)\n",
  • uspace/app/bdsh/cmds/modules/unmount/unmount.c

    ra737667e r5126f80  
    6666        }
    6767
    68         rc = vfs_unmount(argv[1]);
     68        rc = unmount(argv[1]);
    6969        if (rc != EOK) {
    7070                printf("Unable to unmount %s (rc=%d)\n", argv[1], rc);
  • uspace/app/init/init.c

    ra737667e r5126f80  
    127127                opts = "restore";
    128128       
    129         int rc = vfs_mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts,
     129        int rc = mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts,
    130130            IPC_FLAG_BLOCKING, 0);
    131131        return mount_report("Root filesystem", ROOT_MOUNT_POINT, fstype,
     
    144144static bool mount_locfs(void)
    145145{
    146         int rc = vfs_mount(LOCFS_FS_TYPE, LOCFS_MOUNT_POINT, "", "",
     146        int rc = mount(LOCFS_FS_TYPE, LOCFS_MOUNT_POINT, "", "",
    147147            IPC_FLAG_BLOCKING, 0);
    148148        return mount_report("Location service filesystem", LOCFS_MOUNT_POINT,
     
    300300static bool mount_tmpfs(void)
    301301{
    302         int rc = vfs_mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0, 0);
     302        int rc = mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0, 0);
    303303        return mount_report("Temporary filesystem", TMPFS_MOUNT_POINT,
    304304            TMPFS_FS_TYPE, NULL, rc);
  • uspace/app/sysinst/sysinst.c

    ra737667e r5126f80  
    180180
    181181        printf("sysinst_fs_mount(): mount filesystem\n");
    182         rc = vfs_mount(FS_TYPE, MOUNT_POINT, dev, "", 0, 0);
     182        rc = mount(FS_TYPE, MOUNT_POINT, dev, "", 0, 0);
    183183        if (rc != EOK)
    184184                return rc;
     
    219219
    220220        printf("sysinst_copy_boot_files(): mount CD filesystem\n");
    221         rc = vfs_mount(CD_FS_TYPE, CD_MOUNT_POINT, CD_DEV, "", 0, 0);
     221        rc = mount(CD_FS_TYPE, CD_MOUNT_POINT, CD_DEV, "", 0, 0);
    222222        if (rc != EOK)
    223223                return rc;
     
    229229
    230230        printf("sysinst_copy_boot_files(): unmount %s\n", MOUNT_POINT);
    231         rc = vfs_unmount(MOUNT_POINT);
     231        rc = unmount(MOUNT_POINT);
    232232        if (rc != EOK)
    233233                return rc;
  • uspace/app/trace/trace.c

    ra737667e r5126f80  
    512512                goto error;
    513513
    514         /* Send program pathname */
     514        /* Send program. */
    515515        rc = loader_set_program_path(ldr, path);
    516516        if (rc != EOK)
     
    523523
    524524        /* Send default files */
     525        int fd_root;
    525526        int fd_stdin;
    526527        int fd_stdout;
    527528        int fd_stderr;
     529       
     530        fd_root = vfs_root();
     531        if (fd_root >= 0) {
     532                rc = loader_add_inbox(ldr, "root", fd_root);
     533                close(fd_root);
     534                if (rc != EOK)
     535                        goto error;
     536        }
    528537       
    529538        if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK)) {
  • uspace/lib/c/generic/elf/elf_mod.c

    ra737667e r5126f80  
    115115    elf_finfo_t *info)
    116116{
    117         int file = vfs_lookup(path);
     117        int file = vfs_lookup(path, 0);
    118118        int rc = elf_load_file(file, so_bias, flags, info);
    119119        close(file);
  • uspace/lib/c/generic/libc.c

    ra737667e r5126f80  
    4848#include <task.h>
    4949#include <loader/pcb.h>
     50#include <vfs/vfs.h>
     51#include <vfs/inbox.h>
    5052#include "private/libc.h"
    5153#include "private/async.h"
     
    113115                __inbox_init(__pcb->inbox, __pcb->inbox_entries);
    114116                __stdio_init();
     117                vfs_root_set(inbox_get("root"));
    115118                (void) chdir(__pcb->cwd);
    116119        }
  • uspace/lib/c/generic/loader.c

    ra737667e r5126f80  
    198198        }
    199199       
    200         int fd = vfs_lookup(path);
     200        int fd = vfs_lookup(path, 0);
    201201        if (fd < 0) {
    202202                return fd;
  • uspace/lib/c/generic/task.c

    ra737667e r5126f80  
    4848#include "private/ns.h"
    4949#include <vfs/vfs.h>
     50#include <unistd.h>
    5051
    5152task_id_t task_get_id(void)
     
    177178       
    178179        /* Send files */
     180        int root = vfs_root();
     181        if (root >= 0) {
     182                rc = loader_add_inbox(ldr, "root", root);
     183                close(root);
     184                if (rc != EOK)
     185                        goto error;
     186        }
     187       
    179188        if (fd_stdin >= 0) {
    180189                rc = loader_add_inbox(ldr, "stdin", fd_stdin);
  • 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;
  • uspace/lib/c/include/ipc/vfs.h

    ra737667e r5126f80  
    183183        WALK_REGULAR = (1 << 3),
    184184        WALK_DIRECTORY = (1 << 4),
     185        WALK_MOUNT_POINT = (1 << 5),
    185186       
    186187        WALK_ALL_FLAGS = WALK_MAY_CREATE | WALK_MUST_CREATE | WALK_REGULAR | WALK_DIRECTORY,
     188};
     189
     190enum {
     191        VFS_MOUNT_BLOCKING = 1,
     192        VFS_MOUNT_CONNECT_ONLY = 2,
     193        VFS_MOUNT_NO_REF = 4,
    187194};
    188195
  • uspace/lib/c/include/vfs/vfs.h

    ra737667e r5126f80  
    5252extern char *vfs_absolutize(const char *, size_t *);
    5353
    54 extern int vfs_mount(const char *, const char *, const char *, const char *,
     54extern int mount(const char *, const char *, const char *, const char *,
    5555    unsigned int, unsigned int);
    56 extern int vfs_unmount(const char *);
     56extern int unmount(const char *);
    5757
    5858extern int vfs_fhandle(FILE *, int *);
     
    6565extern int _vfs_walk(int, const char *, int);
    6666extern int _vfs_open(int, int);
    67 extern int vfs_lookup(const char *);
     67extern int vfs_lookup(const char *, int);
    6868
    6969extern int vfs_pass_handle(async_exch_t *, int, async_exch_t *);
     
    7171
    7272extern int vfs_clone(int, bool);
     73extern int vfs_root(void);
     74extern void vfs_root_set(int);
     75
     76int vfs_mount(int, const char *, service_id_t, const char *, unsigned, unsigned, int *);
     77int vfs_unmount(int);
    7378
    7479#endif
  • uspace/srv/vfs/vfs_file.c

    ra737667e r5126f80  
    178178                 * endpoint FS and drop our reference to the underlying VFS node.
    179179                 */
    180                 if (file->open_read || file->open_write) {
    181                         rc = vfs_file_close_remote(file);
    182                 }
    183                 vfs_node_delref(file->node);
     180               
     181                if (file->node != NULL) {
     182                        if (file->open_read || file->open_write) {
     183                                rc = vfs_file_close_remote(file);
     184                        }
     185                        vfs_node_delref(file->node);
     186                }
    184187                free(file);
    185188        }
     
    312315}
    313316
     317static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
     318{
     319        fibril_mutex_unlock(&file->_lock);
     320       
     321        fibril_mutex_lock(&vfs_data->lock);
     322        vfs_file_delref(vfs_data, file);
     323        fibril_mutex_unlock(&vfs_data->lock);
     324}
     325
    314326static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd)
    315327{
     
    323335                        vfs_file_addref(vfs_data, file);
    324336                        fibril_mutex_unlock(&vfs_data->lock);
     337                       
    325338                        fibril_mutex_lock(&file->_lock);
     339                        if (file->node == NULL) {
     340                                _vfs_file_put(vfs_data, file);
     341                                return NULL;
     342                        }
     343                        assert(file != NULL);
     344                        assert(file->node != NULL);
    326345                        return file;
    327346                }
     
    341360{
    342361        return _vfs_file_get(VFS_DATA, fd);
    343 }
    344 
    345 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)
    346 {
    347         fibril_mutex_unlock(&file->_lock);
    348        
    349         fibril_mutex_lock(&vfs_data->lock);
    350         vfs_file_delref(vfs_data, file);
    351         fibril_mutex_unlock(&vfs_data->lock);
    352362}
    353363
  • uspace/srv/vfs/vfs_lookup.c

    ra737667e r5126f80  
    330330        if (result != NULL) {
    331331                /* The found file may be a mount point. Try to cross it. */
    332                 if (!(lflag & L_MP)) {
     332                if (!(lflag & (L_MP|L_DISABLE_MOUNTS))) {
    333333                        base = vfs_node_peek(&res);
    334334                        if (base != NULL && base->mount != NULL) {
  • uspace/srv/vfs/vfs_ops.c

    ra737667e r5126f80  
    6868FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock);
    6969
    70 vfs_node_t *root = NULL;
    71 
    7270static int vfs_connect_internal(service_id_t service_id, unsigned flags, unsigned instance,
    73         char *options, char *fsname, vfs_node_t **root)
     71    char *options, char *fsname, vfs_node_t **root)
    7472{
    7573        fs_handle_t fs_handle = 0;
     
    7977                fs_handle = fs_name_to_handle(instance, fsname, false);
    8078               
    81                 if (fs_handle != 0 || !(flags & IPC_FLAG_BLOCKING)) {
     79                if (fs_handle != 0 || !(flags & VFS_MOUNT_BLOCKING)) {
    8280                        break;
    8381                }
     
    123121}
    124122
    125 static int vfs_mount_internal(service_id_t service_id, unsigned flags, unsigned instance,
    126         char *opts, char *fs_name, char *mp)
    127 {
    128         /* Resolve the path to the mountpoint. */
    129        
    130         if (root == NULL) {
    131                 /* We still don't have the root file system mounted. */
    132                 if (str_cmp(mp, "/") != 0) {
    133                         /*
    134                          * We can't resolve this without the root filesystem
    135                          * being mounted first.
    136                          */
    137                         return ENOENT;
    138                 }
    139                
    140                 return vfs_connect_internal(service_id, flags, instance, opts, fs_name, &root);
    141         }
    142        
    143         /* We already have the root FS. */
    144         if (str_cmp(mp, "/") == 0) {
    145                 /* Trying to mount root FS over root FS */
    146                 return EBUSY;
    147         }
    148        
    149         vfs_lookup_res_t mp_res;
    150         int rc = vfs_lookup_internal(root, mp, L_DIRECTORY, &mp_res);
    151         if (rc != EOK) {
    152                 /* The lookup failed. */
    153                 return rc;
    154         }
    155        
    156         vfs_node_t *mp_node;
    157         mp_node = vfs_node_get(&mp_res);
    158         if (!mp_node) {
    159                 return ENOMEM;
    160         }
    161        
    162         if (mp_node->mount != NULL) {
    163                 return EBUSY;
    164         }
    165        
    166         if (mp_node->type != VFS_NODE_DIRECTORY) {
    167                 printf("%s node not a directory, type=%d\n", mp, mp_node->type);
    168                 return ENOTDIR;
    169         }
    170        
    171         if (vfs_node_has_children(mp_node)) {
    172                 return ENOTEMPTY;
    173         }
    174        
    175         vfs_node_t *mountee;
    176        
    177         rc = vfs_connect_internal(service_id, flags, instance, opts, fs_name, &mountee);
    178         if (rc != EOK) {
    179                 vfs_node_put(mp_node);
    180                 return ENOMEM;
    181         }
    182        
    183         mp_node->mount = mountee;
    184         /* The two references to nodes are held by the mount so that they cannot be freed.
    185          * They are removed in detach_internal().
    186          */
    187         return EOK;
    188 }
    189 
    190123void vfs_mount_srv(ipc_callid_t rid, ipc_call_t *request)
    191124{
     125        int mpfd = IPC_GET_ARG1(*request);
     126       
    192127        /*
    193128         * We expect the library to do the device-name to device-handle
     
    195130         * in the request.
    196131         */
    197         service_id_t service_id = (service_id_t) IPC_GET_ARG1(*request);
     132        service_id_t service_id = (service_id_t) IPC_GET_ARG2(*request);
    198133       
    199134        /*
    200135         * Mount flags are passed as ARG2.
    201136         */
    202         unsigned int flags = (unsigned int) IPC_GET_ARG2(*request);
     137        unsigned int flags = (unsigned int) IPC_GET_ARG3(*request);
    203138       
    204139        /*
    205140         * Instance number is passed as ARG3.
    206141         */
    207         unsigned int instance = IPC_GET_ARG3(*request);
    208 
    209         /* We want the client to send us the mount point. */
    210         char *mp;
    211         int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
     142        unsigned int instance = IPC_GET_ARG4(*request);
     143       
     144        char *opts = NULL;
     145        char *fs_name = NULL;
     146        vfs_file_t *mp = NULL;
     147        vfs_file_t *file = NULL;
     148        int fd = -1;
     149        mtab_ent_t *mtab_ent = NULL;
     150
     151        /* Now we expect to receive the mount options. */
     152        int rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
    212153            0, NULL);
    213154        if (rc != EOK) {
    214                 async_answer_0(rid, rc);
    215                 return;
    216         }
    217        
    218         /* Now we expect to receive the mount options. */
    219         char *opts;
    220         rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN,
    221             0, NULL);
    222         if (rc != EOK) {
    223                 async_answer_0(rid, rc);
    224                 free(mp);
    225                 return;
     155                async_data_write_void(rc);
     156                goto out;
    226157        }
    227158       
     
    230161         * system.
    231162         */
    232         char *fs_name;
    233163        rc = async_data_write_accept((void **) &fs_name, true, 0,
    234164            FS_NAME_MAXLEN, 0, NULL);
    235165        if (rc != EOK) {
    236                 async_answer_0(rid, rc);
    237                 free(mp);
    238                 free(opts);
    239                 return;
     166                goto out;
     167        }
     168       
     169        if (!(flags & VFS_MOUNT_CONNECT_ONLY)) {
     170                mp = vfs_file_get(mpfd);
     171                if (mp == NULL) {
     172                        rc = EBADF;
     173                        goto out;
     174                }
     175               
     176                if (mp->node->mount != NULL) {
     177                        rc = EBUSY;
     178                        goto out;
     179                }
     180               
     181                if (mp->node->type != VFS_NODE_DIRECTORY) {
     182                        rc = ENOTDIR;
     183                        goto out;
     184                }
     185               
     186                if (vfs_node_has_children(mp->node)) {
     187                        rc = ENOTEMPTY;
     188                        goto out;
     189                }
     190        }
     191       
     192        if (!(flags & VFS_MOUNT_NO_REF)) {
     193                fd = vfs_fd_alloc(&file, false);
     194                if (fd < 0) {
     195                        rc = fd;
     196                        goto out;
     197                }
    240198        }
    241199       
    242200        /* Add the filesystem info to the list of mounted filesystems */
    243         mtab_ent_t *mtab_ent = malloc(sizeof(mtab_ent_t));
     201        mtab_ent = malloc(sizeof(mtab_ent_t));
    244202        if (!mtab_ent) {
    245                 async_answer_0(rid, ENOMEM);
    246                 free(mp);
    247                 free(fs_name);
    248                 free(opts);
    249                 return;
    250         }
    251        
    252         /* Mount the filesystem. */
     203                rc = ENOMEM;
     204                goto out;
     205        }
     206       
     207        vfs_node_t *root = NULL;
     208       
    253209        fibril_rwlock_write_lock(&namespace_rwlock);
    254         rc = vfs_mount_internal(service_id, flags, instance, opts, fs_name, mp);
     210
     211        rc = vfs_connect_internal(service_id, flags, instance, opts, fs_name, &root);
     212        if (rc == EOK && !(flags & VFS_MOUNT_CONNECT_ONLY)) {
     213                vfs_node_addref(mp->node);
     214                vfs_node_addref(root);
     215                mp->node->mount = root;
     216        }
     217       
    255218        fibril_rwlock_write_unlock(&namespace_rwlock);
    256 
     219       
     220        if (rc != EOK) {
     221                goto out;
     222        }
     223       
     224       
     225        if (flags & VFS_MOUNT_NO_REF) {
     226                vfs_node_delref(root);
     227        } else {
     228                assert(file != NULL);
     229               
     230                file->node = root;
     231                file->permissions = MODE_READ | MODE_WRITE | MODE_APPEND;
     232                file->open_read = false;
     233                file->open_write = false;
     234        }
     235       
    257236        /* Add the filesystem info to the list of mounted filesystems */
    258237        if (rc == EOK) {
    259                 str_cpy(mtab_ent->mp, MAX_PATH_LEN, mp);
     238                str_cpy(mtab_ent->mp, MAX_PATH_LEN, "fixme");
    260239                str_cpy(mtab_ent->fs_name, FS_NAME_MAXLEN, fs_name);
    261240                str_cpy(mtab_ent->opts, MAX_MNTOPTS_LEN, opts);
     
    269248                mtab_size++;
    270249                fibril_mutex_unlock(&mtab_list_lock);
    271         }
    272        
    273         async_answer_0(rid, rc);
    274 
    275         free(mp);
    276         free(fs_name);
    277         free(opts);
     250        }       
     251       
     252        rc = EOK;
     253
     254out:
     255        async_answer_1(rid, rc, rc == EOK ? fd : 0);
     256
     257        if (opts) {
     258                free(opts);
     259        }
     260        if (fs_name) {
     261                free(fs_name);
     262        }
     263        if (mp) {
     264                vfs_file_put(mp);
     265        }
     266        if (file) {
     267                vfs_file_put(file);
     268        }
     269        if (rc != EOK && fd >= 0) {
     270                vfs_fd_free(fd);
     271        }
    278272}
    279273
    280274void vfs_unmount_srv(ipc_callid_t rid, ipc_call_t *request)
    281275{
    282         /*
    283          * Receive the mount point path.
    284          */
    285         char *mp;
    286         int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN,
    287             0, NULL);
    288         if (rc != EOK)
    289                 async_answer_0(rid, rc);
    290        
    291         /*
    292          * Taking the namespace lock will do two things for us. First, it will
    293          * prevent races with other lookup operations. Second, it will stop new
    294          * references to already existing VFS nodes and creation of new VFS
    295          * nodes. This is because new references are added as a result of some
    296          * lookup operation or at least of some operation which is protected by
    297          * the namespace lock.
    298          */
     276        int mpfd = IPC_GET_ARG1(*request);
     277       
     278        vfs_file_t *mp = vfs_file_get(mpfd);
     279        if (mp == NULL) {
     280                async_answer_0(rid, EBADF);
     281                return;
     282        }
     283       
     284        if (mp->node->mount == NULL) {
     285                async_answer_0(rid, ENOENT);
     286                vfs_file_put(mp);
     287                return;
     288        }
     289       
    299290        fibril_rwlock_write_lock(&namespace_rwlock);
    300                
    301         if (str_cmp(mp, "/") == 0) {
    302                 free(mp);
    303                
    304                 /*
    305                  * Unmounting the root file system.
    306                  *
    307                  * In this case, there is no mount point node and we send
    308                  * VFS_OUT_UNMOUNTED directly to the mounted file system.
    309                  */
    310                
    311                 if (!root) {
    312                         fibril_rwlock_write_unlock(&namespace_rwlock);
    313                         async_answer_0(rid, ENOENT);
    314                         return;
    315                 }
    316                
    317                 /*
    318                  * Count the total number of references for the mounted file system. We
    319                  * are expecting at least one, which we got when the file system was mounted.
    320                  * If we find more, it means that
    321                  * the file system cannot be gracefully unmounted at the moment because
    322                  * someone is working with it.
    323                  */
    324                 if (vfs_nodes_refcount_sum_get(root->fs_handle, root->service_id) != 1) {
    325                         fibril_rwlock_write_unlock(&namespace_rwlock);
    326                         async_answer_0(rid, EBUSY);
    327                         return;
    328                 }
    329                
    330                 async_exch_t *exch = vfs_exchange_grab(root->fs_handle);
    331                 rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, root->service_id);
    332                 vfs_exchange_release(exch);
    333                
    334                 fibril_rwlock_write_unlock(&namespace_rwlock);
    335                 if (rc == EOK) {
    336                         vfs_node_forget(root);
    337                         root = NULL;
    338                 }
    339                 async_answer_0(rid, rc);
    340                 return;
    341         }
    342        
    343         /*
    344          * Lookup the mounted root and instantiate it.
    345          */
    346         vfs_lookup_res_t mp_res;
    347         rc = vfs_lookup_internal(root, mp, L_MP, &mp_res);
    348         if (rc != EOK) {
    349                 fibril_rwlock_write_unlock(&namespace_rwlock);
    350                 free(mp);
    351                 async_answer_0(rid, rc);
    352                 return;
    353         }
    354         vfs_node_t *mp_node = vfs_node_get(&mp_res);
    355         if (!mp_node) {
    356                 fibril_rwlock_write_unlock(&namespace_rwlock);
    357                 free(mp);
    358                 async_answer_0(rid, ENOMEM);
    359                 return;
    360         }
    361        
    362         if (mp_node->mount == NULL) {
    363                 fibril_rwlock_write_unlock(&namespace_rwlock);
    364                 vfs_node_put(mp_node);
    365                 free(mp);
    366                 async_answer_0(rid, ENOENT);
    367                 return;
    368         }
    369291       
    370292        /*
    371293         * Count the total number of references for the mounted file system. We
    372          * are expecting at least one, which we got when the file system was mounted.
     294         * are expecting at least one, which is held by the mount point.
    373295         * If we find more, it means that
    374296         * the file system cannot be gracefully unmounted at the moment because
    375297         * someone is working with it.
    376298         */
    377         if (vfs_nodes_refcount_sum_get(mp_node->mount->fs_handle, mp_node->mount->service_id) != 1) {
     299        if (vfs_nodes_refcount_sum_get(mp->node->mount->fs_handle, mp->node->mount->service_id) != 1) {
     300                async_answer_0(rid, EBUSY);
     301                vfs_file_put(mp);
    378302                fibril_rwlock_write_unlock(&namespace_rwlock);
    379                 vfs_node_put(mp_node);
    380                 free(mp);
    381                 async_answer_0(rid, EBUSY);
    382                 return;
    383         }
    384        
    385         /* Unmount the filesystem. */
    386         async_exch_t *exch = vfs_exchange_grab(mp_node->mount->fs_handle);
    387         rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, mp_node->mount->service_id);
     303                return;
     304        }
     305       
     306        async_exch_t *exch = vfs_exchange_grab(mp->node->mount->fs_handle);
     307        int rc = async_req_1_0(exch, VFS_OUT_UNMOUNTED, mp->node->mount->service_id);
    388308        vfs_exchange_release(exch);
    389309       
    390         vfs_node_forget(mp_node->mount);
    391         mp_node->mount = NULL;
    392        
    393         vfs_node_put(mp_node);
     310        if (rc != EOK) {
     311                async_answer_0(rid, rc);
     312                vfs_file_put(mp);
     313                fibril_rwlock_write_unlock(&namespace_rwlock);
     314                return;
     315        }
     316       
     317        vfs_node_forget(mp->node->mount);
     318        vfs_node_put(mp->node);
     319        mp->node->mount = NULL;
     320       
    394321        fibril_rwlock_write_unlock(&namespace_rwlock);
    395322       
     
    398325
    399326        list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
    400                 if (str_cmp(mtab_ent->mp, mp) == 0) {
     327                // FIXME: mp name
     328                if (str_cmp(mtab_ent->mp, "fixme") == 0) {
    401329                        list_remove(&mtab_ent->link);
    402330                        mtab_size--;
     
    408336        assert(found);
    409337        fibril_mutex_unlock(&mtab_list_lock);
    410 
    411         free(mp);       
    412        
     338       
     339        vfs_file_put(mp);
    413340        async_answer_0(rid, EOK);
    414         return;
    415341}
    416342
     
    448374        if (flags&WALK_DIRECTORY) {
    449375                lflags |= L_DIRECTORY;
     376        }
     377        if (flags&WALK_MOUNT_POINT) {
     378                lflags |= L_MP;
    450379        }
    451380        return lflags;
     
    470399       
    471400        /* Lookup the file structure corresponding to the file descriptor. */
    472         vfs_file_t *parent = NULL;
    473         vfs_node_t *parent_node = root;
    474         // TODO: Client-side root.
    475         if (parentfd != -1) {
    476                 parent = vfs_file_get(parentfd);
    477                 if (!parent) {
    478                         free(path);
    479                         async_answer_0(rid, EBADF);
    480                         return;
    481                 }
    482                 parent_node = parent->node;
     401        vfs_file_t *parent = vfs_file_get(parentfd);
     402        if (!parent) {
     403                free(path);
     404                async_answer_0(rid, EBADF);
     405                return;
    483406        }
    484407       
     
    486409       
    487410        vfs_lookup_res_t lr;
    488         rc = vfs_lookup_internal(parent_node, path, walk_lookup_flags(flags), &lr);
     411        rc = vfs_lookup_internal(parent->node, path, walk_lookup_flags(flags), &lr);
    489412        free(path);
    490413
     
    963886        vfs_file_t *parent = NULL;
    964887        vfs_file_t *expect = NULL;
    965         vfs_node_t *parent_node = root;
    966888       
    967889        int parentfd = IPC_GET_ARG1(*request);
     
    974896                return;
    975897        }
     898        if (parentfd == expectfd) {
     899                async_answer_0(rid, EINVAL);
     900                return;
     901        }
    976902       
    977903        fibril_rwlock_write_lock(&namespace_rwlock);
     
    980906
    981907        /* Files are retrieved in order of file descriptors, to prevent deadlock. */
    982         if (parentfd >= 0 && parentfd < expectfd) {
     908        if (parentfd < expectfd) {
    983909                parent = vfs_file_get(parentfd);
    984910                if (!parent) {
    985                         rc = ENOENT;
     911                        rc = EBADF;
    986912                        goto exit;
    987913                }
     
    996922        }
    997923       
    998         if (parentfd >= 0 && parentfd >= expectfd) {
     924        if (parentfd > expectfd) {
    999925                parent = vfs_file_get(parentfd);
    1000926                if (!parent) {
    1001                         rc = ENOENT;
     927                        rc = EBADF;
    1002928                        goto exit;
    1003929                }
    1004930        }
    1005931       
    1006         if (parent) {
    1007                 parent_node = parent->node;
    1008         }
     932        assert(parent != NULL);
    1009933       
    1010934        if (expectfd >= 0) {
    1011935                vfs_lookup_res_t lr;
    1012                 rc = vfs_lookup_internal(parent_node, path, lflag, &lr);
     936                rc = vfs_lookup_internal(parent->node, path, lflag, &lr);
    1013937                if (rc != EOK) {
    1014938                        goto exit;
     
    1026950       
    1027951        vfs_lookup_res_t lr;
    1028         rc = vfs_lookup_internal(parent_node, path, lflag | L_UNLINK, &lr);
     952        rc = vfs_lookup_internal(parent->node, path, lflag | L_UNLINK, &lr);
    1029953        if (rc != EOK) {
    1030954                goto exit;
     
    11881112       
    11891113        /* Lookup the file structure corresponding to the file descriptor. */
    1190         vfs_node_t *base_node = root;
    1191         // TODO: Client-side root.
    1192         if (basefd != -1) {
    1193                 base = vfs_file_get(basefd);
    1194                 if (!base) {
    1195                         rc = EBADF;
    1196                         goto out;
    1197                 }
    1198                 base_node = base->node;
    1199         }
    1200        
    1201         rc = vfs_rename_internal(base_node, oldc, newc);
     1114        base = vfs_file_get(basefd);
     1115        if (!base) {
     1116                rc = EBADF;
     1117                goto out;
     1118        }
     1119       
     1120        rc = vfs_rename_internal(base->node, oldc, newc);
    12021121
    12031122out:
     
    13581277        /* Lookup the file structure corresponding to fd. */
    13591278        vfs_file_t *oldfile = vfs_file_get(oldfd);
    1360         if (!oldfile) {
     1279        if (oldfile == NULL) {
    13611280                async_answer_0(rid, EBADF);
    13621281                return;
     
    13651284        vfs_file_t *newfile;
    13661285        int newfd = vfs_fd_alloc(&newfile, desc);
     1286        async_answer_0(rid, newfd);
     1287       
    13671288        if (newfd < 0) {
    1368                 async_answer_0(rid, newfd);
    13691289                vfs_file_put(oldfile);
    13701290                return;
     
    13791299        vfs_file_put(oldfile);
    13801300        vfs_file_put(newfile);
    1381        
    1382         async_answer_0(rid, newfd);
    13831301}
    13841302
Note: See TracChangeset for help on using the changeset viewer.