Changeset 05b9912 in mainline for uspace/srv/vfs/vfs_ops.c


Ignore:
Timestamp:
2009-06-03T18:54:49Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
17fd1d4
Parents:
215abc1
Message:

VFS rewrite:

  • add new VFS methods
    • VFS_NODE for getting VFS node for a file descriptor
    • VFS_OPEN_NODE for opening an i-node directly
    • VFS_DEVICE for getting the underlying device of a file (if any)
    • VFS_SYNC for syncing buffers
  • L_OPEN flag is set to underlying filesystem in VFS_LOOKUP when opening a file to support initialization (if any)
  • VFS_CLOSE is now propagated to underlying filesystem to support cleanup (if any)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs_ops.c

    r215abc1 r05b9912  
    9494        aid_t msg;
    9595        ipc_call_t answer;
    96                        
     96       
    9797        /* Resolve the path to the mountpoint. */
    9898        rwlock_write_lock(&namespace_rwlock);
     
    491491                return;
    492492        }
    493 
     493       
    494494        /*
    495495         * The POSIX interface is open(path, oflag, mode).
     
    504504        int mode = IPC_GET_ARG3(*request);
    505505        size_t len;
    506 
     506       
    507507        /*
    508508         * Make sure that we are called with exactly one of L_FILE and
    509          * L_DIRECTORY.
    510          */
    511         if ((lflag & (L_FILE | L_DIRECTORY)) == 0 ||
    512             (lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) {
    513                 ipc_answer_0(rid, EINVAL);
    514                 return;
    515         }
    516 
     509         * L_DIRECTORY. Make sure that the user does not pass L_OPEN.
     510         */
     511        if (((lflag & (L_FILE | L_DIRECTORY)) == 0)
     512            || ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY))
     513            || ((lflag & L_OPEN) != 0)) {
     514                ipc_answer_0(rid, EINVAL);
     515                return;
     516        }
     517       
    517518        if (oflag & O_CREAT)
    518519                lflag |= L_CREATE;
    519520        if (oflag & O_EXCL)
    520521                lflag |= L_EXCLUSIVE;
    521 
     522       
    522523        ipc_callid_t callid;
    523 
    524524        if (!ipc_data_write_receive(&callid, &len)) {
    525525                ipc_answer_0(callid, EINVAL);
     
    527527                return;
    528528        }
     529       
    529530        char *path = malloc(len + 1);
    530531        if (!path) {
     
    533534                return;
    534535        }
     536       
    535537        int rc;
    536538        if ((rc = ipc_data_write_finalize(callid, path, len))) {
     
    550552        else
    551553                rwlock_read_lock(&namespace_rwlock);
    552 
     554       
    553555        /* The path is now populated and we can call vfs_lookup_internal(). */
    554556        vfs_lookup_res_t lr;
    555         rc = vfs_lookup_internal(path, lflag, &lr, NULL);
    556         if (rc) {
     557        rc = vfs_lookup_internal(path, lflag | L_OPEN, &lr, NULL);
     558        if (rc != EOK) {
    557559                if (lflag & L_CREATE)
    558560                        rwlock_write_unlock(&namespace_rwlock);
     
    563565                return;
    564566        }
    565 
     567       
    566568        /* Path is no longer needed. */
    567569        free(path);
    568 
     570       
    569571        vfs_node_t *node = vfs_node_get(&lr);
    570572        if (lflag & L_CREATE)
     
    572574        else
    573575                rwlock_read_unlock(&namespace_rwlock);
    574 
     576       
    575577        /* Truncate the file if requested and if necessary. */
    576578        if (oflag & O_TRUNC) {
     
    589591                rwlock_write_unlock(&node->contents_rwlock);
    590592        }
    591 
     593       
    592594        /*
    593595         * Get ourselves a file descriptor and the corresponding vfs_file_t
     
    602604        vfs_file_t *file = vfs_file_get(fd);
    603605        file->node = node;
    604         if (oflag & O_APPEND) 
     606        if (oflag & O_APPEND)
    605607                file->append = true;
    606 
     608       
    607609        /*
    608610         * The following increase in reference count is for the fact that the
     
    614616        vfs_node_addref(node);
    615617        vfs_node_put(node);
    616 
     618       
    617619        /* Success! Return the new file descriptor to the client. */
    618620        ipc_answer_1(rid, EOK, fd);
    619621}
    620622
     623void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)
     624{
     625        // FIXME: check for sanity of the supplied fs, dev and index
     626       
     627        if (!vfs_files_init()) {
     628                ipc_answer_0(rid, ENOMEM);
     629                return;
     630        }
     631       
     632        /*
     633         * The interface is open_node(fs, dev, index, oflag).
     634         */
     635        vfs_lookup_res_t lr;
     636       
     637        lr.triplet.fs_handle = IPC_GET_ARG1(*request);
     638        lr.triplet.dev_handle = IPC_GET_ARG2(*request);
     639        lr.triplet.index = IPC_GET_ARG3(*request);
     640        int oflag = IPC_GET_ARG4(*request);
     641       
     642        rwlock_read_lock(&namespace_rwlock);
     643       
     644        int rc = vfs_open_node_internal(&lr);
     645        if (rc != EOK) {
     646                rwlock_read_unlock(&namespace_rwlock);
     647                ipc_answer_0(rid, rc);
     648                return;
     649        }
     650       
     651        vfs_node_t *node = vfs_node_get(&lr);
     652        rwlock_read_unlock(&namespace_rwlock);
     653       
     654        /* Truncate the file if requested and if necessary. */
     655        if (oflag & O_TRUNC) {
     656                rwlock_write_lock(&node->contents_rwlock);
     657                if (node->size) {
     658                        rc = vfs_truncate_internal(node->fs_handle,
     659                            node->dev_handle, node->index, 0);
     660                        if (rc) {
     661                                rwlock_write_unlock(&node->contents_rwlock);
     662                                vfs_node_put(node);
     663                                ipc_answer_0(rid, rc);
     664                                return;
     665                        }
     666                        node->size = 0;
     667                }
     668                rwlock_write_unlock(&node->contents_rwlock);
     669        }
     670       
     671        /*
     672         * Get ourselves a file descriptor and the corresponding vfs_file_t
     673         * structure.
     674         */
     675        int fd = vfs_fd_alloc();
     676        if (fd < 0) {
     677                vfs_node_put(node);
     678                ipc_answer_0(rid, fd);
     679                return;
     680        }
     681        vfs_file_t *file = vfs_file_get(fd);
     682        file->node = node;
     683        if (oflag & O_APPEND)
     684                file->append = true;
     685       
     686        /*
     687         * The following increase in reference count is for the fact that the
     688         * file is being opened and that a file structure is pointing to it.
     689         * It is necessary so that the file will not disappear when
     690         * vfs_node_put() is called. The reference will be dropped by the
     691         * respective VFS_CLOSE.
     692         */
     693        vfs_node_addref(node);
     694        vfs_node_put(node);
     695       
     696        /* Success! Return the new file descriptor to the client. */
     697        ipc_answer_1(rid, EOK, fd);
     698}
     699
     700void vfs_node(ipc_callid_t rid, ipc_call_t *request)
     701{
     702        int fd = IPC_GET_ARG1(*request);
     703       
     704        /* Lookup the file structure corresponding to the file descriptor. */
     705        vfs_file_t *file = vfs_file_get(fd);
     706        if (!file) {
     707                ipc_answer_0(rid, ENOENT);
     708                return;
     709        }
     710       
     711        ipc_answer_3(rid, EOK, file->node->fs_handle,
     712            file->node->dev_handle, file->node->index);
     713}
     714
     715void vfs_device(ipc_callid_t rid, ipc_call_t *request)
     716{
     717        int fd = IPC_GET_ARG1(*request);
     718       
     719        /* Lookup the file structure corresponding to the file descriptor. */
     720        vfs_file_t *file = vfs_file_get(fd);
     721        if (!file) {
     722                ipc_answer_0(rid, ENOENT);
     723                return;
     724        }
     725       
     726        /*
     727         * Lock the open file structure so that no other thread can manipulate
     728         * the same open file at a time.
     729         */
     730        futex_down(&file->lock);
     731        int fs_phone = vfs_grab_phone(file->node->fs_handle);
     732       
     733        /* Make a VFS_DEVICE request at the destination FS server. */
     734        aid_t msg;
     735        ipc_call_t answer;
     736        msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
     737            file->node->dev_handle, file->node->index, &answer);
     738       
     739        /* Wait for reply from the FS server. */
     740        ipcarg_t rc;
     741        async_wait_for(msg, &rc);
     742       
     743        vfs_release_phone(fs_phone);
     744        futex_up(&file->lock);
     745       
     746        ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer));
     747}
     748
     749void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
     750{
     751        int fd = IPC_GET_ARG1(*request);
     752       
     753        /* Lookup the file structure corresponding to the file descriptor. */
     754        vfs_file_t *file = vfs_file_get(fd);
     755        if (!file) {
     756                ipc_answer_0(rid, ENOENT);
     757                return;
     758        }
     759       
     760        /*
     761         * Lock the open file structure so that no other thread can manipulate
     762         * the same open file at a time.
     763         */
     764        futex_down(&file->lock);
     765        int fs_phone = vfs_grab_phone(file->node->fs_handle);
     766       
     767        /* Make a VFS_SYMC request at the destination FS server. */
     768        aid_t msg;
     769        ipc_call_t answer;
     770        msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
     771            file->node->dev_handle, file->node->index, &answer);
     772       
     773        /* Wait for reply from the FS server. */
     774        ipcarg_t rc;
     775        async_wait_for(msg, &rc);
     776       
     777        vfs_release_phone(fs_phone);
     778        futex_up(&file->lock);
     779       
     780        ipc_answer_0(rid, rc);
     781}
     782
    621783void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    622784{
    623785        int fd = IPC_GET_ARG1(*request);
    624         int rc = vfs_fd_free(fd);
    625         ipc_answer_0(rid, rc);
     786       
     787        /* Lookup the file structure corresponding to the file descriptor. */
     788        vfs_file_t *file = vfs_file_get(fd);
     789        if (!file) {
     790                ipc_answer_0(rid, ENOENT);
     791                return;
     792        }
     793       
     794        /*
     795         * Lock the open file structure so that no other thread can manipulate
     796         * the same open file at a time.
     797         */
     798        futex_down(&file->lock);
     799       
     800        int fs_phone = vfs_grab_phone(file->node->fs_handle);
     801       
     802        /* Make a VFS_CLOSE request at the destination FS server. */
     803        aid_t msg;
     804        ipc_call_t answer;
     805        msg = async_send_2(fs_phone, IPC_GET_METHOD(*request),
     806            file->node->dev_handle, file->node->index, &answer);
     807       
     808        /* Wait for reply from the FS server. */
     809        ipcarg_t rc;
     810        async_wait_for(msg, &rc);
     811       
     812        vfs_release_phone(fs_phone);
     813        futex_up(&file->lock);
     814       
     815        int retval = IPC_GET_ARG1(answer);
     816        if (retval != EOK)
     817                ipc_answer_0(rid, retval);
     818       
     819        retval = vfs_fd_free(fd);
     820        ipc_answer_0(rid, retval);
    626821}
    627822
     
    706901        ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    707902       
    708         vfs_release_phone(fs_phone);
    709        
    710903        /* Wait for reply from the FS server. */
    711904        ipcarg_t rc;
    712905        async_wait_for(msg, &rc);
     906       
     907        vfs_release_phone(fs_phone);
     908       
    713909        size_t bytes = IPC_GET_ARG1(answer);
    714910
     
    11171313/**
    11181314 * @}
    1119  */ 
     1315 */
Note: See TracChangeset for help on using the changeset viewer.