189c9de7dSDavid van Moolenbroek
289c9de7dSDavid van Moolenbroek #include "fsdriver.h"
389c9de7dSDavid van Moolenbroek #include <minix/ds.h>
4e321f655SDavid van Moolenbroek #include <sys/mman.h>
589c9de7dSDavid van Moolenbroek
6*0a2a0873SDavid van Moolenbroek static int fsdriver_vmcache; /* have we used the VM cache? */
7*0a2a0873SDavid van Moolenbroek
889c9de7dSDavid van Moolenbroek /*
989c9de7dSDavid van Moolenbroek * Process a READSUPER request from VFS.
1089c9de7dSDavid van Moolenbroek */
1189c9de7dSDavid van Moolenbroek int
fsdriver_readsuper(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)1289c9de7dSDavid van Moolenbroek fsdriver_readsuper(const struct fsdriver * __restrict fdp,
1389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
1489c9de7dSDavid van Moolenbroek {
1589c9de7dSDavid van Moolenbroek struct fsdriver_node root_node;
1689c9de7dSDavid van Moolenbroek char label[DS_MAX_KEYLEN];
1789c9de7dSDavid van Moolenbroek cp_grant_id_t label_grant;
1889c9de7dSDavid van Moolenbroek size_t label_len;
1989c9de7dSDavid van Moolenbroek unsigned int flags, res_flags;
2089c9de7dSDavid van Moolenbroek dev_t dev;
2189c9de7dSDavid van Moolenbroek int r;
2289c9de7dSDavid van Moolenbroek
2389c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_readsuper.device;
2489c9de7dSDavid van Moolenbroek label_grant = m_in->m_vfs_fs_readsuper.grant;
2589c9de7dSDavid van Moolenbroek label_len = m_in->m_vfs_fs_readsuper.path_len;
2689c9de7dSDavid van Moolenbroek flags = m_in->m_vfs_fs_readsuper.flags;
2789c9de7dSDavid van Moolenbroek
2889c9de7dSDavid van Moolenbroek if (fdp->fdr_mount == NULL)
2989c9de7dSDavid van Moolenbroek return ENOSYS;
3089c9de7dSDavid van Moolenbroek
3189c9de7dSDavid van Moolenbroek if (fsdriver_mounted) {
3289c9de7dSDavid van Moolenbroek printf("fsdriver: attempt to mount multiple times\n");
3389c9de7dSDavid van Moolenbroek return EBUSY;
3489c9de7dSDavid van Moolenbroek }
3589c9de7dSDavid van Moolenbroek
3689c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, label_grant, label_len,
3789c9de7dSDavid van Moolenbroek label, sizeof(label), FALSE /*not_empty*/)) != OK)
3889c9de7dSDavid van Moolenbroek return r;
3989c9de7dSDavid van Moolenbroek
4089c9de7dSDavid van Moolenbroek if (fdp->fdr_driver != NULL)
4189c9de7dSDavid van Moolenbroek fdp->fdr_driver(dev, label);
4289c9de7dSDavid van Moolenbroek
4389c9de7dSDavid van Moolenbroek res_flags = RES_NOFLAGS;
4489c9de7dSDavid van Moolenbroek
4589c9de7dSDavid van Moolenbroek r = fdp->fdr_mount(dev, flags, &root_node, &res_flags);
4689c9de7dSDavid van Moolenbroek
4789c9de7dSDavid van Moolenbroek if (r == OK) {
4889c9de7dSDavid van Moolenbroek /* This one we can set on the file system's behalf. */
49e321f655SDavid van Moolenbroek if ((fdp->fdr_peek != NULL && fdp->fdr_bpeek != NULL) ||
50e321f655SDavid van Moolenbroek major(dev) == NONE_MAJOR)
5189c9de7dSDavid van Moolenbroek res_flags |= RES_HASPEEK;
5289c9de7dSDavid van Moolenbroek
5389c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.inode = root_node.fn_ino_nr;
5489c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.mode = root_node.fn_mode;
5589c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.file_size = root_node.fn_size;
5689c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.uid = root_node.fn_uid;
5789c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.gid = root_node.fn_gid;
5889c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readsuper.flags = res_flags;
5989c9de7dSDavid van Moolenbroek
6089c9de7dSDavid van Moolenbroek /* Update library-local state. */
6189c9de7dSDavid van Moolenbroek fsdriver_mounted = TRUE;
62289b0467SDavid van Moolenbroek fsdriver_device = dev;
6389c9de7dSDavid van Moolenbroek fsdriver_root = root_node.fn_ino_nr;
64*0a2a0873SDavid van Moolenbroek fsdriver_vmcache = FALSE;
6589c9de7dSDavid van Moolenbroek }
6689c9de7dSDavid van Moolenbroek
6789c9de7dSDavid van Moolenbroek return r;
6889c9de7dSDavid van Moolenbroek }
6989c9de7dSDavid van Moolenbroek
7089c9de7dSDavid van Moolenbroek /*
7189c9de7dSDavid van Moolenbroek * Process an UNMOUNT request from VFS.
7289c9de7dSDavid van Moolenbroek */
7389c9de7dSDavid van Moolenbroek int
fsdriver_unmount(const struct fsdriver * __restrict fdp,const message * __restrict __unused m_in,message * __restrict __unused m_out)7489c9de7dSDavid van Moolenbroek fsdriver_unmount(const struct fsdriver * __restrict fdp,
7589c9de7dSDavid van Moolenbroek const message * __restrict __unused m_in,
7689c9de7dSDavid van Moolenbroek message * __restrict __unused m_out)
7789c9de7dSDavid van Moolenbroek {
7889c9de7dSDavid van Moolenbroek
7989c9de7dSDavid van Moolenbroek if (fdp->fdr_unmount != NULL)
8089c9de7dSDavid van Moolenbroek fdp->fdr_unmount();
8189c9de7dSDavid van Moolenbroek
82e321f655SDavid van Moolenbroek /* If we used mmap emulation, clear any cached blocks from VM. */
83*0a2a0873SDavid van Moolenbroek if (fsdriver_vmcache)
84e321f655SDavid van Moolenbroek vm_clear_cache(fsdriver_device);
85e321f655SDavid van Moolenbroek
8689c9de7dSDavid van Moolenbroek /* Update library-local state. */
8789c9de7dSDavid van Moolenbroek fsdriver_mounted = FALSE;
8889c9de7dSDavid van Moolenbroek
8989c9de7dSDavid van Moolenbroek return OK;
9089c9de7dSDavid van Moolenbroek }
9189c9de7dSDavid van Moolenbroek
9289c9de7dSDavid van Moolenbroek /*
9389c9de7dSDavid van Moolenbroek * Process a PUTNODE request from VFS.
9489c9de7dSDavid van Moolenbroek */
9589c9de7dSDavid van Moolenbroek int
fsdriver_putnode(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)9689c9de7dSDavid van Moolenbroek fsdriver_putnode(const struct fsdriver * __restrict fdp,
9789c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
9889c9de7dSDavid van Moolenbroek {
9989c9de7dSDavid van Moolenbroek ino_t ino_nr;
10089c9de7dSDavid van Moolenbroek unsigned int count;
10189c9de7dSDavid van Moolenbroek
10289c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_putnode.inode;
10389c9de7dSDavid van Moolenbroek count = m_in->m_vfs_fs_putnode.count;
10489c9de7dSDavid van Moolenbroek
10589c9de7dSDavid van Moolenbroek if (count == 0 || count > INT_MAX) {
10689c9de7dSDavid van Moolenbroek printf("fsdriver: invalid reference count\n");
10789c9de7dSDavid van Moolenbroek return EINVAL;
10889c9de7dSDavid van Moolenbroek }
10989c9de7dSDavid van Moolenbroek
1103f30eb69SDavid van Moolenbroek if (fdp->fdr_putnode != NULL)
11189c9de7dSDavid van Moolenbroek return fdp->fdr_putnode(ino_nr, count);
1123f30eb69SDavid van Moolenbroek else
1133f30eb69SDavid van Moolenbroek return OK;
11489c9de7dSDavid van Moolenbroek }
11589c9de7dSDavid van Moolenbroek
11689c9de7dSDavid van Moolenbroek /*
11789c9de7dSDavid van Moolenbroek * Process a NEWNODE request from VFS.
11889c9de7dSDavid van Moolenbroek */
11989c9de7dSDavid van Moolenbroek int
fsdriver_newnode(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)12089c9de7dSDavid van Moolenbroek fsdriver_newnode(const struct fsdriver * __restrict fdp,
12189c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
12289c9de7dSDavid van Moolenbroek {
12389c9de7dSDavid van Moolenbroek struct fsdriver_node node;
12489c9de7dSDavid van Moolenbroek mode_t mode;
12589c9de7dSDavid van Moolenbroek uid_t uid;
12689c9de7dSDavid van Moolenbroek gid_t gid;
12789c9de7dSDavid van Moolenbroek dev_t dev;
12889c9de7dSDavid van Moolenbroek int r;
12989c9de7dSDavid van Moolenbroek
13089c9de7dSDavid van Moolenbroek mode = m_in->m_vfs_fs_newnode.mode;
13189c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_newnode.uid;
13289c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_newnode.gid;
13389c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_newnode.device;
13489c9de7dSDavid van Moolenbroek
13589c9de7dSDavid van Moolenbroek if (fdp->fdr_newnode == NULL)
13689c9de7dSDavid van Moolenbroek return ENOSYS;
13789c9de7dSDavid van Moolenbroek
13889c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_newnode(mode, uid, gid, dev, &node)) == OK) {
13989c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.inode = node.fn_ino_nr;
14089c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.mode = node.fn_mode;
14189c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.file_size = node.fn_size;
14289c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.uid = node.fn_uid;
14389c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.gid = node.fn_gid;
14489c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_newnode.device = node.fn_dev;
14589c9de7dSDavid van Moolenbroek }
14689c9de7dSDavid van Moolenbroek
14789c9de7dSDavid van Moolenbroek return r;
14889c9de7dSDavid van Moolenbroek }
14989c9de7dSDavid van Moolenbroek
15089c9de7dSDavid van Moolenbroek /*
15189c9de7dSDavid van Moolenbroek * Process a read or write request from VFS.
15289c9de7dSDavid van Moolenbroek */
15389c9de7dSDavid van Moolenbroek static int
read_write(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out,int call)15489c9de7dSDavid van Moolenbroek read_write(const struct fsdriver * __restrict fdp,
15589c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out, int call)
15689c9de7dSDavid van Moolenbroek {
15789c9de7dSDavid van Moolenbroek struct fsdriver_data data;
15889c9de7dSDavid van Moolenbroek ino_t ino_nr;
15989c9de7dSDavid van Moolenbroek off_t pos;
16089c9de7dSDavid van Moolenbroek size_t nbytes;
16189c9de7dSDavid van Moolenbroek ssize_t r;
16289c9de7dSDavid van Moolenbroek
16389c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_readwrite.inode;
16489c9de7dSDavid van Moolenbroek pos = m_in->m_vfs_fs_readwrite.seek_pos;
16589c9de7dSDavid van Moolenbroek nbytes = m_in->m_vfs_fs_readwrite.nbytes;
16689c9de7dSDavid van Moolenbroek
16789c9de7dSDavid van Moolenbroek if (pos < 0 || nbytes > SSIZE_MAX)
16889c9de7dSDavid van Moolenbroek return EINVAL;
16989c9de7dSDavid van Moolenbroek
17089c9de7dSDavid van Moolenbroek data.endpt = m_in->m_source;
17189c9de7dSDavid van Moolenbroek data.grant = m_in->m_vfs_fs_readwrite.grant;
17289c9de7dSDavid van Moolenbroek data.size = nbytes;
17389c9de7dSDavid van Moolenbroek
17489c9de7dSDavid van Moolenbroek if (call == FSC_WRITE)
17589c9de7dSDavid van Moolenbroek r = fdp->fdr_write(ino_nr, &data, nbytes, pos, call);
17689c9de7dSDavid van Moolenbroek else
17789c9de7dSDavid van Moolenbroek r = fdp->fdr_read(ino_nr, &data, nbytes, pos, call);
17889c9de7dSDavid van Moolenbroek
17989c9de7dSDavid van Moolenbroek if (r >= 0) {
18089c9de7dSDavid van Moolenbroek pos += r;
18189c9de7dSDavid van Moolenbroek
18289c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readwrite.seek_pos = pos;
18389c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readwrite.nbytes = r;
18489c9de7dSDavid van Moolenbroek r = OK;
18589c9de7dSDavid van Moolenbroek }
18689c9de7dSDavid van Moolenbroek
18789c9de7dSDavid van Moolenbroek return r;
18889c9de7dSDavid van Moolenbroek }
18989c9de7dSDavid van Moolenbroek
19089c9de7dSDavid van Moolenbroek /*
19189c9de7dSDavid van Moolenbroek * Process a READ request from VFS.
19289c9de7dSDavid van Moolenbroek */
19389c9de7dSDavid van Moolenbroek int
fsdriver_read(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)19489c9de7dSDavid van Moolenbroek fsdriver_read(const struct fsdriver * __restrict fdp,
19589c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
19689c9de7dSDavid van Moolenbroek {
19789c9de7dSDavid van Moolenbroek
19889c9de7dSDavid van Moolenbroek if (fdp->fdr_read == NULL)
19989c9de7dSDavid van Moolenbroek return ENOSYS;
20089c9de7dSDavid van Moolenbroek
20189c9de7dSDavid van Moolenbroek return read_write(fdp, m_in, m_out, FSC_READ);
20289c9de7dSDavid van Moolenbroek }
20389c9de7dSDavid van Moolenbroek
20489c9de7dSDavid van Moolenbroek /*
20589c9de7dSDavid van Moolenbroek * Process a WRITE request from VFS.
20689c9de7dSDavid van Moolenbroek */
20789c9de7dSDavid van Moolenbroek int
fsdriver_write(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)20889c9de7dSDavid van Moolenbroek fsdriver_write(const struct fsdriver * __restrict fdp,
20989c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
21089c9de7dSDavid van Moolenbroek {
21189c9de7dSDavid van Moolenbroek
21289c9de7dSDavid van Moolenbroek if (fdp->fdr_write == NULL)
21389c9de7dSDavid van Moolenbroek return ENOSYS;
21489c9de7dSDavid van Moolenbroek
21589c9de7dSDavid van Moolenbroek return read_write(fdp, m_in, m_out, FSC_WRITE);
21689c9de7dSDavid van Moolenbroek }
21789c9de7dSDavid van Moolenbroek
21889c9de7dSDavid van Moolenbroek /*
219e321f655SDavid van Moolenbroek * A read-based peek implementation. This allows file systems that do not have
220e321f655SDavid van Moolenbroek * a buffer cache and do not implement peek, to support a limited form of mmap.
221e321f655SDavid van Moolenbroek * We map in a block, fill it by calling the file system's read function, tell
222e321f655SDavid van Moolenbroek * VM about the page, and then unmap the block again. We tell VM not to cache
223e321f655SDavid van Moolenbroek * the block beyond its immediate use for the mmap request, so as to prevent
224e321f655SDavid van Moolenbroek * potentially stale data from being cached--at the cost of performance.
225e321f655SDavid van Moolenbroek */
226e321f655SDavid van Moolenbroek static ssize_t
builtin_peek(const struct fsdriver * __restrict fdp,ino_t ino_nr,size_t nbytes,off_t pos)227e321f655SDavid van Moolenbroek builtin_peek(const struct fsdriver * __restrict fdp, ino_t ino_nr,
228e321f655SDavid van Moolenbroek size_t nbytes, off_t pos)
229e321f655SDavid van Moolenbroek {
230e321f655SDavid van Moolenbroek static u32_t flags = 0; /* storage for the VMMC_ flags of all blocks */
231e321f655SDavid van Moolenbroek static off_t dev_off = 0; /* fake device offset, see below */
232e321f655SDavid van Moolenbroek struct fsdriver_data data;
233e321f655SDavid van Moolenbroek char *buf;
234e321f655SDavid van Moolenbroek ssize_t r;
235e321f655SDavid van Moolenbroek
236e321f655SDavid van Moolenbroek if ((buf = mmap(NULL, nbytes, PROT_READ | PROT_WRITE,
237e321f655SDavid van Moolenbroek MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
238e321f655SDavid van Moolenbroek return ENOMEM;
239e321f655SDavid van Moolenbroek
240e321f655SDavid van Moolenbroek data.endpt = SELF;
241e321f655SDavid van Moolenbroek data.grant = (cp_grant_id_t)buf;
242e321f655SDavid van Moolenbroek data.size = nbytes;
243e321f655SDavid van Moolenbroek
244e321f655SDavid van Moolenbroek r = fdp->fdr_read(ino_nr, &data, nbytes, pos, FSC_READ);
245e321f655SDavid van Moolenbroek
246e321f655SDavid van Moolenbroek if (r >= 0) {
247e321f655SDavid van Moolenbroek if ((size_t)r < nbytes)
248e321f655SDavid van Moolenbroek memset(&buf[r], 0, nbytes - r);
249e321f655SDavid van Moolenbroek
250e321f655SDavid van Moolenbroek /*
251e321f655SDavid van Moolenbroek * VM uses serialized communication to VFS. Since the page is
252e321f655SDavid van Moolenbroek * to be used only once, VM will use and then discard it before
253e321f655SDavid van Moolenbroek * sending a new peek request. Thus, it should be safe to
254e321f655SDavid van Moolenbroek * reuse the same device offset all the time. However, relying
255e321f655SDavid van Moolenbroek * on assumptions in protocols elsewhere a bit dangerous, so we
256e321f655SDavid van Moolenbroek * use an ever-increasing device offset just to be safe.
257e321f655SDavid van Moolenbroek */
258e321f655SDavid van Moolenbroek r = vm_set_cacheblock(buf, fsdriver_device, dev_off, ino_nr,
259e321f655SDavid van Moolenbroek pos, &flags, nbytes, VMSF_ONCE);
260e321f655SDavid van Moolenbroek
261e321f655SDavid van Moolenbroek if (r == OK) {
262*0a2a0873SDavid van Moolenbroek fsdriver_vmcache = TRUE;
263*0a2a0873SDavid van Moolenbroek
264e321f655SDavid van Moolenbroek dev_off += nbytes;
265e321f655SDavid van Moolenbroek
266e321f655SDavid van Moolenbroek r = nbytes;
267e321f655SDavid van Moolenbroek }
268e321f655SDavid van Moolenbroek }
269e321f655SDavid van Moolenbroek
270e321f655SDavid van Moolenbroek munmap(buf, nbytes);
271e321f655SDavid van Moolenbroek
272e321f655SDavid van Moolenbroek return r;
273e321f655SDavid van Moolenbroek }
274e321f655SDavid van Moolenbroek
275e321f655SDavid van Moolenbroek /*
27689c9de7dSDavid van Moolenbroek * Process a PEEK request from VFS.
27789c9de7dSDavid van Moolenbroek */
27889c9de7dSDavid van Moolenbroek int
fsdriver_peek(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)27989c9de7dSDavid van Moolenbroek fsdriver_peek(const struct fsdriver * __restrict fdp,
28089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
28189c9de7dSDavid van Moolenbroek {
28289c9de7dSDavid van Moolenbroek ino_t ino_nr;
28389c9de7dSDavid van Moolenbroek off_t pos;
28489c9de7dSDavid van Moolenbroek size_t nbytes;
28589c9de7dSDavid van Moolenbroek ssize_t r;
28689c9de7dSDavid van Moolenbroek
28789c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_readwrite.inode;
28889c9de7dSDavid van Moolenbroek pos = m_in->m_vfs_fs_readwrite.seek_pos;
28989c9de7dSDavid van Moolenbroek nbytes = m_in->m_vfs_fs_readwrite.nbytes;
29089c9de7dSDavid van Moolenbroek
29189c9de7dSDavid van Moolenbroek if (pos < 0 || nbytes > SSIZE_MAX)
29289c9de7dSDavid van Moolenbroek return EINVAL;
29389c9de7dSDavid van Moolenbroek
294e321f655SDavid van Moolenbroek if (fdp->fdr_peek == NULL) {
295e321f655SDavid van Moolenbroek if (major(fsdriver_device) != NONE_MAJOR)
296e321f655SDavid van Moolenbroek return ENOSYS;
297e321f655SDavid van Moolenbroek
298e321f655SDavid van Moolenbroek /*
299e321f655SDavid van Moolenbroek * For file systems that have no backing device, emulate peek
300e321f655SDavid van Moolenbroek * support by reading into temporary buffers and passing these
301e321f655SDavid van Moolenbroek * to VM.
302e321f655SDavid van Moolenbroek */
303e321f655SDavid van Moolenbroek r = builtin_peek(fdp, ino_nr, nbytes, pos);
304e321f655SDavid van Moolenbroek } else
305e321f655SDavid van Moolenbroek r = fdp->fdr_peek(ino_nr, NULL /*data*/, nbytes, pos,
306e321f655SDavid van Moolenbroek FSC_PEEK);
30789c9de7dSDavid van Moolenbroek
30889c9de7dSDavid van Moolenbroek /* Do not return a new position. */
30989c9de7dSDavid van Moolenbroek if (r >= 0) {
31089c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_readwrite.nbytes = r;
31189c9de7dSDavid van Moolenbroek r = OK;
31289c9de7dSDavid van Moolenbroek }
31389c9de7dSDavid van Moolenbroek
31489c9de7dSDavid van Moolenbroek return r;
31589c9de7dSDavid van Moolenbroek }
31689c9de7dSDavid van Moolenbroek
31789c9de7dSDavid van Moolenbroek /*
31889c9de7dSDavid van Moolenbroek * Process a GETDENTS request from VFS.
31989c9de7dSDavid van Moolenbroek */
32089c9de7dSDavid van Moolenbroek int
fsdriver_getdents(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)32189c9de7dSDavid van Moolenbroek fsdriver_getdents(const struct fsdriver * __restrict fdp,
32289c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
32389c9de7dSDavid van Moolenbroek {
32489c9de7dSDavid van Moolenbroek struct fsdriver_data data;
32589c9de7dSDavid van Moolenbroek ino_t ino_nr;
32689c9de7dSDavid van Moolenbroek off_t pos;
32789c9de7dSDavid van Moolenbroek size_t nbytes;
32889c9de7dSDavid van Moolenbroek ssize_t r;
32989c9de7dSDavid van Moolenbroek
33089c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_getdents.inode;
33189c9de7dSDavid van Moolenbroek pos = m_in->m_vfs_fs_getdents.seek_pos;
33289c9de7dSDavid van Moolenbroek nbytes = m_in->m_vfs_fs_getdents.mem_size;
33389c9de7dSDavid van Moolenbroek
33489c9de7dSDavid van Moolenbroek if (fdp->fdr_getdents == NULL)
33589c9de7dSDavid van Moolenbroek return ENOSYS;
33689c9de7dSDavid van Moolenbroek
33789c9de7dSDavid van Moolenbroek if (pos < 0 || nbytes > SSIZE_MAX)
33889c9de7dSDavid van Moolenbroek return EINVAL;
33989c9de7dSDavid van Moolenbroek
34089c9de7dSDavid van Moolenbroek data.endpt = m_in->m_source;
34189c9de7dSDavid van Moolenbroek data.grant = m_in->m_vfs_fs_getdents.grant;
34289c9de7dSDavid van Moolenbroek data.size = nbytes;
34389c9de7dSDavid van Moolenbroek
34489c9de7dSDavid van Moolenbroek r = fdp->fdr_getdents(ino_nr, &data, nbytes, &pos);
34589c9de7dSDavid van Moolenbroek
34689c9de7dSDavid van Moolenbroek if (r >= 0) {
34789c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_getdents.seek_pos = pos;
34889c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_getdents.nbytes = r;
34989c9de7dSDavid van Moolenbroek r = OK;
35089c9de7dSDavid van Moolenbroek }
35189c9de7dSDavid van Moolenbroek
35289c9de7dSDavid van Moolenbroek return r;
35389c9de7dSDavid van Moolenbroek }
35489c9de7dSDavid van Moolenbroek
35589c9de7dSDavid van Moolenbroek /*
35689c9de7dSDavid van Moolenbroek * Process a FTRUNC request from VFS.
35789c9de7dSDavid van Moolenbroek */
35889c9de7dSDavid van Moolenbroek int
fsdriver_trunc(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)35989c9de7dSDavid van Moolenbroek fsdriver_trunc(const struct fsdriver * __restrict fdp,
36089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
36189c9de7dSDavid van Moolenbroek {
36289c9de7dSDavid van Moolenbroek ino_t ino_nr;
36389c9de7dSDavid van Moolenbroek off_t start_pos, end_pos;
36489c9de7dSDavid van Moolenbroek
36589c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_ftrunc.inode;
36689c9de7dSDavid van Moolenbroek start_pos = m_in->m_vfs_fs_ftrunc.trc_start;
36789c9de7dSDavid van Moolenbroek end_pos = m_in->m_vfs_fs_ftrunc.trc_end;
36889c9de7dSDavid van Moolenbroek
36989c9de7dSDavid van Moolenbroek if (start_pos < 0 || end_pos < 0)
37089c9de7dSDavid van Moolenbroek return EINVAL;
37189c9de7dSDavid van Moolenbroek
37289c9de7dSDavid van Moolenbroek if (fdp->fdr_trunc == NULL)
37389c9de7dSDavid van Moolenbroek return ENOSYS;
37489c9de7dSDavid van Moolenbroek
37589c9de7dSDavid van Moolenbroek return fdp->fdr_trunc(ino_nr, start_pos, end_pos);
37689c9de7dSDavid van Moolenbroek }
37789c9de7dSDavid van Moolenbroek
37889c9de7dSDavid van Moolenbroek /*
37989c9de7dSDavid van Moolenbroek * Process a INHIBREAD request from VFS.
38089c9de7dSDavid van Moolenbroek */
38189c9de7dSDavid van Moolenbroek int
fsdriver_inhibread(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)38289c9de7dSDavid van Moolenbroek fsdriver_inhibread(const struct fsdriver * __restrict fdp,
38389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
38489c9de7dSDavid van Moolenbroek {
38589c9de7dSDavid van Moolenbroek ino_t ino_nr;
38689c9de7dSDavid van Moolenbroek
38789c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_inhibread.inode;
38889c9de7dSDavid van Moolenbroek
38989c9de7dSDavid van Moolenbroek if (fdp->fdr_seek != NULL)
39089c9de7dSDavid van Moolenbroek fdp->fdr_seek(ino_nr);
39189c9de7dSDavid van Moolenbroek
39289c9de7dSDavid van Moolenbroek return OK;
39389c9de7dSDavid van Moolenbroek }
39489c9de7dSDavid van Moolenbroek
39589c9de7dSDavid van Moolenbroek /*
39689c9de7dSDavid van Moolenbroek * Process a CREATE request from VFS.
39789c9de7dSDavid van Moolenbroek */
39889c9de7dSDavid van Moolenbroek int
fsdriver_create(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)39989c9de7dSDavid van Moolenbroek fsdriver_create(const struct fsdriver * __restrict fdp,
40089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
40189c9de7dSDavid van Moolenbroek {
40289c9de7dSDavid van Moolenbroek struct fsdriver_node node;
40389c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
40489c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
40589c9de7dSDavid van Moolenbroek size_t len;
40689c9de7dSDavid van Moolenbroek ino_t dir_nr;
40789c9de7dSDavid van Moolenbroek mode_t mode;
40889c9de7dSDavid van Moolenbroek uid_t uid;
40989c9de7dSDavid van Moolenbroek gid_t gid;
41089c9de7dSDavid van Moolenbroek int r;
41189c9de7dSDavid van Moolenbroek
41289c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_create.grant;
41389c9de7dSDavid van Moolenbroek len = m_in->m_vfs_fs_create.path_len;
41489c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_create.inode;
41589c9de7dSDavid van Moolenbroek mode = m_in->m_vfs_fs_create.mode;
41689c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_create.uid;
41789c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_create.gid;
41889c9de7dSDavid van Moolenbroek
41989c9de7dSDavid van Moolenbroek if (fdp->fdr_create == NULL)
42089c9de7dSDavid van Moolenbroek return ENOSYS;
42189c9de7dSDavid van Moolenbroek
42289c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, len, name,
42389c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
42489c9de7dSDavid van Moolenbroek return r;
42589c9de7dSDavid van Moolenbroek
42689c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
42789c9de7dSDavid van Moolenbroek return EEXIST;
42889c9de7dSDavid van Moolenbroek
42989c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_create(dir_nr, name, mode, uid, gid, &node)) == OK) {
43089c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_create.inode = node.fn_ino_nr;
43189c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_create.mode = node.fn_mode;
43289c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_create.file_size = node.fn_size;
43389c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_create.uid = node.fn_uid;
43489c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_create.gid = node.fn_gid;
43589c9de7dSDavid van Moolenbroek }
43689c9de7dSDavid van Moolenbroek
43789c9de7dSDavid van Moolenbroek return r;
43889c9de7dSDavid van Moolenbroek }
43989c9de7dSDavid van Moolenbroek
44089c9de7dSDavid van Moolenbroek /*
44189c9de7dSDavid van Moolenbroek * Process a MKDIR request from VFS.
44289c9de7dSDavid van Moolenbroek */
44389c9de7dSDavid van Moolenbroek int
fsdriver_mkdir(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)44489c9de7dSDavid van Moolenbroek fsdriver_mkdir(const struct fsdriver * __restrict fdp,
44589c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
44689c9de7dSDavid van Moolenbroek {
44789c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
44889c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
44989c9de7dSDavid van Moolenbroek size_t path_len;
45089c9de7dSDavid van Moolenbroek ino_t dir_nr;
45189c9de7dSDavid van Moolenbroek mode_t mode;
45289c9de7dSDavid van Moolenbroek uid_t uid;
45389c9de7dSDavid van Moolenbroek gid_t gid;
45489c9de7dSDavid van Moolenbroek int r;
45589c9de7dSDavid van Moolenbroek
45689c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_mkdir.grant;
45789c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_mkdir.path_len;
45889c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_mkdir.inode;
45989c9de7dSDavid van Moolenbroek mode = m_in->m_vfs_fs_mkdir.mode;
46089c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_mkdir.uid;
46189c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_mkdir.gid;
46289c9de7dSDavid van Moolenbroek
46389c9de7dSDavid van Moolenbroek if (fdp->fdr_mkdir == NULL)
46489c9de7dSDavid van Moolenbroek return ENOSYS;
46589c9de7dSDavid van Moolenbroek
46689c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
46789c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
46889c9de7dSDavid van Moolenbroek return r;
46989c9de7dSDavid van Moolenbroek
47089c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
47189c9de7dSDavid van Moolenbroek return EEXIST;
47289c9de7dSDavid van Moolenbroek
47389c9de7dSDavid van Moolenbroek return fdp->fdr_mkdir(dir_nr, name, mode, uid, gid);
47489c9de7dSDavid van Moolenbroek }
47589c9de7dSDavid van Moolenbroek
47689c9de7dSDavid van Moolenbroek /*
47789c9de7dSDavid van Moolenbroek * Process a MKNOD request from VFS.
47889c9de7dSDavid van Moolenbroek */
47989c9de7dSDavid van Moolenbroek int
fsdriver_mknod(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)48089c9de7dSDavid van Moolenbroek fsdriver_mknod(const struct fsdriver * __restrict fdp,
48189c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
48289c9de7dSDavid van Moolenbroek {
48389c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
48489c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
48589c9de7dSDavid van Moolenbroek size_t path_len;
48689c9de7dSDavid van Moolenbroek ino_t dir_nr;
48789c9de7dSDavid van Moolenbroek mode_t mode;
48889c9de7dSDavid van Moolenbroek uid_t uid;
48989c9de7dSDavid van Moolenbroek gid_t gid;
49089c9de7dSDavid van Moolenbroek dev_t dev;
49189c9de7dSDavid van Moolenbroek int r;
49289c9de7dSDavid van Moolenbroek
49389c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_mknod.grant;
49489c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_mknod.path_len;
49589c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_mknod.inode;
49689c9de7dSDavid van Moolenbroek mode = m_in->m_vfs_fs_mknod.mode;
49789c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_mknod.uid;
49889c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_mknod.gid;
49989c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_mknod.device;
50089c9de7dSDavid van Moolenbroek
50189c9de7dSDavid van Moolenbroek if (fdp->fdr_mknod == NULL)
50289c9de7dSDavid van Moolenbroek return ENOSYS;
50389c9de7dSDavid van Moolenbroek
50489c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
50589c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
50689c9de7dSDavid van Moolenbroek return r;
50789c9de7dSDavid van Moolenbroek
50889c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
50989c9de7dSDavid van Moolenbroek return EEXIST;
51089c9de7dSDavid van Moolenbroek
51189c9de7dSDavid van Moolenbroek return fdp->fdr_mknod(dir_nr, name, mode, uid, gid, dev);
51289c9de7dSDavid van Moolenbroek }
51389c9de7dSDavid van Moolenbroek
51489c9de7dSDavid van Moolenbroek /*
51589c9de7dSDavid van Moolenbroek * Process a LINK request from VFS.
51689c9de7dSDavid van Moolenbroek */
51789c9de7dSDavid van Moolenbroek int
fsdriver_link(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)51889c9de7dSDavid van Moolenbroek fsdriver_link(const struct fsdriver * __restrict fdp,
51989c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
52089c9de7dSDavid van Moolenbroek {
52189c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
52289c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
52389c9de7dSDavid van Moolenbroek size_t path_len;
52489c9de7dSDavid van Moolenbroek ino_t dir_nr, ino_nr;
52589c9de7dSDavid van Moolenbroek int r;
52689c9de7dSDavid van Moolenbroek
52789c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_link.grant;
52889c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_link.path_len;
52989c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_link.dir_ino;
53089c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_link.inode;
53189c9de7dSDavid van Moolenbroek
53289c9de7dSDavid van Moolenbroek if (fdp->fdr_link == NULL)
53389c9de7dSDavid van Moolenbroek return ENOSYS;
53489c9de7dSDavid van Moolenbroek
53589c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
53689c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
53789c9de7dSDavid van Moolenbroek return r;
53889c9de7dSDavid van Moolenbroek
53989c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
54089c9de7dSDavid van Moolenbroek return EEXIST;
54189c9de7dSDavid van Moolenbroek
54289c9de7dSDavid van Moolenbroek return fdp->fdr_link(dir_nr, name, ino_nr);
54389c9de7dSDavid van Moolenbroek }
54489c9de7dSDavid van Moolenbroek
54589c9de7dSDavid van Moolenbroek /*
54689c9de7dSDavid van Moolenbroek * Process an UNLINK request from VFS.
54789c9de7dSDavid van Moolenbroek */
54889c9de7dSDavid van Moolenbroek int
fsdriver_unlink(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)54989c9de7dSDavid van Moolenbroek fsdriver_unlink(const struct fsdriver * __restrict fdp,
55089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
55189c9de7dSDavid van Moolenbroek {
55289c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
55389c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
55489c9de7dSDavid van Moolenbroek size_t path_len;
55589c9de7dSDavid van Moolenbroek ino_t dir_nr;
55689c9de7dSDavid van Moolenbroek int r;
55789c9de7dSDavid van Moolenbroek
55889c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_unlink.grant;
55989c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_unlink.path_len;
56089c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_unlink.inode;
56189c9de7dSDavid van Moolenbroek
56289c9de7dSDavid van Moolenbroek if (fdp->fdr_unlink == NULL)
56389c9de7dSDavid van Moolenbroek return ENOSYS;
56489c9de7dSDavid van Moolenbroek
56589c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
56689c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
56789c9de7dSDavid van Moolenbroek return r;
56889c9de7dSDavid van Moolenbroek
56989c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
57089c9de7dSDavid van Moolenbroek return EPERM;
57189c9de7dSDavid van Moolenbroek
57289c9de7dSDavid van Moolenbroek return fdp->fdr_unlink(dir_nr, name, FSC_UNLINK);
57389c9de7dSDavid van Moolenbroek }
57489c9de7dSDavid van Moolenbroek
57589c9de7dSDavid van Moolenbroek /*
57689c9de7dSDavid van Moolenbroek * Process a RMDIR request from VFS.
57789c9de7dSDavid van Moolenbroek */
57889c9de7dSDavid van Moolenbroek int
fsdriver_rmdir(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)57989c9de7dSDavid van Moolenbroek fsdriver_rmdir(const struct fsdriver * __restrict fdp,
58089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
58189c9de7dSDavid van Moolenbroek {
58289c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
58389c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
58489c9de7dSDavid van Moolenbroek size_t path_len;
58589c9de7dSDavid van Moolenbroek ino_t dir_nr;
58689c9de7dSDavid van Moolenbroek int r;
58789c9de7dSDavid van Moolenbroek
58889c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_unlink.grant;
58989c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_unlink.path_len;
59089c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_unlink.inode;
59189c9de7dSDavid van Moolenbroek
59289c9de7dSDavid van Moolenbroek if (fdp->fdr_rmdir == NULL)
59389c9de7dSDavid van Moolenbroek return ENOSYS;
59489c9de7dSDavid van Moolenbroek
59589c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
59689c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
59789c9de7dSDavid van Moolenbroek return r;
59889c9de7dSDavid van Moolenbroek
59989c9de7dSDavid van Moolenbroek if (!strcmp(name, "."))
60089c9de7dSDavid van Moolenbroek return EINVAL;
60189c9de7dSDavid van Moolenbroek
60289c9de7dSDavid van Moolenbroek if (!strcmp(name, ".."))
60389c9de7dSDavid van Moolenbroek return ENOTEMPTY;
60489c9de7dSDavid van Moolenbroek
60589c9de7dSDavid van Moolenbroek return fdp->fdr_rmdir(dir_nr, name, FSC_RMDIR);
60689c9de7dSDavid van Moolenbroek }
60789c9de7dSDavid van Moolenbroek
60889c9de7dSDavid van Moolenbroek /*
60989c9de7dSDavid van Moolenbroek * Process a RENAME request from VFS.
61089c9de7dSDavid van Moolenbroek */
61189c9de7dSDavid van Moolenbroek int
fsdriver_rename(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)61289c9de7dSDavid van Moolenbroek fsdriver_rename(const struct fsdriver * __restrict fdp,
61389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
61489c9de7dSDavid van Moolenbroek {
61589c9de7dSDavid van Moolenbroek char old_name[NAME_MAX+1], new_name[NAME_MAX+1];
61689c9de7dSDavid van Moolenbroek cp_grant_id_t old_grant, new_grant;
61789c9de7dSDavid van Moolenbroek size_t old_len, new_len;
61889c9de7dSDavid van Moolenbroek ino_t old_dir_nr, new_dir_nr;
61989c9de7dSDavid van Moolenbroek int r;
62089c9de7dSDavid van Moolenbroek
62189c9de7dSDavid van Moolenbroek old_grant = m_in->m_vfs_fs_rename.grant_old;
62289c9de7dSDavid van Moolenbroek old_len = m_in->m_vfs_fs_rename.len_old;
62389c9de7dSDavid van Moolenbroek old_dir_nr = m_in->m_vfs_fs_rename.dir_old;
62489c9de7dSDavid van Moolenbroek new_grant = m_in->m_vfs_fs_rename.grant_new;
62589c9de7dSDavid van Moolenbroek new_len = m_in->m_vfs_fs_rename.len_new;
62689c9de7dSDavid van Moolenbroek new_dir_nr = m_in->m_vfs_fs_rename.dir_new;
62789c9de7dSDavid van Moolenbroek
62889c9de7dSDavid van Moolenbroek if (fdp->fdr_rename == NULL)
62989c9de7dSDavid van Moolenbroek return ENOSYS;
63089c9de7dSDavid van Moolenbroek
63189c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, old_grant, old_len, old_name,
63289c9de7dSDavid van Moolenbroek sizeof(old_name), TRUE /*not_empty*/)) != OK)
63389c9de7dSDavid van Moolenbroek return r;
63489c9de7dSDavid van Moolenbroek
63589c9de7dSDavid van Moolenbroek if (!strcmp(old_name, ".") || !strcmp(old_name, ".."))
63689c9de7dSDavid van Moolenbroek return EINVAL;
63789c9de7dSDavid van Moolenbroek
63889c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, new_grant, new_len, new_name,
63989c9de7dSDavid van Moolenbroek sizeof(new_name), TRUE /*not_empty*/)) != OK)
64089c9de7dSDavid van Moolenbroek return r;
64189c9de7dSDavid van Moolenbroek
64289c9de7dSDavid van Moolenbroek if (!strcmp(new_name, ".") || !strcmp(new_name, ".."))
64389c9de7dSDavid van Moolenbroek return EINVAL;
64489c9de7dSDavid van Moolenbroek
64589c9de7dSDavid van Moolenbroek return fdp->fdr_rename(old_dir_nr, old_name, new_dir_nr, new_name);
64689c9de7dSDavid van Moolenbroek }
64789c9de7dSDavid van Moolenbroek
64889c9de7dSDavid van Moolenbroek /*
64989c9de7dSDavid van Moolenbroek * Process a SLINK request from VFS.
65089c9de7dSDavid van Moolenbroek */
65189c9de7dSDavid van Moolenbroek int
fsdriver_slink(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)65289c9de7dSDavid van Moolenbroek fsdriver_slink(const struct fsdriver * __restrict fdp,
65389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
65489c9de7dSDavid van Moolenbroek {
65589c9de7dSDavid van Moolenbroek struct fsdriver_data data;
65689c9de7dSDavid van Moolenbroek char name[NAME_MAX+1];
65789c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
65889c9de7dSDavid van Moolenbroek size_t path_len;
65989c9de7dSDavid van Moolenbroek ino_t dir_nr;
66089c9de7dSDavid van Moolenbroek uid_t uid;
66189c9de7dSDavid van Moolenbroek gid_t gid;
66289c9de7dSDavid van Moolenbroek int r;
66389c9de7dSDavid van Moolenbroek
66489c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_slink.grant_path;
66589c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_slink.path_len;
66689c9de7dSDavid van Moolenbroek dir_nr = m_in->m_vfs_fs_slink.inode;
66789c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_slink.uid;
66889c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_slink.gid;
66989c9de7dSDavid van Moolenbroek
67089c9de7dSDavid van Moolenbroek if (fdp->fdr_slink == NULL)
67189c9de7dSDavid van Moolenbroek return ENOSYS;
67289c9de7dSDavid van Moolenbroek
67389c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, name,
67489c9de7dSDavid van Moolenbroek sizeof(name), TRUE /*not_empty*/)) != OK)
67589c9de7dSDavid van Moolenbroek return r;
67689c9de7dSDavid van Moolenbroek
67789c9de7dSDavid van Moolenbroek if (!strcmp(name, ".") || !strcmp(name, ".."))
67889c9de7dSDavid van Moolenbroek return EEXIST;
67989c9de7dSDavid van Moolenbroek
68089c9de7dSDavid van Moolenbroek data.endpt = m_in->m_source;
68189c9de7dSDavid van Moolenbroek data.grant = m_in->m_vfs_fs_slink.grant_target;
68289c9de7dSDavid van Moolenbroek data.size = m_in->m_vfs_fs_slink.mem_size;
68389c9de7dSDavid van Moolenbroek
68489c9de7dSDavid van Moolenbroek return fdp->fdr_slink(dir_nr, name, uid, gid, &data, data.size);
68589c9de7dSDavid van Moolenbroek }
68689c9de7dSDavid van Moolenbroek
68789c9de7dSDavid van Moolenbroek /*
68889c9de7dSDavid van Moolenbroek * Process a RDLINK request from VFS.
68989c9de7dSDavid van Moolenbroek */
69089c9de7dSDavid van Moolenbroek int
fsdriver_rdlink(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)69189c9de7dSDavid van Moolenbroek fsdriver_rdlink(const struct fsdriver * __restrict fdp,
69289c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
69389c9de7dSDavid van Moolenbroek {
69489c9de7dSDavid van Moolenbroek struct fsdriver_data data;
69589c9de7dSDavid van Moolenbroek ssize_t r;
69689c9de7dSDavid van Moolenbroek
69789c9de7dSDavid van Moolenbroek if (fdp->fdr_rdlink == NULL)
69889c9de7dSDavid van Moolenbroek return ENOSYS;
69989c9de7dSDavid van Moolenbroek
70089c9de7dSDavid van Moolenbroek data.endpt = m_in->m_source;
70189c9de7dSDavid van Moolenbroek data.grant = m_in->m_vfs_fs_rdlink.grant;
70289c9de7dSDavid van Moolenbroek data.size = m_in->m_vfs_fs_rdlink.mem_size;
70389c9de7dSDavid van Moolenbroek
70489c9de7dSDavid van Moolenbroek r = fdp->fdr_rdlink(m_in->m_vfs_fs_rdlink.inode, &data, data.size);
70589c9de7dSDavid van Moolenbroek
70689c9de7dSDavid van Moolenbroek if (r >= 0) {
70789c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_rdlink.nbytes = r;
70889c9de7dSDavid van Moolenbroek r = OK;
70989c9de7dSDavid van Moolenbroek }
71089c9de7dSDavid van Moolenbroek
71189c9de7dSDavid van Moolenbroek return r;
71289c9de7dSDavid van Moolenbroek }
71389c9de7dSDavid van Moolenbroek
71489c9de7dSDavid van Moolenbroek /*
71589c9de7dSDavid van Moolenbroek * Process a STAT request from VFS.
71689c9de7dSDavid van Moolenbroek */
71789c9de7dSDavid van Moolenbroek int
fsdriver_stat(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)71889c9de7dSDavid van Moolenbroek fsdriver_stat(const struct fsdriver * __restrict fdp,
71989c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
72089c9de7dSDavid van Moolenbroek {
72189c9de7dSDavid van Moolenbroek struct stat buf;
72289c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
72389c9de7dSDavid van Moolenbroek ino_t ino_nr;
72489c9de7dSDavid van Moolenbroek int r;
72589c9de7dSDavid van Moolenbroek
72689c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_stat.inode;
72789c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_stat.grant;
72889c9de7dSDavid van Moolenbroek
72989c9de7dSDavid van Moolenbroek if (fdp->fdr_stat == NULL)
73089c9de7dSDavid van Moolenbroek return ENOSYS;
73189c9de7dSDavid van Moolenbroek
73289c9de7dSDavid van Moolenbroek memset(&buf, 0, sizeof(buf));
733289b0467SDavid van Moolenbroek buf.st_dev = fsdriver_device;
73422840deaSDavid van Moolenbroek buf.st_ino = ino_nr;
73589c9de7dSDavid van Moolenbroek
73689c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_stat(ino_nr, &buf)) == OK)
73789c9de7dSDavid van Moolenbroek r = sys_safecopyto(m_in->m_source, grant, 0, (vir_bytes)&buf,
73889c9de7dSDavid van Moolenbroek (phys_bytes)sizeof(buf));
73989c9de7dSDavid van Moolenbroek
74089c9de7dSDavid van Moolenbroek return r;
74189c9de7dSDavid van Moolenbroek }
74289c9de7dSDavid van Moolenbroek
74389c9de7dSDavid van Moolenbroek /*
74489c9de7dSDavid van Moolenbroek * Process a CHOWN request from VFS.
74589c9de7dSDavid van Moolenbroek */
74689c9de7dSDavid van Moolenbroek int
fsdriver_chown(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)74789c9de7dSDavid van Moolenbroek fsdriver_chown(const struct fsdriver * __restrict fdp,
74889c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
74989c9de7dSDavid van Moolenbroek {
75089c9de7dSDavid van Moolenbroek ino_t ino_nr;
75189c9de7dSDavid van Moolenbroek uid_t uid;
75289c9de7dSDavid van Moolenbroek gid_t gid;
75389c9de7dSDavid van Moolenbroek mode_t mode;
75489c9de7dSDavid van Moolenbroek int r;
75589c9de7dSDavid van Moolenbroek
75689c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_chown.inode;
75789c9de7dSDavid van Moolenbroek uid = m_in->m_vfs_fs_chown.uid;
75889c9de7dSDavid van Moolenbroek gid = m_in->m_vfs_fs_chown.gid;
75989c9de7dSDavid van Moolenbroek
76089c9de7dSDavid van Moolenbroek if (fdp->fdr_chown == NULL)
76189c9de7dSDavid van Moolenbroek return ENOSYS;
76289c9de7dSDavid van Moolenbroek
76389c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_chown(ino_nr, uid, gid, &mode)) == OK)
76489c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_chown.mode = mode;
76589c9de7dSDavid van Moolenbroek
76689c9de7dSDavid van Moolenbroek return r;
76789c9de7dSDavid van Moolenbroek }
76889c9de7dSDavid van Moolenbroek
76989c9de7dSDavid van Moolenbroek /*
77089c9de7dSDavid van Moolenbroek * Process a CHMOD request from VFS.
77189c9de7dSDavid van Moolenbroek */
77289c9de7dSDavid van Moolenbroek int
fsdriver_chmod(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)77389c9de7dSDavid van Moolenbroek fsdriver_chmod(const struct fsdriver * __restrict fdp,
77489c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
77589c9de7dSDavid van Moolenbroek {
77689c9de7dSDavid van Moolenbroek ino_t ino_nr;
77789c9de7dSDavid van Moolenbroek mode_t mode;
77889c9de7dSDavid van Moolenbroek int r;
77989c9de7dSDavid van Moolenbroek
78089c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_chmod.inode;
78189c9de7dSDavid van Moolenbroek mode = m_in->m_vfs_fs_chmod.mode;
78289c9de7dSDavid van Moolenbroek
78389c9de7dSDavid van Moolenbroek if (fdp->fdr_chmod == NULL)
78489c9de7dSDavid van Moolenbroek return ENOSYS;
78589c9de7dSDavid van Moolenbroek
78689c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_chmod(ino_nr, &mode)) == OK)
78789c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_chmod.mode = mode;
78889c9de7dSDavid van Moolenbroek
78989c9de7dSDavid van Moolenbroek return r;
79089c9de7dSDavid van Moolenbroek }
79189c9de7dSDavid van Moolenbroek
79289c9de7dSDavid van Moolenbroek /*
79389c9de7dSDavid van Moolenbroek * Process a UTIME request from VFS.
79489c9de7dSDavid van Moolenbroek */
79589c9de7dSDavid van Moolenbroek int
fsdriver_utime(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)79689c9de7dSDavid van Moolenbroek fsdriver_utime(const struct fsdriver * __restrict fdp,
79789c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
79889c9de7dSDavid van Moolenbroek {
79989c9de7dSDavid van Moolenbroek ino_t ino_nr;
80089c9de7dSDavid van Moolenbroek struct timespec atime, mtime;
80189c9de7dSDavid van Moolenbroek
80289c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_utime.inode;
80389c9de7dSDavid van Moolenbroek atime.tv_sec = m_in->m_vfs_fs_utime.actime;
80489c9de7dSDavid van Moolenbroek atime.tv_nsec = m_in->m_vfs_fs_utime.acnsec;
80589c9de7dSDavid van Moolenbroek mtime.tv_sec = m_in->m_vfs_fs_utime.modtime;
80689c9de7dSDavid van Moolenbroek mtime.tv_nsec = m_in->m_vfs_fs_utime.modnsec;
80789c9de7dSDavid van Moolenbroek
80889c9de7dSDavid van Moolenbroek if (fdp->fdr_utime == NULL)
80989c9de7dSDavid van Moolenbroek return ENOSYS;
81089c9de7dSDavid van Moolenbroek
81189c9de7dSDavid van Moolenbroek return fdp->fdr_utime(ino_nr, &atime, &mtime);
81289c9de7dSDavid van Moolenbroek }
81389c9de7dSDavid van Moolenbroek
81489c9de7dSDavid van Moolenbroek /*
81589c9de7dSDavid van Moolenbroek * Process a MOUNTPOINT request from VFS.
81689c9de7dSDavid van Moolenbroek */
81789c9de7dSDavid van Moolenbroek int
fsdriver_mountpoint(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)81889c9de7dSDavid van Moolenbroek fsdriver_mountpoint(const struct fsdriver * __restrict fdp,
81989c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
82089c9de7dSDavid van Moolenbroek {
82189c9de7dSDavid van Moolenbroek ino_t ino_nr;
82289c9de7dSDavid van Moolenbroek
82389c9de7dSDavid van Moolenbroek ino_nr = m_in->m_vfs_fs_mountpoint.inode;
82489c9de7dSDavid van Moolenbroek
82589c9de7dSDavid van Moolenbroek if (fdp->fdr_mountpt == NULL)
82689c9de7dSDavid van Moolenbroek return ENOSYS;
82789c9de7dSDavid van Moolenbroek
82889c9de7dSDavid van Moolenbroek return fdp->fdr_mountpt(ino_nr);
82989c9de7dSDavid van Moolenbroek }
83089c9de7dSDavid van Moolenbroek
83189c9de7dSDavid van Moolenbroek /*
83289c9de7dSDavid van Moolenbroek * Process a STATVFS request from VFS.
83389c9de7dSDavid van Moolenbroek */
83489c9de7dSDavid van Moolenbroek int
fsdriver_statvfs(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)83589c9de7dSDavid van Moolenbroek fsdriver_statvfs(const struct fsdriver * __restrict fdp,
83689c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
83789c9de7dSDavid van Moolenbroek {
83889c9de7dSDavid van Moolenbroek struct statvfs buf;
83989c9de7dSDavid van Moolenbroek int r;
84089c9de7dSDavid van Moolenbroek
84189c9de7dSDavid van Moolenbroek if (fdp->fdr_statvfs == NULL)
84289c9de7dSDavid van Moolenbroek return ENOSYS;
84389c9de7dSDavid van Moolenbroek
84489c9de7dSDavid van Moolenbroek memset(&buf, 0, sizeof(buf));
84589c9de7dSDavid van Moolenbroek
84689c9de7dSDavid van Moolenbroek if ((r = fdp->fdr_statvfs(&buf)) != OK)
84789c9de7dSDavid van Moolenbroek return r;
84889c9de7dSDavid van Moolenbroek
84989c9de7dSDavid van Moolenbroek return sys_safecopyto(m_in->m_source, m_in->m_vfs_fs_statvfs.grant, 0,
85089c9de7dSDavid van Moolenbroek (vir_bytes)&buf, (phys_bytes)sizeof(buf));
85189c9de7dSDavid van Moolenbroek }
85289c9de7dSDavid van Moolenbroek
85389c9de7dSDavid van Moolenbroek /*
85489c9de7dSDavid van Moolenbroek * Process a SYNC request from VFS.
85589c9de7dSDavid van Moolenbroek */
85689c9de7dSDavid van Moolenbroek int
fsdriver_sync(const struct fsdriver * __restrict fdp,const message * __restrict __unused m_in,message * __restrict __unused m_out)85789c9de7dSDavid van Moolenbroek fsdriver_sync(const struct fsdriver * __restrict fdp,
85889c9de7dSDavid van Moolenbroek const message * __restrict __unused m_in,
85989c9de7dSDavid van Moolenbroek message * __restrict __unused m_out)
86089c9de7dSDavid van Moolenbroek {
86189c9de7dSDavid van Moolenbroek
86289c9de7dSDavid van Moolenbroek if (fdp->fdr_sync != NULL)
86389c9de7dSDavid van Moolenbroek fdp->fdr_sync();
86489c9de7dSDavid van Moolenbroek
86589c9de7dSDavid van Moolenbroek return OK;
86689c9de7dSDavid van Moolenbroek }
86789c9de7dSDavid van Moolenbroek
86889c9de7dSDavid van Moolenbroek /*
86989c9de7dSDavid van Moolenbroek * Process a NEW_DRIVER request from VFS.
87089c9de7dSDavid van Moolenbroek */
87189c9de7dSDavid van Moolenbroek int
fsdriver_newdriver(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)87289c9de7dSDavid van Moolenbroek fsdriver_newdriver(const struct fsdriver * __restrict fdp,
87389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
87489c9de7dSDavid van Moolenbroek {
87589c9de7dSDavid van Moolenbroek char label[DS_MAX_KEYLEN];
87689c9de7dSDavid van Moolenbroek cp_grant_id_t grant;
87789c9de7dSDavid van Moolenbroek size_t path_len;
87889c9de7dSDavid van Moolenbroek dev_t dev;
87989c9de7dSDavid van Moolenbroek int r;
88089c9de7dSDavid van Moolenbroek
88189c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_new_driver.device;
88289c9de7dSDavid van Moolenbroek grant = m_in->m_vfs_fs_new_driver.grant;
88389c9de7dSDavid van Moolenbroek path_len = m_in->m_vfs_fs_new_driver.path_len;
88489c9de7dSDavid van Moolenbroek
88589c9de7dSDavid van Moolenbroek if (fdp->fdr_driver == NULL)
88689c9de7dSDavid van Moolenbroek return OK;
88789c9de7dSDavid van Moolenbroek
88889c9de7dSDavid van Moolenbroek if ((r = fsdriver_getname(m_in->m_source, grant, path_len, label,
88989c9de7dSDavid van Moolenbroek sizeof(label), FALSE /*not_empty*/)) != OK)
89089c9de7dSDavid van Moolenbroek return r;
89189c9de7dSDavid van Moolenbroek
89289c9de7dSDavid van Moolenbroek fdp->fdr_driver(dev, label);
89389c9de7dSDavid van Moolenbroek
89489c9de7dSDavid van Moolenbroek return OK;
89589c9de7dSDavid van Moolenbroek }
89689c9de7dSDavid van Moolenbroek
89789c9de7dSDavid van Moolenbroek /*
89889c9de7dSDavid van Moolenbroek * Process a block read or write request from VFS.
89989c9de7dSDavid van Moolenbroek */
90089c9de7dSDavid van Moolenbroek static ssize_t
bread_bwrite(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out,int call)90189c9de7dSDavid van Moolenbroek bread_bwrite(const struct fsdriver * __restrict fdp,
90289c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out, int call)
90389c9de7dSDavid van Moolenbroek {
90489c9de7dSDavid van Moolenbroek struct fsdriver_data data;
90589c9de7dSDavid van Moolenbroek dev_t dev;
90689c9de7dSDavid van Moolenbroek off_t pos;
90789c9de7dSDavid van Moolenbroek size_t nbytes;
90889c9de7dSDavid van Moolenbroek ssize_t r;
90989c9de7dSDavid van Moolenbroek
91089c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_breadwrite.device;
91189c9de7dSDavid van Moolenbroek pos = m_in->m_vfs_fs_breadwrite.seek_pos;
91289c9de7dSDavid van Moolenbroek nbytes = m_in->m_vfs_fs_breadwrite.nbytes;
91389c9de7dSDavid van Moolenbroek
91489c9de7dSDavid van Moolenbroek if (pos < 0 || nbytes > SSIZE_MAX)
91589c9de7dSDavid van Moolenbroek return EINVAL;
91689c9de7dSDavid van Moolenbroek
91789c9de7dSDavid van Moolenbroek data.endpt = m_in->m_source;
91889c9de7dSDavid van Moolenbroek data.grant = m_in->m_vfs_fs_breadwrite.grant;
91989c9de7dSDavid van Moolenbroek data.size = nbytes;
92089c9de7dSDavid van Moolenbroek
92189c9de7dSDavid van Moolenbroek if (call == FSC_WRITE)
92289c9de7dSDavid van Moolenbroek r = fdp->fdr_bwrite(dev, &data, nbytes, pos, call);
92389c9de7dSDavid van Moolenbroek else
92489c9de7dSDavid van Moolenbroek r = fdp->fdr_bread(dev, &data, nbytes, pos, call);
92589c9de7dSDavid van Moolenbroek
92689c9de7dSDavid van Moolenbroek if (r >= 0) {
92789c9de7dSDavid van Moolenbroek pos += r;
92889c9de7dSDavid van Moolenbroek
92989c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_breadwrite.seek_pos = pos;
93089c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_breadwrite.nbytes = r;
93189c9de7dSDavid van Moolenbroek r = OK;
93289c9de7dSDavid van Moolenbroek }
93389c9de7dSDavid van Moolenbroek
93489c9de7dSDavid van Moolenbroek return r;
93589c9de7dSDavid van Moolenbroek }
93689c9de7dSDavid van Moolenbroek
93789c9de7dSDavid van Moolenbroek /*
93889c9de7dSDavid van Moolenbroek * Process a BREAD request from VFS.
93989c9de7dSDavid van Moolenbroek */
94089c9de7dSDavid van Moolenbroek ssize_t
fsdriver_bread(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)94189c9de7dSDavid van Moolenbroek fsdriver_bread(const struct fsdriver * __restrict fdp,
94289c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
94389c9de7dSDavid van Moolenbroek {
94489c9de7dSDavid van Moolenbroek
94589c9de7dSDavid van Moolenbroek if (fdp->fdr_bread == NULL)
94689c9de7dSDavid van Moolenbroek return ENOSYS;
94789c9de7dSDavid van Moolenbroek
94889c9de7dSDavid van Moolenbroek return bread_bwrite(fdp, m_in, m_out, FSC_READ);
94989c9de7dSDavid van Moolenbroek }
95089c9de7dSDavid van Moolenbroek
95189c9de7dSDavid van Moolenbroek /*
95289c9de7dSDavid van Moolenbroek * Process a BWRITE request from VFS.
95389c9de7dSDavid van Moolenbroek */
95489c9de7dSDavid van Moolenbroek ssize_t
fsdriver_bwrite(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict m_out)95589c9de7dSDavid van Moolenbroek fsdriver_bwrite(const struct fsdriver * __restrict fdp,
95689c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict m_out)
95789c9de7dSDavid van Moolenbroek {
95889c9de7dSDavid van Moolenbroek
95989c9de7dSDavid van Moolenbroek if (fdp->fdr_bwrite == NULL)
96089c9de7dSDavid van Moolenbroek return ENOSYS;
96189c9de7dSDavid van Moolenbroek
96289c9de7dSDavid van Moolenbroek return bread_bwrite(fdp, m_in, m_out, FSC_WRITE);
96389c9de7dSDavid van Moolenbroek }
96489c9de7dSDavid van Moolenbroek
96589c9de7dSDavid van Moolenbroek /*
96689c9de7dSDavid van Moolenbroek * Process a BPEEK request from VFS.
96789c9de7dSDavid van Moolenbroek */
96889c9de7dSDavid van Moolenbroek int
fsdriver_bpeek(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)96989c9de7dSDavid van Moolenbroek fsdriver_bpeek(const struct fsdriver * __restrict fdp,
97089c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
97189c9de7dSDavid van Moolenbroek {
97289c9de7dSDavid van Moolenbroek dev_t dev;
97389c9de7dSDavid van Moolenbroek off_t pos;
97489c9de7dSDavid van Moolenbroek size_t nbytes;
97589c9de7dSDavid van Moolenbroek ssize_t r;
97689c9de7dSDavid van Moolenbroek
97789c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_breadwrite.device;
97889c9de7dSDavid van Moolenbroek pos = m_in->m_vfs_fs_breadwrite.seek_pos;
97989c9de7dSDavid van Moolenbroek nbytes = m_in->m_vfs_fs_breadwrite.nbytes;
98089c9de7dSDavid van Moolenbroek
98189c9de7dSDavid van Moolenbroek if (fdp->fdr_bpeek == NULL)
98289c9de7dSDavid van Moolenbroek return ENOSYS;
98389c9de7dSDavid van Moolenbroek
98489c9de7dSDavid van Moolenbroek if (pos < 0 || nbytes > SSIZE_MAX)
98589c9de7dSDavid van Moolenbroek return EINVAL;
98689c9de7dSDavid van Moolenbroek
98789c9de7dSDavid van Moolenbroek r = fdp->fdr_bpeek(dev, NULL /*data*/, nbytes, pos, FSC_PEEK);
98889c9de7dSDavid van Moolenbroek
98989c9de7dSDavid van Moolenbroek /* Do not return a new position. */
99089c9de7dSDavid van Moolenbroek if (r >= 0) {
99189c9de7dSDavid van Moolenbroek m_out->m_fs_vfs_breadwrite.nbytes = r;
99289c9de7dSDavid van Moolenbroek r = OK;
99389c9de7dSDavid van Moolenbroek }
99489c9de7dSDavid van Moolenbroek
99589c9de7dSDavid van Moolenbroek return r;
99689c9de7dSDavid van Moolenbroek }
99789c9de7dSDavid van Moolenbroek
99889c9de7dSDavid van Moolenbroek /*
99989c9de7dSDavid van Moolenbroek * Process a FLUSH request from VFS.
100089c9de7dSDavid van Moolenbroek */
100189c9de7dSDavid van Moolenbroek int
fsdriver_flush(const struct fsdriver * __restrict fdp,const message * __restrict m_in,message * __restrict __unused m_out)100289c9de7dSDavid van Moolenbroek fsdriver_flush(const struct fsdriver * __restrict fdp,
100389c9de7dSDavid van Moolenbroek const message * __restrict m_in, message * __restrict __unused m_out)
100489c9de7dSDavid van Moolenbroek {
100589c9de7dSDavid van Moolenbroek dev_t dev;
100689c9de7dSDavid van Moolenbroek
100789c9de7dSDavid van Moolenbroek dev = m_in->m_vfs_fs_flush.device;
100889c9de7dSDavid van Moolenbroek
100989c9de7dSDavid van Moolenbroek if (fdp->fdr_bflush != NULL)
101089c9de7dSDavid van Moolenbroek fdp->fdr_bflush(dev);
101189c9de7dSDavid van Moolenbroek
101289c9de7dSDavid van Moolenbroek return OK;
101389c9de7dSDavid van Moolenbroek }
1014