6 static int fsdriver_vmcache
; /* have we used the VM cache? */
9 * Process a READSUPER request from VFS.
12 fsdriver_readsuper(const struct fsdriver
* __restrict fdp
,
13 const message
* __restrict m_in
, message
* __restrict m_out
)
15 struct fsdriver_node root_node
;
16 char label
[DS_MAX_KEYLEN
];
17 cp_grant_id_t label_grant
;
19 unsigned int flags
, res_flags
;
23 dev
= m_in
->m_vfs_fs_readsuper
.device
;
24 label_grant
= m_in
->m_vfs_fs_readsuper
.grant
;
25 label_len
= m_in
->m_vfs_fs_readsuper
.path_len
;
26 flags
= m_in
->m_vfs_fs_readsuper
.flags
;
28 if (fdp
->fdr_mount
== NULL
)
31 if (fsdriver_mounted
) {
32 printf("fsdriver: attempt to mount multiple times\n");
36 if ((r
= fsdriver_getname(m_in
->m_source
, label_grant
, label_len
,
37 label
, sizeof(label
), FALSE
/*not_empty*/)) != OK
)
40 if (fdp
->fdr_driver
!= NULL
)
41 fdp
->fdr_driver(dev
, label
);
43 res_flags
= RES_NOFLAGS
;
45 r
= fdp
->fdr_mount(dev
, flags
, &root_node
, &res_flags
);
48 /* This one we can set on the file system's behalf. */
49 if ((fdp
->fdr_peek
!= NULL
&& fdp
->fdr_bpeek
!= NULL
) ||
50 major(dev
) == NONE_MAJOR
)
51 res_flags
|= RES_HASPEEK
;
53 m_out
->m_fs_vfs_readsuper
.inode
= root_node
.fn_ino_nr
;
54 m_out
->m_fs_vfs_readsuper
.mode
= root_node
.fn_mode
;
55 m_out
->m_fs_vfs_readsuper
.file_size
= root_node
.fn_size
;
56 m_out
->m_fs_vfs_readsuper
.uid
= root_node
.fn_uid
;
57 m_out
->m_fs_vfs_readsuper
.gid
= root_node
.fn_gid
;
58 m_out
->m_fs_vfs_readsuper
.flags
= res_flags
;
60 /* Update library-local state. */
61 fsdriver_mounted
= TRUE
;
62 fsdriver_device
= dev
;
63 fsdriver_root
= root_node
.fn_ino_nr
;
64 fsdriver_vmcache
= FALSE
;
71 * Process an UNMOUNT request from VFS.
74 fsdriver_unmount(const struct fsdriver
* __restrict fdp
,
75 const message
* __restrict __unused m_in
,
76 message
* __restrict __unused m_out
)
79 if (fdp
->fdr_unmount
!= NULL
)
82 /* If we used mmap emulation, clear any cached blocks from VM. */
84 vm_clear_cache(fsdriver_device
);
86 /* Update library-local state. */
87 fsdriver_mounted
= FALSE
;
93 * Process a PUTNODE request from VFS.
96 fsdriver_putnode(const struct fsdriver
* __restrict fdp
,
97 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
102 ino_nr
= m_in
->m_vfs_fs_putnode
.inode
;
103 count
= m_in
->m_vfs_fs_putnode
.count
;
105 if (count
== 0 || count
> INT_MAX
) {
106 printf("fsdriver: invalid reference count\n");
110 if (fdp
->fdr_putnode
!= NULL
)
111 return fdp
->fdr_putnode(ino_nr
, count
);
117 * Process a NEWNODE request from VFS.
120 fsdriver_newnode(const struct fsdriver
* __restrict fdp
,
121 const message
* __restrict m_in
, message
* __restrict m_out
)
123 struct fsdriver_node node
;
130 mode
= m_in
->m_vfs_fs_newnode
.mode
;
131 uid
= m_in
->m_vfs_fs_newnode
.uid
;
132 gid
= m_in
->m_vfs_fs_newnode
.gid
;
133 dev
= m_in
->m_vfs_fs_newnode
.device
;
135 if (fdp
->fdr_newnode
== NULL
)
138 if ((r
= fdp
->fdr_newnode(mode
, uid
, gid
, dev
, &node
)) == OK
) {
139 m_out
->m_fs_vfs_newnode
.inode
= node
.fn_ino_nr
;
140 m_out
->m_fs_vfs_newnode
.mode
= node
.fn_mode
;
141 m_out
->m_fs_vfs_newnode
.file_size
= node
.fn_size
;
142 m_out
->m_fs_vfs_newnode
.uid
= node
.fn_uid
;
143 m_out
->m_fs_vfs_newnode
.gid
= node
.fn_gid
;
144 m_out
->m_fs_vfs_newnode
.device
= node
.fn_dev
;
151 * Process a read or write request from VFS.
154 read_write(const struct fsdriver
* __restrict fdp
,
155 const message
* __restrict m_in
, message
* __restrict m_out
, int call
)
157 struct fsdriver_data data
;
163 ino_nr
= m_in
->m_vfs_fs_readwrite
.inode
;
164 pos
= m_in
->m_vfs_fs_readwrite
.seek_pos
;
165 nbytes
= m_in
->m_vfs_fs_readwrite
.nbytes
;
167 if (pos
< 0 || nbytes
> SSIZE_MAX
)
170 data
.endpt
= m_in
->m_source
;
171 data
.grant
= m_in
->m_vfs_fs_readwrite
.grant
;
174 if (call
== FSC_WRITE
)
175 r
= fdp
->fdr_write(ino_nr
, &data
, nbytes
, pos
, call
);
177 r
= fdp
->fdr_read(ino_nr
, &data
, nbytes
, pos
, call
);
182 m_out
->m_fs_vfs_readwrite
.seek_pos
= pos
;
183 m_out
->m_fs_vfs_readwrite
.nbytes
= r
;
191 * Process a READ request from VFS.
194 fsdriver_read(const struct fsdriver
* __restrict fdp
,
195 const message
* __restrict m_in
, message
* __restrict m_out
)
198 if (fdp
->fdr_read
== NULL
)
201 return read_write(fdp
, m_in
, m_out
, FSC_READ
);
205 * Process a WRITE request from VFS.
208 fsdriver_write(const struct fsdriver
* __restrict fdp
,
209 const message
* __restrict m_in
, message
* __restrict m_out
)
212 if (fdp
->fdr_write
== NULL
)
215 return read_write(fdp
, m_in
, m_out
, FSC_WRITE
);
219 * A read-based peek implementation. This allows file systems that do not have
220 * a buffer cache and do not implement peek, to support a limited form of mmap.
221 * We map in a block, fill it by calling the file system's read function, tell
222 * VM about the page, and then unmap the block again. We tell VM not to cache
223 * the block beyond its immediate use for the mmap request, so as to prevent
224 * potentially stale data from being cached--at the cost of performance.
227 builtin_peek(const struct fsdriver
* __restrict fdp
, ino_t ino_nr
,
228 size_t nbytes
, off_t pos
)
230 static u32_t flags
= 0; /* storage for the VMMC_ flags of all blocks */
231 static off_t dev_off
= 0; /* fake device offset, see below */
232 struct fsdriver_data data
;
236 if ((buf
= mmap(NULL
, nbytes
, PROT_READ
| PROT_WRITE
,
237 MAP_ANON
| MAP_PRIVATE
, -1, 0)) == MAP_FAILED
)
241 data
.grant
= (cp_grant_id_t
)buf
;
244 r
= fdp
->fdr_read(ino_nr
, &data
, nbytes
, pos
, FSC_READ
);
247 if ((size_t)r
< nbytes
)
248 memset(&buf
[r
], 0, nbytes
- r
);
251 * VM uses serialized communication to VFS. Since the page is
252 * to be used only once, VM will use and then discard it before
253 * sending a new peek request. Thus, it should be safe to
254 * reuse the same device offset all the time. However, relying
255 * on assumptions in protocols elsewhere a bit dangerous, so we
256 * use an ever-increasing device offset just to be safe.
258 r
= vm_set_cacheblock(buf
, fsdriver_device
, dev_off
, ino_nr
,
259 pos
, &flags
, nbytes
, VMSF_ONCE
);
262 fsdriver_vmcache
= TRUE
;
276 * Process a PEEK request from VFS.
279 fsdriver_peek(const struct fsdriver
* __restrict fdp
,
280 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
287 ino_nr
= m_in
->m_vfs_fs_readwrite
.inode
;
288 pos
= m_in
->m_vfs_fs_readwrite
.seek_pos
;
289 nbytes
= m_in
->m_vfs_fs_readwrite
.nbytes
;
291 if (pos
< 0 || nbytes
> SSIZE_MAX
)
294 if (fdp
->fdr_peek
== NULL
) {
295 if (major(fsdriver_device
) != NONE_MAJOR
)
299 * For file systems that have no backing device, emulate peek
300 * support by reading into temporary buffers and passing these
303 r
= builtin_peek(fdp
, ino_nr
, nbytes
, pos
);
305 r
= fdp
->fdr_peek(ino_nr
, NULL
/*data*/, nbytes
, pos
,
308 /* Do not return a new position. */
310 m_out
->m_fs_vfs_readwrite
.nbytes
= r
;
318 * Process a GETDENTS request from VFS.
321 fsdriver_getdents(const struct fsdriver
* __restrict fdp
,
322 const message
* __restrict m_in
, message
* __restrict m_out
)
324 struct fsdriver_data data
;
330 ino_nr
= m_in
->m_vfs_fs_getdents
.inode
;
331 pos
= m_in
->m_vfs_fs_getdents
.seek_pos
;
332 nbytes
= m_in
->m_vfs_fs_getdents
.mem_size
;
334 if (fdp
->fdr_getdents
== NULL
)
337 if (pos
< 0 || nbytes
> SSIZE_MAX
)
340 data
.endpt
= m_in
->m_source
;
341 data
.grant
= m_in
->m_vfs_fs_getdents
.grant
;
344 r
= fdp
->fdr_getdents(ino_nr
, &data
, nbytes
, &pos
);
347 m_out
->m_fs_vfs_getdents
.seek_pos
= pos
;
348 m_out
->m_fs_vfs_getdents
.nbytes
= r
;
356 * Process a FTRUNC request from VFS.
359 fsdriver_trunc(const struct fsdriver
* __restrict fdp
,
360 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
363 off_t start_pos
, end_pos
;
365 ino_nr
= m_in
->m_vfs_fs_ftrunc
.inode
;
366 start_pos
= m_in
->m_vfs_fs_ftrunc
.trc_start
;
367 end_pos
= m_in
->m_vfs_fs_ftrunc
.trc_end
;
369 if (start_pos
< 0 || end_pos
< 0)
372 if (fdp
->fdr_trunc
== NULL
)
375 return fdp
->fdr_trunc(ino_nr
, start_pos
, end_pos
);
379 * Process a INHIBREAD request from VFS.
382 fsdriver_inhibread(const struct fsdriver
* __restrict fdp
,
383 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
387 ino_nr
= m_in
->m_vfs_fs_inhibread
.inode
;
389 if (fdp
->fdr_seek
!= NULL
)
390 fdp
->fdr_seek(ino_nr
);
396 * Process a CREATE request from VFS.
399 fsdriver_create(const struct fsdriver
* __restrict fdp
,
400 const message
* __restrict m_in
, message
* __restrict m_out
)
402 struct fsdriver_node node
;
403 char name
[NAME_MAX
+1];
412 grant
= m_in
->m_vfs_fs_create
.grant
;
413 len
= m_in
->m_vfs_fs_create
.path_len
;
414 dir_nr
= m_in
->m_vfs_fs_create
.inode
;
415 mode
= m_in
->m_vfs_fs_create
.mode
;
416 uid
= m_in
->m_vfs_fs_create
.uid
;
417 gid
= m_in
->m_vfs_fs_create
.gid
;
419 if (fdp
->fdr_create
== NULL
)
422 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, len
, name
,
423 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
426 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
429 if ((r
= fdp
->fdr_create(dir_nr
, name
, mode
, uid
, gid
, &node
)) == OK
) {
430 m_out
->m_fs_vfs_create
.inode
= node
.fn_ino_nr
;
431 m_out
->m_fs_vfs_create
.mode
= node
.fn_mode
;
432 m_out
->m_fs_vfs_create
.file_size
= node
.fn_size
;
433 m_out
->m_fs_vfs_create
.uid
= node
.fn_uid
;
434 m_out
->m_fs_vfs_create
.gid
= node
.fn_gid
;
441 * Process a MKDIR request from VFS.
444 fsdriver_mkdir(const struct fsdriver
* __restrict fdp
,
445 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
447 char name
[NAME_MAX
+1];
456 grant
= m_in
->m_vfs_fs_mkdir
.grant
;
457 path_len
= m_in
->m_vfs_fs_mkdir
.path_len
;
458 dir_nr
= m_in
->m_vfs_fs_mkdir
.inode
;
459 mode
= m_in
->m_vfs_fs_mkdir
.mode
;
460 uid
= m_in
->m_vfs_fs_mkdir
.uid
;
461 gid
= m_in
->m_vfs_fs_mkdir
.gid
;
463 if (fdp
->fdr_mkdir
== NULL
)
466 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
467 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
470 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
473 return fdp
->fdr_mkdir(dir_nr
, name
, mode
, uid
, gid
);
477 * Process a MKNOD request from VFS.
480 fsdriver_mknod(const struct fsdriver
* __restrict fdp
,
481 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
483 char name
[NAME_MAX
+1];
493 grant
= m_in
->m_vfs_fs_mknod
.grant
;
494 path_len
= m_in
->m_vfs_fs_mknod
.path_len
;
495 dir_nr
= m_in
->m_vfs_fs_mknod
.inode
;
496 mode
= m_in
->m_vfs_fs_mknod
.mode
;
497 uid
= m_in
->m_vfs_fs_mknod
.uid
;
498 gid
= m_in
->m_vfs_fs_mknod
.gid
;
499 dev
= m_in
->m_vfs_fs_mknod
.device
;
501 if (fdp
->fdr_mknod
== NULL
)
504 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
505 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
508 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
511 return fdp
->fdr_mknod(dir_nr
, name
, mode
, uid
, gid
, dev
);
515 * Process a LINK request from VFS.
518 fsdriver_link(const struct fsdriver
* __restrict fdp
,
519 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
521 char name
[NAME_MAX
+1];
524 ino_t dir_nr
, ino_nr
;
527 grant
= m_in
->m_vfs_fs_link
.grant
;
528 path_len
= m_in
->m_vfs_fs_link
.path_len
;
529 dir_nr
= m_in
->m_vfs_fs_link
.dir_ino
;
530 ino_nr
= m_in
->m_vfs_fs_link
.inode
;
532 if (fdp
->fdr_link
== NULL
)
535 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
536 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
539 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
542 return fdp
->fdr_link(dir_nr
, name
, ino_nr
);
546 * Process an UNLINK request from VFS.
549 fsdriver_unlink(const struct fsdriver
* __restrict fdp
,
550 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
552 char name
[NAME_MAX
+1];
558 grant
= m_in
->m_vfs_fs_unlink
.grant
;
559 path_len
= m_in
->m_vfs_fs_unlink
.path_len
;
560 dir_nr
= m_in
->m_vfs_fs_unlink
.inode
;
562 if (fdp
->fdr_unlink
== NULL
)
565 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
566 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
569 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
572 return fdp
->fdr_unlink(dir_nr
, name
, FSC_UNLINK
);
576 * Process a RMDIR request from VFS.
579 fsdriver_rmdir(const struct fsdriver
* __restrict fdp
,
580 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
582 char name
[NAME_MAX
+1];
588 grant
= m_in
->m_vfs_fs_unlink
.grant
;
589 path_len
= m_in
->m_vfs_fs_unlink
.path_len
;
590 dir_nr
= m_in
->m_vfs_fs_unlink
.inode
;
592 if (fdp
->fdr_rmdir
== NULL
)
595 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
596 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
599 if (!strcmp(name
, "."))
602 if (!strcmp(name
, ".."))
605 return fdp
->fdr_rmdir(dir_nr
, name
, FSC_RMDIR
);
609 * Process a RENAME request from VFS.
612 fsdriver_rename(const struct fsdriver
* __restrict fdp
,
613 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
615 char old_name
[NAME_MAX
+1], new_name
[NAME_MAX
+1];
616 cp_grant_id_t old_grant
, new_grant
;
617 size_t old_len
, new_len
;
618 ino_t old_dir_nr
, new_dir_nr
;
621 old_grant
= m_in
->m_vfs_fs_rename
.grant_old
;
622 old_len
= m_in
->m_vfs_fs_rename
.len_old
;
623 old_dir_nr
= m_in
->m_vfs_fs_rename
.dir_old
;
624 new_grant
= m_in
->m_vfs_fs_rename
.grant_new
;
625 new_len
= m_in
->m_vfs_fs_rename
.len_new
;
626 new_dir_nr
= m_in
->m_vfs_fs_rename
.dir_new
;
628 if (fdp
->fdr_rename
== NULL
)
631 if ((r
= fsdriver_getname(m_in
->m_source
, old_grant
, old_len
, old_name
,
632 sizeof(old_name
), TRUE
/*not_empty*/)) != OK
)
635 if (!strcmp(old_name
, ".") || !strcmp(old_name
, ".."))
638 if ((r
= fsdriver_getname(m_in
->m_source
, new_grant
, new_len
, new_name
,
639 sizeof(new_name
), TRUE
/*not_empty*/)) != OK
)
642 if (!strcmp(new_name
, ".") || !strcmp(new_name
, ".."))
645 return fdp
->fdr_rename(old_dir_nr
, old_name
, new_dir_nr
, new_name
);
649 * Process a SLINK request from VFS.
652 fsdriver_slink(const struct fsdriver
* __restrict fdp
,
653 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
655 struct fsdriver_data data
;
656 char name
[NAME_MAX
+1];
664 grant
= m_in
->m_vfs_fs_slink
.grant_path
;
665 path_len
= m_in
->m_vfs_fs_slink
.path_len
;
666 dir_nr
= m_in
->m_vfs_fs_slink
.inode
;
667 uid
= m_in
->m_vfs_fs_slink
.uid
;
668 gid
= m_in
->m_vfs_fs_slink
.gid
;
670 if (fdp
->fdr_slink
== NULL
)
673 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, name
,
674 sizeof(name
), TRUE
/*not_empty*/)) != OK
)
677 if (!strcmp(name
, ".") || !strcmp(name
, ".."))
680 data
.endpt
= m_in
->m_source
;
681 data
.grant
= m_in
->m_vfs_fs_slink
.grant_target
;
682 data
.size
= m_in
->m_vfs_fs_slink
.mem_size
;
684 return fdp
->fdr_slink(dir_nr
, name
, uid
, gid
, &data
, data
.size
);
688 * Process a RDLINK request from VFS.
691 fsdriver_rdlink(const struct fsdriver
* __restrict fdp
,
692 const message
* __restrict m_in
, message
* __restrict m_out
)
694 struct fsdriver_data data
;
697 if (fdp
->fdr_rdlink
== NULL
)
700 data
.endpt
= m_in
->m_source
;
701 data
.grant
= m_in
->m_vfs_fs_rdlink
.grant
;
702 data
.size
= m_in
->m_vfs_fs_rdlink
.mem_size
;
704 r
= fdp
->fdr_rdlink(m_in
->m_vfs_fs_rdlink
.inode
, &data
, data
.size
);
707 m_out
->m_fs_vfs_rdlink
.nbytes
= r
;
715 * Process a STAT request from VFS.
718 fsdriver_stat(const struct fsdriver
* __restrict fdp
,
719 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
726 ino_nr
= m_in
->m_vfs_fs_stat
.inode
;
727 grant
= m_in
->m_vfs_fs_stat
.grant
;
729 if (fdp
->fdr_stat
== NULL
)
732 memset(&buf
, 0, sizeof(buf
));
733 buf
.st_dev
= fsdriver_device
;
736 if ((r
= fdp
->fdr_stat(ino_nr
, &buf
)) == OK
)
737 r
= sys_safecopyto(m_in
->m_source
, grant
, 0, (vir_bytes
)&buf
,
738 (phys_bytes
)sizeof(buf
));
744 * Process a CHOWN request from VFS.
747 fsdriver_chown(const struct fsdriver
* __restrict fdp
,
748 const message
* __restrict m_in
, message
* __restrict m_out
)
756 ino_nr
= m_in
->m_vfs_fs_chown
.inode
;
757 uid
= m_in
->m_vfs_fs_chown
.uid
;
758 gid
= m_in
->m_vfs_fs_chown
.gid
;
760 if (fdp
->fdr_chown
== NULL
)
763 if ((r
= fdp
->fdr_chown(ino_nr
, uid
, gid
, &mode
)) == OK
)
764 m_out
->m_fs_vfs_chown
.mode
= mode
;
770 * Process a CHMOD request from VFS.
773 fsdriver_chmod(const struct fsdriver
* __restrict fdp
,
774 const message
* __restrict m_in
, message
* __restrict m_out
)
780 ino_nr
= m_in
->m_vfs_fs_chmod
.inode
;
781 mode
= m_in
->m_vfs_fs_chmod
.mode
;
783 if (fdp
->fdr_chmod
== NULL
)
786 if ((r
= fdp
->fdr_chmod(ino_nr
, &mode
)) == OK
)
787 m_out
->m_fs_vfs_chmod
.mode
= mode
;
793 * Process a UTIME request from VFS.
796 fsdriver_utime(const struct fsdriver
* __restrict fdp
,
797 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
800 struct timespec atime
, mtime
;
802 ino_nr
= m_in
->m_vfs_fs_utime
.inode
;
803 atime
.tv_sec
= m_in
->m_vfs_fs_utime
.actime
;
804 atime
.tv_nsec
= m_in
->m_vfs_fs_utime
.acnsec
;
805 mtime
.tv_sec
= m_in
->m_vfs_fs_utime
.modtime
;
806 mtime
.tv_nsec
= m_in
->m_vfs_fs_utime
.modnsec
;
808 if (fdp
->fdr_utime
== NULL
)
811 return fdp
->fdr_utime(ino_nr
, &atime
, &mtime
);
815 * Process a MOUNTPOINT request from VFS.
818 fsdriver_mountpoint(const struct fsdriver
* __restrict fdp
,
819 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
823 ino_nr
= m_in
->m_vfs_fs_mountpoint
.inode
;
825 if (fdp
->fdr_mountpt
== NULL
)
828 return fdp
->fdr_mountpt(ino_nr
);
832 * Process a STATVFS request from VFS.
835 fsdriver_statvfs(const struct fsdriver
* __restrict fdp
,
836 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
841 if (fdp
->fdr_statvfs
== NULL
)
844 memset(&buf
, 0, sizeof(buf
));
846 if ((r
= fdp
->fdr_statvfs(&buf
)) != OK
)
849 return sys_safecopyto(m_in
->m_source
, m_in
->m_vfs_fs_statvfs
.grant
, 0,
850 (vir_bytes
)&buf
, (phys_bytes
)sizeof(buf
));
854 * Process a SYNC request from VFS.
857 fsdriver_sync(const struct fsdriver
* __restrict fdp
,
858 const message
* __restrict __unused m_in
,
859 message
* __restrict __unused m_out
)
862 if (fdp
->fdr_sync
!= NULL
)
869 * Process a NEW_DRIVER request from VFS.
872 fsdriver_newdriver(const struct fsdriver
* __restrict fdp
,
873 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
875 char label
[DS_MAX_KEYLEN
];
881 dev
= m_in
->m_vfs_fs_new_driver
.device
;
882 grant
= m_in
->m_vfs_fs_new_driver
.grant
;
883 path_len
= m_in
->m_vfs_fs_new_driver
.path_len
;
885 if (fdp
->fdr_driver
== NULL
)
888 if ((r
= fsdriver_getname(m_in
->m_source
, grant
, path_len
, label
,
889 sizeof(label
), FALSE
/*not_empty*/)) != OK
)
892 fdp
->fdr_driver(dev
, label
);
898 * Process a block read or write request from VFS.
901 bread_bwrite(const struct fsdriver
* __restrict fdp
,
902 const message
* __restrict m_in
, message
* __restrict m_out
, int call
)
904 struct fsdriver_data data
;
910 dev
= m_in
->m_vfs_fs_breadwrite
.device
;
911 pos
= m_in
->m_vfs_fs_breadwrite
.seek_pos
;
912 nbytes
= m_in
->m_vfs_fs_breadwrite
.nbytes
;
914 if (pos
< 0 || nbytes
> SSIZE_MAX
)
917 data
.endpt
= m_in
->m_source
;
918 data
.grant
= m_in
->m_vfs_fs_breadwrite
.grant
;
921 if (call
== FSC_WRITE
)
922 r
= fdp
->fdr_bwrite(dev
, &data
, nbytes
, pos
, call
);
924 r
= fdp
->fdr_bread(dev
, &data
, nbytes
, pos
, call
);
929 m_out
->m_fs_vfs_breadwrite
.seek_pos
= pos
;
930 m_out
->m_fs_vfs_breadwrite
.nbytes
= r
;
938 * Process a BREAD request from VFS.
941 fsdriver_bread(const struct fsdriver
* __restrict fdp
,
942 const message
* __restrict m_in
, message
* __restrict m_out
)
945 if (fdp
->fdr_bread
== NULL
)
948 return bread_bwrite(fdp
, m_in
, m_out
, FSC_READ
);
952 * Process a BWRITE request from VFS.
955 fsdriver_bwrite(const struct fsdriver
* __restrict fdp
,
956 const message
* __restrict m_in
, message
* __restrict m_out
)
959 if (fdp
->fdr_bwrite
== NULL
)
962 return bread_bwrite(fdp
, m_in
, m_out
, FSC_WRITE
);
966 * Process a BPEEK request from VFS.
969 fsdriver_bpeek(const struct fsdriver
* __restrict fdp
,
970 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
977 dev
= m_in
->m_vfs_fs_breadwrite
.device
;
978 pos
= m_in
->m_vfs_fs_breadwrite
.seek_pos
;
979 nbytes
= m_in
->m_vfs_fs_breadwrite
.nbytes
;
981 if (fdp
->fdr_bpeek
== NULL
)
984 if (pos
< 0 || nbytes
> SSIZE_MAX
)
987 r
= fdp
->fdr_bpeek(dev
, NULL
/*data*/, nbytes
, pos
, FSC_PEEK
);
989 /* Do not return a new position. */
991 m_out
->m_fs_vfs_breadwrite
.nbytes
= r
;
999 * Process a FLUSH request from VFS.
1002 fsdriver_flush(const struct fsdriver
* __restrict fdp
,
1003 const message
* __restrict m_in
, message
* __restrict __unused m_out
)
1007 dev
= m_in
->m_vfs_fs_flush
.device
;
1009 if (fdp
->fdr_bflush
!= NULL
)
1010 fdp
->fdr_bflush(dev
);