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 | */ |