Changes in uspace/srv/vfs/vfs_file.c [e2ab36f1:79ae36dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs_file.c
re2ab36f1 r79ae36dd 43 43 #include <fibril.h> 44 44 #include <fibril_synch.h> 45 #include <adt/list.h>46 #include <task.h>47 45 #include "vfs.h" 48 46 … … 52 50 typedef struct { 53 51 fibril_mutex_t lock; 54 fibril_condvar_t cv;55 list_t passed_handles;56 52 vfs_file_t **files; 57 53 } vfs_client_data_t; 58 54 59 typedef struct {60 link_t link;61 int handle;62 } vfs_boxed_handle_t;63 64 static int _vfs_fd_free(vfs_client_data_t *, int);65 66 55 /** Initialize the table of open files. */ 67 static bool vfs_files_init(v fs_client_data_t *vfs_data)68 { 69 fibril_mutex_lock(& vfs_data->lock);70 if (! vfs_data->files) {71 vfs_data->files= malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));72 if (! vfs_data->files) {73 fibril_mutex_unlock(& vfs_data->lock);56 static bool vfs_files_init(void) 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); 74 63 return false; 75 64 } 76 memset( vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));77 } 78 fibril_mutex_unlock(& vfs_data->lock);65 memset(FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *)); 66 } 67 fibril_mutex_unlock(&VFS_DATA->lock); 79 68 return true; 80 69 } 81 70 82 71 /** Cleanup the table of open files. */ 83 static void vfs_files_done(v fs_client_data_t *vfs_data)72 static void vfs_files_done(void) 84 73 { 85 74 int i; 86 75 87 if (! vfs_data->files)76 if (!FILES) 88 77 return; 89 78 90 79 for (i = 0; i < MAX_OPEN_FILES; i++) { 91 if (vfs_data->files[i]) 92 (void) _vfs_fd_free(vfs_data, i); 93 } 94 95 free(vfs_data->files); 96 97 while (!list_empty(&vfs_data->passed_handles)) { 98 link_t *lnk; 99 vfs_boxed_handle_t *bh; 100 101 lnk = list_first(&vfs_data->passed_handles); 102 list_remove(lnk); 103 104 bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 105 free(bh); 106 } 80 if (FILES[i]) { 81 (void) vfs_fd_free(i); 82 } 83 } 84 85 free(FILES); 107 86 } 108 87 … … 114 93 if (vfs_data) { 115 94 fibril_mutex_initialize(&vfs_data->lock); 116 fibril_condvar_initialize(&vfs_data->cv);117 list_initialize(&vfs_data->passed_handles);118 95 vfs_data->files = NULL; 119 96 } … … 126 103 vfs_client_data_t *vfs_data = (vfs_client_data_t *) data; 127 104 128 vfs_files_done( vfs_data);105 vfs_files_done(); 129 106 free(vfs_data); 130 107 } … … 138 115 139 116 ipc_call_t answer; 140 aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node-> service_id,117 aid_t msg = async_send_2(exch, VFS_OUT_CLOSE, file->node->devmap_handle, 141 118 file->node->index, &answer); 142 119 … … 154 131 * incremented. 155 132 */ 156 static void vfs_file_addref(vfs_ client_data_t *vfs_data, vfs_file_t *file)157 { 158 assert(fibril_mutex_is_locked(& vfs_data->lock));133 static void vfs_file_addref(vfs_file_t *file) 134 { 135 assert(fibril_mutex_is_locked(&VFS_DATA->lock)); 159 136 160 137 file->refcnt++; … … 166 143 * decremented. 167 144 */ 168 static int vfs_file_delref(vfs_ client_data_t *vfs_data, vfs_file_t *file)145 static int vfs_file_delref(vfs_file_t *file) 169 146 { 170 147 int rc = EOK; 171 148 172 assert(fibril_mutex_is_locked(& vfs_data->lock));149 assert(fibril_mutex_is_locked(&VFS_DATA->lock)); 173 150 174 151 if (file->refcnt-- == 1) { … … 185 162 } 186 163 187 static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc) 188 { 189 if (!vfs_files_init(vfs_data)) 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()) 190 176 return ENOMEM; 191 177 … … 196 182 i = 0; 197 183 198 fibril_mutex_lock(& vfs_data->lock);184 fibril_mutex_lock(&VFS_DATA->lock); 199 185 while (true) { 200 if (! vfs_data->files[i]) {201 vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));202 if (! vfs_data->files[i]) {203 fibril_mutex_unlock(& vfs_data->lock);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); 204 190 return ENOMEM; 205 191 } 206 192 207 memset( vfs_data->files[i], 0, sizeof(vfs_file_t));208 fibril_mutex_initialize(& vfs_data->files[i]->lock);209 vfs_file_addref( vfs_data, vfs_data->files[i]);210 fibril_mutex_unlock(& vfs_data->lock);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); 211 197 return (int) i; 212 198 } … … 224 210 } 225 211 } 226 fibril_mutex_unlock(& vfs_data->lock);212 fibril_mutex_unlock(&VFS_DATA->lock); 227 213 228 214 return EMFILE; 229 }230 231 /** Allocate a file descriptor.232 *233 * @param desc If true, look for an available file descriptor234 * in a descending order.235 *236 * @return First available file descriptor or a negative error237 * code.238 */239 int vfs_fd_alloc(bool desc)240 {241 return _vfs_fd_alloc(VFS_DATA, desc);242 }243 244 static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd)245 {246 int rc;247 248 if (!vfs_files_init(vfs_data))249 return ENOMEM;250 251 fibril_mutex_lock(&vfs_data->lock);252 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) {253 fibril_mutex_unlock(&vfs_data->lock);254 return EBADF;255 }256 257 rc = vfs_file_delref(vfs_data, vfs_data->files[fd]);258 vfs_data->files[fd] = NULL;259 fibril_mutex_unlock(&vfs_data->lock);260 261 return rc;262 215 } 263 216 … … 271 224 int vfs_fd_free(int fd) 272 225 { 273 return _vfs_fd_free(VFS_DATA, fd); 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; 274 242 } 275 243 … … 285 253 int vfs_fd_assign(vfs_file_t *file, int fd) 286 254 { 287 if (!vfs_files_init( VFS_DATA))255 if (!vfs_files_init()) 288 256 return ENOMEM; 289 257 … … 295 263 296 264 FILES[fd] = file; 297 vfs_file_addref( VFS_DATA,FILES[fd]);265 vfs_file_addref(FILES[fd]); 298 266 fibril_mutex_unlock(&VFS_DATA->lock); 299 267 … … 301 269 } 302 270 303 static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd) 304 { 305 if (!vfs_files_init(vfs_data)) 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()) 306 280 return NULL; 307 281 308 fibril_mutex_lock(& vfs_data->lock);282 fibril_mutex_lock(&VFS_DATA->lock); 309 283 if ((fd >= 0) && (fd < MAX_OPEN_FILES)) { 310 vfs_file_t *file = vfs_data->files[fd];284 vfs_file_t *file = FILES[fd]; 311 285 if (file != NULL) { 312 vfs_file_addref( vfs_data,file);313 fibril_mutex_unlock(& vfs_data->lock);286 vfs_file_addref(file); 287 fibril_mutex_unlock(&VFS_DATA->lock); 314 288 return file; 315 289 } 316 290 } 317 fibril_mutex_unlock(& vfs_data->lock);291 fibril_mutex_unlock(&VFS_DATA->lock); 318 292 319 293 return NULL; 320 294 } 321 295 322 /** Find VFS file structure for a given file descriptor.323 *324 * @param fd File descriptor.325 *326 * @return VFS file structure corresponding to fd.327 */328 vfs_file_t *vfs_file_get(int fd)329 {330 return _vfs_file_get(VFS_DATA, fd);331 }332 333 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file)334 {335 fibril_mutex_lock(&vfs_data->lock);336 vfs_file_delref(vfs_data, file);337 fibril_mutex_unlock(&vfs_data->lock);338 }339 340 296 /** Stop using a file structure. 341 297 * … … 344 300 void vfs_file_put(vfs_file_t *file) 345 301 { 346 _vfs_file_put(VFS_DATA, file); 347 } 348 349 void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd) 350 { 351 vfs_client_data_t *donor_data = NULL; 352 vfs_client_data_t *acceptor_data = NULL; 353 vfs_file_t *donor_file = NULL; 354 vfs_file_t *acceptor_file = NULL; 355 vfs_boxed_handle_t *bh; 356 int acceptor_fd; 357 358 acceptor_data = async_get_client_data_by_id(acceptor_id); 359 if (!acceptor_data) 360 return; 361 362 bh = malloc(sizeof(vfs_boxed_handle_t)); 363 assert(bh); 364 365 link_initialize(&bh->link); 366 bh->handle = -1; 367 368 donor_data = async_get_client_data_by_id(donor_id); 369 if (!donor_data) 370 goto out; 371 372 donor_file = _vfs_file_get(donor_data, donor_fd); 373 if (!donor_file) 374 goto out; 375 376 acceptor_fd = _vfs_fd_alloc(acceptor_data, false); 377 if (acceptor_fd < 0) 378 goto out; 379 380 bh->handle = acceptor_fd; 381 382 /* 383 * Add a new reference to the underlying VFS node. 384 */ 385 vfs_node_addref(donor_file->node); 386 (void) vfs_open_node_remote(donor_file->node); 387 388 acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd); 389 assert(acceptor_file); 390 391 /* 392 * Inherit attributes from the donor. 393 */ 394 acceptor_file->node = donor_file->node; 395 acceptor_file->append = donor_file->append; 396 acceptor_file->pos = donor_file->pos; 397 398 out: 399 fibril_mutex_lock(&acceptor_data->lock); 400 list_append(&bh->link, &acceptor_data->passed_handles); 401 fibril_condvar_broadcast(&acceptor_data->cv); 402 fibril_mutex_unlock(&acceptor_data->lock); 403 404 if (donor_data) 405 async_put_client_data_by_id(donor_id); 406 if (acceptor_data) 407 async_put_client_data_by_id(acceptor_id); 408 if (donor_file) 409 _vfs_file_put(donor_data, donor_file); 410 if (acceptor_file) 411 _vfs_file_put(acceptor_data, acceptor_file); 412 413 } 414 415 int vfs_wait_handle_internal(void) 416 { 417 vfs_client_data_t *vfs_data = VFS_DATA; 418 int fd; 419 420 fibril_mutex_lock(&vfs_data->lock); 421 while (list_empty(&vfs_data->passed_handles)) 422 fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock); 423 link_t *lnk = list_first(&vfs_data->passed_handles); 424 list_remove(lnk); 425 fibril_mutex_unlock(&vfs_data->lock); 426 427 vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 428 fd = bh->handle; 429 free(bh); 430 431 return fd; 302 fibril_mutex_lock(&VFS_DATA->lock); 303 vfs_file_delref(file); 304 fibril_mutex_unlock(&VFS_DATA->lock); 432 305 } 433 306
Note:
See TracChangeset
for help on using the changeset viewer.