Changeset cb65bbe in mainline


Ignore:
Timestamp:
2013-07-23T22:43:48Z (11 years ago)
Author:
Ji?? Z?rev?cky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0b18364
Parents:
c442f63
Message:

Implement server side of VFS_WALK and VFS_OPEN2.

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/ipc/vfs.h

    rc442f63 rcb65bbe  
    8282        VFS_IN_WAIT_HANDLE,
    8383        VFS_IN_MTAB_GET,
     84        VFS_IN_WALK,
     85        VFS_IN_OPEN2,
    8486} vfs_in_request_t;
    8587
     
    168170#define L_OPEN                  256
    169171
     172/*
     173 * Walk flags.
     174 */
     175enum {
     176        /**
     177         * WALK_PARTIAL requests that if the whole path cannot be traversed,
     178         * the walk() operation should return the last visited file, along
     179         * with an indication of how many directories have been traversed.
     180         */
     181        //WALK_PARTIAL = (1 << 0),
     182       
     183        WALK_ALL_FLAGS = 0,
     184};
     185
     186enum {
     187        MODE_READ = 1,
     188        MODE_WRITE = 2,
     189        MODE_APPEND = 4,
     190};
     191
    170192#endif
    171193
  • uspace/srv/vfs/vfs.c

    rc442f63 rcb65bbe  
    8585                        vfs_unmount(callid, &call);
    8686                        break;
     87                case VFS_IN_WALK:
     88                        vfs_walk(callid, &call);
     89                        break;
     90                case VFS_IN_OPEN2:
     91                        vfs_open(callid, &call);
     92                        break;
    8793                case VFS_IN_OPEN:
    8894                        vfs_open(callid, &call);
  • uspace/srv/vfs/vfs.h

    rc442f63 rcb65bbe  
    137137        /** Number of file handles referencing this file. */
    138138        unsigned refcnt;
     139
     140        int permissions;
     141        bool open_read;
     142        bool open_write;
    139143
    140144        /** Append on write. */
     
    223227extern void vfs_get_mtab(ipc_callid_t, ipc_call_t *);
    224228
     229extern void vfs_walk(ipc_callid_t, ipc_call_t *);
     230extern void vfs_create(ipc_callid_t, ipc_call_t *);
     231extern void vfs_open2(ipc_callid_t, ipc_call_t *);
     232
    225233#endif
    226234
  • uspace/srv/vfs/vfs_file.c

    rc442f63 rcb65bbe  
    177177                 * endpoint FS and drop our reference to the underlying VFS node.
    178178                 */
    179                 rc = vfs_file_close_remote(file);
     179                if (file->open_read || file->open_write) {
     180                        rc = vfs_file_close_remote(file);
     181                }
    180182                vfs_node_delref(file->node);
    181183                free(file);
  • uspace/srv/vfs/vfs_ops.c

    rc442f63 rcb65bbe  
    568568}
    569569
     570void vfs_walk(ipc_callid_t rid, ipc_call_t *request)
     571{
     572        /*
     573         * Parent is our relative root for file lookup.
     574         * For defined flags, see <ipc/vfs.h>.
     575         */
     576        int parentfd = IPC_GET_ARG1(*request);
     577        int flags = IPC_GET_ARG2(*request);
     578       
     579        if ((flags&~WALK_ALL_FLAGS) != 0) {
     580                /* Invalid flags. */
     581                async_answer_0(rid, EINVAL);
     582                return;
     583        }
     584       
     585        char *path;
     586        int rc = async_data_write_accept((void **)&path, true, 0, 0, 0, NULL);
     587       
     588        /* Lookup the file structure corresponding to the file descriptor. */
     589        vfs_file_t *parent = NULL;
     590        vfs_pair_t *parent_node = NULL;
     591        // TODO: Client-side root.
     592        if (parentfd != -1) {
     593                parent = vfs_file_get(parentfd);
     594                if (!parent) {
     595                        free(path);
     596                        async_answer_0(rid, EBADF);
     597                        return;
     598                }
     599                parent_node = (vfs_pair_t *)parent->node;
     600        }
     601       
     602        fibril_rwlock_read_lock(&namespace_rwlock);
     603       
     604        vfs_lookup_res_t lr;
     605        rc = vfs_lookup_internal(path, 0, &lr, parent_node);
     606        free(path);
     607
     608        if (rc != EOK) {
     609                fibril_rwlock_read_unlock(&namespace_rwlock);
     610                if (parent) {
     611                        vfs_file_put(parent);
     612                }
     613                async_answer_0(rid, rc);
     614                return;
     615        }
     616       
     617        vfs_node_t *node = vfs_node_get(&lr);
     618       
     619        int fd = vfs_fd_alloc(false);
     620        if (fd < 0) {
     621                vfs_node_put(node);
     622                if (parent) {
     623                        vfs_file_put(parent);
     624                }
     625                async_answer_0(rid, fd);
     626                return;
     627        }
     628       
     629        vfs_file_t *file = vfs_file_get(fd);
     630        assert(file != NULL);
     631       
     632        file->node = node;
     633        if (parent) {
     634                file->permissions = parent->permissions;
     635        } else {
     636                file->permissions = MODE_READ | MODE_WRITE | MODE_APPEND;
     637        }
     638        file->open_read = false;
     639        file->open_write = false;
     640       
     641        vfs_node_addref(node);
     642        vfs_node_put(node);
     643        vfs_file_put(file);
     644        if (parent) {
     645                vfs_file_put(parent);
     646        }
     647       
     648        fibril_rwlock_read_unlock(&namespace_rwlock);
     649
     650        async_answer_1(rid, EOK, fd);
     651}
     652
     653void vfs_open2(ipc_callid_t rid, ipc_call_t *request)
     654{
     655        int fd = IPC_GET_ARG1(*request);
     656        int flags = IPC_GET_ARG2(*request);
     657
     658        if (flags == 0) {
     659                async_answer_0(rid, EINVAL);
     660                return;
     661        }
     662
     663        vfs_file_t *file = vfs_file_get(fd);
     664        if (!file) {
     665                async_answer_0(rid, EBADF);
     666                return;
     667        }
     668       
     669        if ((flags & ~file->permissions) != 0) {
     670                vfs_file_put(file);
     671                async_answer_0(rid, EPERM);
     672                return;
     673        }
     674       
     675        file->open_read = (flags & MODE_READ) != 0;
     676        file->open_write = (flags & (MODE_WRITE | MODE_APPEND)) != 0;
     677        file->append = (flags & MODE_APPEND) != 0;
     678       
     679        if (!file->open_read && !file->open_write) {
     680                vfs_file_put(file);
     681                async_answer_0(rid, EINVAL);
     682                return;
     683        }
     684       
     685        if (file->node->type == VFS_NODE_DIRECTORY && file->open_write) {
     686                file->open_read = file->open_write = false;
     687                vfs_file_put(file);
     688                async_answer_0(rid, EINVAL);
     689                return;
     690        }
     691       
     692        int rc = vfs_open_node_remote(file->node);
     693        if (rc != EOK) {
     694                file->open_read = file->open_write = false;
     695                vfs_file_put(file);
     696                async_answer_0(rid, rc);
     697                return;
     698        }
     699       
     700        vfs_file_put(file);
     701        async_answer_0(rid, EOK);
     702}
     703
    570704void vfs_open(ipc_callid_t rid, ipc_call_t *request)
    571705{
     
    669803        }
    670804        vfs_file_t *file = vfs_file_get(fd);
    671         assert(file);
     805       
     806        /* There is a potential race with another fibril of a malicious client. */
     807        if (!file) {
     808                vfs_node_put(node);
     809                async_answer_0(rid, EBUSY);
     810                return;
     811        }
     812       
    672813        file->node = node;
     814        if (oflag & O_RDONLY)
     815                file->open_read = true;
     816        if (oflag & O_WRONLY)
     817                file->open_write = true;
     818        if (oflag & O_RDWR)
     819                file->open_read = file->open_write = true;
    673820        if (oflag & O_APPEND)
    674821                file->append = true;
     
    758905         */
    759906        fibril_mutex_lock(&file->lock);
     907       
     908        if ((read && !file->open_read) || (!read && !file->open_write)) {
     909                fibril_mutex_unlock(&file->lock);
     910                async_answer_0(rid, EINVAL);
     911                return;
     912        }
    760913       
    761914        vfs_info_t *fs_info = fs_handle_to_info(file->node->fs_handle);
Note: See TracChangeset for help on using the changeset viewer.