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

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

Remove wrong assertions

  • Property mode set to 100644
File size: 13.3 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);
[ac28650]59
60static
61int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
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,
[54caa41b]80 .plb_get_char = mfs_plb_get_char,
[41202a9]81 .has_children = mfs_has_children,
82 .lnkcnt_get = mfs_lnkcnt_get
[e54ba607]83};
[3b08178]84
[096c8835]85void mfs_mounted(ipc_callid_t rid, ipc_call_t *request)
86{
87 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
88 enum cache_mode cmode;
[953a823]89 struct mfs_superblock *sb;
90 struct mfs3_superblock *sb3;
91 struct mfs_sb_info *sbi;
92 struct mfs_instance *instance;
[8ceba1e]93 bool native, longnames;
[9e3dc95]94 mfs_version_t version;
[245eb02d]95 uint16_t magic;
[096c8835]96
97 /* Accept the mount options */
98 char *opts;
99 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
100
101 if (rc != EOK) {
[92dd5c8]102 mfsdebug("Can't accept async data write\n");
[096c8835]103 async_answer_0(rid, rc);
104 return;
105 }
106
107 /* Check for option enabling write through. */
108 if (str_cmp(opts, "wtcache") == 0)
109 cmode = CACHE_MODE_WT;
110 else
111 cmode = CACHE_MODE_WB;
112
113 free(opts);
114
115 /* initialize libblock */
[92dd5c8]116 rc = block_init(devmap_handle, 1024);
[096c8835]117 if (rc != EOK) {
[92dd5c8]118 mfsdebug("libblock initialization failed\n");
[096c8835]119 async_answer_0(rid, rc);
120 return;
121 }
122
[953a823]123 /*Allocate space for generic MFS superblock*/
[b438804]124 sbi = malloc(sizeof(*sbi));
[953a823]125
126 if (!sbi) {
127 async_answer_0(rid, ENOMEM);
128 return;
129 }
130
131 /*Allocate space for filesystem instance*/
[b438804]132 instance = malloc(sizeof(*instance));
[953a823]133
134 if (!instance) {
135 async_answer_0(rid, ENOMEM);
136 return;
137 }
138
[b438804]139 sb = malloc(MFS_SUPERBLOCK_SIZE);
[953a823]140
141 if (!sb) {
142 async_answer_0(rid, ENOMEM);
143 return;
144 }
[92dd5c8]145
146 /* Read the superblock */
[953a823]147 rc = block_read_direct(devmap_handle, MFS_SUPERBLOCK << 1, 1, sb);
[096c8835]148 if (rc != EOK) {
149 block_fini(devmap_handle);
150 async_answer_0(rid, rc);
151 return;
152 }
153
[953a823]154 sb3 = (struct mfs3_superblock *) sb;
155
156 if (check_magic_number(sb->s_magic, &native, &version, &longnames)) {
[7a96476]157 /*This is a V1 or V2 Minix filesystem*/
[953a823]158 magic = sb->s_magic;
[245eb02d]159 goto recognized;
160 }
161
[953a823]162 if (!check_magic_number(sb3->s_magic, &native, &version, &longnames)) {
[92dd5c8]163 mfsdebug("magic number not recognized\n");
[9e3dc95]164 block_fini(devmap_handle);
165 async_answer_0(rid, ENOTSUP);
166 return;
167 }
[92dd5c8]168
[7a96476]169 /*This is a V3 Minix filesystem*/
170
[953a823]171 magic = sb3->s_magic;
[245eb02d]172
173recognized:
174
175 mfsdebug("magic number recognized = %04x\n", magic);
[953a823]176
177 /*Fill superblock info structure*/
178
179 sbi->fs_version = version;
180 sbi->long_names = longnames;
181 sbi->native = native;
182 sbi->magic = magic;
[ef76d72]183 sbi->isearch = 0;
184 sbi->zsearch = 0;
[953a823]185
186 if (version == MFS_VERSION_V3) {
187 sbi->ninodes = conv32(native, sb3->s_ninodes);
188 sbi->ibmap_blocks = conv16(native, sb3->s_ibmap_blocks);
189 sbi->zbmap_blocks = conv16(native, sb3->s_zbmap_blocks);
190 sbi->firstdatazone = conv16(native, sb3->s_first_data_zone);
191 sbi->log2_zone_size = conv16(native, sb3->s_log2_zone_size);
192 sbi->max_file_size = conv32(native, sb3->s_max_file_size);
193 sbi->nzones = conv32(native, sb3->s_nzones);
194 sbi->block_size = conv16(native, sb3->s_block_size);
[10eb754]195 sbi->ino_per_block = V3_INODES_PER_BLOCK(sbi->block_size);
[a04b62d]196 sbi->dirsize = MFS3_DIRSIZE;
[bd64680]197 sbi->max_name_len = MFS3_MAX_NAME_LEN;
[953a823]198 } else {
199 sbi->ninodes = conv16(native, sb->s_ninodes);
200 sbi->ibmap_blocks = conv16(native, sb->s_ibmap_blocks);
201 sbi->zbmap_blocks = conv16(native, sb->s_zbmap_blocks);
202 sbi->firstdatazone = conv16(native, sb->s_first_data_zone);
203 sbi->log2_zone_size = conv16(native, sb->s_log2_zone_size);
204 sbi->max_file_size = conv32(native, sb->s_max_file_size);
205 sbi->nzones = conv16(native, sb->s_nzones);
[3b08178]206 sbi->block_size = MFS_BLOCKSIZE;
[10eb754]207 sbi->ino_per_block = V1_INODES_PER_BLOCK;
[953a823]208 if (version == MFS_VERSION_V2)
209 sbi->nzones = conv32(native, sb->s_nzones2);
[a04b62d]210 sbi->dirsize = longnames ? MFSL_DIRSIZE : MFS_DIRSIZE;
[bd64680]211 sbi->max_name_len = longnames ? MFS_L_MAX_NAME_LEN :
212 MFS_MAX_NAME_LEN;
[953a823]213 }
[10eb754]214 sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks;
[953a823]215
216 free(sb);
217
[586f123]218 rc = block_cache_init(devmap_handle, sbi->block_size, 0, cmode);
[3b08178]219
220 if (rc != EOK) {
221 block_fini(devmap_handle);
222 async_answer_0(rid, EINVAL);
223 mfsdebug("block cache initialization failed\n");
224 return;
225 }
226
[953a823]227 /*Initialize the instance structure and add it to the list*/
228 link_initialize(&instance->link);
229 instance->handle = devmap_handle;
230 instance->sbi = sbi;
231
232 fibril_mutex_lock(&inst_list_mutex);
233 list_append(&instance->link, &inst_list);
234 fibril_mutex_unlock(&inst_list_mutex);
235
236 mfsdebug("mount successful\n");
237
238 async_answer_0(rid, EOK);
[9e3dc95]239}
240
[3b08178]241void mfs_mount(ipc_callid_t rid, ipc_call_t *request)
242{
243 libfs_mount(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
244}
245
[e54ba607]246devmap_handle_t mfs_device_get(fs_node_t *fsnode)
247{
248 struct mfs_node *node = fsnode->data;
249 return node->instance->handle;
250}
251
[10eb754]252static int mfs_create_node(fs_node_t **rfn, devmap_handle_t handle, int flags)
253{
254 mfsdebug("create_node()\n");
255 return ENOTSUP;
256}
257
[bd64680]258static int mfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
259{
260 struct mfs_node *mnode = pfn->data;
261 struct mfs_ino_info *ino_i = mnode->ino_i;
262 struct mfs_dentry_info *d_info;
263
264 if (!S_ISDIR(ino_i->i_mode))
265 return ENOTDIR;
266
267 mfsdebug("mfs_match()\n");
268
269 struct mfs_sb_info *sbi = mnode->instance->sbi;
270 const size_t comp_size = str_size(component);
271
272 int i = 2;
273 while (1) {
274 d_info = read_directory_entry(mnode, i++);
275 if (!d_info) {
276 /*Reached the end of the directory entry list*/
277 break;
278 }
279
280 if (!d_info->d_inum) {
281 /*This entry is not used*/
[9cd199c]282 free(d_info);
[bd64680]283 continue;
284 }
285
286 if (!bcmp(component, d_info->d_name, min(sbi->max_name_len,
287 comp_size))) {
288 /*Hit!*/
289 mfs_node_core_get(rfn, mnode->instance,
290 d_info->d_inum);
[9cd199c]291 free(d_info);
[bd64680]292 goto found;
293 }
[9cd199c]294 free(d_info);
[bd64680]295 }
296 *rfn = NULL;
297 return ENOENT;
298found:
299 return EOK;
300}
301
[ac28650]302static aoff64_t mfs_size_get(fs_node_t *node)
[0d6ab10]303{
304 assert(node);
305
306 const struct mfs_node *mnode = node->data;
307 assert(mnode);
[155f792]308 assert(mnode->ino_i);
[0d6ab10]309
[41202a9]310 mfsdebug("inode size is %d\n", (int) mnode->ino_i->i_size);
311
[155f792]312 return mnode->ino_i->i_size;
[0d6ab10]313}
314
315void mfs_stat(ipc_callid_t rid, ipc_call_t *request)
316{
[7a96476]317 mfsdebug("mfs_stat()\n");
[0d6ab10]318 libfs_stat(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
319}
320
[ac28650]321static int mfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle,
[44c0f5b]322 fs_index_t index)
323{
324 int rc;
325 struct mfs_instance *instance;
326
[7a96476]327 mfsdebug("mfs_node_get()\n");
[41202a9]328
[44c0f5b]329 rc = mfs_instance_get(devmap_handle, &instance);
330
331 if (rc != EOK)
332 return rc;
333
334 return mfs_node_core_get(rfn, instance, index);
335}
336
[41202a9]337static int mfs_node_put(fs_node_t *fsnode)
338{
339 struct mfs_node *mnode = fsnode->data;
340
341 mfsdebug("mfs_node_put()\n");
342
[ae8541d]343 put_inode(mnode);
[41202a9]344 free(mnode->ino_i);
345 free(mnode);
346
347 return EOK;
348}
349
350static int mfs_node_open(fs_node_t *fsnode)
351{
352 /*
353 * Opening a file is stateless, nothing
354 * to be done here.
355 */
356 return EOK;
357}
358
359static fs_index_t mfs_index_get(fs_node_t *fsnode)
360{
361 struct mfs_node *mnode = fsnode->data;
362
363 mfsdebug("mfs_index_get()\n");
364
365 assert(mnode->ino_i);
366 return mnode->ino_i->index;
367}
368
369static unsigned mfs_lnkcnt_get(fs_node_t *fsnode)
370{
371 unsigned rc;
372 struct mfs_node *mnode = fsnode->data;
373
374 assert(mnode);
375 assert(mnode->ino_i);
376
377 rc = mnode->ino_i->i_nlinks;
378 mfsdebug("mfs_lnkcnt_get(): %u\n", rc);
379 return rc;
380}
381
[44c0f5b]382static int mfs_node_core_get(fs_node_t **rfn, struct mfs_instance *inst,
383 fs_index_t index)
384{
385 fs_node_t *node = NULL;
386 struct mfs_node *mnode = NULL;
387 int rc;
388
[b438804]389 node = malloc(sizeof(fs_node_t));
[44c0f5b]390 if (!node) {
391 rc = ENOMEM;
392 goto out_err;
393 }
394
395 fs_node_initialize(node);
396
[b438804]397 mnode = malloc(sizeof(*mnode));
[44c0f5b]398 if (!mnode) {
399 rc = ENOMEM;
400 goto out_err;
401 }
402
[155f792]403 struct mfs_ino_info *ino_i;
404
[c922bc7]405 rc = get_inode(inst, &ino_i, index);
406 if (rc != EOK)
[7a96476]407 goto out_err;
[155f792]408
[41202a9]409 ino_i->index = index;
[155f792]410 mnode->ino_i = ino_i;
411
[44c0f5b]412 mnode->instance = inst;
413 node->data = mnode;
414 *rfn = node;
415
[41202a9]416 mfsdebug("node_get_core(%d) OK\n", (int) index);
417
[44c0f5b]418 return EOK;
419
420out_err:
421 if (node)
422 free(node);
423 if (mnode)
424 free(mnode);
425 return rc;
426}
427
[ac28650]428static bool mfs_is_directory(fs_node_t *fsnode)
[5a58ae2]429{
[44c0f5b]430 const struct mfs_node *node = fsnode->data;
[155f792]431 return S_ISDIR(node->ino_i->i_mode);
[5a58ae2]432}
433
[ac28650]434static bool mfs_is_file(fs_node_t *fsnode)
[7d04324]435{
436 struct mfs_node *node = fsnode->data;
[155f792]437 return S_ISREG(node->ino_i->i_mode);
[7d04324]438}
439
[ac28650]440static int mfs_root_get(fs_node_t **rfn, devmap_handle_t handle)
[fe4ac35]441{
[41202a9]442 int rc = mfs_node_get(rfn, handle, MFS_ROOT_INO);
443
444 mfsdebug("mfs_root_get %s\n", rc == EOK ? "OK" : "FAIL");
445 return rc;
[fe4ac35]446}
447
[54caa41b]448void mfs_lookup(ipc_callid_t rid, ipc_call_t *request)
449{
450 libfs_lookup(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
451}
452
[ac28650]453static char mfs_plb_get_char(unsigned pos)
[cfbcd86]454{
455 return mfs_reg.plb_ro[pos % PLB_SIZE];
456}
457
[ac28650]458static int mfs_has_children(bool *has_children, fs_node_t *fsnode)
[54caa41b]459{
460 struct mfs_node *mnode = fsnode->data;
461
462 *has_children = false;
463
464 if (!S_ISDIR(mnode->ino_i->i_mode))
465 goto out;
466
467 struct mfs_dentry_info *d_info;
[ac28650]468
469 /* The first two dentries are always . and .. */
470 int i = 2;
471 while (1) {
472 d_info = read_directory_entry(mnode, i++);
[54caa41b]473
[7a96476]474 if (!d_info) {
475 /*Reached the end of the dentries list*/
[152610a8]476 break;
[7a96476]477 }
[54caa41b]478
479 if (d_info->d_inum) {
[7a96476]480 /*A valid entry has been found*/
[54caa41b]481 *has_children = true;
482 free(d_info);
483 break;
484 }
485
486 free(d_info);
487 }
488
[41202a9]489out:
490
[54caa41b]491 if (*has_children)
492 mfsdebug("Has children\n");
493 else
494 mfsdebug("Has not children\n");
495
496 return EOK;
497}
498
[3b08178]499/*
500 * Find a filesystem instance given the devmap handle
501 */
[44c0f5b]502int mfs_instance_get(devmap_handle_t handle, struct mfs_instance **instance)
[3b08178]503{
504 link_t *link;
505 struct mfs_instance *instance_ptr;
506
507 fibril_mutex_lock(&inst_list_mutex);
508
509 for (link = inst_list.next; link != &inst_list; link = link->next) {
[bd64680]510 instance_ptr = list_get_instance(link, struct mfs_instance,
511 link);
[3b08178]512
513 if (instance_ptr->handle == handle) {
514 *instance = instance_ptr;
515 fibril_mutex_unlock(&inst_list_mutex);
516 return EOK;
517 }
518 }
519
520 mfsdebug("Instance not found\n");
521
522 fibril_mutex_unlock(&inst_list_mutex);
523 return EINVAL;
524}
525
[8ceba1e]526static bool check_magic_number(uint16_t magic, bool *native,
527 mfs_version_t *version, bool *longfilenames)
[9e3dc95]528{
[7a96476]529 bool rc = false;
[8ceba1e]530 *longfilenames = false;
531
[57640e7]532 if (magic == MFS_MAGIC_V1 || magic == MFS_MAGIC_V1R) {
533 *native = magic == MFS_MAGIC_V1;
[9e3dc95]534 *version = MFS_VERSION_V1;
[7a96476]535 rc = true;
[8ceba1e]536 } else if (magic == MFS_MAGIC_V1L || magic == MFS_MAGIC_V1LR) {
537 *native = magic == MFS_MAGIC_V1L;
538 *version = MFS_VERSION_V1;
539 *longfilenames = true;
[7a96476]540 rc = true;
[57640e7]541 } else if (magic == MFS_MAGIC_V2 || magic == MFS_MAGIC_V2R) {
542 *native = magic == MFS_MAGIC_V2;
[9e3dc95]543 *version = MFS_VERSION_V2;
[7a96476]544 rc = true;
[8ceba1e]545 } else if (magic == MFS_MAGIC_V2L || magic == MFS_MAGIC_V2LR) {
546 *native = magic == MFS_MAGIC_V2L;
547 *version = MFS_VERSION_V2;
548 *longfilenames = true;
[7a96476]549 rc = true;
[57640e7]550 } else if (magic == MFS_MAGIC_V3 || magic == MFS_MAGIC_V3R) {
551 *native = magic == MFS_MAGIC_V3;
[9e3dc95]552 *version = MFS_VERSION_V3;
[7a96476]553 rc = true;
[9e3dc95]554 }
555
[7a96476]556 return rc;
[096c8835]557}
558
559/**
560 * @}
561 */
562
Note: See TracBrowser for help on using the repository browser.