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