/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c |
---|
274,7 → 274,8 |
} |
} |
ipc_answer_3(rid, EOK, tmpfs_reg.fs_handle, dev_handle, dcur->index); |
ipc_answer_4(rid, EOK, tmpfs_reg.fs_handle, dev_handle, dcur->index, |
dcur->size); |
} |
void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) |
372,7 → 373,7 |
dentry->size += delta; |
dentry->data = newdata; |
(void) ipc_data_write_finalize(callid, dentry->data + pos, len); |
ipc_answer_1(rid, EOK, len); |
ipc_answer_2(rid, EOK, len, dentry->size); |
} |
/** |
/trunk/uspace/srv/vfs/vfs_open.c |
---|
57,11 → 57,11 |
*/ |
int flags = IPC_GET_ARG1(*request); |
int mode = IPC_GET_ARG2(*request); |
size_t size; |
size_t len; |
ipc_callid_t callid; |
if (!ipc_data_write_receive(&callid, &size)) { |
if (!ipc_data_write_receive(&callid, &len)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
73,7 → 73,7 |
* There is one optimization we could do in the future: copy the path |
* directly into the PLB using some kind of a callback. |
*/ |
char *path = malloc(size); |
char *path = malloc(len); |
if (!path) { |
ipc_answer_0(callid, ENOMEM); |
82,7 → 82,7 |
} |
int rc; |
if ((rc = ipc_data_write_finalize(callid, path, size))) { |
if ((rc = ipc_data_write_finalize(callid, path, len))) { |
ipc_answer_0(rid, rc); |
free(path); |
return; |
99,7 → 99,8 |
* The path is now populated and we can call vfs_lookup_internal(). |
*/ |
vfs_triplet_t triplet; |
rc = vfs_lookup_internal(path, size, &triplet, NULL); |
size_t size; |
rc = vfs_lookup_internal(path, len, &triplet, &size, NULL); |
if (rc) { |
rwlock_reader_unlock(&namespace_rwlock); |
ipc_answer_0(rid, rc); |
112,7 → 113,7 |
*/ |
free(path); |
vfs_node_t *node = vfs_node_get(&triplet); |
vfs_node_t *node = vfs_node_get(&triplet, size); |
rwlock_reader_unlock(&namespace_rwlock); |
/* |
/trunk/uspace/srv/vfs/vfs_mount.c |
---|
52,7 → 52,8 |
.index = 0, |
}; |
static int lookup_root(int fs_handle, int dev_handle, vfs_triplet_t *root) |
static int lookup_root(int fs_handle, int dev_handle, vfs_triplet_t *root, |
size_t *size) |
{ |
vfs_pair_t altroot = { |
.fs_handle = fs_handle, |
59,7 → 60,7 |
.dev_handle = dev_handle, |
}; |
return vfs_lookup_internal("/", strlen("/"), root, &altroot); |
return vfs_lookup_internal("/", strlen("/"), root, size, &altroot); |
} |
void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
160,13 → 161,14 |
*/ |
int rc; |
vfs_triplet_t mounted_root; |
rc = lookup_root(fs_handle, dev_handle, &mounted_root); |
size_t mrsz; |
rc = lookup_root(fs_handle, dev_handle, &mounted_root, &mrsz); |
if (rc != EOK) { |
free(buf); |
ipc_answer_0(rid, rc); |
return; |
} |
vfs_node_t *mr_node = vfs_node_get(&mounted_root); |
vfs_node_t *mr_node = vfs_node_get(&mounted_root, mrsz); |
if (!mr_node) { |
free(buf); |
ipc_answer_0(rid, ENOMEM); |
177,6 → 179,7 |
* Finally, we need to resolve the path to the mountpoint. |
*/ |
vfs_triplet_t mp; |
size_t mpsz; |
futex_down(&rootfs_futex); |
if (rootfs.fs_handle) { |
/* |
183,7 → 186,7 |
* We already have the root FS. |
*/ |
rwlock_writer_lock(&namespace_rwlock); |
rc = vfs_lookup_internal(buf, size, &mp, NULL); |
rc = vfs_lookup_internal(buf, size, &mp, &mpsz, NULL); |
if (rc != EOK) { |
/* |
* The lookup failed for some reason. |
195,7 → 198,7 |
ipc_answer_0(rid, rc); |
return; |
} |
mp_node = vfs_node_get(&mp); |
mp_node = vfs_node_get(&mp, mpsz); |
if (!mp_node) { |
rwlock_writer_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
/trunk/uspace/srv/vfs/vfs.h |
---|
187,10 → 187,11 |
extern int fs_name_to_handle(char *, bool); |
extern int vfs_lookup_internal(char *, size_t, vfs_triplet_t *, vfs_pair_t *); |
extern int vfs_lookup_internal(char *, size_t, vfs_triplet_t *, size_t *, |
vfs_pair_t *); |
extern bool vfs_nodes_init(void); |
extern vfs_node_t *vfs_node_get(vfs_triplet_t *); |
extern vfs_node_t *vfs_node_get(vfs_triplet_t *, size_t); |
extern void vfs_node_put(vfs_node_t *); |
#define MAX_OPEN_FILES 128 |
/trunk/uspace/srv/vfs/vfs_node.c |
---|
42,6 → 42,7 |
#include <futex.h> |
#include <rwlock.h> |
#include <libadt/hash_table.h> |
#include <assert.h> |
/** Futex protecting the VFS node hash table. */ |
atomic_t nodes_futex = FUTEX_INITIALIZER; |
121,10 → 122,11 |
* vfs_node_put() on it. |
* |
* @param triplet Triplet encoding the identity of the VFS node. |
* @param size Size of the node as filled by vfs_lookup_internal(). |
* |
* @return VFS node corresponding to the given triplet. |
*/ |
vfs_node_t *vfs_node_get(vfs_triplet_t *triplet) |
vfs_node_t *vfs_node_get(vfs_triplet_t *triplet, size_t size) |
{ |
unsigned long key[] = { |
[KEY_FS_HANDLE] = triplet->fs_handle, |
146,6 → 148,7 |
node->fs_handle = triplet->fs_handle; |
node->dev_handle = triplet->fs_handle; |
node->index = triplet->index; |
node->size = size; |
link_initialize(&node->nh_link); |
rwlock_initialize(&node->contents_rwlock); |
hash_table_insert(&nodes, key, &node->nh_link); |
152,6 → 155,9 |
} else { |
node = hash_table_get_instance(tmp, vfs_node_t, nh_link); |
} |
assert(node->size == size); |
_vfs_node_addref(node); |
futex_up(&nodes_futex); |
/trunk/uspace/srv/vfs/vfs_lookup.c |
---|
56,6 → 56,8 |
* @param path Path to be resolved; it needn't be an ASCIIZ string. |
* @param len Number of path characters pointed by path. |
* @param result Empty node structure where the result will be stored. |
* @param size Storage where the size of the node will be stored. Can |
* be NULL. |
* @param altroot If non-empty, will be used instead of rootfs as the root |
* of the whole VFS tree. |
* |
62,7 → 64,7 |
* @return EOK on success or an error code from errno.h. |
*/ |
int vfs_lookup_internal(char *path, size_t len, vfs_triplet_t *result, |
vfs_pair_t *altroot) |
size_t *size, vfs_pair_t *altroot) |
{ |
vfs_pair_t *root; |
165,6 → 167,8 |
result->fs_handle = (int) IPC_GET_ARG1(answer); |
result->dev_handle = (int) IPC_GET_ARG2(answer); |
result->index = (int) IPC_GET_ARG3(answer); |
if (size) |
*size = (size_t) IPC_GET_ARG4(answer); |
} |
return rc; |
/trunk/uspace/srv/vfs/vfs_rdwr.c |
---|
129,8 → 129,11 |
*/ |
if (read) |
rwlock_reader_unlock(&file->node->contents_rwlock); |
else |
else { |
/* Update the cached version of node's size. */ |
file->node->size = IPC_GET_ARG2(answer); |
rwlock_writer_unlock(&file->node->contents_rwlock); |
} |
/* |
* Update the position pointer and unlock the open file. |