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

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

return the ENAMETOOLONG error in the mfs_link() function

  • Property mode set to 100644
File size: 17.5 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 struct mfs_sb_info *sbi = parent->instance->sbi;
526
527 if (str_size(name) > sbi->max_name_len)
528 return ENAMETOOLONG;
529
530 mfsdebug("mfs_link() %d\n", (int) child->ino_i->index);
531
532 int r = insert_dentry(parent, name, child->ino_i->index);
533
534 return r;
535}
536
537static int mfs_has_children(bool *has_children, fs_node_t *fsnode)
538{
539 struct mfs_node *mnode = fsnode->data;
540 int r;
541
542 *has_children = false;
543
544 mfsdebug("mfs_has_children()\n");
545
546 if (!S_ISDIR(mnode->ino_i->i_mode))
547 goto out;
548
549 struct mfs_dentry_info *d_info;
550
551 /* The first two dentries are always . and .. */
552 int i = 2;
553 while (1) {
554 r = read_directory_entry(mnode, &d_info, i++);
555 on_error(r, return r);
556
557 if (!d_info) {
558 /*Reached the end of the dentries list*/
559 break;
560 }
561
562 if (d_info->d_inum) {
563 /*A valid entry has been found*/
564 *has_children = true;
565 free(d_info);
566 break;
567 }
568
569 free(d_info);
570 }
571
572out:
573
574 if (*has_children) {
575 mfsdebug("Has children\n");
576 } else {
577 mfsdebug("Has not children\n");
578 }
579
580 return EOK;
581}
582
583void
584mfs_read(ipc_callid_t rid, ipc_call_t *request)
585{
586 int rc;
587 devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(*request);
588 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
589 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request),
590 IPC_GET_ARG4(*request));
591 fs_node_t *fn;
592
593 mfsdebug("mfs_read()\n");
594
595 rc = mfs_node_get(&fn, handle, index);
596 if (rc != EOK) {
597 async_answer_0(rid, rc);
598 return;
599 }
600 if (!fn) {
601 async_answer_0(rid, ENOENT);
602 return;
603 }
604
605 struct mfs_node *mnode;
606 struct mfs_ino_info *ino_i;
607 size_t len, bytes = 0;
608 ipc_callid_t callid;
609
610 mnode = fn->data;
611 ino_i = mnode->ino_i;
612
613 if (!async_data_read_receive(&callid, &len)) {
614 rc = EINVAL;
615 goto out_error;
616 }
617
618 if (S_ISDIR(ino_i->i_mode)) {
619 aoff64_t spos = pos;
620 struct mfs_dentry_info *d_info;
621
622 while (1) {
623 rc = read_directory_entry(mnode, &d_info, pos);
624 on_error(rc, goto out_error);
625
626 if (!d_info) {
627 /*Reached the end of the dentries list*/
628 break;
629 }
630
631 if (d_info->d_inum) {
632 /*Dentry found!*/
633 mfsdebug("DENTRY FOUND %s!!\n", d_info->d_name);
634 goto found;
635 }
636
637 free(d_info);
638 pos++;
639 }
640
641 rc = mfs_node_put(fn);
642 async_answer_0(callid, rc != EOK ? rc : ENOENT);
643 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
644 return;
645found:
646 async_data_read_finalize(callid, d_info->d_name,
647 str_size(d_info->d_name) + 1);
648 bytes = ((pos - spos) + 1);
649 } else {
650 struct mfs_sb_info *sbi = mnode->instance->sbi;
651
652 if (pos >= (size_t) ino_i->i_size) {
653 /*Trying to read beyond the end of file*/
654 bytes = 0;
655 (void) async_data_read_finalize(callid, NULL, 0);
656 goto out_success;
657 }
658
659 bytes = min(len, sbi->block_size - pos % sbi->block_size);
660 bytes = min(bytes, ino_i->i_size - pos);
661
662 uint32_t zone;
663 block_t *b;
664
665 rc = read_map(&zone, mnode, pos);
666 on_error(rc, goto out_error);
667
668 if (zone == 0) {
669 /*sparse file*/
670 uint8_t *buf = malloc(sbi->block_size);
671 if (!buf) {
672 rc = ENOMEM;
673 goto out_error;
674 }
675 memset(buf, 0, sizeof(sbi->block_size));
676 async_data_read_finalize(callid,
677 buf + pos % sbi->block_size, bytes);
678 free(buf);
679 goto out_success;
680 }
681
682 rc = block_get(&b, handle, zone, BLOCK_FLAGS_NONE);
683 on_error(rc, goto out_error);
684
685 async_data_read_finalize(callid, b->data +
686 pos % sbi->block_size, bytes);
687
688 rc = block_put(b);
689 if (rc != EOK) {
690 mfs_node_put(fn);
691 async_answer_0(rid, rc);
692 return;
693 }
694 }
695out_success:
696 rc = mfs_node_put(fn);
697 async_answer_1(rid, rc, (sysarg_t)bytes);
698 return;
699out_error: ;
700 int tmp = mfs_node_put(fn);
701 async_answer_0(callid, tmp != EOK ? tmp : rc);
702 async_answer_0(rid, tmp != EOK ? tmp : rc);
703}
704
705int mfs_instance_get(devmap_handle_t handle, struct mfs_instance **instance)
706{
707 link_t *link;
708 struct mfs_instance *instance_ptr;
709
710 fibril_mutex_lock(&inst_list_mutex);
711
712 for (link = inst_list.next; link != &inst_list; link = link->next) {
713 instance_ptr = list_get_instance(link, struct mfs_instance,
714 link);
715
716 if (instance_ptr->handle == handle) {
717 *instance = instance_ptr;
718 fibril_mutex_unlock(&inst_list_mutex);
719 return EOK;
720 }
721 }
722
723 mfsdebug("Instance not found\n");
724
725 fibril_mutex_unlock(&inst_list_mutex);
726 return EINVAL;
727}
728
729static bool check_magic_number(uint16_t magic, bool *native,
730 mfs_version_t *version, bool *longfilenames)
731{
732 bool rc = true;
733 *longfilenames = false;
734
735 if (magic == MFS_MAGIC_V1 || magic == MFS_MAGIC_V1R) {
736 *native = magic == MFS_MAGIC_V1;
737 *version = MFS_VERSION_V1;
738 } else if (magic == MFS_MAGIC_V1L || magic == MFS_MAGIC_V1LR) {
739 *native = magic == MFS_MAGIC_V1L;
740 *version = MFS_VERSION_V1;
741 *longfilenames = true;
742 } else if (magic == MFS_MAGIC_V2 || magic == MFS_MAGIC_V2R) {
743 *native = magic == MFS_MAGIC_V2;
744 *version = MFS_VERSION_V2;
745 } else if (magic == MFS_MAGIC_V2L || magic == MFS_MAGIC_V2LR) {
746 *native = magic == MFS_MAGIC_V2L;
747 *version = MFS_VERSION_V2;
748 *longfilenames = true;
749 } else if (magic == MFS_MAGIC_V3 || magic == MFS_MAGIC_V3R) {
750 *native = magic == MFS_MAGIC_V3;
751 *version = MFS_VERSION_V3;
752 } else
753 rc = false;
754
755 return rc;
756}
757
758void
759mfs_close(ipc_callid_t rid, ipc_call_t *request)
760{
761 async_answer_0(rid, EOK);
762}
763
764void
765mfs_open_node(ipc_callid_t rid, ipc_call_t *request)
766{
767 libfs_open_node(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
768}
769
770/**
771 * @}
772 */
773
Note: See TracBrowser for help on using the repository browser.