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

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

call the insert_dentry() function in mfs_link()

  • Property mode set to 100644
File size: 17.0 KB
RevLine 
[096c8835]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
[92dd5c8]33#include <stdio.h>
[9e3dc95]34#include <stdlib.h>
[0d6ab10]35#include <assert.h>
[953a823]36#include <fibril_synch.h>
[9e3dc95]37#include <errno.h>
[7413683]38#include "mfs.h"
[9e3dc95]39#include "mfs_utils.h"
40
[8ceba1e]41static bool check_magic_number(uint16_t magic, bool *native,
42 mfs_version_t *version, bool *longfilenames);
[44c0f5b]43static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst,
44 fs_index_t index);
[096c8835]45
[41202a9]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);
[ac28650]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);
[bd64680]57static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component);
[10eb754]58static int mfs_create_node(fs_node_t **rfn, devmap_handle_t handle, int flags);
[88ccd8b8]59static int mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name);
[ac28650]60
[668f1949]61static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
[ac28650]62 fs_index_t index);
63
[41202a9]64
[953a823]65static LIST_INITIALIZE(inst_list);
66static FIBRIL_MUTEX_INITIALIZE(inst_list_mutex);
67
[e54ba607]68libfs_ops_t mfs_libfs_ops = {
[0d6ab10]69 .size_get = mfs_size_get,
[fe4ac35]70 .root_get = mfs_root_get,
[5a58ae2]71 .device_get = mfs_device_get,
[7d04324]72 .is_directory = mfs_is_directory,
[44c0f5b]73 .is_file = mfs_is_file,
[cfbcd86]74 .node_get = mfs_node_get,
[41202a9]75 .node_put = mfs_node_put,
76 .node_open = mfs_node_open,
77 .index_get = mfs_index_get,
[bd64680]78 .match = mfs_match,
[10eb754]79 .create = mfs_create_node,
[88ccd8b8]80 .link = mfs_link,
[54caa41b]81 .plb_get_char = mfs_plb_get_char,
[41202a9]82 .has_children = mfs_has_children,
83 .lnkcnt_get = mfs_lnkcnt_get
[e54ba607]84};
[3b08178]85
[096c8835]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;
[953a823]90 struct mfs_superblock *sb;
91 struct mfs3_superblock *sb3;
92 struct mfs_sb_info *sbi;
93 struct mfs_instance *instance;
[8ceba1e]94 bool native, longnames;
[9e3dc95]95 mfs_version_t version;
[245eb02d]96 uint16_t magic;
[096c8835]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) {
[92dd5c8]103 mfsdebug("Can't accept async data write\n");
[096c8835]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 */
[92dd5c8]117 rc = block_init(devmap_handle, 1024);
[096c8835]118 if (rc != EOK) {
[92dd5c8]119 mfsdebug("libblock initialization failed\n");
[096c8835]120 async_answer_0(rid, rc);
121 return;
122 }
123
[953a823]124 /*Allocate space for generic MFS superblock*/
[b438804]125 sbi = malloc(sizeof(*sbi));
[953a823]126
127 if (!sbi) {
128 async_answer_0(rid, ENOMEM);
129 return;
130 }
131
132 /*Allocate space for filesystem instance*/
[b438804]133 instance = malloc(sizeof(*instance));
[953a823]134
135 if (!instance) {
136 async_answer_0(rid, ENOMEM);
137 return;
138 }
139
[b438804]140 sb = malloc(MFS_SUPERBLOCK_SIZE);
[953a823]141
142 if (!sb) {
143 async_answer_0(rid, ENOMEM);
144 return;
145 }
[92dd5c8]146
147 /* Read the superblock */
[953a823]148 rc = block_read_direct(devmap_handle, MFS_SUPERBLOCK << 1, 1, sb);
[096c8835]149 if (rc != EOK) {
150 block_fini(devmap_handle);
151 async_answer_0(rid, rc);
152 return;
153 }
154
[953a823]155 sb3 = (struct mfs3_superblock *) sb;
156
157 if (check_magic_number(sb->s_magic, &native, &version, &longnames)) {
[7a96476]158 /*This is a V1 or V2 Minix filesystem*/
[953a823]159 magic = sb->s_magic;
[245eb02d]160 goto recognized;
161 }
162
[953a823]163 if (!check_magic_number(sb3->s_magic, &native, &version, &longnames)) {
[92dd5c8]164 mfsdebug("magic number not recognized\n");
[9e3dc95]165 block_fini(devmap_handle);
166 async_answer_0(rid, ENOTSUP);
167 return;
168 }
[92dd5c8]169
[7a96476]170 /*This is a V3 Minix filesystem*/
171
[953a823]172 magic = sb3->s_magic;
[245eb02d]173
174recognized:
175
176 mfsdebug("magic number recognized = %04x\n", magic);
[953a823]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;
[ef76d72]184 sbi->isearch = 0;
185 sbi->zsearch = 0;
[953a823]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);
[10eb754]196 sbi->ino_per_block = V3_INODES_PER_BLOCK(sbi->block_size);
[a04b62d]197 sbi->dirsize = MFS3_DIRSIZE;
[bd64680]198 sbi->max_name_len = MFS3_MAX_NAME_LEN;
[953a823]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);
[3b08178]206 sbi->block_size = MFS_BLOCKSIZE;
[5a841a4]207 if (version == MFS_VERSION_V2) {
[953a823]208 sbi->nzones = conv32(native, sb->s_nzones2);
[5a841a4]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 }
[a04b62d]214 sbi->dirsize = longnames ? MFSL_DIRSIZE : MFS_DIRSIZE;
[bd64680]215 sbi->max_name_len = longnames ? MFS_L_MAX_NAME_LEN :
216 MFS_MAX_NAME_LEN;
[953a823]217 }
[10eb754]218 sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks;
[953a823]219
220 free(sb);
221
[586f123]222 rc = block_cache_init(devmap_handle, sbi->block_size, 0, cmode);
[3b08178]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
[953a823]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);
[9e3dc95]243}
244
[3b08178]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
[e54ba607]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
[10eb754]256static int mfs_create_node(fs_node_t **rfn, devmap_handle_t handle, int flags)
257{
[88ccd8b8]258 int r;
259 struct mfs_instance *inst;
260 struct mfs_node *mnode;
261 fs_node_t *fsnode;
262 uint32_t inum;
263
[10eb754]264 mfsdebug("create_node()\n");
[88ccd8b8]265
266 r = mfs_instance_get(handle, &inst);
267 if (r != EOK)
268 return r;
269
270 if (flags & L_DIRECTORY) {
271 /*Not yet supported*/
272 return ENOTSUP;
273 }
274
275 /*Alloc a new inode*/
276 r = mfs_alloc_bit(inst, &inum, BMAP_INODE);
277 if (r != EOK)
278 return r;
279
280 struct mfs_ino_info *ino_i;
281
282 ino_i = malloc(sizeof(*ino_i));
283 if (!ino_i) {
284 r = ENOMEM;
285 goto out_err;
286 }
287
288 mnode = malloc(sizeof(*mnode));
289 if (!mnode) {
290 r = ENOMEM;
291 goto out_err_1;
292 }
293
294 fsnode = malloc(sizeof(fs_node_t));
295 if (!fsnode) {
296 r = ENOMEM;
297 goto out_err_2;
298 }
299
300 ino_i->i_mode = S_IFREG;
301 ino_i->i_nlinks = 1;
302 ino_i->i_uid = 0;
303 ino_i->i_gid = 0;
304 ino_i->i_size = 0;
305 ino_i->i_atime = 0;
306 ino_i->i_mtime = 0;
307 ino_i->i_ctime = 0;
308
309 memset(ino_i->i_dzone, 0, sizeof(uint32_t) * V2_NR_DIRECT_ZONES);
310 memset(ino_i->i_izone, 0, sizeof(uint32_t) * V2_NR_INDIRECT_ZONES);
311
312 ino_i->index = inum;
313 ino_i->dirty = true;
314 mnode->ino_i = ino_i;
315 mnode->instance = inst;
316
317 put_inode(mnode);
318
319 fs_node_initialize(fsnode);
320 fsnode->data = mnode;
321 *rfn = fsnode;
322
323 return EOK;
324
325out_err_2:
326 free(mnode);
327out_err_1:
328 free(ino_i);
329out_err:
330 return r;
[10eb754]331}
332
[bd64680]333static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
334{
335 struct mfs_node *mnode = pfn->data;
336 struct mfs_ino_info *ino_i = mnode->ino_i;
337 struct mfs_dentry_info *d_info;
338
[534d08e8]339 mfsdebug("mfs_match()\n");
340
[bd64680]341 if (!S_ISDIR(ino_i->i_mode))
342 return ENOTDIR;
343
344 struct mfs_sb_info *sbi = mnode->instance->sbi;
345 const size_t comp_size = str_size(component);
346
347 int i = 2;
348 while (1) {
349 d_info = read_directory_entry(mnode, i++);
350 if (!d_info) {
351 /*Reached the end of the directory entry list*/
352 break;
353 }
354
355 if (!d_info->d_inum) {
356 /*This entry is not used*/
[9cd199c]357 free(d_info);
[bd64680]358 continue;
359 }
360
361 if (!bcmp(component, d_info->d_name, min(sbi->max_name_len,
362 comp_size))) {
363 /*Hit!*/
364 mfs_node_core_get(rfn, mnode->instance,
365 d_info->d_inum);
[9cd199c]366 free(d_info);
[bd64680]367 goto found;
368 }
[9cd199c]369 free(d_info);
[bd64680]370 }
371 *rfn = NULL;
372 return ENOENT;
373found:
374 return EOK;
375}
376
[ac28650]377static aoff64_t mfs_size_get(fs_node_t *node)
[0d6ab10]378{
379 assert(node);
380
381 const struct mfs_node *mnode = node->data;
382 assert(mnode);
[155f792]383 assert(mnode->ino_i);
[0d6ab10]384
[155f792]385 return mnode->ino_i->i_size;
[0d6ab10]386}
387
388void mfs_stat(ipc_callid_t rid, ipc_call_t *request)
389{
[7a96476]390 mfsdebug("mfs_stat()\n");
[0d6ab10]391 libfs_stat(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
392}
393
[ac28650]394static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
[44c0f5b]395 fs_index_t index)
396{
397 int rc;
398 struct mfs_instance *instance;
399
400 rc = mfs_instance_get(devmap_handle, &instance);
401
402 if (rc != EOK)
403 return rc;
404
405 return mfs_node_core_get(rfn, instance, index);
406}
407
[41202a9]408static int mfs_node_put(fs_node_t *fsnode)
409{
410 struct mfs_node *mnode = fsnode->data;
411
[ae8541d]412 put_inode(mnode);
[41202a9]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
[44c0f5b]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
[b438804]455 node = malloc(sizeof(fs_node_t));
[44c0f5b]456 if (!node) {
457 rc = ENOMEM;
458 goto out_err;
459 }
460
461 fs_node_initialize(node);
462
[b438804]463 mnode = malloc(sizeof(*mnode));
[44c0f5b]464 if (!mnode) {
465 rc = ENOMEM;
466 goto out_err;
467 }
468
[155f792]469 struct mfs_ino_info *ino_i;
470
[c922bc7]471 rc = get_inode(inst, &ino_i, index);
472 if (rc != EOK)
[7a96476]473 goto out_err;
[155f792]474
[41202a9]475 ino_i->index = index;
[155f792]476 mnode->ino_i = ino_i;
477
[44c0f5b]478 mnode->instance = inst;
479 node->data = mnode;
480 *rfn = node;
481
[41202a9]482 mfsdebug("node_get_core(%d) OK\n", (int) index);
483
[44c0f5b]484 return EOK;
485
486out_err:
487 if (node)
488 free(node);
489 if (mnode)
490 free(mnode);
491 return rc;
492}
493
[ac28650]494static bool mfs_is_directory(fs_node_t *fsnode)
[5a58ae2]495{
[44c0f5b]496 const struct mfs_node *node = fsnode->data;
[155f792]497 return S_ISDIR(node->ino_i->i_mode);
[5a58ae2]498}
499
[ac28650]500static bool mfs_is_file(fs_node_t *fsnode)
[7d04324]501{
502 struct mfs_node *node = fsnode->data;
[155f792]503 return S_ISREG(node->ino_i->i_mode);
[7d04324]504}
505
[ac28650]506static int mfs_root_get(fs_node_t **rfn, devmap_handle_t handle)
[fe4ac35]507{
[41202a9]508 int rc = mfs_node_get(rfn, handle, MFS_ROOT_INO);
509 return rc;
[fe4ac35]510}
511
[54caa41b]512void mfs_lookup(ipc_callid_t rid, ipc_call_t *request)
513{
514 libfs_lookup(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
515}
516
[ac28650]517static char mfs_plb_get_char(unsigned pos)
[cfbcd86]518{
519 return mfs_reg.plb_ro[pos % PLB_SIZE];
520}
521
[88ccd8b8]522static int mfs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
523{
[afd9c3b]524 struct mfs_node *parent = pfn->data;
525 struct mfs_node *child = cfn->data;
526
[88ccd8b8]527 mfsdebug("mfs_link()\n");
[afd9c3b]528
529 int r = insert_dentry(parent, name, child->ino_i->index);
530
531 return r;
[88ccd8b8]532}
533
[ac28650]534static int mfs_has_children(bool *has_children, fs_node_t *fsnode)
[54caa41b]535{
536 struct mfs_node *mnode = fsnode->data;
537
538 *has_children = false;
539
540 if (!S_ISDIR(mnode->ino_i->i_mode))
541 goto out;
542
543 struct mfs_dentry_info *d_info;
[ac28650]544
545 /* The first two dentries are always . and .. */
546 int i = 2;
547 while (1) {
548 d_info = read_directory_entry(mnode, i++);
[54caa41b]549
[7a96476]550 if (!d_info) {
551 /*Reached the end of the dentries list*/
[152610a8]552 break;
[7a96476]553 }
[54caa41b]554
555 if (d_info->d_inum) {
[7a96476]556 /*A valid entry has been found*/
[54caa41b]557 *has_children = true;
558 free(d_info);
559 break;
560 }
561
562 free(d_info);
563 }
564
[41202a9]565out:
566
[18c9e6b]567 if (*has_children) {
[54caa41b]568 mfsdebug("Has children\n");
[18c9e6b]569 } else {
[54caa41b]570 mfsdebug("Has not children\n");
[18c9e6b]571 }
[54caa41b]572
573 return EOK;
574}
575
[668f1949]576void
577mfs_read(ipc_callid_t rid, ipc_call_t *request)
578{
579 int rc;
580 devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(*request);
581 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
582 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request),
583 IPC_GET_ARG4(*request));
584 fs_node_t *fn;
585
586 rc = mfs_node_get(&fn, handle, index);
587 if (rc != EOK) {
588 async_answer_0(rid, rc);
589 return;
590 }
591 if (!fn) {
592 async_answer_0(rid, ENOENT);
593 return;
594 }
595
596 struct mfs_node *mnode;
597 struct mfs_ino_info *ino_i;
598 size_t len, bytes = 0;
599 ipc_callid_t callid;
600
601 mnode = fn->data;
602 ino_i = mnode->ino_i;
603
604 if (!async_data_read_receive(&callid, &len)) {
[230229de]605 rc = EINVAL;
606 goto out_error;
[668f1949]607 }
608
609 if (S_ISDIR(ino_i->i_mode)) {
610 aoff64_t spos = pos;
611 struct mfs_dentry_info *d_info;
612
613 while (1) {
614 d_info = read_directory_entry(mnode, pos);
615 if (!d_info) {
616 /*Reached the end of the dentries list*/
617 break;
618 }
619
620 if (d_info->d_inum) {
621 /*Dentry found!*/
622 mfsdebug("DENTRY FOUND %s!!\n", d_info->d_name);
623 goto found;
624 }
625
626 free(d_info);
627 pos++;
628 }
629
630 rc = mfs_node_put(fn);
631 async_answer_0(callid, rc != EOK ? rc : ENOENT);
632 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
633 return;
634found:
635 async_data_read_finalize(callid, d_info->d_name,
636 str_size(d_info->d_name) + 1);
637 bytes = ((pos - spos) + 1);
[230229de]638 } else {
639 struct mfs_sb_info *sbi = mnode->instance->sbi;
640
641 if (pos >= (size_t) ino_i->i_size) {
642 /*Trying to read beyond the end of file*/
643 bytes = 0;
644 (void) async_data_read_finalize(callid, NULL, 0);
645 goto out_success;
646 }
647
648 bytes = min(len, sbi->block_size - pos % sbi->block_size);
649 bytes = min(bytes, ino_i->i_size - pos);
650
651 uint32_t zone;
652 block_t *b;
[668f1949]653
[230229de]654 rc = read_map(&zone, mnode, pos);
655 if (rc != EOK)
656 goto out_error;
657
658 if (zone == 0) {
659 /*sparse file*/
660 uint8_t *buf = malloc(sbi->block_size);
661 if (!buf) {
662 rc = ENOMEM;
663 goto out_error;
664 }
665 async_data_read_finalize(callid,
666 buf + pos % sbi->block_size, bytes);
667 free(buf);
668 goto out_success;
669 }
670
671 rc = block_get(&b, handle, zone, BLOCK_FLAGS_NONE);
672 if (rc != EOK)
673 goto out_error;
674
675 async_data_read_finalize(callid, b->data +
676 pos % sbi->block_size, bytes);
677
678 rc = block_put(b);
679 if (rc != EOK) {
680 mfs_node_put(fn);
681 async_answer_0(rid, rc);
682 return;
683 }
684 }
685out_success:
[668f1949]686 rc = mfs_node_put(fn);
687 async_answer_1(rid, rc, (sysarg_t)bytes);
[230229de]688 return;
689out_error: ;
690 int tmp = mfs_node_put(fn);
691 async_answer_0(callid, tmp != EOK ? tmp : rc);
692 async_answer_0(rid, tmp != EOK ? tmp : rc);
[668f1949]693}
694
[44c0f5b]695int mfs_instance_get(devmap_handle_t handle, struct mfs_instance **instance)
[3b08178]696{
697 link_t *link;
698 struct mfs_instance *instance_ptr;
699
700 fibril_mutex_lock(&inst_list_mutex);
701
702 for (link = inst_list.next; link != &inst_list; link = link->next) {
[bd64680]703 instance_ptr = list_get_instance(link, struct mfs_instance,
704 link);
[3b08178]705
706 if (instance_ptr->handle == handle) {
707 *instance = instance_ptr;
708 fibril_mutex_unlock(&inst_list_mutex);
709 return EOK;
710 }
711 }
712
713 mfsdebug("Instance not found\n");
714
715 fibril_mutex_unlock(&inst_list_mutex);
716 return EINVAL;
717}
718
[8ceba1e]719static bool check_magic_number(uint16_t magic, bool *native,
720 mfs_version_t *version, bool *longfilenames)
[9e3dc95]721{
[7a96476]722 bool rc = false;
[8ceba1e]723 *longfilenames = false;
724
[57640e7]725 if (magic == MFS_MAGIC_V1 || magic == MFS_MAGIC_V1R) {
726 *native = magic == MFS_MAGIC_V1;
[9e3dc95]727 *version = MFS_VERSION_V1;
[7a96476]728 rc = true;
[8ceba1e]729 } else if (magic == MFS_MAGIC_V1L || magic == MFS_MAGIC_V1LR) {
730 *native = magic == MFS_MAGIC_V1L;
731 *version = MFS_VERSION_V1;
732 *longfilenames = true;
[7a96476]733 rc = true;
[57640e7]734 } else if (magic == MFS_MAGIC_V2 || magic == MFS_MAGIC_V2R) {
735 *native = magic == MFS_MAGIC_V2;
[9e3dc95]736 *version = MFS_VERSION_V2;
[7a96476]737 rc = true;
[8ceba1e]738 } else if (magic == MFS_MAGIC_V2L || magic == MFS_MAGIC_V2LR) {
739 *native = magic == MFS_MAGIC_V2L;
740 *version = MFS_VERSION_V2;
741 *longfilenames = true;
[7a96476]742 rc = true;
[57640e7]743 } else if (magic == MFS_MAGIC_V3 || magic == MFS_MAGIC_V3R) {
744 *native = magic == MFS_MAGIC_V3;
[9e3dc95]745 *version = MFS_VERSION_V3;
[7a96476]746 rc = true;
[9e3dc95]747 }
748
[7a96476]749 return rc;
[096c8835]750}
751
752/**
753 * @}
754 */
755
Note: See TracBrowser for help on using the repository browser.