panic() cleanup.
[minix.git] / servers / vfs / request.c
blobef5f4aeabbb2d48424794fc1b1708baa6e69d493
1 /* This file contains the wrapper functions for issueing 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 * The low-level fs_sendrec handles the recovery mechanism from
7 * a dead driver and reissues the request.
8 */
10 #include "fs.h"
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <sys/statfs.h>
14 #include <minix/vfsif.h>
15 #include <minix/callnr.h>
16 #include <minix/com.h>
17 #include <minix/keymap.h>
18 #include <minix/const.h>
19 #include <minix/endpoint.h>
20 #include <minix/u64.h>
21 #include <unistd.h>
22 #include <minix/vfsif.h>
23 #include "fproc.h"
24 #include "vmnt.h"
25 #include "vnode.h"
26 #include "param.h"
28 FORWARD _PROTOTYPE(int fs_sendrec_f, (char *file, int line, endpoint_t fs_e,
29 message *reqm) );
31 #define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
34 /*===========================================================================*
35 * req_breadwrite *
36 *===========================================================================*/
37 PUBLIC int req_breadwrite(fs_e, user_e, dev, pos, num_of_bytes, user_addr,
38 rw_flag, new_posp, cum_iop)
39 endpoint_t fs_e;
40 endpoint_t user_e;
41 dev_t dev;
42 u64_t pos;
43 unsigned int num_of_bytes;
44 char *user_addr;
45 int rw_flag;
46 u64_t *new_posp;
47 unsigned int *cum_iop;
49 int r;
50 cp_grant_id_t grant_id;
51 message m;
53 grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
54 (rw_flag == READING ? CPF_WRITE : CPF_READ));
55 if(grant_id == -1)
56 panic("req_breadwrite: cpf_grant_magic failed");
58 /* Fill in request message */
59 m.m_type = rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
60 m.REQ_DEV2 = dev;
61 m.REQ_GRANT = grant_id;
62 m.REQ_SEEK_POS_LO = ex64lo(pos);
63 m.REQ_SEEK_POS_HI = ex64hi(pos);
64 m.REQ_NBYTES = num_of_bytes;
66 /* Send/rec request */
67 r = fs_sendrec(fs_e, &m);
68 cpf_revoke(grant_id);
69 if (r != OK) return(r);
71 /* Fill in response structure */
72 *new_posp = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI);
73 *cum_iop = m.RES_NBYTES;
75 return(OK);
79 /*===========================================================================*
80 * req_chmod *
81 *===========================================================================*/
82 PUBLIC int req_chmod(fs_e, inode_nr, rmode, new_modep)
83 int fs_e;
84 ino_t inode_nr;
85 mode_t rmode;
86 mode_t *new_modep;
88 message m;
89 int r;
91 /* Fill in request message */
92 m.m_type = REQ_CHMOD;
93 m.REQ_INODE_NR = inode_nr;
94 m.REQ_MODE = rmode;
96 /* Send/rec request */
97 r = fs_sendrec(fs_e, &m);
99 /* Copy back actual mode. */
100 *new_modep = m.RES_MODE;
102 return(r);
106 /*===========================================================================*
107 * req_chown *
108 *===========================================================================*/
109 PUBLIC int req_chown(fs_e, inode_nr, newuid, newgid, new_modep)
110 endpoint_t fs_e;
111 ino_t inode_nr;
112 uid_t newuid;
113 gid_t newgid;
114 mode_t *new_modep;
116 message m;
117 int r;
119 /* Fill in request message */
120 m.m_type = REQ_CHOWN;
121 m.REQ_INODE_NR = inode_nr;
122 m.REQ_UID = newuid;
123 m.REQ_GID = newgid;
125 /* Send/rec request */
126 r = fs_sendrec(fs_e, &m);
128 /* Return new mode to caller. */
129 *new_modep = m.RES_MODE;
131 return(r);
135 /*===========================================================================*
136 * req_create *
137 *===========================================================================*/
138 int req_create(fs_e, inode_nr, omode, uid, gid, path, res)
139 int fs_e;
140 ino_t inode_nr;
141 int omode;
142 uid_t uid;
143 gid_t gid;
144 char *path;
145 node_details_t *res;
147 int r;
148 cp_grant_id_t grant_id;
149 size_t len;
150 message m;
152 if (path[0] == '/')
153 panic("req_create: filename starts with '/'");
155 len = strlen(path) + 1;
156 grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ);
157 if (grant_id == -1)
158 panic("req_create: cpf_grant_direct failed");
160 /* Fill in request message */
161 m.m_type = REQ_CREATE;
162 m.REQ_INODE_NR = inode_nr;
163 m.REQ_MODE = omode;
164 m.REQ_UID = uid;
165 m.REQ_GID = gid;
166 m.REQ_GRANT = grant_id;
167 m.REQ_PATH_LEN = len;
169 /* Send/rec request */
170 r = fs_sendrec(fs_e, &m);
171 cpf_revoke(grant_id);
172 if (r != OK) return(r);
174 /* Fill in response structure */
175 res->fs_e = m.m_source;
176 res->inode_nr = m.RES_INODE_NR;
177 res->fmode = m.RES_MODE;
178 res->fsize = m.RES_FILE_SIZE_LO;
179 res->uid = m.RES_UID;
180 res->gid = m.RES_GID;
181 res->dev = m.RES_DEV;
183 return(OK);
187 /*===========================================================================*
188 * req_flush *
189 *===========================================================================*/
190 PUBLIC int req_flush(fs_e, dev)
191 endpoint_t fs_e;
192 dev_t dev;
194 message m;
196 /* Fill in request message */
197 m.m_type = REQ_FLUSH;
198 m.REQ_DEV = dev;
200 /* Send/rec request */
201 return fs_sendrec(fs_e, &m);
205 /*===========================================================================*
206 * req_fstatfs *
207 *===========================================================================*/
208 PUBLIC int req_fstatfs(fs_e, who_e, buf)
209 int fs_e;
210 int who_e;
211 char *buf;
213 int r;
214 cp_grant_id_t grant_id;
215 message m;
217 grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, sizeof(struct statfs),
218 CPF_WRITE);
219 if(grant_id == -1)
220 panic("req_fstatfs: cpf_grant_magic failed");
222 /* Fill in request message */
223 m.m_type = REQ_FSTATFS;
224 m.REQ_GRANT = grant_id;
226 /* Send/rec request */
227 r = fs_sendrec(fs_e, &m);
228 cpf_revoke(grant_id);
230 return(r);
234 /*===========================================================================*
235 * req_ftrunc *
236 *===========================================================================*/
237 PUBLIC int req_ftrunc(fs_e, inode_nr, start, end)
238 endpoint_t fs_e;
239 ino_t inode_nr;
240 off_t start;
241 off_t end;
243 message m;
245 /* Fill in request message */
246 m.m_type = REQ_FTRUNC;
247 m.REQ_INODE_NR = inode_nr;
248 m.REQ_TRC_START_LO = start;
249 m.REQ_TRC_START_HI = 0; /* Not used for now, so clear it. */
250 m.REQ_TRC_END_LO = end;
251 m.REQ_TRC_END_HI = 0; /* Not used for now, so clear it. */
253 /* Send/rec request */
254 return fs_sendrec(fs_e, &m);
258 /*===========================================================================*
259 * req_getdents *
260 *===========================================================================*/
261 PUBLIC int req_getdents(fs_e, inode_nr, pos, buf, size, new_pos)
262 endpoint_t fs_e;
263 ino_t inode_nr;
264 u64_t pos;
265 char *buf;
266 size_t size;
267 u64_t *new_pos;
269 int r;
270 message m;
271 cp_grant_id_t grant_id;
273 grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, size, CPF_WRITE);
274 if (grant_id < 0)
275 panic("req_getdents: cpf_grant_magic failed: %d", grant_id);
277 m.m_type = REQ_GETDENTS;
278 m.REQ_INODE_NR = inode_nr;
279 m.REQ_GRANT = grant_id;
280 m.REQ_MEM_SIZE = size;
281 m.REQ_SEEK_POS_LO = ex64lo(pos);
282 m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */
284 r = fs_sendrec(fs_e, &m);
285 cpf_revoke(grant_id);
287 if (r == OK) {
288 *new_pos = cvul64(m.RES_SEEK_POS_LO);
289 r = m.RES_NBYTES;
292 return(r);
296 /*===========================================================================*
297 * req_inhibread *
298 *===========================================================================*/
299 PUBLIC int req_inhibread(fs_e, inode_nr)
300 endpoint_t fs_e;
301 ino_t inode_nr;
303 message m;
305 /* Fill in request message */
306 m.m_type = REQ_INHIBREAD;
307 m.REQ_INODE_NR = inode_nr;
309 /* Send/rec request */
310 return fs_sendrec(fs_e, &m);
314 /*===========================================================================*
315 * req_link *
316 *===========================================================================*/
317 PUBLIC int req_link(fs_e, link_parent, lastc, linked_file)
318 endpoint_t fs_e;
319 ino_t link_parent;
320 char *lastc;
321 ino_t linked_file;
323 int r;
324 cp_grant_id_t grant_id;
325 size_t len;
326 message m;
328 len = strlen(lastc) + 1;
329 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
330 if(grant_id == -1)
331 panic("req_link: cpf_grant_direct failed");
333 /* Fill in request message */
334 m.m_type = REQ_LINK;
335 m.REQ_INODE_NR = linked_file;
336 m.REQ_DIR_INO = link_parent;
337 m.REQ_GRANT = grant_id;
338 m.REQ_PATH_LEN = len;
340 /* Send/rec request */
341 r = fs_sendrec(fs_e, &m);
342 cpf_revoke(grant_id);
344 return(r);
348 /*===========================================================================*
349 * req_lookup *
350 *===========================================================================*/
351 PUBLIC int req_lookup(fs_e, dir_ino, root_ino, uid, gid, flags, res)
352 endpoint_t fs_e;
353 ino_t dir_ino;
354 ino_t root_ino;
355 uid_t uid;
356 gid_t gid;
357 int flags;
358 lookup_res_t *res;
360 int r;
361 size_t len;
362 cp_grant_id_t grant_id, grant_id2;
363 message m;
364 vfs_ucred_t credentials;
366 grant_id = cpf_grant_direct(fs_e, (vir_bytes) user_fullpath,
367 sizeof(user_fullpath), CPF_READ | CPF_WRITE);
368 if(grant_id == -1)
369 panic("req_lookup: cpf_grant_direct failed");
371 len = strlen(user_fullpath) + 1;
373 m.m_type = REQ_LOOKUP;
374 m.REQ_GRANT = grant_id;
375 m.REQ_PATH_LEN = len;
376 m.REQ_PATH_SIZE = sizeof(user_fullpath);
377 m.REQ_DIR_INO = dir_ino;
378 m.REQ_ROOT_INO = root_ino;
380 if(fp->fp_ngroups > 0) { /* Is the process member of multiple groups? */
381 /* In that case the FS has to copy the uid/gid credentials */
382 int i;
384 /* Set credentials */
385 credentials.vu_uid = fp->fp_effuid;
386 credentials.vu_gid = fp->fp_effgid;
387 credentials.vu_ngroups = fp->fp_ngroups;
388 for (i = 0; i < fp->fp_ngroups; i++)
389 credentials.vu_sgroups[i] = fp->fp_sgroups[i];
391 grant_id2 = cpf_grant_direct(fs_e, (vir_bytes) &credentials,
392 sizeof(credentials), CPF_READ);
393 if(grant_id2 == -1)
394 panic("req_lookup: cpf_grant_direct failed");
396 m.REQ_GRANT2 = grant_id2;
397 m.REQ_UCRED_SIZE= sizeof(credentials);
398 flags |= PATH_GET_UCRED;
399 } else {
400 /* When there's only one gid, we can send it directly */
401 m.REQ_UID = uid;
402 m.REQ_GID = gid;
403 flags &= ~PATH_GET_UCRED;
406 m.REQ_FLAGS = flags;
408 /* Send/rec request */
409 r = fs_sendrec(fs_e, &m);
410 cpf_revoke(grant_id);
411 if(fp->fp_ngroups > 0) cpf_revoke(grant_id2);
413 /* Fill in response according to the return value */
414 res->fs_e = m.m_source;
416 switch (r) {
417 case OK:
418 res->inode_nr = m.RES_INODE_NR;
419 res->fmode = m.RES_MODE;
420 res->fsize = m.RES_FILE_SIZE_LO;
421 res->dev = m.RES_DEV;
422 res->uid= m.RES_UID;
423 res->gid= m.RES_GID;
424 break;
425 case EENTERMOUNT:
426 res->inode_nr = m.RES_INODE_NR;
427 res->char_processed = m.RES_OFFSET;
428 res->symloop = m.RES_SYMLOOP;
429 break;
430 case ELEAVEMOUNT:
431 res->char_processed = m.RES_OFFSET;
432 res->symloop = m.RES_SYMLOOP;
433 break;
434 case ESYMLINK:
435 res->char_processed = m.RES_OFFSET;
436 res->symloop = m.RES_SYMLOOP;
437 break;
438 default:
439 break;
442 return(r);
446 /*===========================================================================*
447 * req_mkdir *
448 *===========================================================================*/
449 PUBLIC int req_mkdir(fs_e, inode_nr, lastc, uid, gid, dmode)
450 endpoint_t fs_e;
451 ino_t inode_nr;
452 char *lastc;
453 uid_t uid;
454 gid_t gid;
455 mode_t dmode;
457 int r;
458 cp_grant_id_t grant_id;
459 size_t len;
460 message m;
462 len = strlen(lastc) + 1;
463 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
464 if(grant_id == -1)
465 panic("req_mkdir: cpf_grant_direct failed");
467 /* Fill in request message */
468 m.m_type = REQ_MKDIR;
469 m.REQ_INODE_NR = inode_nr;
470 m.REQ_MODE = dmode;
471 m.REQ_UID = uid;
472 m.REQ_GID = gid;
473 m.REQ_GRANT = grant_id;
474 m.REQ_PATH_LEN = len;
476 /* Send/rec request */
477 r = fs_sendrec(fs_e, &m);
478 cpf_revoke(grant_id);
480 return(r);
484 /*===========================================================================*
485 * req_mknod *
486 *===========================================================================*/
487 PUBLIC int req_mknod(fs_e, inode_nr, lastc, uid, gid, dmode, dev)
488 endpoint_t fs_e;
489 ino_t inode_nr;
490 char *lastc;
491 uid_t uid;
492 gid_t gid;
493 mode_t dmode;
494 dev_t dev;
496 int r;
497 size_t len;
498 cp_grant_id_t grant_id;
499 message m;
501 len = strlen(lastc) + 1;
502 grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
503 if(grant_id == -1)
504 panic("req_mknod: cpf_grant_direct failed");
506 /* Fill in request message */
507 m.m_type = REQ_MKNOD;
508 m.REQ_INODE_NR = inode_nr;
509 m.REQ_MODE = dmode;
510 m.REQ_DEV = dev;
511 m.REQ_UID = uid;
512 m.REQ_GID = gid;
513 m.REQ_GRANT = grant_id;
514 m.REQ_PATH_LEN = len;
516 /* Send/rec request */
517 r = fs_sendrec(fs_e, &m);
518 cpf_revoke(grant_id);
520 return(r);
524 /*===========================================================================*
525 * req_mountpoint *
526 *===========================================================================*/
527 PUBLIC int req_mountpoint(fs_e, inode_nr)
528 endpoint_t fs_e;
529 ino_t inode_nr;
531 int r;
532 message m;
534 /* Fill in request message */
535 m.m_type = REQ_MOUNTPOINT;
536 m.REQ_INODE_NR = inode_nr;
538 /* Send/rec request */
539 return fs_sendrec(fs_e, &m);
543 /*===========================================================================*
544 * req_newnode *
545 *===========================================================================*/
546 PUBLIC int req_newnode(fs_e, uid, gid, dmode, dev, res)
547 endpoint_t fs_e;
548 uid_t uid;
549 gid_t gid;
550 mode_t dmode;
551 dev_t dev;
552 struct node_details *res;
554 int r;
555 message m;
557 /* Fill in request message */
558 m.m_type = REQ_NEWNODE;
559 m.REQ_MODE = dmode;
560 m.REQ_DEV = dev;
561 m.REQ_UID = uid;
562 m.REQ_GID = gid;
564 /* Send/rec request */
565 r = fs_sendrec(fs_e, &m);
567 res->fs_e = m.m_source;
568 res->inode_nr = m.RES_INODE_NR;
569 res->fmode = m.RES_MODE;
570 res->fsize = m.RES_FILE_SIZE_LO;
571 res->dev = m.RES_DEV;
572 res->uid = m.RES_UID;
573 res->gid = m.RES_GID;
575 return(r);
579 /*===========================================================================*
580 * req_newdriver *
581 *===========================================================================*/
582 PUBLIC int req_newdriver(fs_e, dev, driver_e)
583 endpoint_t fs_e;
584 Dev_t dev;
585 endpoint_t driver_e;
587 /* Note: this is the only request function that doesn't use the
588 * fs_sendrec internal routine, since we want to avoid the dead
589 * driver recovery mechanism here. This function is actually called
590 * during the recovery.
592 message m;
593 int r;
595 /* Fill in request message */
596 m.m_type = REQ_NEW_DRIVER;
597 m.REQ_DEV = dev;
598 m.REQ_DRIVER_E = driver_e;
600 /* Issue request */
601 if((r = sendrec(fs_e, &m)) != OK) {
602 printf("%s:%d VFS req_newdriver: error sending message %d to %d\n",
603 __FILE__, __LINE__, r, fs_e);
604 util_stacktrace();
605 return(r);
608 return(OK);
613 /*===========================================================================*
614 * req_putnode *
615 *===========================================================================*/
616 PUBLIC int req_putnode(fs_e, inode_nr, count)
617 int fs_e;
618 ino_t inode_nr;
619 int count;
621 message m;
623 /* Fill in request message */
624 m.m_type = REQ_PUTNODE;
625 m.REQ_INODE_NR = inode_nr;
626 m.REQ_COUNT = count;
628 /* Send/rec request */
629 return fs_sendrec(fs_e, &m);
633 /*===========================================================================*
634 * req_rdlink *
635 *===========================================================================*/
636 PUBLIC int req_rdlink(fs_e, inode_nr, who_e, buf, len)
637 endpoint_t fs_e;
638 ino_t inode_nr;
639 endpoint_t who_e;
640 char *buf;
641 size_t len;
643 message m;
644 int r;
645 cp_grant_id_t grant_id;
647 grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, len, CPF_WRITE);
648 if(grant_id == -1)
649 panic("req_rdlink: cpf_grant_magic failed");
651 /* Fill in request message */
652 m.m_type = REQ_RDLINK;
653 m.REQ_INODE_NR = inode_nr;
654 m.REQ_GRANT = grant_id;
655 m.REQ_MEM_SIZE = len;
657 /* Send/rec request */
658 r = fs_sendrec(fs_e, &m);
659 cpf_revoke(grant_id);
661 if(r == OK) r = m.RES_NBYTES;
663 return(r);
667 /*===========================================================================*
668 * req_readsuper *
669 *===========================================================================*/
670 PUBLIC int req_readsuper(fs_e, label, dev, readonly, isroot, res_nodep)
671 endpoint_t fs_e;
672 char *label;
673 dev_t dev;
674 int readonly;
675 int isroot;
676 struct node_details *res_nodep;
678 int r;
679 cp_grant_id_t grant_id;
680 size_t len;
681 message m;
683 len = strlen(label)+1;
684 grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
685 if (grant_id == -1)
686 panic("req_readsuper: cpf_grant_direct failed");
688 /* Fill in request message */
689 m.m_type = REQ_READSUPER;
690 m.REQ_FLAGS = 0;
691 if(readonly) m.REQ_FLAGS |= REQ_RDONLY;
692 if(isroot) m.REQ_FLAGS |= REQ_ISROOT;
693 m.REQ_GRANT = grant_id;
694 m.REQ_DEV = dev;
695 m.REQ_PATH_LEN = len;
697 /* Send/rec request */
698 r = fs_sendrec(fs_e, &m);
699 cpf_revoke(grant_id);
701 if(r == OK) {
702 /* Fill in response structure */
703 res_nodep->fs_e = m.m_source;
704 res_nodep->inode_nr = m.RES_INODE_NR;
705 res_nodep->fmode = m.RES_MODE;
706 res_nodep->fsize = m.RES_FILE_SIZE_LO;
707 res_nodep->uid = m.RES_UID;
708 res_nodep->gid = m.RES_GID;
711 return(r);
715 /*===========================================================================*
716 * req_readwrite *
717 *===========================================================================*/
718 PUBLIC int req_readwrite(fs_e, inode_nr, pos, rw_flag, user_e,
719 user_addr, num_of_bytes, new_posp, cum_iop)
720 endpoint_t fs_e;
721 ino_t inode_nr;
722 u64_t pos;
723 int rw_flag;
724 endpoint_t user_e;
725 char *user_addr;
726 unsigned int num_of_bytes;
727 u64_t *new_posp;
728 unsigned int *cum_iop;
730 int r;
731 cp_grant_id_t grant_id;
732 message m;
734 if (ex64hi(pos) != 0)
735 panic("req_readwrite: pos too large");
737 grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
738 (rw_flag==READING ? CPF_WRITE:CPF_READ));
739 if (grant_id == -1)
740 panic("req_readwrite: cpf_grant_magic failed");
742 /* Fill in request message */
743 m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
744 m.REQ_INODE_NR = inode_nr;
745 m.REQ_GRANT = grant_id;
746 m.REQ_SEEK_POS_LO = ex64lo(pos);
747 m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */
748 m.REQ_NBYTES = num_of_bytes;
750 /* Send/rec request */
751 r = fs_sendrec(fs_e, &m);
752 cpf_revoke(grant_id);
754 if (r == OK) {
755 /* Fill in response structure */
756 *new_posp = cvul64(m.RES_SEEK_POS_LO);
757 *cum_iop = m.RES_NBYTES;
760 return(r);
764 /*===========================================================================*
765 * req_rename *
766 *===========================================================================*/
767 PUBLIC int req_rename(fs_e, old_dir, old_name, new_dir, new_name)
768 endpoint_t fs_e;
769 ino_t old_dir;
770 char *old_name;
771 ino_t new_dir;
772 char *new_name;
774 int r;
775 cp_grant_id_t gid_old, gid_new;
776 size_t len_old, len_new;
777 message m;
779 len_old = strlen(old_name) + 1;
780 gid_old = cpf_grant_direct(fs_e, (vir_bytes) old_name, len_old, CPF_READ);
781 if(gid_old == -1)
782 panic("req_rename: cpf_grant_direct failed");
784 len_new = strlen(new_name) + 1;
785 gid_new = cpf_grant_direct(fs_e, (vir_bytes) new_name, len_new, CPF_READ);
786 if(gid_new == -1)
787 panic("req_rename: cpf_grant_direct failed");
789 /* Fill in request message */
790 m.m_type = REQ_RENAME;
791 m.REQ_REN_OLD_DIR = old_dir;
792 m.REQ_REN_NEW_DIR = new_dir;
793 m.REQ_REN_GRANT_OLD = gid_old;
794 m.REQ_REN_LEN_OLD = len_old;
795 m.REQ_REN_GRANT_NEW = gid_new;
796 m.REQ_REN_LEN_NEW = len_new;
798 /* Send/rec request */
799 r = fs_sendrec(fs_e, &m);
800 cpf_revoke(gid_old);
801 cpf_revoke(gid_new);
803 return(r);
807 /*===========================================================================*
808 * req_rmdir *
809 *===========================================================================*/
810 PUBLIC int req_rmdir(fs_e, inode_nr, lastc)
811 endpoint_t fs_e;
812 ino_t inode_nr;
813 char *lastc;
815 int r;
816 cp_grant_id_t grant_id;
817 size_t len;
818 message m;
820 len = strlen(lastc) + 1;
821 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
822 if(grant_id == -1)
823 panic("req_rmdir: cpf_grant_direct failed");
825 /* Fill in request message */
826 m.m_type = REQ_RMDIR;
827 m.REQ_INODE_NR = inode_nr;
828 m.REQ_GRANT = grant_id;
829 m.REQ_PATH_LEN = len;
831 /* Send/rec request */
832 r = fs_sendrec(fs_e, &m);
833 cpf_revoke(grant_id);
835 return(r);
839 /*===========================================================================*
840 * req_slink *
841 *===========================================================================*/
842 PUBLIC int req_slink(fs_e, inode_nr, lastc, who_e, path_addr, path_length,
843 uid, gid)
844 endpoint_t fs_e;
845 ino_t inode_nr;
846 char *lastc;
847 endpoint_t who_e;
848 char *path_addr;
849 unsigned short path_length;
850 uid_t uid;
851 gid_t gid;
853 int r;
854 size_t len;
855 cp_grant_id_t gid_name, gid_buf;
856 message m;
858 len = strlen(lastc) + 1;
859 gid_name = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
860 if(gid_name == -1)
861 panic("req_slink: cpf_grant_direct failed");
863 gid_buf = cpf_grant_magic(fs_e, who_e, (vir_bytes) path_addr, path_length,
864 CPF_READ);
865 if(gid_buf == -1) {
866 cpf_revoke(gid_name);
867 panic("req_slink: cpf_grant_magic failed");
870 /* Fill in request message */
871 m.m_type = REQ_SLINK;
872 m.REQ_INODE_NR = inode_nr;
873 m.REQ_UID = uid;
874 m.REQ_GID = gid;
875 m.REQ_GRANT = gid_name;
876 m.REQ_PATH_LEN = len;
877 m.REQ_GRANT3 = gid_buf;
878 m.REQ_MEM_SIZE = path_length;
880 /* Send/rec request */
881 r = fs_sendrec(fs_e, &m);
882 cpf_revoke(gid_name);
883 cpf_revoke(gid_buf);
885 return(r);
889 /*===========================================================================*
890 * req_stat *
891 *===========================================================================*/
892 PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos)
893 int fs_e;
894 ino_t inode_nr;
895 int who_e;
896 char *buf;
897 int pos;
899 cp_grant_id_t grant_id;
900 int r;
901 message m;
902 struct stat sb;
904 if (pos != 0)
905 grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb,
906 sizeof(struct stat), CPF_WRITE);
907 else
908 grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf,
909 sizeof(struct stat), CPF_WRITE);
911 if (grant_id < 0)
912 panic("req_stat: cpf_grant_* failed");
914 /* Fill in request message */
915 m.m_type = REQ_STAT;
916 m.REQ_INODE_NR = inode_nr;
917 m.REQ_GRANT = grant_id;
919 /* Send/rec request */
920 r = fs_sendrec(fs_e, &m);
921 cpf_revoke(grant_id);
923 if (r == OK && pos != 0) {
924 sb.st_size -= pos;
925 r = sys_vircopy(SELF, D, (vir_bytes) &sb, who_e, D, (vir_bytes) buf,
926 sizeof(struct stat));
929 return(r);
933 /*===========================================================================*
934 * req_sync *
935 *===========================================================================*/
936 PUBLIC int req_sync(fs_e)
937 endpoint_t fs_e;
939 message m;
941 /* Fill in request message */
942 m.m_type = REQ_SYNC;
944 /* Send/rec request */
945 return fs_sendrec(fs_e, &m);
949 /*===========================================================================*
950 * req_unlink *
951 *===========================================================================*/
952 PUBLIC int req_unlink(fs_e, inode_nr, lastc)
953 endpoint_t fs_e;
954 ino_t inode_nr;
955 char *lastc;
957 cp_grant_id_t grant_id;
958 size_t len;
959 int r;
960 message m;
962 len = strlen(lastc) + 1;
963 grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
964 if(grant_id == -1)
965 panic("req_unlink: cpf_grant_direct failed");
967 /* Fill in request message */
968 m.m_type = REQ_UNLINK;
969 m.REQ_INODE_NR = inode_nr;
970 m.REQ_GRANT = grant_id;
971 m.REQ_PATH_LEN = len;
973 /* Send/rec request */
974 r = fs_sendrec(fs_e, &m);
975 cpf_revoke(grant_id);
977 return(r);
981 /*===========================================================================*
982 * req_unmount *
983 *===========================================================================*/
984 PUBLIC int req_unmount(fs_e)
985 endpoint_t fs_e;
987 message m;
989 /* Fill in request message */
990 m.m_type = REQ_UNMOUNT;
992 /* Send/rec request */
993 return fs_sendrec(fs_e, &m);
997 /*===========================================================================*
998 * req_utime *
999 *===========================================================================*/
1000 PUBLIC int req_utime(fs_e, inode_nr, actime, modtime)
1001 endpoint_t fs_e;
1002 ino_t inode_nr;
1003 time_t actime;
1004 time_t modtime;
1006 message m;
1008 /* Fill in request message */
1009 m.m_type = REQ_UTIME;
1010 m.REQ_INODE_NR = inode_nr;
1011 m.REQ_ACTIME = actime;
1012 m.REQ_MODTIME = modtime;
1014 /* Send/rec request */
1015 return fs_sendrec(fs_e, &m);
1019 /*===========================================================================*
1020 * fs_sendrec *
1021 *===========================================================================*/
1022 PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
1024 /* This is the low level function that sends requests to FS processes.
1025 * It also handles driver recovery mechanism and reissuing the
1026 * request which failed due to a dead driver.
1028 int r, old_driver_e, new_driver_e;
1029 message origm, m;
1030 struct vmnt *vmp;
1032 if(fs_e <= 0 || fs_e == NONE)
1033 panic("talking to bogus endpoint: %d", fs_e);
1035 /* Make a copy of the request so that we can load it back in
1036 * case of a dead driver */
1037 origm = *reqm;
1039 /* In response to the request we sent, some file systems may send back their
1040 * own VFS request, instead of a reply. VFS currently offers limited support
1041 * for this. As long as the FS keeps sending requests, we process them and
1042 * send back a reply. We break out of the loop as soon as the FS sends a
1043 * reply to the original request.
1045 * There is no form of locking or whatever on global data structures, so it
1046 * is quite easy to mess things up; hence, 'limited' support. A future async
1047 * VFS will solve this problem for good.
1049 for (;;) {
1050 /* Do the actual send, receive */
1051 if (OK != (r = sendrec(fs_e, reqm))) {
1052 printf("VFS:fs_sendrec:%s:%d: error sending message. "
1053 "FS_e: %d req_nr: %d err: %d\n", file, line, fs_e,
1054 reqm->m_type, r);
1055 util_stacktrace();
1056 return(r);
1059 /* If the type field is 0 (OK) or negative (E*), this is a reply. If it
1060 * contains a positive nonzero value, this is a request.
1062 if (reqm->m_type <= 0)
1063 break; /* Reply */
1065 if (reqm->m_type == -EENTERMOUNT || reqm->m_type == -ELEAVEMOUNT ||
1066 reqm->m_type == -ESYMLINK) {
1068 reqm->m_type = -reqm->m_type;
1069 break; /* Reply */
1072 /* Request */
1073 nested_fs_call(reqm);
1076 #if 0
1077 if(r == OK) {
1078 /* Sendrec was okay */
1079 break;
1081 /* Dead driver */
1082 if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
1083 old_driver_e = NONE;
1084 /* Find old driver by endpoint */
1085 for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
1086 if (vmp->m_fs_e == fs_e) { /* found FS */
1087 #if 0
1088 old_driver_e = vmp->m_driver_e;
1089 #endif
1090 dmap_unmap_by_endpt(old_driver_e); /* unmap driver */
1091 break;
1095 /* No FS ?? */
1096 if (old_driver_e == NONE)
1097 panic("VFSdead_driver: couldn't find FS: %d", fs_e);
1099 /* Wait for a new driver. */
1100 for (;;) {
1101 new_driver_e = 0;
1102 printf("VFSdead_driver: waiting for new driver\n");
1103 r = sef_receive(RS_PROC_NR, &m);
1104 if (r != OK) {
1105 panic("VFSdead_driver: unable to receive from RS: %d", r);
1107 if (m.m_type == DEVCTL) {
1108 /* Map new driver */
1109 r = fs_devctl(m.ctl_req, m.dev_nr, m.driver_nr,
1110 m.dev_style, m.m_force);
1111 if (m.ctl_req == DEV_MAP && r == OK) {
1112 new_driver_e = m.driver_nr;
1113 printf("VFSdead_driver: new driver endpoint: %d\n",
1114 new_driver_e);
1117 else {
1118 panic("VFSdead_driver: got message from RS type: %d", m.m_type);
1120 m.m_type = r;
1121 if ((r = send(RS_PROC_NR, &m)) != OK) {
1122 panic("VFSdead_driver: unable to send to RS: %d", r);
1124 /* New driver is ready */
1125 if (new_driver_e) break;
1128 /* Copy back original request */
1129 *reqm = origm;
1130 continue;
1133 printf("fs_sendrec: unhandled error %d sending to %d\n", r, fs_e);
1134 panic("fs_sendrec: unhandled error");
1136 #endif
1138 /* Return message type */
1139 return(reqm->m_type);