Subversion Repositories HelenOS

Rev

Rev 2593 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup fs
  30.  * @{
  31.  */
  32.  
  33. /**
  34.  * @file    vfs_open.c
  35.  * @brief   VFS_OPEN method.
  36.  */
  37.  
  38. #include <ipc/ipc.h>
  39. #include <async.h>
  40. #include <errno.h>
  41. #include <futex.h>
  42. #include <sys/types.h>
  43. #include <stdlib.h>
  44. #include "vfs.h"
  45.  
  46. void vfs_open(ipc_callid_t rid, ipc_call_t *request)
  47. {
  48.     if (!vfs_files_init()) {
  49.         ipc_answer_0(rid, ENOMEM);
  50.         return;
  51.     }
  52.  
  53.     /*
  54.      * The POSIX interface is open(path, flags, mode).
  55.      * We can receive flags and mode along with the VFS_OPEN call; the path
  56.      * will need to arrive in another call.
  57.      */
  58.     int flags = IPC_GET_ARG1(*request);
  59.     int mode = IPC_GET_ARG2(*request);
  60.     size_t size;
  61.  
  62.     ipc_callid_t callid;
  63.  
  64.     if (!ipc_data_receive(&callid, NULL, &size)) {
  65.         ipc_answer_0(callid, EINVAL);
  66.         ipc_answer_0(rid, EINVAL);
  67.         return;
  68.     }
  69.  
  70.     /*
  71.      * Now we are on the verge of accepting the path.
  72.      *
  73.      * There is one optimization we could do in the future: copy the path
  74.      * directly into the PLB using some kind of a callback.
  75.      */
  76.     char *path = malloc(size);
  77.    
  78.     if (!path) {
  79.         ipc_answer_0(callid, ENOMEM);
  80.         ipc_answer_0(rid, ENOMEM);
  81.         return;
  82.     }
  83.  
  84.     int rc;
  85.     if ((rc = ipc_data_deliver(callid, path, size))) {
  86.         ipc_answer_0(rid, rc);
  87.         free(path);
  88.         return;
  89.     }
  90.    
  91.     /*
  92.      * Avoid the race condition in which the file can be deleted before we
  93.      * find/create-and-lock the VFS node corresponding to the looked-up
  94.      * triplet.
  95.      */
  96.     futex_down(&unlink_futex);
  97.  
  98.     /*
  99.      * The path is now populated and we can call vfs_lookup_internal().
  100.      */
  101.     vfs_triplet_t triplet;
  102.     rc = vfs_lookup_internal(path, size, &triplet, NULL);
  103.     if (rc) {
  104.         futex_up(&unlink_futex);
  105.         ipc_answer_0(rid, rc);
  106.         free(path);
  107.         return;
  108.     }
  109.  
  110.     /*
  111.      * Path is no longer needed.
  112.      */
  113.     free(path);
  114.  
  115.     vfs_node_t *node = vfs_node_get(&triplet);
  116.     futex_up(&unlink_futex);
  117.  
  118.     /*
  119.      * Get ourselves a file descriptor and the corresponding vfs_file_t
  120.      * structure.
  121.      */
  122.     int fd = vfs_fd_alloc();
  123.     if (fd < 0) {
  124.         vfs_node_put(node);
  125.         ipc_answer_0(rid, fd);
  126.         return;
  127.     }
  128.     vfs_file_t *file = vfs_file_get(fd);
  129.     file->node = node;
  130.  
  131.     /*
  132.      * The following increase in reference count is for the fact that the
  133.      * file is being opened and that a file structure is pointing to it.
  134.      * It is necessary so that the file will not disappear when
  135.      * vfs_node_put() is called. The reference will be dropped by the
  136.      * respective VFS_CLOSE.
  137.      */
  138.     vfs_node_addref(node);
  139.     vfs_node_put(node);
  140.  
  141.     /*
  142.      * Success! Return the new file descriptor to the client.
  143.      */
  144.     ipc_answer_1(rid, EOK, fd);
  145. }
  146.  
  147. /**
  148.  * @}
  149.  */
  150.