Changeset 320c884 in mainline for uspace/srv/vfs/vfs_open.c
- Timestamp:
- 2007-11-04T19:47:32Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 798f364
- Parents:
- 89cb140
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_open.c
r89cb140 r320c884 39 39 #include <async.h> 40 40 #include <errno.h> 41 #include <futex.h> 42 #include <sys/types.h> 41 43 #include <stdlib.h> 42 #include <string.h>43 #include <bool.h>44 #include <futex.h>45 #include <libadt/list.h>46 #include <sys/types.h>47 44 #include "vfs.h" 48 49 /** Per-connection futex protecting the files array. */50 __thread atomic_t files_futex = FUTEX_INITIALIZER;51 52 /**53 * This is a per-connection table of open files.54 * Our assumption is that each client opens only one connection and therefore55 * there is one table of open files per task. However, this may not be the case56 * and the client can open more connections to VFS. In that case, there will be57 * several tables and several file handle name spaces per task. Besides of this,58 * the functionality will stay unchanged. So unless the client knows what it is59 * doing, it should open one connection to VFS only.60 *61 * Allocation of the open files table is deferred until the client makes the62 * first VFS_OPEN operation.63 */64 __thread vfs_file_t *files = NULL;65 66 /** Initialize the table of open files. */67 static bool vfs_conn_open_files_init(void)68 {69 /*70 * Optimized fast path that will never go to sleep unnecessarily.71 * The assumption is that once files is non-zero, it will never be zero72 * again.73 */74 if (files)75 return true;76 77 futex_down(&files_futex);78 if (!files) {79 files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t));80 if (!files) {81 futex_up(&files_futex);82 return false;83 }84 memset(files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t));85 }86 futex_up(&files_futex);87 return true;88 }89 45 90 46 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 91 47 { 92 if (!vfs_ conn_open_files_init()) {48 if (!vfs_files_init()) { 93 49 ipc_answer_fast_0(rid, ENOMEM); 94 50 return; … … 128 84 129 85 int rc; 130 if ( rc = ipc_data_deliver(callid, &call, path, size)) {86 if ((rc = ipc_data_deliver(callid, &call, path, size))) { 131 87 ipc_answer_fast_0(rid, rc); 132 88 free(path); … … 135 91 136 92 /* 93 * Avoid the race condition in which the file can be deleted before we 94 * find/create-and-lock the VFS node corresponding to the looked-up 95 * triplet. 96 */ 97 futex_down(&unlink_futex); 98 99 /* 137 100 * The path is now populated and we can call vfs_lookup_internal(). 138 101 */ … … 140 103 rc = vfs_lookup_internal(path, size, &triplet, NULL); 141 104 if (rc) { 105 futex_up(&unlink_futex); 142 106 ipc_answer_fast_0(rid, rc); 143 107 free(path); … … 151 115 152 116 vfs_node_t *node = vfs_node_get(&triplet); 153 // TODO: not finished 117 futex_up(&unlink_futex); 118 119 /* 120 * Get ourselves a file descriptor and the corresponding vfs_file_t 121 * structure. 122 */ 123 int fd = vfs_fd_alloc(); 124 if (fd < 0) { 125 vfs_node_put(node); 126 ipc_answer_fast_0(rid, fd); 127 return; 128 } 129 vfs_file_t *file = vfs_file_get(fd); 130 file->node = node; 131 132 /* 133 * The following increase in reference count is for the fact that the 134 * file is being opened and that a file structure is pointing to it. 135 * It is necessary so that the file will not disappear when 136 * vfs_node_put() is called. The reference will be dropped by the 137 * respective VFS_CLOSE. 138 */ 139 vfs_node_addref(node); 140 vfs_node_put(node); 141 142 /* 143 * Success! Return the new file descriptor to the client. 144 */ 145 ipc_answer_fast_1(rid, EOK, fd); 154 146 } 155 147
Note:
See TracChangeset
for help on using the changeset viewer.