Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2747 → Rev 2748

/trunk/uspace/srv/vfs/vfs_ops.c
52,6 → 52,9
#include <atomic.h>
#include "vfs.h"
 
/* Forward declarations of static functions. */
static int vfs_truncate_internal(int, int, unsigned long, size_t);
 
/**
* This rwlock prevents the race between a triplet-to-VFS-node resolution and a
* concurrent VFS operation which modifies the file system namespace.
349,7 → 352,7
return;
}
 
/** Path is no longer needed. */
/* Path is no longer needed. */
free(path);
 
vfs_node_t *node = vfs_node_get(&lr);
358,6 → 361,23
else
rwlock_read_unlock(&namespace_rwlock);
 
/* Truncate the file if requested and if necessary. */
if (oflag & O_TRUNC) {
futex_down(&node->contents_rwlock);
if (node->size) {
rc = vfs_truncate_internal(node->fs_handle,
node->dev_handle, node->index, 0);
if (rc) {
futex_up(&node->contents_rwlock);
vfs_node_put(node);
ipc_answer_0(rid, rc);
return;
}
node->size = 0;
}
futex_up(&node->contents_rwlock);
}
 
/*
* Get ourselves a file descriptor and the corresponding vfs_file_t
* structure.
560,11 → 580,24
ipc_answer_0(rid, EINVAL);
}
 
int vfs_truncate_internal(int fs_handle, int dev_handle, unsigned long index,
size_t size)
{
ipcarg_t rc;
int fs_phone;
fs_phone = vfs_grab_phone(fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
(ipcarg_t)index, (ipcarg_t)size);
vfs_release_phone(fs_phone);
return (int)rc;
}
 
void vfs_truncate(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
size_t size = IPC_GET_ARG2(*request);
ipcarg_t rc;
int rc;
 
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
574,17 → 607,14
futex_down(&file->lock);
 
rwlock_write_lock(&file->node->contents_rwlock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE,
(ipcarg_t)file->node->dev_handle, (ipcarg_t)file->node->index,
(ipcarg_t)size);
vfs_release_phone(fs_phone);
rc = vfs_truncate_internal(file->node->fs_handle,
file->node->dev_handle, file->node->index, size);
if (rc == EOK)
file->node->size = size;
rwlock_write_unlock(&file->node->contents_rwlock);
 
futex_up(&file->lock);
ipc_answer_0(rid, rc);
ipc_answer_0(rid, (ipcarg_t)rc);
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)