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

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

part of code needed for successful mount (porting from ext2)

  • Property mode set to 100644
File size: 10.5 KB
RevLine 
[d3a9ae74]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>
[6c501f8]39#include <fibril_synch.h>
40#include <libext4.h>
[d3a9ae74]41#include <libfs.h>
[6c501f8]42#include <malloc.h>
[9c0c0e1]43#include <stdio.h>
[d3a9ae74]44#include <ipc/loc.h>
45#include "ext4fs.h"
46#include "../../vfs/vfs.h"
47
[6c501f8]48#define EXT4FS_NODE(node) ((node) ? (ext4fs_node_t *) (node)->data : NULL)
[9c0c0e1]49#define EXT4FS_DBG(format, ...) {if (true) printf("ext4fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);}
[6c501f8]50
51typedef struct ext4fs_instance {
52 link_t link;
53 service_id_t service_id;
54 ext4_filesystem_t *filesystem;
55 unsigned int open_nodes_count;
56} ext4fs_instance_t;
57
58typedef struct ext4fs_node {
59 ext4fs_instance_t *instance;
60 ext4_inode_ref_t *inode_ref;
61 fs_node_t *fs_node;
62 link_t link;
63 unsigned int references;
64} ext4fs_node_t;
65
66/*
67 * Forward declarations of auxiliary functions
68 */
69static int ext4fs_instance_get(service_id_t, ext4fs_instance_t **);
70static int ext4fs_node_get_core(fs_node_t **, ext4fs_instance_t *, fs_index_t);
[9c0c0e1]71static int ext4fs_node_put_core(ext4fs_node_t *);
[d3a9ae74]72
73/*
74 * Forward declarations of EXT4 libfs operations.
75 */
76static int ext4fs_root_get(fs_node_t **, service_id_t);
77static int ext4fs_match(fs_node_t **, fs_node_t *, const char *);
78static int ext4fs_node_get(fs_node_t **, service_id_t, fs_index_t);
79static int ext4fs_node_open(fs_node_t *);
80static int ext4fs_node_put(fs_node_t *);
81static int ext4fs_create_node(fs_node_t **, service_id_t, int);
82static int ext4fs_destroy_node(fs_node_t *);
83static int ext4fs_link(fs_node_t *, fs_node_t *, const char *);
84static int ext4fs_unlink(fs_node_t *, fs_node_t *, const char *);
85static int ext4fs_has_children(bool *, fs_node_t *);
86static fs_index_t ext4fs_index_get(fs_node_t *);
87static aoff64_t ext4fs_size_get(fs_node_t *);
88static unsigned ext4fs_lnkcnt_get(fs_node_t *);
89static bool ext4fs_is_directory(fs_node_t *);
90static bool ext4fs_is_file(fs_node_t *node);
91static service_id_t ext4fs_service_get(fs_node_t *node);
92
[6c501f8]93/*
94 * Static variables
95 */
96static LIST_INITIALIZE(instance_list);
97static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex);
98static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
99
100
[d3a9ae74]101/**
[01ab41b]102 * TODO doxy
[d3a9ae74]103 */
104int ext4fs_global_init(void)
105{
106 // TODO
107 return EOK;
108}
109
[01ab41b]110/**
111 * TODO doxy
112 */
[d3a9ae74]113int ext4fs_global_fini(void)
114{
115 // TODO
116 return EOK;
117}
118
119
120/*
121 * EXT4 libfs operations.
122 */
123
[9c0c0e1]124/**
125 * TODO doxy
126 */
[6c501f8]127int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
128{
129 ext4fs_instance_t *tmp;
130
131 fibril_mutex_lock(&instance_list_mutex);
132
133 if (list_empty(&instance_list)) {
134 fibril_mutex_unlock(&instance_list_mutex);
135 return EINVAL;
136 }
137
138 list_foreach(instance_list, link) {
139 tmp = list_get_instance(link, ext4fs_instance_t, link);
140
141 if (tmp->service_id == service_id) {
142 *inst = tmp;
143 fibril_mutex_unlock(&instance_list_mutex);
144 return EOK;
145 }
146 }
147
148 fibril_mutex_unlock(&instance_list_mutex);
149 return EINVAL;
150}
151
[9c0c0e1]152/**
153 * TODO doxy
154 */
[d3a9ae74]155int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
156{
[01ab41b]157 return ext4fs_node_get(rfn, service_id, EXT4_INODE_ROOT_INDEX);
[d3a9ae74]158}
159
[9c0c0e1]160/**
161 * TODO doxy
162 */
[d3a9ae74]163int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
164{
165 // TODO
166 return EOK;
167}
168
[9c0c0e1]169/**
170 * TODO doxy
171 */
[d3a9ae74]172int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
173{
[9c0c0e1]174 ext4fs_instance_t *inst = NULL;
175 int rc;
176
177 rc = ext4fs_instance_get(service_id, &inst);
178 if (rc != EOK) {
179 return rc;
180 }
181
182 return ext4fs_node_get_core(rfn, inst, index);
[d3a9ae74]183}
184
[9c0c0e1]185/**
186 * TODO doxy
187 */
[6c501f8]188int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
189 fs_index_t index)
190{
191 // TODO
192 return EOK;
193}
194
[9c0c0e1]195/**
196 * TODO doxy
197 */
198int ext4fs_node_put_core(ext4fs_node_t *enode) {
199 // TODO
200 return EOK;
201}
202
[01ab41b]203/**
204 * TODO doxy
205 */
[d3a9ae74]206int ext4fs_node_open(fs_node_t *fn)
207{
[01ab41b]208 // TODO stateless operation
[d3a9ae74]209 return EOK;
210}
211
212int ext4fs_node_put(fs_node_t *fn)
213{
[9c0c0e1]214 EXT4FS_DBG("");
215 int rc;
216 ext4fs_node_t *enode = EXT4FS_NODE(fn);
217
218 fibril_mutex_lock(&open_nodes_lock);
219
220 assert(enode->references > 0);
221 enode->references--;
222 if (enode->references == 0) {
223 rc = ext4fs_node_put_core(enode);
224 if (rc != EOK) {
225 fibril_mutex_unlock(&open_nodes_lock);
226 return rc;
227 }
228 }
229
230 fibril_mutex_unlock(&open_nodes_lock);
231
[d3a9ae74]232 return EOK;
233}
234
235int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
236{
237 // TODO
238 return ENOTSUP;
239}
240
241int ext4fs_destroy_node(fs_node_t *fn)
242{
243 // TODO
244 return ENOTSUP;
245}
246
247int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
248{
249 // TODO
250 return ENOTSUP;
251}
252
253int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
254{
255 // TODO
256 return ENOTSUP;
257}
258
259int ext4fs_has_children(bool *has_children, fs_node_t *fn)
260{
261 // TODO
262 return EOK;
263}
264
265
266fs_index_t ext4fs_index_get(fs_node_t *fn)
267{
268 // TODO
269 return 0;
270}
271
272aoff64_t ext4fs_size_get(fs_node_t *fn)
273{
274 // TODO
275 return 0;
276}
277
278unsigned ext4fs_lnkcnt_get(fs_node_t *fn)
279{
280 // TODO
281 return 0;
282}
283
284bool ext4fs_is_directory(fs_node_t *fn)
285{
286 // TODO
287 return false;
288}
289
290bool ext4fs_is_file(fs_node_t *fn)
291{
292 // TODO
293 return false;
294}
295
296service_id_t ext4fs_service_get(fs_node_t *fn)
297{
298 // TODO
299 return 0;
300}
301
302/*
303 * libfs operations.
304 */
305libfs_ops_t ext4fs_libfs_ops = {
306 .root_get = ext4fs_root_get,
307 .match = ext4fs_match,
308 .node_get = ext4fs_node_get,
309 .node_open = ext4fs_node_open,
310 .node_put = ext4fs_node_put,
311 .create = ext4fs_create_node,
312 .destroy = ext4fs_destroy_node,
313 .link = ext4fs_link,
314 .unlink = ext4fs_unlink,
315 .has_children = ext4fs_has_children,
316 .index_get = ext4fs_index_get,
317 .size_get = ext4fs_size_get,
318 .lnkcnt_get = ext4fs_lnkcnt_get,
319 .is_directory = ext4fs_is_directory,
320 .is_file = ext4fs_is_file,
321 .service_get = ext4fs_service_get
322};
323
324
325/*
326 * VFS operations.
327 */
328
[9c0c0e1]329/**
330 * TODO doxy
331 */
[d3a9ae74]332static int ext4fs_mounted(service_id_t service_id, const char *opts,
333 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
334{
[6c501f8]335
[9c0c0e1]336 EXT4FS_DBG("Mounting...");
337
[6c501f8]338 int rc;
339 ext4_filesystem_t *fs;
340 ext4fs_instance_t *inst;
341 bool read_only;
342
343 /* Allocate libext4 filesystem structure */
344 fs = (ext4_filesystem_t *) malloc(sizeof(ext4_filesystem_t));
345 if (fs == NULL) {
346 return ENOMEM;
347 }
348
349 /* Allocate instance structure */
350 inst = (ext4fs_instance_t *) malloc(sizeof(ext4fs_instance_t));
351 if (inst == NULL) {
352 free(fs);
353 return ENOMEM;
354 }
355
[9c0c0e1]356 EXT4FS_DBG("Basic structures allocated");
357
358 /* Initialize the filesystem */
[6c501f8]359 rc = ext4_filesystem_init(fs, service_id);
360 if (rc != EOK) {
361 free(fs);
362 free(inst);
363 return rc;
364 }
365
[9c0c0e1]366 EXT4FS_DBG("initialized");
367
[6c501f8]368 /* Do some sanity checking */
369 rc = ext4_filesystem_check_sanity(fs);
370 if (rc != EOK) {
371 ext4_filesystem_fini(fs);
372 free(fs);
373 free(inst);
374 return rc;
375 }
376
[9c0c0e1]377 EXT4FS_DBG("Checked and clean");
378
[6c501f8]379 /* Check flags */
[9c0c0e1]380 rc = ext4_filesystem_check_features(fs, &read_only);
[6c501f8]381 if (rc != EOK) {
382 ext4_filesystem_fini(fs);
383 free(fs);
384 free(inst);
385 return rc;
386 }
387
[9c0c0e1]388 EXT4FS_DBG("Features checked");
389
[6c501f8]390 /* Initialize instance */
391 link_initialize(&inst->link);
392 inst->service_id = service_id;
393 inst->filesystem = fs;
394 inst->open_nodes_count = 0;
395
[9c0c0e1]396 EXT4FS_DBG("Instance initialized");
397
[6c501f8]398 /* Read root node */
399 fs_node_t *root_node;
[9c0c0e1]400 rc = ext4fs_root_get(&root_node, inst->service_id);
[6c501f8]401 if (rc != EOK) {
402 ext4_filesystem_fini(fs);
403 free(fs);
404 free(inst);
405 return rc;
406 }
407 ext4fs_node_t *enode = EXT4FS_NODE(root_node);
408
[9c0c0e1]409 EXT4FS_DBG("Root node found");
410
[6c501f8]411 /* Add instance to the list */
412 fibril_mutex_lock(&instance_list_mutex);
413 list_append(&inst->link, &instance_list);
414 fibril_mutex_unlock(&instance_list_mutex);
415
[9c0c0e1]416 EXT4FS_DBG("Instance added");
417
[6c501f8]418 *index = EXT4_INODE_ROOT_INDEX;
419 *size = 0;
420 *lnkcnt = ext4_inode_get_usage_count(enode->inode_ref->inode);
421
[9c0c0e1]422 EXT4FS_DBG("Return values set");
423
[6c501f8]424 ext4fs_node_put(root_node);
425
[9c0c0e1]426 EXT4FS_DBG("Mounting finished");
427
[d3a9ae74]428 return EOK;
429}
430
[9c0c0e1]431/**
432 * TODO doxy
433 */
[d3a9ae74]434static int ext4fs_unmounted(service_id_t service_id)
435{
[6c501f8]436
437 int rc;
438 ext4fs_instance_t *inst;
439
440 rc = ext4fs_instance_get(service_id, &inst);
441
442 if (rc != EOK) {
443 return rc;
444 }
445
446 fibril_mutex_lock(&open_nodes_lock);
447
448 if (inst->open_nodes_count != 0) {
449 fibril_mutex_unlock(&open_nodes_lock);
450 return EBUSY;
451 }
452
453 /* Remove the instance from the list */
454 fibril_mutex_lock(&instance_list_mutex);
455 list_remove(&inst->link);
456 fibril_mutex_unlock(&instance_list_mutex);
457
458 fibril_mutex_unlock(&open_nodes_lock);
459
460 ext4_filesystem_fini(inst->filesystem);
461
[d3a9ae74]462 return EOK;
463}
464
[9c0c0e1]465/**
466 * TODO doxy
467 */
[d3a9ae74]468static int
469ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
470 size_t *rbytes)
471{
472 // TODO
473 return 0;
474}
475
[9c0c0e1]476/**
477 * TODO doxy
478 */
[d3a9ae74]479static int
480ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
481 size_t *wbytes, aoff64_t *nsize)
482{
483 // TODO
484 return ENOTSUP;
485}
486
[9c0c0e1]487/**
488 * TODO doxy
489 */
[d3a9ae74]490static int
491ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
492{
493 // TODO
494 return ENOTSUP;
495}
496
[9c0c0e1]497/**
498 * TODO doxy
499 */
[d3a9ae74]500static int ext4fs_close(service_id_t service_id, fs_index_t index)
501{
502 // TODO
503 return EOK;
504}
505
[9c0c0e1]506/**
507 * TODO doxy
508 */
[d3a9ae74]509static int ext4fs_destroy(service_id_t service_id, fs_index_t index)
510{
511 //TODO
512 return ENOTSUP;
513}
514
[9c0c0e1]515/**
516 * TODO doxy
517 */
[d3a9ae74]518static int ext4fs_sync(service_id_t service_id, fs_index_t index)
519{
520 // TODO
521 return ENOTSUP;
522}
523
524vfs_out_ops_t ext4fs_ops = {
525 .mounted = ext4fs_mounted,
526 .unmounted = ext4fs_unmounted,
527 .read = ext4fs_read,
528 .write = ext4fs_write,
529 .truncate = ext4fs_truncate,
530 .close = ext4fs_close,
531 .destroy = ext4fs_destroy,
532 .sync = ext4fs_sync,
533};
534
535/**
536 * @}
537 */
Note: See TracBrowser for help on using the repository browser.