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