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 result->st_type = this->type;
514 !! 511 result->st_storage_location = this->storage_location;
515 result->st_rdev.device_class = 0; !! 512 result->st_access_rights = this->access_rights;
516 result->st_rdev.device_instance = 0; !! 513 result->st_nlink = this->ondisk_lnk_cnt;
517 if ( (this->type == SOS_FS_NODE_DEVICE_CHAR) <<
518 || (this->type == SOS_FS_NODE_DEVICE_BL <<
519 { <<
520 <<
521 <<
522 result->st_rdev.device_class = this-> <<
523 result->st_rdev.device_instance = this-> <<
524 } <<
525 else <<
526 { <<
527 <<
528 <<
529 struct sos_fs_node * rootdev = this->fs- <<
530 if (rootdev) <<
531 { <<
532 result->st_rdev.device_class = ro <<
533 result->st_rdev.device_instance = ro <<
534 } <<
535 } <<
536 <<
537 result->st_type = this->type <<
538 result->st_storage_location = this->stor <<
539 result->st_access_rights = this->acce <<
540 result->st_nlink = this->ondi <<
541 if (this->type == SOS_FS_NODE_REGULAR_FILE) 514 if (this->type == SOS_FS_NODE_REGULAR_FILE)
542 result->st_size = virtfsnode !! 515 result->st_size = virtfsnode->file.size;
543 else 516 else
544 result->st_size = 0; !! 517 result->st_size = 0;
545 return SOS_OK; 518 return SOS_OK;
546 } 519 }
547 520
548 521
549 static sos_ret_t virtfs_truncate(struct sos_fs 522 static sos_ret_t virtfs_truncate(struct sos_fs_node *this,
550 sos_lsoffset_ 523 sos_lsoffset_t length)
551 { 524 {
552 sos_ret_t retval; 525 sos_ret_t retval;
553 struct virtfs_node * virtfsnode; 526 struct virtfs_node * virtfsnode;
554 527
555 virtfsnode = (struct virtfs_node*) this->cus 528 virtfsnode = (struct virtfs_node*) this->custom_data;
556 529
557 if ( (virtfsnode->super.type != SOS_FS_NODE_ 530 if ( (virtfsnode->super.type != SOS_FS_NODE_REGULAR_FILE)
558 && (virtfsnode->super.type != SOS_FS_NO 531 && (virtfsnode->super.type != SOS_FS_NODE_SYMLINK))
559 return -SOS_ENOSUP; 532 return -SOS_ENOSUP;
560 533
561 virtfs_lock(virtfsnode); 534 virtfs_lock(virtfsnode);
562 retval = virtfs_resize(virtfsnode, length); 535 retval = virtfs_resize(virtfsnode, length);
563 virtfs_unlock(virtfsnode); 536 virtfs_unlock(virtfsnode);
564 537
565 return retval; 538 return retval;
566 } 539 }
567 540
568 541
569 static sos_ret_t virtfs_sync_node(struct sos_f 542 static sos_ret_t virtfs_sync_node(struct sos_fs_node *this)
570 { 543 {
571 544
572 return SOS_OK; 545 return SOS_OK;
573 } 546 }
574 547
575 548
576 static sos_ret_t virtfs_chmod_node(struct sos_ 549 static sos_ret_t virtfs_chmod_node(struct sos_fs_node * this,
577 sos_ui32_t 550 sos_ui32_t access_rights)
578 { 551 {
579 this->access_rights = access_rights; 552 this->access_rights = access_rights;
580 return SOS_OK; 553 return SOS_OK;
581 } 554 }
582 555
583 556
584 557
585 558
586 static sos_ret_t virtfs_node_destructor(struct 559 static sos_ret_t virtfs_node_destructor(struct sos_fs_node * this)
587 { 560 {
588 561
589 562
590 563
591 564
592 if (this->ondisk_lnk_cnt <= 0) 565 if (this->ondisk_lnk_cnt <= 0)
593 { 566 {
594 struct virtfs_instance * virtfs = (struc 567 struct virtfs_instance * virtfs = (struct virtfs_instance*)this->fs->custom_data;
595 struct virtfs_node * virtfsnode = (struc 568 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
596 569
597 list_delete(virtfs->list_fsnodes, virtfs 570 list_delete(virtfs->list_fsnodes, virtfsnode);
598 sos_kfree((sos_vaddr_t) this->custom_dat 571 sos_kfree((sos_vaddr_t) this->custom_data);
599 } 572 }
600 573
601 return SOS_OK; 574 return SOS_OK;
602 } 575 }
603 576
604 577
605 static struct sos_fs_node_ops_file virtfs_ops_ 578 static struct sos_fs_node_ops_file virtfs_ops_file =
606 (struct sos_fs_node_ops_file){ 579 (struct sos_fs_node_ops_file){
607 .truncate = virtfs_truncate, 580 .truncate = virtfs_truncate,
608 .stat = virtfs_stat_node, 581 .stat = virtfs_stat_node,
609 .chmod = virtfs_chmod_node, !! 582 .sync = virtfs_sync_node,
610 .sync = virtfs_sync_node !! 583 .chmod = virtfs_chmod_node
611 }; 584 };
612 585
613 586
614 static sos_ret_t virtfs_new_opened_file(struct 587 static sos_ret_t virtfs_new_opened_file(struct sos_fs_node * this,
615 const 588 const struct sos_process * owner,
616 sos_ui 589 sos_ui32_t open_flags,
617 struct 590 struct sos_fs_opened_file ** result_of)
618 { 591 {
619 struct sos_fs_opened_file * of 592 struct sos_fs_opened_file * of
620 = (struct sos_fs_opened_file*)sos_kmalloc( 593 = (struct sos_fs_opened_file*)sos_kmalloc(sizeof(*of), 0);
621 if (! of) 594 if (! of)
622 return -SOS_ENOMEM; 595 return -SOS_ENOMEM;
623 596
624 memset(of, 0x0, sizeof(*of)); 597 memset(of, 0x0, sizeof(*of));
625 of->owner = owner; 598 of->owner = owner;
626 of->duplicate = virtfs_duplicate_opened_fil 599 of->duplicate = virtfs_duplicate_opened_file;
627 of->open_flags = open_flags; 600 of->open_flags = open_flags;
628 of->ops_file = & virtfs_ops_opened_file; 601 of->ops_file = & virtfs_ops_opened_file;
629 if (this->type == SOS_FS_NODE_DIRECTORY) 602 if (this->type == SOS_FS_NODE_DIRECTORY)
630 of->ops_dir = & virtfs_ops_opened_dir; 603 of->ops_dir = & virtfs_ops_opened_dir;
631 604
632 *result_of = of; 605 *result_of = of;
633 return SOS_OK; 606 return SOS_OK;
634 } 607 }
635 608
636 609
637 static sos_ret_t virtfs_close_opened_file(stru 610 static sos_ret_t virtfs_close_opened_file(struct sos_fs_node * this,
638 stru 611 struct sos_fs_opened_file * of)
639 { 612 {
640 sos_kfree((sos_vaddr_t)of); 613 sos_kfree((sos_vaddr_t)of);
641 return SOS_OK; 614 return SOS_OK;
642 } 615 }
643 616
644 617
645 static sos_ret_t virtfs_symlink_expand(struct 618 static sos_ret_t virtfs_symlink_expand(struct sos_fs_node *this,
646 char co 619 char const ** target,
647 sos_siz 620 sos_size_t * target_len)
648 { 621 {
649 struct virtfs_node * virtfsnode = (struct vi 622 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
650 623
651 *target = virtfsnode->file.data; 624 *target = virtfsnode->file.data;
652 *target_len = virtfsnode->file.size; 625 *target_len = virtfsnode->file.size;
653 626
654 return SOS_OK; 627 return SOS_OK;
655 } 628 }
656 629
657 630
658 static struct sos_fs_node_ops_symlink virtfs_o 631 static struct sos_fs_node_ops_symlink virtfs_ops_symlink
659 = (struct sos_fs_node_ops_symlink){ 632 = (struct sos_fs_node_ops_symlink){
660 .expand = virtfs_symlink_expand 633 .expand = virtfs_symlink_expand
661 }; 634 };
662 635
663 636
664 static sos_ret_t virtfs_dir_lookup(struct sos_ 637 static sos_ret_t virtfs_dir_lookup(struct sos_fs_node *this,
665 const char 638 const char * name, sos_ui16_t namelen,
666 sos_ui64_t 639 sos_ui64_t * result_storage_location)
667 { 640 {
668 struct virtfs_node * virtfsnode = (struct vi 641 struct virtfs_node * virtfsnode = (struct virtfs_node*)this->custom_data;
669 struct virtfs_direntry * direntry; 642 struct virtfs_direntry * direntry;
670 int nbentries; 643 int nbentries;
671 644
672 list_foreach_forward_named(virtfsnode->dir.l 645 list_foreach_forward_named(virtfsnode->dir.list_entries,
673 direntry, nbentri 646 direntry, nbentries,
674 sibling_prev, sib 647 sibling_prev, sibling_next)
675 { 648 {
676 if (!memcmp(name, direntry->name, namele 649 if (!memcmp(name, direntry->name, namelen) && !direntry->name[namelen])
677 { 650 {
678 *result_storage_location = direntry- 651 *result_storage_location = direntry->fsnode->storage_location;
679 return SOS_OK; 652 return SOS_OK;
680 } 653 }
681 } 654 }
682 655
683 return -SOS_ENOENT; 656 return -SOS_ENOENT;
684 } 657 }
685 658
686 659
687 static sos_ret_t virtfs_link(struct sos_fs_nod 660 static sos_ret_t virtfs_link(struct sos_fs_node *this,
688 const struct sos_ 661 const struct sos_process *actor,
689 const char * entr 662 const char * entry_name, sos_ui16_t entry_namelen,
690 struct sos_fs_nod 663 struct sos_fs_node * node)
691 { 664 {
692 struct virtfs_node * parent = (struct virtfs 665 struct virtfs_node * parent = (struct virtfs_node*)this->custom_data;
693 struct virtfs_direntry * direntry; 666 struct virtfs_direntry * direntry;
694 667
695 direntry = (struct virtfs_direntry*)sos_kmal 668 direntry = (struct virtfs_direntry*)sos_kmalloc(sizeof(*direntry), 0);
696 if (! direntry) 669 if (! direntry)
697 return -SOS_ENOMEM; 670 return -SOS_ENOMEM;
698 671
699 direntry->name = (char*)sos_kmalloc(entry_na 672 direntry->name = (char*)sos_kmalloc(entry_namelen + 1, 0);
700 if (! direntry->name) 673 if (! direntry->name)
701 { 674 {
702 sos_kfree((sos_vaddr_t)direntry->name); 675 sos_kfree((sos_vaddr_t)direntry->name);
703 return -SOS_ENOMEM; 676 return -SOS_ENOMEM;
704 } 677 }
705 678
706 memcpy(direntry->name, entry_name, entry_nam 679 memcpy(direntry->name, entry_name, entry_namelen);
707 direntry->name[entry_namelen] = '\0'; 680 direntry->name[entry_namelen] = '\0';
708 681
709 direntry->fsnode = node; 682 direntry->fsnode = node;
710 node->ondisk_lnk_cnt ++; 683 node->ondisk_lnk_cnt ++;
711 this->ondisk_lnk_cnt ++; 684 this->ondisk_lnk_cnt ++;
712 list_add_tail_named(parent->dir.list_entries 685 list_add_tail_named(parent->dir.list_entries, direntry,
713 sibling_prev, sibling_ne 686 sibling_prev, sibling_next);
714 687
715 688
716 689
717 parent->dir.top_creation_order ++; 690 parent->dir.top_creation_order ++;
718 direntry->creation_order = parent->dir.top_c 691 direntry->creation_order = parent->dir.top_creation_order;
719 692
720 return SOS_OK; 693 return SOS_OK;
721 } 694 }
722 695
723 696
724 static sos_ret_t 697 static sos_ret_t
725 virtfs_unlink(struct sos_fs_node *this, 698 virtfs_unlink(struct sos_fs_node *this,
726 const struct sos_process *actor, 699 const struct sos_process *actor,
727 const char * entry_name, sos_ui1 700 const char * entry_name, sos_ui16_t entry_namelen)
728 { 701 {
729 struct virtfs_node * parent = (struct virtfs 702 struct virtfs_node * parent = (struct virtfs_node*)this->custom_data;
730 struct virtfs_direntry * direntry; 703 struct virtfs_direntry * direntry;
731 int nbentries; 704 int nbentries;
732 705
733 list_foreach_forward_named(parent->dir.list_ 706 list_foreach_forward_named(parent->dir.list_entries,
734 direntry, nbentri 707 direntry, nbentries,
735 sibling_prev, sib 708 sibling_prev, sibling_next)
736 { 709 {
737 if (!memcmp(entry_name, direntry->name, 710 if (!memcmp(entry_name, direntry->name, entry_namelen)
738 && !direntry->name[entry_namelen]) 711 && !direntry->name[entry_namelen])
739 { 712 {
740 list_delete_named(parent->dir.list_e 713 list_delete_named(parent->dir.list_entries, direntry,
741 sibling_prev, sibl 714 sibling_prev, sibling_next);
742 direntry->fsnode->ondisk_lnk_cnt --; 715 direntry->fsnode->ondisk_lnk_cnt --;
743 this->ondisk_lnk_cnt --; 716 this->ondisk_lnk_cnt --;
744 sos_kfree((sos_vaddr_t)direntry); 717 sos_kfree((sos_vaddr_t)direntry);
745 return SOS_OK; 718 return SOS_OK;
746 } 719 }
747 } 720 }
748 721
749 return -SOS_ENOENT; 722 return -SOS_ENOENT;
750 } 723 }
751 724
752 725
753 static struct sos_fs_node_ops_dir virtfs_ops_d 726 static struct sos_fs_node_ops_dir virtfs_ops_dir
754 = (struct sos_fs_node_ops_dir){ 727 = (struct sos_fs_node_ops_dir){
755 .lookup = virtfs_dir_lookup, 728 .lookup = virtfs_dir_lookup,
756 .link = virtfs_link, 729 .link = virtfs_link,
757 .unlink = virtfs_unlink 730 .unlink = virtfs_unlink
758 }; 731 };
759 732
760 733
761 734
762 735
763 736
764 737
765 738
766 739
767 740
768 741
769 742
770 static sos_ret_t 743 static sos_ret_t
771 virtfs_fetch_node_from_disk(struct sos_fs_mana 744 virtfs_fetch_node_from_disk(struct sos_fs_manager_instance * this,
772 sos_ui64_t storage 745 sos_ui64_t storage_location,
773 struct sos_fs_node 746 struct sos_fs_node ** result)
774 { 747 {
775 748
776 struct virtfs_node * virtfsnode; 749 struct virtfs_node * virtfsnode;
777 750
778 virtfsnode = (struct virtfs_node *)((sos_vad 751 virtfsnode = (struct virtfs_node *)((sos_vaddr_t)storage_location);
779 *result = & virtfsnode->super; 752 *result = & virtfsnode->super;
780 753
781 return SOS_OK; 754 return SOS_OK;
782 } 755 }
783 756
784 757
785 static sos_ret_t 758 static sos_ret_t
786 virtfs_allocate_new_node(struct sos_fs_manager 759 virtfs_allocate_new_node(struct sos_fs_manager_instance * this,
787 sos_fs_node_type_t ty 760 sos_fs_node_type_t type,
788 const struct sos_proc 761 const struct sos_process * creator,
789 sos_ui32_t access_rig 762 sos_ui32_t access_rights,
790 sos_ui32_t flags, 763 sos_ui32_t flags,
791 struct sos_fs_node ** 764 struct sos_fs_node ** result)
792 { 765 {
793 struct virtfs_node * virtfsnode; 766 struct virtfs_node * virtfsnode;
794 767
795 !! 768
796 if ((type != SOS_FS_NODE_REGULAR_FILE) 769 if ((type != SOS_FS_NODE_REGULAR_FILE)
797 && (type != SOS_FS_NODE_SYMLINK) 770 && (type != SOS_FS_NODE_SYMLINK)
798 && (type != SOS_FS_NODE_DIRECTORY) !! 771 && (type != SOS_FS_NODE_DIRECTORY))
799 && (type != SOS_FS_NODE_DEVICE_CHAR) <<
800 && (type != SOS_FS_NODE_DEVICE_BLOCK)) <<
801 return -SOS_ENOSUP; 772 return -SOS_ENOSUP;
802 773
803 virtfsnode = (struct virtfs_node*) sos_kmall 774 virtfsnode = (struct virtfs_node*) sos_kmalloc(sizeof(*virtfsnode), 0);
804 if (! virtfsnode) 775 if (! virtfsnode)
805 return -SOS_ENOMEM; 776 return -SOS_ENOMEM;
806 777
807 memset(virtfsnode, 0x0, sizeof(*virtfsnode)) 778 memset(virtfsnode, 0x0, sizeof(*virtfsnode));
808 *result = & virtfsnode->super; 779 *result = & virtfsnode->super;
809 780
810 781
811 (*result)->inmem_ref_cnt = 1; 782 (*result)->inmem_ref_cnt = 1;
812 (*result)->custom_data = virtfsnode; 783 (*result)->custom_data = virtfsnode;
813 (*result)->storage_location = (sos_ui64_t)( 784 (*result)->storage_location = (sos_ui64_t)((sos_vaddr_t)virtfsnode);
814 (*result)->type = type; 785 (*result)->type = type;
815 (*result)->access_rights = access_rights 786 (*result)->access_rights = access_rights;
816 (*result)->destructor = virtfs_node_d 787 (*result)->destructor = virtfs_node_destructor;
>> 788 (*result)->new_opened_file = virtfs_new_opened_file;
>> 789 (*result)->close_opened_file = virtfs_close_opened_file;
817 (*result)->ops_file = & virtfs_ops_ 790 (*result)->ops_file = & virtfs_ops_file;
818 <<
819 <<
820 <<
821 if ((type != SOS_FS_NODE_DEVICE_CHAR) <<
822 && (type != SOS_FS_NODE_DEVICE_BLOCK)) <<
823 { <<
824 (*result)->new_opened_file = virtfs_ne <<
825 (*result)->close_opened_file = virtfs_cl <<
826 } <<
827 <<
828 if (type == SOS_FS_NODE_SYMLINK) 791 if (type == SOS_FS_NODE_SYMLINK)
829 (*result)->ops_symlink = & virtfs_ops_syml 792 (*result)->ops_symlink = & virtfs_ops_symlink;
830 else if (type == SOS_FS_NODE_DIRECTORY) 793 else if (type == SOS_FS_NODE_DIRECTORY)
831 (*result)->ops_dir = & virtfs_ops_dir; 794 (*result)->ops_dir = & virtfs_ops_dir;
832 795
833 796
834 if (type == SOS_FS_NODE_REGULAR_FILE) 797 if (type == SOS_FS_NODE_REGULAR_FILE)
835 { 798 {
836 virtfsnode->file.mapres.allowed_access_r 799 virtfsnode->file.mapres.allowed_access_rights
837 = SOS_VM_MAP_PROT_READ 800 = SOS_VM_MAP_PROT_READ
838 | SOS_VM_MAP_PROT_WRITE 801 | SOS_VM_MAP_PROT_WRITE
839 | SOS_VM_MAP_PROT_EXEC; 802 | SOS_VM_MAP_PROT_EXEC;
840 virtfsnode->file.mapres.custom_data = 803 virtfsnode->file.mapres.custom_data = virtfsnode;
841 virtfsnode->file.mapres.mmap = 804 virtfsnode->file.mapres.mmap = virtfs_new_mapping;
842 } 805 }
843 806
844 list_add_tail(((struct virtfs_instance*)this 807 list_add_tail(((struct virtfs_instance*)this->custom_data)->list_fsnodes,
845 virtfsnode); 808 virtfsnode);
846 809
847 return SOS_OK; 810 return SOS_OK;
848 } 811 }
849 812
850 813
851 814
852 815
853 816
854 817
855 static sos_ret_t virtfs_mount(struct sos_fs_ma 818 static sos_ret_t virtfs_mount(struct sos_fs_manager_type * this,
856 struct sos_fs_no 819 struct sos_fs_node * device,
857 const char * arg 820 const char * args,
858 struct sos_fs_ma 821 struct sos_fs_manager_instance ** mounted_fs)
859 { 822 {
860 sos_ret_t retval; 823 sos_ret_t retval;
861 struct virtfs_instance * fs; 824 struct virtfs_instance * fs;
862 struct sos_fs_node * fsnode_root; 825 struct sos_fs_node * fsnode_root;
863 struct sos_hash_table * hash; 826 struct sos_hash_table * hash;
864 827
865 *mounted_fs = (struct sos_fs_manager_instanc 828 *mounted_fs = (struct sos_fs_manager_instance*)NULL;
866 829
867 830
868 hash = sos_hash_create("virtfs H", struct so 831 hash = sos_hash_create("virtfs H", struct sos_fs_node,
869 sos_hash_ui64, 832 sos_hash_ui64,
870 sos_hash_key_eq_ui64, 833 sos_hash_key_eq_ui64, 17,
871 storage_location, hli 834 storage_location, hlink_nodecache);
872 if (! hash) 835 if (! hash)
873 return -SOS_ENOMEM; 836 return -SOS_ENOMEM;
874 837
875 fs = (struct virtfs_instance*) 838 fs = (struct virtfs_instance*)
876 sos_kmalloc(sizeof(struct virtfs_instance) 839 sos_kmalloc(sizeof(struct virtfs_instance), 0);
877 if (! fs) 840 if (! fs)
878 { 841 {
879 sos_hash_dispose(hash); 842 sos_hash_dispose(hash);
880 return -SOS_ENOMEM; 843 return -SOS_ENOMEM;
881 } 844 }
882 845
883 memset(fs, 0x0, sizeof(struct virtfs_instanc 846 memset(fs, 0x0, sizeof(struct virtfs_instance));
884 retval = sos_kmutex_init(& fs->lock, "virtfs 847 retval = sos_kmutex_init(& fs->lock, "virtfs", SOS_KWQ_ORDER_FIFO);
885 if (SOS_OK != retval) 848 if (SOS_OK != retval)
886 { 849 {
887 sos_hash_dispose(hash); 850 sos_hash_dispose(hash);
888 sos_kfree((sos_vaddr_t) fs); 851 sos_kfree((sos_vaddr_t) fs);
889 return retval; 852 return retval;
890 } 853 }
891 fs->super.custom_data = fs; 854 fs->super.custom_data = fs;
892 fs->super.fs_type = this; 855 fs->super.fs_type = this;
893 fs->super.allocate_new_node = virtfs_allo 856 fs->super.allocate_new_node = virtfs_allocate_new_node;
894 fs->super.fetch_node_from_disk = virtfs_fetc 857 fs->super.fetch_node_from_disk = virtfs_fetch_node_from_disk;
895 fs->super.nodecache = hash; 858 fs->super.nodecache = hash;
896 859
897 retval = virtfs_allocate_new_node(& fs->supe 860 retval = virtfs_allocate_new_node(& fs->super, SOS_FS_NODE_DIRECTORY,
898 NULL, 861 NULL,
899 SOS_FS_REA 862 SOS_FS_READABLE | SOS_FS_WRITABLE
900 | SOS_FS_E 863 | SOS_FS_EXECUTABLE,
901 0, 864 0,
902 & fsnode_r 865 & fsnode_root);
903 if (SOS_OK != retval) 866 if (SOS_OK != retval)
904 { 867 {
905 sos_hash_dispose(hash); 868 sos_hash_dispose(hash);
906 sos_kmutex_dispose(& fs->lock); 869 sos_kmutex_dispose(& fs->lock);
907 sos_kfree((sos_vaddr_t) fs); 870 sos_kfree((sos_vaddr_t) fs);
908 return retval; 871 return retval;
909 } 872 }
910 873
911 retval = sos_fs_register_fs_instance(& fs->s 874 retval = sos_fs_register_fs_instance(& fs->super, fsnode_root);
912 sos_fs_unref_fsnode(fsnode_root); 875 sos_fs_unref_fsnode(fsnode_root);
913 if (SOS_OK != retval) 876 if (SOS_OK != retval)
914 { 877 {
915 sos_hash_dispose(hash); 878 sos_hash_dispose(hash);
916 sos_kmutex_dispose(& fs->lock); 879 sos_kmutex_dispose(& fs->lock);
917 sos_kfree((sos_vaddr_t) fs); 880 sos_kfree((sos_vaddr_t) fs);
918 return retval; 881 return retval;
919 } 882 }
920 883
921 *mounted_fs = & fs->super; 884 *mounted_fs = & fs->super;
922 return SOS_OK; 885 return SOS_OK;
923 } 886 }
924 887
925 888
926 static sos_ret_t virtfs_umount(struct sos_fs_m 889 static sos_ret_t virtfs_umount(struct sos_fs_manager_type * this,
927 struct sos_fs_m 890 struct sos_fs_manager_instance * mounted_fs)
928 { 891 {
929 struct virtfs_instance * virtfs = (struct vi 892 struct virtfs_instance * virtfs = (struct virtfs_instance*)mounted_fs->custom_data;
930 893
931 sos_hash_dispose(virtfs->super.nodecache); 894 sos_hash_dispose(virtfs->super.nodecache);
932 while (! list_is_empty(virtfs->list_fsnodes) 895 while (! list_is_empty(virtfs->list_fsnodes))
933 { 896 {
934 struct virtfs_node * virtfsnode = list_p 897 struct virtfs_node * virtfsnode = list_pop_head(virtfs->list_fsnodes);
935 898
936 if (virtfsnode->super.type == SOS_FS_NOD 899 if (virtfsnode->super.type == SOS_FS_NODE_REGULAR_FILE)
937 { 900 {
938 if (virtfsnode->file.size > 0) 901 if (virtfsnode->file.size > 0)
939 sos_kfree((sos_vaddr_t) virtfsnode 902 sos_kfree((sos_vaddr_t) virtfsnode->file.data);
940 } 903 }
941 else if (virtfsnode->super.type == SOS_F 904 else if (virtfsnode->super.type == SOS_FS_NODE_DIRECTORY)
942 { 905 {
943 while (! list_is_empty_named(virtfsn 906 while (! list_is_empty_named(virtfsnode->dir.list_entries,
944 sibling 907 sibling_prev, sibling_next))
945 { 908 {
946 struct virtfs_direntry * direntr 909 struct virtfs_direntry * direntry
947 = list_pop_head_named(virtfsno 910 = list_pop_head_named(virtfsnode->dir.list_entries,
948 sibling_ 911 sibling_prev, sibling_next);
949 912
950 sos_kfree((sos_vaddr_t)direntry- 913 sos_kfree((sos_vaddr_t)direntry->name);
951 sos_kfree((sos_vaddr_t)direntry) 914 sos_kfree((sos_vaddr_t)direntry);
952 } 915 }
953 } 916 }
954 917
955 sos_kfree((sos_vaddr_t)virtfsnode); 918 sos_kfree((sos_vaddr_t)virtfsnode);
956 } 919 }
957 920
958 sos_fs_unregister_fs_instance(& virtfs->supe 921 sos_fs_unregister_fs_instance(& virtfs->super);
959 sos_kmutex_dispose(& virtfs->lock); 922 sos_kmutex_dispose(& virtfs->lock);
960 sos_kfree((sos_vaddr_t)virtfs); 923 sos_kfree((sos_vaddr_t)virtfs);
961 return SOS_OK; 924 return SOS_OK;
962 } 925 }
963 926
964 927
965 928
966 929
967 930
968 inline static struct virtfs_node * 931 inline static struct virtfs_node *
969 get_virtfsnode_of_vr(struct sos_umem_vmm_vr * 932 get_virtfsnode_of_vr(struct sos_umem_vmm_vr * vr)
970 { 933 {
971 struct sos_umem_vmm_mapped_resource *mr 934 struct sos_umem_vmm_mapped_resource *mr
972 = sos_umem_vmm_get_mapped_resource_of_vr(v 935 = sos_umem_vmm_get_mapped_resource_of_vr(vr);
973 936
974 return (struct virtfs_node *)mr->custom_data 937 return (struct virtfs_node *)mr->custom_data;
975 } 938 }
976 939
977 940
978 static void virtfs_map_ref(struct sos_umem_vmm 941 static void virtfs_map_ref(struct sos_umem_vmm_vr * vr)
979 { 942 {
980 struct virtfs_node * virtfsnode = get_virtfs 943 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
981 sos_fs_ref_fsnode(& virtfsnode->super); 944 sos_fs_ref_fsnode(& virtfsnode->super);
982 virtfsnode->file.num_mappings ++; 945 virtfsnode->file.num_mappings ++;
983 } 946 }
984 947
985 948
986 static void virtfs_map_unref(struct sos_umem_v 949 static void virtfs_map_unref(struct sos_umem_vmm_vr * vr)
987 { 950 {
988 struct virtfs_node * virtfsnode = get_virtfs 951 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
989 952
990 SOS_ASSERT_FATAL(virtfsnode->file.num_mappin 953 SOS_ASSERT_FATAL(virtfsnode->file.num_mappings > 0);
991 virtfsnode->file.num_mappings --; 954 virtfsnode->file.num_mappings --;
992 955
993 _sos_fs_unref_fsnode(& virtfsnode->super); 956 _sos_fs_unref_fsnode(& virtfsnode->super);
994 } 957 }
995 958
996 959
997 static sos_ret_t virtfs_map_page_in(struct sos 960 static sos_ret_t virtfs_map_page_in(struct sos_umem_vmm_vr * vr,
998 sos_uaddr_ 961 sos_uaddr_t uaddr,
999 sos_bool_t 962 sos_bool_t write_access)
1000 { 963 {
1001 struct virtfs_node * virtfsnode = get_virtf 964 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
1002 sos_luoffset_t offset = uaddr - sos_umem_vm 965 sos_luoffset_t offset = uaddr - sos_umem_vmm_get_start_of_vr(vr);
1003 sos_ret_t retval = SOS_OK; 966 sos_ret_t retval = SOS_OK;
1004 sos_paddr_t ppage_paddr; 967 sos_paddr_t ppage_paddr;
1005 968
1006 969
1007 if (SOS_PAGE_ALIGN_SUP(offset) > virtfsnode 970 if (SOS_PAGE_ALIGN_SUP(offset) > virtfsnode->file.size)
1008 return -SOS_EFAULT; 971 return -SOS_EFAULT;
1009 972
1010 973
1011 ppage_paddr = sos_paging_get_paddr(SOS_PAGE 974 ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ALIGN_INF(virtfsnode->file.data
1012 975 + offset));
1013 976
1014 977
1015 if (! ppage_paddr) 978 if (! ppage_paddr)
1016 return -SOS_EFAULT; 979 return -SOS_EFAULT;
1017 980
1018 981
1019 retval = sos_paging_map(ppage_paddr, 982 retval = sos_paging_map(ppage_paddr,
1020 SOS_PAGE_ALIGN_INF( 983 SOS_PAGE_ALIGN_INF(uaddr),
1021 TRUE, 984 TRUE,
1022 sos_umem_vmm_get_pr 985 sos_umem_vmm_get_prot_of_vr(vr));
1023 986
1024 return retval; 987 return retval;
1025 } 988 }
1026 989
1027 990
1028 static struct sos_umem_vmm_vr_ops virtfs_map_ 991 static struct sos_umem_vmm_vr_ops virtfs_map_ops
1029 = (struct sos_umem_vmm_vr_ops){ 992 = (struct sos_umem_vmm_vr_ops){
1030 .ref = virtfs_map_ref, 993 .ref = virtfs_map_ref,
1031 .unref = virtfs_map_unref, 994 .unref = virtfs_map_unref,
1032 .page_in = virtfs_map_page_in 995 .page_in = virtfs_map_page_in
1033 }; 996 };
1034 997
1035 static sos_ret_t virtfs_new_mapping(struct so 998 static sos_ret_t virtfs_new_mapping(struct sos_umem_vmm_vr *vr)
1036 { 999 {
1037 struct virtfs_node * virtfsnode = get_virtf 1000 struct virtfs_node * virtfsnode = get_virtfsnode_of_vr(vr);
1038 sos_size_t reqsize; 1001 sos_size_t reqsize;
1039 sos_ret_t retval; 1002 sos_ret_t retval;
1040 1003
1041 reqsize = sos_umem_vmm_get_offset_in_resou 1004 reqsize = sos_umem_vmm_get_offset_in_resource(vr);
1042 reqsize += sos_umem_vmm_get_size_of_vr(vr); 1005 reqsize += sos_umem_vmm_get_size_of_vr(vr);
1043 1006
1044 1007
1045 if (reqsize > virtfsnode->file.size) 1008 if (reqsize > virtfsnode->file.size)
1046 { 1009 {
1047 retval = virtfs_resize(virtfsnode, 1010 retval = virtfs_resize(virtfsnode,
1048 SOS_PAGE_ALIGN_S 1011 SOS_PAGE_ALIGN_SUP(reqsize));
1049 if (SOS_OK != retval) 1012 if (SOS_OK != retval)
1050 return retval; 1013 return retval;
1051 } 1014 }
1052 1015
1053 return sos_umem_vmm_set_ops_of_vr(vr, &virt 1016 return sos_umem_vmm_set_ops_of_vr(vr, &virtfs_map_ops);
1054 } 1017 }