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