source: mainline/uspace/srv/fs/ext4fs/ext4fs_ops.c@ 6c501f8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6c501f8 was 6c501f8, checked in by Frantisek Princ <frantisek.princ@…>, 14 years ago

_mounted and _unmounted operations skeletons (copied from ext2fs)

  • Property mode set to 100644
File size: 9.1 KB
Line 
1/*
2 * Copyright (c) 2011 Frantisek Princ
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file ext4fs_ops.c
35 * @brief VFS operations for EXT4 filesystem.
36 */
37
38#include <errno.h>
39#include <fibril_synch.h>
40#include <libext4.h>
41#include <libfs.h>
42#include <malloc.h>
43#include <ipc/loc.h>
44#include "ext4fs.h"
45#include "../../vfs/vfs.h"
46
47#define EXT4FS_NODE(node) ((node) ? (ext4fs_node_t *) (node)->data : NULL)
48
49typedef struct ext4fs_instance {
50 link_t link;
51 service_id_t service_id;
52 ext4_filesystem_t *filesystem;
53 unsigned int open_nodes_count;
54} ext4fs_instance_t;
55
56typedef struct ext4fs_node {
57 ext4fs_instance_t *instance;
58 ext4_inode_ref_t *inode_ref;
59 fs_node_t *fs_node;
60 link_t link;
61 unsigned int references;
62} ext4fs_node_t;
63
64/*
65 * Forward declarations of auxiliary functions
66 */
67static int ext4fs_instance_get(service_id_t, ext4fs_instance_t **);
68static int ext4fs_node_get_core(fs_node_t **, ext4fs_instance_t *, fs_index_t);
69
70
71/*
72 * Forward declarations of EXT4 libfs operations.
73 */
74static int ext4fs_root_get(fs_node_t **, service_id_t);
75static int ext4fs_match(fs_node_t **, fs_node_t *, const char *);
76static int ext4fs_node_get(fs_node_t **, service_id_t, fs_index_t);
77static int ext4fs_node_open(fs_node_t *);
78static int ext4fs_node_put(fs_node_t *);
79static int ext4fs_create_node(fs_node_t **, service_id_t, int);
80static int ext4fs_destroy_node(fs_node_t *);
81static int ext4fs_link(fs_node_t *, fs_node_t *, const char *);
82static int ext4fs_unlink(fs_node_t *, fs_node_t *, const char *);
83static int ext4fs_has_children(bool *, fs_node_t *);
84static fs_index_t ext4fs_index_get(fs_node_t *);
85static aoff64_t ext4fs_size_get(fs_node_t *);
86static unsigned ext4fs_lnkcnt_get(fs_node_t *);
87static bool ext4fs_is_directory(fs_node_t *);
88static bool ext4fs_is_file(fs_node_t *node);
89static service_id_t ext4fs_service_get(fs_node_t *node);
90
91/*
92 * Static variables
93 */
94static LIST_INITIALIZE(instance_list);
95static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex);
96static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
97
98
99/**
100 * TODO comment
101 */
102int ext4fs_global_init(void)
103{
104 // TODO
105 return EOK;
106}
107
108int ext4fs_global_fini(void)
109{
110 // TODO
111 return EOK;
112}
113
114
115/*
116 * EXT4 libfs operations.
117 */
118
119int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
120{
121 ext4fs_instance_t *tmp;
122
123 fibril_mutex_lock(&instance_list_mutex);
124
125 if (list_empty(&instance_list)) {
126 fibril_mutex_unlock(&instance_list_mutex);
127 return EINVAL;
128 }
129
130 list_foreach(instance_list, link) {
131 tmp = list_get_instance(link, ext4fs_instance_t, link);
132
133 if (tmp->service_id == service_id) {
134 *inst = tmp;
135 fibril_mutex_unlock(&instance_list_mutex);
136 return EOK;
137 }
138 }
139
140 fibril_mutex_unlock(&instance_list_mutex);
141 return EINVAL;
142}
143
144int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
145{
146 // TODO
147 return 0;
148}
149
150int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
151{
152 // TODO
153 return EOK;
154}
155
156int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
157{
158 // TODO
159 return 0;
160}
161
162int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
163 fs_index_t index)
164{
165 // TODO
166 return EOK;
167}
168
169int ext4fs_node_open(fs_node_t *fn)
170{
171 // TODO
172 return EOK;
173}
174
175int ext4fs_node_put(fs_node_t *fn)
176{
177 // TODO
178 return EOK;
179}
180
181int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
182{
183 // TODO
184 return ENOTSUP;
185}
186
187int ext4fs_destroy_node(fs_node_t *fn)
188{
189 // TODO
190 return ENOTSUP;
191}
192
193int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
194{
195 // TODO
196 return ENOTSUP;
197}
198
199int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
200{
201 // TODO
202 return ENOTSUP;
203}
204
205int ext4fs_has_children(bool *has_children, fs_node_t *fn)
206{
207 // TODO
208 return EOK;
209}
210
211
212fs_index_t ext4fs_index_get(fs_node_t *fn)
213{
214 // TODO
215 return 0;
216}
217
218aoff64_t ext4fs_size_get(fs_node_t *fn)
219{
220 // TODO
221 return 0;
222}
223
224unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
225{
226 // TODO
227 return 0;
228}
229
230bool ext4fs_is_directory(fs_node_t *fn)
231{
232 // TODO
233 return false;
234}
235
236bool ext4fs_is_file(fs_node_t *fn)
237{
238 // TODO
239 return false;
240}
241
242service_id_t ext4fs_service_get(fs_node_t *fn)
243{
244 // TODO
245 return 0;
246}
247
248/*
249 * libfs operations.
250 */
251libfs_ops_t ext4fs_libfs_ops = {
252 .root_get = ext4fs_root_get,
253 .match = ext4fs_match,
254 .node_get = ext4fs_node_get,
255 .node_open = ext4fs_node_open,
256 .node_put = ext4fs_node_put,
257 .create = ext4fs_create_node,
258 .destroy = ext4fs_destroy_node,
259 .link = ext4fs_link,
260 .unlink = ext4fs_unlink,
261 .has_children = ext4fs_has_children,
262 .index_get = ext4fs_index_get,
263 .size_get = ext4fs_size_get,
264 .lnkcnt_get = ext4fs_lnkcnt_get,
265 .is_directory = ext4fs_is_directory,
266 .is_file = ext4fs_is_file,
267 .service_get = ext4fs_service_get
268};
269
270
271/*
272 * VFS operations.
273 */
274
275static int ext4fs_mounted(service_id_t service_id, const char *opts,
276 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
277{
278
279 int rc;
280 ext4_filesystem_t *fs;
281 ext4fs_instance_t *inst;
282 bool read_only;
283
284 /* Allocate libext4 filesystem structure */
285 fs = (ext4_filesystem_t *) malloc(sizeof(ext4_filesystem_t));
286 if (fs == NULL) {
287 return ENOMEM;
288 }
289
290 /* Allocate instance structure */
291 inst = (ext4fs_instance_t *) malloc(sizeof(ext4fs_instance_t));
292 if (inst == NULL) {
293 free(fs);
294 return ENOMEM;
295 }
296
297 /* Initialize the filesystem */
298 rc = ext4_filesystem_init(fs, service_id);
299 if (rc != EOK) {
300 free(fs);
301 free(inst);
302 return rc;
303 }
304
305 /* Do some sanity checking */
306 rc = ext4_filesystem_check_sanity(fs);
307 if (rc != EOK) {
308 ext4_filesystem_fini(fs);
309 free(fs);
310 free(inst);
311 return rc;
312 }
313
314 /* Check flags */
315 rc = ext4_filesystem_check_flags(fs, &read_only);
316 if (rc != EOK) {
317 ext4_filesystem_fini(fs);
318 free(fs);
319 free(inst);
320 return rc;
321 }
322
323 /* Initialize instance */
324 link_initialize(&inst->link);
325 inst->service_id = service_id;
326 inst->filesystem = fs;
327 inst->open_nodes_count = 0;
328
329 /* Read root node */
330 fs_node_t *root_node;
331 rc = ext4fs_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
332 if (rc != EOK) {
333 ext4_filesystem_fini(fs);
334 free(fs);
335 free(inst);
336 return rc;
337 }
338 ext4fs_node_t *enode = EXT4FS_NODE(root_node);
339
340 /* Add instance to the list */
341 fibril_mutex_lock(&instance_list_mutex);
342 list_append(&inst->link, &instance_list);
343 fibril_mutex_unlock(&instance_list_mutex);
344
345 *index = EXT4_INODE_ROOT_INDEX;
346 *size = 0;
347 *lnkcnt = ext4_inode_get_usage_count(enode->inode_ref->inode);
348
349 ext4fs_node_put(root_node);
350
351 return EOK;
352}
353
354static int ext4fs_unmounted(service_id_t service_id)
355{
356
357 int rc;
358 ext4fs_instance_t *inst;
359
360 rc = ext4fs_instance_get(service_id, &inst);
361
362 if (rc != EOK) {
363 return rc;
364 }
365
366 fibril_mutex_lock(&open_nodes_lock);
367
368 if (inst->open_nodes_count != 0) {
369 fibril_mutex_unlock(&open_nodes_lock);
370 return EBUSY;
371 }
372
373 /* Remove the instance from the list */
374 fibril_mutex_lock(&instance_list_mutex);
375 list_remove(&inst->link);
376 fibril_mutex_unlock(&instance_list_mutex);
377
378 fibril_mutex_unlock(&open_nodes_lock);
379
380 ext4_filesystem_fini(inst->filesystem);
381
382 return EOK;
383}
384
385static int
386ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
387 size_t *rbytes)
388{
389 // TODO
390 return 0;
391}
392
393static int
394ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
395 size_t *wbytes, aoff64_t *nsize)
396{
397 // TODO
398 return ENOTSUP;
399}
400
401static int
402ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
403{
404 // TODO
405 return ENOTSUP;
406}
407
408static int ext4fs_close(service_id_t service_id, fs_index_t index)
409{
410 // TODO
411 return EOK;
412}
413
414static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
415{
416 //TODO
417 return ENOTSUP;
418}
419
420static int ext4fs_sync(service_id_t service_id, fs_index_t index)
421{
422 // TODO
423 return ENOTSUP;
424}
425
426vfs_out_ops_t ext4fs_ops = {
427 .mounted = ext4fs_mounted,
428 .unmounted = ext4fs_unmounted,
429 .read = ext4fs_read,
430 .write = ext4fs_write,
431 .truncate = ext4fs_truncate,
432 .close = ext4fs_close,
433 .destroy = ext4fs_destroy,
434 .sync = ext4fs_sync,
435};
436
437/**
438 * @}
439 */
Note: See TracBrowser for help on using the repository browser.