2 /* Sending requests to VFS and handling the replies. */
6 #include <minix/callnr.h>
8 #include <minix/config.h>
9 #include <minix/const.h>
11 #include <minix/endpoint.h>
12 #include <minix/minlib.h>
13 #include <minix/type.h>
14 #include <minix/ipc.h>
15 #include <minix/sysutil.h>
16 #include <minix/syslib.h>
17 #include <minix/type.h>
18 #include <minix/bitmap.h>
23 #include <sys/param.h>
29 #include "sanitycheck.h"
33 static struct vfs_request_node
{
35 char reqstate
[STATELEN
];
39 vfs_callback_t callback
;
40 struct vfs_request_node
*next
;
41 } *first_queued
, *active
;
43 static void activate(void)
48 active
= first_queued
;
49 first_queued
= first_queued
->next
;
51 if(asynsend3(VFS_PROC_NR
, &active
->reqmsg
, AMF_NOREPLY
) != OK
)
52 panic("VM: asynsend to VFS failed");
55 #define ID_MAX LONG_MAX
57 /*===========================================================================*
59 *===========================================================================*/
60 int vfs_request(int reqno
, int fd
, struct vmproc
*vmp
, u64_t offset
, u32_t len
,
61 vfs_callback_t reply_callback
, void *cbarg
, void *state
, int statelen
)
63 /* Perform an asynchronous request to VFS.
64 * We send a message of type VFS_VMCALL to VFS. VFS will respond
65 * with message type VM_VFS_REPLY. We send the request asynchronously
66 * and then handle the reply as it if were a VM_VFS_REPLY request.
70 struct vfs_request_node
*reqnode
;
74 assert(statelen
<= STATELEN
);
76 if(!SLABALLOC(reqnode
)) {
77 printf("vfs_request: no memory for request node\n");
82 memset(m
, 0, sizeof(*m
));
83 m
->m_type
= VFS_VMCALL
;
84 m
->VFS_VMCALL_REQ
= reqno
;
85 m
->VFS_VMCALL_FD
= fd
;
86 m
->VFS_VMCALL_REQID
= reqid
;
87 m
->VFS_VMCALL_ENDPOINT
= vmp
->vm_endpoint
;
88 m
->VFS_VMCALL_OFFSET
= offset
;
89 m
->VFS_VMCALL_LENGTH
= len
;
91 reqnode
->who
= vmp
->vm_endpoint
;
92 reqnode
->req_id
= reqid
;
93 reqnode
->next
= first_queued
;
94 reqnode
->callback
= reply_callback
;
95 reqnode
->opaque
= cbarg
;
96 if(state
) memcpy(reqnode
->reqstate
, state
, statelen
);
97 first_queued
= reqnode
;
99 /* Send the request message if none pending. */
106 /*===========================================================================*
108 *===========================================================================*/
109 int do_vfs_reply(message
*m
)
111 /* VFS has handled a VM request and VFS has replied. It must be the
114 struct vfs_request_node
*orignode
= active
;
115 vfs_callback_t req_callback
;
121 assert(active
->req_id
== m
->VMV_REQID
);
123 /* the endpoint may have exited */
124 if(vm_isokendpt(m
->VMV_ENDPOINT
, &n
) != OK
)
126 else vmp
= &vmproc
[n
];
128 req_callback
= active
->callback
;
129 cbarg
= active
->opaque
;
132 /* Invoke requested reply-callback within VM. */
133 if(req_callback
) req_callback(vmp
, m
, cbarg
, orignode
->reqstate
);
137 /* Send the next request message if any and not re-activated. */
138 if(first_queued
&& !active
)
141 return SUSPEND
; /* don't reply to the reply */