Changeset 2bc13887 in mainline
- Timestamp:
- 2011-08-17T15:07:20Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2c4aa39
- Parents:
- 455f190
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/vfs/vfs.h
r455f190 r2bc13887 41 41 #include <stdio.h> 42 42 43 enum vfs_change_state_type { 44 VFS_PASS_HANDLE 45 }; 46 43 47 /** Libc version of the VFS triplet. 44 48 * -
uspace/srv/vfs/vfs.c
r455f190 r2bc13887 37 37 38 38 #include <ipc/services.h> 39 #include <abi/ipc/event.h> 40 #include <event.h> 39 41 #include <ns.h> 40 42 #include <async.h> … … 130 132 } 131 133 134 enum { 135 VFS_TASK_STATE_CHANGE 136 }; 137 138 static void notification_received(ipc_callid_t callid, ipc_call_t *call) 139 { 140 switch (IPC_GET_IMETHOD(*call)) { 141 case VFS_TASK_STATE_CHANGE: 142 if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE) 143 vfs_pass_handle(IPC_GET_ARG4(*call), 144 IPC_GET_ARG5(*call), (int) IPC_GET_ARG2(*call)); 145 break; 146 default: 147 break; 148 } 149 } 150 132 151 int main(int argc, char **argv) 133 152 { … … 170 189 171 190 /* 191 * Set notification handler and subscribe to notifications. 192 */ 193 async_set_interrupt_received(notification_received); 194 event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE); 195 196 /* 172 197 * Register at the naming service. 173 198 */ -
uspace/srv/vfs/vfs.h
r455f190 r2bc13887 188 188 extern void *vfs_client_data_create(void); 189 189 extern void vfs_client_data_destroy(void *); 190 191 extern void vfs_pass_handle(sysarg_t, sysarg_t, int); 190 192 191 193 extern vfs_file_t *vfs_file_get(int); -
uspace/srv/vfs/vfs_file.c
r455f190 r2bc13887 53 53 } vfs_client_data_t; 54 54 55 static int _vfs_fd_free(vfs_client_data_t *, int); 56 55 57 /** Initialize the table of open files. */ 56 static bool vfs_files_init(v oid)57 { 58 fibril_mutex_lock(& VFS_DATA->lock);59 if (! FILES) {60 FILES= malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));61 if (! FILES) {62 fibril_mutex_unlock(& VFS_DATA->lock);58 static bool vfs_files_init(vfs_client_data_t *vfs_data) 59 { 60 fibril_mutex_lock(&vfs_data->lock); 61 if (!vfs_data->files) { 62 vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *)); 63 if (!vfs_data->files) { 64 fibril_mutex_unlock(&vfs_data->lock); 63 65 return false; 64 66 } 65 memset( FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));66 } 67 fibril_mutex_unlock(& VFS_DATA->lock);67 memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *)); 68 } 69 fibril_mutex_unlock(&vfs_data->lock); 68 70 return true; 69 71 } 70 72 71 73 /** Cleanup the table of open files. */ 72 static void vfs_files_done(v oid)74 static void vfs_files_done(vfs_client_data_t *vfs_data) 73 75 { 74 76 int i; 75 77 76 if (! FILES)78 if (!vfs_data->files) 77 79 return; 78 80 79 81 for (i = 0; i < MAX_OPEN_FILES; i++) { 80 if (FILES[i]) { 81 (void) vfs_fd_free(i); 82 } 83 } 84 85 free(FILES); 82 if (vfs_data->files[i]) 83 (void) _vfs_fd_free(vfs_data, i); 84 } 85 86 free(vfs_data->files); 86 87 } 87 88 … … 103 104 vfs_client_data_t *vfs_data = (vfs_client_data_t *) data; 104 105 105 vfs_files_done( );106 vfs_files_done(vfs_data); 106 107 free(vfs_data); 107 108 } … … 131 132 * incremented. 132 133 */ 133 static void vfs_file_addref(vfs_ file_t *file)134 { 135 assert(fibril_mutex_is_locked(& VFS_DATA->lock));134 static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file) 135 { 136 assert(fibril_mutex_is_locked(&vfs_data->lock)); 136 137 137 138 file->refcnt++; … … 143 144 * decremented. 144 145 */ 145 static int vfs_file_delref(vfs_ file_t *file)146 static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file) 146 147 { 147 148 int rc = EOK; 148 149 149 assert(fibril_mutex_is_locked(& VFS_DATA->lock));150 assert(fibril_mutex_is_locked(&vfs_data->lock)); 150 151 151 152 if (file->refcnt-- == 1) { … … 162 163 } 163 164 164 165 /** Allocate a file descriptor. 166 * 167 * @param desc If true, look for an available file descriptor 168 * in a descending order. 169 * 170 * @return First available file descriptor or a negative error 171 * code. 172 */ 173 int vfs_fd_alloc(bool desc) 174 { 175 if (!vfs_files_init()) 165 static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc) 166 { 167 if (!vfs_files_init(vfs_data)) 176 168 return ENOMEM; 177 169 … … 182 174 i = 0; 183 175 184 fibril_mutex_lock(& VFS_DATA->lock);176 fibril_mutex_lock(&vfs_data->lock); 185 177 while (true) { 186 if (! FILES[i]) {187 FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));188 if (! FILES[i]) {189 fibril_mutex_unlock(& VFS_DATA->lock);178 if (!vfs_data->files[i]) { 179 vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t)); 180 if (!vfs_data->files[i]) { 181 fibril_mutex_unlock(&vfs_data->lock); 190 182 return ENOMEM; 191 183 } 192 184 193 memset( FILES[i], 0, sizeof(vfs_file_t));194 fibril_mutex_initialize(& FILES[i]->lock);195 vfs_file_addref( FILES[i]);196 fibril_mutex_unlock(& VFS_DATA->lock);185 memset(vfs_data->files[i], 0, sizeof(vfs_file_t)); 186 fibril_mutex_initialize(&vfs_data->files[i]->lock); 187 vfs_file_addref(vfs_data, vfs_data->files[i]); 188 fibril_mutex_unlock(&vfs_data->lock); 197 189 return (int) i; 198 190 } … … 210 202 } 211 203 } 212 fibril_mutex_unlock(& VFS_DATA->lock);204 fibril_mutex_unlock(&vfs_data->lock); 213 205 214 206 return EMFILE; 207 } 208 209 /** Allocate a file descriptor. 210 * 211 * @param desc If true, look for an available file descriptor 212 * in a descending order. 213 * 214 * @return First available file descriptor or a negative error 215 * code. 216 */ 217 int vfs_fd_alloc(bool desc) 218 { 219 return _vfs_fd_alloc(VFS_DATA, desc); 220 } 221 222 static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd) 223 { 224 int rc; 225 226 if (!vfs_files_init(vfs_data)) 227 return ENOMEM; 228 229 fibril_mutex_lock(&vfs_data->lock); 230 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) { 231 fibril_mutex_unlock(&vfs_data->lock); 232 return EBADF; 233 } 234 235 rc = vfs_file_delref(vfs_data, vfs_data->files[fd]); 236 vfs_data->files[fd] = NULL; 237 fibril_mutex_unlock(&vfs_data->lock); 238 239 return rc; 215 240 } 216 241 … … 224 249 int vfs_fd_free(int fd) 225 250 { 226 int rc; 227 228 if (!vfs_files_init()) 229 return ENOMEM; 230 231 fibril_mutex_lock(&VFS_DATA->lock); 232 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) { 233 fibril_mutex_unlock(&VFS_DATA->lock); 234 return EBADF; 235 } 236 237 rc = vfs_file_delref(FILES[fd]); 238 FILES[fd] = NULL; 239 fibril_mutex_unlock(&VFS_DATA->lock); 240 241 return rc; 251 return _vfs_fd_free(VFS_DATA, fd); 242 252 } 243 253 … … 253 263 int vfs_fd_assign(vfs_file_t *file, int fd) 254 264 { 255 if (!vfs_files_init( ))265 if (!vfs_files_init(VFS_DATA)) 256 266 return ENOMEM; 257 267 … … 263 273 264 274 FILES[fd] = file; 265 vfs_file_addref( FILES[fd]);275 vfs_file_addref(VFS_DATA, FILES[fd]); 266 276 fibril_mutex_unlock(&VFS_DATA->lock); 267 277 … … 269 279 } 270 280 271 /** Find VFS file structure for a given file descriptor. 272 * 273 * @param fd File descriptor. 274 * 275 * @return VFS file structure corresponding to fd. 276 */ 277 vfs_file_t *vfs_file_get(int fd) 278 { 279 if (!vfs_files_init()) 281 static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd) 282 { 283 if (!vfs_files_init(vfs_data)) 280 284 return NULL; 281 285 282 fibril_mutex_lock(& VFS_DATA->lock);286 fibril_mutex_lock(&vfs_data->lock); 283 287 if ((fd >= 0) && (fd < MAX_OPEN_FILES)) { 284 vfs_file_t *file = FILES[fd];288 vfs_file_t *file = vfs_data->files[fd]; 285 289 if (file != NULL) { 286 vfs_file_addref( file);287 fibril_mutex_unlock(& VFS_DATA->lock);290 vfs_file_addref(vfs_data, file); 291 fibril_mutex_unlock(&vfs_data->lock); 288 292 return file; 289 293 } 290 294 } 291 fibril_mutex_unlock(& VFS_DATA->lock);295 fibril_mutex_unlock(&vfs_data->lock); 292 296 293 297 return NULL; 294 298 } 295 299 300 /** Find VFS file structure for a given file descriptor. 301 * 302 * @param fd File descriptor. 303 * 304 * @return VFS file structure corresponding to fd. 305 */ 306 vfs_file_t *vfs_file_get(int fd) 307 { 308 return _vfs_file_get(VFS_DATA, fd); 309 } 310 311 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file) 312 { 313 fibril_mutex_lock(&vfs_data->lock); 314 vfs_file_delref(vfs_data, file); 315 fibril_mutex_unlock(&vfs_data->lock); 316 } 317 296 318 /** Stop using a file structure. 297 319 * … … 300 322 void vfs_file_put(vfs_file_t *file) 301 323 { 302 fibril_mutex_lock(&VFS_DATA->lock); 303 vfs_file_delref(file); 304 fibril_mutex_unlock(&VFS_DATA->lock); 324 _vfs_file_put(VFS_DATA, file); 325 } 326 327 void vfs_pass_handle(sysarg_t donor_hash, sysarg_t acceptor_hash, int donor_fd) 328 { 329 vfs_client_data_t *donor_data = NULL; 330 vfs_client_data_t *acceptor_data = NULL; 331 vfs_file_t *donor_file = NULL; 332 vfs_file_t *acceptor_file = NULL; 333 int acceptor_fd; 334 335 donor_data = async_get_client_data_by_hash(donor_hash); 336 if (!donor_data) 337 return; 338 acceptor_data = async_get_client_data_by_hash(acceptor_hash); 339 if (!acceptor_data) 340 goto out; 341 342 donor_file = _vfs_file_get(donor_data, donor_fd); 343 if (!donor_file) 344 goto out; 345 346 acceptor_fd = _vfs_fd_alloc(acceptor_data, false); 347 if (acceptor_fd < 0) 348 goto out; 349 350 /* 351 * Add a new reference to the underlying VFS node. 352 */ 353 vfs_node_addref(donor_file->node); 354 355 acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd); 356 assert(acceptor_file); 357 358 /* 359 * Inherit attributes from the donor. 360 */ 361 acceptor_file->node = donor_file->node; 362 acceptor_file->append = donor_file->append; 363 acceptor_file->pos = donor_file->pos; 364 365 out: 366 if (donor_data) 367 async_put_client_data_by_hash(donor_hash); 368 if (acceptor_data) 369 async_put_client_data_by_hash(acceptor_hash); 370 if (donor_file) 371 _vfs_file_put(donor_data, donor_file); 372 if (acceptor_file) 373 _vfs_file_put(acceptor_data, acceptor_file); 305 374 } 306 375
Note:
See TracChangeset
for help on using the changeset viewer.