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