correct references to manpage section 9 to 1x.
[minix3.git] / servers / vfs / request.c
blobb4ca2810ebf08cc542d27d413af1a56f973b4a1c
2 /* This file contains the wrapper functions for issueing a request
3 * and receiving response from FS processes.
4 * Each function builds a request message according to the request
5 * parameter, calls the most low-level fs_sendrec and copies
6 * back the response.
7 * The low-level fs_sendrec handles the recovery mechanism from
8 * a dead driver and reissues the request.
10 * Sep 2006 (Balazs Gerofi)
13 #include "fs.h"
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/statfs.h>
17 #include <minix/callnr.h>
18 #include <minix/com.h>
19 #include <minix/keymap.h>
20 #include <minix/const.h>
21 #include <minix/endpoint.h>
22 #include <minix/u64.h>
23 #include <unistd.h>
25 #include <minix/vfsif.h>
26 #include "fproc.h"
27 #include "vmnt.h"
28 #include "vnode.h"
29 #include "param.h"
31 FORWARD _PROTOTYPE(int fs_sendrec_f, (char *file, int line, endpoint_t fs_e, message *reqm));
33 #define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
35 /*===========================================================================*
36 * req_getnode *
37 *===========================================================================*/
38 PUBLIC int req_getnode_f(file, line, req, res)
39 char *file;
40 int line;
41 node_req_t *req;
42 node_details_t *res;
44 int r;
45 message m;
47 /* Fill in request message */
48 m.m_type = REQ_GETNODE;
49 m.REQ_INODE_NR = req->inode_nr;
51 /* Send/rec request */
52 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
54 /* Fill in response structure */
55 res->fs_e = m.m_source;
56 res->inode_nr = m.RES_INODE_NR;
57 res->fmode = m.RES_MODE;
58 res->fsize = m.RES_FILE_SIZE;
59 res->dev = m.RES_DEV;
60 res->uid = m.RES_UID;
61 res->gid = m.RES_GID;
63 return OK;
67 /*===========================================================================*
68 * req_putnode *
69 *===========================================================================*/
70 PUBLIC int req_putnode(fs_e, inode_nr, count)
71 int fs_e;
72 ino_t inode_nr;
73 int count;
75 message m;
77 /* Fill in request message */
78 m.m_type = REQ_PUTNODE;
79 m.REQ_INODE_NR = inode_nr;
80 m.REQ_COUNT = count;
82 /* Send/rec request */
83 return fs_sendrec(fs_e, &m);
86 /*===========================================================================*
87 * req_open *
88 *===========================================================================*/
89 int req_open(req, res)
90 open_req_t *req;
91 node_details_t *res;
93 int r;
94 message m;
96 /* Fill in request message */
97 m.m_type = REQ_OPEN;
98 m.REQ_INODE_NR = req->inode_nr;
99 m.REQ_FLAGS = req->oflags;
100 m.REQ_MODE = req->omode;
101 m.REQ_UID = req->uid;
102 m.REQ_GID = req->gid;
103 m.REQ_PATH = req->lastc;
104 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
106 /* Send/rec request */
107 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
109 /* Fill in response structure */
110 res->fs_e = m.m_source;
111 res->inode_nr = m.RES_INODE_NR;
112 res->fmode = m.RES_MODE;
113 res->fsize = m.RES_FILE_SIZE;
114 res->dev = m.RES_DEV;
115 res->inode_index = m.RES_INODE_INDEX;
116 /* For exec */
117 res->uid = m.RES_UID;
118 res->gid = m.RES_GID;
119 res->ctime = m.RES_CTIME;
121 return OK;
125 /*===========================================================================*
126 * req_create *
127 *===========================================================================*/
128 int req_create(fs_e, inode_nr, omode, uid, gid, path, res)
129 int fs_e;
130 ino_t inode_nr;
131 int omode;
132 uid_t uid;
133 gid_t gid;
134 char *path;
135 node_details_t *res;
137 int r;
138 message m;
140 /* Fill in request message */
141 m.m_type = REQ_CREATE;
142 m.REQ_INODE_NR = inode_nr;
143 m.REQ_MODE = omode;
144 m.REQ_UID = uid;
145 m.REQ_GID = gid;
146 m.REQ_PATH = path;
147 m.REQ_PATH_LEN = strlen(path) + 1;
149 /* Send/rec request */
150 if ((r = fs_sendrec(fs_e, &m)) != OK) return r;
152 /* Fill in response structure */
153 res->fs_e = m.m_source;
154 res->inode_nr = m.RES_INODE_NR;
155 res->fmode = m.RES_MODE;
156 res->fsize = m.RES_FILE_SIZE;
157 res->dev = m.RES_DEV;
158 res->inode_index = m.RES_INODE_INDEX;
159 /* For exec */
160 res->uid = m.RES_UID;
161 res->gid = m.RES_GID;
162 res->ctime = m.RES_CTIME;
164 return OK;
168 /*===========================================================================*
169 * req_readwrite *
170 *===========================================================================*/
171 int req_readwrite(req, res)
172 readwrite_req_t *req;
173 readwrite_res_t *res;
175 int r;
176 message m;
178 if (ex64hi(req->pos) != 0)
179 panic(__FILE__, "req_readwrite: pos too large", NO_NUM);
181 /* Fill in request message */
182 m.m_type = req->rw_flag == READING ? REQ_READ : REQ_WRITE;
183 m.REQ_FD_INODE_NR = req->inode_nr;
184 m.REQ_FD_WHO_E = req->user_e;
185 m.REQ_FD_SEG = req->seg;
186 m.REQ_FD_POS = ex64lo(req->pos);
187 m.REQ_FD_NBYTES = req->num_of_bytes;
188 m.REQ_FD_USER_ADDR = req->user_addr;
189 m.REQ_FD_INODE_INDEX = req->inode_index;
191 /* Send/rec request */
192 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
194 /* Fill in response structure */
195 res->new_pos = cvul64(m.RES_FD_POS);
196 res->cum_io = m.RES_FD_CUM_IO;
198 return OK;
203 /*===========================================================================*
204 * req_pipe *
205 *===========================================================================*/
206 PUBLIC int req_pipe(req, res)
207 pipe_req_t *req;
208 node_details_t *res;
210 int r;
211 message m;
213 /* Fill in request message */
214 m.m_type = REQ_PIPE;
215 m.REQ_UID = req->uid;
216 m.REQ_GID = req->gid;
218 /* Send/rec request */
219 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
221 /* Fill in response structure */
222 res->fs_e = m.m_source;
223 res->inode_nr = m.RES_INODE_NR;
224 res->fmode = m.RES_MODE;
225 res->fsize = m.RES_FILE_SIZE;
226 res->dev = m.RES_DEV;
227 res->inode_index = m.RES_INODE_INDEX;
229 return OK;
233 /*===========================================================================*
234 * req_clone_opcl *
235 *===========================================================================*/
236 PUBLIC int req_clone_opcl(req, res)
237 clone_opcl_req_t *req;
238 node_details_t *res;
240 int r;
241 message m;
243 /* Fill in request message */
244 m.m_type = REQ_CLONE_OPCL;
245 m.REQ_DEV = req->dev;
247 /* Send/rec request */
248 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
250 /* Fill in response structure */
251 res->fs_e = m.m_source;
252 res->inode_nr = m.RES_INODE_NR;
253 res->fmode = m.RES_MODE;
254 res->fsize = m.RES_FILE_SIZE;
255 res->dev = m.RES_DEV;
256 res->inode_index = m.RES_INODE_INDEX;
258 return OK;
263 /*===========================================================================*
264 * req_ftrunc *
265 *===========================================================================*/
266 PUBLIC int req_ftrunc(req)
267 ftrunc_req_t *req;
269 message m;
271 /* Fill in request message */
272 m.m_type = REQ_FTRUNC;
273 m.REQ_FD_INODE_NR = req->inode_nr;
274 m.REQ_FD_START = req->start;
275 m.REQ_FD_END = req->end;
277 /* Send/rec request */
278 return fs_sendrec(req->fs_e, &m);
282 /*===========================================================================*
283 * req_chmod *
284 *===========================================================================*/
285 PUBLIC int req_chmod(req, ch_mode)
286 chmod_req_t *req;
287 int *ch_mode;
289 message m;
290 int r;
292 /* Fill in request message */
293 m.m_type = REQ_CHMOD;
294 m.REQ_INODE_NR = req->inode_nr;
295 m.REQ_MODE = req->rmode;
296 m.REQ_UID = req->uid;
297 m.REQ_GID = req->gid;
299 /* Send/rec request */
300 r = fs_sendrec(req->fs_e, &m);
302 /* Copy back actual mode. */
303 if(ch_mode) *ch_mode = m.RES_MODE;
305 return r;
309 /*===========================================================================*
310 * req_chown *
311 *===========================================================================*/
312 PUBLIC int req_chown(req, ch_mode)
313 chown_req_t *req;
314 int *ch_mode;
316 message m;
317 int r;
319 /* Fill in request message */
320 m.m_type = REQ_CHOWN;
321 m.REQ_INODE_NR = req->inode_nr;
322 m.REQ_UID = req->uid;
323 m.REQ_GID = req->gid;
324 m.REQ_NEW_UID = req->newuid;
325 m.REQ_NEW_GID = req->newgid;
327 /* Send/rec request */
328 r = fs_sendrec(req->fs_e, &m);
330 /* Return new mode to caller. */
331 if(ch_mode) *ch_mode = m.RES_MODE;
333 return r;
337 /*===========================================================================*
338 * req_access *
339 *===========================================================================*/
340 PUBLIC int req_access(req)
341 access_req_t *req;
343 message m;
345 /* Fill in request message */
346 m.m_type = REQ_ACCESS;
347 m.REQ_INODE_NR = req->inode_nr;
348 m.REQ_MODE = req->amode;
349 m.REQ_UID = req->uid;
350 m.REQ_GID = req->gid;
352 /* Send/rec request */
353 return fs_sendrec(req->fs_e, &m);
357 /*===========================================================================*
358 * req_mknod *
359 *===========================================================================*/
360 PUBLIC int req_mknod(req)
361 mknod_req_t *req;
363 message m;
365 /* Fill in request message */
366 m.m_type = REQ_MKNOD;
367 m.REQ_INODE_NR = req->inode_nr;
368 m.REQ_MODE = req->rmode;
369 m.REQ_DEV = req->dev;
370 m.REQ_UID = req->uid;
371 m.REQ_GID = req->gid;
372 m.REQ_PATH = req->lastc;
373 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
375 /* Send/rec request */
376 return fs_sendrec(req->fs_e, &m);
380 /*===========================================================================*
381 * req_mkdir *
382 *===========================================================================*/
383 PUBLIC int req_mkdir(req)
384 mkdir_req_t *req;
386 message m;
388 /* Fill in request message */
389 m.m_type = REQ_MKDIR;
390 m.REQ_INODE_NR = req->d_inode_nr;
391 m.REQ_MODE = req->rmode;
392 m.REQ_UID = req->uid;
393 m.REQ_GID = req->gid;
394 m.REQ_PATH = req->lastc;
395 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
397 /* Send/rec request */
398 return fs_sendrec(req->fs_e, &m);
403 /*===========================================================================*
404 * req_inhibread *
405 *===========================================================================*/
406 PUBLIC int req_inhibread(req)
407 node_req_t *req;
409 message m;
411 /* Fill in request message */
412 m.m_type = REQ_INHIBREAD;
413 m.REQ_INODE_NR = req->inode_nr;
415 /* Send/rec request */
416 return fs_sendrec(req->fs_e, &m);
420 /*===========================================================================*
421 * req_stat *
422 *===========================================================================*/
423 PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos)
424 int fs_e;
425 ino_t inode_nr;
426 int who_e;
427 char *buf;
428 int pos;
430 cp_grant_id_t gid;
431 int r;
432 message m;
433 struct stat sb;
435 if (pos != 0)
437 gid= cpf_grant_direct(fs_e, (vir_bytes)&sb, sizeof(struct stat),
438 CPF_WRITE);
440 else
442 gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct stat),
443 CPF_WRITE);
445 if (gid < 0)
446 return gid;
448 /* Fill in request message */
449 m.m_type = REQ_STAT;
450 m.REQ_INODE_NR = inode_nr;
451 m.REQ_GRANT = gid;
453 /* Send/rec request */
454 r= fs_sendrec(fs_e, &m);
456 cpf_revoke(gid);
458 if (r == OK && pos != 0)
460 sb.st_size -= pos;
461 r= sys_vircopy(SELF, D, (vir_bytes)&sb, who_e, D, (vir_bytes)buf,
462 sizeof(struct stat));
465 return r;
469 /*===========================================================================*
470 * req_fstatfs *
471 *===========================================================================*/
472 PUBLIC int req_fstatfs(fs_e, inode_nr, who_e, buf)
473 int fs_e;
474 ino_t inode_nr;
475 int who_e;
476 char *buf;
478 int r;
479 cp_grant_id_t gid;
480 message m;
482 gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct statfs),
483 CPF_WRITE);
484 if (gid < 0)
485 return gid;
487 /* Fill in request message */
488 m.m_type = REQ_FSTATFS;
489 m.REQ_INODE_NR = inode_nr;
490 m.REQ_GRANT = gid;
492 /* Send/rec request */
493 r= fs_sendrec(fs_e, &m);
495 cpf_revoke(gid);
497 return r;
501 /*===========================================================================*
502 * req_unlink *
503 *===========================================================================*/
504 PUBLIC int req_unlink(req)
505 unlink_req_t *req;
507 message m;
509 /* Fill in request message */
510 m.m_type = REQ_UNLINK;
511 m.REQ_INODE_NR = req->d_inode_nr;
512 m.REQ_UID = req->uid;
513 m.REQ_GID = req->gid;
514 m.REQ_PATH = req->lastc;
515 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
517 /* Send/rec request */
518 return fs_sendrec(req->fs_e, &m);
522 /*===========================================================================*
523 * req_rmdir *
524 *===========================================================================*/
525 PUBLIC int req_rmdir(req)
526 unlink_req_t *req;
528 message m;
530 /* Fill in request message */
531 m.m_type = REQ_RMDIR;
532 m.REQ_INODE_NR = req->d_inode_nr;
533 m.REQ_UID = req->uid;
534 m.REQ_GID = req->gid;
535 m.REQ_PATH = req->lastc;
536 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
538 /* Send/rec request */
539 return fs_sendrec(req->fs_e, &m);
543 /*===========================================================================*
544 * req_utime *
545 *===========================================================================*/
546 PUBLIC int req_utime(req)
547 utime_req_t *req;
549 message m;
551 /* Fill in request message */
552 m.m_type = REQ_UTIME;
553 m.REQ_INODE_NR = req->inode_nr;
554 m.REQ_UID = req->uid;
555 m.REQ_GID = req->gid;
556 m.REQ_ACTIME = req->actime;
557 m.REQ_MODTIME = req->modtime;
559 /* Send/rec request */
560 return fs_sendrec(req->fs_e, &m);
564 /*===========================================================================*
565 * req_stime *
566 *===========================================================================*/
567 PUBLIC int req_stime(fs_e, boottime)
568 endpoint_t fs_e;
569 time_t boottime;
571 message m;
573 /* Fill in request message */
574 m.m_type = REQ_STIME;
575 m.REQ_BOOTTIME = boottime;
577 /* Send/rec request */
578 return fs_sendrec(fs_e, &m);
582 /*===========================================================================*
583 * req_sync *
584 *===========================================================================*/
585 PUBLIC int req_sync(fs_e)
586 endpoint_t fs_e;
588 message m;
590 /* Fill in request message */
591 m.m_type = REQ_SYNC;
593 /* Send/rec request */
594 return fs_sendrec(fs_e, &m);
598 /*===========================================================================*
599 * req_link *
600 *===========================================================================*/
601 PUBLIC int req_link(req)
602 link_req_t *req;
604 message m;
606 /* Fill in request message */
607 m.m_type = REQ_LINK;
608 m.REQ_LINKED_FILE = req->linked_file;
609 m.REQ_LINK_PARENT = req->link_parent;
610 m.REQ_UID = req->uid;
611 m.REQ_GID = req->gid;
612 m.REQ_PATH = req->lastc;
613 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
615 /* Send/rec request */
616 return fs_sendrec(req->fs_e, &m);
620 /*===========================================================================*
621 * req_slink *
622 *===========================================================================*/
623 PUBLIC int req_slink(req)
624 slink_req_t *req;
626 message m;
628 /* Fill in request message */
629 m.m_type = REQ_SLINK;
630 m.REQ_INODE_NR = req->parent_dir;
631 m.REQ_UID = req->uid;
632 m.REQ_GID = req->gid;
633 m.REQ_PATH = req->lastc;
634 m.REQ_PATH_LEN = strlen(req->lastc) + 1;
635 m.REQ_WHO_E = req->who_e;
636 m.REQ_USER_ADDR = req->path_addr;
637 m.REQ_SLENGTH = req->path_length;
639 /* Send/rec request */
640 return fs_sendrec(req->fs_e, &m);
644 /*===========================================================================*
645 * req_rdlink *
646 *===========================================================================*/
647 PUBLIC int req_rdlink(req)
648 rdlink_req_t *req;
650 message m;
652 /* Fill in request message */
653 m.m_type = REQ_RDLINK;
654 m.REQ_INODE_NR = req->inode_nr;
655 m.REQ_UID = req->uid;
656 m.REQ_GID = req->gid;
657 m.REQ_WHO_E = req->who_e;
658 m.REQ_USER_ADDR = req->path_buffer;
659 m.REQ_SLENGTH = req->max_length;
661 /* Send/rec request */
662 return fs_sendrec(req->fs_e, &m);
666 /*===========================================================================*
667 * req_rename *
668 *===========================================================================*/
669 PUBLIC int req_rename(req)
670 rename_req_t *req;
672 message m;
674 /* Fill in request message */
675 m.m_type = REQ_RENAME;
676 m.REQ_OLD_DIR = req->old_dir;
677 m.REQ_NEW_DIR = req->new_dir;
678 m.REQ_UID = req->uid;
679 m.REQ_GID = req->gid;
680 m.REQ_PATH = req->old_name;
681 m.REQ_PATH_LEN = strlen(req->old_name) + 1;
682 m.REQ_USER_ADDR = req->new_name;
683 m.REQ_SLENGTH = strlen(req->new_name) + 1;
685 /* Send/rec request */
686 return fs_sendrec(req->fs_e, &m);
690 /*===========================================================================*
691 * req_mountpoint *
692 *===========================================================================*/
693 PUBLIC int req_mountpoint(req, res)
694 mountpoint_req_t *req;
695 node_details_t *res;
697 int r;
698 message m;
700 /* Fill in request message */
701 m.m_type = REQ_MOUNTPOINT;
702 m.REQ_INODE_NR = req->inode_nr;
703 m.REQ_UID = req->uid;
704 m.REQ_GID = req->gid;
706 /* Send/rec request */
707 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
709 /* Fill in response structure */
710 res->fs_e = m.m_source;
711 res->inode_nr = m.RES_INODE_NR;
712 res->fmode = m.RES_MODE;
713 res->fsize = m.RES_FILE_SIZE;
715 return OK;
719 /*===========================================================================*
720 * req_readsuper *
721 *===========================================================================*/
722 PUBLIC int req_readsuper(req, res)
723 readsuper_req_t *req;
724 readsuper_res_t *res;
726 int r;
727 message m;
729 /* Fill in request message */
730 m.m_type = REQ_READSUPER;
731 m.REQ_READONLY = req->readonly;
732 m.REQ_BOOTTIME = req->boottime;
733 m.REQ_DRIVER_E = req->driver_e;
734 m.REQ_DEV = req->dev;
735 m.REQ_SLINK_STORAGE = req->slink_storage;
736 m.REQ_ISROOT = req->isroot;
738 /* Send/rec request */
739 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
741 /* Fill in response structure */
742 res->fs_e = m.m_source;
743 res->inode_nr = m.RES_INODE_NR;
744 res->fmode = m.RES_MODE;
745 res->fsize = m.RES_FILE_SIZE;
746 res->blocksize = m.RES_BLOCKSIZE;
747 res->maxsize = m.RES_MAXSIZE;
749 return OK;
753 /*===========================================================================*
754 * req_unmount *
755 *===========================================================================*/
756 PUBLIC int req_unmount(fs_e)
757 endpoint_t fs_e;
759 message m;
761 /* Fill in request message */
762 m.m_type = REQ_UNMOUNT;
764 /* Send/rec request */
765 return fs_sendrec(fs_e, &m);
769 /*===========================================================================*
770 * req_trunc *
771 *===========================================================================*/
772 PUBLIC int req_trunc(req)
773 trunc_req_t *req;
775 message m;
777 /* Fill in request message */
778 m.m_type = REQ_TRUNC;
779 m.REQ_FD_INODE_NR = req->inode_nr;
780 m.REQ_UID = req->uid;
781 m.REQ_GID = req->gid;
782 m.REQ_LENGTH = req->length;
784 /* Send/rec request */
785 return fs_sendrec(req->fs_e, &m);
790 /*===========================================================================*
791 * req_newdriver *
792 *===========================================================================*/
793 PUBLIC int req_newdriver(fs_e, dev, driver_e)
794 endpoint_t fs_e;
795 Dev_t dev;
796 endpoint_t driver_e;
798 /* Note: this is the only request function that doesn't use the
799 * fs_sendrec internal routine, since we want to avoid the dead
800 * driver recovery mechanism here. This function is actually called
801 * during the recovery.
803 message m;
804 int r;
806 /* Fill in request message */
807 m.m_type = REQ_NEW_DRIVER;
808 m.REQ_DEV = dev;
809 m.REQ_DRIVER_E = driver_e;
811 /* Issue request */
812 if ((r = sendrec(fs_e, &m)) != OK) {
813 printf("VFSreq_newdriver: error sending message to %d: %d\n", fs_e, r);
814 return r;
817 return OK;
821 /*===========================================================================*
822 * req_lookup *
823 *===========================================================================*/
824 PUBLIC int req_lookup(req, res)
825 lookup_req_t *req;
826 lookup_res_t *res;
828 int r;
829 message m;
831 /* Fill in request message */
832 m.m_type = REQ_LOOKUP;
833 m.REQ_PATH = req->path;
834 m.REQ_PATH_LEN = strlen(req->path) + 1;
835 m.REQ_USER_ADDR = req->lastc;
836 m.REQ_FLAGS = req->flags;
838 m.REQ_INODE_NR = req->start_dir;
839 m.REQ_CHROOT_NR = req->root_dir;
840 m.REQ_UID = req->uid;
841 m.REQ_GID = req->gid;
842 m.REQ_SYMLOOP = req->symloop;
844 /* Send/rec request */
845 r = fs_sendrec(req->fs_e, &m);
847 /* Fill in response according to the return value */
848 res->fs_e = m.m_source;
849 switch (r) {
850 case OK:
851 default:
852 res->inode_nr = m.RES_INODE_NR;
853 res->fmode = m.RES_MODE;
854 res->fsize = m.RES_FILE_SIZE;
855 res->dev = m.RES_DEV;
856 res->uid= m.RES_UID;
857 res->gid= m.RES_GID;
858 res->char_processed = m.RES_OFFSET; /* For ENOENT */
859 break;
860 case EENTERMOUNT:
861 res->inode_nr = m.RES_INODE_NR;
862 case ELEAVEMOUNT:
863 case ESYMLINK:
864 res->char_processed = m.RES_OFFSET;
865 res->symloop = m.RES_SYMLOOP;
866 break;
869 return r;
873 /*===========================================================================*
874 * req_breadwrite *
875 *===========================================================================*/
876 int req_breadwrite(req, res)
877 breadwrite_req_t *req;
878 readwrite_res_t *res;
880 int r;
881 message m;
883 /* Fill in request message */
884 m.m_type = req->rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
885 m.REQ_XFD_BDEV = req->dev;
886 m.REQ_XFD_BLOCK_SIZE = req->blocksize;
887 m.REQ_XFD_WHO_E = req->user_e;
888 m.REQ_XFD_POS_LO = ex64lo(req->pos);
889 m.REQ_XFD_POS_HI = ex64hi(req->pos);
890 m.REQ_XFD_NBYTES = req->num_of_bytes;
891 m.REQ_XFD_USER_ADDR = req->user_addr;
893 /* Send/rec request */
894 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
896 /* Fill in response structure */
897 res->new_pos = make64(m.RES_XFD_POS_LO, m.RES_XFD_POS_HI);
898 res->cum_io = m.RES_XFD_CUM_IO;
900 return OK;
904 PUBLIC int req_getdents(fs_e, inode_nr, pos, gid, size, pos_change)
905 endpoint_t fs_e;
906 ino_t inode_nr;
907 off_t pos;
908 cp_grant_id_t gid;
909 size_t size;
910 off_t *pos_change;
912 int r;
913 message m;
915 m.m_type= REQ_GETDENTS;
916 m.REQ_GDE_INODE= inode_nr;
917 m.REQ_GDE_GRANT= gid;
918 m.REQ_GDE_SIZE= size;
919 m.REQ_GDE_POS= pos;
921 r = fs_sendrec(fs_e, &m);
922 *pos_change= m.RES_GDE_POS_CHANGE;
923 return r;
927 /*===========================================================================*
928 * req_flush *
929 *===========================================================================*/
930 PUBLIC int req_flush(fs_e, dev)
931 endpoint_t fs_e;
932 dev_t dev;
934 message m;
936 /* Fill in request message */
937 m.m_type = REQ_FLUSH;
938 m.REQ_DEV = dev;
940 /* Send/rec request */
941 return fs_sendrec(fs_e, &m);
945 #if 0
946 /* Wrapper pattern: */
947 /*===========================================================================*
948 * req_ *
949 *===========================================================================*/
950 PUBLIC int req_(req, res)
951 _req_t *req;
952 _t *res;
954 int r;
955 message m;
957 /* Fill in request message */
960 /* Send/rec request */
961 if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
963 /* Fill in response structure */
966 return OK;
968 #endif
973 /*===========================================================================*
974 * fs_sendrec *
975 *===========================================================================*/
976 PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
978 /* This is the low level function that sends requests to FS processes.
979 * It also handles driver recovery mechanism and reissuing the
980 * request which failed due to a dead driver.
982 int r, old_driver_e, new_driver_e;
983 message origm, m;
984 struct vmnt *vmp;
986 /* Make a copy of the request so that we can load it back in
987 * case of a dead driver */
988 origm = *reqm;
990 for (;;) {
991 /* Do the actual send, receive */
992 if (OK != (r=sendrec(fs_e, reqm))) {
993 printf("VFS:fs_sendrec:%s:%d: error sending message. FS_e: %d req_nr: %d err: %d\n",
994 file, line, fs_e, reqm->m_type, r);
997 if(r == OK) {
998 /* Sendrec was okay */
999 break;
1002 /* Dead driver */
1003 if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
1004 old_driver_e = NONE;
1005 /* Find old driver by endpoint */
1006 for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
1007 if (vmp->m_fs_e == fs_e) { /* found FS */
1008 old_driver_e = vmp->m_driver_e;
1009 dmap_unmap_by_endpt(old_driver_e); /* unmap driver */
1010 break;
1014 /* No FS ?? */
1015 if (old_driver_e == NONE)
1016 panic(__FILE__, "VFSdead_driver: couldn't find FS\n", fs_e);
1018 /* Wait for a new driver. */
1019 for (;;) {
1020 new_driver_e = 0;
1021 printf("VFSdead_driver: waiting for new driver\n");
1022 r = receive(RS_PROC_NR, &m);
1023 if (r != OK) {
1024 panic(__FILE__, "VFSdead_driver: unable to receive from RS",
1027 if (m.m_type == DEVCTL) {
1028 /* Map new driver */
1029 r = fs_devctl(m.ctl_req, m.dev_nr, m.driver_nr,
1030 m.dev_style, m.m_force);
1031 if (m.ctl_req == DEV_MAP && r == OK) {
1032 new_driver_e = m.driver_nr;
1033 printf("VFSdead_driver: new driver endpoint: %d\n",
1034 new_driver_e);
1037 else {
1038 panic(__FILE__, "VFSdead_driver: got message from RS, type",
1039 m.m_type);
1041 m.m_type = r;
1042 if ((r = send(RS_PROC_NR, &m)) != OK) {
1043 panic(__FILE__, "VFSdead_driver: unable to send to RS",
1046 /* New driver is ready */
1047 if (new_driver_e) break;
1050 /* Copy back original request */
1051 *reqm = origm;
1052 continue;
1055 printf("fs_sendrec: unhandled error %d sending to %d\n", r, fs_e);
1056 panic(__FILE__, "fs_sendrec: unhandled error", NO_NUM);
1059 /* Return message type */
1060 return reqm->m_type;