5 #include <minix/vfsif.h>
8 static int sendmsg(struct vmnt
*vmp
, struct worker_thread
*wp
);
9 static int queuemsg(struct vmnt
*vmp
);
11 /*===========================================================================*
13 *===========================================================================*/
14 static int sendmsg(struct vmnt
*vmp
, struct worker_thread
*wp
)
16 /* This is the low level function that sends requests to FS processes.
20 vmp
->m_comm
.c_cur_reqs
++; /* One more request awaiting a reply */
21 transid
= wp
->w_tid
+ VFS_TRANSID
;
22 wp
->w_fs_sendrec
->m_type
= TRNS_ADD_ID(wp
->w_fs_sendrec
->m_type
, transid
);
23 wp
->w_task
= vmp
->m_fs_e
;
24 if ((r
= asynsend3(vmp
->m_fs_e
, wp
->w_fs_sendrec
, AMF_NOREPLY
)) != OK
) {
25 printf("VFS: sendmsg: error sending message. "
26 "FS_e: %d req_nr: %d err: %d\n", vmp
->m_fs_e
,
27 wp
->w_fs_sendrec
->m_type
, r
);
35 /*===========================================================================*
37 *===========================================================================*/
40 /* Try to send out as many requests as possible */
43 if (sending
== 0) return;
44 for (vmp
= &vmnt
[0]; vmp
< &vmnt
[NR_MNTS
]; vmp
++)
48 /*===========================================================================*
50 *===========================================================================*/
51 void fs_cancel(struct vmnt
*vmp
)
53 /* Cancel all pending requests for this vmp */
54 struct worker_thread
*worker
;
56 while ((worker
= vmp
->m_comm
.c_req_queue
) != NULL
) {
57 vmp
->m_comm
.c_req_queue
= worker
->w_next
;
58 worker
->w_next
= NULL
;
64 /*===========================================================================*
66 *===========================================================================*/
67 void fs_sendmore(struct vmnt
*vmp
)
69 struct worker_thread
*worker
;
71 /* Can we send more requests? */
72 if (vmp
->m_fs_e
== NONE
) return;
73 if ((worker
= vmp
->m_comm
.c_req_queue
) == NULL
) /* No process is queued */
75 if (vmp
->m_comm
.c_cur_reqs
>= vmp
->m_comm
.c_max_reqs
)/*No room to send more*/
77 if (vmp
->m_flags
& VMNT_CALLBACK
) /* Hold off for now */
80 vmp
->m_comm
.c_req_queue
= worker
->w_next
; /* Remove head */
81 worker
->w_next
= NULL
;
84 (void) sendmsg(vmp
, worker
);
87 /*===========================================================================*
89 *===========================================================================*/
90 int drv_sendrec(endpoint_t drv_e
, message
*reqmp
)
95 if ((dp
= get_dmap(drv_e
)) == NULL
)
96 panic("driver endpoint %d invalid", drv_e
);
99 if (dp
->dmap_servicing
!= NONE
)
100 panic("driver locking inconsistency");
101 dp
->dmap_servicing
= self
->w_tid
;
102 self
->w_task
= drv_e
;
103 self
->w_drv_sendrec
= reqmp
;
105 if ((r
= asynsend3(drv_e
, self
->w_drv_sendrec
, AMF_NOREPLY
)) == OK
) {
106 /* Yield execution until we've received the reply */
109 printf("VFS: drv_sendrec: error sending msg to driver %d: %d\n",
114 dp
->dmap_servicing
= NONE
;
116 self
->w_drv_sendrec
= NULL
;
121 /*===========================================================================*
123 *===========================================================================*/
124 int fs_sendrec(endpoint_t fs_e
, message
*reqmp
)
129 if ((vmp
= find_vmnt(fs_e
)) == NULL
) {
130 printf("Trying to talk to non-existent FS endpoint %d\n", fs_e
);
133 if (fs_e
== fp
->fp_endpoint
) return(EDEADLK
);
135 self
->w_fs_sendrec
= reqmp
; /* Where to store request and reply */
137 /* Find out whether we can send right away or have to enqueue */
138 if ( !(vmp
->m_flags
& VMNT_CALLBACK
) &&
139 vmp
->m_comm
.c_cur_reqs
< vmp
->m_comm
.c_max_reqs
) {
140 /* There's still room to send more and no proc is queued */
141 r
= sendmsg(vmp
, self
);
145 self
->w_next
= NULL
; /* End of list */
147 if (r
!= OK
) return(r
);
149 worker_wait(); /* Yield execution until we've received the reply. */
151 return(reqmp
->m_type
);
154 /*===========================================================================*
156 *===========================================================================*/
157 static int queuemsg(struct vmnt
*vmp
)
159 /* Put request on queue for vmnt */
161 struct worker_thread
*queue
;
163 if (vmp
->m_comm
.c_req_queue
== NULL
) {
164 vmp
->m_comm
.c_req_queue
= self
;
166 /* Walk the list ... */
167 queue
= vmp
->m_comm
.c_req_queue
;
168 while (queue
->w_next
!= NULL
) queue
= queue
->w_next
;
170 /* ... and append this worker */
171 queue
->w_next
= self
;
174 self
->w_next
= NULL
; /* End of list */