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