tools/llvm: Do not build with symbols
[minix3.git] / minix / servers / vfs / request.c
blob7be99e38481380b6b7df8054a57482ae92b35220
1 /* This file contains the wrapper functions for issuing a request
2 * and receiving response from FS processes.
3 * Each function builds a request message according to the request
4 * parameter, calls the most low-level fs_sendrec, and copies
5 * back the response.
6 */
8 #include "fs.h"
9 #include <minix/com.h>
10 #include <minix/const.h>
11 #include <minix/endpoint.h>
12 #include <minix/u64.h>
13 #include <minix/vfsif.h>
14 #include <sys/dirent.h>
15 #include <sys/stat.h>
16 #include <sys/statvfs.h>
17 #include <assert.h>
18 #include <stddef.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <time.h>
22 #include "path.h"
23 #include "vmnt.h"
24 #include "vnode.h"
27 /*===========================================================================*
28 * req_breadwrite_actual *
29 *===========================================================================*/
30 static int req_breadwrite_actual(endpoint_t fs_e, endpoint_t user_e, dev_t dev, off_t pos,
31 unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag,
32 off_t *new_pos, unsigned int *cum_iop, int cpflag)
34 int r;
35 cp_grant_id_t grant_id;
36 message m;
38 grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
39 (rw_flag == READING ? CPF_WRITE : CPF_READ) | cpflag);
40 if(grant_id == -1)
41 panic("req_breadwrite: cpf_grant_magic failed");
43 /* Fill in request message */
44 m.m_type = rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
45 m.m_vfs_fs_breadwrite.device = dev;
46 m.m_vfs_fs_breadwrite.grant = grant_id;
47 m.m_vfs_fs_breadwrite.seek_pos = pos;
48 m.m_vfs_fs_breadwrite.nbytes = num_of_bytes;
50 /* Send/rec request */
51 r = fs_sendrec(fs_e, &m);
52 cpf_revoke(grant_id);
53 if (r != OK) return(r);
55 /* Fill in response structure */
56 *new_pos = m.m_fs_vfs_breadwrite.seek_pos;
57 *cum_iop = m.m_fs_vfs_breadwrite.nbytes;
59 return(OK);
62 int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, off_t pos,
63 unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag,
64 off_t *new_pos, unsigned int *cum_iop)
66 int r;
68 r = req_breadwrite_actual(fs_e, user_e, dev, pos, num_of_bytes,
69 user_addr, rw_flag, new_pos, cum_iop, CPF_TRY);
71 if(r == EFAULT) {
72 if((r=vm_vfs_procctl_handlemem(user_e, user_addr, num_of_bytes,
73 rw_flag == READING)) != OK) {
74 return r;
77 r = req_breadwrite_actual(fs_e, user_e, dev, pos, num_of_bytes,
78 user_addr, rw_flag, new_pos, cum_iop, 0);
81 return r;
84 /*===========================================================================*
85 * req_bpeek *
86 *===========================================================================*/
87 int req_bpeek(endpoint_t fs_e, dev_t dev, off_t pos, unsigned int num_of_bytes)
89 message m;
91 memset(&m, 0, sizeof(m));
93 /* Fill in request message */
94 m.m_type = REQ_BPEEK;
95 m.m_vfs_fs_breadwrite.device = dev;
96 m.m_vfs_fs_breadwrite.seek_pos = pos;
97 m.m_vfs_fs_breadwrite.nbytes = num_of_bytes;
99 /* Send/rec request */
100 return fs_sendrec(fs_e, &m);
103 /*===========================================================================*
104 * req_chmod *
105 *===========================================================================*/
106 int req_chmod(
107 endpoint_t fs_e,
108 ino_t inode_nr,
109 mode_t rmode,
110 mode_t *new_modep
113 message m;
114 int r;
116 /* Fill in request message */
117 m.m_type = REQ_CHMOD;
118 m.m_vfs_fs_chmod.inode = inode_nr;
119 m.m_vfs_fs_chmod.mode = rmode;
121 /* Send/rec request */
122 r = fs_sendrec(fs_e, &m);
124 /* Copy back actual mode. */
125 *new_modep = m.m_fs_vfs_chmod.mode;
127 return(r);
131 /*===========================================================================*
132 * req_chown *
133 *===========================================================================*/
134 int req_chown(
135 endpoint_t fs_e,
136 ino_t inode_nr,
137 uid_t newuid,
138 gid_t newgid,
139 mode_t *new_modep
142 message m;
143 int r;
145 /* Fill in request message */
146 m.m_type = REQ_CHOWN;
147 m.m_vfs_fs_chown.inode = inode_nr;
148 m.m_vfs_fs_chown.uid = newuid;
149 m.m_vfs_fs_chown.gid = newgid;
151 /* Send/rec request */
152 r = fs_sendrec(fs_e, &m);
154 /* Return new mode to caller. */
155 *new_modep = m.m_fs_vfs_chown.mode;
157 return(r);
161 /*===========================================================================*
162 * req_create *
163 *===========================================================================*/
164 int req_create(
165 endpoint_t fs_e,
166 ino_t inode_nr,
167 int omode,
168 uid_t uid,
169 gid_t gid,
170 char *path,
171 node_details_t *res
174 int r;
175 cp_grant_id_t grant_id;
176 size_t len;
177 message m;
178 struct vmnt *vmp;
180 vmp = find_vmnt(fs_e);
182 len = strlen(path) + 1;
183 grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ);
184 if (grant_id == -1)
185 panic("req_create: cpf_grant_direct failed");
187 /* Fill in request message */
188 m.m_type = REQ_CREATE;
189 m.m_vfs_fs_create.inode = inode_nr;
190 m.m_vfs_fs_create.mode = omode;
191 m.m_vfs_fs_create.uid = uid;
192 m.m_vfs_fs_create.gid = gid;
193 m.m_vfs_fs_create.grant = grant_id;
194 m.m_vfs_fs_create.path_len = len;
196 /* Send/rec request */
197 r = fs_sendrec(fs_e, &m);
198 cpf_revoke(grant_id);
199 if (r != OK) return(r);
201 /* Fill in response structure */
202 res->fs_e = m.m_source;
203 res->inode_nr = m.m_fs_vfs_create.inode;
204 res->fmode = m.m_fs_vfs_create.mode;
205 res->fsize = m.m_fs_vfs_create.file_size;
206 res->uid = m.m_fs_vfs_create.uid;
207 res->gid = m.m_fs_vfs_create.gid;
208 res->dev = NO_DEV;
210 return(OK);
214 /*===========================================================================*
215 * req_flush *
216 *===========================================================================*/
217 int req_flush(endpoint_t fs_e, dev_t dev)
219 message m;
221 /* Fill in request message */
222 m.m_type = REQ_FLUSH;
223 m.m_vfs_fs_flush.device = dev;
225 /* Send/rec request */
226 return fs_sendrec(fs_e, &m);
230 /*===========================================================================*
231 * req_statvfs *
232 *===========================================================================*/
233 int req_statvfs(endpoint_t fs_e, struct statvfs *buf)
235 int r;
236 cp_grant_id_t grant_id;
237 message m;
239 grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, sizeof(struct statvfs),
240 CPF_WRITE);
241 if(grant_id == GRANT_INVALID)
242 panic("req_statvfs: cpf_grant_direct failed");
244 /* Fill in request message */
245 m.m_type = REQ_STATVFS;
246 m.m_vfs_fs_statvfs.grant = grant_id;
248 /* Send/rec request */
249 r = fs_sendrec(fs_e, &m);
250 cpf_revoke(grant_id);
252 return(r);
256 /*===========================================================================*
257 * req_ftrunc *
258 *===========================================================================*/
259 int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end)
261 message m;
262 struct vmnt *vmp;
264 vmp = find_vmnt(fs_e);
266 /* Fill in request message */
267 m.m_type = REQ_FTRUNC;
268 m.m_vfs_fs_ftrunc.inode = inode_nr;
269 m.m_vfs_fs_ftrunc.trc_start = start;
270 m.m_vfs_fs_ftrunc.trc_end = end;
272 if (!(vmp->m_fs_flags & RES_64BIT) &&
273 ((start > INT_MAX) || (end > INT_MAX))) {
274 /* FS does not support 64-bit off_t and 32 bits is not enough */
275 return EINVAL;
278 /* Send/rec request */
279 return fs_sendrec(fs_e, &m);
283 /*===========================================================================*
284 * req_getdents_actual *
285 *===========================================================================*/
286 static int req_getdents_actual(
287 endpoint_t fs_e,
288 ino_t inode_nr,
289 off_t pos,
290 vir_bytes buf,
291 size_t size,
292 off_t *new_pos,
293 int direct,
294 int cpflag
297 int r;
298 message m;
299 cp_grant_id_t grant_id;
300 struct vmnt *vmp;
302 vmp = find_vmnt(fs_e);
303 assert(vmp != NULL);
305 if (direct) {
306 grant_id = cpf_grant_direct(fs_e, buf, size, CPF_WRITE);
307 } else {
308 grant_id = cpf_grant_magic(fs_e, who_e, buf, size,
309 CPF_WRITE | cpflag);
312 if (grant_id < 0)
313 panic("req_getdents: cpf_grant_direct/cpf_grant_magic failed: %d",
314 grant_id);
316 m.m_type = REQ_GETDENTS;
317 m.m_vfs_fs_getdents.inode = inode_nr;
318 m.m_vfs_fs_getdents.grant = grant_id;
319 m.m_vfs_fs_getdents.mem_size = size;
320 m.m_vfs_fs_getdents.seek_pos = pos;
321 if (!(vmp->m_fs_flags & RES_64BIT) && (pos > INT_MAX)) {
322 /* FS does not support 64-bit off_t and 32 bits is not enough */
323 return EINVAL;
326 r = fs_sendrec(fs_e, &m);
327 cpf_revoke(grant_id);
329 if (r == OK) {
330 *new_pos = m.m_fs_vfs_getdents.seek_pos;
331 r = m.m_fs_vfs_getdents.nbytes;
334 return(r);
337 /*===========================================================================*
338 * req_getdents *
339 *===========================================================================*/
340 int req_getdents(
341 endpoint_t fs_e,
342 ino_t inode_nr,
343 off_t pos,
344 vir_bytes buf,
345 size_t size,
346 off_t *new_pos,
347 int direct)
349 int r;
351 r = req_getdents_actual(fs_e, inode_nr, pos, buf, size, new_pos,
352 direct, CPF_TRY);
354 if(r == EFAULT && !direct) {
355 if((r=vm_vfs_procctl_handlemem(who_e, buf, size, 1)) != OK) {
356 return r;
359 r = req_getdents_actual(fs_e, inode_nr, pos, buf, size,
360 new_pos, direct, 0);
363 return r;
366 /*===========================================================================*
367 * req_inhibread *
368 *===========================================================================*/
369 int req_inhibread(endpoint_t fs_e, ino_t inode_nr)
371 message m;
373 /* Fill in request message */
374 m.m_type = REQ_INHIBREAD;
375 m.m_vfs_fs_inhibread.inode = inode_nr;
377 /* Send/rec request */
378 return fs_sendrec(fs_e, &m);
382 /*===========================================================================*
383 * req_link *
384 *===========================================================================*/
385 int req_link(
386 endpoint_t fs_e,
387 ino_t link_parent,
388 char *lastc,
389 ino_t linked_file
392 int r;
393 cp_grant_id_t grant_id;
394 const size_t len = strlen(lastc) + 1;
395 message m;
397 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
398 if(grant_id == -1)
399 panic("req_link: cpf_grant_direct failed");
401 /* Fill in request message */
402 m.m_type = REQ_LINK;
403 m.m_vfs_fs_link.inode = linked_file;
404 m.m_vfs_fs_link.dir_ino = link_parent;
405 m.m_vfs_fs_link.grant = grant_id;
406 m.m_vfs_fs_link.path_len = len;
408 /* Send/rec request */
409 r = fs_sendrec(fs_e, &m);
410 cpf_revoke(grant_id);
412 return(r);
416 /*===========================================================================*
417 * req_lookup *
418 *===========================================================================*/
419 int req_lookup(
420 endpoint_t fs_e,
421 ino_t dir_ino,
422 ino_t root_ino,
423 uid_t uid,
424 gid_t gid,
425 struct lookup *resolve,
426 lookup_res_t *res,
427 struct fproc *rfp
430 message m;
431 vfs_ucred_t credentials;
432 int r, flags;
433 size_t len;
434 struct vmnt *vmp;
435 cp_grant_id_t grant_id=0, grant_id2=0;
437 vmp = find_vmnt(fs_e);
439 grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX,
440 CPF_READ | CPF_WRITE);
441 if(grant_id == -1)
442 panic("req_lookup: cpf_grant_direct failed");
444 flags = resolve->l_flags;
445 len = strlen(resolve->l_path) + 1;
447 m.m_type = REQ_LOOKUP;
448 m.m_vfs_fs_lookup.grant_path = grant_id;
449 m.m_vfs_fs_lookup.path_len = len;
450 m.m_vfs_fs_lookup.path_size = PATH_MAX + 1;
451 m.m_vfs_fs_lookup.dir_ino = dir_ino;
452 m.m_vfs_fs_lookup.root_ino = root_ino;
454 if(rfp->fp_ngroups > 0) { /* Is the process member of multiple groups? */
455 /* In that case the FS has to copy the uid/gid credentials */
456 int i;
458 /* Set credentials */
459 credentials.vu_uid = rfp->fp_effuid;
460 credentials.vu_gid = rfp->fp_effgid;
461 credentials.vu_ngroups = rfp->fp_ngroups;
462 for (i = 0; i < rfp->fp_ngroups; i++)
463 credentials.vu_sgroups[i] = rfp->fp_sgroups[i];
465 grant_id2 = cpf_grant_direct(fs_e, (vir_bytes) &credentials,
466 sizeof(credentials), CPF_READ);
467 if(grant_id2 == -1)
468 panic("req_lookup: cpf_grant_direct failed");
470 m.m_vfs_fs_lookup.grant_ucred = grant_id2;
471 m.m_vfs_fs_lookup.ucred_size = sizeof(credentials);
472 flags |= PATH_GET_UCRED;
473 } else {
474 /* When there's only one gid, we can send it directly */
475 m.m_vfs_fs_lookup.uid = uid;
476 m.m_vfs_fs_lookup.gid = gid;
477 flags &= ~PATH_GET_UCRED;
480 m.m_vfs_fs_lookup.flags = flags;
482 /* Send/rec request */
483 r = fs_sendrec(fs_e, &m);
484 cpf_revoke(grant_id);
485 if(rfp->fp_ngroups > 0) cpf_revoke(grant_id2);
487 /* Fill in response according to the return value */
488 res->fs_e = m.m_source;
490 switch (r) {
491 case OK:
492 res->inode_nr = m.m_fs_vfs_lookup.inode;
493 res->fmode = m.m_fs_vfs_lookup.mode;
494 res->fsize = m.m_fs_vfs_lookup.file_size;
495 res->dev = m.m_fs_vfs_lookup.device;
496 res->uid = m.m_fs_vfs_lookup.uid;
497 res->gid = m.m_fs_vfs_lookup.gid;
498 break;
499 case EENTERMOUNT:
500 res->inode_nr = m.m_fs_vfs_lookup.inode;
501 res->char_processed = m.m_fs_vfs_lookup.offset;
502 res->symloop = m.m_fs_vfs_lookup.symloop;
503 break;
504 case ELEAVEMOUNT:
505 res->char_processed = m.m_fs_vfs_lookup.offset;
506 res->symloop = m.m_fs_vfs_lookup.symloop;
507 break;
508 case ESYMLINK:
509 res->char_processed = m.m_fs_vfs_lookup.offset;
510 res->symloop = m.m_fs_vfs_lookup.symloop;
511 break;
512 default:
513 break;
516 return(r);
520 /*===========================================================================*
521 * req_mkdir *
522 *===========================================================================*/
523 int req_mkdir(
524 endpoint_t fs_e,
525 ino_t inode_nr,
526 char *lastc,
527 uid_t uid,
528 gid_t gid,
529 mode_t dmode
532 int r;
533 cp_grant_id_t grant_id;
534 size_t len;
535 message m;
537 len = strlen(lastc) + 1;
538 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
539 if(grant_id == -1)
540 panic("req_mkdir: cpf_grant_direct failed");
542 /* Fill in request message */
543 m.m_type = REQ_MKDIR;
544 m.m_vfs_fs_mkdir.inode = inode_nr;
545 m.m_vfs_fs_mkdir.mode = dmode;
546 m.m_vfs_fs_mkdir.uid = uid;
547 m.m_vfs_fs_mkdir.gid = gid;
548 m.m_vfs_fs_mkdir.grant = grant_id;
549 m.m_vfs_fs_mkdir.path_len = len;
551 /* Send/rec request */
552 r = fs_sendrec(fs_e, &m);
553 cpf_revoke(grant_id);
555 return(r);
559 /*===========================================================================*
560 * req_mknod *
561 *===========================================================================*/
562 int req_mknod(
563 endpoint_t fs_e,
564 ino_t inode_nr,
565 char *lastc,
566 uid_t uid,
567 gid_t gid,
568 mode_t dmode,
569 dev_t dev
572 int r;
573 size_t len;
574 cp_grant_id_t grant_id;
575 message m;
577 len = strlen(lastc) + 1;
578 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
579 if(grant_id == -1)
580 panic("req_mknod: cpf_grant_direct failed");
582 /* Fill in request message */
583 m.m_type = REQ_MKNOD;
584 m.m_vfs_fs_mknod.inode = inode_nr;
585 m.m_vfs_fs_mknod.mode = dmode;
586 m.m_vfs_fs_mknod.device = dev;
587 m.m_vfs_fs_mknod.uid = uid;
588 m.m_vfs_fs_mknod.gid = gid;
589 m.m_vfs_fs_mknod.grant = grant_id;
590 m.m_vfs_fs_mknod.path_len = len;
592 /* Send/rec request */
593 r = fs_sendrec(fs_e, &m);
594 cpf_revoke(grant_id);
596 return(r);
600 /*===========================================================================*
601 * req_mountpoint *
602 *===========================================================================*/
603 int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
605 message m;
607 /* Fill in request message */
608 m.m_type = REQ_MOUNTPOINT;
609 m.m_vfs_fs_mountpoint.inode = inode_nr;
611 /* Send/rec request */
612 return fs_sendrec(fs_e, &m);
616 /*===========================================================================*
617 * req_newnode *
618 *===========================================================================*/
619 int req_newnode(
620 endpoint_t fs_e,
621 uid_t uid,
622 gid_t gid,
623 mode_t dmode,
624 dev_t dev,
625 struct node_details *res
628 struct vmnt *vmp;
629 int r;
630 message m;
632 vmp = find_vmnt(fs_e);
634 /* Fill in request message */
635 m.m_type = REQ_NEWNODE;
636 m.m_vfs_fs_newnode.mode = dmode;
637 m.m_vfs_fs_newnode.device = dev;
638 m.m_vfs_fs_newnode.uid = uid;
639 m.m_vfs_fs_newnode.gid = gid;
641 /* Send/rec request */
642 r = fs_sendrec(fs_e, &m);
644 res->fs_e = m.m_source;
645 res->inode_nr = m.m_fs_vfs_newnode.inode;
646 res->fmode = m.m_fs_vfs_newnode.mode;
647 res->fsize = m.m_fs_vfs_newnode.file_size;
648 res->dev = m.m_fs_vfs_newnode.device;
649 res->uid = m.m_fs_vfs_newnode.uid;
650 res->gid = m.m_fs_vfs_newnode.gid;
652 return(r);
656 /*===========================================================================*
657 * req_newdriver *
658 *===========================================================================*/
659 int req_newdriver(
660 endpoint_t fs_e,
661 dev_t dev,
662 char *label
665 cp_grant_id_t grant_id;
666 size_t len;
667 message m;
668 int r;
670 /* Grant access to label */
671 len = strlen(label) + 1;
672 grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
673 if (grant_id == -1)
674 panic("req_newdriver: cpf_grant_direct failed");
676 /* Fill in request message */
677 m.m_type = REQ_NEW_DRIVER;
678 m.m_vfs_fs_new_driver.device = dev;
679 m.m_vfs_fs_new_driver.grant = grant_id;
680 m.m_vfs_fs_new_driver.path_len = len;
682 /* Issue request */
683 r = fs_sendrec(fs_e, &m);
685 cpf_revoke(grant_id);
687 return(r);
691 /*===========================================================================*
692 * req_putnode *
693 *===========================================================================*/
694 int req_putnode(fs_e, inode_nr, count)
695 int fs_e;
696 ino_t inode_nr;
697 int count;
699 message m;
701 /* Fill in request message */
702 m.m_type = REQ_PUTNODE;
703 m.m_vfs_fs_putnode.inode = inode_nr;
704 m.m_vfs_fs_putnode.count = count;
706 /* Send/rec request */
707 return fs_sendrec(fs_e, &m);
711 /*===========================================================================*
712 * req_rdlink_actual *
713 *===========================================================================*/
714 static int req_rdlink_actual(endpoint_t fs_e, ino_t inode_nr,
715 endpoint_t proc_e, vir_bytes buf, size_t len,
716 int direct, /* set to 1 to use direct grants instead of magic grants */
717 int cpflag)
719 message m;
720 int r;
721 cp_grant_id_t grant_id;
723 if (direct) {
724 grant_id = cpf_grant_direct(fs_e, buf, len, CPF_WRITE);
725 } else {
726 grant_id = cpf_grant_magic(fs_e, proc_e, buf, len, CPF_WRITE | cpflag);
728 if (grant_id == -1)
729 panic("req_rdlink: cpf_grant_magic failed");
731 /* Fill in request message */
732 m.m_type = REQ_RDLINK;
733 m.m_vfs_fs_rdlink.inode = inode_nr;
734 m.m_vfs_fs_rdlink.grant = grant_id;
735 m.m_vfs_fs_rdlink.mem_size = len;
737 /* Send/rec request */
738 r = fs_sendrec(fs_e, &m);
739 cpf_revoke(grant_id);
741 if (r == OK) r = m.m_fs_vfs_rdlink.nbytes;
743 return(r);
746 /*===========================================================================*
747 * req_rdlink *
748 *===========================================================================*/
749 int req_rdlink(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
750 vir_bytes buf, size_t len,
751 int direct /* set to 1 to use direct grants instead of magic grants */
754 int r;
756 r = req_rdlink_actual(fs_e, inode_nr, proc_e, buf, len, direct,
757 CPF_TRY);
759 if(r == EFAULT && !direct) {
760 if((r=vm_vfs_procctl_handlemem(proc_e, buf, len, 1)) != OK) {
761 return r;
764 r = req_rdlink_actual(fs_e, inode_nr, proc_e, buf, len,
765 direct, 0);
768 return r;
771 /*===========================================================================*
772 * req_readsuper *
773 *===========================================================================*/
774 int req_readsuper(
775 struct vmnt *vmp,
776 char *label,
777 dev_t dev,
778 int readonly,
779 int isroot,
780 struct node_details *res,
781 unsigned int *fs_flags
784 int r;
785 cp_grant_id_t grant_id;
786 size_t len;
787 message m;
788 endpoint_t fs_e;
790 fs_e = vmp->m_fs_e;
792 len = strlen(label)+1;
793 grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
794 if (grant_id == -1)
795 panic("req_readsuper: cpf_grant_direct failed");
797 /* Fill in request message */
798 m.m_type = REQ_READSUPER;
799 m.m_vfs_fs_readsuper.flags = 0;
800 if(readonly) m.m_vfs_fs_readsuper.flags |= REQ_RDONLY;
801 if(isroot) m.m_vfs_fs_readsuper.flags |= REQ_ISROOT;
802 m.m_vfs_fs_readsuper.grant = grant_id;
803 m.m_vfs_fs_readsuper.device = dev;
804 m.m_vfs_fs_readsuper.path_len = len;
806 /* Send/rec request */
807 r = fs_sendrec(fs_e, &m);
808 cpf_revoke(grant_id);
810 if(r == OK) {
811 /* Fill in response structure */
812 res->fs_e = m.m_source;
813 res->inode_nr = m.m_fs_vfs_readsuper.inode;
814 res->fmode = m.m_fs_vfs_readsuper.mode;
815 res->fsize = m.m_fs_vfs_readsuper.file_size;
816 res->uid = m.m_fs_vfs_readsuper.uid;
817 res->gid = m.m_fs_vfs_readsuper.gid;
818 *fs_flags = m.m_fs_vfs_readsuper.flags;
821 return(r);
825 /*===========================================================================*
826 * req_readwrite_actual *
827 *===========================================================================*/
828 static int req_readwrite_actual(endpoint_t fs_e, ino_t inode_nr, off_t pos,
829 int rw_flag, endpoint_t user_e, vir_bytes user_addr,
830 unsigned int num_of_bytes, off_t *new_posp, size_t *cum_iop,
831 int cpflag)
833 struct vmnt *vmp;
834 int r;
835 cp_grant_id_t grant_id;
836 message m;
838 vmp = find_vmnt(fs_e);
840 grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
841 (rw_flag==READING ? CPF_WRITE:CPF_READ) | cpflag);
842 if (grant_id == -1)
843 panic("req_readwrite: cpf_grant_magic failed");
845 /* Fill in request message */
846 m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
847 m.m_vfs_fs_readwrite.inode = inode_nr;
848 m.m_vfs_fs_readwrite.grant = grant_id;
849 m.m_vfs_fs_readwrite.seek_pos = pos;
850 if ((!(vmp->m_fs_flags & RES_64BIT)) && (pos > INT_MAX)) {
851 return EINVAL;
853 m.m_vfs_fs_readwrite.nbytes = num_of_bytes;
855 /* Send/rec request */
856 r = fs_sendrec(fs_e, &m);
857 cpf_revoke(grant_id);
859 if (r == OK) {
860 /* Fill in response structure */
861 *new_posp = m.m_fs_vfs_readwrite.seek_pos;
862 *cum_iop = m.m_fs_vfs_readwrite.nbytes;
865 return(r);
868 /*===========================================================================*
869 * req_readwrite *
870 *===========================================================================*/
871 int req_readwrite(endpoint_t fs_e, ino_t inode_nr, off_t pos,
872 int rw_flag, endpoint_t user_e, vir_bytes user_addr,
873 unsigned int num_of_bytes, off_t *new_posp, unsigned int *cum_iop)
875 int r;
877 r = req_readwrite_actual(fs_e, inode_nr, pos, rw_flag, user_e,
878 user_addr, num_of_bytes, new_posp, cum_iop, CPF_TRY);
880 if(r == EFAULT) {
881 if((r=vm_vfs_procctl_handlemem(user_e, (vir_bytes) user_addr, num_of_bytes,
882 rw_flag == READING)) != OK) {
883 return r;
886 r = req_readwrite_actual(fs_e, inode_nr, pos, rw_flag, user_e,
887 user_addr, num_of_bytes, new_posp, cum_iop, 0);
890 return r;
893 /*===========================================================================*
894 * req_peek *
895 *===========================================================================*/
896 int req_peek(endpoint_t fs_e, ino_t inode_nr, off_t pos, unsigned int bytes)
898 message m;
900 memset(&m, 0, sizeof(m));
902 if (ex64hi(pos) != 0)
903 panic("req_peek: pos too large");
905 /* Fill in request message */
906 m.m_type = REQ_PEEK;
907 m.m_vfs_fs_readwrite.inode = inode_nr;
908 m.m_vfs_fs_readwrite.grant = -1;
909 m.m_vfs_fs_readwrite.seek_pos = pos;
910 m.m_vfs_fs_readwrite.nbytes = bytes;
912 /* Send/rec request */
913 return fs_sendrec(fs_e, &m);
916 /*===========================================================================*
917 * req_rename *
918 *===========================================================================*/
919 int req_rename(fs_e, old_dir, old_name, new_dir, new_name)
920 endpoint_t fs_e;
921 ino_t old_dir;
922 char *old_name;
923 ino_t new_dir;
924 char *new_name;
926 int r;
927 cp_grant_id_t gid_old, gid_new;
928 size_t len_old, len_new;
929 message m;
931 len_old = strlen(old_name) + 1;
932 gid_old = cpf_grant_direct(fs_e, (vir_bytes) old_name, len_old, CPF_READ);
933 if(gid_old == -1)
934 panic("req_rename: cpf_grant_direct failed");
936 len_new = strlen(new_name) + 1;
937 gid_new = cpf_grant_direct(fs_e, (vir_bytes) new_name, len_new, CPF_READ);
938 if(gid_new == -1)
939 panic("req_rename: cpf_grant_direct failed");
941 /* Fill in request message */
942 m.m_type = REQ_RENAME;
943 m.m_vfs_fs_rename.dir_old = old_dir;
944 m.m_vfs_fs_rename.grant_old = gid_old;
945 m.m_vfs_fs_rename.len_old = len_old;
947 m.m_vfs_fs_rename.dir_new = new_dir;
948 m.m_vfs_fs_rename.grant_new = gid_new;
949 m.m_vfs_fs_rename.len_new = len_new;
951 /* Send/rec request */
952 r = fs_sendrec(fs_e, &m);
953 cpf_revoke(gid_old);
954 cpf_revoke(gid_new);
956 return(r);
960 /*===========================================================================*
961 * req_rmdir *
962 *===========================================================================*/
963 int req_rmdir(fs_e, inode_nr, lastc)
964 endpoint_t fs_e;
965 ino_t inode_nr;
966 char *lastc;
968 int r;
969 cp_grant_id_t grant_id;
970 size_t len;
971 message m;
973 len = strlen(lastc) + 1;
974 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
975 if(grant_id == -1)
976 panic("req_rmdir: cpf_grant_direct failed");
978 /* Fill in request message */
979 m.m_type = REQ_RMDIR;
980 m.m_vfs_fs_unlink.inode = inode_nr;
981 m.m_vfs_fs_unlink.grant = grant_id;
982 m.m_vfs_fs_unlink.path_len = len;
984 /* Send/rec request */
985 r = fs_sendrec(fs_e, &m);
986 cpf_revoke(grant_id);
988 return(r);
992 /*===========================================================================*
993 * req_slink_actual *
994 *===========================================================================*/
995 static int req_slink_actual(
996 endpoint_t fs_e,
997 ino_t inode_nr,
998 char *lastc,
999 endpoint_t proc_e,
1000 vir_bytes path_addr,
1001 size_t path_length,
1002 uid_t uid,
1003 gid_t gid,
1004 int cpflag
1007 int r;
1008 size_t len;
1009 cp_grant_id_t gid_name, gid_buf;
1010 message m;
1012 len = strlen(lastc) + 1;
1013 gid_name = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
1014 if (gid_name == GRANT_INVALID)
1015 panic("req_slink: cpf_grant_direct failed");
1017 gid_buf = cpf_grant_magic(fs_e, proc_e, path_addr, path_length,
1018 CPF_READ | cpflag);
1020 if (gid_buf == GRANT_INVALID) {
1021 cpf_revoke(gid_name);
1022 panic("req_slink: cpf_grant_magic failed");
1025 /* Fill in request message */
1026 m.m_type = REQ_SLINK;
1027 m.m_vfs_fs_slink.inode = inode_nr;
1028 m.m_vfs_fs_slink.uid = uid;
1029 m.m_vfs_fs_slink.gid = gid;
1030 m.m_vfs_fs_slink.grant_path = gid_name;
1031 m.m_vfs_fs_slink.path_len = len;
1032 m.m_vfs_fs_slink.grant_target = gid_buf;
1033 m.m_vfs_fs_slink.mem_size = path_length;
1035 /* Send/rec request */
1036 r = fs_sendrec(fs_e, &m);
1037 cpf_revoke(gid_name);
1038 cpf_revoke(gid_buf);
1040 return(r);
1043 /*===========================================================================*
1044 * req_slink *
1045 *===========================================================================*/
1046 int req_slink(
1047 endpoint_t fs_e,
1048 ino_t inode_nr,
1049 char *lastc,
1050 endpoint_t proc_e,
1051 vir_bytes path_addr,
1052 size_t path_length,
1053 uid_t uid,
1054 gid_t gid
1057 int r;
1059 r = req_slink_actual(fs_e, inode_nr, lastc, proc_e, path_addr,
1060 path_length, uid, gid, CPF_TRY);
1062 if(r == EFAULT) {
1063 if((r=vm_vfs_procctl_handlemem(proc_e, (vir_bytes) path_addr,
1064 path_length, 0)) != OK) {
1065 return r;
1068 r = req_slink_actual(fs_e, inode_nr, lastc, proc_e, path_addr,
1069 path_length, uid, gid, 0);
1072 return r;
1075 /*===========================================================================*
1076 * req_stat_actual *
1077 *===========================================================================*/
1078 int req_stat_actual(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
1079 vir_bytes buf, int cpflag)
1081 cp_grant_id_t grant_id;
1082 int r;
1083 message m;
1085 /* Grant FS access to copy straight into user provided buffer */
1086 grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct stat),
1087 CPF_WRITE | cpflag);
1089 if (grant_id < 0)
1090 panic("req_stat: cpf_grant_* failed");
1092 /* Fill in request message */
1093 m.m_type = REQ_STAT;
1094 m.m_vfs_fs_stat.inode = inode_nr;
1095 m.m_vfs_fs_stat.grant = grant_id;
1097 /* Send/rec request */
1098 r = fs_sendrec(fs_e, &m);
1099 cpf_revoke(grant_id);
1101 return(r);
1105 /*===========================================================================*
1106 * req_stat *
1107 *===========================================================================*/
1108 int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
1109 vir_bytes buf)
1111 int r;
1113 r = req_stat_actual(fs_e, inode_nr, proc_e, buf, CPF_TRY);
1115 if(r == EFAULT) {
1116 if((r=vm_vfs_procctl_handlemem(proc_e, (vir_bytes) buf,
1117 sizeof(struct stat), 1)) != OK) {
1118 return r;
1121 r = req_stat_actual(fs_e, inode_nr, proc_e, buf, 0);
1124 return r;
1127 /*===========================================================================*
1128 * req_sync *
1129 *===========================================================================*/
1130 int req_sync(fs_e)
1131 endpoint_t fs_e;
1133 message m;
1135 /* Fill in request message */
1136 m.m_type = REQ_SYNC;
1138 /* Send/rec request */
1139 return fs_sendrec(fs_e, &m);
1143 /*===========================================================================*
1144 * req_unlink *
1145 *===========================================================================*/
1146 int req_unlink(fs_e, inode_nr, lastc)
1147 endpoint_t fs_e;
1148 ino_t inode_nr;
1149 char *lastc;
1151 cp_grant_id_t grant_id;
1152 size_t len;
1153 int r;
1154 message m;
1156 len = strlen(lastc) + 1;
1157 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
1158 if(grant_id == -1)
1159 panic("req_unlink: cpf_grant_direct failed");
1161 /* Fill in request message */
1162 m.m_type = REQ_UNLINK;
1163 m.m_vfs_fs_unlink.inode = inode_nr;
1164 m.m_vfs_fs_unlink.grant = grant_id;
1165 m.m_vfs_fs_unlink.path_len = len;
1167 /* Send/rec request */
1168 r = fs_sendrec(fs_e, &m);
1169 cpf_revoke(grant_id);
1171 return(r);
1175 /*===========================================================================*
1176 * req_unmount *
1177 *===========================================================================*/
1178 int req_unmount(fs_e)
1179 endpoint_t fs_e;
1181 message m;
1183 /* Fill in request message */
1184 m.m_type = REQ_UNMOUNT;
1186 /* Send/rec request */
1187 return fs_sendrec(fs_e, &m);
1191 /*===========================================================================*
1192 * req_utime *
1193 *===========================================================================*/
1194 int req_utime(endpoint_t fs_e, ino_t inode_nr, struct timespec * actimespec,
1195 struct timespec * modtimespec)
1197 message m;
1199 assert(actimespec != NULL);
1200 assert(modtimespec != NULL);
1202 /* Fill in request message */
1203 m.m_type = REQ_UTIME;
1204 m.m_vfs_fs_utime.inode = inode_nr;
1205 m.m_vfs_fs_utime.actime = actimespec->tv_sec;
1206 m.m_vfs_fs_utime.modtime = modtimespec->tv_sec;
1207 m.m_vfs_fs_utime.acnsec = actimespec->tv_nsec;
1208 m.m_vfs_fs_utime.modnsec = modtimespec->tv_nsec;
1210 /* Send/rec request */
1211 return fs_sendrec(fs_e, &m);