Changeset cb65bbe in mainline for uspace/srv/vfs/vfs_ops.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.