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

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

Link mfs_is_directory() and mfs_is_file() functions to the libfs_ops structure

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