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