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
6 * The low-level fs_sendrec handles the recovery mechanism from
7 * a dead driver and reissues the request.
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>
22 #include <minix/vfsif.h>
28 FORWARD
_PROTOTYPE(int fs_sendrec_f
, (char *file
, int line
, endpoint_t fs_e
,
31 #define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
34 /*===========================================================================*
36 *===========================================================================*/
37 PUBLIC
int req_breadwrite(fs_e
, user_e
, dev
, pos
, num_of_bytes
, user_addr
,
38 rw_flag
, new_posp
, cum_iop
)
43 unsigned int num_of_bytes
;
47 unsigned int *cum_iop
;
50 cp_grant_id_t grant_id
;
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
));
56 panic("req_breadwrite: cpf_grant_magic failed");
58 /* Fill in request message */
59 m
.m_type
= rw_flag
== READING
? REQ_BREAD
: REQ_BWRITE
;
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
);
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
;
79 /*===========================================================================*
81 *===========================================================================*/
82 PUBLIC
int req_chmod(fs_e
, inode_nr
, rmode
, new_modep
)
91 /* Fill in request message */
93 m
.REQ_INODE_NR
= inode_nr
;
96 /* Send/rec request */
97 r
= fs_sendrec(fs_e
, &m
);
99 /* Copy back actual mode. */
100 *new_modep
= m
.RES_MODE
;
106 /*===========================================================================*
108 *===========================================================================*/
109 PUBLIC
int req_chown(fs_e
, inode_nr
, newuid
, newgid
, new_modep
)
119 /* Fill in request message */
120 m
.m_type
= REQ_CHOWN
;
121 m
.REQ_INODE_NR
= inode_nr
;
125 /* Send/rec request */
126 r
= fs_sendrec(fs_e
, &m
);
128 /* Return new mode to caller. */
129 *new_modep
= m
.RES_MODE
;
135 /*===========================================================================*
137 *===========================================================================*/
138 int req_create(fs_e
, inode_nr
, omode
, uid
, gid
, path
, res
)
148 cp_grant_id_t grant_id
;
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
);
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
;
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
;
187 /*===========================================================================*
189 *===========================================================================*/
190 PUBLIC
int req_flush(fs_e
, dev
)
196 /* Fill in request message */
197 m
.m_type
= REQ_FLUSH
;
200 /* Send/rec request */
201 return fs_sendrec(fs_e
, &m
);
205 /*===========================================================================*
207 *===========================================================================*/
208 PUBLIC
int req_fstatfs(fs_e
, who_e
, buf
)
214 cp_grant_id_t grant_id
;
217 grant_id
= cpf_grant_magic(fs_e
, who_e
, (vir_bytes
) buf
, sizeof(struct statfs
),
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
);
234 /*===========================================================================*
236 *===========================================================================*/
237 PUBLIC
int req_ftrunc(fs_e
, inode_nr
, start
, end
)
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 /*===========================================================================*
260 *===========================================================================*/
261 PUBLIC
int req_getdents(fs_e
, inode_nr
, pos
, buf
, size
, new_pos
)
271 cp_grant_id_t grant_id
;
273 grant_id
= cpf_grant_magic(fs_e
, who_e
, (vir_bytes
) buf
, size
, CPF_WRITE
);
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
);
288 *new_pos
= cvul64(m
.RES_SEEK_POS_LO
);
296 /*===========================================================================*
298 *===========================================================================*/
299 PUBLIC
int req_inhibread(fs_e
, inode_nr
)
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 /*===========================================================================*
316 *===========================================================================*/
317 PUBLIC
int req_link(fs_e
, link_parent
, lastc
, linked_file
)
324 cp_grant_id_t grant_id
;
328 len
= strlen(lastc
) + 1;
329 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
)lastc
, len
, CPF_READ
);
331 panic("req_link: cpf_grant_direct failed");
333 /* Fill in request message */
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
);
348 /*===========================================================================*
350 *===========================================================================*/
351 PUBLIC
int req_lookup(fs_e
, dir_ino
, root_ino
, uid
, gid
, flags
, res
)
362 cp_grant_id_t grant_id
, grant_id2
;
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
);
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 */
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
);
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
;
400 /* When there's only one gid, we can send it directly */
403 flags
&= ~PATH_GET_UCRED
;
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
;
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
;
426 res
->inode_nr
= m
.RES_INODE_NR
;
427 res
->char_processed
= m
.RES_OFFSET
;
428 res
->symloop
= m
.RES_SYMLOOP
;
431 res
->char_processed
= m
.RES_OFFSET
;
432 res
->symloop
= m
.RES_SYMLOOP
;
435 res
->char_processed
= m
.RES_OFFSET
;
436 res
->symloop
= m
.RES_SYMLOOP
;
446 /*===========================================================================*
448 *===========================================================================*/
449 PUBLIC
int req_mkdir(fs_e
, inode_nr
, lastc
, uid
, gid
, dmode
)
458 cp_grant_id_t grant_id
;
462 len
= strlen(lastc
) + 1;
463 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
)lastc
, len
, CPF_READ
);
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
;
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
);
484 /*===========================================================================*
486 *===========================================================================*/
487 PUBLIC
int req_mknod(fs_e
, inode_nr
, lastc
, uid
, gid
, dmode
, dev
)
498 cp_grant_id_t grant_id
;
501 len
= strlen(lastc
) + 1;
502 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
)lastc
, len
, CPF_READ
);
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
;
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
);
524 /*===========================================================================*
526 *===========================================================================*/
527 PUBLIC
int req_mountpoint(fs_e
, inode_nr
)
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 /*===========================================================================*
545 *===========================================================================*/
546 PUBLIC
int req_newnode(fs_e
, uid
, gid
, dmode
, dev
, res
)
552 struct node_details
*res
;
557 /* Fill in request message */
558 m
.m_type
= REQ_NEWNODE
;
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
;
579 /*===========================================================================*
581 *===========================================================================*/
582 PUBLIC
int req_newdriver(fs_e
, dev
, 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.
595 /* Fill in request message */
596 m
.m_type
= REQ_NEW_DRIVER
;
598 m
.REQ_DRIVER_E
= driver_e
;
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
);
613 /*===========================================================================*
615 *===========================================================================*/
616 PUBLIC
int req_putnode(fs_e
, inode_nr
, count
)
623 /* Fill in request message */
624 m
.m_type
= REQ_PUTNODE
;
625 m
.REQ_INODE_NR
= inode_nr
;
628 /* Send/rec request */
629 return fs_sendrec(fs_e
, &m
);
633 /*===========================================================================*
635 *===========================================================================*/
636 PUBLIC
int req_rdlink(fs_e
, inode_nr
, who_e
, buf
, len
)
645 cp_grant_id_t grant_id
;
647 grant_id
= cpf_grant_magic(fs_e
, who_e
, (vir_bytes
) buf
, len
, CPF_WRITE
);
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
;
667 /*===========================================================================*
669 *===========================================================================*/
670 PUBLIC
int req_readsuper(fs_e
, label
, dev
, readonly
, isroot
, res_nodep
)
676 struct node_details
*res_nodep
;
679 cp_grant_id_t grant_id
;
683 len
= strlen(label
)+1;
684 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
) label
, len
, CPF_READ
);
686 panic("req_readsuper: cpf_grant_direct failed");
688 /* Fill in request message */
689 m
.m_type
= REQ_READSUPER
;
691 if(readonly
) m
.REQ_FLAGS
|= REQ_RDONLY
;
692 if(isroot
) m
.REQ_FLAGS
|= REQ_ISROOT
;
693 m
.REQ_GRANT
= grant_id
;
695 m
.REQ_PATH_LEN
= len
;
697 /* Send/rec request */
698 r
= fs_sendrec(fs_e
, &m
);
699 cpf_revoke(grant_id
);
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
;
715 /*===========================================================================*
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
)
726 unsigned int num_of_bytes
;
728 unsigned int *cum_iop
;
731 cp_grant_id_t grant_id
;
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
));
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
);
755 /* Fill in response structure */
756 *new_posp
= cvul64(m
.RES_SEEK_POS_LO
);
757 *cum_iop
= m
.RES_NBYTES
;
764 /*===========================================================================*
766 *===========================================================================*/
767 PUBLIC
int req_rename(fs_e
, old_dir
, old_name
, new_dir
, new_name
)
775 cp_grant_id_t gid_old
, gid_new
;
776 size_t len_old
, len_new
;
779 len_old
= strlen(old_name
) + 1;
780 gid_old
= cpf_grant_direct(fs_e
, (vir_bytes
) old_name
, len_old
, CPF_READ
);
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
);
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
);
807 /*===========================================================================*
809 *===========================================================================*/
810 PUBLIC
int req_rmdir(fs_e
, inode_nr
, lastc
)
816 cp_grant_id_t grant_id
;
820 len
= strlen(lastc
) + 1;
821 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
) lastc
, len
, CPF_READ
);
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
);
839 /*===========================================================================*
841 *===========================================================================*/
842 PUBLIC
int req_slink(fs_e
, inode_nr
, lastc
, who_e
, path_addr
, path_length
,
849 unsigned short path_length
;
855 cp_grant_id_t gid_name
, gid_buf
;
858 len
= strlen(lastc
) + 1;
859 gid_name
= cpf_grant_direct(fs_e
, (vir_bytes
) lastc
, len
, CPF_READ
);
861 panic("req_slink: cpf_grant_direct failed");
863 gid_buf
= cpf_grant_magic(fs_e
, who_e
, (vir_bytes
) path_addr
, path_length
,
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
;
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
);
889 /*===========================================================================*
891 *===========================================================================*/
892 PUBLIC
int req_stat(fs_e
, inode_nr
, who_e
, buf
, pos
)
899 cp_grant_id_t grant_id
;
905 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
) &sb
,
906 sizeof(struct stat
), CPF_WRITE
);
908 grant_id
= cpf_grant_magic(fs_e
, who_e
, (vir_bytes
) buf
,
909 sizeof(struct stat
), CPF_WRITE
);
912 panic("req_stat: cpf_grant_* failed");
914 /* Fill in request message */
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) {
925 r
= sys_vircopy(SELF
, D
, (vir_bytes
) &sb
, who_e
, D
, (vir_bytes
) buf
,
926 sizeof(struct stat
));
933 /*===========================================================================*
935 *===========================================================================*/
936 PUBLIC
int req_sync(fs_e
)
941 /* Fill in request message */
944 /* Send/rec request */
945 return fs_sendrec(fs_e
, &m
);
949 /*===========================================================================*
951 *===========================================================================*/
952 PUBLIC
int req_unlink(fs_e
, inode_nr
, lastc
)
957 cp_grant_id_t grant_id
;
962 len
= strlen(lastc
) + 1;
963 grant_id
= cpf_grant_direct(fs_e
, (vir_bytes
) lastc
, len
, CPF_READ
);
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
);
981 /*===========================================================================*
983 *===========================================================================*/
984 PUBLIC
int req_unmount(fs_e
)
989 /* Fill in request message */
990 m
.m_type
= REQ_UNMOUNT
;
992 /* Send/rec request */
993 return fs_sendrec(fs_e
, &m
);
997 /*===========================================================================*
999 *===========================================================================*/
1000 PUBLIC
int req_utime(fs_e
, inode_nr
, actime
, modtime
)
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 /*===========================================================================*
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
;
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 */
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.
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
,
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)
1065 if (reqm
->m_type
== -EENTERMOUNT
|| reqm
->m_type
== -ELEAVEMOUNT
||
1066 reqm
->m_type
== -ESYMLINK
) {
1068 reqm
->m_type
= -reqm
->m_type
;
1073 nested_fs_call(reqm
);
1078 /* Sendrec was okay */
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 */
1088 old_driver_e
= vmp
->m_driver_e
;
1090 dmap_unmap_by_endpt(old_driver_e
); /* unmap driver */
1096 if (old_driver_e
== NONE
)
1097 panic("VFSdead_driver: couldn't find FS: %d", fs_e
);
1099 /* Wait for a new driver. */
1102 printf("VFSdead_driver: waiting for new driver\n");
1103 r
= sef_receive(RS_PROC_NR
, &m
);
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",
1118 panic("VFSdead_driver: got message from RS type: %d", m
.m_type
);
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 */
1133 printf("fs_sendrec: unhandled error %d sending to %d\n", r
, fs_e
);
1134 panic("fs_sendrec: unhandled error");
1138 /* Return message type */
1139 return(reqm
->m_type
);