coverity appeasement
[minix.git] / servers / vfs / request.c
blobe39979dea5290998f1283ea711ffce26ba87f234
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 <string.h>
10 #include <assert.h>
11 #include <sys/stat.h>
12 #include <sys/statfs.h>
13 #include <sys/statvfs.h>
14 #include <minix/vfsif.h>
15 #include <minix/com.h>
16 #include <minix/const.h>
17 #include <minix/endpoint.h>
18 #include <minix/u64.h>
19 #include <unistd.h>
20 #include <minix/vfsif.h>
21 #include "fproc.h"
22 #include "vmnt.h"
23 #include "vnode.h"
24 #include "path.h"
25 #include "param.h"
28 /*===========================================================================*
29 * req_breadwrite *
30 *===========================================================================*/
31 int req_breadwrite(
32 endpoint_t fs_e,
33 endpoint_t user_e,
34 dev_t dev,
35 u64_t pos,
36 unsigned int num_of_bytes,
37 char *user_addr,
38 int rw_flag,
39 u64_t *new_posp,
40 unsigned int *cum_iop
43 int r;
44 cp_grant_id_t grant_id;
45 message m;
47 grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
48 (rw_flag == READING ? CPF_WRITE : CPF_READ));
49 if(grant_id == -1)
50 panic("req_breadwrite: cpf_grant_magic failed");
52 /* Fill in request message */
53 m.m_type = rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
54 m.REQ_DEV2 = dev;
55 m.REQ_GRANT = grant_id;
56 m.REQ_SEEK_POS_LO = ex64lo(pos);
57 m.REQ_SEEK_POS_HI = ex64hi(pos);
58 m.REQ_NBYTES = num_of_bytes;
60 /* Send/rec request */
61 r = fs_sendrec(fs_e, &m);
62 cpf_revoke(grant_id);
63 if (r != OK) return(r);
65 /* Fill in response structure */
66 *new_posp = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI);
67 *cum_iop = m.RES_NBYTES;
69 return(OK);
73 /*===========================================================================*
74 * req_chmod *
75 *===========================================================================*/
76 int req_chmod(
77 int fs_e,
78 ino_t inode_nr,
79 mode_t rmode,
80 mode_t *new_modep
83 message m;
84 int r;
86 /* Fill in request message */
87 m.m_type = REQ_CHMOD;
88 m.REQ_INODE_NR = inode_nr;
89 m.REQ_MODE = rmode;
91 /* Send/rec request */
92 r = fs_sendrec(fs_e, &m);
94 /* Copy back actual mode. */
95 *new_modep = m.RES_MODE;
97 return(r);
101 /*===========================================================================*
102 * req_chown *
103 *===========================================================================*/
104 int req_chown(
105 endpoint_t fs_e,
106 ino_t inode_nr,
107 uid_t newuid,
108 gid_t newgid,
109 mode_t *new_modep
112 message m;
113 int r;
115 /* Fill in request message */
116 m.m_type = REQ_CHOWN;
117 m.REQ_INODE_NR = inode_nr;
118 m.REQ_UID = newuid;
119 m.REQ_GID = newgid;
121 /* Send/rec request */
122 r = fs_sendrec(fs_e, &m);
124 /* Return new mode to caller. */
125 *new_modep = m.RES_MODE;
127 return(r);
131 /*===========================================================================*
132 * req_create *
133 *===========================================================================*/
134 int req_create(
135 int fs_e,
136 ino_t inode_nr,
137 int omode,
138 uid_t uid,
139 gid_t gid,
140 char *path,
141 node_details_t *res
144 int r;
145 cp_grant_id_t grant_id;
146 size_t len;
147 message m;
149 if (path[0] == '/')
150 panic("req_create: filename starts with '/'");
152 len = strlen(path) + 1;
153 grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ);
154 if (grant_id == -1)
155 panic("req_create: cpf_grant_direct failed");
157 /* Fill in request message */
158 m.m_type = REQ_CREATE;
159 m.REQ_INODE_NR = inode_nr;
160 m.REQ_MODE = omode;
161 m.REQ_UID = uid;
162 m.REQ_GID = gid;
163 m.REQ_GRANT = grant_id;
164 m.REQ_PATH_LEN = len;
166 /* Send/rec request */
167 r = fs_sendrec(fs_e, &m);
168 cpf_revoke(grant_id);
169 if (r != OK) return(r);
171 /* Fill in response structure */
172 res->fs_e = m.m_source;
173 res->inode_nr = m.RES_INODE_NR;
174 res->fmode = m.RES_MODE;
175 res->fsize = m.RES_FILE_SIZE_LO;
176 res->uid = m.RES_UID;
177 res->gid = m.RES_GID;
178 res->dev = m.RES_DEV;
180 return(OK);
184 /*===========================================================================*
185 * req_flush *
186 *===========================================================================*/
187 int req_flush(endpoint_t fs_e, dev_t dev)
189 message m;
191 /* Fill in request message */
192 m.m_type = REQ_FLUSH;
193 m.REQ_DEV = dev;
195 /* Send/rec request */
196 return fs_sendrec(fs_e, &m);
200 /*===========================================================================*
201 * req_fstatfs *
202 *===========================================================================*/
203 int req_fstatfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf)
205 int r;
206 cp_grant_id_t grant_id;
207 message m;
209 grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct statfs),
210 CPF_WRITE);
211 if (grant_id == GRANT_INVALID)
212 panic("req_fstatfs: cpf_grant_magic failed");
214 /* Fill in request message */
215 m.m_type = REQ_FSTATFS;
216 m.REQ_GRANT = grant_id;
218 /* Send/rec request */
219 r = fs_sendrec(fs_e, &m);
220 cpf_revoke(grant_id);
222 return(r);
226 /*===========================================================================*
227 * req_statvfs *
228 *===========================================================================*/
229 int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf)
231 int r;
232 cp_grant_id_t grant_id;
233 message m;
235 grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct statvfs),
236 CPF_WRITE);
237 if(grant_id == GRANT_INVALID)
238 panic("req_statvfs: cpf_grant_magic failed");
240 /* Fill in request message */
241 m.m_type = REQ_STATVFS;
242 m.REQ_GRANT = grant_id;
244 /* Send/rec request */
245 r = fs_sendrec(fs_e, &m);
246 cpf_revoke(grant_id);
248 return(r);
252 /*===========================================================================*
253 * req_ftrunc *
254 *===========================================================================*/
255 int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end)
257 message m;
259 /* Fill in request message */
260 m.m_type = REQ_FTRUNC;
261 m.REQ_INODE_NR = inode_nr;
262 m.REQ_TRC_START_LO = start;
263 m.REQ_TRC_START_HI = 0; /* Not used for now, so clear it. */
264 m.REQ_TRC_END_LO = end;
265 m.REQ_TRC_END_HI = 0; /* Not used for now, so clear it. */
267 /* Send/rec request */
268 return fs_sendrec(fs_e, &m);
272 /*===========================================================================*
273 * req_getdents *
274 *===========================================================================*/
275 int req_getdents(
276 endpoint_t fs_e,
277 ino_t inode_nr,
278 u64_t pos,
279 char *buf,
280 size_t size,
281 u64_t *new_pos,
282 int direct
285 int r;
286 message m;
287 cp_grant_id_t grant_id;
289 if (direct) {
290 grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, size,
291 CPF_WRITE);
292 } else {
293 grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, size,
294 CPF_WRITE);
297 if (grant_id < 0)
298 panic("req_getdents: cpf_grant_direct/cpf_grant_magic failed: %d",
299 grant_id);
301 m.m_type = REQ_GETDENTS;
302 m.REQ_INODE_NR = inode_nr;
303 m.REQ_GRANT = grant_id;
304 m.REQ_MEM_SIZE = size;
305 m.REQ_SEEK_POS_LO = ex64lo(pos);
306 m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */
308 r = fs_sendrec(fs_e, &m);
309 cpf_revoke(grant_id);
311 if (r == OK) {
312 *new_pos = cvul64(m.RES_SEEK_POS_LO);
313 r = m.RES_NBYTES;
316 return(r);
319 /*===========================================================================*
320 * req_inhibread *
321 *===========================================================================*/
322 int req_inhibread(endpoint_t fs_e, ino_t inode_nr)
324 message m;
326 /* Fill in request message */
327 m.m_type = REQ_INHIBREAD;
328 m.REQ_INODE_NR = inode_nr;
330 /* Send/rec request */
331 return fs_sendrec(fs_e, &m);
335 /*===========================================================================*
336 * req_link *
337 *===========================================================================*/
338 int req_link(
339 endpoint_t fs_e,
340 ino_t link_parent,
341 char *lastc,
342 ino_t linked_file
345 int r;
346 cp_grant_id_t grant_id;
347 const size_t len = strlen(lastc) + 1;
348 message m;
350 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
351 if(grant_id == -1)
352 panic("req_link: cpf_grant_direct failed");
354 /* Fill in request message */
355 m.m_type = REQ_LINK;
356 m.REQ_INODE_NR = linked_file;
357 m.REQ_DIR_INO = link_parent;
358 m.REQ_GRANT = grant_id;
359 m.REQ_PATH_LEN = len;
361 /* Send/rec request */
362 r = fs_sendrec(fs_e, &m);
363 cpf_revoke(grant_id);
365 return(r);
369 /*===========================================================================*
370 * req_lookup *
371 *===========================================================================*/
372 int req_lookup(
373 endpoint_t fs_e,
374 ino_t dir_ino,
375 ino_t root_ino,
376 uid_t uid,
377 gid_t gid,
378 struct lookup *resolve,
379 lookup_res_t *res,
380 struct fproc *rfp
383 int r;
384 size_t len;
385 cp_grant_id_t grant_id=0, grant_id2=0;
386 message m;
387 vfs_ucred_t credentials;
388 int flags;
390 grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX,
391 CPF_READ | CPF_WRITE);
392 if(grant_id == -1)
393 panic("req_lookup: cpf_grant_direct failed");
395 flags = resolve->l_flags;
396 len = strlen(resolve->l_path) + 1;
398 m.m_type = REQ_LOOKUP;
399 m.REQ_GRANT = grant_id;
400 m.REQ_PATH_LEN = len;
401 m.REQ_PATH_SIZE = PATH_MAX + 1;
402 m.REQ_DIR_INO = dir_ino;
403 m.REQ_ROOT_INO = root_ino;
405 if(rfp->fp_ngroups > 0) { /* Is the process member of multiple groups? */
406 /* In that case the FS has to copy the uid/gid credentials */
407 int i;
409 /* Set credentials */
410 credentials.vu_uid = rfp->fp_effuid;
411 credentials.vu_gid = rfp->fp_effgid;
412 credentials.vu_ngroups = rfp->fp_ngroups;
413 for (i = 0; i < rfp->fp_ngroups; i++)
414 credentials.vu_sgroups[i] = rfp->fp_sgroups[i];
416 grant_id2 = cpf_grant_direct(fs_e, (vir_bytes) &credentials,
417 sizeof(credentials), CPF_READ);
418 if(grant_id2 == -1)
419 panic("req_lookup: cpf_grant_direct failed");
421 m.REQ_GRANT2 = grant_id2;
422 m.REQ_UCRED_SIZE= sizeof(credentials);
423 flags |= PATH_GET_UCRED;
424 } else {
425 /* When there's only one gid, we can send it directly */
426 m.REQ_UID = uid;
427 m.REQ_GID = gid;
428 flags &= ~PATH_GET_UCRED;
431 m.REQ_FLAGS = flags;
433 /* Send/rec request */
434 r = fs_sendrec(fs_e, &m);
435 cpf_revoke(grant_id);
436 if(rfp->fp_ngroups > 0) cpf_revoke(grant_id2);
438 /* Fill in response according to the return value */
439 res->fs_e = m.m_source;
441 switch (r) {
442 case OK:
443 res->inode_nr = m.RES_INODE_NR;
444 res->fmode = m.RES_MODE;
445 res->fsize = m.RES_FILE_SIZE_LO;
446 res->dev = m.RES_DEV;
447 res->uid= m.RES_UID;
448 res->gid= m.RES_GID;
449 break;
450 case EENTERMOUNT:
451 res->inode_nr = m.RES_INODE_NR;
452 res->char_processed = m.RES_OFFSET;
453 res->symloop = m.RES_SYMLOOP;
454 break;
455 case ELEAVEMOUNT:
456 res->char_processed = m.RES_OFFSET;
457 res->symloop = m.RES_SYMLOOP;
458 break;
459 case ESYMLINK:
460 res->char_processed = m.RES_OFFSET;
461 res->symloop = m.RES_SYMLOOP;
462 break;
463 default:
464 break;
467 return(r);
471 /*===========================================================================*
472 * req_mkdir *
473 *===========================================================================*/
474 int req_mkdir(
475 endpoint_t fs_e,
476 ino_t inode_nr,
477 char *lastc,
478 uid_t uid,
479 gid_t gid,
480 mode_t dmode
483 int r;
484 cp_grant_id_t grant_id;
485 size_t len;
486 message m;
488 len = strlen(lastc) + 1;
489 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
490 if(grant_id == -1)
491 panic("req_mkdir: cpf_grant_direct failed");
493 /* Fill in request message */
494 m.m_type = REQ_MKDIR;
495 m.REQ_INODE_NR = inode_nr;
496 m.REQ_MODE = dmode;
497 m.REQ_UID = uid;
498 m.REQ_GID = gid;
499 m.REQ_GRANT = grant_id;
500 m.REQ_PATH_LEN = len;
502 /* Send/rec request */
503 r = fs_sendrec(fs_e, &m);
504 cpf_revoke(grant_id);
506 return(r);
510 /*===========================================================================*
511 * req_mknod *
512 *===========================================================================*/
513 int req_mknod(
514 endpoint_t fs_e,
515 ino_t inode_nr,
516 char *lastc,
517 uid_t uid,
518 gid_t gid,
519 mode_t dmode,
520 dev_t dev
523 int r;
524 size_t len;
525 cp_grant_id_t grant_id;
526 message m;
528 len = strlen(lastc) + 1;
529 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
530 if(grant_id == -1)
531 panic("req_mknod: cpf_grant_direct failed");
533 /* Fill in request message */
534 m.m_type = REQ_MKNOD;
535 m.REQ_INODE_NR = inode_nr;
536 m.REQ_MODE = dmode;
537 m.REQ_DEV = dev;
538 m.REQ_UID = uid;
539 m.REQ_GID = gid;
540 m.REQ_GRANT = grant_id;
541 m.REQ_PATH_LEN = len;
543 /* Send/rec request */
544 r = fs_sendrec(fs_e, &m);
545 cpf_revoke(grant_id);
547 return(r);
551 /*===========================================================================*
552 * req_mountpoint *
553 *===========================================================================*/
554 int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
556 message m;
558 /* Fill in request message */
559 m.m_type = REQ_MOUNTPOINT;
560 m.REQ_INODE_NR = inode_nr;
562 /* Send/rec request */
563 return fs_sendrec(fs_e, &m);
567 /*===========================================================================*
568 * req_newnode *
569 *===========================================================================*/
570 int req_newnode(
571 endpoint_t fs_e,
572 uid_t uid,
573 gid_t gid,
574 mode_t dmode,
575 dev_t dev,
576 struct node_details *res
579 int r;
580 message m;
582 /* Fill in request message */
583 m.m_type = REQ_NEWNODE;
584 m.REQ_MODE = dmode;
585 m.REQ_DEV = dev;
586 m.REQ_UID = uid;
587 m.REQ_GID = gid;
589 /* Send/rec request */
590 r = fs_sendrec(fs_e, &m);
592 res->fs_e = m.m_source;
593 res->inode_nr = m.RES_INODE_NR;
594 res->fmode = m.RES_MODE;
595 res->fsize = m.RES_FILE_SIZE_LO;
596 res->dev = m.RES_DEV;
597 res->uid = m.RES_UID;
598 res->gid = m.RES_GID;
600 return(r);
604 /*===========================================================================*
605 * req_newdriver *
606 *===========================================================================*/
607 int req_newdriver(
608 endpoint_t fs_e,
609 dev_t dev,
610 char *label
613 cp_grant_id_t grant_id;
614 size_t len;
615 message m;
616 int r;
618 /* Grant access to label */
619 len = strlen(label) + 1;
620 grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
621 if (grant_id == -1)
622 panic("req_newdriver: cpf_grant_direct failed");
624 /* Fill in request message */
625 m.m_type = REQ_NEW_DRIVER;
626 m.REQ_DEV = dev;
627 m.REQ_GRANT = grant_id;
628 m.REQ_PATH_LEN = len;
630 /* Issue request */
631 r = fs_sendrec(fs_e, &m);
633 cpf_revoke(grant_id);
635 return(r);
639 /*===========================================================================*
640 * req_putnode *
641 *===========================================================================*/
642 int req_putnode(fs_e, inode_nr, count)
643 int fs_e;
644 ino_t inode_nr;
645 int count;
647 message m;
649 /* Fill in request message */
650 m.m_type = REQ_PUTNODE;
651 m.REQ_INODE_NR = inode_nr;
652 m.REQ_COUNT = count;
654 /* Send/rec request */
655 return fs_sendrec(fs_e, &m);
659 /*===========================================================================*
660 * req_rdlink *
661 *===========================================================================*/
662 int req_rdlink(fs_e, inode_nr, proc_e, buf, len, direct)
663 endpoint_t fs_e;
664 ino_t inode_nr;
665 endpoint_t proc_e;
666 vir_bytes buf;
667 size_t len;
668 int direct; /* set to 1 to use direct grants instead of magic grants */
670 message m;
671 int r;
672 cp_grant_id_t grant_id;
674 if (direct) {
675 grant_id = cpf_grant_direct(fs_e, buf, len, CPF_WRITE);
676 } else {
677 grant_id = cpf_grant_magic(fs_e, proc_e, buf, len, CPF_WRITE);
679 if (grant_id == -1)
680 panic("req_rdlink: cpf_grant_magic failed");
682 /* Fill in request message */
683 m.m_type = REQ_RDLINK;
684 m.REQ_INODE_NR = inode_nr;
685 m.REQ_GRANT = grant_id;
686 m.REQ_MEM_SIZE = len;
688 /* Send/rec request */
689 r = fs_sendrec(fs_e, &m);
690 cpf_revoke(grant_id);
692 if (r == OK) r = m.RES_NBYTES;
694 return(r);
698 /*===========================================================================*
699 * req_readsuper *
700 *===========================================================================*/
701 int req_readsuper(
702 endpoint_t fs_e,
703 char *label,
704 dev_t dev,
705 int readonly,
706 int isroot,
707 struct node_details *res_nodep,
708 int *con_reqs
711 int r;
712 cp_grant_id_t grant_id;
713 size_t len;
714 message m;
716 len = strlen(label)+1;
717 grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
718 if (grant_id == -1)
719 panic("req_readsuper: cpf_grant_direct failed");
721 /* Fill in request message */
722 m.m_type = REQ_READSUPER;
723 m.REQ_FLAGS = 0;
724 if(readonly) m.REQ_FLAGS |= REQ_RDONLY;
725 if(isroot) m.REQ_FLAGS |= REQ_ISROOT;
726 m.REQ_GRANT = grant_id;
727 m.REQ_DEV = dev;
728 m.REQ_PATH_LEN = len;
730 /* Send/rec request */
731 r = fs_sendrec(fs_e, &m);
732 cpf_revoke(grant_id);
734 if(r == OK) {
735 /* Fill in response structure */
736 res_nodep->fs_e = m.m_source;
737 res_nodep->inode_nr = m.RES_INODE_NR;
738 res_nodep->fmode = m.RES_MODE;
739 res_nodep->fsize = m.RES_FILE_SIZE_LO;
740 res_nodep->uid = m.RES_UID;
741 res_nodep->gid = m.RES_GID;
742 *con_reqs = m.RES_CONREQS;
745 return(r);
749 /*===========================================================================*
750 * req_readwrite *
751 *===========================================================================*/
752 int req_readwrite(fs_e, inode_nr, pos, rw_flag, user_e,
753 user_addr, num_of_bytes, new_posp, cum_iop)
754 endpoint_t fs_e;
755 ino_t inode_nr;
756 u64_t pos;
757 int rw_flag;
758 endpoint_t user_e;
759 char *user_addr;
760 unsigned int num_of_bytes;
761 u64_t *new_posp;
762 unsigned int *cum_iop;
764 int r;
765 cp_grant_id_t grant_id;
766 message m;
768 if (ex64hi(pos) != 0)
769 panic("req_readwrite: pos too large");
771 grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
772 (rw_flag==READING ? CPF_WRITE:CPF_READ));
773 if (grant_id == -1)
774 panic("req_readwrite: cpf_grant_magic failed");
776 /* Fill in request message */
777 m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
778 m.REQ_INODE_NR = inode_nr;
779 m.REQ_GRANT = grant_id;
780 m.REQ_SEEK_POS_LO = ex64lo(pos);
781 m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */
782 m.REQ_NBYTES = num_of_bytes;
784 /* Send/rec request */
785 r = fs_sendrec(fs_e, &m);
786 cpf_revoke(grant_id);
788 if (r == OK) {
789 /* Fill in response structure */
790 *new_posp = cvul64(m.RES_SEEK_POS_LO);
791 *cum_iop = m.RES_NBYTES;
794 return(r);
798 /*===========================================================================*
799 * req_rename *
800 *===========================================================================*/
801 int req_rename(fs_e, old_dir, old_name, new_dir, new_name)
802 endpoint_t fs_e;
803 ino_t old_dir;
804 char *old_name;
805 ino_t new_dir;
806 char *new_name;
808 int r;
809 cp_grant_id_t gid_old, gid_new;
810 size_t len_old, len_new;
811 message m;
813 len_old = strlen(old_name) + 1;
814 gid_old = cpf_grant_direct(fs_e, (vir_bytes) old_name, len_old, CPF_READ);
815 if(gid_old == -1)
816 panic("req_rename: cpf_grant_direct failed");
818 len_new = strlen(new_name) + 1;
819 gid_new = cpf_grant_direct(fs_e, (vir_bytes) new_name, len_new, CPF_READ);
820 if(gid_new == -1)
821 panic("req_rename: cpf_grant_direct failed");
823 /* Fill in request message */
824 m.m_type = REQ_RENAME;
825 m.REQ_REN_OLD_DIR = old_dir;
826 m.REQ_REN_NEW_DIR = new_dir;
827 m.REQ_REN_GRANT_OLD = gid_old;
828 m.REQ_REN_LEN_OLD = len_old;
829 m.REQ_REN_GRANT_NEW = gid_new;
830 m.REQ_REN_LEN_NEW = len_new;
832 /* Send/rec request */
833 r = fs_sendrec(fs_e, &m);
834 cpf_revoke(gid_old);
835 cpf_revoke(gid_new);
837 return(r);
841 /*===========================================================================*
842 * req_rmdir *
843 *===========================================================================*/
844 int req_rmdir(fs_e, inode_nr, lastc)
845 endpoint_t fs_e;
846 ino_t inode_nr;
847 char *lastc;
849 int r;
850 cp_grant_id_t grant_id;
851 size_t len;
852 message m;
854 len = strlen(lastc) + 1;
855 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
856 if(grant_id == -1)
857 panic("req_rmdir: cpf_grant_direct failed");
859 /* Fill in request message */
860 m.m_type = REQ_RMDIR;
861 m.REQ_INODE_NR = inode_nr;
862 m.REQ_GRANT = grant_id;
863 m.REQ_PATH_LEN = len;
865 /* Send/rec request */
866 r = fs_sendrec(fs_e, &m);
867 cpf_revoke(grant_id);
869 return(r);
873 /*===========================================================================*
874 * req_slink *
875 *===========================================================================*/
876 int req_slink(
877 endpoint_t fs_e,
878 ino_t inode_nr,
879 char *lastc,
880 endpoint_t proc_e,
881 vir_bytes path_addr,
882 size_t path_length,
883 uid_t uid,
884 gid_t gid
887 int r;
888 size_t len;
889 cp_grant_id_t gid_name, gid_buf;
890 message m;
892 len = strlen(lastc) + 1;
893 gid_name = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
894 if (gid_name == GRANT_INVALID)
895 panic("req_slink: cpf_grant_direct failed");
897 gid_buf = cpf_grant_magic(fs_e, proc_e, path_addr, path_length, CPF_READ);
898 if (gid_buf == GRANT_INVALID) {
899 cpf_revoke(gid_name);
900 panic("req_slink: cpf_grant_magic failed");
903 /* Fill in request message */
904 m.m_type = REQ_SLINK;
905 m.REQ_INODE_NR = inode_nr;
906 m.REQ_UID = uid;
907 m.REQ_GID = gid;
908 m.REQ_GRANT = gid_name;
909 m.REQ_PATH_LEN = len;
910 m.REQ_GRANT3 = gid_buf;
911 m.REQ_MEM_SIZE = path_length;
913 /* Send/rec request */
914 r = fs_sendrec(fs_e, &m);
915 cpf_revoke(gid_name);
916 cpf_revoke(gid_buf);
918 return(r);
922 /*===========================================================================*
923 * req_stat *
924 *===========================================================================*/
925 int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf,
926 int old_stat)
928 cp_grant_id_t grant_id;
929 int r;
930 message m;
931 struct stat sb;
932 struct minix_prev_stat old_sb; /* for backward compatibility */
934 if (old_stat == 1) {
935 /* We're dealing with the old stat() call. First copy stat structure
936 * to VFS so we can convert the new struct stat to the old version.
938 grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb, sizeof(struct stat),
939 CPF_WRITE);
940 } else {
941 /* Grant FS access to copy straight into user provided buffer */
942 grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct stat),
943 CPF_WRITE);
946 if (grant_id < 0)
947 panic("req_stat: cpf_grant_* failed");
949 /* Fill in request message */
950 m.m_type = REQ_STAT;
951 m.REQ_INODE_NR = inode_nr;
952 m.REQ_GRANT = grant_id;
954 /* Send/rec request */
955 r = fs_sendrec(fs_e, &m);
956 cpf_revoke(grant_id);
958 if (r != OK || old_stat == 0)
959 return(r);
961 #if defined(_NETBSD_SOURCE)
962 #undef st_atime
963 #undef st_ctime
964 #undef st_mtime
965 #endif
967 /* Copy field by field because of st_gid type mismatch and
968 * difference in order after atime.
970 old_sb.st_dev = sb.st_dev;
971 old_sb.st_ino = sb.st_ino;
972 old_sb.st_mode = sb.st_mode;
973 old_sb.st_nlink = sb.st_nlink;
974 old_sb.st_uid = sb.st_uid;
975 old_sb.st_gid = sb.st_gid;
976 old_sb.st_rdev = sb.st_rdev;
977 old_sb.st_size = sb.st_size;
978 #if defined(_NETBSD_SOURCE)
979 old_sb.st_atime = sb.st_atimespec.tv_sec;
980 old_sb.st_mtime = sb.st_mtimespec.tv_sec;
981 old_sb.st_ctime = sb.st_ctimespec.tv_sec;
982 #else
983 old_sb.st_atime = sb.st_atime;
984 old_sb.st_mtime = sb.st_mtime;
985 old_sb.st_ctime = sb.st_ctime;
986 #endif
988 r = sys_vircopy(SELF, (vir_bytes) &old_sb, proc_e, buf,
989 sizeof(struct minix_prev_stat));
991 return(r);
995 /*===========================================================================*
996 * req_sync *
997 *===========================================================================*/
998 int req_sync(fs_e)
999 endpoint_t fs_e;
1001 message m;
1003 /* Fill in request message */
1004 m.m_type = REQ_SYNC;
1006 /* Send/rec request */
1007 return fs_sendrec(fs_e, &m);
1011 /*===========================================================================*
1012 * req_unlink *
1013 *===========================================================================*/
1014 int req_unlink(fs_e, inode_nr, lastc)
1015 endpoint_t fs_e;
1016 ino_t inode_nr;
1017 char *lastc;
1019 cp_grant_id_t grant_id;
1020 size_t len;
1021 int r;
1022 message m;
1024 len = strlen(lastc) + 1;
1025 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
1026 if(grant_id == -1)
1027 panic("req_unlink: cpf_grant_direct failed");
1029 /* Fill in request message */
1030 m.m_type = REQ_UNLINK;
1031 m.REQ_INODE_NR = inode_nr;
1032 m.REQ_GRANT = grant_id;
1033 m.REQ_PATH_LEN = len;
1035 /* Send/rec request */
1036 r = fs_sendrec(fs_e, &m);
1037 cpf_revoke(grant_id);
1039 return(r);
1043 /*===========================================================================*
1044 * req_unmount *
1045 *===========================================================================*/
1046 int req_unmount(fs_e)
1047 endpoint_t fs_e;
1049 message m;
1051 /* Fill in request message */
1052 m.m_type = REQ_UNMOUNT;
1054 /* Send/rec request */
1055 return fs_sendrec(fs_e, &m);
1059 /*===========================================================================*
1060 * req_utime *
1061 *===========================================================================*/
1062 int req_utime(fs_e, inode_nr, actime, modtime)
1063 endpoint_t fs_e;
1064 ino_t inode_nr;
1065 time_t actime;
1066 time_t modtime;
1068 message m;
1070 /* Fill in request message */
1071 m.m_type = REQ_UTIME;
1072 m.REQ_INODE_NR = inode_nr;
1073 m.REQ_ACTIME = actime;
1074 m.REQ_MODTIME = modtime;
1076 /* Send/rec request */
1077 return fs_sendrec(fs_e, &m);