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

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

Link mfs_is_directory() function to the libfs_ops structure

  • Property mode set to 100644
File size: 7.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 <fibril_synch.h>
36#include <errno.h>
37#include "mfs.h"
38#include "mfs_utils.h"
39
40static bool check_magic_number(uint16_t magic, bool *native,
41 mfs_version_t *version, bool *longfilenames);
42
43static LIST_INITIALIZE(inst_list);
44static FIBRIL_MUTEX_INITIALIZE(inst_list_mutex);
45
46libfs_ops_t mfs_libfs_ops = {
47 .device_get = mfs_device_get,
48 .is_directory = mfs_is_directory
49};
50
51void mfs_mounted(ipc_callid_t rid, ipc_call_t *request)
52{
53 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
54 enum cache_mode cmode;
55 struct mfs_superblock *sb;
56 struct mfs3_superblock *sb3;
57 struct mfs_sb_info *sbi;
58 struct mfs_instance *instance;
59 bool native, longnames;
60 mfs_version_t version;
61 uint16_t magic;
62
63 /* Accept the mount options */
64 char *opts;
65 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
66
67 if (rc != EOK) {
68 mfsdebug("Can't accept async data write\n");
69 async_answer_0(rid, rc);
70 return;
71 }
72
73 /* Check for option enabling write through. */
74 if (str_cmp(opts, "wtcache") == 0)
75 cmode = CACHE_MODE_WT;
76 else
77 cmode = CACHE_MODE_WB;
78
79 free(opts);
80
81 /* initialize libblock */
82 rc = block_init(devmap_handle, 1024);
83 if (rc != EOK) {
84 mfsdebug("libblock initialization failed\n");
85 async_answer_0(rid, rc);
86 return;
87 }
88
89 /*Allocate space for generic MFS superblock*/
90 sbi = (struct mfs_sb_info *) malloc(sizeof(struct mfs_sb_info));
91
92 if (!sbi) {
93 async_answer_0(rid, ENOMEM);
94 return;
95 }
96
97 /*Allocate space for filesystem instance*/
98 instance = (struct mfs_instance *) malloc(sizeof(struct mfs_instance));
99
100 if (!instance) {
101 async_answer_0(rid, ENOMEM);
102 return;
103 }
104
105 sb = (struct mfs_superblock *) malloc(MFS_SUPERBLOCK_SIZE);
106
107 if (!sb) {
108 async_answer_0(rid, ENOMEM);
109 return;
110 }
111
112 /* Read the superblock */
113 rc = block_read_direct(devmap_handle, MFS_SUPERBLOCK << 1, 1, sb);
114 if (rc != EOK) {
115 block_fini(devmap_handle);
116 async_answer_0(rid, rc);
117 return;
118 }
119
120 sb3 = (struct mfs3_superblock *) sb;
121
122 if (check_magic_number(sb->s_magic, &native, &version, &longnames)) {
123 magic = sb->s_magic;
124 goto recognized;
125 }
126
127 if (!check_magic_number(sb3->s_magic, &native, &version, &longnames)) {
128 mfsdebug("magic number not recognized\n");
129 block_fini(devmap_handle);
130 async_answer_0(rid, ENOTSUP);
131 return;
132 }
133
134 magic = sb3->s_magic;
135
136recognized:
137
138 mfsdebug("magic number recognized = %04x\n", magic);
139
140 /*Fill superblock info structure*/
141
142 sbi->fs_version = version;
143 sbi->long_names = longnames;
144 sbi->native = native;
145 sbi->magic = magic;
146
147 if (version == MFS_VERSION_V3) {
148 sbi->ninodes = conv32(native, sb3->s_ninodes);
149 sbi->ibmap_blocks = conv16(native, sb3->s_ibmap_blocks);
150 sbi->zbmap_blocks = conv16(native, sb3->s_zbmap_blocks);
151 sbi->firstdatazone = conv16(native, sb3->s_first_data_zone);
152 sbi->log2_zone_size = conv16(native, sb3->s_log2_zone_size);
153 sbi->max_file_size = conv32(native, sb3->s_max_file_size);
154 sbi->nzones = conv32(native, sb3->s_nzones);
155 sbi->block_size = conv16(native, sb3->s_block_size);
156 } else {
157 sbi->ninodes = conv16(native, sb->s_ninodes);
158 sbi->ibmap_blocks = conv16(native, sb->s_ibmap_blocks);
159 sbi->zbmap_blocks = conv16(native, sb->s_zbmap_blocks);
160 sbi->firstdatazone = conv16(native, sb->s_first_data_zone);
161 sbi->log2_zone_size = conv16(native, sb->s_log2_zone_size);
162 sbi->max_file_size = conv32(native, sb->s_max_file_size);
163 sbi->nzones = conv16(native, sb->s_nzones);
164 sbi->block_size = MFS_BLOCKSIZE;
165 if (version == MFS_VERSION_V2)
166 sbi->nzones = conv32(native, sb->s_nzones2);
167 }
168
169 free(sb);
170
171 rc = block_cache_init(devmap_handle, sbi->block_size, 0, CACHE_MODE_WT);
172
173 if (rc != EOK) {
174 block_fini(devmap_handle);
175 async_answer_0(rid, EINVAL);
176 mfsdebug("block cache initialization failed\n");
177 return;
178 }
179
180 /*Initialize the instance structure and add it to the list*/
181 link_initialize(&instance->link);
182 instance->handle = devmap_handle;
183 instance->sbi = sbi;
184
185 fibril_mutex_lock(&inst_list_mutex);
186 list_append(&instance->link, &inst_list);
187 fibril_mutex_unlock(&inst_list_mutex);
188
189 mfsdebug("mount successful\n");
190
191 async_answer_0(rid, EOK);
192}
193
194void mfs_mount(ipc_callid_t rid, ipc_call_t *request)
195{
196 libfs_mount(&mfs_libfs_ops, mfs_reg.fs_handle, rid, request);
197}
198
199devmap_handle_t mfs_device_get(fs_node_t *fsnode)
200{
201 struct mfs_node *node = fsnode->data;
202 return node->instance->handle;
203}
204
205bool mfs_is_directory(fs_node_t *fsnode)
206{
207 struct mfs_node *node = fsnode->data;
208 struct mfs_sb_info *sbi = node->instance->sbi;
209
210 if (sbi->fs_version == MFS_VERSION_V1)
211 return S_ISDIR(node->ino->i_mode);
212 else
213 return S_ISDIR(node->ino2->i_mode);
214}
215
216/*
217 * Find a filesystem instance given the devmap handle
218 */
219int mfs_get_instance(devmap_handle_t handle, struct mfs_instance **instance)
220{
221 link_t *link;
222 struct mfs_instance *instance_ptr;
223
224 fibril_mutex_lock(&inst_list_mutex);
225
226 for (link = inst_list.next; link != &inst_list; link = link->next) {
227 instance_ptr = list_get_instance(link, struct mfs_instance, link);
228
229 if (instance_ptr->handle == handle) {
230 *instance = instance_ptr;
231 fibril_mutex_unlock(&inst_list_mutex);
232 return EOK;
233 }
234 }
235
236 mfsdebug("Instance not found\n");
237
238 fibril_mutex_unlock(&inst_list_mutex);
239 return EINVAL;
240}
241
242static bool check_magic_number(uint16_t magic, bool *native,
243 mfs_version_t *version, bool *longfilenames)
244{
245 *longfilenames = false;
246
247 if (magic == MFS_MAGIC_V1 || magic == MFS_MAGIC_V1R) {
248 *native = magic == MFS_MAGIC_V1;
249 *version = MFS_VERSION_V1;
250 return true;
251 } else if (magic == MFS_MAGIC_V1L || magic == MFS_MAGIC_V1LR) {
252 *native = magic == MFS_MAGIC_V1L;
253 *version = MFS_VERSION_V1;
254 *longfilenames = true;
255 return true;
256 } else if (magic == MFS_MAGIC_V2 || magic == MFS_MAGIC_V2R) {
257 *native = magic == MFS_MAGIC_V2;
258 *version = MFS_VERSION_V2;
259 return true;
260 } else if (magic == MFS_MAGIC_V2L || magic == MFS_MAGIC_V2LR) {
261 *native = magic == MFS_MAGIC_V2L;
262 *version = MFS_VERSION_V2;
263 *longfilenames = true;
264 return true;
265 } else if (magic == MFS_MAGIC_V3 || magic == MFS_MAGIC_V3R) {
266 *native = magic == MFS_MAGIC_V3;
267 *version = MFS_VERSION_V3;
268 return true;
269 }
270
271 return false;
272}
273
274/**
275 * @}
276 */
277
Note: See TracBrowser for help on using the repository browser.