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