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