Rev 2730 | Rev 2740 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2730 | Rev 2731 | ||
|---|---|---|---|
| Line 41... | Line 41... | ||
| 41 | #include <atomic.h> |
41 | #include <atomic.h> |
| 42 | #include <futex.h> |
42 | #include <futex.h> |
| 43 | #include <rwlock.h> |
43 | #include <rwlock.h> |
| 44 | #include <libadt/hash_table.h> |
44 | #include <libadt/hash_table.h> |
| 45 | #include <assert.h> |
45 | #include <assert.h> |
| - | 46 | #include <async.h> |
|
| - | 47 | #include <errno.h> |
|
| 46 | 48 | ||
| 47 | /** Futex protecting the VFS node hash table. */ |
49 | /** Futex protecting the VFS node hash table. */ |
| 48 | atomic_t nodes_futex = FUTEX_INITIALIZER; |
50 | atomic_t nodes_futex = FUTEX_INITIALIZER; |
| 49 | 51 | ||
| 50 | #define NODES_BUCKETS_LOG 8 |
52 | #define NODES_BUCKETS_LOG 8 |
| Line 99... | Line 101... | ||
| 99 | * |
101 | * |
| 100 | * @param node VFS node that will have its refcnt decremented. |
102 | * @param node VFS node that will have its refcnt decremented. |
| 101 | */ |
103 | */ |
| 102 | void vfs_node_delref(vfs_node_t *node) |
104 | void vfs_node_delref(vfs_node_t *node) |
| 103 | { |
105 | { |
| - | 106 | bool free_vfs_node = false; |
|
| - | 107 | bool free_fs_node = false; |
|
| - | 108 | ||
| 104 | futex_down(&nodes_futex); |
109 | futex_down(&nodes_futex); |
| 105 | if (node->refcnt-- == 1) { |
110 | if (node->refcnt-- == 1) { |
| - | 111 | /* |
|
| - | 112 | * We are dropping the last reference to this node. |
|
| - | 113 | * Remove it from the VFS node hash table. |
|
| - | 114 | */ |
|
| 106 | unsigned long key[] = { |
115 | unsigned long key[] = { |
| 107 | [KEY_FS_HANDLE] = node->fs_handle, |
116 | [KEY_FS_HANDLE] = node->fs_handle, |
| 108 | [KEY_DEV_HANDLE] = node->dev_handle, |
117 | [KEY_DEV_HANDLE] = node->dev_handle, |
| 109 | [KEY_INDEX] = node->index |
118 | [KEY_INDEX] = node->index |
| 110 | }; |
119 | }; |
| 111 | hash_table_remove(&nodes, key, 3); |
120 | hash_table_remove(&nodes, key, 3); |
| - | 121 | free_vfs_node = true; |
|
| - | 122 | if (!node->lnkcnt) |
|
| - | 123 | free_fs_node = true; |
|
| 112 | } |
124 | } |
| 113 | futex_up(&nodes_futex); |
125 | futex_up(&nodes_futex); |
| - | 126 | ||
| - | 127 | if (free_fs_node) { |
|
| - | 128 | /* |
|
| - | 129 | * The node is not visible in the file system namespace. |
|
| - | 130 | * Free up its resources. |
|
| - | 131 | */ |
|
| - | 132 | int phone = vfs_grab_phone(node->fs_handle); |
|
| - | 133 | ipcarg_t rc; |
|
| - | 134 | rc = async_req_2_0(phone, VFS_FREE, (ipcarg_t)node->dev_handle, |
|
| - | 135 | (ipcarg_t)node->index); |
|
| - | 136 | assert(rc == EOK); |
|
| - | 137 | vfs_release_phone(phone); |
|
| - | 138 | } |
|
| - | 139 | if (free_vfs_node) |
|
| - | 140 | free(node); |
|
| 114 | } |
141 | } |
| 115 | 142 | ||
| 116 | /** Find VFS node. |
143 | /** Find VFS node. |
| 117 | * |
144 | * |
| 118 | * This function will try to lookup the given triplet in the VFS node hash |
145 | * This function will try to lookup the given triplet in the VFS node hash |
| Line 194... | Line 221... | ||
| 194 | (node->index == key[KEY_INDEX]); |
221 | (node->index == key[KEY_INDEX]); |
| 195 | } |
222 | } |
| 196 | 223 | ||
| 197 | void nodes_remove_callback(link_t *item) |
224 | void nodes_remove_callback(link_t *item) |
| 198 | { |
225 | { |
| 199 | vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link); |
- | |
| 200 | free(node); |
- | |
| 201 | } |
226 | } |
| 202 | 227 | ||
| 203 | /** |
228 | /** |
| 204 | * @} |
229 | * @} |
| 205 | */ |
230 | */ |