Diff markup
001 !! 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 019
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/list.h> 022 #include <sos/list.h>
023 #include <sos/kmem_slab.h> 023 #include <sos/kmem_slab.h>
024 #include <sos/kmalloc.h> 024 #include <sos/kmalloc.h>
025 #include "chardev.h" 025 #include "chardev.h"
026 026
027 #include "fs.h" 027 #include "fs.h"
028 028
029 029
030 030
031 static struct sos_fs_manager_type * fs_list = 031 static struct sos_fs_manager_type * fs_list = NULL;
032 032
033 033
034 static sos_ui64_t last_fs_instance_uid; 034 static sos_ui64_t last_fs_instance_uid;
035 035
036 036
037 037
038 038
039 039
040 static sos_ret_t fs_fetch_node(struct sos_fs_m 040 static sos_ret_t fs_fetch_node(struct sos_fs_manager_instance *fs,
041 sos_ui64_t stor 041 sos_ui64_t storage_location,
042 struct sos_fs_n 042 struct sos_fs_node ** result_fsnode);
043 043
044 static sos_ret_t 044 static sos_ret_t
045 fs_allocate_node(struct sos_fs_manager_instanc 045 fs_allocate_node(struct sos_fs_manager_instance * fs,
046 sos_fs_node_type_t type, 046 sos_fs_node_type_t type,
047 sos_ui32_t flags, 047 sos_ui32_t flags,
048 const struct sos_process * cr 048 const struct sos_process * creator,
049 sos_ui32_t access_rights, 049 sos_ui32_t access_rights,
050 struct sos_fs_node ** result_ 050 struct sos_fs_node ** result_fsnode);
051 051
052 static sos_ret_t mark_dirty_fsnode(struct sos_ 052 static sos_ret_t mark_dirty_fsnode(struct sos_fs_node * fsnode,
053 sos_bool_t 053 sos_bool_t force_sync);
054 054
055 static sos_ret_t sos_fs_sync_node(struct sos_f 055 static sos_ret_t sos_fs_sync_node(struct sos_fs_node * fsnode);
056 056
057 static sos_ret_t sos_fs_sync_fs(struct sos_fs_ 057 static sos_ret_t sos_fs_sync_fs(struct sos_fs_manager_instance * fs);
058 058
059 static sos_ret_t 059 static sos_ret_t
060 fs_lookup_node(const struct sos_fs_pathname * 060 fs_lookup_node(const struct sos_fs_pathname * path,
061 sos_bool_t follow_symlinks, 061 sos_bool_t follow_symlinks,
062 const struct sos_fs_nscache_nod 062 const struct sos_fs_nscache_node * root_nsnode,
063 const struct sos_fs_nscache_nod 063 const struct sos_fs_nscache_node * start_nsnode,
064 struct sos_fs_nscache_node ** r 064 struct sos_fs_nscache_node ** result_nsnode,
065 struct sos_fs_pathname * result 065 struct sos_fs_pathname * result_remaining_path,
066 int lookup_recursion_level); 066 int lookup_recursion_level);
067 067
068 static sos_ret_t 068 static sos_ret_t
069 fs_resolve_symlink(const struct sos_fs_nscache 069 fs_resolve_symlink(const struct sos_fs_nscache_node * root_nsnode,
070 const struct sos_fs_nscache 070 const struct sos_fs_nscache_node * symlink_nsnode,
071 struct sos_fs_nscache_node 071 struct sos_fs_nscache_node ** target_nsnode,
072 int lookup_recursion_level) 072 int lookup_recursion_level);
073 073
074 static sos_ret_t 074 static sos_ret_t
075 fs_register_child_node(const struct sos_proces 075 fs_register_child_node(const struct sos_process * creator,
076 struct sos_fs_nscache_n 076 struct sos_fs_nscache_node * parent_nsnode,
077 const struct sos_fs_pat 077 const struct sos_fs_pathname * name,
078 struct sos_fs_node * fs 078 struct sos_fs_node * fsnode,
079 sos_ui32_t flags, 079 sos_ui32_t flags,
080 struct sos_fs_nscache_n 080 struct sos_fs_nscache_node ** result_nsnode);
081 081
082 static sos_ret_t 082 static sos_ret_t
083 fs_create_child_node(struct sos_fs_nscache_nod 083 fs_create_child_node(struct sos_fs_nscache_node * parent_nsnode,
084 const struct sos_fs_pathn 084 const struct sos_fs_pathname * name,
085 sos_fs_node_type_t type, 085 sos_fs_node_type_t type,
086 sos_ui32_t flags, 086 sos_ui32_t flags,
087 const struct sos_process 087 const struct sos_process * creator,
088 sos_ui32_t access_rights, 088 sos_ui32_t access_rights,
089 struct sos_fs_nscache_nod 089 struct sos_fs_nscache_node ** result_nsnode);
090 090
091 static sos_ret_t 091 static sos_ret_t
092 fs_connect_existing_child_node(const struct so 092 fs_connect_existing_child_node(const struct sos_process * creator,
093 struct sos_fs_n 093 struct sos_fs_nscache_node * parent_nsnode,
094 const struct so 094 const struct sos_fs_pathname * name,
095 struct sos_fs_n 095 struct sos_fs_nscache_node * nsnode);
096 096
097 static sos_ret_t 097 static sos_ret_t
098 fs_create_node(const struct sos_fs_pathname * 098 fs_create_node(const struct sos_fs_pathname * _path,
099 const struct sos_process * crea 099 const struct sos_process * creator,
100 sos_ui32_t access_rights, 100 sos_ui32_t access_rights,
101 sos_fs_node_type_t type, 101 sos_fs_node_type_t type,
102 struct sos_fs_nscache_node ** r 102 struct sos_fs_nscache_node ** result_nsnode);
103 103
104 static sos_ret_t 104 static sos_ret_t
105 fs_remove_node(const struct sos_process * acto 105 fs_remove_node(const struct sos_process * actor,
106 struct sos_fs_nscache_node * ns 106 struct sos_fs_nscache_node * nsnode);
107 107
108 108
109 109
110 110
111 111
112 112
113 sos_ret_t 113 sos_ret_t
114 sos_fs_subsystem_setup(const char * root_devic 114 sos_fs_subsystem_setup(const char * root_device,
115 const char * fsname, 115 const char * fsname,
116 const char * mount_args 116 const char * mount_args,
117 struct sos_fs_manager_i 117 struct sos_fs_manager_instance ** result_rootfs)
118 { 118 {
119 sos_ret_t retval; 119 sos_ret_t retval;
120 struct sos_fs_manager_type * fs_type; 120 struct sos_fs_manager_type * fs_type;
121 struct sos_fs_manager_instance * new_fs; 121 struct sos_fs_manager_instance * new_fs;
122 struct sos_fs_node * rdev_fsnode; 122 struct sos_fs_node * rdev_fsnode;
123 int nb_fstypes; 123 int nb_fstypes;
124 124
125 125
126 rdev_fsnode = NULL; 126 rdev_fsnode = NULL;
127 127
128 last_fs_instance_uid = 0; 128 last_fs_instance_uid = 0;
129 *result_rootfs = NULL; 129 *result_rootfs = NULL;
130 130
131 retval = sos_fs_nscache_subsystem_setup(); 131 retval = sos_fs_nscache_subsystem_setup();
132 if (SOS_OK != retval) 132 if (SOS_OK != retval)
133 return retval; 133 return retval;
134 134
135 135
136 list_foreach(fs_list, fs_type, nb_fstypes) 136 list_foreach(fs_list, fs_type, nb_fstypes)
137 { 137 {
138 if (! strcmp(fsname, fs_type->name)) 138 if (! strcmp(fsname, fs_type->name))
139 break; 139 break;
140 } 140 }
141 if (! list_foreach_early_break(fs_list, fs_t 141 if (! list_foreach_early_break(fs_list, fs_type, nb_fstypes))
142 return -SOS_ENODEV; 142 return -SOS_ENODEV;
143 143
144 retval = fs_type->mount(fs_type, 144 retval = fs_type->mount(fs_type,
145 rdev_fsnode, 145 rdev_fsnode,
146 mount_args, & new_fs 146 mount_args, & new_fs);
147 if (SOS_OK != retval) 147 if (SOS_OK != retval)
148 { 148 {
149 if (rdev_fsnode) 149 if (rdev_fsnode)
150 sos_fs_unref_fsnode(rdev_fsnode); 150 sos_fs_unref_fsnode(rdev_fsnode);
151 return retval; 151 return retval;
152 } 152 }
153 153
154 154
155 sos_fs_nscache_get_fs_node(new_fs->root)->fs 155 sos_fs_nscache_get_fs_node(new_fs->root)->fs = new_fs;
156 156
157 *result_rootfs = new_fs; 157 *result_rootfs = new_fs;
158 return SOS_OK; 158 return SOS_OK;
159 } 159 }
160 160
161 161
162 sos_ret_t sos_fs_ref_fsnode(struct sos_fs_node 162 sos_ret_t sos_fs_ref_fsnode(struct sos_fs_node * fsnode)
163 { 163 {
164 fsnode->inmem_ref_cnt ++; 164 fsnode->inmem_ref_cnt ++;
165 return SOS_OK; 165 return SOS_OK;
166 } 166 }
167 167
168 168
169 sos_ret_t _sos_fs_unref_fsnode(struct sos_fs_n 169 sos_ret_t _sos_fs_unref_fsnode(struct sos_fs_node * node)
170 { 170 {
171 SOS_ASSERT_FATAL(node->inmem_ref_cnt > 0); 171 SOS_ASSERT_FATAL(node->inmem_ref_cnt > 0);
172 172
173 173
174 174
175 if ((node->inmem_ref_cnt == 1) && (node->dir 175 if ((node->inmem_ref_cnt == 1) && (node->dirty))
176 { 176 {
177 SOS_ASSERT_FATAL(SOS_OK == sos_fs_sync_n 177 SOS_ASSERT_FATAL(SOS_OK == sos_fs_sync_node(node));
178 } 178 }
179 179
180 node->inmem_ref_cnt --; 180 node->inmem_ref_cnt --;
181 181
182 if (node->inmem_ref_cnt == 0) 182 if (node->inmem_ref_cnt == 0)
183 { 183 {
184 if (SOS_FS_NODE_DEVICE_CHAR == node->typ 184 if (SOS_FS_NODE_DEVICE_CHAR == node->type)
185 sos_chardev_helper_release_fsnode(node 185 sos_chardev_helper_release_fsnode(node);
>> 186 else if (SOS_FS_NODE_DEVICE_BLOCK == node->type)
>> 187 sos_blockdev_helper_release_fsnode(node);
186 sos_hash_remove(node->fs->nodecache, nod 188 sos_hash_remove(node->fs->nodecache, node);
187 node->destructor(node); 189 node->destructor(node);
188 } 190 }
189 191
190 return SOS_OK; 192 return SOS_OK;
191 } 193 }
192 194
193 195
194 sos_ret_t sos_fs_ref_opened_file(struct sos_fs 196 sos_ret_t sos_fs_ref_opened_file(struct sos_fs_opened_file * of)
195 { 197 {
196 of->ref_cnt ++; 198 of->ref_cnt ++;
197 return SOS_OK; 199 return SOS_OK;
198 } 200 }
199 201
200 202
201 sos_ret_t _sos_fs_unref_opened_file(struct sos 203 sos_ret_t _sos_fs_unref_opened_file(struct sos_fs_opened_file ** _of)
202 { 204 {
203 struct sos_fs_opened_file * of = *_of; 205 struct sos_fs_opened_file * of = *_of;
204 *_of = NULL; 206 *_of = NULL;
205 207
206 SOS_ASSERT_FATAL(of->ref_cnt > 0); 208 SOS_ASSERT_FATAL(of->ref_cnt > 0);
207 of->ref_cnt --; 209 of->ref_cnt --;
208 210
209 if (0 == of->ref_cnt) 211 if (0 == of->ref_cnt)
210 { 212 {
211 sos_ret_t retval; 213 sos_ret_t retval;
212 struct sos_fs_nscache_node * nsnode = of 214 struct sos_fs_nscache_node * nsnode = of->direntry;
213 struct sos_fs_node * fsnode = sos_fs_nsc 215 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(nsnode);
214 216
215 retval = fsnode->close_opened_file(fsnod 217 retval = fsnode->close_opened_file(fsnode, of);
216 if (SOS_OK != retval) 218 if (SOS_OK != retval)
217 return retval; 219 return retval;
218 220
219 return sos_fs_nscache_unref_node(nsnode) 221 return sos_fs_nscache_unref_node(nsnode);
220 } 222 }
221 223
222 return SOS_OK; 224 return SOS_OK;
223 } 225 }
224 226
225 227
226 228
227 229
228 230
229 231
230 232
231 233
232 static sos_ret_t fs_fetch_node(struct sos_fs_m 234 static sos_ret_t fs_fetch_node(struct sos_fs_manager_instance *fs,
233 sos_ui64_t stor 235 sos_ui64_t storage_location,
234 struct sos_fs_n 236 struct sos_fs_node ** result_fsnode)
235 { 237 {
236 sos_ret_t retval; 238 sos_ret_t retval;
237 239
238 240
239 *result_fsnode = (struct sos_fs_node*) 241 *result_fsnode = (struct sos_fs_node*)
240 sos_hash_lookup(fs->nodecache, 242 sos_hash_lookup(fs->nodecache,
241 & storage_location); 243 & storage_location);
242 if (*result_fsnode) 244 if (*result_fsnode)
243 return SOS_OK; 245 return SOS_OK;
244 246
245 247
246 retval = fs->fetch_node_from_disk(fs, storag 248 retval = fs->fetch_node_from_disk(fs, storage_location, result_fsnode);
247 if (SOS_OK != retval) 249 if (SOS_OK != retval)
248 return retval; 250 return retval;
249 251
250 (*result_fsnode)->generation = 0; 252 (*result_fsnode)->generation = 0;
251 253
252 254
253 if (SOS_FS_NODE_DEVICE_CHAR == (*result_fsno 255 if (SOS_FS_NODE_DEVICE_CHAR == (*result_fsnode)->type)
254 SOS_ASSERT_FATAL(SOS_OK 256 SOS_ASSERT_FATAL(SOS_OK
255 == sos_chardev_helper_ref 257 == sos_chardev_helper_ref_new_fsnode(*result_fsnode));
>> 258 else if (SOS_FS_NODE_DEVICE_BLOCK == (*result_fsnode)->type)
>> 259 SOS_ASSERT_FATAL(SOS_OK
>> 260 == sos_blockdev_helper_ref_new_fsnode(*result_fsnode));
>> 261
256 sos_hash_insert(fs->nodecache, *result_fsnod 262 sos_hash_insert(fs->nodecache, *result_fsnode);
257 return SOS_OK; 263 return SOS_OK;
258 } 264 }
259 265
260 266
261 267
262 268
263 269
264 static sos_ret_t 270 static sos_ret_t
265 fs_allocate_node(struct sos_fs_manager_instanc 271 fs_allocate_node(struct sos_fs_manager_instance * fs,
266 sos_fs_node_type_t type, 272 sos_fs_node_type_t type,
267 sos_ui32_t flags, 273 sos_ui32_t flags,
268 const struct sos_process * cr 274 const struct sos_process * creator,
269 sos_ui32_t access_rights, 275 sos_ui32_t access_rights,
270 struct sos_fs_node ** result_ 276 struct sos_fs_node ** result_fsnode)
271 { 277 {
272 sos_ret_t retval; 278 sos_ret_t retval;
273 279
274 280
275 if (fs->flags & SOS_FS_MOUNT_READONLY) 281 if (fs->flags & SOS_FS_MOUNT_READONLY)
276 return -SOS_EPERM; 282 return -SOS_EPERM;
277 283
278 284
279 retval = fs->allocate_new_node(fs, type, 285 retval = fs->allocate_new_node(fs, type,
280 creator, acce 286 creator, access_rights,
281 flags, 287 flags,
282 result_fsnode 288 result_fsnode);
283 if (SOS_OK != retval) 289 if (SOS_OK != retval)
284 return retval; 290 return retval;
285 291
286 292
287 (*result_fsnode)->fs = fs; 293 (*result_fsnode)->fs = fs;
288 294
289 295
290 if (SOS_FS_NODE_DEVICE_CHAR == (*result_fsno 296 if (SOS_FS_NODE_DEVICE_CHAR == (*result_fsnode)->type)
291 { 297 {
292 SOS_ASSERT_FATAL(SOS_OK 298 SOS_ASSERT_FATAL(SOS_OK
293 == sos_chardev_helper_r 299 == sos_chardev_helper_ref_new_fsnode(*result_fsnode));
294 } 300 }
>> 301 else if (SOS_FS_NODE_DEVICE_BLOCK == (*result_fsnode)->type)
>> 302 {
>> 303 SOS_ASSERT_FATAL(SOS_OK
>> 304 == sos_blockdev_helper_ref_new_fsnode(*result_fsnode));
>> 305 }
>> 306
295 307
296 308
297 retval = sos_hash_insert(fs->nodecache, *res 309 retval = sos_hash_insert(fs->nodecache, *result_fsnode);
298 if (SOS_OK != retval) 310 if (SOS_OK != retval)
299 { 311 {
300 sos_fs_unref_fsnode(*result_fsnode); 312 sos_fs_unref_fsnode(*result_fsnode);
301 return retval; 313 return retval;
302 } 314 }
303 315
304 316
305 mark_dirty_fsnode(*result_fsnode, FALSE); 317 mark_dirty_fsnode(*result_fsnode, FALSE);
306 return retval; 318 return retval;
307 } 319 }
308 320
309 321
310 322
311 323
312 324
313 static sos_ret_t mark_dirty_fsnode(struct sos_ 325 static sos_ret_t mark_dirty_fsnode(struct sos_fs_node * fsnode,
314 sos_bool_t 326 sos_bool_t force_sync)
315 { 327 {
316 sos_ret_t retval; 328 sos_ret_t retval;
317 sos_bool_t was_dirty = fsnode->dirty; 329 sos_bool_t was_dirty = fsnode->dirty;
318 330
319 fsnode->dirty = TRUE; 331 fsnode->dirty = TRUE;
320 fsnode->generation ++; 332 fsnode->generation ++;
321 retval = SOS_OK; 333 retval = SOS_OK;
322 334
323 335
324 336
325 if (!was_dirty && fsnode->dirty) 337 if (!was_dirty && fsnode->dirty)
326 list_add_tail_named(fsnode->fs->dirty_node 338 list_add_tail_named(fsnode->fs->dirty_nodes, fsnode,
327 prev_dirty, next_dirty 339 prev_dirty, next_dirty);
328 340
329 if (force_sync || (fsnode->fs->flags & SOS_F 341 if (force_sync || (fsnode->fs->flags & SOS_FS_MOUNT_SYNC))
330 { !! 342 return sos_fs_sync_node(fsnode);
331 <<
332 if (SOS_OK == sos_fs_sync_node(fsnode)) <<
333 { <<
334 <<
335 if (SOS_OK <<
336 == fsnode->fs->device->sync(fsno <<
337 return SOS_OK; <<
338 <<
339 <<
340 was_dirty = FALSE; <<
341 fsnode->dirty = TRUE; <<
342 retval = -SOS_EBUSY; <<
343 } <<
344 } <<
345 343
346 return retval; 344 return retval;
347 } 345 }
348 346
349 347
350 348
351 static sos_ret_t sos_fs_sync_node(struct sos_f 349 static sos_ret_t sos_fs_sync_node(struct sos_fs_node * fsnode)
352 { 350 {
353 sos_ret_t retval; 351 sos_ret_t retval;
354 352
355 if (! fsnode->dirty) 353 if (! fsnode->dirty)
356 return SOS_OK; 354 return SOS_OK;
357 355
358 retval = fsnode->sync(fsnode); !! 356 retval = fsnode->ops_file->sync(fsnode);
359 if (SOS_OK != retval) 357 if (SOS_OK != retval)
360 return retval; 358 return retval;
361 359
362 360
363 list_delete_named(fsnode->fs->dirty_nodes, f 361 list_delete_named(fsnode->fs->dirty_nodes, fsnode,
364 prev_dirty, next_dirty); 362 prev_dirty, next_dirty);
365 fsnode->dirty = FALSE; 363 fsnode->dirty = FALSE;
366 364
>> 365
>> 366 if (fsnode->fs->device)
>> 367 {
>> 368 retval = sos_blockdev_helper_sync_fsnode(fsnode->fs->device);
>> 369 if (SOS_OK != retval)
>> 370 {
>> 371
>> 372 list_add_tail_named(fsnode->fs->dirty_nodes, fsnode,
>> 373 prev_dirty, next_dirty);
>> 374 fsnode->dirty = TRUE;
>> 375 return retval;
>> 376 }
>> 377 }
>> 378
367 return SOS_OK; 379 return SOS_OK;
368 } 380 }
369 381
370 382
371 383
372 384
373 static sos_ret_t sos_fs_sync_fs(struct sos_fs_ 385 static sos_ret_t sos_fs_sync_fs(struct sos_fs_manager_instance * fs)
374 { 386 {
375 struct sos_fs_node * fsnode; 387 struct sos_fs_node * fsnode;
376 while (NULL != (fsnode = list_get_head_named 388 while (NULL != (fsnode = list_get_head_named(fs->dirty_nodes,
377 389 prev_dirty, next_dirty)))
378 { 390 {
379 sos_ret_t retval = sos_fs_sync_node(fsno 391 sos_ret_t retval = sos_fs_sync_node(fsnode);
380 if (SOS_OK != retval) 392 if (SOS_OK != retval)
381 return retval; 393 return retval;
382 } 394 }
383 <<
384 if (NULL != fs->device) <<
385 return fs->device->sync(fs->device); <<
386 395
387 return SOS_OK; 396 return SOS_OK;
388 } 397 }
389 398
390 399
391 400
392 401
393 402
394 403
395 404
396 405
397 406
398 static sos_ret_t 407 static sos_ret_t
399 fs_resolve_symlink(const struct sos_fs_nscache 408 fs_resolve_symlink(const struct sos_fs_nscache_node * root_nsnode,
400 const struct sos_fs_nscache 409 const struct sos_fs_nscache_node * symlink_nsnode,
401 struct sos_fs_nscache_node 410 struct sos_fs_nscache_node ** target_nsnode,
402 int lookup_recursion_level) 411 int lookup_recursion_level)
403 { 412 {
404 sos_ret_t retval; 413 sos_ret_t retval;
405 const struct sos_fs_nscache_node * start_nsn 414 const struct sos_fs_nscache_node * start_nsnode;
406 struct sos_fs_node * symlink_fsnode; 415 struct sos_fs_node * symlink_fsnode;
407 struct sos_fs_pathname path; 416 struct sos_fs_pathname path;
408 struct sos_fs_pathname remaining; 417 struct sos_fs_pathname remaining;
409 418
410 symlink_fsnode = sos_fs_nscache_get_fs_node( 419 symlink_fsnode = sos_fs_nscache_get_fs_node(symlink_nsnode);
411 retval = symlink_fsnode->ops_symlink->expand 420 retval = symlink_fsnode->ops_symlink->expand(symlink_fsnode,
412 421 & path.contents,
413 422 & path.length);
414 if (SOS_OK != retval) 423 if (SOS_OK != retval)
415 return retval; 424 return retval;
416 if (path.length <= 0) 425 if (path.length <= 0)
417 return -SOS_ENOENT; 426 return -SOS_ENOENT;
418 427
419 428
420 if (path.contents[0] == '/') 429 if (path.contents[0] == '/')
421 start_nsnode = root_nsnode; 430 start_nsnode = root_nsnode;
422 else 431 else
423 { 432 {
424 retval = sos_fs_nscache_get_parent(symli 433 retval = sos_fs_nscache_get_parent(symlink_nsnode,
425 (stru 434 (struct sos_fs_nscache_node**)& start_nsnode);
426 if (SOS_OK != retval) 435 if (SOS_OK != retval)
427 return retval; 436 return retval;
428 } 437 }
429 438
430 retval = fs_lookup_node(& path, TRUE, root_n 439 retval = fs_lookup_node(& path, TRUE, root_nsnode, start_nsnode,
431 target_nsnode, 440 target_nsnode,
432 & remaining, lookup_ 441 & remaining, lookup_recursion_level);
433 if (SOS_OK != retval) 442 if (SOS_OK != retval)
434 return retval; 443 return retval;
435 444
436 445
437 if (remaining.length != 0) 446 if (remaining.length != 0)
438 { 447 {
439 sos_fs_nscache_unref_node(*target_nsnode 448 sos_fs_nscache_unref_node(*target_nsnode);
440 return -SOS_ENOENT; 449 return -SOS_ENOENT;
441 } 450 }
442 451
443 return SOS_OK; 452 return SOS_OK;
444 } 453 }
445 454
446 455
447 #define MAX_LOOKUP_RECURSION_LEVEL 5 456 #define MAX_LOOKUP_RECURSION_LEVEL 5
448 457
449 458
450 459
451 460
452 461
453 462
454 463
455 464
456 465
457 466
458 467
459 468
460 static sos_ret_t 469 static sos_ret_t
461 fs_lookup_node(const struct sos_fs_pathname * 470 fs_lookup_node(const struct sos_fs_pathname * path,
462 sos_bool_t follow_symlinks, 471 sos_bool_t follow_symlinks,
463 const struct sos_fs_nscache_nod 472 const struct sos_fs_nscache_node * root_nsnode,
464 const struct sos_fs_nscache_nod 473 const struct sos_fs_nscache_node * start_nsnode,
465 struct sos_fs_nscache_node ** r 474 struct sos_fs_nscache_node ** result_nsnode,
466 struct sos_fs_pathname * result 475 struct sos_fs_pathname * result_remaining_path,
467 int lookup_recursion_level) 476 int lookup_recursion_level)
468 { 477 {
469 sos_ret_t retval; 478 sos_ret_t retval;
470 struct sos_fs_nscache_node * current_nsnode; 479 struct sos_fs_nscache_node * current_nsnode;
471 480
472 481
473 lookup_recursion_level ++; 482 lookup_recursion_level ++;
474 if (lookup_recursion_level > MAX_LOOKUP_RECU 483 if (lookup_recursion_level > MAX_LOOKUP_RECURSION_LEVEL)
475 { 484 {
476 return -SOS_ELOOP; 485 return -SOS_ELOOP;
477 } 486 }
478 487
479 if (path->length <= 0) 488 if (path->length <= 0)
480 return -SOS_ENOENT; 489 return -SOS_ENOENT;
481 490
482 *result_nsnode = NULL; 491 *result_nsnode = NULL;
483 memcpy(result_remaining_path, path, sizeof(* 492 memcpy(result_remaining_path, path, sizeof(*path));
484 493
485 current_nsnode = (struct sos_fs_nscache_node 494 current_nsnode = (struct sos_fs_nscache_node *)start_nsnode;
486 sos_fs_nscache_ref_node(current_nsnode); 495 sos_fs_nscache_ref_node(current_nsnode);
487 while (1) 496 while (1)
488 { 497 {
489 struct sos_fs_pathname current_component 498 struct sos_fs_pathname current_component, remaining;
490 struct sos_fs_nscache_node * next_nsnode 499 struct sos_fs_nscache_node * next_nsnode = NULL;
491 sos_bool_t slashes_after_first_component 500 sos_bool_t slashes_after_first_component;
492 501
493 502
494 503
495 504
496 slashes_after_first_component 505 slashes_after_first_component
497 = sos_fs_pathname_split_path(result_re 506 = sos_fs_pathname_split_path(result_remaining_path,
498 & current 507 & current_component, & remaining);
499 508
500 509
501 510
502 511
503 512
504 513
505 if (current_component.length == 0) 514 if (current_component.length == 0)
506 { 515 {
507 516
508 memcpy(result_remaining_path, & rema 517 memcpy(result_remaining_path, & remaining, sizeof(remaining));
509 *result_nsnode = current_nsnode; 518 *result_nsnode = current_nsnode;
510 return SOS_OK; 519 return SOS_OK;
511 } 520 }
512 521
513 522
514 if (sos_fs_nscache_get_fs_node(current_n 523 if (sos_fs_nscache_get_fs_node(current_nsnode)->type
515 != SOS_FS_NODE_DIRECTORY) 524 != SOS_FS_NODE_DIRECTORY)
516 { 525 {
517 sos_fs_nscache_unref_node(current_ns 526 sos_fs_nscache_unref_node(current_nsnode);
518 return -SOS_ENOENT; 527 return -SOS_ENOENT;
519 } 528 }
520 529
521 530
522 if (! (sos_fs_nscache_get_fs_node(curren 531 if (! (sos_fs_nscache_get_fs_node(current_nsnode)->access_rights
523 & SOS_FS_EXECUTABLE) ) 532 & SOS_FS_EXECUTABLE) )
524 { 533 {
525 sos_fs_nscache_unref_node(current_ns 534 sos_fs_nscache_unref_node(current_nsnode);
526 return -SOS_EACCES; 535 return -SOS_EACCES;
527 } 536 }
528 537
529 538
530 539
531 retval = sos_fs_nscache_lookup(current_n 540 retval = sos_fs_nscache_lookup(current_nsnode,
532 & current 541 & current_component,
533 root_nsno 542 root_nsnode,
534 & next_ns 543 & next_nsnode);
535 if (SOS_OK != retval) 544 if (SOS_OK != retval)
536 { 545 {
537 struct sos_fs_node * current_fsnode, 546 struct sos_fs_node * current_fsnode, * next_fsnode;
538 sos_ui64_t storage_location; 547 sos_ui64_t storage_location;
539 548
540 549
541 550
542 551
543 552
544 current_fsnode = sos_fs_nscache_get_ 553 current_fsnode = sos_fs_nscache_get_fs_node(current_nsnode);
545 554
546 retval = current_fsnode->ops_dir 555 retval = current_fsnode->ops_dir
547 ->lookup(current_fsnode, 556 ->lookup(current_fsnode,
548 current_component.content 557 current_component.contents,
549 current_component.length, 558 current_component.length,
550 & storage_location); 559 & storage_location);
551 if (SOS_OK != retval) 560 if (SOS_OK != retval)
552 { 561 {
553 562
554 *result_nsnode = current_nsnode; 563 *result_nsnode = current_nsnode;
555 return SOS_OK; 564 return SOS_OK;
556 } 565 }
557 566
558 567
559 568
560 retval = fs_fetch_node(current_fsnod 569 retval = fs_fetch_node(current_fsnode->fs,
561 storage_locat 570 storage_location, & next_fsnode);
562 if (SOS_OK != retval) 571 if (SOS_OK != retval)
563 { 572 {
564 sos_fs_nscache_unref_node(curren 573 sos_fs_nscache_unref_node(current_nsnode);
565 return retval; 574 return retval;
566 } 575 }
567 576
568 577
569 retval = sos_fs_nscache_add_new_chil 578 retval = sos_fs_nscache_add_new_child_node(current_nsnode,
570 579 & current_component,
571 580 next_fsnode,
572 581 & next_nsnode);
573 sos_fs_nscache_unref_node(current_ns 582 sos_fs_nscache_unref_node(current_nsnode);
574 if (SOS_OK != retval) 583 if (SOS_OK != retval)
575 return retval; 584 return retval;
576 } 585 }
577 else 586 else
578 sos_fs_nscache_unref_node(current_nsno 587 sos_fs_nscache_unref_node(current_nsnode);
579 588
580 589
581 if (sos_fs_nscache_get_fs_node(next_nsno 590 if (sos_fs_nscache_get_fs_node(next_nsnode)->type
582 == SOS_FS_NODE_SYMLINK) 591 == SOS_FS_NODE_SYMLINK)
583 { 592 {
584 593
585 594
586 if ( (remaining.length != 0) 595 if ( (remaining.length != 0)
587 || follow_symlinks ) 596 || follow_symlinks )
588 { 597 {
589 struct sos_fs_nscache_node * sym 598 struct sos_fs_nscache_node * symlink_target;
590 599
591 retval = fs_resolve_symlink(root 600 retval = fs_resolve_symlink(root_nsnode, next_nsnode,
592 & sy 601 & symlink_target,
593 look 602 lookup_recursion_level);
594 sos_fs_nscache_unref_node(next_n 603 sos_fs_nscache_unref_node(next_nsnode);
595 if (SOS_OK != retval) 604 if (SOS_OK != retval)
596 return retval; 605 return retval;
597 606
598 next_nsnode = symlink_target; 607 next_nsnode = symlink_target;
599 } 608 }
600 } 609 }
601 610
602 611
603 612
604 if (slashes_after_first_component 613 if (slashes_after_first_component
605 && 614 &&
606 ( sos_fs_nscache_get_fs_node(next_ns 615 ( sos_fs_nscache_get_fs_node(next_nsnode)->type
607 != SOS_FS_NODE_DIRECTORY) ) 616 != SOS_FS_NODE_DIRECTORY) )
608 { 617 {
609 sos_fs_nscache_unref_node(next_nsnod 618 sos_fs_nscache_unref_node(next_nsnode);
610 return -SOS_ENOTDIR; 619 return -SOS_ENOTDIR;
611 } 620 }
612 621
613 622
614 memcpy(result_remaining_path, & remainin 623 memcpy(result_remaining_path, & remaining, sizeof(remaining));
615 current_nsnode = next_nsnode; 624 current_nsnode = next_nsnode;
616 } 625 }
617 626
618 sos_display_fatal_error("Should not get ther 627 sos_display_fatal_error("Should not get there");
619 return -SOS_EFATAL; 628 return -SOS_EFATAL;
620 } 629 }
621 630
622 631
623 632
624 633
625 634
626 635
627 636
628 637
629 static sos_ret_t 638 static sos_ret_t
630 fs_register_child_node(const struct sos_proces 639 fs_register_child_node(const struct sos_process * creator,
631 struct sos_fs_nscache_n 640 struct sos_fs_nscache_node * parent_nsnode,
632 const struct sos_fs_pat 641 const struct sos_fs_pathname * name,
633 struct sos_fs_node * fs 642 struct sos_fs_node * fsnode,
634 sos_ui32_t flags, 643 sos_ui32_t flags,
635 struct sos_fs_nscache_n 644 struct sos_fs_nscache_node ** result_nsnode)
636 { 645 {
637 sos_ret_t retval; 646 sos_ret_t retval;
638 struct sos_fs_node * parent_fsnode; 647 struct sos_fs_node * parent_fsnode;
639 struct sos_fs_pathname first_component, rema 648 struct sos_fs_pathname first_component, remaining;
640 sos_bool_t slashes_after_first_component = F 649 sos_bool_t slashes_after_first_component = FALSE;
641 650
642 parent_fsnode = sos_fs_nscache_get_fs_node(p 651 parent_fsnode = sos_fs_nscache_get_fs_node(parent_nsnode);
643 if (parent_fsnode->type != SOS_FS_NODE_DIREC 652 if (parent_fsnode->type != SOS_FS_NODE_DIRECTORY)
644 return -SOS_ENOTDIR; 653 return -SOS_ENOTDIR;
645 654
646 if (name->length <= 0) 655 if (name->length <= 0)
647 return -SOS_EINVAL; 656 return -SOS_EINVAL;
648 657
649 slashes_after_first_component 658 slashes_after_first_component
650 = sos_fs_pathname_split_path(name, & first 659 = sos_fs_pathname_split_path(name, & first_component, & remaining);
651 660
652 if (fsnode->type != SOS_FS_NODE_DIRECTORY) 661 if (fsnode->type != SOS_FS_NODE_DIRECTORY)
653 { 662 {
654 663
655 664
656 if (slashes_after_first_component) 665 if (slashes_after_first_component)
657 return -SOS_EINVAL; 666 return -SOS_EINVAL;
658 } 667 }
659 else 668 else
660 { 669 {
661 670
662 671
663 if (remaining.length > 0) 672 if (remaining.length > 0)
664 return -SOS_EINVAL; 673 return -SOS_EINVAL;
665 } 674 }
666 675
667 676
668 if (! (parent_fsnode->access_rights & SOS_FS 677 if (! (parent_fsnode->access_rights & SOS_FS_WRITABLE) )
669 return -SOS_EACCES; 678 return -SOS_EACCES;
670 679
671 680
672 if (fsnode->fs != parent_fsnode->fs) 681 if (fsnode->fs != parent_fsnode->fs)
673 return -SOS_EXDEV; 682 return -SOS_EXDEV;
674 683
675 684
676 sos_fs_nscache_ref_node(parent_nsnode); 685 sos_fs_nscache_ref_node(parent_nsnode);
677 686
678 687
679 retval = parent_fsnode->ops_dir->link(parent 688 retval = parent_fsnode->ops_dir->link(parent_fsnode,
680 creato 689 creator,
681 first_ 690 first_component.contents,
682 first_ 691 first_component.length,
683 fsnode 692 fsnode);
684 if (SOS_OK != retval) 693 if (SOS_OK != retval)
685 { 694 {
686 sos_fs_nscache_unref_node(parent_nsnode) 695 sos_fs_nscache_unref_node(parent_nsnode);
687 return retval; 696 return retval;
688 } 697 }
689 698
690 699
691 mark_dirty_fsnode(parent_fsnode, FALSE); 700 mark_dirty_fsnode(parent_fsnode, FALSE);
692 701
693 702
694 retval = sos_fs_nscache_add_new_child_node(p 703 retval = sos_fs_nscache_add_new_child_node(parent_nsnode, & first_component,
695 f 704 fsnode, result_nsnode);
696 705
697 sos_fs_nscache_unref_node(parent_nsnode); 706 sos_fs_nscache_unref_node(parent_nsnode);
698 return retval; 707 return retval;
699 } 708 }
700 709
701 710
702 711
703 712
704 713
705 static sos_ret_t 714 static sos_ret_t
706 fs_create_child_node(struct sos_fs_nscache_nod 715 fs_create_child_node(struct sos_fs_nscache_node * parent_nsnode,
707 const struct sos_fs_pathn 716 const struct sos_fs_pathname * name,
708 sos_fs_node_type_t type, 717 sos_fs_node_type_t type,
709 sos_ui32_t flags, 718 sos_ui32_t flags,
710 const struct sos_process 719 const struct sos_process * creator,
711 sos_ui32_t access_rights, 720 sos_ui32_t access_rights,
712 struct sos_fs_nscache_nod 721 struct sos_fs_nscache_node ** result_nsnode)
713 { 722 {
714 sos_ret_t retval; 723 sos_ret_t retval;
715 struct sos_fs_node * fsnode, * parent_fsnode 724 struct sos_fs_node * fsnode, * parent_fsnode;
716 725
717 parent_fsnode = sos_fs_nscache_get_fs_node(p 726 parent_fsnode = sos_fs_nscache_get_fs_node(parent_nsnode);
718 if (parent_fsnode->type != SOS_FS_NODE_DIREC 727 if (parent_fsnode->type != SOS_FS_NODE_DIRECTORY)
719 return -SOS_ENOTDIR; 728 return -SOS_ENOTDIR;
720 729
721 730
722 sos_fs_nscache_ref_node(parent_nsnode); 731 sos_fs_nscache_ref_node(parent_nsnode);
723 732
724 retval = fs_allocate_node(parent_fsnode->fs, 733 retval = fs_allocate_node(parent_fsnode->fs, type, flags, creator,
725 access_rights, & f 734 access_rights, & fsnode);
726 if (SOS_OK != retval) 735 if (SOS_OK != retval)
727 { 736 {
728 sos_fs_nscache_unref_node(parent_nsnode) 737 sos_fs_nscache_unref_node(parent_nsnode);
729 return retval; 738 return retval;
730 } 739 }
731 740
732 retval = fs_register_child_node(creator, 741 retval = fs_register_child_node(creator,
733 parent_nsnod 742 parent_nsnode, name, fsnode, flags,
734 result_nsnod 743 result_nsnode);
735 sos_fs_nscache_unref_node(parent_nsnode); 744 sos_fs_nscache_unref_node(parent_nsnode);
736 745
737 746
738 sos_fs_unref_fsnode(fsnode); 747 sos_fs_unref_fsnode(fsnode);
739 748
740 return retval; 749 return retval;
741 } 750 }
742 751
743 752
744 753
745 754
746 755
747 756
748 757
749 758
750 static sos_ret_t 759 static sos_ret_t
751 fs_connect_existing_child_node(const struct so 760 fs_connect_existing_child_node(const struct sos_process * creator,
752 struct sos_fs_n 761 struct sos_fs_nscache_node * parent_nsnode,
753 const struct so 762 const struct sos_fs_pathname * name,
754 struct sos_fs_n 763 struct sos_fs_nscache_node * nsnode)
755 { 764 {
756 sos_ret_t retval; 765 sos_ret_t retval;
757 struct sos_fs_node * parent_fsnode, * fsnode 766 struct sos_fs_node * parent_fsnode, * fsnode;
758 struct sos_fs_pathname first_component, rema 767 struct sos_fs_pathname first_component, remaining;
759 sos_bool_t slashes_after_first_component = F 768 sos_bool_t slashes_after_first_component = FALSE;
760 769
761 fsnode = sos_fs_nscache_get_fs_node(nsnode); 770 fsnode = sos_fs_nscache_get_fs_node(nsnode);
762 parent_fsnode = sos_fs_nscache_get_fs_node(p 771 parent_fsnode = sos_fs_nscache_get_fs_node(parent_nsnode);
763 if (parent_fsnode->type != SOS_FS_NODE_DIREC 772 if (parent_fsnode->type != SOS_FS_NODE_DIRECTORY)
764 return -SOS_ENOTDIR; 773 return -SOS_ENOTDIR;
765 774
766 if (name->length <= 0) 775 if (name->length <= 0)
767 return -SOS_EINVAL; 776 return -SOS_EINVAL;
768 777
769 slashes_after_first_component 778 slashes_after_first_component
770 = sos_fs_pathname_split_path(name, & first 779 = sos_fs_pathname_split_path(name, & first_component, & remaining);
771 780
772 if (fsnode->type != SOS_FS_NODE_DIRECTORY) 781 if (fsnode->type != SOS_FS_NODE_DIRECTORY)
773 { 782 {
774 783
775 784
776 if (slashes_after_first_component) 785 if (slashes_after_first_component)
777 return -SOS_EINVAL; 786 return -SOS_EINVAL;
778 } 787 }
779 else 788 else
780 { 789 {
781 790
782 791
783 if (remaining.length > 0) 792 if (remaining.length > 0)
784 return -SOS_EINVAL; 793 return -SOS_EINVAL;
785 } 794 }
786 795
787 796
788 if (! (parent_fsnode->access_rights & SOS_FS 797 if (! (parent_fsnode->access_rights & SOS_FS_WRITABLE) )
789 return -SOS_EACCES; 798 return -SOS_EACCES;
790 799
791 800
792 if (fsnode->fs != parent_fsnode->fs) 801 if (fsnode->fs != parent_fsnode->fs)
793 return -SOS_EXDEV; 802 return -SOS_EXDEV;
794 803
795 804
796 sos_fs_nscache_ref_node(parent_nsnode); 805 sos_fs_nscache_ref_node(parent_nsnode);
797 806
798 807
799 retval = parent_fsnode->ops_dir->link(parent 808 retval = parent_fsnode->ops_dir->link(parent_fsnode,
800 creato 809 creator,
801 first_ 810 first_component.contents,
802 first_ 811 first_component.length,
803 fsnode 812 fsnode);
804 if (SOS_OK != retval) 813 if (SOS_OK != retval)
805 { 814 {
806 sos_fs_nscache_unref_node(parent_nsnode) 815 sos_fs_nscache_unref_node(parent_nsnode);
807 return retval; 816 return retval;
808 } 817 }
809 818
810 819
811 mark_dirty_fsnode(parent_fsnode, FALSE); 820 mark_dirty_fsnode(parent_fsnode, FALSE);
812 821
813 822
814 retval = sos_fs_nscache_add_existing_child_n 823 retval = sos_fs_nscache_add_existing_child_node(parent_nsnode,
815 824 & first_component,
816 825 nsnode);
817 sos_fs_nscache_unref_node(parent_nsnode); 826 sos_fs_nscache_unref_node(parent_nsnode);
818 return retval; 827 return retval;
819 } 828 }
820 829
821 830
822 831
823 832
824 static sos_ret_t 833 static sos_ret_t
825 fs_create_node(const struct sos_fs_pathname * 834 fs_create_node(const struct sos_fs_pathname * _path,
826 const struct sos_process * crea 835 const struct sos_process * creator,
827 sos_ui32_t access_rights, 836 sos_ui32_t access_rights,
828 sos_fs_node_type_t type, 837 sos_fs_node_type_t type,
829 struct sos_fs_nscache_node ** r 838 struct sos_fs_nscache_node ** result_nsnode)
830 { 839 {
831 sos_ret_t retval; 840 sos_ret_t retval;
832 struct sos_fs_pathname path; 841 struct sos_fs_pathname path;
833 struct sos_fs_nscache_node *nsnode, *new_nsn 842 struct sos_fs_nscache_node *nsnode, *new_nsnode;
834 843
835 path.contents = _path->contents; 844 path.contents = _path->contents;
836 path.length = _path->length; 845 path.length = _path->length;
837 846
838 if (path.length <= 0) 847 if (path.length <= 0)
839 return -SOS_ENOENT; 848 return -SOS_ENOENT;
840 849
841 if (path.contents[0] == '/') 850 if (path.contents[0] == '/')
842 nsnode = sos_process_get_root(creator)->di 851 nsnode = sos_process_get_root(creator)->direntry;
843 else 852 else
844 nsnode = sos_process_get_cwd(creator)->dir 853 nsnode = sos_process_get_cwd(creator)->direntry;
845 854
846 retval = fs_lookup_node(& path, 855 retval = fs_lookup_node(& path,
847 TRUE, 856 TRUE,
848 sos_process_get_root 857 sos_process_get_root(creator)->direntry,
849 nsnode, 858 nsnode,
850 & nsnode, 859 & nsnode,
851 & path, 860 & path,
852 0); 861 0);
853 if (SOS_OK != retval) 862 if (SOS_OK != retval)
854 return retval; 863 return retval;
855 864
856 if (path.length <= 0) 865 if (path.length <= 0)
857 { 866 {
858 867
859 sos_fs_nscache_unref_node(nsnode); 868 sos_fs_nscache_unref_node(nsnode);
860 return -SOS_EEXIST; 869 return -SOS_EEXIST;
861 } 870 }
862 871
863 872
864 retval = fs_create_child_node(nsnode, 873 retval = fs_create_child_node(nsnode,
865 & path, 874 & path,
866 type, 875 type,
867 0, 876 0,
868 creator, acces 877 creator, access_rights,
869 & new_nsnode); 878 & new_nsnode);
870 sos_fs_nscache_unref_node(nsnode); 879 sos_fs_nscache_unref_node(nsnode);
871 880
872 881
873 if (NULL == result_nsnode) 882 if (NULL == result_nsnode)
874 sos_fs_nscache_unref_node(new_nsnode); 883 sos_fs_nscache_unref_node(new_nsnode);
875 else 884 else
876 *result_nsnode = new_nsnode; 885 *result_nsnode = new_nsnode;
877 886
878 return retval; 887 return retval;
879 } 888 }
880 889
881 890
882 static sos_ret_t 891 static sos_ret_t
883 fs_remove_node(const struct sos_process * acto 892 fs_remove_node(const struct sos_process * actor,
884 struct sos_fs_nscache_node * ns 893 struct sos_fs_nscache_node * nsnode)
885 { 894 {
886 sos_ret_t retval; 895 sos_ret_t retval;
887 struct sos_fs_nscache_node * parent_nsnode; 896 struct sos_fs_nscache_node * parent_nsnode;
888 struct sos_fs_node * parent_fsnode; 897 struct sos_fs_node * parent_fsnode;
889 struct sos_fs_pathname childname; 898 struct sos_fs_pathname childname;
890 899
891 900
892 if (nsnode == sos_fs_nscache_get_fs_node(nsn 901 if (nsnode == sos_fs_nscache_get_fs_node(nsnode)->fs->root)
893 return -SOS_EBUSY; 902 return -SOS_EBUSY;
894 903
895 retval = sos_fs_nscache_get_parent(nsnode, & 904 retval = sos_fs_nscache_get_parent(nsnode, & parent_nsnode);
896 if (SOS_OK != retval) 905 if (SOS_OK != retval)
897 return retval; 906 return retval;
898 parent_fsnode = sos_fs_nscache_get_fs_node(p 907 parent_fsnode = sos_fs_nscache_get_fs_node(parent_nsnode);
899 908
900 909
901 if (parent_fsnode->fs->flags & SOS_FS_MOUNT_ 910 if (parent_fsnode->fs->flags & SOS_FS_MOUNT_READONLY)
902 return -SOS_EPERM; 911 return -SOS_EPERM;
903 912
904 913
905 if (! (parent_fsnode->access_rights & SOS_FS 914 if (! (parent_fsnode->access_rights & SOS_FS_WRITABLE) )
906 return -SOS_EACCES; 915 return -SOS_EACCES;
907 916
908 sos_fs_nscache_ref_node(parent_nsnode); 917 sos_fs_nscache_ref_node(parent_nsnode);
909 918
910 sos_fs_nscache_get_name(nsnode, & childname) 919 sos_fs_nscache_get_name(nsnode, & childname);
911 retval = parent_fsnode->ops_dir->unlink(pare 920 retval = parent_fsnode->ops_dir->unlink(parent_fsnode, actor,
912 chil 921 childname.contents,
913 chil 922 childname.length);
914 if (SOS_OK == retval) 923 if (SOS_OK == retval)
915 sos_fs_nscache_disconnect_node(nsnode); 924 sos_fs_nscache_disconnect_node(nsnode);
916 925
917 926
918 if (SOS_OK == retval) 927 if (SOS_OK == retval)
919 mark_dirty_fsnode(parent_fsnode, FALSE); 928 mark_dirty_fsnode(parent_fsnode, FALSE);
920 929
921 sos_fs_nscache_unref_node(parent_nsnode); 930 sos_fs_nscache_unref_node(parent_nsnode);
922 return retval; 931 return retval;
923 } 932 }
924 933
925 934
926 935
927 936
928 937
929 938
930 sos_ret_t sos_fs_new_opened_file(const struct 939 sos_ret_t sos_fs_new_opened_file(const struct sos_process * owner,
931 struct sos_fs 940 struct sos_fs_nscache_node * nsnode,
932 sos_ui32_t op 941 sos_ui32_t open_flags,
933 struct sos_fs 942 struct sos_fs_opened_file ** result_of)
934 { 943 {
935 sos_ret_t retval; 944 sos_ret_t retval;
936 struct sos_fs_node * fsnode = sos_fs_nscache 945 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(nsnode);
937 946
938 retval = fsnode->new_opened_file(fsnode, own 947 retval = fsnode->new_opened_file(fsnode, owner, open_flags, result_of);
939 if (SOS_OK != retval) 948 if (SOS_OK != retval)
940 return retval; 949 return retval;
941 950
942 (*result_of)->ref_cnt = 1; 951 (*result_of)->ref_cnt = 1;
943 (*result_of)->generation = 1; 952 (*result_of)->generation = 1;
944 953
945 retval = sos_fs_nscache_register_opened_file 954 retval = sos_fs_nscache_register_opened_file(nsnode, *result_of);
946 if (SOS_OK != retval) 955 if (SOS_OK != retval)
947 { 956 {
948 fsnode->close_opened_file(fsnode, *resul 957 fsnode->close_opened_file(fsnode, *result_of);
949 return retval; 958 return retval;
950 } 959 }
951 960
952 (*result_of)->open_flags = open_flags; 961 (*result_of)->open_flags = open_flags;
953 return SOS_OK; 962 return SOS_OK;
954 } 963 }
955 964
956 965
957 sos_ret_t 966 sos_ret_t
958 sos_fs_duplicate_opened_file(struct sos_fs_ope 967 sos_fs_duplicate_opened_file(struct sos_fs_opened_file * src_of,
959 const struct sos_ 968 const struct sos_process * dst_proc,
960 struct sos_fs_ope 969 struct sos_fs_opened_file ** result_of)
961 { 970 {
962 sos_ret_t retval = src_of->duplicate(src_of, 971 sos_ret_t retval = src_of->duplicate(src_of, dst_proc, result_of);
963 if (SOS_OK != retval) 972 if (SOS_OK != retval)
964 return retval; 973 return retval;
965 974
966 SOS_ASSERT_FATAL((*result_of)->owner == dst_ 975 SOS_ASSERT_FATAL((*result_of)->owner == dst_proc);
967 (*result_of)->ref_cnt = 1; 976 (*result_of)->ref_cnt = 1;
968 (*result_of)->generation = 1; 977 (*result_of)->generation = 1;
969 retval = sos_fs_nscache_register_opened_file 978 retval = sos_fs_nscache_register_opened_file(src_of->direntry, *result_of);
970 if (SOS_OK != retval) 979 if (SOS_OK != retval)
971 { 980 {
972 struct sos_fs_node * fsnode = sos_fs_nsc 981 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(src_of->direntry);
973 fsnode->close_opened_file(fsnode, *resul 982 fsnode->close_opened_file(fsnode, *result_of);
974 return retval; 983 return retval;
975 } 984 }
976 985
977 return retval; 986 return retval;
978 } 987 }
979 988
980 989
981 sos_ret_t sos_fs_open(const struct sos_process 990 sos_ret_t sos_fs_open(const struct sos_process *owner,
982 const char *_path, 991 const char *_path,
983 sos_size_t _pathlen, 992 sos_size_t _pathlen,
984 sos_ui32_t open_flags, 993 sos_ui32_t open_flags,
985 sos_ui32_t creat_access_ 994 sos_ui32_t creat_access_rights,
986 struct sos_fs_opened_fil 995 struct sos_fs_opened_file ** of)
987 { 996 {
988 sos_ret_t retval; 997 sos_ret_t retval;
989 struct sos_fs_nscache_node *nsnode; 998 struct sos_fs_nscache_node *nsnode;
990 struct sos_fs_node * fsnode; 999 struct sos_fs_node * fsnode;
991 struct sos_fs_pathname path; 1000 struct sos_fs_pathname path;
992 1001
993 1002
994 if ( (open_flags & SOS_FS_OPEN_DIRECTORY) 1003 if ( (open_flags & SOS_FS_OPEN_DIRECTORY)
995 && ( (open_flags & (SOS_FS_OPEN_CREAT 1004 && ( (open_flags & (SOS_FS_OPEN_CREAT
996 | SOS_FS_OPEN_TRUNC 1005 | SOS_FS_OPEN_TRUNC)) ) )
997 return -SOS_EINVAL; 1006 return -SOS_EINVAL;
998 1007
999 if (_pathlen <= 0) 1008 if (_pathlen <= 0)
1000 return -SOS_ENOENT; 1009 return -SOS_ENOENT;
1001 1010
1002 path.contents = _path; 1011 path.contents = _path;
1003 path.length = _pathlen; 1012 path.length = _pathlen;
1004 1013
1005 if (path.contents[0] == '/') 1014 if (path.contents[0] == '/')
1006 nsnode = sos_process_get_root(owner)->dir 1015 nsnode = sos_process_get_root(owner)->direntry;
1007 else 1016 else
1008 nsnode = sos_process_get_cwd(owner)->dire 1017 nsnode = sos_process_get_cwd(owner)->direntry;
1009 1018
1010 retval = fs_lookup_node(& path, 1019 retval = fs_lookup_node(& path,
1011 ! (open_flags & SOS 1020 ! (open_flags & SOS_FS_OPEN_NOFOLLOW),
1012 sos_process_get_roo 1021 sos_process_get_root(owner)->direntry,
1013 nsnode, 1022 nsnode,
1014 & nsnode, 1023 & nsnode,
1015 & path, 1024 & path,
1016 0); 1025 0);
1017 if (SOS_OK != retval) 1026 if (SOS_OK != retval)
1018 return retval; 1027 return retval;
1019 1028
1020 if (path.length <= 0) 1029 if (path.length <= 0)
1021 { 1030 {
1022 1031
1023 1032
1024 1033
1025 if (open_flags & SOS_FS_OPEN_EXCL) 1034 if (open_flags & SOS_FS_OPEN_EXCL)
1026 { 1035 {
1027 sos_fs_nscache_unref_node(nsnode); 1036 sos_fs_nscache_unref_node(nsnode);
1028 return -SOS_EEXIST; 1037 return -SOS_EEXIST;
1029 } 1038 }
1030 1039
1031 fsnode = sos_fs_nscache_get_fs_node(nsn 1040 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1032 if ((open_flags & SOS_FS_OPEN_DIRECTORY 1041 if ((open_flags & SOS_FS_OPEN_DIRECTORY)
1033 && (fsnode->type != SOS_FS_NODE_DIR 1042 && (fsnode->type != SOS_FS_NODE_DIRECTORY))
1034 { 1043 {
1035 sos_fs_nscache_unref_node(nsnode); 1044 sos_fs_nscache_unref_node(nsnode);
1036 return -SOS_ENOTDIR; 1045 return -SOS_ENOTDIR;
1037 } 1046 }
1038 1047
1039 1048
1040 if ((open_flags & SOS_FS_OPEN_TRUNC) 1049 if ((open_flags & SOS_FS_OPEN_TRUNC)
1041 && fsnode->ops_file->truncate) 1050 && fsnode->ops_file->truncate)
1042 { 1051 {
1043 retval = fsnode->ops_file->truncate 1052 retval = fsnode->ops_file->truncate(fsnode, 0);
1044 if (SOS_OK != retval) 1053 if (SOS_OK != retval)
1045 { 1054 {
1046 sos_fs_nscache_unref_node(nsnod 1055 sos_fs_nscache_unref_node(nsnode);
1047 return retval; 1056 return retval;
1048 } 1057 }
1049 } 1058 }
1050 } 1059 }
1051 else 1060 else
1052 { 1061 {
1053 struct sos_fs_nscache_node * parent_nsn 1062 struct sos_fs_nscache_node * parent_nsnode = nsnode;
1054 1063
1055 1064
1056 if (! (open_flags & SOS_FS_OPEN_CREAT)) 1065 if (! (open_flags & SOS_FS_OPEN_CREAT))
1057 { 1066 {
1058 sos_fs_nscache_unref_node(parent_ns 1067 sos_fs_nscache_unref_node(parent_nsnode);
1059 return -SOS_ENOENT; 1068 return -SOS_ENOENT;
1060 } 1069 }
1061 1070
1062 1071
1063 retval = fs_create_child_node(parent_ns 1072 retval = fs_create_child_node(parent_nsnode,
1064 & path, 1073 & path,
1065 SOS_FS_NO 1074 SOS_FS_NODE_REGULAR_FILE,
1066 open_flag 1075 open_flags,
1067 owner, 1076 owner,
1068 creat_acc 1077 creat_access_rights,
1069 & nsnode) 1078 & nsnode);
1070 sos_fs_nscache_unref_node(parent_nsnode 1079 sos_fs_nscache_unref_node(parent_nsnode);
1071 if (SOS_OK != retval) 1080 if (SOS_OK != retval)
1072 { 1081 {
1073 return retval; 1082 return retval;
1074 } 1083 }
1075 1084
1076 fsnode = sos_fs_nscache_get_fs_node(nsn 1085 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1077 } 1086 }
1078 1087
1079 1088
1080 open_flags &= ~(SOS_FS_OPEN_CREAT 1089 open_flags &= ~(SOS_FS_OPEN_CREAT
1081 | SOS_FS_OPEN_EXCL 1090 | SOS_FS_OPEN_EXCL
1082 | SOS_FS_OPEN_NOFOLLOW 1091 | SOS_FS_OPEN_NOFOLLOW
1083 | SOS_FS_OPEN_DIRECTORY); 1092 | SOS_FS_OPEN_DIRECTORY);
1084 if (! (fsnode->access_rights & SOS_FS_WRITA 1093 if (! (fsnode->access_rights & SOS_FS_WRITABLE))
1085 open_flags &= ~(SOS_FS_OPEN_WRITE); 1094 open_flags &= ~(SOS_FS_OPEN_WRITE);
1086 if (! (fsnode->access_rights & SOS_FS_READA 1095 if (! (fsnode->access_rights & SOS_FS_READABLE))
1087 open_flags &= ~(SOS_FS_OPEN_READ); 1096 open_flags &= ~(SOS_FS_OPEN_READ);
1088 if (fsnode->fs->flags & SOS_FS_MOUNT_READON 1097 if (fsnode->fs->flags & SOS_FS_MOUNT_READONLY)
1089 open_flags &= ~(SOS_FS_OPEN_READ); 1098 open_flags &= ~(SOS_FS_OPEN_READ);
1090 1099
1091 1100
1092 1101
1093 1102
1094 retval = sos_fs_new_opened_file(owner, nsno 1103 retval = sos_fs_new_opened_file(owner, nsnode, open_flags, of);
1095 1104
1096 sos_fs_nscache_unref_node(nsnode); 1105 sos_fs_nscache_unref_node(nsnode);
1097 return retval; 1106 return retval;
1098 } 1107 }
1099 1108
1100 1109
1101 sos_ret_t sos_fs_close(struct sos_fs_opened_f 1110 sos_ret_t sos_fs_close(struct sos_fs_opened_file * of)
1102 { 1111 {
1103 return sos_fs_unref_opened_file(of); 1112 return sos_fs_unref_opened_file(of);
1104 } 1113 }
1105 1114
1106 1115
1107 sos_ret_t sos_fs_mark_dirty(struct sos_fs_ope 1116 sos_ret_t sos_fs_mark_dirty(struct sos_fs_opened_file * of)
1108 { 1117 {
1109 struct sos_fs_node * fsnode = sos_fs_nscach 1118 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1110 1119
1111 1120
1112 SOS_ASSERT_FATAL(! (fsnode->fs->flags & SOS 1121 SOS_ASSERT_FATAL(! (fsnode->fs->flags & SOS_FS_MOUNT_READONLY));
1113 1122
1114 return mark_dirty_fsnode(fsnode, of->open_f 1123 return mark_dirty_fsnode(fsnode, of->open_flags & SOS_FS_OPEN_SYNC);
1115 } 1124 }
1116 1125
1117 1126
1118 sos_ret_t sos_fs_read(struct sos_fs_opened_fi 1127 sos_ret_t sos_fs_read(struct sos_fs_opened_file * of,
1119 sos_uaddr_t dest_buf, 1128 sos_uaddr_t dest_buf,
1120 sos_size_t * 1129 sos_size_t * len)
1121 { 1130 {
1122 if (! (of->open_flags & SOS_FS_OPEN_READ)) 1131 if (! (of->open_flags & SOS_FS_OPEN_READ))
1123 return -SOS_EPERM; 1132 return -SOS_EPERM;
1124 1133
1125 if (! of->ops_file->read) 1134 if (! of->ops_file->read)
1126 return -SOS_ENOSYS; 1135 return -SOS_ENOSYS;
1127 1136
1128 return of->ops_file->read(of, dest_buf, len 1137 return of->ops_file->read(of, dest_buf, len);
1129 } 1138 }
1130 1139
1131 1140
1132 sos_ret_t sos_fs_write(struct sos_fs_opened_f 1141 sos_ret_t sos_fs_write(struct sos_fs_opened_file * of,
1133 sos_uaddr_t src_buf, 1142 sos_uaddr_t src_buf,
1134 sos_size_t * 1143 sos_size_t * len)
1135 { 1144 {
1136 if (! (of->open_flags & SOS_FS_OPEN_WRITE)) 1145 if (! (of->open_flags & SOS_FS_OPEN_WRITE))
1137 return -SOS_EPERM; 1146 return -SOS_EPERM;
1138 1147
1139 if (! of->ops_file->write) 1148 if (! of->ops_file->write)
1140 return -SOS_ENOSYS; 1149 return -SOS_ENOSYS;
1141 1150
1142 return of->ops_file->write(of, src_buf, len 1151 return of->ops_file->write(of, src_buf, len);
1143 } 1152 }
1144 1153
1145 1154
1146 sos_ret_t sos_fs_seek(struct sos_fs_opened_fi 1155 sos_ret_t sos_fs_seek(struct sos_fs_opened_file *of,
1147 sos_lsoffset_t offset, 1156 sos_lsoffset_t offset,
1148 sos_seek_whence_t whenc 1157 sos_seek_whence_t whence,
1149 sos_lsoffset_t * result 1158 sos_lsoffset_t * result_position)
1150 { 1159 {
1151 if (! of->ops_file->seek) 1160 if (! of->ops_file->seek)
1152 return -SOS_ENOSYS; 1161 return -SOS_ENOSYS;
1153 1162
1154 return of->ops_file->seek(of, offset, whenc 1163 return of->ops_file->seek(of, offset, whence, result_position);
1155 } 1164 }
1156 1165
1157 1166
1158 sos_ret_t sos_fs_ftruncate(struct sos_fs_open 1167 sos_ret_t sos_fs_ftruncate(struct sos_fs_opened_file *of,
1159 sos_lsoffset_t len 1168 sos_lsoffset_t length)
1160 { 1169 {
1161 sos_ret_t retval; 1170 sos_ret_t retval;
1162 struct sos_fs_node * fsnode = sos_fs_nscach 1171 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1163 1172
1164 if (! (of->open_flags & SOS_FS_OPEN_WRITE)) 1173 if (! (of->open_flags & SOS_FS_OPEN_WRITE))
1165 return -SOS_EPERM; 1174 return -SOS_EPERM;
1166 1175
1167 if (! fsnode->ops_file->truncate) 1176 if (! fsnode->ops_file->truncate)
1168 return -SOS_ENOSYS; 1177 return -SOS_ENOSYS;
1169 1178
1170 retval = fsnode->ops_file->truncate(fsnode, 1179 retval = fsnode->ops_file->truncate(fsnode, length);
1171 if (SOS_OK == retval) 1180 if (SOS_OK == retval)
1172 mark_dirty_fsnode(fsnode, FALSE); 1181 mark_dirty_fsnode(fsnode, FALSE);
1173 1182
1174 return retval; 1183 return retval;
1175 } 1184 }
1176 1185
1177 1186
1178 sos_ret_t sos_fs_mmap(struct sos_fs_opened_fi 1187 sos_ret_t sos_fs_mmap(struct sos_fs_opened_file *of,
1179 sos_uaddr_t *uaddr, sos 1188 sos_uaddr_t *uaddr, sos_size_t size,
1180 sos_ui32_t access_right 1189 sos_ui32_t access_rights,
1181 sos_ui32_t flags, 1190 sos_ui32_t flags,
1182 sos_luoffset_t offset) 1191 sos_luoffset_t offset)
1183 { 1192 {
1184 sos_ui32_t required_access = 0; 1193 sos_ui32_t required_access = 0;
1185 struct sos_fs_node * fsnode = sos_fs_nscach 1194 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1186 1195
1187 if (! of->ops_file->mmap) 1196 if (! of->ops_file->mmap)
1188 return -SOS_ENOSYS; 1197 return -SOS_ENOSYS;
1189 1198
1190 1199
1191 if (access_rights & SOS_VM_MAP_PROT_READ) 1200 if (access_rights & SOS_VM_MAP_PROT_READ)
1192 required_access |= SOS_FS_OPEN_READ; 1201 required_access |= SOS_FS_OPEN_READ;
1193 if ( (access_rights & SOS_VM_MAP_PROT_WRITE 1202 if ( (access_rights & SOS_VM_MAP_PROT_WRITE) && (flags & SOS_VR_MAP_SHARED) )
1194 required_access |= SOS_FS_OPEN_WRITE; 1203 required_access |= SOS_FS_OPEN_WRITE;
1195 if (access_rights & SOS_VM_MAP_PROT_EXEC) 1204 if (access_rights & SOS_VM_MAP_PROT_EXEC)
1196 required_access |= SOS_FS_OPEN_READ; 1205 required_access |= SOS_FS_OPEN_READ;
1197 1206
1198 1207
1199 if ((of->open_flags & required_access) != r 1208 if ((of->open_flags & required_access) != required_access)
1200 return -SOS_EPERM; 1209 return -SOS_EPERM;
1201 1210
1202 if ( (access_rights & SOS_VM_MAP_PROT_EXEC) 1211 if ( (access_rights & SOS_VM_MAP_PROT_EXEC)
1203 && (fsnode->fs->flags & SOS_FS_MOUNT_N 1212 && (fsnode->fs->flags & SOS_FS_MOUNT_NOEXEC) )
1204 return -SOS_EPERM; 1213 return -SOS_EPERM;
1205 1214
1206 return of->ops_file->mmap(of, uaddr, size, 1215 return of->ops_file->mmap(of, uaddr, size, access_rights, flags, offset);
1207 } 1216 }
1208 1217
1209 1218
1210 sos_ret_t sos_fs_fcntl(struct sos_fs_opened_f 1219 sos_ret_t sos_fs_fcntl(struct sos_fs_opened_file *of,
1211 int req_id, 1220 int req_id,
1212 sos_ui32_t req_arg 1221 sos_ui32_t req_arg )
1213 { 1222 {
1214 if (! of->ops_file->fcntl) 1223 if (! of->ops_file->fcntl)
1215 return -SOS_ENOSYS; 1224 return -SOS_ENOSYS;
1216 1225
1217 return of->ops_file->fcntl(of, req_id, req_ 1226 return of->ops_file->fcntl(of, req_id, req_arg);
1218 } 1227 }
1219 1228
1220 1229
1221 sos_ret_t sos_fs_ioctl(struct sos_fs_opened_f 1230 sos_ret_t sos_fs_ioctl(struct sos_fs_opened_file *of,
1222 int req_id, 1231 int req_id,
1223 sos_ui32_t req_arg 1232 sos_ui32_t req_arg )
1224 { 1233 {
1225 struct sos_fs_node * fsnode = sos_fs_nscach 1234 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1226 1235
1227 if (fsnode->type == SOS_FS_NODE_DEVICE_CHAR 1236 if (fsnode->type == SOS_FS_NODE_DEVICE_CHAR)
1228 { 1237 {
1229 if (! of->ops_chardev->ioctl) 1238 if (! of->ops_chardev->ioctl)
1230 return -SOS_ENOSYS; 1239 return -SOS_ENOSYS;
1231 1240
1232 return of->ops_chardev->ioctl(of, req_i 1241 return of->ops_chardev->ioctl(of, req_id, req_arg);
1233 } 1242 }
>> 1243 else if (fsnode->type == SOS_FS_NODE_DEVICE_BLOCK)
>> 1244 {
>> 1245 if (! of->ops_blockdev->ioctl)
>> 1246 return -SOS_ENOSYS;
>> 1247
>> 1248 return of->ops_blockdev->ioctl(of, req_id, req_arg);
>> 1249 }
1234 1250
1235 return -SOS_ENOSYS; 1251 return -SOS_ENOSYS;
1236 } 1252 }
1237 1253
1238 1254
1239 sos_ret_t sos_fs_readdir(struct sos_fs_opened 1255 sos_ret_t sos_fs_readdir(struct sos_fs_opened_file * of,
1240 struct sos_fs_dirent 1256 struct sos_fs_dirent * result)
1241 { 1257 {
1242 struct sos_fs_node * fsnode = sos_fs_nscach 1258 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1243 1259
1244 if (fsnode->type != SOS_FS_NODE_DIRECTORY) 1260 if (fsnode->type != SOS_FS_NODE_DIRECTORY)
1245 return -SOS_ENOTDIR; 1261 return -SOS_ENOTDIR;
1246 1262
1247 return of->ops_dir->readdir(of, result); 1263 return of->ops_dir->readdir(of, result);
1248 } 1264 }
1249 1265
1250 1266
1251 sos_ret_t sos_fs_creat(const struct sos_proce 1267 sos_ret_t sos_fs_creat(const struct sos_process * creator,
1252 const char * _path, 1268 const char * _path,
1253 sos_size_t _pathlen, 1269 sos_size_t _pathlen,
1254 sos_ui32_t access_righ 1270 sos_ui32_t access_rights)
1255 { 1271 {
1256 struct sos_fs_pathname path; 1272 struct sos_fs_pathname path;
1257 1273
1258 path.contents = _path; 1274 path.contents = _path;
1259 path.length = _pathlen; 1275 path.length = _pathlen;
1260 1276
1261 return fs_create_node(& path, creator, acce 1277 return fs_create_node(& path, creator, access_rights,
1262 SOS_FS_NODE_REGULAR_F 1278 SOS_FS_NODE_REGULAR_FILE, NULL);
1263 } 1279 }
1264 1280
1265 1281
1266 sos_ret_t sos_fs_link(const struct sos_proces 1282 sos_ret_t sos_fs_link(const struct sos_process * creator,
1267 const char * _old_path, 1283 const char * _old_path,
1268 sos_size_t _old_pathlen 1284 sos_size_t _old_pathlen,
1269 const char * _new_path, 1285 const char * _new_path,
1270 sos_size_t _new_pathlen 1286 sos_size_t _new_pathlen)
1271 { 1287 {
1272 sos_ret_t retval; 1288 sos_ret_t retval;
1273 struct sos_fs_nscache_node *old_nsnode, *de 1289 struct sos_fs_nscache_node *old_nsnode, *dest_parent_nsnode, *new_nsnode;
1274 struct sos_fs_node * fsnode; 1290 struct sos_fs_node * fsnode;
1275 struct sos_fs_pathname old_path, new_path; 1291 struct sos_fs_pathname old_path, new_path;
1276 1292
1277 if (_old_pathlen <= 0) 1293 if (_old_pathlen <= 0)
1278 return -SOS_ENOENT; 1294 return -SOS_ENOENT;
1279 if (_new_pathlen <= 0) 1295 if (_new_pathlen <= 0)
1280 return -SOS_ENOENT; 1296 return -SOS_ENOENT;
1281 1297
1282 1298
1283 old_path.contents = _old_path; 1299 old_path.contents = _old_path;
1284 old_path.length = _old_pathlen; 1300 old_path.length = _old_pathlen;
1285 1301
1286 if (old_path.contents[0] == '/') 1302 if (old_path.contents[0] == '/')
1287 old_nsnode = sos_process_get_root(creator 1303 old_nsnode = sos_process_get_root(creator)->direntry;
1288 else 1304 else
1289 old_nsnode = sos_process_get_cwd(creator) 1305 old_nsnode = sos_process_get_cwd(creator)->direntry;
1290 1306
1291 retval = fs_lookup_node(& old_path, 1307 retval = fs_lookup_node(& old_path,
1292 FALSE 1308 FALSE ,
1293 sos_process_get_roo 1309 sos_process_get_root(creator)->direntry,
1294 old_nsnode, 1310 old_nsnode,
1295 & old_nsnode, 1311 & old_nsnode,
1296 & old_path, 1312 & old_path,
1297 0); 1313 0);
1298 if (SOS_OK != retval) 1314 if (SOS_OK != retval)
1299 return retval; 1315 return retval;
1300 1316
1301 if (old_path.length > 0) 1317 if (old_path.length > 0)
1302 { 1318 {
1303 1319
1304 sos_fs_nscache_unref_node(old_nsnode); 1320 sos_fs_nscache_unref_node(old_nsnode);
1305 return -SOS_ENOENT; 1321 return -SOS_ENOENT;
1306 } 1322 }
1307 1323
1308 fsnode = sos_fs_nscache_get_fs_node(old_nsn 1324 fsnode = sos_fs_nscache_get_fs_node(old_nsnode);
1309 1325
1310 1326
1311 if (fsnode->type == SOS_FS_NODE_DIRECTORY) 1327 if (fsnode->type == SOS_FS_NODE_DIRECTORY)
1312 { 1328 {
1313 sos_fs_nscache_unref_node(old_nsnode); 1329 sos_fs_nscache_unref_node(old_nsnode);
1314 return -SOS_ENOENT; 1330 return -SOS_ENOENT;
1315 } 1331 }
1316 1332
1317 1333
1318 new_path.contents = _new_path; 1334 new_path.contents = _new_path;
1319 new_path.length = _new_pathlen; 1335 new_path.length = _new_pathlen;
1320 1336
1321 if (new_path.contents[0] == '/') 1337 if (new_path.contents[0] == '/')
1322 dest_parent_nsnode = sos_process_get_root 1338 dest_parent_nsnode = sos_process_get_root(creator)->direntry;
1323 else 1339 else
1324 dest_parent_nsnode = sos_process_get_cwd( 1340 dest_parent_nsnode = sos_process_get_cwd(creator)->direntry;
1325 1341
1326 retval = fs_lookup_node(& new_path, 1342 retval = fs_lookup_node(& new_path,
1327 TRUE 1343 TRUE ,
1328 sos_process_get_roo 1344 sos_process_get_root(creator)->direntry,
1329 dest_parent_nsnode, 1345 dest_parent_nsnode,
1330 & dest_parent_nsnod 1346 & dest_parent_nsnode,
1331 & new_path, 1347 & new_path,
1332 0); 1348 0);
1333 if (SOS_OK != retval) 1349 if (SOS_OK != retval)
1334 { 1350 {
1335 sos_fs_nscache_unref_node(old_nsnode); 1351 sos_fs_nscache_unref_node(old_nsnode);
1336 return retval; 1352 return retval;
1337 } 1353 }
1338 1354
1339 if (new_path.length == 0) 1355 if (new_path.length == 0)
1340 { 1356 {
1341 1357
1342 sos_fs_nscache_unref_node(dest_parent_n 1358 sos_fs_nscache_unref_node(dest_parent_nsnode);
1343 sos_fs_nscache_unref_node(old_nsnode); 1359 sos_fs_nscache_unref_node(old_nsnode);
1344 return -SOS_EEXIST; 1360 return -SOS_EEXIST;
1345 } 1361 }
1346 1362
1347 1363
1348 retval = fs_register_child_node(creator, de 1364 retval = fs_register_child_node(creator, dest_parent_nsnode, & new_path,
1349 fsnode, 0, 1365 fsnode, 0,
1350 & new_nsnod 1366 & new_nsnode);
1351 1367
1352 sos_fs_nscache_unref_node(dest_parent_nsnod 1368 sos_fs_nscache_unref_node(dest_parent_nsnode);
1353 sos_fs_nscache_unref_node(old_nsnode); 1369 sos_fs_nscache_unref_node(old_nsnode);
1354 sos_fs_nscache_unref_node(new_nsnode); 1370 sos_fs_nscache_unref_node(new_nsnode);
1355 return retval; 1371 return retval;
1356 } 1372 }
1357 1373
1358 1374
1359 sos_ret_t sos_fs_rename(const struct sos_proc 1375 sos_ret_t sos_fs_rename(const struct sos_process * actor,
1360 const char * _old_pat 1376 const char * _old_path,
1361 sos_size_t _old_pathl 1377 sos_size_t _old_pathlen,
1362 const char * _new_pat 1378 const char * _new_path,
1363 sos_size_t _new_pathl 1379 sos_size_t _new_pathlen)
1364 { 1380 {
1365 sos_ret_t retval; 1381 sos_ret_t retval;
1366 struct sos_fs_nscache_node *old_nsnode, *ol 1382 struct sos_fs_nscache_node *old_nsnode, *old_parent_nsnode,
1367 *dest_parent_nsnode, *replaced_nsnode; 1383 *dest_parent_nsnode, *replaced_nsnode;
1368 struct sos_fs_pathname old_name, replaced_n 1384 struct sos_fs_pathname old_name, replaced_name;
1369 struct sos_fs_pathname old_path, new_path; 1385 struct sos_fs_pathname old_path, new_path;
1370 1386
1371 old_nsnode = old_parent_nsnode = dest_paren 1387 old_nsnode = old_parent_nsnode = dest_parent_nsnode = replaced_nsnode = NULL;
1372 1388
1373 if (_old_pathlen <= 0) 1389 if (_old_pathlen <= 0)
1374 return -SOS_ENOENT; 1390 return -SOS_ENOENT;
1375 if (_new_pathlen <= 0) 1391 if (_new_pathlen <= 0)
1376 return -SOS_ENOENT; 1392 return -SOS_ENOENT;
1377 1393
1378 1394
1379 old_path.contents = _old_path; 1395 old_path.contents = _old_path;
1380 old_path.length = _old_pathlen; 1396 old_path.length = _old_pathlen;
1381 1397
1382 if (old_path.contents[0] == '/') 1398 if (old_path.contents[0] == '/')
1383 old_nsnode = sos_process_get_root(actor)- 1399 old_nsnode = sos_process_get_root(actor)->direntry;
1384 else 1400 else
1385 old_nsnode = sos_process_get_cwd(actor)-> 1401 old_nsnode = sos_process_get_cwd(actor)->direntry;
1386 1402
1387 retval = fs_lookup_node(& old_path, 1403 retval = fs_lookup_node(& old_path,
1388 FALSE 1404 FALSE ,
1389 sos_process_get_roo 1405 sos_process_get_root(actor)->direntry,
1390 old_nsnode, 1406 old_nsnode,
1391 & old_nsnode, 1407 & old_nsnode,
1392 & old_path, 1408 & old_path,
1393 0); 1409 0);
1394 if (SOS_OK != retval) 1410 if (SOS_OK != retval)
1395 return retval; 1411 return retval;
1396 1412
1397 if (old_path.length > 0) 1413 if (old_path.length > 0)
1398 { 1414 {
1399 1415
1400 sos_fs_nscache_unref_node(old_nsnode); 1416 sos_fs_nscache_unref_node(old_nsnode);
1401 return -SOS_ENOENT; 1417 return -SOS_ENOENT;
1402 } 1418 }
1403 1419
1404 1420
1405 if (sos_fs_nscache_is_mountnode(old_nsnode) 1421 if (sos_fs_nscache_is_mountnode(old_nsnode))
1406 { 1422 {
1407 sos_fs_nscache_unref_node(old_nsnode); 1423 sos_fs_nscache_unref_node(old_nsnode);
1408 return -SOS_ENOENT; 1424 return -SOS_ENOENT;
1409 } 1425 }
1410 1426
1411 1427
1412 1428
1413 retval = sos_fs_nscache_get_parent(old_nsno 1429 retval = sos_fs_nscache_get_parent(old_nsnode, & old_parent_nsnode);
1414 if (SOS_OK != retval) 1430 if (SOS_OK != retval)
1415 { 1431 {
1416 sos_fs_nscache_unref_node(old_nsnode); 1432 sos_fs_nscache_unref_node(old_nsnode);
1417 return retval; 1433 return retval;
1418 } 1434 }
1419 sos_fs_nscache_ref_node(old_parent_nsnode); 1435 sos_fs_nscache_ref_node(old_parent_nsnode);
1420 1436
1421 1437
1422 replaced_nsnode = NULL; 1438 replaced_nsnode = NULL;
1423 new_path.contents = _new_path; 1439 new_path.contents = _new_path;
1424 new_path.length = _new_pathlen; 1440 new_path.length = _new_pathlen;
1425 1441
1426 if (new_path.contents[0] == '/') 1442 if (new_path.contents[0] == '/')
1427 dest_parent_nsnode = sos_process_get_root 1443 dest_parent_nsnode = sos_process_get_root(actor)->direntry;
1428 else 1444 else
1429 dest_parent_nsnode = sos_process_get_cwd( 1445 dest_parent_nsnode = sos_process_get_cwd(actor)->direntry;
1430 1446
1431 retval = fs_lookup_node(& new_path, 1447 retval = fs_lookup_node(& new_path,
1432 TRUE 1448 TRUE ,
1433 sos_process_get_roo 1449 sos_process_get_root(actor)->direntry,
1434 dest_parent_nsnode, 1450 dest_parent_nsnode,
1435 & dest_parent_nsnod 1451 & dest_parent_nsnode,
1436 & new_path, 1452 & new_path,
1437 0); 1453 0);
1438 if (SOS_OK != retval) 1454 if (SOS_OK != retval)
1439 { 1455 {
1440 goto undo_rename; 1456 goto undo_rename;
1441 } 1457 }
1442 1458
1443 1459
1444 if (old_nsnode == dest_parent_nsnode) 1460 if (old_nsnode == dest_parent_nsnode)
1445 { 1461 {
1446 sos_fs_nscache_unref_node(old_nsnode); 1462 sos_fs_nscache_unref_node(old_nsnode);
1447 sos_fs_nscache_unref_node(old_parent_ns 1463 sos_fs_nscache_unref_node(old_parent_nsnode);
1448 sos_fs_nscache_unref_node(dest_parent_n 1464 sos_fs_nscache_unref_node(dest_parent_nsnode);
1449 return SOS_OK; 1465 return SOS_OK;
1450 } 1466 }
1451 1467
1452 1468
1453 sos_fs_nscache_get_name(old_nsnode, & old_n 1469 sos_fs_nscache_get_name(old_nsnode, & old_name);
1454 retval = fs_remove_node(actor, old_nsnode); 1470 retval = fs_remove_node(actor, old_nsnode);
1455 if (SOS_OK != retval) 1471 if (SOS_OK != retval)
1456 { 1472 {
1457 sos_fs_nscache_unref_node(old_nsnode); 1473 sos_fs_nscache_unref_node(old_nsnode);
1458 sos_fs_nscache_unref_node(old_parent_ns 1474 sos_fs_nscache_unref_node(old_parent_nsnode);
1459 sos_fs_nscache_unref_node(dest_parent_n 1475 sos_fs_nscache_unref_node(dest_parent_nsnode);
1460 return -SOS_ENOENT; 1476 return -SOS_ENOENT;
1461 } 1477 }
1462 1478
1463 if (new_path.length == 0) 1479 if (new_path.length == 0)
1464 { 1480 {
1465 1481
1466 1482
1467 1483
1468 1484
1469 if (sos_fs_nscache_get_fs_node(dest_par 1485 if (sos_fs_nscache_get_fs_node(dest_parent_nsnode)->type
1470 == SOS_FS_NODE_DIRECTORY) 1486 == SOS_FS_NODE_DIRECTORY)
1471 { 1487 {
1472 retval = -SOS_EBUSY; 1488 retval = -SOS_EBUSY;
1473 goto undo_rename; 1489 goto undo_rename;
1474 } 1490 }
1475 1491
1476 replaced_nsnode = dest_parent_nsnode; 1492 replaced_nsnode = dest_parent_nsnode;
1477 dest_parent_nsnode = NULL; 1493 dest_parent_nsnode = NULL;
1478 1494
1479 1495
1480 retval = sos_fs_nscache_get_parent(repl 1496 retval = sos_fs_nscache_get_parent(replaced_nsnode,
1481 & de 1497 & dest_parent_nsnode);
1482 if (SOS_OK != retval) 1498 if (SOS_OK != retval)
1483 { 1499 {
1484 dest_parent_nsnode = replaced_nsnod 1500 dest_parent_nsnode = replaced_nsnode;
1485 goto undo_rename; 1501 goto undo_rename;
1486 } 1502 }
1487 1503
1488 sos_fs_nscache_ref_node(dest_parent_nsn 1504 sos_fs_nscache_ref_node(dest_parent_nsnode);
1489 1505
1490 1506
1491 sos_fs_nscache_get_name(replaced_nsnode 1507 sos_fs_nscache_get_name(replaced_nsnode, & replaced_name);
1492 retval = fs_remove_node(actor, replaced 1508 retval = fs_remove_node(actor, replaced_nsnode);
1493 if (SOS_OK != retval) 1509 if (SOS_OK != retval)
1494 goto undo_rename; 1510 goto undo_rename;
1495 } 1511 }
1496 1512
1497 1513
1498 retval = fs_connect_existing_child_node(act 1514 retval = fs_connect_existing_child_node(actor, dest_parent_nsnode,
1499 & n 1515 & new_path,
1500 old 1516 old_nsnode);
1501 if (SOS_OK != retval) 1517 if (SOS_OK != retval)
1502 goto undo_rename; 1518 goto undo_rename;
1503 1519
1504 sos_fs_nscache_unref_node(old_nsnode); 1520 sos_fs_nscache_unref_node(old_nsnode);
1505 sos_fs_nscache_unref_node(old_parent_nsnode 1521 sos_fs_nscache_unref_node(old_parent_nsnode);
1506 sos_fs_nscache_unref_node(dest_parent_nsnod 1522 sos_fs_nscache_unref_node(dest_parent_nsnode);
1507 if (NULL != replaced_nsnode) 1523 if (NULL != replaced_nsnode)
1508 sos_fs_nscache_unref_node(replaced_nsnode 1524 sos_fs_nscache_unref_node(replaced_nsnode);
1509 1525
1510 return retval; 1526 return retval;
1511 1527
1512 undo_rename: 1528 undo_rename:
1513 1529
1514 1530
1515 1531
1516 1532
1517 if (NULL != replaced_nsnode) 1533 if (NULL != replaced_nsnode)
1518 { 1534 {
1519 fs_connect_existing_child_node(actor, d 1535 fs_connect_existing_child_node(actor, dest_parent_nsnode,
1520 & replac 1536 & replaced_name,
1521 replaced 1537 replaced_nsnode);
1522 sos_fs_nscache_unref_node(replaced_nsno 1538 sos_fs_nscache_unref_node(replaced_nsnode);
1523 } 1539 }
1524 1540
1525 fs_connect_existing_child_node(actor, old_p 1541 fs_connect_existing_child_node(actor, old_parent_nsnode,
1526 & old_name, 1542 & old_name,
1527 old_nsnode); 1543 old_nsnode);
1528 sos_fs_nscache_unref_node(old_nsnode); 1544 sos_fs_nscache_unref_node(old_nsnode);
1529 sos_fs_nscache_unref_node(old_parent_nsnode 1545 sos_fs_nscache_unref_node(old_parent_nsnode);
1530 1546
1531 if (NULL != dest_parent_nsnode) 1547 if (NULL != dest_parent_nsnode)
1532 sos_fs_nscache_unref_node(dest_parent_nsn 1548 sos_fs_nscache_unref_node(dest_parent_nsnode);
1533 1549
1534 return retval; 1550 return retval;
1535 } 1551 }
1536 1552
1537 1553
1538 sos_ret_t sos_fs_unlink(const struct sos_proc 1554 sos_ret_t sos_fs_unlink(const struct sos_process * actor,
1539 const char * _path, 1555 const char * _path,
1540 sos_size_t _pathlen) 1556 sos_size_t _pathlen)
1541 { 1557 {
1542 sos_ret_t retval; 1558 sos_ret_t retval;
1543 struct sos_fs_pathname path; 1559 struct sos_fs_pathname path;
1544 struct sos_fs_nscache_node * nsnode; 1560 struct sos_fs_nscache_node * nsnode;
1545 1561
1546 path.contents = _path; 1562 path.contents = _path;
1547 path.length = _pathlen; 1563 path.length = _pathlen;
1548 1564
1549 if (path.length <= 0) 1565 if (path.length <= 0)
1550 return -SOS_ENOENT; 1566 return -SOS_ENOENT;
1551 1567
1552 if (path.contents[0] == '/') 1568 if (path.contents[0] == '/')
1553 nsnode = sos_process_get_root(actor)->dir 1569 nsnode = sos_process_get_root(actor)->direntry;
1554 else 1570 else
1555 nsnode = sos_process_get_cwd(actor)->dire 1571 nsnode = sos_process_get_cwd(actor)->direntry;
1556 1572
1557 retval = fs_lookup_node(& path, FALSE, 1573 retval = fs_lookup_node(& path, FALSE,
1558 sos_process_get_roo 1574 sos_process_get_root(actor)->direntry,
1559 nsnode, 1575 nsnode,
1560 & nsnode, & path, 0 1576 & nsnode, & path, 0);
1561 if (SOS_OK != retval) 1577 if (SOS_OK != retval)
1562 return retval; 1578 return retval;
1563 1579
1564 1580
1565 if (path.length > 0) 1581 if (path.length > 0)
1566 { 1582 {
1567 sos_fs_nscache_unref_node(nsnode); 1583 sos_fs_nscache_unref_node(nsnode);
1568 return -SOS_ENOENT; 1584 return -SOS_ENOENT;
1569 } 1585 }
1570 1586
1571 if (sos_fs_nscache_get_fs_node(nsnode)->typ 1587 if (sos_fs_nscache_get_fs_node(nsnode)->type == SOS_FS_NODE_DIRECTORY)
1572 retval = -SOS_EISDIR; 1588 retval = -SOS_EISDIR;
1573 else 1589 else
1574 retval = fs_remove_node(actor, nsnode); 1590 retval = fs_remove_node(actor, nsnode);
1575 1591
1576 sos_fs_nscache_unref_node(nsnode); 1592 sos_fs_nscache_unref_node(nsnode);
1577 return retval; 1593 return retval;
1578 } 1594 }
1579 1595
1580 1596
1581 sos_ret_t sos_fs_symlink(const struct sos_pro 1597 sos_ret_t sos_fs_symlink(const struct sos_process * creator,
1582 const char * _path, 1598 const char * _path,
1583 sos_size_t _pathlen, 1599 sos_size_t _pathlen,
1584 sos_uaddr_t symlink_ 1600 sos_uaddr_t symlink_target,
1585 sos_size_t symlink_t 1601 sos_size_t symlink_target_len)
1586 { 1602 {
1587 sos_ret_t retval; 1603 sos_ret_t retval;
1588 struct sos_fs_pathname path; 1604 struct sos_fs_pathname path;
1589 struct sos_fs_node * fsnode; 1605 struct sos_fs_node * fsnode;
1590 struct sos_fs_nscache_node * symlink; 1606 struct sos_fs_nscache_node * symlink;
1591 struct sos_fs_opened_file * tmp_of; 1607 struct sos_fs_opened_file * tmp_of;
1592 sos_size_t len; 1608 sos_size_t len;
1593 1609
1594 path.contents = _path; 1610 path.contents = _path;
1595 path.length = _pathlen; 1611 path.length = _pathlen;
1596 1612
1597 retval = fs_create_node(& path, creator, SO 1613 retval = fs_create_node(& path, creator, SOS_FS_S_IRWXALL,
1598 SOS_FS_NODE_SYMLINK 1614 SOS_FS_NODE_SYMLINK, & symlink);
1599 if (SOS_OK != retval) 1615 if (SOS_OK != retval)
1600 return retval; 1616 return retval;
1601 1617
1602 1618
1603 fsnode = sos_fs_nscache_get_fs_node(symlink 1619 fsnode = sos_fs_nscache_get_fs_node(symlink);
1604 retval = fsnode->new_opened_file(fsnode, cr 1620 retval = fsnode->new_opened_file(fsnode, creator,
1605 SOS_FS_OPE 1621 SOS_FS_OPEN_WRITE, & tmp_of);
1606 if (SOS_OK != retval) 1622 if (SOS_OK != retval)
1607 { 1623 {
1608 fs_remove_node(creator, symlink); 1624 fs_remove_node(creator, symlink);
1609 sos_fs_nscache_unref_node(symlink); 1625 sos_fs_nscache_unref_node(symlink);
1610 return retval; 1626 return retval;
1611 } 1627 }
1612 1628
1613 tmp_of->ref_cnt = 1; 1629 tmp_of->ref_cnt = 1;
1614 retval = sos_fs_nscache_register_opened_fil 1630 retval = sos_fs_nscache_register_opened_file(symlink, tmp_of);
1615 if (SOS_OK != retval) 1631 if (SOS_OK != retval)
1616 { 1632 {
1617 fsnode->close_opened_file(fsnode, tmp_o 1633 fsnode->close_opened_file(fsnode, tmp_of);
1618 fs_remove_node(creator, symlink); 1634 fs_remove_node(creator, symlink);
1619 sos_fs_nscache_unref_node(symlink); 1635 sos_fs_nscache_unref_node(symlink);
1620 return retval; 1636 return retval;
1621 } 1637 }
1622 1638
1623 len = symlink_target_len; 1639 len = symlink_target_len;
1624 retval = sos_fs_write(tmp_of, symlink_targe 1640 retval = sos_fs_write(tmp_of, symlink_target, & len);
1625 mark_dirty_fsnode(fsnode, FALSE); 1641 mark_dirty_fsnode(fsnode, FALSE);
1626 fsnode->close_opened_file(fsnode, tmp_of); 1642 fsnode->close_opened_file(fsnode, tmp_of);
1627 1643
1628 if ((SOS_OK != retval) || (len != symlink_t 1644 if ((SOS_OK != retval) || (len != symlink_target_len))
1629 { 1645 {
1630 fs_remove_node(creator, symlink); 1646 fs_remove_node(creator, symlink);
1631 if (SOS_OK == retval) 1647 if (SOS_OK == retval)
1632 retval = -SOS_ENAMETOOLONG; 1648 retval = -SOS_ENAMETOOLONG;
1633 } 1649 }
1634 1650
1635 sos_fs_nscache_unref_node(symlink); 1651 sos_fs_nscache_unref_node(symlink);
1636 return retval; 1652 return retval;
1637 } 1653 }
1638 1654
1639 1655
1640 sos_ret_t sos_fs_mkdir(const struct sos_proce 1656 sos_ret_t sos_fs_mkdir(const struct sos_process * creator,
1641 const char * _path, 1657 const char * _path,
1642 sos_size_t _pathlen, 1658 sos_size_t _pathlen,
1643 sos_ui32_t access_righ 1659 sos_ui32_t access_rights)
1644 { 1660 {
1645 struct sos_fs_pathname path; 1661 struct sos_fs_pathname path;
1646 1662
1647 path.contents = _path; 1663 path.contents = _path;
1648 path.length = _pathlen; 1664 path.length = _pathlen;
1649 1665
1650 return fs_create_node(& path, creator, acce 1666 return fs_create_node(& path, creator, access_rights,
1651 SOS_FS_NODE_DIRECTORY 1667 SOS_FS_NODE_DIRECTORY, NULL);
1652 } 1668 }
1653 1669
1654 1670
1655 sos_ret_t sos_fs_rmdir(const struct sos_proce 1671 sos_ret_t sos_fs_rmdir(const struct sos_process * actor,
1656 const char * _path, 1672 const char * _path,
1657 sos_size_t _pathlen) 1673 sos_size_t _pathlen)
1658 { 1674 {
1659 sos_ret_t retval; 1675 sos_ret_t retval;
1660 struct sos_fs_pathname path; 1676 struct sos_fs_pathname path;
1661 struct sos_fs_nscache_node * nsnode; 1677 struct sos_fs_nscache_node * nsnode;
1662 1678
1663 path.contents = _path; 1679 path.contents = _path;
1664 path.length = _pathlen; 1680 path.length = _pathlen;
1665 1681
1666 if (path.length <= 0) 1682 if (path.length <= 0)
1667 return -SOS_ENOENT; 1683 return -SOS_ENOENT;
1668 1684
1669 if (path.contents[0] == '/') 1685 if (path.contents[0] == '/')
1670 nsnode = sos_process_get_root(actor)->dir 1686 nsnode = sos_process_get_root(actor)->direntry;
1671 else 1687 else
1672 nsnode = sos_process_get_cwd(actor)->dire 1688 nsnode = sos_process_get_cwd(actor)->direntry;
1673 1689
1674 retval = fs_lookup_node(& path, FALSE, 1690 retval = fs_lookup_node(& path, FALSE,
1675 sos_process_get_roo 1691 sos_process_get_root(actor)->direntry,
1676 nsnode, 1692 nsnode,
1677 & nsnode, & path, 0 1693 & nsnode, & path, 0);
1678 if (SOS_OK != retval) 1694 if (SOS_OK != retval)
1679 return retval; 1695 return retval;
1680 1696
1681 1697
1682 if (path.length > 0) 1698 if (path.length > 0)
1683 { 1699 {
1684 sos_fs_nscache_unref_node(nsnode); 1700 sos_fs_nscache_unref_node(nsnode);
1685 return -SOS_ENOENT; 1701 return -SOS_ENOENT;
1686 } 1702 }
1687 1703
1688 1704
1689 if (sos_fs_nscache_get_fs_node(nsnode)->typ 1705 if (sos_fs_nscache_get_fs_node(nsnode)->type != SOS_FS_NODE_DIRECTORY)
1690 retval = -SOS_ENOTDIR; 1706 retval = -SOS_ENOTDIR;
1691 1707
1692 1708
1693 else if (sos_fs_nscache_get_ref_cnt(nsnode) 1709 else if (sos_fs_nscache_get_ref_cnt(nsnode) > 1)
1694 retval = -SOS_EBUSY; 1710 retval = -SOS_EBUSY;
1695 1711
1696 1712
1697 1713
1698 else if (sos_fs_nscache_get_fs_node(nsnode) 1714 else if (sos_fs_nscache_get_fs_node(nsnode)->ondisk_lnk_cnt > 1)
1699 retval = -SOS_ENOTEMPTY; 1715 retval = -SOS_ENOTEMPTY;
1700 1716
1701 1717
1702 else 1718 else
1703 retval = fs_remove_node(actor, nsnode); 1719 retval = fs_remove_node(actor, nsnode);
1704 1720
1705 sos_fs_nscache_unref_node(nsnode); 1721 sos_fs_nscache_unref_node(nsnode);
1706 return retval; 1722 return retval;
1707 } 1723 }
1708 1724
1709 1725
1710 sos_ret_t sos_fs_mknod(const struct sos_proce 1726 sos_ret_t sos_fs_mknod(const struct sos_process * creator,
1711 const char * _path, 1727 const char * _path,
1712 sos_size_t _pathlen, 1728 sos_size_t _pathlen,
1713 sos_fs_node_type_t typ 1729 sos_fs_node_type_t type ,
1714 sos_ui32_t access_righ 1730 sos_ui32_t access_rights,
1715 const struct sos_fs_de 1731 const struct sos_fs_dev_id_t * devid)
1716 { 1732 {
1717 sos_ret_t retval; 1733 sos_ret_t retval;
1718 struct sos_fs_pathname path; 1734 struct sos_fs_pathname path;
1719 struct sos_fs_nscache_node * nsnode; 1735 struct sos_fs_nscache_node * nsnode;
1720 struct sos_fs_node * fsnode; 1736 struct sos_fs_node * fsnode;
1721 1737
1722 if (type != SOS_FS_NODE_DEVICE_CHAR) !! 1738 if ((type != SOS_FS_NODE_DEVICE_BLOCK)
>> 1739 && (type != SOS_FS_NODE_DEVICE_CHAR))
1723 return -SOS_EINVAL; 1740 return -SOS_EINVAL;
1724 1741
1725 path.contents = _path; 1742 path.contents = _path;
1726 path.length = _pathlen; 1743 path.length = _pathlen;
1727 1744
1728 retval = fs_create_node(& path, creator, ac 1745 retval = fs_create_node(& path, creator, access_rights,
1729 type, & nsnode); 1746 type, & nsnode);
1730 if (SOS_OK != retval) 1747 if (SOS_OK != retval)
1731 return retval; 1748 return retval;
1732 1749
1733 fsnode = sos_fs_nscache_get_fs_node(nsnode) 1750 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1734 fsnode->dev_id.device_class = devid->dev 1751 fsnode->dev_id.device_class = devid->device_class;
1735 fsnode->dev_id.device_instance = devid->dev 1752 fsnode->dev_id.device_instance = devid->device_instance;
1736 1753
1737 sos_fs_nscache_unref_node(nsnode); 1754 sos_fs_nscache_unref_node(nsnode);
1738 return SOS_OK; 1755 return SOS_OK;
1739 } 1756 }
1740 1757
1741 1758
1742 sos_ret_t sos_fs_stat(const struct sos_proces 1759 sos_ret_t sos_fs_stat(const struct sos_process * actor,
1743 const char * _path, 1760 const char * _path,
1744 sos_size_t _pathlen, 1761 sos_size_t _pathlen,
1745 int nofollow, 1762 int nofollow,
1746 struct sos_fs_stat * re 1763 struct sos_fs_stat * result)
1747 { 1764 {
1748 sos_ret_t retval; 1765 sos_ret_t retval;
1749 struct sos_fs_pathname path; 1766 struct sos_fs_pathname path;
1750 struct sos_fs_nscache_node * nsnode; 1767 struct sos_fs_nscache_node * nsnode;
1751 struct sos_fs_node * fsnode; 1768 struct sos_fs_node * fsnode;
1752 1769
1753 path.contents = _path; 1770 path.contents = _path;
1754 path.length = _pathlen; 1771 path.length = _pathlen;
1755 1772
1756 if (path.length <= 0) 1773 if (path.length <= 0)
1757 return -SOS_ENOENT; 1774 return -SOS_ENOENT;
1758 1775
1759 if (path.contents[0] == '/') 1776 if (path.contents[0] == '/')
1760 nsnode = sos_process_get_root(actor)->dir 1777 nsnode = sos_process_get_root(actor)->direntry;
1761 else 1778 else
1762 nsnode = sos_process_get_cwd(actor)->dire 1779 nsnode = sos_process_get_cwd(actor)->direntry;
1763 1780
1764 retval = fs_lookup_node(& path, (nofollow ! 1781 retval = fs_lookup_node(& path, (nofollow != 0),
1765 sos_process_get_roo 1782 sos_process_get_root(actor)->direntry,
1766 nsnode, 1783 nsnode,
1767 & nsnode, & path, 0 1784 & nsnode, & path, 0);
1768 if (SOS_OK != retval) 1785 if (SOS_OK != retval)
1769 return retval; 1786 return retval;
1770 1787
1771 1788
1772 if (path.length > 0) 1789 if (path.length > 0)
1773 { 1790 {
1774 sos_fs_nscache_unref_node(nsnode); 1791 sos_fs_nscache_unref_node(nsnode);
1775 return -SOS_ENOENT; 1792 return -SOS_ENOENT;
1776 } 1793 }
1777 1794
1778 fsnode = sos_fs_nscache_get_fs_node(nsnode) 1795 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1779 retval = fsnode->ops_file->stat(fsnode, res 1796 retval = fsnode->ops_file->stat(fsnode, result);
1780 1797
1781 sos_fs_nscache_unref_node(nsnode); 1798 sos_fs_nscache_unref_node(nsnode);
1782 return retval; 1799 return retval;
1783 } 1800 }
1784 1801
1785 1802
1786 sos_ret_t sos_fs_fsync(struct sos_fs_opened_f 1803 sos_ret_t sos_fs_fsync(struct sos_fs_opened_file * of)
1787 { 1804 {
1788 struct sos_fs_node * fsnode = sos_fs_nscach 1805 struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);
1789 return fsnode->sync(fsnode); !! 1806 return sos_fs_sync_node(fsnode);
1790 } 1807 }
1791 1808
1792 1809
1793 sos_ret_t sos_fs_chmod(const struct sos_proce 1810 sos_ret_t sos_fs_chmod(const struct sos_process * actor,
1794 const char * _path, 1811 const char * _path,
1795 sos_size_t _pathlen, 1812 sos_size_t _pathlen,
1796 sos_ui32_t access_righ 1813 sos_ui32_t access_rights)
1797 { 1814 {
1798 sos_ret_t retval; 1815 sos_ret_t retval;
1799 struct sos_fs_pathname path; 1816 struct sos_fs_pathname path;
1800 struct sos_fs_nscache_node * nsnode; 1817 struct sos_fs_nscache_node * nsnode;
1801 struct sos_fs_node * fsnode; 1818 struct sos_fs_node * fsnode;
1802 1819
1803 path.contents = _path; 1820 path.contents = _path;
1804 path.length = _pathlen; 1821 path.length = _pathlen;
1805 1822
1806 if (path.length <= 0) 1823 if (path.length <= 0)
1807 return -SOS_ENOENT; 1824 return -SOS_ENOENT;
1808 1825
1809 if (path.contents[0] == '/') 1826 if (path.contents[0] == '/')
1810 nsnode = sos_process_get_root(actor)->dir 1827 nsnode = sos_process_get_root(actor)->direntry;
1811 else 1828 else
1812 nsnode = sos_process_get_cwd(actor)->dire 1829 nsnode = sos_process_get_cwd(actor)->direntry;
1813 1830
1814 retval = fs_lookup_node(& path, TRUE, 1831 retval = fs_lookup_node(& path, TRUE,
1815 sos_process_get_roo 1832 sos_process_get_root(actor)->direntry,
1816 nsnode, 1833 nsnode,
1817 & nsnode, & path, 0 1834 & nsnode, & path, 0);
1818 if (SOS_OK != retval) 1835 if (SOS_OK != retval)
1819 return retval; 1836 return retval;
1820 1837
1821 1838
1822 if (path.length > 0) 1839 if (path.length > 0)
1823 { 1840 {
1824 sos_fs_nscache_unref_node(nsnode); 1841 sos_fs_nscache_unref_node(nsnode);
1825 return -SOS_ENOENT; 1842 return -SOS_ENOENT;
1826 } 1843 }
1827 1844
1828 fsnode = sos_fs_nscache_get_fs_node(nsnode) 1845 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1829 retval = fsnode->ops_file->chmod(fsnode, ac 1846 retval = fsnode->ops_file->chmod(fsnode, access_rights);
1830 if (SOS_OK == retval) 1847 if (SOS_OK == retval)
1831 mark_dirty_fsnode(fsnode, FALSE); 1848 mark_dirty_fsnode(fsnode, FALSE);
1832 1849
1833 sos_fs_nscache_unref_node(nsnode); 1850 sos_fs_nscache_unref_node(nsnode);
1834 return retval; 1851 return retval;
1835 } 1852 }
1836 1853
1837 1854
1838 sos_ret_t sos_fs_vfstat(const struct sos_proc 1855 sos_ret_t sos_fs_vfstat(const struct sos_process * actor,
1839 const char * _path, 1856 const char * _path,
1840 sos_size_t _pathlen, 1857 sos_size_t _pathlen,
1841 struct sos_fs_statfs 1858 struct sos_fs_statfs * result)
1842 { 1859 {
1843 sos_ret_t retval; 1860 sos_ret_t retval;
1844 struct sos_fs_pathname path; 1861 struct sos_fs_pathname path;
1845 struct sos_fs_nscache_node * nsnode; 1862 struct sos_fs_nscache_node * nsnode;
1846 struct sos_fs_node * fsnode; 1863 struct sos_fs_node * fsnode;
1847 1864
1848 path.contents = _path; 1865 path.contents = _path;
1849 path.length = _pathlen; 1866 path.length = _pathlen;
1850 1867
1851 if (path.length <= 0) 1868 if (path.length <= 0)
1852 return -SOS_ENOENT; 1869 return -SOS_ENOENT;
1853 1870
1854 if (path.contents[0] == '/') 1871 if (path.contents[0] == '/')
1855 nsnode = sos_process_get_root(actor)->dir 1872 nsnode = sos_process_get_root(actor)->direntry;
1856 else 1873 else
1857 nsnode = sos_process_get_cwd(actor)->dire 1874 nsnode = sos_process_get_cwd(actor)->direntry;
1858 1875
1859 retval = fs_lookup_node(& path, FALSE, 1876 retval = fs_lookup_node(& path, FALSE,
1860 sos_process_get_roo 1877 sos_process_get_root(actor)->direntry,
1861 nsnode, 1878 nsnode,
1862 & nsnode, & path, 0 1879 & nsnode, & path, 0);
1863 if (SOS_OK != retval) 1880 if (SOS_OK != retval)
1864 return retval; 1881 return retval;
1865 1882
1866 1883
1867 if (path.length > 0) 1884 if (path.length > 0)
1868 { 1885 {
1869 sos_fs_nscache_unref_node(nsnode); 1886 sos_fs_nscache_unref_node(nsnode);
1870 return -SOS_ENOENT; 1887 return -SOS_ENOENT;
1871 } 1888 }
1872 1889
1873 fsnode = sos_fs_nscache_get_fs_node(nsnode) 1890 fsnode = sos_fs_nscache_get_fs_node(nsnode);
1874 if (fsnode->fs->statfs) 1891 if (fsnode->fs->statfs)
1875 retval = fsnode->fs->statfs(fsnode->fs, r 1892 retval = fsnode->fs->statfs(fsnode->fs, result);
1876 else 1893 else
1877 retval = -SOS_ENOSYS; 1894 retval = -SOS_ENOSYS;
1878 1895
1879 sos_fs_nscache_unref_node(nsnode); 1896 sos_fs_nscache_unref_node(nsnode);
1880 return retval; 1897 return retval;
1881 } 1898 }
1882 1899
1883 1900
1884 1901
1885 sos_ret_t sos_fs_sync_all_fs() 1902 sos_ret_t sos_fs_sync_all_fs()
1886 { 1903 {
1887 int dummy = 0; 1904 int dummy = 0;
1888 sos_ui64_t uid = 0; 1905 sos_ui64_t uid = 0;
1889 1906
1890 while (1) 1907 while (1)
1891 { 1908 {
1892 1909
1893 struct sos_fs_manager_type * fstype; 1910 struct sos_fs_manager_type * fstype;
1894 int ntype; 1911 int ntype;
1895 list_foreach(fs_list, fstype, ntype) 1912 list_foreach(fs_list, fstype, ntype)
1896 { 1913 {
1897 1914
1898 struct sos_fs_manager_instance * fs 1915 struct sos_fs_manager_instance * fs;
1899 int ninst; 1916 int ninst;
1900 1917
1901 list_foreach(fstype->instances, fs, !! 1918
>> 1919
>> 1920
>> 1921
>> 1922
>> 1923
>> 1924
>> 1925 list_foreach_forward(fstype->instances, fs, ninst)
1902 { 1926 {
1903 if (fs->uid <= uid) 1927 if (fs->uid <= uid)
1904 continue; 1928 continue;
1905 1929
1906 uid = fs->uid; 1930 uid = fs->uid;
1907 sos_fs_sync_fs(fs); 1931 sos_fs_sync_fs(fs);
1908 1932
1909 1933
1910 1934
1911 1935
1912 goto lookup_next_fs; 1936 goto lookup_next_fs;
1913 } 1937 }
1914 } 1938 }
1915 1939
>> 1940
>> 1941 break;
>> 1942
1916 lookup_next_fs: 1943 lookup_next_fs:
1917 1944
1918 dummy ++; 1945 dummy ++;
1919 } 1946 }
1920 1947
1921 return SOS_OK; !! 1948
>> 1949 return sos_blockdev_sync_all_devices();
1922 } 1950 }
1923 1951
1924 1952
1925 1953
1926 1954
1927 1955
1928 1956
1929 1957
1930 1958
1931 sos_ret_t sos_fs_register_fs_instance(struct 1959 sos_ret_t sos_fs_register_fs_instance(struct sos_fs_manager_instance * fs,
1932 struct 1960 struct sos_fs_node * root_fsnode)
1933 { 1961 {
1934 sos_ret_t retval; 1962 sos_ret_t retval;
1935 struct sos_fs_nscache_node * nsnode_root; 1963 struct sos_fs_nscache_node * nsnode_root;
1936 1964
1937 retval = sos_fs_nscache_create_mounted_root 1965 retval = sos_fs_nscache_create_mounted_root(root_fsnode, & nsnode_root);
1938 if (SOS_OK != retval) 1966 if (SOS_OK != retval)
1939 return retval; 1967 return retval;
1940 1968
1941 fs->uid = ++last_fs_instance_uid; 1969 fs->uid = ++last_fs_instance_uid;
1942 fs->root = nsnode_root; 1970 fs->root = nsnode_root;
1943 sos_hash_insert(fs->nodecache, root_fsnode) 1971 sos_hash_insert(fs->nodecache, root_fsnode);
1944 1972
1945 list_add_tail(fs->fs_type->instances, fs); 1973 list_add_tail(fs->fs_type->instances, fs);
1946 return SOS_OK; 1974 return SOS_OK;
1947 } 1975 }
1948 1976
1949 1977
1950 sos_ret_t sos_fs_unregister_fs_instance(struc 1978 sos_ret_t sos_fs_unregister_fs_instance(struct sos_fs_manager_instance * fs)
1951 { 1979 {
1952 fs->uid = 0; 1980 fs->uid = 0;
1953 list_delete(fs->fs_type->instances, fs); 1981 list_delete(fs->fs_type->instances, fs);
1954 return SOS_OK; 1982 return SOS_OK;
1955 } 1983 }
1956 1984
1957 1985
1958 sos_ret_t sos_fs_register_fs_type(struct sos_ 1986 sos_ret_t sos_fs_register_fs_type(struct sos_fs_manager_type * fstype)
1959 { 1987 {
1960 struct sos_fs_manager_type * iterator; 1988 struct sos_fs_manager_type * iterator;
1961 int nbtypes; 1989 int nbtypes;
1962 1990
1963 list_foreach_forward(fs_list, iterator, nbt 1991 list_foreach_forward(fs_list, iterator, nbtypes)
1964 { 1992 {
1965 if (! strncmp(fstype->name, iterator->n 1993 if (! strncmp(fstype->name, iterator->name, SOS_FS_MANAGER_NAME_MAXLEN))
1966 return -SOS_EEXIST; 1994 return -SOS_EEXIST;
1967 } 1995 }
1968 1996
1969 list_add_tail(fs_list, fstype); 1997 list_add_tail(fs_list, fstype);
1970 return SOS_OK; 1998 return SOS_OK;
1971 } 1999 }
1972 2000
1973 2001
1974 sos_ret_t sos_fs_unregister_fs_type(struct so 2002 sos_ret_t sos_fs_unregister_fs_type(struct sos_fs_manager_type * fstype)
1975 { 2003 {
1976 struct sos_fs_manager_type * iterator; 2004 struct sos_fs_manager_type * iterator;
1977 int nbtypes; 2005 int nbtypes;
1978 2006
1979 if (! list_is_empty(fstype->instances)) 2007 if (! list_is_empty(fstype->instances))
1980 return -SOS_EBUSY; 2008 return -SOS_EBUSY;
1981 2009
1982 list_foreach_forward(fs_list, iterator, nbt 2010 list_foreach_forward(fs_list, iterator, nbtypes)
1983 { 2011 {
1984 if (! strncmp(fstype->name, iterator->n 2012 if (! strncmp(fstype->name, iterator->name, SOS_FS_MANAGER_NAME_MAXLEN))
1985 { 2013 {
1986 list_delete(fs_list, fstype); 2014 list_delete(fs_list, fstype);
1987 return SOS_OK; 2015 return SOS_OK;
1988 } 2016 }
1989 } 2017 }
1990 2018
1991 return -SOS_EINVAL; 2019 return -SOS_EINVAL;
1992 } 2020 }
1993 2021
1994 2022
1995 2023
1996 2024
1997 2025
1998 sos_ret_t sos_fs_mount(struct sos_process * a 2026 sos_ret_t sos_fs_mount(struct sos_process * actor,
1999 const char * _src_path 2027 const char * _src_path,
2000 sos_size_t _src_pathle 2028 sos_size_t _src_pathlen,
2001 const char * _dst_path 2029 const char * _dst_path,
2002 sos_size_t _dst_pathle 2030 sos_size_t _dst_pathlen,
2003 const char * fsname, 2031 const char * fsname,
2004 sos_ui32_t mountflags, 2032 sos_ui32_t mountflags,
2005 const char * args, 2033 const char * args,
2006 struct sos_fs_manager_ 2034 struct sos_fs_manager_instance ** result_fs)
2007 { 2035 {
2008 sos_ret_t retval; 2036 sos_ret_t retval;
2009 struct sos_fs_pathname src_path, dst_path; 2037 struct sos_fs_pathname src_path, dst_path;
2010 struct sos_fs_nscache_node * src_nsnode, * 2038 struct sos_fs_nscache_node * src_nsnode, * dst_nsnode;
2011 struct sos_fs_manager_type * fs_type; 2039 struct sos_fs_manager_type * fs_type;
2012 struct sos_fs_manager_instance * new_fs; 2040 struct sos_fs_manager_instance * new_fs;
2013 int nb_fstypes; 2041 int nb_fstypes;
2014 2042
2015 if (_dst_pathlen <= 0) 2043 if (_dst_pathlen <= 0)
2016 return -SOS_ENOENT; 2044 return -SOS_ENOENT;
2017 2045
2018 2046
2019 list_foreach(fs_list, fs_type, nb_fstypes) 2047 list_foreach(fs_list, fs_type, nb_fstypes)
2020 { 2048 {
2021 if (! strcmp(fsname, fs_type->name)) 2049 if (! strcmp(fsname, fs_type->name))
2022 break; 2050 break;
2023 } 2051 }
2024 if (! list_foreach_early_break(fs_list, fs_ 2052 if (! list_foreach_early_break(fs_list, fs_type, nb_fstypes))
2025 return -SOS_ENODEV; 2053 return -SOS_ENODEV;
2026 2054
2027 src_path.contents = _src_path; 2055 src_path.contents = _src_path;
2028 src_path.length = _src_pathlen; 2056 src_path.length = _src_pathlen;
2029 2057
2030 2058
2031 if (src_path.length <= 0) 2059 if (src_path.length <= 0)
2032 src_nsnode = NULL; 2060 src_nsnode = NULL;
2033 else if (src_path.contents[0] == '/') 2061 else if (src_path.contents[0] == '/')
2034 src_nsnode = sos_process_get_root(actor)- 2062 src_nsnode = sos_process_get_root(actor)->direntry;
2035 else 2063 else
2036 src_nsnode = sos_process_get_cwd(actor)-> 2064 src_nsnode = sos_process_get_cwd(actor)->direntry;
2037 2065
2038 2066
2039 if (src_nsnode) 2067 if (src_nsnode)
2040 { 2068 {
2041 retval = fs_lookup_node(& src_path, TRU 2069 retval = fs_lookup_node(& src_path, TRUE,
2042 sos_process_get 2070 sos_process_get_root(actor)->direntry,
2043 src_nsnode, 2071 src_nsnode,
2044 & src_nsnode, & 2072 & src_nsnode, & src_path, 0);
2045 if (SOS_OK != retval) 2073 if (SOS_OK != retval)
2046 return retval; 2074 return retval;
2047 2075
2048 2076
2049 if (src_path.length > 0) 2077 if (src_path.length > 0)
2050 { 2078 {
2051 sos_fs_nscache_unref_node(src_nsnod 2079 sos_fs_nscache_unref_node(src_nsnode);
2052 return -SOS_ENOENT; 2080 return -SOS_ENOENT;
2053 } 2081 }
2054 } 2082 }
2055 2083
2056 dst_path.contents = _dst_path; 2084 dst_path.contents = _dst_path;
2057 dst_path.length = _dst_pathlen; 2085 dst_path.length = _dst_pathlen;
2058 2086
2059 2087
2060 if (dst_path.contents[0] == '/') 2088 if (dst_path.contents[0] == '/')
2061 dst_nsnode = sos_process_get_root(actor)- 2089 dst_nsnode = sos_process_get_root(actor)->direntry;
2062 else 2090 else
2063 dst_nsnode = sos_process_get_cwd(actor)-> 2091 dst_nsnode = sos_process_get_cwd(actor)->direntry;
2064 2092
2065 2093
2066 retval = fs_lookup_node(& dst_path, TRUE, 2094 retval = fs_lookup_node(& dst_path, TRUE,
2067 sos_process_get_roo 2095 sos_process_get_root(actor)->direntry,
2068 dst_nsnode, 2096 dst_nsnode,
2069 & dst_nsnode, & dst 2097 & dst_nsnode, & dst_path, 0);
2070 if ((SOS_OK != retval) || (dst_path.length 2098 if ((SOS_OK != retval) || (dst_path.length > 0))
2071 { 2099 {
2072 if (src_nsnode) 2100 if (src_nsnode)
2073 sos_fs_nscache_unref_node(src_nsnode) 2101 sos_fs_nscache_unref_node(src_nsnode);
2074 if (dst_path.length > 0) 2102 if (dst_path.length > 0)
2075 retval = -SOS_ENOENT; 2103 retval = -SOS_ENOENT;
2076 return retval; 2104 return retval;
2077 } 2105 }
2078 2106
2079 2107
2080 retval 2108 retval
2081 = fs_type->mount(fs_type, 2109 = fs_type->mount(fs_type,
2082 (src_nsnode)?sos_fs_nsca 2110 (src_nsnode)?sos_fs_nscache_get_fs_node(src_nsnode):NULL,
2083 args, & new_fs); 2111 args, & new_fs);
2084 if (SOS_OK != retval) 2112 if (SOS_OK != retval)
2085 { 2113 {
2086 if (src_nsnode) 2114 if (src_nsnode)
2087 sos_fs_nscache_unref_node(src_nsnode) 2115 sos_fs_nscache_unref_node(src_nsnode);
2088 sos_fs_nscache_unref_node(dst_nsnode); 2116 sos_fs_nscache_unref_node(dst_nsnode);
2089 return retval; 2117 return retval;
2090 } 2118 }
2091 2119
2092 2120
2093 SOS_ASSERT_FATAL(NULL != new_fs->nodecache) 2121 SOS_ASSERT_FATAL(NULL != new_fs->nodecache);
2094 SOS_ASSERT_FATAL(NULL != new_fs->root); 2122 SOS_ASSERT_FATAL(NULL != new_fs->root);
2095 2123
2096 2124
2097 sos_fs_nscache_get_fs_node(new_fs->root)->f 2125 sos_fs_nscache_get_fs_node(new_fs->root)->fs = new_fs;
2098 2126
2099 2127
2100 retval = sos_fs_nscache_mount(dst_nsnode, n 2128 retval = sos_fs_nscache_mount(dst_nsnode, new_fs->root);
2101 SOS_ASSERT_FATAL(SOS_OK == retval); 2129 SOS_ASSERT_FATAL(SOS_OK == retval);
2102 2130
2103 2131
2104 if (src_nsnode) 2132 if (src_nsnode)
2105 sos_fs_nscache_unref_node(src_nsnode); 2133 sos_fs_nscache_unref_node(src_nsnode);
2106 sos_fs_nscache_unref_node(dst_nsnode); 2134 sos_fs_nscache_unref_node(dst_nsnode);
2107 2135
2108 if (result_fs) 2136 if (result_fs)
2109 *result_fs = new_fs; 2137 *result_fs = new_fs;
2110 2138
2111 return SOS_OK; 2139 return SOS_OK;
2112 } 2140 }
2113 2141
2114 2142
2115 sos_ret_t sos_fs_umount(struct sos_process * 2143 sos_ret_t sos_fs_umount(struct sos_process * actor,
2116 const char * _mounted 2144 const char * _mounted_root_path,
2117 sos_size_t _mounted_r 2145 sos_size_t _mounted_root_pathlen)
2118 { 2146 {
2119 sos_ret_t retval; 2147 sos_ret_t retval;
2120 struct sos_fs_pathname mounted_root_path; 2148 struct sos_fs_pathname mounted_root_path;
2121 struct sos_fs_nscache_node * mounted_root_n 2149 struct sos_fs_nscache_node * mounted_root_nsnode;
2122 struct sos_fs_manager_instance * fs; 2150 struct sos_fs_manager_instance * fs;
2123 2151
2124 if (_mounted_root_pathlen <= 0) 2152 if (_mounted_root_pathlen <= 0)
2125 return -SOS_ENOENT; 2153 return -SOS_ENOENT;
2126 2154
2127 mounted_root_path.contents = _mounted_root_ 2155 mounted_root_path.contents = _mounted_root_path;
2128 mounted_root_path.length = _mounted_root_ 2156 mounted_root_path.length = _mounted_root_pathlen;
2129 2157
2130 2158
2131 if (mounted_root_path.contents[0] == '/') 2159 if (mounted_root_path.contents[0] == '/')
2132 mounted_root_nsnode = sos_process_get_roo 2160 mounted_root_nsnode = sos_process_get_root(actor)->direntry;
2133 else 2161 else
2134 mounted_root_nsnode = sos_process_get_cwd 2162 mounted_root_nsnode = sos_process_get_cwd(actor)->direntry;
2135 2163
2136 2164
2137 retval = fs_lookup_node(& mounted_root_path 2165 retval = fs_lookup_node(& mounted_root_path, TRUE,
2138 sos_process_get_roo 2166 sos_process_get_root(actor)->direntry,
2139 mounted_root_nsnode 2167 mounted_root_nsnode,
2140 & mounted_root_nsno 2168 & mounted_root_nsnode, & mounted_root_path, 0);
2141 if (SOS_OK != retval) 2169 if (SOS_OK != retval)
2142 return retval; 2170 return retval;
2143 2171
2144 2172
2145 if (mounted_root_path.length > 0) 2173 if (mounted_root_path.length > 0)
2146 { 2174 {
2147 sos_fs_nscache_unref_node(mounted_root_ 2175 sos_fs_nscache_unref_node(mounted_root_nsnode);
2148 return -SOS_ENOENT; 2176 return -SOS_ENOENT;
2149 } 2177 }
2150 2178
2151 2179
2152 fs = sos_fs_nscache_get_fs_node(mounted_roo 2180 fs = sos_fs_nscache_get_fs_node(mounted_root_nsnode)->fs;
2153 if (fs->root != mounted_root_nsnode) 2181 if (fs->root != mounted_root_nsnode)
2154 { 2182 {
2155 sos_fs_nscache_unref_node(mounted_root_ 2183 sos_fs_nscache_unref_node(mounted_root_nsnode);
2156 return -SOS_ENOENT; 2184 return -SOS_ENOENT;
2157 } 2185 }
2158 2186
2159 2187
2160 retval = sos_fs_nscache_umount(mounted_root 2188 retval = sos_fs_nscache_umount(mounted_root_nsnode);
2161 2189
2162 2190
2163 sos_fs_nscache_unref_node(mounted_root_nsno 2191 sos_fs_nscache_unref_node(mounted_root_nsnode);
2164 if (SOS_OK != retval) 2192 if (SOS_OK != retval)
2165 return retval; 2193 return retval;
2166 2194
2167 fs->root = NULL; 2195 fs->root = NULL;
2168 2196
2169 2197
2170 retval = sos_fs_sync_fs(fs); 2198 retval = sos_fs_sync_fs(fs);
2171 if (SOS_OK != retval) 2199 if (SOS_OK != retval)
2172 { 2200 {
2173 return retval; 2201 return retval;
2174 } 2202 }
2175 2203
2176 retval = fs->fs_type->umount(fs->fs_type, f 2204 retval = fs->fs_type->umount(fs->fs_type, fs);
2177 return retval; 2205 return retval;
2178 } 2206 }