/trunk/uspace/srv/fs/tmpfs/tmpfs.h |
---|
64,6 → 64,7 |
extern void tmpfs_read(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_write(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_free(ipc_callid_t, ipc_call_t *); |
#endif |
/trunk/uspace/srv/fs/tmpfs/tmpfs.c |
---|
55,18 → 55,12 |
.name = "tmpfs", |
.ops = { |
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_RENAME)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_OPENDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_READDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_CLOSEDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_UNLINK)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_FREE)] = VFS_OP_DEFINED, |
} |
}; |
118,6 → 112,12 |
case VFS_WRITE: |
tmpfs_write(callid, &call); |
break; |
case VFS_TRUNCATE: |
tmpfs_truncate(callid, &call); |
break; |
case VFS_FREE: |
tmpfs_free(callid, &call); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c |
---|
496,6 → 496,32 |
ipc_answer_0(rid, EOK); |
} |
void tmpfs_free(ipc_callid_t rid, ipc_call_t *request) |
{ |
int dev_handle = IPC_GET_ARG1(*request); |
unsigned long index = IPC_GET_ARG2(*request); |
link_t *hlp; |
hlp = hash_table_find(&dentries, &index); |
if (!hlp) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t, |
dh_link); |
assert(!dentry->parent); |
assert(!dentry->child); |
assert(!dentry->sibling); |
if (dentry->type == TMPFS_FILE) |
free(dentry->data); |
free(dentry->name); |
free(dentry); |
ipc_answer_0(rid, EOK); |
} |
/** |
* @} |
*/ |
/trunk/uspace/srv/fs/fat/fat.c |
---|
51,16 → 51,9 |
.name = "fat", |
.ops = { |
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_RENAME)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_OPENDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_READDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_CLOSEDIR)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_UNLINK)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
} |
/trunk/uspace/srv/vfs/vfs_register.c |
---|
106,14 → 106,6 |
dprintf("Operation VFS_LOOKUP not defined by the client.\n"); |
return false; |
} |
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] != VFS_OP_DEFINED) { |
dprintf("Operation VFS_OPEN not defined by the client.\n"); |
return false; |
} |
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] != VFS_OP_DEFINED) { |
dprintf("Operation VFS_CLOSE not defined by the client.\n"); |
return false; |
} |
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_READ)] != VFS_OP_DEFINED) { |
dprintf("Operation VFS_READ not defined by the client.\n"); |
return false; |
/trunk/uspace/srv/vfs/vfs.h |
---|
47,17 → 47,9 |
#define IPC_METHOD_TO_VFS_OP(m) ((m) - VFS_FIRST) |
typedef enum { |
VFS_OPEN = VFS_FIRST, |
VFS_CLOSE, |
VFS_READ, |
VFS_READ = VFS_FIRST, |
VFS_WRITE, |
VFS_TRUNCATE, |
VFS_RENAME, |
VFS_OPENDIR, |
VFS_READDIR, |
VFS_CLOSEDIR, |
VFS_MKDIR, |
VFS_UNLINK, |
VFS_MOUNT, |
VFS_UNMOUNT, |
VFS_LAST_CMN, /* keep this the last member of this enum */ |
65,12 → 57,18 |
typedef enum { |
VFS_LOOKUP = VFS_LAST_CMN, |
VFS_FREE, |
VFS_LAST_CLNT, /* keep this the last member of this enum */ |
} vfs_request_clnt_t; |
typedef enum { |
VFS_REGISTER = VFS_LAST_CMN, |
VFS_OPEN, |
VFS_CLOSE, |
VFS_SEEK, |
VFS_MKDIR, |
VFS_UNLINK, |
VFS_RENAME, |
VFS_LAST_SRV, /* keep this the last member of this enum */ |
} vfs_request_srv_t; |
/trunk/uspace/srv/vfs/vfs_node.c |
---|
43,6 → 43,8 |
#include <rwlock.h> |
#include <libadt/hash_table.h> |
#include <assert.h> |
#include <async.h> |
#include <errno.h> |
/** Futex protecting the VFS node hash table. */ |
atomic_t nodes_futex = FUTEX_INITIALIZER; |
101,8 → 103,15 |
*/ |
void vfs_node_delref(vfs_node_t *node) |
{ |
bool free_vfs_node = false; |
bool free_fs_node = false; |
futex_down(&nodes_futex); |
if (node->refcnt-- == 1) { |
/* |
* We are dropping the last reference to this node. |
* Remove it from the VFS node hash table. |
*/ |
unsigned long key[] = { |
[KEY_FS_HANDLE] = node->fs_handle, |
[KEY_DEV_HANDLE] = node->dev_handle, |
109,8 → 118,26 |
[KEY_INDEX] = node->index |
}; |
hash_table_remove(&nodes, key, 3); |
free_vfs_node = true; |
if (!node->lnkcnt) |
free_fs_node = true; |
} |
futex_up(&nodes_futex); |
if (free_fs_node) { |
/* |
* The node is not visible in the file system namespace. |
* Free up its resources. |
*/ |
int phone = vfs_grab_phone(node->fs_handle); |
ipcarg_t rc; |
rc = async_req_2_0(phone, VFS_FREE, (ipcarg_t)node->dev_handle, |
(ipcarg_t)node->index); |
assert(rc == EOK); |
vfs_release_phone(phone); |
} |
if (free_vfs_node) |
free(node); |
} |
/** Find VFS node. |
196,8 → 223,6 |
void nodes_remove_callback(link_t *item) |
{ |
vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link); |
free(node); |
} |
/** |
/trunk/uspace/srv/vfs/vfs_file.c |
---|
130,7 → 130,7 |
{ |
if (file->refcnt-- == 1) { |
/* |
* Lost last reference to a file, need to drop our reference |
* Lost the last reference to a file, need to drop our reference |
* to the underlying VFS node. |
*/ |
vfs_node_delref(file->node); |