Rev 2742 | Rev 2749 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2742 | Rev 2748 | ||
---|---|---|---|
Line 50... | Line 50... | ||
50 | #include <fcntl.h> |
50 | #include <fcntl.h> |
51 | #include <assert.h> |
51 | #include <assert.h> |
52 | #include <atomic.h> |
52 | #include <atomic.h> |
53 | #include "vfs.h" |
53 | #include "vfs.h" |
54 | 54 | ||
- | 55 | /* Forward declarations of static functions. */ |
|
- | 56 | static int vfs_truncate_internal(int, int, unsigned long, size_t); |
|
- | 57 | ||
55 | /** |
58 | /** |
56 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
59 | * This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
57 | * concurrent VFS operation which modifies the file system namespace. |
60 | * concurrent VFS operation which modifies the file system namespace. |
58 | */ |
61 | */ |
59 | RWLOCK_INITIALIZE(namespace_rwlock); |
62 | RWLOCK_INITIALIZE(namespace_rwlock); |
Line 347... | Line 350... | ||
347 | ipc_answer_0(rid, rc); |
350 | ipc_answer_0(rid, rc); |
348 | free(path); |
351 | free(path); |
349 | return; |
352 | return; |
350 | } |
353 | } |
351 | 354 | ||
352 | /** Path is no longer needed. */ |
355 | /* Path is no longer needed. */ |
353 | free(path); |
356 | free(path); |
354 | 357 | ||
355 | vfs_node_t *node = vfs_node_get(&lr); |
358 | vfs_node_t *node = vfs_node_get(&lr); |
356 | if (lflag & L_CREATE) |
359 | if (lflag & L_CREATE) |
357 | rwlock_write_unlock(&namespace_rwlock); |
360 | rwlock_write_unlock(&namespace_rwlock); |
358 | else |
361 | else |
359 | rwlock_read_unlock(&namespace_rwlock); |
362 | rwlock_read_unlock(&namespace_rwlock); |
360 | 363 | ||
- | 364 | /* Truncate the file if requested and if necessary. */ |
|
- | 365 | if (oflag & O_TRUNC) { |
|
- | 366 | futex_down(&node->contents_rwlock); |
|
- | 367 | if (node->size) { |
|
- | 368 | rc = vfs_truncate_internal(node->fs_handle, |
|
- | 369 | node->dev_handle, node->index, 0); |
|
- | 370 | if (rc) { |
|
- | 371 | futex_up(&node->contents_rwlock); |
|
- | 372 | vfs_node_put(node); |
|
- | 373 | ipc_answer_0(rid, rc); |
|
- | 374 | return; |
|
- | 375 | } |
|
- | 376 | node->size = 0; |
|
- | 377 | } |
|
- | 378 | futex_up(&node->contents_rwlock); |
|
- | 379 | } |
|
- | 380 | ||
361 | /* |
381 | /* |
362 | * Get ourselves a file descriptor and the corresponding vfs_file_t |
382 | * Get ourselves a file descriptor and the corresponding vfs_file_t |
363 | * structure. |
383 | * structure. |
364 | */ |
384 | */ |
365 | int fd = vfs_fd_alloc(); |
385 | int fd = vfs_fd_alloc(); |
Line 558... | Line 578... | ||
558 | } |
578 | } |
559 | futex_up(&file->lock); |
579 | futex_up(&file->lock); |
560 | ipc_answer_0(rid, EINVAL); |
580 | ipc_answer_0(rid, EINVAL); |
561 | } |
581 | } |
562 | 582 | ||
- | 583 | int vfs_truncate_internal(int fs_handle, int dev_handle, unsigned long index, |
|
- | 584 | size_t size) |
|
- | 585 | { |
|
- | 586 | ipcarg_t rc; |
|
- | 587 | int fs_phone; |
|
- | 588 | ||
- | 589 | fs_phone = vfs_grab_phone(fs_handle); |
|
- | 590 | rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle, |
|
- | 591 | (ipcarg_t)index, (ipcarg_t)size); |
|
- | 592 | vfs_release_phone(fs_phone); |
|
- | 593 | return (int)rc; |
|
- | 594 | } |
|
- | 595 | ||
563 | void vfs_truncate(ipc_callid_t rid, ipc_call_t *request) |
596 | void vfs_truncate(ipc_callid_t rid, ipc_call_t *request) |
564 | { |
597 | { |
565 | int fd = IPC_GET_ARG1(*request); |
598 | int fd = IPC_GET_ARG1(*request); |
566 | size_t size = IPC_GET_ARG2(*request); |
599 | size_t size = IPC_GET_ARG2(*request); |
567 | ipcarg_t rc; |
600 | int rc; |
568 | 601 | ||
569 | vfs_file_t *file = vfs_file_get(fd); |
602 | vfs_file_t *file = vfs_file_get(fd); |
570 | if (!file) { |
603 | if (!file) { |
571 | ipc_answer_0(rid, ENOENT); |
604 | ipc_answer_0(rid, ENOENT); |
572 | return; |
605 | return; |
573 | } |
606 | } |
574 | futex_down(&file->lock); |
607 | futex_down(&file->lock); |
575 | 608 | ||
576 | rwlock_write_lock(&file->node->contents_rwlock); |
609 | rwlock_write_lock(&file->node->contents_rwlock); |
577 | int fs_phone = vfs_grab_phone(file->node->fs_handle); |
610 | rc = vfs_truncate_internal(file->node->fs_handle, |
578 | rc = async_req_3_0(fs_phone, VFS_TRUNCATE, |
- | |
579 | (ipcarg_t)file->node->dev_handle, (ipcarg_t)file->node->index, |
611 | file->node->dev_handle, file->node->index, size); |
580 | (ipcarg_t)size); |
- | |
581 | vfs_release_phone(fs_phone); |
- | |
582 | if (rc == EOK) |
612 | if (rc == EOK) |
583 | file->node->size = size; |
613 | file->node->size = size; |
584 | rwlock_write_unlock(&file->node->contents_rwlock); |
614 | rwlock_write_unlock(&file->node->contents_rwlock); |
585 | 615 | ||
586 | futex_up(&file->lock); |
616 | futex_up(&file->lock); |
587 | ipc_answer_0(rid, rc); |
617 | ipc_answer_0(rid, (ipcarg_t)rc); |
588 | } |
618 | } |
589 | 619 | ||
590 | void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request) |
620 | void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request) |
591 | { |
621 | { |
592 | int mode = IPC_GET_ARG1(*request); |
622 | int mode = IPC_GET_ARG1(*request); |