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 #include <sos/kmalloc.h> 019 #include <sos/kmalloc.h>
020 #include <sos/klibc.h> 020 #include <sos/klibc.h>
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/list.h> 022 #include <sos/list.h>
023 #include <sos/ksynch.h> 023 #include <sos/ksynch.h>
024 #include <sos/uaccess.h> 024 #include <sos/uaccess.h>
025 #include <sos/physmem.h> 025 #include <sos/physmem.h>
026 026
027 #include <sos/fs.h> 027 #include <sos/fs.h>
028 #include <sos/fs_nscache.h> 028 #include <sos/fs_nscache.h>
029 029
030 #include "fs_virtfs.h" 030 #include "fs_virtfs.h"
031 031
032 032
033 033
034 034
035 035
036 036
037 037
038 038
039 039
040 040
041 041
042 042
043 043
044 044
045 045
046 046
047 047
048 048
049 049
050 050
051 051
052 052
053 053
054 054
055 struct virtfs_direntry 055 struct virtfs_direntry
056 { 056 {
057 char * name; 057 char * name;
058 struct sos_fs_node * fsnode; 058 struct sos_fs_node * fsnode;
059 059
060 060
061 061
062 062
063 063
064 064
065 065
066 sos_lcount_t creation_order; 066 sos_lcount_t creation_order;
067 067
068 struct virtfs_direntry * sibling_prev, * sib 068 struct virtfs_direntry * sibling_prev, * sibling_next;
069 }; 069 };
070 070
071 071
072 072
073 073
074 074
075 075
076 076
077 077
078 078
079 079
080 080
081 081
082 082
083 struct virtfs_node 083 struct virtfs_node
084 { 084 {
085 085
086 struct sos_fs_node super; 086 struct sos_fs_node super;
087 087
088 union 088 union
089 { 089 {
090 090
091 struct 091 struct
092 { 092 {
093 093
094 sos_size_t size; 094 sos_size_t size;
095 void * data; 095 void * data;
096 096
097 097
098 struct sos_umem_vmm_mapped_resource mapr 098 struct sos_umem_vmm_mapped_resource mapres;
099 sos_count_t num_mappings; 099 sos_count_t num_mappings;
100 !! 100
101 !! 101
102 !! 102
>> 103
>> 104
>> 105
103 } file; 106 } file;
104 107
105 108
106 struct 109 struct
107 { 110 {
108 111
109 112
110 113
111 struct virtfs_direntry * list_entries; 114 struct virtfs_direntry * list_entries;
112 115
113 116
114 117
115 sos_lcount_t top_creation_order; 118 sos_lcount_t top_creation_order;
116 } dir; 119 } dir;
117 }; 120 };
118 121
119 122
120 struct virtfs_node * prev, * next; 123 struct virtfs_node * prev, * next;
121 }; 124 };
122 125
123 126
124 127
125 128
126 129
127 130
128 131
129 132
130 133
131 134
132 135
133 struct virtfs_instance 136 struct virtfs_instance
134 { 137 {
135 138
136 struct sos_fs_manager_instance super; 139 struct sos_fs_manager_instance super;
137 140
138 141
139 142
140 struct sos_kmutex lock; 143 struct sos_kmutex lock;
141 144
142 145
143 struct virtfs_node * list_fsnodes; 146 struct virtfs_node * list_fsnodes;
144 }; 147 };
145 148
146 149
147 150
148 static struct sos_fs_manager_type virtfs_type; 151 static struct sos_fs_manager_type virtfs_type;
149 152
150 153
151 154
152 static sos_ret_t virtfs_mount(struct sos_fs_ma 155 static sos_ret_t virtfs_mount(struct sos_fs_manager_type * this,
153 struct sos_fs_no 156 struct sos_fs_node * device,
154 const char * arg 157 const char * args,
155 struct sos_fs_ma 158 struct sos_fs_manager_instance ** mounted_fs);
156 159
157 160
158 static sos_ret_t virtfs_umount(struct sos_fs_m 161 static sos_ret_t virtfs_umount(struct sos_fs_manager_type * this,
159 struct sos_fs_m 162 struct sos_fs_manager_instance * mounted_fs);
160 163
161 164
162 static sos_ret_t virtfs_new_mapping(struct sos 165 static sos_ret_t virtfs_new_mapping(struct sos_umem_vmm_vr *vr);
163 166
164 167
165 sos_ret_t sos_fs_virtfs_subsystem_setup() 168 sos_ret_t sos_fs_virtfs_subsystem_setup()
166 { 169 {
167 strzcpy(virtfs_type.name, "virtfs", SOS_FS_M 170 strzcpy(virtfs_type.name, "virtfs", SOS_FS_MANAGER_NAME_MAXLEN);
168 virtfs_type.mount = virtfs_mount; 171 virtfs_type.mount = virtfs_mount;
169 virtfs_type.umount = virtfs_umount; 172 virtfs_type.umount = virtfs_umount;
170 173
171 return sos_fs_register_fs_type(& virtfs_type 174 return sos_fs_register_fs_type(& virtfs_type);
172 } 175 }
173 176
174 177
175 178
176 179
177 180
178 181
179 182
180 183
181 inline static void virtfs_lock(struct virtfs_n 184 inline static void virtfs_lock(struct virtfs_node *a_node)
182 { 185 {
183 struct virtfs_instance * fs = (struct virtfs 186 struct virtfs_instance * fs = (struct virtfs_instance*)a_node->super.fs->custom_data;
184 sos_kmutex_lock(& fs->lock, NULL); 187 sos_kmutex_lock(& fs->lock, NULL);
185 } 188 }
186 189
187 190
188 191
189 inline static void virtfs_unlock(struct virtfs 192 inline static void virtfs_unlock(struct virtfs_node *a_node)
190 { 193 {
191 struct virtfs_instance * fs = (struct virtfs 194 struct virtfs_instance * fs = (struct virtfs_instance*)a_node->super.fs->custom_data;
192 sos_kmutex_unlock(& fs->lock); 195 sos_kmutex_unlock(& fs->lock);
193 } 196 }
194 197
195 198
196 199
197 200
198 static sos_ret_t virtfs_resize(struct virtfs_n 201 static sos_ret_t virtfs_resize(struct virtfs_node *this,
199 sos_size_t new_ 202 sos_size_t new_size)
200 { 203 {
201 void * new_data = NULL; 204 void * new_data = NULL;
202 205
203 if (this->file.size == new_size) 206 if (this->file.size == new_size)
204 return SOS_OK; 207 return SOS_OK;
205 208
206 209
207 if (this->file.num_mappings > 0) 210 if (this->file.num_mappings > 0)
208 return -SOS_EBUSY; 211 return -SOS_EBUSY;
209 212
210 if (new_size > 0) 213 if (new_size > 0)
211 { 214 {
212 215
213 216
214 sos_ui32_t npages = SOS_PAGE_ALIGN_SUP(n 217 sos_ui32_t npages = SOS_PAGE_ALIGN_SUP(new_size) / SOS_PAGE_SIZE;
215 new_data = (void*)sos_kmem_vmm_alloc(npa 218 new_data = (void*)sos_kmem_vmm_alloc(npages,
216 SOS 219 SOS_KMEM_VMM_MAP);
217 if (! new_data) 220 if (! new_data)
218 return -SOS_OK; 221 return -SOS_OK;
219 } 222 }
220 223
221 224
222 if (this->file.size < new_size) 225 if (this->file.size < new_size)
223 { 226 {
224 if (this->file.size > 0) 227 if (this->file.size > 0)
225 memcpy(new_data, this->file.data, this 228 memcpy(new_data, this->file.data, this->file.size);
226 if (new_size > this->file.size) 229 if (new_size > this->file.size)
227 memset(new_data + this->file.size, 0x0 230 memset(new_data + this->file.size, 0x0,
228 new_size - this->file.size); 231 new_size - this->file.size);
229 } 232 }
230 else if (new_size > 0) 233 else if (new_size > 0)
231 memcpy(new_data, this->file.data, new_size 234 memcpy(new_data, this->file.data, new_size);
232 235
233 if (this->file.data) 236 if (this->file.data)
234 sos_kfree((sos_vaddr_t)this->file.data); 237 sos_kfree((sos_vaddr_t)this->file.data);
235 this->file.data = new_data; 238 this->file.data = new_data;
236 this->file.size = new_size; 239 this->file.size = new_size;
237 240
238 return SOS_OK; 241 return SOS_OK;
239 } 242 }
240 243
241 244
242 245
243 246
244 247
245 248
246 249
247 static sos_ret_t 250 static sos_ret_t
248 virtfs_duplicate_opened_file(struct sos_fs_ope 251 virtfs_duplicate_opened_file(struct sos_fs_opened_file *this,
249 const struct sos_ 252 const struct sos_process * for_owner,
250 struct sos_fs_ope 253 struct sos_fs_opened_file **result)
251 { 254 {
252 *result = (struct sos_fs_opened_file*) 255 *result = (struct sos_fs_opened_file*)
253 sos_kmalloc(sizeof(struct sos_fs_opened_fi 256 sos_kmalloc(sizeof(struct sos_fs_opened_file), 0);
254 if (! *result) 257 if (! *result)
255 return -SOS_ENOMEM; 258 return -SOS_ENOMEM;
256 259
257 memcpy(*result, this, sizeof(*this)); 260 memcpy(*result, this, sizeof(*this));
258 (*result)->owner = for_owner; 261 (*result)->owner = for_owner;
259 return SOS_OK; 262 return SOS_OK;
260 } 263 }
261 264
262 265
263 static sos_ret_t 266 static sos_ret_t
264 virtfs_seek(struct sos_fs_opened_file *this, 267 virtfs_seek(struct sos_fs_opened_file *this,
265 sos_lsoffset_t offset, 268 sos_lsoffset_t offset,
266 sos_seek_whence_t whence, 269 sos_seek_whence_t whence,
267 sos_lsoffset_t * result_ 270 sos_lsoffset_t * result_position)
268 { 271 {
269 sos_lsoffset_t ref_offs; 272 sos_lsoffset_t ref_offs;
270 struct virtfs_node * virtfsnode; 273 struct virtfs_node * virtfsnode;
271 274
272 virtfsnode = (struct virtfs_node*) 275 virtfsnode = (struct virtfs_node*)
273 sos_fs_nscache_get_fs_node(this->direntry) 276 sos_fs_nscache_get_fs_node(this->direntry)->custom_data;
274 277
275 if ( (virtfsnode->super.type != SOS_FS_NODE_ 278 if ( (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
276 && (virtfsnode->super.type != SOS_FS_NO 279 && (virtfsnode->super.type != SOS_FS_NODE_SYMLINK))
277 return -SOS_ENOSUP; 280 return -SOS_ENOSUP;
278 281
279 *result_position = this->position; 282 *result_position = this->position;
280 switch (whence) 283 switch (whence)
281 { 284 {
282 case SOS_SEEK_SET: 285 case SOS_SEEK_SET:
283 ref_offs = 0; 286 ref_offs = 0;
284 break; 287 break;
285 288
286 case SOS_SEEK_CUR: 289 case SOS_SEEK_CUR:
287 ref_offs = this->position; 290 ref_offs = this->position;
288 break; 291 break;
289 292
290 case SOS_SEEK_END: 293 case SOS_SEEK_END:
291 ref_offs = virtfsnode->file.size; 294 ref_offs = virtfsnode->file.size;
292 break; 295 break;
293 296
294 default: 297 default:
295 return -SOS_EINVAL; 298 return -SOS_EINVAL;
296 } 299 }
297 300
298 if (offset < -ref_offs) 301 if (offset < -ref_offs)
299 return -SOS_EINVAL; 302 return -SOS_EINVAL;
300 303
301 this->position = ref_offs + offset; 304 this->position = ref_offs + offset;
302 *result_position = this->position; 305 *result_position = this->position;
303 return SOS_OK; 306 return SOS_OK;
304 } 307 }
305 308
306 309
307 static sos_ret_t virtfs_read(struct sos_fs_ope 310 static sos_ret_t virtfs_read(struct sos_fs_opened_file *this,
308 sos_uaddr_t dest_ 311 sos_uaddr_t dest_buf,
309 sos_size_t * 312 sos_size_t * len)
310 { 313 {
311 sos_ret_t retval; 314 sos_ret_t retval;
312 struct virtfs_node * virtfsnode; 315 struct virtfs_node * virtfsnode;
313 316
314 virtfsnode = (struct virtfs_node*) 317 virtfsnode = (struct virtfs_node*)
315 sos_fs_nscache_get_fs_node(this->direntry) 318 sos_fs_nscache_get_fs_node(this->direntry)->custom_data;
316 319
317 if ( (virtfsnode->super.type != SOS_FS_NODE_ 320 if ( (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
318 && (virtfsnode->super.type != SOS_FS_NO 321 && (virtfsnode->super.type != SOS_FS_NODE_SYMLINK))
319 return -SOS_ENOSUP; 322 return -SOS_ENOSUP;
320 323
321 if (this->position >= virtfsnode->file.size) 324 if (this->position >= virtfsnode->file.size)
322 { 325 {
323 *len = 0; 326 *len = 0;
324 return SOS_OK; 327 return SOS_OK;
325 } 328 }
326 329
327 virtfs_lock(virtfsnode); 330 virtfs_lock(virtfsnode);
328 331
329 if (this->position + *len >= virtfsnode->fil 332 if (this->position + *len >= virtfsnode->file.size)
330 *len = virtfsnode->file.size - this->posit 333 *len = virtfsnode->file.size - this->position;
331 334
332 retval = sos_memcpy_to_user(dest_buf, 335 retval = sos_memcpy_to_user(dest_buf,
333 ((sos_vaddr_t)vi 336 ((sos_vaddr_t)virtfsnode->file.data)
334 + this->position 337 + this->position,
335 *len); 338 *len);
336 if (retval < 0) 339 if (retval < 0)
337 { 340 {
338 virtfs_unlock(virtfsnode); 341 virtfs_unlock(virtfsnode);
339 return retval; 342 return retval;
340 } 343 }
341 344
342 this->position += retval; 345 this->position += retval;
343 *len = retval; 346 *len = retval;
344 347
345 virtfs_unlock(virtfsnode); 348 virtfs_unlock(virtfsnode);
346 349
347 return SOS_OK; 350 return SOS_OK;
348 } 351 }
349 352
350 353
351 static sos_ret_t virtfs_write(struct sos_fs_op 354 static sos_ret_t virtfs_write(struct sos_fs_opened_file *this,
352 sos_uaddr_t src_b 355 sos_uaddr_t src_buf,
353 sos_size_t * 356 sos_size_t * len)
354 { 357 {
355 sos_ret_t retval; 358 sos_ret_t retval;
356 struct virtfs_node * virtfsnode; 359 struct virtfs_node * virtfsnode;
357 360
358 virtfsnode = (struct virtfs_node*) 361 virtfsnode = (struct virtfs_node*)
359 sos_fs_nscache_get_fs_node(this->direntry) 362 sos_fs_nscache_get_fs_node(this->direntry)->custom_data;
360 363
361 if ( (virtfsnode->super.type != SOS_FS_NODE_ 364 if ( (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
362 && (virtfsnode->super.type != SOS_FS_NO 365 && (virtfsnode->super.type != SOS_FS_NODE_SYMLINK))
363 return -SOS_ENOSUP; 366 return -SOS_ENOSUP;
364 367
365 virtfs_lock(virtfsnode); 368 virtfs_lock(virtfsnode);
366 if (this->position + *len >= virtfsnode->fil 369 if (this->position + *len >= virtfsnode->file.size)
367 { 370 {
368 371
369 if (SOS_OK != virtfs_resize(virtfsnode, 372 if (SOS_OK != virtfs_resize(virtfsnode, this->position + *len))
370 *len = virtfsnode->file.size - this->p 373 *len = virtfsnode->file.size - this->position;
371 } 374 }
372 375
373 retval = sos_memcpy_from_user(((sos_vaddr_t) 376 retval = sos_memcpy_from_user(((sos_vaddr_t)virtfsnode->file.data)
374 + this->posi 377 + this->position,
375 src_buf, 378 src_buf,
376 *len); 379 *len);
377 if (retval < 0) 380 if (retval < 0)
378 { 381 {
379 virtfs_unlock(virtfsnode); 382 virtfs_unlock(virtfsnode);
380 return retval; 383 return retval;
381 } 384 }
382 385
383 this->position += retval; 386 this->position += retval;
384 *len = retval; 387 *len = retval;
385 388
386 virtfs_unlock(virtfsnode); 389 virtfs_unlock(virtfsnode);
387 390
388 return SOS_OK; 391 return SOS_OK;
389 } 392 }
390 393
391 394
392 static sos_ret_t virtfs_mmap(struct sos_fs_ope 395 static sos_ret_t virtfs_mmap(struct sos_fs_opened_file *this,
393 sos_uaddr_t *uadd 396 sos_uaddr_t *uaddr, sos_size_t size,
394 sos_ui32_t access 397 sos_ui32_t access_rights,
395 sos_ui32_t flags, 398 sos_ui32_t flags,
396 sos_luoffset_t of 399 sos_luoffset_t offset)
397 { 400 {
398 struct virtfs_node * virtfsnode; 401 struct virtfs_node * virtfsnode;
399 402
400 virtfsnode = (struct virtfs_node*) 403 virtfsnode = (struct virtfs_node*)
401 sos_fs_nscache_get_fs_node(this->direntry) 404 sos_fs_nscache_get_fs_node(this->direntry)->custom_data;
402 405
403 if (virtfsnode->super.type != SOS_FS_NODE_RE 406 if (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
404 return -SOS_ENOSUP; 407 return -SOS_ENOSUP;
405 408
406 return sos_umem_vmm_map(sos_process_get_addr 409 return sos_umem_vmm_map(sos_process_get_address_space(this->owner),
407 uaddr, size, access_ 410 uaddr, size, access_rights,
408 flags, & virtfsnode- 411 flags, & virtfsnode->file.mapres, offset);
409 } 412 }
410 413
411 414
412 static sos_ret_t virtfs_readdir(struct sos_fs_ 415 static sos_ret_t virtfs_readdir(struct sos_fs_opened_file *this,
413 struct sos_fs_ 416 struct sos_fs_dirent * result)
414 { 417 {
415 418
416 419
417 420
418 421
419 struct virtfs_direntry * direntry, * next_di 422 struct virtfs_direntry * direntry, * next_direntry;
420 struct virtfs_node * virtfsnode; 423 struct virtfs_node * virtfsnode;
421 int nb; 424 int nb;
422 425
423 virtfsnode = (struct virtfs_node*) 426 virtfsnode = (struct virtfs_node*)
424 sos_fs_nscache_get_fs_node(this->direntry) 427 sos_fs_nscache_get_fs_node(this->direntry)->custom_data;
425 next_direntry = NULL; 428 next_direntry = NULL;
426 429
427 430
428 431
429 432
430 if ((this->generation == virtfsnode->super.g 433 if ((this->generation == virtfsnode->super.generation)
431 && (this->custom_data != NULL)) 434 && (this->custom_data != NULL))
432 { 435 {
433 direntry = (struct virtfs_direntry*)this 436 direntry = (struct virtfs_direntry*)this->custom_data;
434 next_direntry = direntry->sibling_next; 437 next_direntry = direntry->sibling_next;
435 438
436 439
437 if (next_direntry == list_get_head_named 440 if (next_direntry == list_get_head_named(virtfsnode->dir.list_entries,
438 441 sibling_prev, sibling_next))
439 next_direntry = NULL; 442 next_direntry = NULL;
440 } 443 }
441 else 444 else
442 445
443 { 446 {
444 447
445 next_direntry = NULL; 448 next_direntry = NULL;
446 list_foreach_forward_named(virtfsnode->d 449 list_foreach_forward_named(virtfsnode->dir.list_entries,
447 direntry, nb, 450 direntry, nb,
448 sibling_prev, 451 sibling_prev, sibling_next)
449 { 452 {
450 if (direntry->creation_order <= this 453 if (direntry->creation_order <= this->position)
451 continue; 454 continue;
452 455
453 if (! next_direntry) 456 if (! next_direntry)
454 { 457 {
455 next_direntry = direntry; 458 next_direntry = direntry;
456 continue; 459 continue;
457 } 460 }
458 461
459 if (direntry->creation_order < next_ 462 if (direntry->creation_order < next_direntry->creation_order)
460 next_direntry = direntry; 463 next_direntry = direntry;
461 } 464 }
462 } 465 }
463 466
464 if (! next_direntry) 467 if (! next_direntry)
465 { 468 {
466 this->custom_data = NULL; 469 this->custom_data = NULL;
467 this->position = 0; 470 this->position = 0;
468 return -SOS_ENOENT; 471 return -SOS_ENOENT;
469 } 472 }
470 473
471 474
472 result->storage_location = ((sos_vaddr_t)ne 475 result->storage_location = ((sos_vaddr_t)next_direntry->fsnode);
473 result->offset_in_dirfile = next_direntry->c 476 result->offset_in_dirfile = next_direntry->creation_order;
474 result->type = next_direntry->f 477 result->type = next_direntry->fsnode->type;
475 result->namelen = strnlen(next_dir 478 result->namelen = strnlen(next_direntry->name,
476 SOS_FS_D 479 SOS_FS_DIRENT_NAME_MAXLEN);
477 strzcpy(result->name, next_direntry->name, S 480 strzcpy(result->name, next_direntry->name, SOS_FS_DIRENT_NAME_MAXLEN);
478 481
479 482
480 this->position = next_direntry->creation_ 483 this->position = next_direntry->creation_order;
481 this->custom_data = next_direntry; 484 this->custom_data = next_direntry;
482 485
483 return SOS_OK; 486 return SOS_OK;
484 } 487 }
485 488
486 489
487 static struct sos_fs_ops_opened_file virtfs_op 490 static struct sos_fs_ops_opened_file virtfs_ops_opened_file =
488 (struct sos_fs_ops_opened_file){ 491 (struct sos_fs_ops_opened_file){
489 .seek = virtfs_seek, 492 .seek = virtfs_seek,
490 .read = virtfs_read, 493 .read = virtfs_read,
491 .write = virtfs_write, 494 .write = virtfs_write,
492 .mmap = virtfs_mmap 495 .mmap = virtfs_mmap
493 }; 496 };
494 497
495 498
496 static struct sos_fs_ops_opened_dir virtfs_ops 499 static struct sos_fs_ops_opened_dir virtfs_ops_opened_dir =
497 (struct sos_fs_ops_opened_dir){ 500 (struct sos_fs_ops_opened_dir){
498 .readdir = virtfs_readdir 501 .readdir = virtfs_readdir
499 }; 502 };
500 503
501 504
502 505
503 506
504 507
505 508
506 static sos_ret_t virtfs_stat_node(struct sos_f 509 static sos_ret_t virtfs_stat_node(struct sos_fs_node * this,
507 struct sos_f 510 struct sos_fs_stat * result)
508 { 511 {
509 struct virtfs_node * virtfsnode = (struct vi 512 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
510 513
511 514
512 result->st_rdev.device_class = 0; 515 result->st_rdev.device_class = 0;
513 result->st_rdev.device_instance = 0; 516 result->st_rdev.device_instance = 0;
514 if (this->type == SOS_FS_NODE_DEVICE_CHAR) !! 517 if ( (this->type == SOS_FS_NODE_DEVICE_CHAR)
>> 518 || (this->type == SOS_FS_NODE_DEVICE_BLOCK) )
515 { 519 {
516 520
517 521
518 result->st_rdev.device_class = this-> 522 result->st_rdev.device_class = this->dev_id.device_class;
519 result->st_rdev.device_instance = this-> 523 result->st_rdev.device_instance = this->dev_id.device_instance;
520 } 524 }
521 else 525 else
522 { 526 {
523 527
524 528
525 struct sos_fs_node * rootdev = this->fs- 529 struct sos_fs_node * rootdev = this->fs->device;
526 if (rootdev) 530 if (rootdev)
527 { 531 {
528 result->st_rdev.device_class = ro 532 result->st_rdev.device_class = rootdev->dev_id.device_class;
529 result->st_rdev.device_instance = ro 533 result->st_rdev.device_instance = rootdev->dev_id.device_instance;
530 } 534 }
531 } 535 }
532 536
533 result->st_type = this->type 537 result->st_type = this->type;
534 result->st_storage_location = this->stor 538 result->st_storage_location = this->storage_location;
535 result->st_access_rights = this->acce 539 result->st_access_rights = this->access_rights;
536 result->st_nlink = this->ondi 540 result->st_nlink = this->ondisk_lnk_cnt;
537 if (this->type == SOS_FS_NODE_REGULAR_FILE) 541 if (this->type == SOS_FS_NODE_REGULAR_FILE)
538 result->st_size = virtfsnode 542 result->st_size = virtfsnode->file.size;
539 else 543 else
540 result->st_size = 0; 544 result->st_size = 0;
541 return SOS_OK; 545 return SOS_OK;
542 } 546 }
543 547
544 548
545 static sos_ret_t virtfs_truncate(struct sos_fs 549 static sos_ret_t virtfs_truncate(struct sos_fs_node *this,
546 sos_lsoffset_ 550 sos_lsoffset_t length)
547 { 551 {
548 sos_ret_t retval; 552 sos_ret_t retval;
549 struct virtfs_node * virtfsnode; 553 struct virtfs_node * virtfsnode;
550 554
551 virtfsnode = (struct virtfs_node*) this->cus 555 virtfsnode = (struct virtfs_node*) this->custom_data;
552 556
553 if ( (virtfsnode->super.type != SOS_FS_NODE_ 557 if ( (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
554 && (virtfsnode->super.type != SOS_FS_NO 558 && (virtfsnode->super.type != SOS_FS_NODE_SYMLINK))
555 return -SOS_ENOSUP; 559 return -SOS_ENOSUP;
556 560
557 virtfs_lock(virtfsnode); 561 virtfs_lock(virtfsnode);
558 retval = virtfs_resize(virtfsnode, length); 562 retval = virtfs_resize(virtfsnode, length);
559 virtfs_unlock(virtfsnode); 563 virtfs_unlock(virtfsnode);
560 564
561 return retval; 565 return retval;
562 } 566 }
563 567
564 568
565 static sos_ret_t virtfs_sync_node(struct sos_f 569 static sos_ret_t virtfs_sync_node(struct sos_fs_node *this)
566 { 570 {
567 571
568 return SOS_OK; 572 return SOS_OK;
569 } 573 }
570 574
571 575
572 static sos_ret_t virtfs_chmod_node(struct sos_ 576 static sos_ret_t virtfs_chmod_node(struct sos_fs_node * this,
573 sos_ui32_t 577 sos_ui32_t access_rights)
574 { 578 {
575 this->access_rights = access_rights; 579 this->access_rights = access_rights;
576 return SOS_OK; 580 return SOS_OK;
577 } 581 }
578 582
579 583
580 584
581 585
582 static sos_ret_t virtfs_node_destructor(struct 586 static sos_ret_t virtfs_node_destructor(struct sos_fs_node * this)
583 { 587 {
584 588
585 589
586 590
587 591
588 if (this->ondisk_lnk_cnt <= 0) 592 if (this->ondisk_lnk_cnt <= 0)
589 { 593 {
590 struct virtfs_instance * virtfs = (struc 594 struct virtfs_instance * virtfs = (struct virtfs_instance*)this->fs->custom_data;
591 struct virtfs_node * virtfsnode = (struc 595 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
592 596
593 list_delete(virtfs->list_fsnodes, virtfs 597 list_delete(virtfs->list_fsnodes, virtfsnode);
594 sos_kfree((sos_vaddr_t) this->custom_dat 598 sos_kfree((sos_vaddr_t) this->custom_data);
595 } 599 }
596 600
597 return SOS_OK; 601 return SOS_OK;
598 } 602 }
599 603
600 604
601 static struct sos_fs_node_ops_file virtfs_ops_ 605 static struct sos_fs_node_ops_file virtfs_ops_file =
602 (struct sos_fs_node_ops_file){ 606 (struct sos_fs_node_ops_file){
603 .truncate = virtfs_truncate, 607 .truncate = virtfs_truncate,
604 .stat = virtfs_stat_node, 608 .stat = virtfs_stat_node,
605 .chmod = virtfs_chmod_node !! 609 .chmod = virtfs_chmod_node,
>> 610 .sync = virtfs_sync_node
606 }; 611 };
607 612
608 613
609 static sos_ret_t virtfs_new_opened_file(struct 614 static sos_ret_t virtfs_new_opened_file(struct sos_fs_node * this,
610 const 615 const struct sos_process * owner,
611 sos_ui 616 sos_ui32_t open_flags,
612 struct 617 struct sos_fs_opened_file ** result_of)
613 { 618 {
614 struct sos_fs_opened_file * of 619 struct sos_fs_opened_file * of
615 = (struct sos_fs_opened_file*)sos_kmalloc( 620 = (struct sos_fs_opened_file*)sos_kmalloc(sizeof(*of), 0);
616 if (! of) 621 if (! of)
617 return -SOS_ENOMEM; 622 return -SOS_ENOMEM;
618 623
619 memset(of, 0x0, sizeof(*of)); 624 memset(of, 0x0, sizeof(*of));
620 of->owner = owner; 625 of->owner = owner;
621 of->duplicate = virtfs_duplicate_opened_fil 626 of->duplicate = virtfs_duplicate_opened_file;
622 of->open_flags = open_flags; 627 of->open_flags = open_flags;
623 of->ops_file = & virtfs_ops_opened_file; 628 of->ops_file = & virtfs_ops_opened_file;
624 if (this->type == SOS_FS_NODE_DIRECTORY) 629 if (this->type == SOS_FS_NODE_DIRECTORY)
625 of->ops_dir = & virtfs_ops_opened_dir; 630 of->ops_dir = & virtfs_ops_opened_dir;
626 631
627 *result_of = of; 632 *result_of = of;
628 return SOS_OK; 633 return SOS_OK;
629 } 634 }
630 635
631 636
632 static sos_ret_t virtfs_close_opened_file(stru 637 static sos_ret_t virtfs_close_opened_file(struct sos_fs_node * this,
633 stru 638 struct sos_fs_opened_file * of)
634 { 639 {
635 sos_kfree((sos_vaddr_t)of); 640 sos_kfree((sos_vaddr_t)of);
636 return SOS_OK; 641 return SOS_OK;
637 } 642 }
638 643
639 644
640 static sos_ret_t virtfs_symlink_expand(struct 645 static sos_ret_t virtfs_symlink_expand(struct sos_fs_node *this,
641 char co 646 char const ** target,
642 sos_siz 647 sos_size_t * target_len)
643 { 648 {
644 struct virtfs_node * virtfsnode = (struct vi 649 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
645 650
646 *target = virtfsnode->file.data; 651 *target = virtfsnode->file.data;
647 *target_len = virtfsnode->file.size; 652 *target_len = virtfsnode->file.size;
648 653
649 return SOS_OK; 654 return SOS_OK;
650 } 655 }
651 656
652 657
653 static struct sos_fs_node_ops_symlink virtfs_o 658 static struct sos_fs_node_ops_symlink virtfs_ops_symlink
654 = (struct sos_fs_node_ops_symlink){ 659 = (struct sos_fs_node_ops_symlink){
655 .expand = virtfs_symlink_expand 660 .expand = virtfs_symlink_expand
656 }; 661 };
657 662
658 663
659 static sos_ret_t virtfs_dir_lookup(struct sos_ 664 static sos_ret_t virtfs_dir_lookup(struct sos_fs_node *this,
660 const char 665 const char * name, sos_ui16_t namelen,
661 sos_ui64_t 666 sos_ui64_t * result_storage_location)
662 { 667 {
663 struct virtfs_node * virtfsnode = (struct vi 668 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
664 struct virtfs_direntry * direntry; 669 struct virtfs_direntry * direntry;
665 int nbentries; 670 int nbentries;
666 671
667 list_foreach_forward_named(virtfsnode->dir.l 672 list_foreach_forward_named(virtfsnode->dir.list_entries,
668 direntry, nbentri 673 direntry, nbentries,
669 sibling_prev, sib 674 sibling_prev, sibling_next)
670 { 675 {
671 if (!memcmp(name, direntry->name, namele 676 if (!memcmp(name, direntry->name, namelen) && !direntry->name[namelen])
672 { 677 {
673 *result_storage_location = direntry- 678 *result_storage_location = direntry->fsnode->storage_location;
674 return SOS_OK; 679 return SOS_OK;
675 } 680 }
676 } 681 }
677 682
678 return -SOS_ENOENT; 683 return -SOS_ENOENT;
679 } 684 }
680 685
681 686
682 static sos_ret_t virtfs_link(struct sos_fs_nod 687 static sos_ret_t virtfs_link(struct sos_fs_node *this,
683 const struct sos_ 688 const struct sos_process *actor,
684 const char * entr 689 const char * entry_name, sos_ui16_t entry_namelen,
685 struct sos_fs_nod 690 struct sos_fs_node * node)
686 { 691 {
687 struct virtfs_node * parent = (struct virtfs 692 struct virtfs_node * parent = (struct virtfs_node*)this->custom_data;
688 struct virtfs_direntry * direntry; 693 struct virtfs_direntry * direntry;
689 694
690 direntry = (struct virtfs_direntry*)sos_kmal 695 direntry = (struct virtfs_direntry*)sos_kmalloc(sizeof(*direntry), 0);
691 if (! direntry) 696 if (! direntry)
692 return -SOS_ENOMEM; 697 return -SOS_ENOMEM;
693 698
694 direntry->name = (char*)sos_kmalloc(entry_na 699 direntry->name = (char*)sos_kmalloc(entry_namelen + 1, 0);
695 if (! direntry->name) 700 if (! direntry->name)
696 { 701 {
697 sos_kfree((sos_vaddr_t)direntry->name); 702 sos_kfree((sos_vaddr_t)direntry->name);
698 return -SOS_ENOMEM; 703 return -SOS_ENOMEM;
699 } 704 }
700 705
701 memcpy(direntry->name, entry_name, entry_nam 706 memcpy(direntry->name, entry_name, entry_namelen);
702 direntry->name[entry_namelen] = '\0'; 707 direntry->name[entry_namelen] = '\0';
703 708
704 direntry->fsnode = node; 709 direntry->fsnode = node;
705 node->ondisk_lnk_cnt ++; 710 node->ondisk_lnk_cnt ++;
706 this->ondisk_lnk_cnt ++; 711 this->ondisk_lnk_cnt ++;
707 list_add_tail_named(parent->dir.list_entries 712 list_add_tail_named(parent->dir.list_entries, direntry,
708 sibling_prev, sibling_ne 713 sibling_prev, sibling_next);
709 714
710 715
711 716
712 parent->dir.top_creation_order ++; 717 parent->dir.top_creation_order ++;
713 direntry->creation_order = parent->dir.top_c 718 direntry->creation_order = parent->dir.top_creation_order;
714 719
715 return SOS_OK; 720 return SOS_OK;
716 } 721 }
717 722
718 723
719 static sos_ret_t 724 static sos_ret_t
720 virtfs_unlink(struct sos_fs_node *this, 725 virtfs_unlink(struct sos_fs_node *this,
721 const struct sos_process *actor, 726 const struct sos_process *actor,
722 const char * entry_name, sos_ui1 727 const char * entry_name, sos_ui16_t entry_namelen)
723 { 728 {
724 struct virtfs_node * parent = (struct virtfs 729 struct virtfs_node * parent = (struct virtfs_node*)this->custom_data;
725 struct virtfs_direntry * direntry; 730 struct virtfs_direntry * direntry;
726 int nbentries; 731 int nbentries;
727 732
728 list_foreach_forward_named(parent->dir.list_ 733 list_foreach_forward_named(parent->dir.list_entries,
729 direntry, nbentri 734 direntry, nbentries,
730 sibling_prev, sib 735 sibling_prev, sibling_next)
731 { 736 {
732 if (!memcmp(entry_name, direntry->name, 737 if (!memcmp(entry_name, direntry->name, entry_namelen)
733 && !direntry->name[entry_namelen]) 738 && !direntry->name[entry_namelen])
734 { 739 {
735 list_delete_named(parent->dir.list_e 740 list_delete_named(parent->dir.list_entries, direntry,
736 sibling_prev, sibl 741 sibling_prev, sibling_next);
737 direntry->fsnode->ondisk_lnk_cnt --; 742 direntry->fsnode->ondisk_lnk_cnt --;
738 this->ondisk_lnk_cnt --; 743 this->ondisk_lnk_cnt --;
739 sos_kfree((sos_vaddr_t)direntry); 744 sos_kfree((sos_vaddr_t)direntry);
740 return SOS_OK; 745 return SOS_OK;
741 } 746 }
742 } 747 }
743 748
744 return -SOS_ENOENT; 749 return -SOS_ENOENT;
745 } 750 }
746 751
747 752
748 static struct sos_fs_node_ops_dir virtfs_ops_d 753 static struct sos_fs_node_ops_dir virtfs_ops_dir
749 = (struct sos_fs_node_ops_dir){ 754 = (struct sos_fs_node_ops_dir){
750 .lookup = virtfs_dir_lookup, 755 .lookup = virtfs_dir_lookup,
751 .link = virtfs_link, 756 .link = virtfs_link,
752 .unlink = virtfs_unlink 757 .unlink = virtfs_unlink
753 }; 758 };
754 759
755 760
756 761
757 762
758 763
759 764
760 765
761 766
762 767
763 768
764 769
765 static sos_ret_t 770 static sos_ret_t
766 virtfs_fetch_node_from_disk(struct sos_fs_mana 771 virtfs_fetch_node_from_disk(struct sos_fs_manager_instance * this,
767 sos_ui64_t storage 772 sos_ui64_t storage_location,
768 struct sos_fs_node 773 struct sos_fs_node ** result)
769 { 774 {
770 775
771 struct virtfs_node * virtfsnode; 776 struct virtfs_node * virtfsnode;
772 777
773 virtfsnode = (struct virtfs_node *)((sos_vad 778 virtfsnode = (struct virtfs_node *)((sos_vaddr_t)storage_location);
774 *result = & virtfsnode->super; 779 *result = & virtfsnode->super;
775 780
776 return SOS_OK; 781 return SOS_OK;
777 } 782 }
778 783
779 784
780 static sos_ret_t 785 static sos_ret_t
781 virtfs_allocate_new_node(struct sos_fs_manager 786 virtfs_allocate_new_node(struct sos_fs_manager_instance * this,
782 sos_fs_node_type_t ty 787 sos_fs_node_type_t type,
783 const struct sos_proc 788 const struct sos_process * creator,
784 sos_ui32_t access_rig 789 sos_ui32_t access_rights,
785 sos_ui32_t flags, 790 sos_ui32_t flags,
786 struct sos_fs_node ** 791 struct sos_fs_node ** result)
787 { 792 {
788 struct virtfs_node * virtfsnode; 793 struct virtfs_node * virtfsnode;
789 794
790 795
791 if ((type != SOS_FS_NODE_REGULAR_FILE) 796 if ((type != SOS_FS_NODE_REGULAR_FILE)
792 && (type != SOS_FS_NODE_SYMLINK) 797 && (type != SOS_FS_NODE_SYMLINK)
793 && (type != SOS_FS_NODE_DIRECTORY) 798 && (type != SOS_FS_NODE_DIRECTORY)
794 && (type != SOS_FS_NODE_DEVICE_CHAR)) !! 799 && (type != SOS_FS_NODE_DEVICE_CHAR)
>> 800 && (type != SOS_FS_NODE_DEVICE_BLOCK))
795 return -SOS_ENOSUP; 801 return -SOS_ENOSUP;
796 802
797 virtfsnode = (struct virtfs_node*) sos_kmall 803 virtfsnode = (struct virtfs_node*) sos_kmalloc(sizeof(*virtfsnode), 0);
798 if (! virtfsnode) 804 if (! virtfsnode)
799 return -SOS_ENOMEM; 805 return -SOS_ENOMEM;
800 806
801 memset(virtfsnode, 0x0, sizeof(*virtfsnode)) 807 memset(virtfsnode, 0x0, sizeof(*virtfsnode));
802 *result = & virtfsnode->super; 808 *result = & virtfsnode->super;
803 809
804 810
805 (*result)->inmem_ref_cnt = 1; 811 (*result)->inmem_ref_cnt = 1;
806 (*result)->custom_data = virtfsnode; 812 (*result)->custom_data = virtfsnode;
807 (*result)->storage_location = (sos_ui64_t)( 813 (*result)->storage_location = (sos_ui64_t)((sos_vaddr_t)virtfsnode);
808 (*result)->type = type; 814 (*result)->type = type;
809 (*result)->access_rights = access_rights 815 (*result)->access_rights = access_rights;
810 (*result)->destructor = virtfs_node_d 816 (*result)->destructor = virtfs_node_destructor;
811 (*result)->ops_file = & virtfs_ops_ 817 (*result)->ops_file = & virtfs_ops_file;
812 818
813 819
814 820
815 if (type != SOS_FS_NODE_DEVICE_CHAR) !! 821 if ((type != SOS_FS_NODE_DEVICE_CHAR)
>> 822 && (type != SOS_FS_NODE_DEVICE_BLOCK))
816 { 823 {
817 (*result)->sync = virtfs_sy <<
818 (*result)->new_opened_file = virtfs_ne 824 (*result)->new_opened_file = virtfs_new_opened_file;
819 (*result)->close_opened_file = virtfs_cl 825 (*result)->close_opened_file = virtfs_close_opened_file;
820 } 826 }
821 827
822 if (type == SOS_FS_NODE_SYMLINK) 828 if (type == SOS_FS_NODE_SYMLINK)
823 (*result)->ops_symlink = & virtfs_ops_syml 829 (*result)->ops_symlink = & virtfs_ops_symlink;
824 else if (type == SOS_FS_NODE_DIRECTORY) 830 else if (type == SOS_FS_NODE_DIRECTORY)
825 (*result)->ops_dir = & virtfs_ops_dir; 831 (*result)->ops_dir = & virtfs_ops_dir;
826 832
827 833
828 if (type == SOS_FS_NODE_REGULAR_FILE) 834 if (type == SOS_FS_NODE_REGULAR_FILE)
829 { 835 {
830 virtfsnode->file.mapres.allowed_access_r 836 virtfsnode->file.mapres.allowed_access_rights
831 = SOS_VM_MAP_PROT_READ 837 = SOS_VM_MAP_PROT_READ
832 | SOS_VM_MAP_PROT_WRITE 838 | SOS_VM_MAP_PROT_WRITE
833 | SOS_VM_MAP_PROT_EXEC; 839 | SOS_VM_MAP_PROT_EXEC;
834 virtfsnode->file.mapres.custom_data = 840 virtfsnode->file.mapres.custom_data = virtfsnode;
835 virtfsnode->file.mapres.mmap = 841 virtfsnode->file.mapres.mmap = virtfs_new_mapping;
836 } 842 }
837 843
838 list_add_tail(((struct virtfs_instance*)this 844 list_add_tail(((struct virtfs_instance*)this->custom_data)->list_fsnodes,
839 virtfsnode); 845 virtfsnode);
840 846
841 return SOS_OK; 847 return SOS_OK;
842 } 848 }
843 849
844 850
845 851
846 852
847 853
848 854
849 static sos_ret_t virtfs_mount(struct sos_fs_ma 855 static sos_ret_t virtfs_mount(struct sos_fs_manager_type * this,
850 struct sos_fs_no 856 struct sos_fs_node * device,
851 const char * arg 857 const char * args,
852 struct sos_fs_ma 858 struct sos_fs_manager_instance ** mounted_fs)
853 { 859 {
854 sos_ret_t retval; 860 sos_ret_t retval;
855 struct virtfs_instance * fs; 861 struct virtfs_instance * fs;
856 struct sos_fs_node * fsnode_root; 862 struct sos_fs_node * fsnode_root;
857 struct sos_hash_table * hash; 863 struct sos_hash_table * hash;
858 864
859 *mounted_fs = (struct sos_fs_manager_instanc 865 *mounted_fs = (struct sos_fs_manager_instance*)NULL;
860 866
861 867
862 hash = sos_hash_create("virtfs H", struct so 868 hash = sos_hash_create("virtfs H", struct sos_fs_node,
863 sos_hash_ui64, 869 sos_hash_ui64,
864 sos_hash_key_eq_ui64, 870 sos_hash_key_eq_ui64, 17,
865 storage_location, hli 871 storage_location, hlink_nodecache);
866 if (! hash) 872 if (! hash)
867 return -SOS_ENOMEM; 873 return -SOS_ENOMEM;
868 874
869 fs = (struct virtfs_instance*) 875 fs = (struct virtfs_instance*)
870 sos_kmalloc(sizeof(struct virtfs_instance) 876 sos_kmalloc(sizeof(struct virtfs_instance), 0);
871 if (! fs) 877 if (! fs)
872 { 878 {
873 sos_hash_dispose(hash); 879 sos_hash_dispose(hash);
874 return -SOS_ENOMEM; 880 return -SOS_ENOMEM;
875 } 881 }
876 882
877 memset(fs, 0x0, sizeof(struct virtfs_instanc 883 memset(fs, 0x0, sizeof(struct virtfs_instance));
878 retval = sos_kmutex_init(& fs->lock, "virtfs 884 retval = sos_kmutex_init(& fs->lock, "virtfs", SOS_KWQ_ORDER_FIFO);
879 if (SOS_OK != retval) 885 if (SOS_OK != retval)
880 { 886 {
881 sos_hash_dispose(hash); 887 sos_hash_dispose(hash);
882 sos_kfree((sos_vaddr_t) fs); 888 sos_kfree((sos_vaddr_t) fs);
883 return retval; 889 return retval;
884 } 890 }
885 fs->super.custom_data = fs; 891 fs->super.custom_data = fs;
886 fs->super.fs_type = this; 892 fs->super.fs_type = this;
887 fs->super.allocate_new_node = virtfs_allo 893 fs->super.allocate_new_node = virtfs_allocate_new_node;
888 fs->super.fetch_node_from_disk = virtfs_fetc 894 fs->super.fetch_node_from_disk = virtfs_fetch_node_from_disk;
889 fs->super.nodecache = hash; 895 fs->super.nodecache = hash;
890 896
891 retval = virtfs_allocate_new_node(& fs->supe 897 retval = virtfs_allocate_new_node(& fs->super, SOS_FS_NODE_DIRECTORY,
892 NULL, 898 NULL,
893 SOS_FS_REA 899 SOS_FS_READABLE | SOS_FS_WRITABLE
894 | SOS_FS_E 900 | SOS_FS_EXECUTABLE,
895 0, 901 0,
896 & fsnode_r 902 & fsnode_root);
897 if (SOS_OK != retval) 903 if (SOS_OK != retval)
898 { 904 {
899 sos_hash_dispose(hash); 905 sos_hash_dispose(hash);
900 sos_kmutex_dispose(& fs->lock); 906 sos_kmutex_dispose(& fs->lock);
901 sos_kfree((sos_vaddr_t) fs); 907 sos_kfree((sos_vaddr_t) fs);
902 return retval; 908 return retval;
903 } 909 }
904 910
905 retval = sos_fs_register_fs_instance(& fs->s 911 retval = sos_fs_register_fs_instance(& fs->super, fsnode_root);
906 sos_fs_unref_fsnode(fsnode_root); 912 sos_fs_unref_fsnode(fsnode_root);
907 if (SOS_OK != retval) 913 if (SOS_OK != retval)
908 { 914 {
909 sos_hash_dispose(hash); 915 sos_hash_dispose(hash);
910 sos_kmutex_dispose(& fs->lock); 916 sos_kmutex_dispose(& fs->lock);
911 sos_kfree((sos_vaddr_t) fs); 917 sos_kfree((sos_vaddr_t) fs);
912 return retval; 918 return retval;
913 } 919 }
914 920
915 *mounted_fs = & fs->super; 921 *mounted_fs = & fs->super;
916 return SOS_OK; 922 return SOS_OK;
917 } 923 }
918 924
919 925
920 static sos_ret_t virtfs_umount(struct sos_fs_m 926 static sos_ret_t virtfs_umount(struct sos_fs_manager_type * this,
921 struct sos_fs_m 927 struct sos_fs_manager_instance * mounted_fs)
922 { 928 {
923 struct virtfs_instance * virtfs = (struct vi 929 struct virtfs_instance * virtfs = (struct virtfs_instance*)mounted_fs->custom_data;
924 930
925 sos_hash_dispose(virtfs->super.nodecache); 931 sos_hash_dispose(virtfs->super.nodecache);
926 while (! list_is_empty(virtfs->list_fsnodes) 932 while (! list_is_empty(virtfs->list_fsnodes))
927 { 933 {
928 struct virtfs_node * virtfsnode = list_p 934 struct virtfs_node * virtfsnode = list_pop_head(virtfs->list_fsnodes);
929 935
930 if (virtfsnode->super.type == SOS_FS_NOD 936 if (virtfsnode->super.type == SOS_FS_NODE_REGULAR_FILE)
931 { 937 {
932 if (virtfsnode->file.size > 0) 938 if (virtfsnode->file.size > 0)
933 sos_kfree((sos_vaddr_t) virtfsnode 939 sos_kfree((sos_vaddr_t) virtfsnode->file.data);
934 } 940 }
935 else if (virtfsnode->super.type == SOS_F 941 else if (virtfsnode->super.type == SOS_FS_NODE_DIRECTORY)
936 { 942 {
937 while (! list_is_empty_named(virtfsn 943 while (! list_is_empty_named(virtfsnode->dir.list_entries,
938 sibling 944 sibling_prev, sibling_next))
939 { 945 {
940 struct virtfs_direntry * direntr 946 struct virtfs_direntry * direntry
941 = list_pop_head_named(virtfsno 947 = list_pop_head_named(virtfsnode->dir.list_entries,
942 sibling_ 948 sibling_prev, sibling_next);
943 949
944 sos_kfree((sos_vaddr_t)direntry- 950 sos_kfree((sos_vaddr_t)direntry->name);
945 sos_kfree((sos_vaddr_t)direntry) 951 sos_kfree((sos_vaddr_t)direntry);
946 } 952 }
947 } 953 }
948 954
949 sos_kfree((sos_vaddr_t)virtfsnode); 955 sos_kfree((sos_vaddr_t)virtfsnode);
950 } 956 }
951 957
952 sos_fs_unregister_fs_instance(& virtfs->supe 958 sos_fs_unregister_fs_instance(& virtfs->super);
953 sos_kmutex_dispose(& virtfs->lock); 959 sos_kmutex_dispose(& virtfs->lock);
954 sos_kfree((sos_vaddr_t)virtfs); 960 sos_kfree((sos_vaddr_t)virtfs);
955 return SOS_OK; 961 return SOS_OK;
956 } 962 }
957 963
958 964
959 965
960 966
961 967
962 inline static struct virtfs_node * 968 inline static struct virtfs_node *
963 get_virtfsnode_of_vr(struct sos_umem_vmm_vr * 969 get_virtfsnode_of_vr(struct sos_umem_vmm_vr * vr)
964 { 970 {
965 struct sos_umem_vmm_mapped_resource *mr 971 struct sos_umem_vmm_mapped_resource *mr
966 = sos_umem_vmm_get_mapped_resource_of_vr(v 972 = sos_umem_vmm_get_mapped_resource_of_vr(vr);
967 973
968 return (struct virtfs_node *)mr->custom_data 974 return (struct virtfs_node *)mr->custom_data;
969 } 975 }
970 976
971 977
972 static void virtfs_map_ref(struct sos_umem_vmm 978 static void virtfs_map_ref(struct sos_umem_vmm_vr * vr)
973 { 979 {
974 struct virtfs_node * virtfsnode = get_virtfs 980 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
975 sos_fs_ref_fsnode(& virtfsnode->super); 981 sos_fs_ref_fsnode(& virtfsnode->super);
976 virtfsnode->file.num_mappings ++; 982 virtfsnode->file.num_mappings ++;
977 } 983 }
978 984
979 985
980 static void virtfs_map_unref(struct sos_umem_v 986 static void virtfs_map_unref(struct sos_umem_vmm_vr * vr)
981 { 987 {
982 struct virtfs_node * virtfsnode = get_virtfs 988 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
983 989
984 SOS_ASSERT_FATAL(virtfsnode->file.num_mappin 990 SOS_ASSERT_FATAL(virtfsnode->file.num_mappings > 0);
985 virtfsnode->file.num_mappings --; 991 virtfsnode->file.num_mappings --;
986 992
987 _sos_fs_unref_fsnode(& virtfsnode->super); 993 _sos_fs_unref_fsnode(& virtfsnode->super);
988 } 994 }
989 995
990 996
991 static sos_ret_t virtfs_map_page_in(struct sos 997 static sos_ret_t virtfs_map_page_in(struct sos_umem_vmm_vr * vr,
992 sos_uaddr_ 998 sos_uaddr_t uaddr,
993 sos_bool_t 999 sos_bool_t write_access)
994 { 1000 {
995 struct virtfs_node * virtfsnode = get_virtfs 1001 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
996 sos_luoffset_t offset = uaddr - sos_umem_vmm 1002 sos_luoffset_t offset = uaddr - sos_umem_vmm_get_start_of_vr(vr);
997 sos_ret_t retval = SOS_OK; 1003 sos_ret_t retval = SOS_OK;
998 sos_paddr_t ppage_paddr; 1004 sos_paddr_t ppage_paddr;
999 1005
1000 1006
1001 if (SOS_PAGE_ALIGN_SUP(offset) > virtfsnode 1007 if (SOS_PAGE_ALIGN_SUP(offset) > virtfsnode->file.size)
1002 return -SOS_EFAULT; 1008 return -SOS_EFAULT;
1003 1009
1004 1010
1005 ppage_paddr = sos_paging_get_paddr(SOS_PAGE 1011 ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ALIGN_INF(virtfsnode->file.data
1006 1012 + offset));
1007 1013
1008 1014
1009 if (! ppage_paddr) 1015 if (! ppage_paddr)
1010 return -SOS_EFAULT; 1016 return -SOS_EFAULT;
1011 1017
1012 1018
1013 retval = sos_paging_map(ppage_paddr, 1019 retval = sos_paging_map(ppage_paddr,
1014 SOS_PAGE_ALIGN_INF( 1020 SOS_PAGE_ALIGN_INF(uaddr),
1015 TRUE, 1021 TRUE,
1016 sos_umem_vmm_get_pr 1022 sos_umem_vmm_get_prot_of_vr(vr));
1017 1023
1018 return retval; 1024 return retval;
1019 } 1025 }
1020 1026
1021 1027
1022 static struct sos_umem_vmm_vr_ops virtfs_map_ 1028 static struct sos_umem_vmm_vr_ops virtfs_map_ops
1023 = (struct sos_umem_vmm_vr_ops){ 1029 = (struct sos_umem_vmm_vr_ops){
1024 .ref = virtfs_map_ref, 1030 .ref = virtfs_map_ref,
1025 .unref = virtfs_map_unref, 1031 .unref = virtfs_map_unref,
1026 .page_in = virtfs_map_page_in 1032 .page_in = virtfs_map_page_in
1027 }; 1033 };
1028 1034
1029 static sos_ret_t virtfs_new_mapping(struct so 1035 static sos_ret_t virtfs_new_mapping(struct sos_umem_vmm_vr *vr)
1030 { 1036 {
1031 struct virtfs_node * virtfsnode = get_virtf 1037 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
1032 sos_size_t reqsize; 1038 sos_size_t reqsize;
1033 sos_ret_t retval; 1039 sos_ret_t retval;
1034 1040
1035 reqsize = sos_umem_vmm_get_offset_in_resou 1041 reqsize = sos_umem_vmm_get_offset_in_resource(vr);
1036 reqsize += sos_umem_vmm_get_size_of_vr(vr); 1042 reqsize += sos_umem_vmm_get_size_of_vr(vr);
1037 1043
1038 1044
1039 if (reqsize > virtfsnode->file.size) 1045 if (reqsize > virtfsnode->file.size)
1040 { 1046 {
1041 retval = virtfs_resize(virtfsnode, 1047 retval = virtfs_resize(virtfsnode,
1042 SOS_PAGE_ALIGN_S 1048 SOS_PAGE_ALIGN_SUP(reqsize));
1043 if (SOS_OK != retval) 1049 if (SOS_OK != retval)
1044 return retval; 1050 return retval;
1045 } 1051 }
1046 1052
1047 return sos_umem_vmm_set_ops_of_vr(vr, &virt 1053 return sos_umem_vmm_set_ops_of_vr(vr, &virtfs_map_ops);
1048 } 1054 }