source: mainline/uspace/srv/fs/minixfs/mfs_ops.c@ cfac897

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cfac897 was cfac897, checked in by Maurizio Lombardi <m.lombardi85@…>, 15 years ago

Use the on_error() macro where appropriated

  • Property mode set to 100644
File size: 17.4 KB
Line 
1/*
2 * Copyright (c) 2011 Maurizio Lombardi
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#include <stdio.h>
34#include <stdlib.h>
35#include <assert.h>
36#include <fibril_synch.h>
37#include <errno.h>
38#include "mfs.h"
39#include "mfs_utils.h"
40
41static bool check_magic_number(uint16_t magic, bool *native,
42 mfs_version_t *version, bool *longfilenames);
43static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst,
44 fs_index_t index);
45
46static int mfs_node_put(fs_node_t *fsnode);
47static int mfs_node_open(fs_node_t *fsnode);
48static fs_index_t mfs_index_get(fs_node_t *fsnode);
49static unsigned mfs_lnkcnt_get(fs_node_t *fsnode);
50static char mfs_plb_get_char(unsigned pos);
51static bool mfs_is_directory(fs_node_t *fsnode);
52static bool mfs_is_file(fs_node_t *fsnode);
53static int mfs_has_children(bool *has_children, fs_node_t *fsnode);
54static int mfs_root_get(fs_node_t **rfn, devmap_handle_t handle);
55static devmap_handle_t mfs_device_get(fs_node_t *fsnode);
56static aoff64_t mfs_size_get(fs_node_t *node);
57static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component);
58static int mfs_create_node(fs_node_t **rfn, devmap_handle_t handle, int flags);
59static int mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name);
60
61static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
62 fs_index_t index);
63
64
65static LIST_INITIALIZE(inst_list);
66static FIBRIL_MUTEX_INITIALIZE(inst_list_mutex);
67
68libfs_ops_t mfs_libfs_ops = {
69 .size_get = mfs_size_get,
70 .root_get = mfs_root_get,
71 .device_get = mfs_device_get,
72 .is_directory = mfs_is_directory,
73 .is_file = mfs_is_file,
74 .node_get = mfs_node_get,
75 .node_put = mfs_node_put,
76 .node_open = mfs_node_open,
77 .index_get = mfs_index_get,
78 .match = mfs_match,
79 .create = mfs_create_node,
80 .link = mfs_link,
81 .plb_get_char = mfs_plb_get_char,
82 .has_children = mfs_has_children,
83 .lnkcnt_get = mfs_lnkcnt_get
84};
85
86void mfs_mounted(ipc_callid_t rid, ipc_call_t *request)
87{
88 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
89 enum cache_mode cmode;
90 struct mfs_superblock *sb;
91 struct mfs3_superblock *sb3;
92 struct mfs_sb_info *sbi;
93 struct mfs_instance *instance;
94 bool native, longnames;
95 mfs_version_t version;
96 uint16_t magic;
97
98 /* Accept the mount options */
99 char *opts;
100 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
101
102 if (rc != EOK) {
103 mfsdebug("Can't accept async data write\n");
104 async_answer_0(rid, rc);
105 return;
106 }
107
108 /* Check for option enabling write through. */
109 if (str_cmp(opts, "wtcache") == 0)
110 cmode = CACHE_MODE_WT;
111 else
112 cmode = CACHE_MODE_WB;
113
114 free(opts);
115
116 /* initialize libblock */
117 rc = block_init(devmap_handle, 1024);
118 if (rc != EOK) {
119 mfsdebug("libblock initialization failed\n");
120 async_answer_0(rid, rc);
121 return;
122 }
123
124 /*Allocate space for generic MFS superblock*/
125 sbi = malloc(sizeof(*sbi));
126
127 if (!sbi) {
128 async_answer_0(rid, ENOMEM);
129 return;
130 }
131
132 /*Allocate space for filesystem instance*/
133 instance = malloc(sizeof(*instance));
134
135 if (!instance) {
136 async_answer_0(rid, ENOMEM);
137 return;
138 }
139
140 sb = malloc(MFS_SUPERBLOCK_SIZE);
141
142 if (!sb) {
143 async_answer_0(rid, ENOMEM);
144 return;
145 }
146
147 /* Read the superblock */
148 rc = block_read_direct(devmap_handle, MFS_SUPERBLOCK << 1, 1, sb);
149 if (rc != EOK) {
150 block_fini(devmap_handle);
151 async_answer_0(rid, rc);
152 return;
153 }
154
155 sb3 = (struct mfs3_superblock *) sb;
156
157 if (check_magic_number(sb->s_magic, &native, &version, &longnames)) {
158 /*This is a V1 or V2 Minix filesystem*/
159 magic = sb->s_magic;
160 goto recognized;
161 }
162
163 if (!check_magic_number(sb3->s_magic, &native, &version, &longnames)) {
164 mfsdebug("magic number not recognized\n");
165 block_fini(devmap_handle);
166 async_answer_0(rid, ENOTSUP);
167 return;
168 }
169
170 /*This is a V3 Minix filesystem*/
171
172 magic = sb3->s_magic;
173
174recognized:
175
176 mfsdebug("magic number recognized = %04x\n", magic);
177
178 /*Fill superblock info structure*/
179
180 sbi->fs_version = version;
181 sbi->long_names = longnames;
182 sbi->native = native;
183 sbi->magic = magic;
184 sbi->isearch = 0;
185 sbi->zsearch = 0;
186
187 if (version == MFS_VERSION_V3) {
188 sbi->ninodes = conv32(native, sb3->s_ninodes);
189 sbi->ibmap_blocks = conv16(native, sb3->s_ibmap_blocks);
190 sbi->zbmap_blocks = conv16(native, sb3->s_zbmap_blocks);
191 sbi->firstdatazone = conv16(native, sb3->s_first_data_zone);
192 sbi->log2_zone_size = conv16(native, sb3->s_log2_zone_size);
193 sbi->max_file_size = conv32(native, sb3->s_max_file_size);
194 sbi->nzones = conv32(native, sb3->s_nzones);
195 sbi->block_size = conv16(native, sb3->s_block_size);
196 sbi->ino_per_block = V3_INODES_PER_BLOCK(sbi->block_size);
197 sbi->dirsize = MFS3_DIRSIZE;
198 sbi->max_name_len = MFS3_MAX_NAME_LEN;
199 } else {
200 sbi->ninodes = conv16(native, sb->s_ninodes);
201 sbi->ibmap_blocks = conv16(native, sb->s_ibmap_blocks);
202 sbi->zbmap_blocks = conv16(native, sb->s_zbmap_blocks);
203 sbi->firstdatazone = conv16(native, sb->s_first_data_zone);
204 sbi->log2_zone_size = conv16(native, sb->s_log2_zone_size);
205 sbi->max_file_size = conv32(native, sb->s_max_file_size);
206 sbi->block_size = MFS_BLOCKSIZE;
207 if (version == MFS_VERSION_V2) {
208 sbi->nzones = conv32(native, sb->s_nzones2);
209 sbi->ino_per_block = V2_INODES_PER_BLOCK;
210 } else {
211 sbi->nzones = conv16(native, sb->s_nzones);
212 sbi->ino_per_block = V1_INODES_PER_BLOCK;
213 }
214 sbi->dirsize = longnames ? MFSL_DIRSIZE : MFS_DIRSIZE;
215 sbi->max_name_len = longnames ? MFS_L_MAX_NAME_LEN :
216 MFS_MAX_NAME_LEN;
217 }
218 sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks;
219
220 free(sb);
221
222 rc = block_cache_init(devmap_handle, sbi->block_size, 0, cmode);
223
224 if (rc != EOK) {
225 block_fini(devmap_handle);
226 async_answer_0(rid, EINVAL);
227 mfsdebug("block cache initialization failed\n");
228 return;
229 }
230
231 /*Initialize the instance structure and add it to the list*/
232 link_initialize(&instance->link);
233 instance->handle = devmap_handle;
234 instance->sbi = sbi;
235
236 fibril_mutex_lock(&inst_list_mutex);
237 list_append(&instance->link, &inst_list);
238 fibril_mutex_unlock(&inst_list_mutex);
239
240 mfsdebug("mount successful\n");
241
242 async_answer_0(rid, EOK);
243}
244
245void mfs_mount(ipc_callid_t rid, ipc_call_t *request)
246{
247 libfs_mount(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
248}
249
250devmap_handle_t mfs_device_get(fs_node_t *fsnode)
251{
252 struct mfs_node *node = fsnode->data;
253 return node->instance->handle;
254}
255
256static int mfs_create_node(fs_node_t **rfn, devmap_handle_t handle, int flags)
257{
258 int r;
259 struct mfs_instance *inst;
260 struct mfs_node *mnode;
261 fs_node_t *fsnode;
262 uint32_t inum;
263
264 mfsdebug("create_node()\n");
265
266 r = mfs_instance_get(handle, &inst);
267 on_error(r, return r);
268
269 if (flags & L_DIRECTORY) {
270 /*Not yet supported*/
271 return ENOTSUP;
272 }
273
274 /*Alloc a new inode*/
275 r = mfs_alloc_bit(inst, &inum, BMAP_INODE);
276 on_error(r, return r);
277
278 struct mfs_ino_info *ino_i;
279
280 ino_i = malloc(sizeof(*ino_i));
281 if (!ino_i) {
282 r = ENOMEM;
283 goto out_err;
284 }
285
286 mnode = malloc(sizeof(*mnode));
287 if (!mnode) {
288 r = ENOMEM;
289 goto out_err_1;
290 }
291
292 fsnode = malloc(sizeof(fs_node_t));
293 if (!fsnode) {
294 r = ENOMEM;
295 goto out_err_2;
296 }
297
298 ino_i->i_mode = S_IFREG;
299 ino_i->i_nlinks = 1;
300 ino_i->i_uid = 0;
301 ino_i->i_gid = 0;
302 ino_i->i_size = 0;
303 ino_i->i_atime = 0;
304 ino_i->i_mtime = 0;
305 ino_i->i_ctime = 0;
306
307 memset(ino_i->i_dzone, 0, sizeof(uint32_t) * V2_NR_DIRECT_ZONES);
308 memset(ino_i->i_izone, 0, sizeof(uint32_t) * V2_NR_INDIRECT_ZONES);
309
310 mfsdebug("new node idx = %d\n", (int) inum);
311
312 ino_i->index = inum;
313 ino_i->dirty = true;
314 mnode->ino_i = ino_i;
315 mnode->instance = inst;
316
317 r = put_inode(mnode);
318 on_error(r, goto out_err_2);
319
320 fs_node_initialize(fsnode);
321 fsnode->data = mnode;
322 *rfn = fsnode;
323
324 return EOK;
325
326out_err_2:
327 free(mnode);
328out_err_1:
329 free(ino_i);
330out_err:
331 return r;
332}
333
334static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
335{
336 struct mfs_node *mnode = pfn->data;
337 struct mfs_ino_info *ino_i = mnode->ino_i;
338 struct mfs_dentry_info *d_info;
339 int r;
340
341 mfsdebug("mfs_match()\n");
342
343 if (!S_ISDIR(ino_i->i_mode))
344 return ENOTDIR;
345
346 struct mfs_sb_info *sbi = mnode->instance->sbi;
347 const size_t comp_size = str_size(component);
348
349 int i = 2;
350 while (1) {
351 r = read_directory_entry(mnode, &d_info, i++);
352 on_error(r, return r);
353
354 if (!d_info) {
355 /*Reached the end of the directory entry list*/
356 break;
357 }
358
359 if (!d_info->d_inum) {
360 /*This entry is not used*/
361 free(d_info);
362 continue;
363 }
364
365 if (!bcmp(component, d_info->d_name, min(sbi->max_name_len,
366 comp_size))) {
367 /*Hit!*/
368 mfs_node_core_get(rfn, mnode->instance,
369 d_info->d_inum);
370 free(d_info);
371 goto found;
372 }
373 free(d_info);
374 }
375 *rfn = NULL;
376found:
377 return EOK;
378}
379
380static aoff64_t mfs_size_get(fs_node_t *node)
381{
382 assert(node);
383
384 const struct mfs_node *mnode = node->data;
385 assert(mnode);
386 assert(mnode->ino_i);
387
388 return mnode->ino_i->i_size;
389}
390
391void mfs_stat(ipc_callid_t rid, ipc_call_t *request)
392{
393 libfs_stat(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
394}
395
396static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
397 fs_index_t index)
398{
399 int rc;
400 struct mfs_instance *instance;
401
402 rc = mfs_instance_get(devmap_handle, &instance);
403 on_error(rc, return rc);
404
405 return mfs_node_core_get(rfn, instance, index);
406}
407
408static int mfs_node_put(fs_node_t *fsnode)
409{
410 struct mfs_node *mnode = fsnode->data;
411
412 put_inode(mnode);
413 free(mnode->ino_i);
414 free(mnode);
415
416 return EOK;
417}
418
419static int mfs_node_open(fs_node_t *fsnode)
420{
421 /*
422 * Opening a file is stateless, nothing
423 * to be done here.
424 */
425 return EOK;
426}
427
428static fs_index_t mfs_index_get(fs_node_t *fsnode)
429{
430 struct mfs_node *mnode = fsnode->data;
431
432 assert(mnode->ino_i);
433 return mnode->ino_i->index;
434}
435
436static unsigned mfs_lnkcnt_get(fs_node_t *fsnode)
437{
438 unsigned rc;
439 struct mfs_node *mnode = fsnode->data;
440
441 assert(mnode);
442 assert(mnode->ino_i);
443
444 rc = mnode->ino_i->i_nlinks;
445 return rc;
446}
447
448static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst,
449 fs_index_t index)
450{
451 fs_node_t *node = NULL;
452 struct mfs_node *mnode = NULL;
453 int rc;
454
455 node = malloc(sizeof(fs_node_t));
456 if (!node) {
457 rc = ENOMEM;
458 goto out_err;
459 }
460
461 fs_node_initialize(node);
462
463 mnode = malloc(sizeof(*mnode));
464 if (!mnode) {
465 rc = ENOMEM;
466 goto out_err;
467 }
468
469 struct mfs_ino_info *ino_i;
470
471 rc = get_inode(inst, &ino_i, index);
472 on_error(rc, goto out_err);
473
474 ino_i->index = index;
475 mnode->ino_i = ino_i;
476
477 mnode->instance = inst;
478 node->data = mnode;
479 *rfn = node;
480
481 mfsdebug("node_get_core(%d) OK\n", (int) index);
482
483 return EOK;
484
485out_err:
486 if (node)
487 free(node);
488 if (mnode)
489 free(mnode);
490 return rc;
491}
492
493static bool mfs_is_directory(fs_node_t *fsnode)
494{
495 const struct mfs_node *node = fsnode->data;
496 return S_ISDIR(node->ino_i->i_mode);
497}
498
499static bool mfs_is_file(fs_node_t *fsnode)
500{
501 struct mfs_node *node = fsnode->data;
502 return S_ISREG(node->ino_i->i_mode);
503}
504
505static int mfs_root_get(fs_node_t **rfn, devmap_handle_t handle)
506{
507 int rc = mfs_node_get(rfn, handle, MFS_ROOT_INO);
508 return rc;
509}
510
511void mfs_lookup(ipc_callid_t rid, ipc_call_t *request)
512{
513 libfs_lookup(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
514}
515
516static char mfs_plb_get_char(unsigned pos)
517{
518 return mfs_reg.plb_ro[pos % PLB_SIZE];
519}
520
521static int mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
522{
523 struct mfs_node *parent = pfn->data;
524 struct mfs_node *child = cfn->data;
525
526 mfsdebug("mfs_link() %d\n", (int) child->ino_i->index);
527
528 int r = insert_dentry(parent, name, child->ino_i->index);
529
530 return r;
531}
532
533static int mfs_has_children(bool *has_children, fs_node_t *fsnode)
534{
535 struct mfs_node *mnode = fsnode->data;
536 int r;
537
538 *has_children = false;
539
540 mfsdebug("mfs_has_children()\n");
541
542 if (!S_ISDIR(mnode->ino_i->i_mode))
543 goto out;
544
545 struct mfs_dentry_info *d_info;
546
547 /* The first two dentries are always . and .. */
548 int i = 2;
549 while (1) {
550 r = read_directory_entry(mnode, &d_info, i++);
551 on_error(r, return r);
552
553 if (!d_info) {
554 /*Reached the end of the dentries list*/
555 break;
556 }
557
558 if (d_info->d_inum) {
559 /*A valid entry has been found*/
560 *has_children = true;
561 free(d_info);
562 break;
563 }
564
565 free(d_info);
566 }
567
568out:
569
570 if (*has_children) {
571 mfsdebug("Has children\n");
572 } else {
573 mfsdebug("Has not children\n");
574 }
575
576 return EOK;
577}
578
579void
580mfs_read(ipc_callid_t rid, ipc_call_t *request)
581{
582 int rc;
583 devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(*request);
584 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
585 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request),
586 IPC_GET_ARG4(*request));
587 fs_node_t *fn;
588
589 mfsdebug("mfs_read()\n");
590
591 rc = mfs_node_get(&fn, handle, index);
592 if (rc != EOK) {
593 async_answer_0(rid, rc);
594 return;
595 }
596 if (!fn) {
597 async_answer_0(rid, ENOENT);
598 return;
599 }
600
601 struct mfs_node *mnode;
602 struct mfs_ino_info *ino_i;
603 size_t len, bytes = 0;
604 ipc_callid_t callid;
605
606 mnode = fn->data;
607 ino_i = mnode->ino_i;
608
609 if (!async_data_read_receive(&callid, &len)) {
610 rc = EINVAL;
611 goto out_error;
612 }
613
614 if (S_ISDIR(ino_i->i_mode)) {
615 aoff64_t spos = pos;
616 struct mfs_dentry_info *d_info;
617
618 while (1) {
619 rc = read_directory_entry(mnode, &d_info, pos);
620 on_error(rc, goto out_error);
621
622 if (!d_info) {
623 /*Reached the end of the dentries list*/
624 break;
625 }
626
627 if (d_info->d_inum) {
628 /*Dentry found!*/
629 mfsdebug("DENTRY FOUND %s!!\n", d_info->d_name);
630 goto found;
631 }
632
633 free(d_info);
634 pos++;
635 }
636
637 rc = mfs_node_put(fn);
638 async_answer_0(callid, rc != EOK ? rc : ENOENT);
639 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
640 return;
641found:
642 async_data_read_finalize(callid, d_info->d_name,
643 str_size(d_info->d_name) + 1);
644 bytes = ((pos - spos) + 1);
645 } else {
646 struct mfs_sb_info *sbi = mnode->instance->sbi;
647
648 if (pos >= (size_t) ino_i->i_size) {
649 /*Trying to read beyond the end of file*/
650 bytes = 0;
651 (void) async_data_read_finalize(callid, NULL, 0);
652 goto out_success;
653 }
654
655 bytes = min(len, sbi->block_size - pos % sbi->block_size);
656 bytes = min(bytes, ino_i->i_size - pos);
657
658 uint32_t zone;
659 block_t *b;
660
661 rc = read_map(&zone, mnode, pos);
662 on_error(rc, goto out_error);
663
664 if (zone == 0) {
665 /*sparse file*/
666 uint8_t *buf = malloc(sbi->block_size);
667 if (!buf) {
668 rc = ENOMEM;
669 goto out_error;
670 }
671 memset(buf, 0, sizeof(sbi->block_size));
672 async_data_read_finalize(callid,
673 buf + pos % sbi->block_size, bytes);
674 free(buf);
675 goto out_success;
676 }
677
678 rc = block_get(&b, handle, zone, BLOCK_FLAGS_NONE);
679 on_error(rc, goto out_error);
680
681 async_data_read_finalize(callid, b->data +
682 pos % sbi->block_size, bytes);
683
684 rc = block_put(b);
685 if (rc != EOK) {
686 mfs_node_put(fn);
687 async_answer_0(rid, rc);
688 return;
689 }
690 }
691out_success:
692 rc = mfs_node_put(fn);
693 async_answer_1(rid, rc, (sysarg_t)bytes);
694 return;
695out_error: ;
696 int tmp = mfs_node_put(fn);
697 async_answer_0(callid, tmp != EOK ? tmp : rc);
698 async_answer_0(rid, tmp != EOK ? tmp : rc);
699}
700
701int mfs_instance_get(devmap_handle_t handle, struct mfs_instance **instance)
702{
703 link_t *link;
704 struct mfs_instance *instance_ptr;
705
706 fibril_mutex_lock(&inst_list_mutex);
707
708 for (link = inst_list.next; link != &inst_list; link = link->next) {
709 instance_ptr = list_get_instance(link, struct mfs_instance,
710 link);
711
712 if (instance_ptr->handle == handle) {
713 *instance = instance_ptr;
714 fibril_mutex_unlock(&inst_list_mutex);
715 return EOK;
716 }
717 }
718
719 mfsdebug("Instance not found\n");
720
721 fibril_mutex_unlock(&inst_list_mutex);
722 return EINVAL;
723}
724
725static bool check_magic_number(uint16_t magic, bool *native,
726 mfs_version_t *version, bool *longfilenames)
727{
728 bool rc = true;
729 *longfilenames = false;
730
731 if (magic == MFS_MAGIC_V1 || magic == MFS_MAGIC_V1R) {
732 *native = magic == MFS_MAGIC_V1;
733 *version = MFS_VERSION_V1;
734 } else if (magic == MFS_MAGIC_V1L || magic == MFS_MAGIC_V1LR) {
735 *native = magic == MFS_MAGIC_V1L;
736 *version = MFS_VERSION_V1;
737 *longfilenames = true;
738 } else if (magic == MFS_MAGIC_V2 || magic == MFS_MAGIC_V2R) {
739 *native = magic == MFS_MAGIC_V2;
740 *version = MFS_VERSION_V2;
741 } else if (magic == MFS_MAGIC_V2L || magic == MFS_MAGIC_V2LR) {
742 *native = magic == MFS_MAGIC_V2L;
743 *version = MFS_VERSION_V2;
744 *longfilenames = true;
745 } else if (magic == MFS_MAGIC_V3 || magic == MFS_MAGIC_V3R) {
746 *native = magic == MFS_MAGIC_V3;
747 *version = MFS_VERSION_V3;
748 } else
749 rc = false;
750
751 return rc;
752}
753
754void
755mfs_close(ipc_callid_t rid, ipc_call_t *request)
756{
757 async_answer_0(rid, EOK);
758}
759
760void
761mfs_open_node(ipc_callid_t rid, ipc_call_t *request)
762{
763 libfs_open_node(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
764}
765
766/**
767 * @}
768 */
769
Note: See TracBrowser for help on using the repository browser.