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