Some rework, not yet complete.
@@ -163,17 +163,17 @@ | ||
163 | 163 | .open_file = drv_open_file |
164 | 164 | }; |
165 | 165 | |
166 | -static void node_release(void *instance); | |
167 | - | |
166 | +static void node_dir_release(void *instance); | |
168 | 167 | static msg_t node_dir_first(void *instance, vfs_node_info_t *nip); |
169 | 168 | static msg_t node_dir_next(void *instance, vfs_node_info_t *nip); |
170 | 169 | |
171 | 170 | static const struct vfs_stream_dir_node_vmt dir_node_vmt = { |
172 | - .release = node_release, | |
171 | + .release = node_dir_release, | |
173 | 172 | .dir_first = node_dir_first, |
174 | 173 | .dir_next = node_dir_next |
175 | 174 | }; |
176 | 175 | |
176 | +static void node_file_release(void *instance); | |
177 | 177 | static BaseSequentialStream *node_file_get_stream(void *instance); |
178 | 178 | static ssize_t node_file_read(void *instance, uint8_t *buf, size_t n); |
179 | 179 | static ssize_t node_file_write(void *instance, const uint8_t *buf, size_t n); |
@@ -182,7 +182,7 @@ | ||
182 | 182 | static vfs_offset_t node_file_getsize(void *instance); |
183 | 183 | |
184 | 184 | static const struct vfs_stream_file_node_vmt file_node_vmt = { |
185 | - .release = node_release, | |
185 | + .release = node_file_release, | |
186 | 186 | .get_stream = node_file_get_stream, |
187 | 187 | .file_read = node_file_read, |
188 | 188 | .file_write = node_file_write, |
@@ -191,7 +191,7 @@ | ||
191 | 191 | .file_getsize = node_file_getsize |
192 | 192 | }; |
193 | 193 | |
194 | -static vfs_stream_file_node_t drv_dir_nodes[DRV_DIR_NODES_NUM]; | |
194 | +static vfs_stream_dir_node_t drv_dir_nodes[DRV_DIR_NODES_NUM]; | |
195 | 195 | static vfs_stream_file_node_t drv_file_nodes[DRV_FILE_NODES_NUM]; |
196 | 196 | |
197 | 197 | static vfs_streams_driver_t drv_streams; |
@@ -285,13 +285,13 @@ | ||
285 | 285 | return err; |
286 | 286 | } |
287 | 287 | |
288 | -static void node_release(void *instance) { | |
289 | - vfs_stream_file_node_t *sfnp = (vfs_stream_file_node_t *)instance; | |
288 | +static void node_dir_release(void *instance) { | |
289 | + vfs_stream_dir_node_t *sdnp = (vfs_stream_dir_node_t *)instance; | |
290 | 290 | |
291 | - if (--sfnp->refs == 0U) { | |
291 | + if (--sdnp->refs == 0U) { | |
292 | 292 | |
293 | - chPoolFree(&((vfs_streams_driver_t *)sfnp->driver)->file_nodes_pool, | |
294 | - (void *)sfnp); | |
293 | + chPoolFree(&((vfs_streams_driver_t *)sdnp->driver)->dir_nodes_pool, | |
294 | + (void *)sdnp); | |
295 | 295 | } |
296 | 296 | } |
297 | 297 |
@@ -320,6 +320,16 @@ | ||
320 | 320 | return VFS_RET_EOF; |
321 | 321 | } |
322 | 322 | |
323 | +static void node_file_release(void *instance) { | |
324 | + vfs_stream_file_node_t *sfnp = (vfs_stream_file_node_t *)instance; | |
325 | + | |
326 | + if (--sfnp->refs == 0U) { | |
327 | + | |
328 | + chPoolFree(&((vfs_streams_driver_t *)sfnp->driver)->file_nodes_pool, | |
329 | + (void *)sfnp); | |
330 | + } | |
331 | +} | |
332 | + | |
323 | 333 | static BaseSequentialStream *node_file_get_stream(void *instance) { |
324 | 334 | vfs_stream_file_node_t *sfnp = (vfs_stream_file_node_t *)instance; |
325 | 335 |
@@ -32,6 +32,26 @@ | ||
32 | 32 | /* Module constants. */ |
33 | 33 | /*===========================================================================*/ |
34 | 34 | |
35 | +/** | |
36 | + * @brief @p vfs_root_driver_t specific methods. | |
37 | + */ | |
38 | +#define __vfs_root_driver_methods \ | |
39 | + __vfs_driver_methods | |
40 | + | |
41 | +/** | |
42 | + * @brief @p vfs_root_driver_t specific data. | |
43 | + */ | |
44 | +#define __vfs_root_driver_data \ | |
45 | + __vfs_driver_data \ | |
46 | + /* VFS access mutex.*/ \ | |
47 | + mutex_t mtx; \ | |
48 | + /* Pool of the root directory nodes.*/ \ | |
49 | + memory_pool_t dir_nodes_pool; \ | |
50 | + /* Next registration slot.*/ \ | |
51 | + vfs_driver_t **next_driver; \ | |
52 | + /* Registration slots.*/ \ | |
53 | + vfs_driver_t *drivers[VFS_CFG_MAX_DRIVERS]; | |
54 | + | |
35 | 55 | /*===========================================================================*/ |
36 | 56 | /* Module pre-compile time settings. */ |
37 | 57 | /*===========================================================================*/ |
@@ -45,38 +65,32 @@ | ||
45 | 65 | /*===========================================================================*/ |
46 | 66 | |
47 | 67 | /** |
68 | + * @brief @p vfs_root_driver_t virtual methods table. | |
69 | + */ | |
70 | +struct vfs_root_driver_vmt { | |
71 | + __vfs_root_driver_methods | |
72 | +}; | |
73 | + | |
74 | +/** | |
48 | 75 | * @brief Type of a structure representing the VFS system. |
49 | 76 | */ |
50 | -typedef struct vfs_system { | |
77 | +typedef struct vfs_root_driver { | |
51 | 78 | /** |
52 | - * @brief VFS access mutex. | |
79 | + * @brief Virtual Methods Table. | |
53 | 80 | */ |
54 | - mutex_t mtx; | |
55 | - /** | |
56 | - * @brief Next registration slot. | |
57 | - */ | |
58 | - vfs_driver_t **next_driver; | |
59 | - /** | |
60 | - * @brief Registration slots. | |
61 | - */ | |
62 | - vfs_driver_t *drivers[VFS_CFG_MAX_DRIVERS]; | |
63 | -} vfs_system_t; | |
81 | + const struct vfs_root_driver_vmt *vmt; | |
82 | + __vfs_root_driver_data | |
83 | +} vfs_root_driver_t; | |
64 | 84 | |
65 | 85 | /*===========================================================================*/ |
66 | 86 | /* Module macros. */ |
67 | 87 | /*===========================================================================*/ |
68 | 88 | |
69 | -/* | |
70 | - * Defaults on the best synchronization mechanism available. | |
71 | - */ | |
72 | -#define VFS_LOCK() osalMutexLock(&vfs.mtx) | |
73 | -#define VFS_UNLOCK() osalMutexUnlock(&vfs.mtx) | |
74 | - | |
75 | 89 | /*===========================================================================*/ |
76 | 90 | /* External declarations. */ |
77 | 91 | /*===========================================================================*/ |
78 | 92 | |
79 | -extern vfs_system_t vfs; | |
93 | +extern vfs_root_driver_t vfs; | |
80 | 94 | |
81 | 95 | #ifdef __cplusplus |
82 | 96 | extern "C" { |
@@ -34,6 +34,11 @@ | ||
34 | 34 | /*===========================================================================*/ |
35 | 35 | |
36 | 36 | /** |
37 | + * @brief Number of directory nodes pre-allocated in the pool. | |
38 | + */ | |
39 | +#define ROOT_DIR_NODES_NUM 1 | |
40 | + | |
41 | +/** | |
37 | 42 | * @brief @p vfs_root_dir_node_t specific methods. |
38 | 43 | */ |
39 | 44 | #define __vfs_root_dir_node_methods \ |
@@ -51,9 +56,9 @@ | ||
51 | 56 | /*===========================================================================*/ |
52 | 57 | |
53 | 58 | /** |
54 | - * @brief Global VFS state. | |
59 | + * @brief Root VFS driver. | |
55 | 60 | */ |
56 | -vfs_system_t vfs; | |
61 | +vfs_root_driver_t vfs; | |
57 | 62 | |
58 | 63 | /*===========================================================================*/ |
59 | 64 | /* Module local types. */ |
@@ -81,6 +86,30 @@ | ||
81 | 86 | /* Module local variables. */ |
82 | 87 | /*===========================================================================*/ |
83 | 88 | |
89 | +static vfs_root_dir_node_t root_dir_nodes[ROOT_DIR_NODES_NUM]; | |
90 | + | |
91 | +static msg_t root_open_dir(void *instance, | |
92 | + const char *path, | |
93 | + vfs_directory_node_t **vdnpp); | |
94 | +static msg_t root_open_file(void *instance, | |
95 | + const char *path, | |
96 | + vfs_file_node_t **vfnpp); | |
97 | + | |
98 | +static const struct vfs_root_driver_vmt root_driver_vmt = { | |
99 | + .open_dir = root_open_dir, | |
100 | + .open_file = root_open_file | |
101 | +}; | |
102 | + | |
103 | +static void node_dir_release(void *instance); | |
104 | +static msg_t node_dir_first(void *instance, vfs_node_info_t *nip); | |
105 | +static msg_t node_dir_next(void *instance, vfs_node_info_t *nip); | |
106 | + | |
107 | +static const struct vfs_root_dir_node_vmt root_dir_node_vmt = { | |
108 | + .release = node_dir_release, | |
109 | + .dir_first = node_dir_first, | |
110 | + .dir_next = node_dir_next | |
111 | +}; | |
112 | + | |
84 | 113 | /*===========================================================================*/ |
85 | 114 | /* Module local functions. */ |
86 | 115 | /*===========================================================================*/ |
@@ -91,9 +120,6 @@ | ||
91 | 120 | vfs_driver_t **pp; |
92 | 121 | |
93 | 122 | do { |
94 | - err = vfs_parse_match_separator(pathp); | |
95 | - VFS_BREAK_ON_ERROR(err); | |
96 | - | |
97 | 123 | err = vfs_parse_filename(pathp, fname); |
98 | 124 | VFS_BREAK_ON_ERROR(err); |
99 | 125 |
@@ -113,6 +139,30 @@ | ||
113 | 139 | return err; |
114 | 140 | } |
115 | 141 | |
142 | +static void node_dir_release(void *instance) { | |
143 | + vfs_root_dir_node_t *rdnp = (vfs_root_dir_node_t *)instance; | |
144 | + | |
145 | + if (--rdnp->refs == 0U) { | |
146 | + | |
147 | + chPoolFree(&((vfs_root_driver_t *)rdnp->driver)->dir_nodes_pool, | |
148 | + (void *)rdnp); | |
149 | + } | |
150 | +} | |
151 | + | |
152 | +static msg_t node_dir_first(void *instance, vfs_node_info_t *nip) { | |
153 | + vfs_root_dir_node_t *rdnp = (vfs_root_dir_node_t *)instance; | |
154 | + | |
155 | + rdnp->index = 0U; | |
156 | + | |
157 | + return node_dir_next(instance, nip); | |
158 | +} | |
159 | + | |
160 | +static msg_t node_dir_next(void *instance, vfs_node_info_t *nip) { | |
161 | + vfs_root_dir_node_t *rdnp = (vfs_root_dir_node_t *)instance; | |
162 | + | |
163 | + return VFS_RET_EOF; | |
164 | +} | |
165 | + | |
116 | 166 | /*===========================================================================*/ |
117 | 167 | /* Module exported functions. */ |
118 | 168 | /*===========================================================================*/ |
@@ -127,6 +177,12 @@ | ||
127 | 177 | |
128 | 178 | vfs.next_driver = &vfs.drivers[0]; |
129 | 179 | |
180 | + chPoolObjectInit(&vfs.dir_nodes_pool, | |
181 | + sizeof (vfs_root_dir_node_t), | |
182 | + chCoreAllocAligned); | |
183 | + chPoolLoadArray(&vfs.dir_nodes_pool, | |
184 | + root_dir_nodes, | |
185 | + ROOT_DIR_NODES_NUM); | |
130 | 186 | #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) |
131 | 187 | chMtxObjectInit(&vfs.mtx); |
132 | 188 | #else |
@@ -145,8 +201,6 @@ | ||
145 | 201 | msg_t vfsRegisterDriver(vfs_driver_t *vdp) { |
146 | 202 | msg_t err; |
147 | 203 | |
148 | - VFS_LOCK(); | |
149 | - | |
150 | 204 | if (vfs.next_driver >= &vfs.drivers[VFS_CFG_MAX_DRIVERS]) { |
151 | 205 | err = VFS_RET_NO_RESOURCE; |
152 | 206 | } |
@@ -155,8 +209,6 @@ | ||
155 | 209 | err = VFS_RET_SUCCESS; |
156 | 210 | } |
157 | 211 | |
158 | - VFS_UNLOCK(); | |
159 | - | |
160 | 212 | return err; |
161 | 213 | } |
162 | 214 |
@@ -175,10 +227,31 @@ | ||
175 | 227 | vfs_driver_t *dp; |
176 | 228 | |
177 | 229 | do { |
178 | - err = match_driver(&path, &dp); | |
230 | + err = vfs_parse_match_separator(&path); | |
179 | 231 | VFS_BREAK_ON_ERROR(err); |
180 | 232 | |
181 | - err = dp->vmt->open_dir((void *)dp, path, vdnpp); | |
233 | + if (*path == '\0') { | |
234 | + /* Creating a root directory node.*/ | |
235 | + vfs_root_dir_node_t *rdnp = chPoolAlloc(&vfs.dir_nodes_pool); | |
236 | + if (rdnp != NULL) { | |
237 | + | |
238 | + /* Node object initialization.*/ | |
239 | + rdnp->vmt = &root_dir_node_vmt; | |
240 | + rdnp->refs = 1U; | |
241 | + rdnp->driver = (vfs_driver_t *)&vfs; | |
242 | + rdnp->index = 0U; | |
243 | + | |
244 | + *vdnpp = (vfs_directory_node_t *)rdnp; | |
245 | + return VFS_RET_SUCCESS; | |
246 | + } | |
247 | + } | |
248 | + else { | |
249 | + /* Delegating node creation to a registered driver.*/ | |
250 | + err = match_driver(&path, &dp); | |
251 | + VFS_BREAK_ON_ERROR(err); | |
252 | + | |
253 | + err = dp->vmt->open_dir((void *)dp, path, vdnpp); | |
254 | + } | |
182 | 255 | } |
183 | 256 | while (false); |
184 | 257 |
@@ -249,6 +322,9 @@ | ||
249 | 322 | vfs_driver_t *dp; |
250 | 323 | |
251 | 324 | do { |
325 | + err = vfs_parse_match_separator(&path); | |
326 | + VFS_BREAK_ON_ERROR(err); | |
327 | + | |
252 | 328 | err = match_driver(&path, &dp); |
253 | 329 | VFS_BREAK_ON_ERROR(err); |
254 | 330 |