xref: /minix3/minix/servers/vfs/request.c (revision a0814afb2e128f52ed10c9a5d4c91bf6abc22290)
1433d6423SLionel Sambuc /* This file contains the wrapper functions for issuing a request
2433d6423SLionel Sambuc  * and receiving response from FS processes.
3433d6423SLionel Sambuc  * Each function builds a request message according to the request
4433d6423SLionel Sambuc  * parameter, calls the most low-level fs_sendrec, and copies
5433d6423SLionel Sambuc  * back the response.
6433d6423SLionel Sambuc  */
7433d6423SLionel Sambuc 
8433d6423SLionel Sambuc #include "fs.h"
9433d6423SLionel Sambuc #include <minix/com.h>
10433d6423SLionel Sambuc #include <minix/const.h>
11433d6423SLionel Sambuc #include <minix/endpoint.h>
12433d6423SLionel Sambuc #include <minix/u64.h>
13433d6423SLionel Sambuc #include <minix/vfsif.h>
14433d6423SLionel Sambuc #include <sys/dirent.h>
15433d6423SLionel Sambuc #include <sys/stat.h>
16433d6423SLionel Sambuc #include <sys/statvfs.h>
17433d6423SLionel Sambuc #include <assert.h>
18433d6423SLionel Sambuc #include <stddef.h>
19433d6423SLionel Sambuc #include <string.h>
20433d6423SLionel Sambuc #include <unistd.h>
21433d6423SLionel Sambuc #include <time.h>
22433d6423SLionel Sambuc #include "path.h"
23433d6423SLionel Sambuc #include "vmnt.h"
24433d6423SLionel Sambuc #include "vnode.h"
25433d6423SLionel Sambuc 
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc /*===========================================================================*
28433d6423SLionel Sambuc  *			req_breadwrite_actual				     *
29433d6423SLionel Sambuc  *===========================================================================*/
req_breadwrite_actual(endpoint_t fs_e,endpoint_t user_e,dev_t dev,off_t pos,unsigned int num_of_bytes,vir_bytes user_addr,int rw_flag,off_t * new_pos,size_t * cum_iop,int cpflag)30433d6423SLionel Sambuc static int req_breadwrite_actual(endpoint_t fs_e, endpoint_t user_e, dev_t dev, off_t pos,
31433d6423SLionel Sambuc         unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag,
323c8950ccSBen Gras         off_t *new_pos, size_t *cum_iop, int cpflag)
33433d6423SLionel Sambuc {
34433d6423SLionel Sambuc   int r;
35433d6423SLionel Sambuc   cp_grant_id_t grant_id;
36433d6423SLionel Sambuc   message m;
37433d6423SLionel Sambuc 
38433d6423SLionel Sambuc   grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
39433d6423SLionel Sambuc 			(rw_flag == READING ? CPF_WRITE : CPF_READ) | cpflag);
40433d6423SLionel Sambuc   if(grant_id == -1)
41433d6423SLionel Sambuc 	  panic("req_breadwrite: cpf_grant_magic failed");
42433d6423SLionel Sambuc 
43433d6423SLionel Sambuc   /* Fill in request message */
44433d6423SLionel Sambuc   m.m_type = rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
45433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.device = dev;
46433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.grant = grant_id;
47433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.seek_pos = pos;
48433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.nbytes = num_of_bytes;
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc   /* Send/rec request */
51433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
5210b7016bSDavid van Moolenbroek 
5310b7016bSDavid van Moolenbroek   if (cpf_revoke(grant_id) == GRANT_FAULTED) return(ERESTART);
5410b7016bSDavid van Moolenbroek 
55433d6423SLionel Sambuc   if (r != OK) return(r);
56433d6423SLionel Sambuc 
57433d6423SLionel Sambuc   /* Fill in response structure */
58433d6423SLionel Sambuc   *new_pos = m.m_fs_vfs_breadwrite.seek_pos;
59433d6423SLionel Sambuc   *cum_iop = m.m_fs_vfs_breadwrite.nbytes;
60433d6423SLionel Sambuc 
61433d6423SLionel Sambuc   return(OK);
62433d6423SLionel Sambuc }
63433d6423SLionel Sambuc 
req_breadwrite(endpoint_t fs_e,endpoint_t user_e,dev_t dev,off_t pos,unsigned int num_of_bytes,vir_bytes user_addr,int rw_flag,off_t * new_pos,size_t * cum_iop)64433d6423SLionel Sambuc int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, off_t pos,
65433d6423SLionel Sambuc         unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag,
663c8950ccSBen Gras         off_t *new_pos, size_t *cum_iop)
67433d6423SLionel Sambuc {
68433d6423SLionel Sambuc 	int r;
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc 	r = req_breadwrite_actual(fs_e, user_e, dev, pos, num_of_bytes,
71433d6423SLionel Sambuc 		user_addr, rw_flag, new_pos, cum_iop, CPF_TRY);
72433d6423SLionel Sambuc 
7310b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
74433d6423SLionel Sambuc 		if((r=vm_vfs_procctl_handlemem(user_e, user_addr, num_of_bytes,
75433d6423SLionel Sambuc 			rw_flag == READING)) != OK) {
76433d6423SLionel Sambuc 			return r;
77433d6423SLionel Sambuc 		}
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc 		r = req_breadwrite_actual(fs_e, user_e, dev, pos, num_of_bytes,
80433d6423SLionel Sambuc 			user_addr, rw_flag, new_pos, cum_iop, 0);
81433d6423SLionel Sambuc 	}
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc 	return r;
84433d6423SLionel Sambuc }
85433d6423SLionel Sambuc 
86433d6423SLionel Sambuc /*===========================================================================*
87433d6423SLionel Sambuc  *			req_bpeek					     *
88433d6423SLionel Sambuc  *===========================================================================*/
req_bpeek(endpoint_t fs_e,dev_t dev,off_t pos,unsigned int num_of_bytes)89433d6423SLionel Sambuc int req_bpeek(endpoint_t fs_e, dev_t dev, off_t pos, unsigned int num_of_bytes)
90433d6423SLionel Sambuc {
91433d6423SLionel Sambuc   message m;
92433d6423SLionel Sambuc 
93433d6423SLionel Sambuc   memset(&m, 0, sizeof(m));
94433d6423SLionel Sambuc 
95433d6423SLionel Sambuc   /* Fill in request message */
96433d6423SLionel Sambuc   m.m_type = REQ_BPEEK;
97433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.device = dev;
98433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.seek_pos = pos;
99433d6423SLionel Sambuc   m.m_vfs_fs_breadwrite.nbytes = num_of_bytes;
100433d6423SLionel Sambuc 
101433d6423SLionel Sambuc   /* Send/rec request */
102433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
103433d6423SLionel Sambuc }
104433d6423SLionel Sambuc 
105433d6423SLionel Sambuc /*===========================================================================*
106433d6423SLionel Sambuc  *				req_chmod	      			     *
107433d6423SLionel Sambuc  *===========================================================================*/
req_chmod(endpoint_t fs_e,ino_t inode_nr,mode_t rmode,mode_t * new_modep)108433d6423SLionel Sambuc int req_chmod(
109433d6423SLionel Sambuc   endpoint_t fs_e,
110433d6423SLionel Sambuc   ino_t inode_nr,
111433d6423SLionel Sambuc   mode_t rmode,
112433d6423SLionel Sambuc   mode_t *new_modep
113433d6423SLionel Sambuc )
114433d6423SLionel Sambuc {
115433d6423SLionel Sambuc   message m;
116433d6423SLionel Sambuc   int r;
117433d6423SLionel Sambuc 
118433d6423SLionel Sambuc   /* Fill in request message */
119433d6423SLionel Sambuc   m.m_type = REQ_CHMOD;
120433d6423SLionel Sambuc   m.m_vfs_fs_chmod.inode = inode_nr;
121433d6423SLionel Sambuc   m.m_vfs_fs_chmod.mode = rmode;
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc   /* Send/rec request */
124433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
125433d6423SLionel Sambuc 
126433d6423SLionel Sambuc   /* Copy back actual mode. */
127433d6423SLionel Sambuc   *new_modep = m.m_fs_vfs_chmod.mode;
128433d6423SLionel Sambuc 
129433d6423SLionel Sambuc   return(r);
130433d6423SLionel Sambuc }
131433d6423SLionel Sambuc 
132433d6423SLionel Sambuc 
133433d6423SLionel Sambuc /*===========================================================================*
134433d6423SLionel Sambuc  *				req_chown          			     *
135433d6423SLionel Sambuc  *===========================================================================*/
req_chown(endpoint_t fs_e,ino_t inode_nr,uid_t newuid,gid_t newgid,mode_t * new_modep)136433d6423SLionel Sambuc int req_chown(
137433d6423SLionel Sambuc   endpoint_t fs_e,
138433d6423SLionel Sambuc   ino_t inode_nr,
139433d6423SLionel Sambuc   uid_t newuid,
140433d6423SLionel Sambuc   gid_t newgid,
141433d6423SLionel Sambuc   mode_t *new_modep
142433d6423SLionel Sambuc )
143433d6423SLionel Sambuc {
144433d6423SLionel Sambuc   message m;
145433d6423SLionel Sambuc   int r;
146433d6423SLionel Sambuc 
147433d6423SLionel Sambuc   /* Fill in request message */
148433d6423SLionel Sambuc   m.m_type = REQ_CHOWN;
149433d6423SLionel Sambuc   m.m_vfs_fs_chown.inode = inode_nr;
150433d6423SLionel Sambuc   m.m_vfs_fs_chown.uid = newuid;
151433d6423SLionel Sambuc   m.m_vfs_fs_chown.gid = newgid;
152433d6423SLionel Sambuc 
153433d6423SLionel Sambuc   /* Send/rec request */
154433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
155433d6423SLionel Sambuc 
156433d6423SLionel Sambuc   /* Return new mode to caller. */
157433d6423SLionel Sambuc   *new_modep = m.m_fs_vfs_chown.mode;
158433d6423SLionel Sambuc 
159433d6423SLionel Sambuc   return(r);
160433d6423SLionel Sambuc }
161433d6423SLionel Sambuc 
162433d6423SLionel Sambuc 
163433d6423SLionel Sambuc /*===========================================================================*
164433d6423SLionel Sambuc  *				req_create				     *
165433d6423SLionel Sambuc  *===========================================================================*/
req_create(endpoint_t fs_e,ino_t inode_nr,int omode,uid_t uid,gid_t gid,char * path,node_details_t * res)166433d6423SLionel Sambuc int req_create(
167433d6423SLionel Sambuc   endpoint_t fs_e,
168433d6423SLionel Sambuc   ino_t inode_nr,
169433d6423SLionel Sambuc   int omode,
170433d6423SLionel Sambuc   uid_t uid,
171433d6423SLionel Sambuc   gid_t gid,
172433d6423SLionel Sambuc   char *path,
173433d6423SLionel Sambuc   node_details_t *res
174433d6423SLionel Sambuc )
175433d6423SLionel Sambuc {
176433d6423SLionel Sambuc   int r;
177433d6423SLionel Sambuc   cp_grant_id_t grant_id;
178433d6423SLionel Sambuc   size_t len;
179433d6423SLionel Sambuc   message m;
1800a6a1f1dSLionel Sambuc //  struct vmnt *vmp;
181433d6423SLionel Sambuc 
1820a6a1f1dSLionel Sambuc //  vmp = find_vmnt(fs_e);
183433d6423SLionel Sambuc 
184433d6423SLionel Sambuc   len = strlen(path) + 1;
185433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ);
186433d6423SLionel Sambuc   if (grant_id == -1)
187433d6423SLionel Sambuc 	panic("req_create: cpf_grant_direct failed");
188433d6423SLionel Sambuc 
189433d6423SLionel Sambuc   /* Fill in request message */
190433d6423SLionel Sambuc   m.m_type = REQ_CREATE;
191433d6423SLionel Sambuc   m.m_vfs_fs_create.inode = inode_nr;
192433d6423SLionel Sambuc   m.m_vfs_fs_create.mode = omode;
193433d6423SLionel Sambuc   m.m_vfs_fs_create.uid = uid;
194433d6423SLionel Sambuc   m.m_vfs_fs_create.gid = gid;
195433d6423SLionel Sambuc   m.m_vfs_fs_create.grant = grant_id;
196433d6423SLionel Sambuc   m.m_vfs_fs_create.path_len = len;
197433d6423SLionel Sambuc 
198433d6423SLionel Sambuc   /* Send/rec request */
199433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
200433d6423SLionel Sambuc   cpf_revoke(grant_id);
201433d6423SLionel Sambuc   if (r != OK) return(r);
202433d6423SLionel Sambuc 
203433d6423SLionel Sambuc   /* Fill in response structure */
204433d6423SLionel Sambuc   res->fs_e	= m.m_source;
205433d6423SLionel Sambuc   res->inode_nr	= m.m_fs_vfs_create.inode;
206433d6423SLionel Sambuc   res->fmode	= m.m_fs_vfs_create.mode;
207433d6423SLionel Sambuc   res->fsize    = m.m_fs_vfs_create.file_size;
208433d6423SLionel Sambuc   res->uid	= m.m_fs_vfs_create.uid;
209433d6423SLionel Sambuc   res->gid	= m.m_fs_vfs_create.gid;
210433d6423SLionel Sambuc   res->dev	= NO_DEV;
211433d6423SLionel Sambuc 
212433d6423SLionel Sambuc   return(OK);
213433d6423SLionel Sambuc }
214433d6423SLionel Sambuc 
215433d6423SLionel Sambuc 
216433d6423SLionel Sambuc /*===========================================================================*
217433d6423SLionel Sambuc  *				req_flush	      			     *
218433d6423SLionel Sambuc  *===========================================================================*/
req_flush(endpoint_t fs_e,dev_t dev)219433d6423SLionel Sambuc int req_flush(endpoint_t fs_e, dev_t dev)
220433d6423SLionel Sambuc {
221433d6423SLionel Sambuc   message m;
222433d6423SLionel Sambuc 
223433d6423SLionel Sambuc   /* Fill in request message */
224433d6423SLionel Sambuc   m.m_type = REQ_FLUSH;
225433d6423SLionel Sambuc   m.m_vfs_fs_flush.device = dev;
226433d6423SLionel Sambuc 
227433d6423SLionel Sambuc   /* Send/rec request */
228433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
229433d6423SLionel Sambuc }
230433d6423SLionel Sambuc 
231433d6423SLionel Sambuc 
232433d6423SLionel Sambuc /*===========================================================================*
233433d6423SLionel Sambuc  *				req_statvfs	    			     *
234433d6423SLionel Sambuc  *===========================================================================*/
req_statvfs(endpoint_t fs_e,struct statvfs * buf)235433d6423SLionel Sambuc int req_statvfs(endpoint_t fs_e, struct statvfs *buf)
236433d6423SLionel Sambuc {
237433d6423SLionel Sambuc   int r;
238433d6423SLionel Sambuc   cp_grant_id_t grant_id;
239433d6423SLionel Sambuc   message m;
240433d6423SLionel Sambuc 
241433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, sizeof(struct statvfs),
242433d6423SLionel Sambuc 			CPF_WRITE);
243433d6423SLionel Sambuc   if(grant_id == GRANT_INVALID)
244433d6423SLionel Sambuc 	panic("req_statvfs: cpf_grant_direct failed");
245433d6423SLionel Sambuc 
246433d6423SLionel Sambuc   /* Fill in request message */
247433d6423SLionel Sambuc   m.m_type = REQ_STATVFS;
248433d6423SLionel Sambuc   m.m_vfs_fs_statvfs.grant = grant_id;
249433d6423SLionel Sambuc 
250433d6423SLionel Sambuc   /* Send/rec request */
251433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
252433d6423SLionel Sambuc   cpf_revoke(grant_id);
253433d6423SLionel Sambuc 
254433d6423SLionel Sambuc   return(r);
255433d6423SLionel Sambuc }
256433d6423SLionel Sambuc 
257433d6423SLionel Sambuc 
258433d6423SLionel Sambuc /*===========================================================================*
259433d6423SLionel Sambuc  *				req_ftrunc	     			     *
260433d6423SLionel Sambuc  *===========================================================================*/
req_ftrunc(endpoint_t fs_e,ino_t inode_nr,off_t start,off_t end)261433d6423SLionel Sambuc int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end)
262433d6423SLionel Sambuc {
263433d6423SLionel Sambuc   message m;
264433d6423SLionel Sambuc   struct vmnt *vmp;
265433d6423SLionel Sambuc 
266433d6423SLionel Sambuc   vmp = find_vmnt(fs_e);
267433d6423SLionel Sambuc 
268433d6423SLionel Sambuc   /* Fill in request message */
269433d6423SLionel Sambuc   m.m_type = REQ_FTRUNC;
270433d6423SLionel Sambuc   m.m_vfs_fs_ftrunc.inode = inode_nr;
271433d6423SLionel Sambuc   m.m_vfs_fs_ftrunc.trc_start = start;
272433d6423SLionel Sambuc   m.m_vfs_fs_ftrunc.trc_end = end;
273433d6423SLionel Sambuc 
274433d6423SLionel Sambuc   if (!(vmp->m_fs_flags & RES_64BIT) &&
275433d6423SLionel Sambuc 	((start > INT_MAX) || (end > INT_MAX))) {
276433d6423SLionel Sambuc 	/* FS does not support 64-bit off_t and 32 bits is not enough */
277433d6423SLionel Sambuc 	return EINVAL;
278433d6423SLionel Sambuc   }
279433d6423SLionel Sambuc 
280433d6423SLionel Sambuc   /* Send/rec request */
281433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
282433d6423SLionel Sambuc }
283433d6423SLionel Sambuc 
284433d6423SLionel Sambuc 
285433d6423SLionel Sambuc /*===========================================================================*
286433d6423SLionel Sambuc  *				req_getdents_actual    			     *
287433d6423SLionel Sambuc  *===========================================================================*/
req_getdents_actual(endpoint_t fs_e,ino_t inode_nr,off_t pos,vir_bytes buf,size_t size,off_t * new_pos,int direct,int cpflag)288433d6423SLionel Sambuc static int req_getdents_actual(
289433d6423SLionel Sambuc   endpoint_t fs_e,
290433d6423SLionel Sambuc   ino_t inode_nr,
291433d6423SLionel Sambuc   off_t pos,
292433d6423SLionel Sambuc   vir_bytes buf,
293433d6423SLionel Sambuc   size_t size,
294433d6423SLionel Sambuc   off_t *new_pos,
295433d6423SLionel Sambuc   int direct,
296433d6423SLionel Sambuc   int cpflag
297433d6423SLionel Sambuc )
298433d6423SLionel Sambuc {
299433d6423SLionel Sambuc   int r;
300433d6423SLionel Sambuc   message m;
301433d6423SLionel Sambuc   cp_grant_id_t grant_id;
302433d6423SLionel Sambuc   struct vmnt *vmp;
303433d6423SLionel Sambuc 
304433d6423SLionel Sambuc   vmp = find_vmnt(fs_e);
305433d6423SLionel Sambuc   assert(vmp != NULL);
306433d6423SLionel Sambuc 
307433d6423SLionel Sambuc   if (direct) {
308433d6423SLionel Sambuc 	grant_id = cpf_grant_direct(fs_e, buf, size, CPF_WRITE);
309433d6423SLionel Sambuc   } else {
310433d6423SLionel Sambuc 	grant_id = cpf_grant_magic(fs_e, who_e, buf, size,
311433d6423SLionel Sambuc 				   CPF_WRITE | cpflag);
312433d6423SLionel Sambuc   }
313433d6423SLionel Sambuc 
314433d6423SLionel Sambuc   if (grant_id < 0)
315433d6423SLionel Sambuc 	panic("req_getdents: cpf_grant_direct/cpf_grant_magic failed: %d",
316433d6423SLionel Sambuc 								grant_id);
317433d6423SLionel Sambuc 
318433d6423SLionel Sambuc   m.m_type = REQ_GETDENTS;
319433d6423SLionel Sambuc   m.m_vfs_fs_getdents.inode = inode_nr;
320433d6423SLionel Sambuc   m.m_vfs_fs_getdents.grant = grant_id;
321433d6423SLionel Sambuc   m.m_vfs_fs_getdents.mem_size = size;
322433d6423SLionel Sambuc   m.m_vfs_fs_getdents.seek_pos = pos;
323433d6423SLionel Sambuc   if (!(vmp->m_fs_flags & RES_64BIT) && (pos > INT_MAX)) {
324433d6423SLionel Sambuc 	/* FS does not support 64-bit off_t and 32 bits is not enough */
325433d6423SLionel Sambuc 	return EINVAL;
326433d6423SLionel Sambuc   }
327433d6423SLionel Sambuc 
328433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
32910b7016bSDavid van Moolenbroek 
33010b7016bSDavid van Moolenbroek   if (cpf_revoke(grant_id) == GRANT_FAULTED) return(ERESTART);
331433d6423SLionel Sambuc 
332433d6423SLionel Sambuc   if (r == OK) {
333433d6423SLionel Sambuc 	*new_pos = m.m_fs_vfs_getdents.seek_pos;
334433d6423SLionel Sambuc 	r = m.m_fs_vfs_getdents.nbytes;
335433d6423SLionel Sambuc   }
336433d6423SLionel Sambuc 
337433d6423SLionel Sambuc   return(r);
338433d6423SLionel Sambuc }
339433d6423SLionel Sambuc 
340433d6423SLionel Sambuc /*===========================================================================*
341433d6423SLionel Sambuc  *				req_getdents	     			     *
342433d6423SLionel Sambuc  *===========================================================================*/
req_getdents(endpoint_t fs_e,ino_t inode_nr,off_t pos,vir_bytes buf,size_t size,off_t * new_pos,int direct)343433d6423SLionel Sambuc int req_getdents(
344433d6423SLionel Sambuc   endpoint_t fs_e,
345433d6423SLionel Sambuc   ino_t inode_nr,
346433d6423SLionel Sambuc   off_t pos,
347433d6423SLionel Sambuc   vir_bytes buf,
348433d6423SLionel Sambuc   size_t size,
349433d6423SLionel Sambuc   off_t *new_pos,
350433d6423SLionel Sambuc   int direct)
351433d6423SLionel Sambuc {
352433d6423SLionel Sambuc 	int r;
353433d6423SLionel Sambuc 
354433d6423SLionel Sambuc 	r = req_getdents_actual(fs_e, inode_nr, pos, buf, size, new_pos,
355433d6423SLionel Sambuc 		direct, CPF_TRY);
356433d6423SLionel Sambuc 
35710b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
35810b7016bSDavid van Moolenbroek 		assert(!direct);
35910b7016bSDavid van Moolenbroek 
360433d6423SLionel Sambuc 		if((r=vm_vfs_procctl_handlemem(who_e, buf, size, 1)) != OK) {
361433d6423SLionel Sambuc 			return r;
362433d6423SLionel Sambuc 		}
363433d6423SLionel Sambuc 
364433d6423SLionel Sambuc 		r = req_getdents_actual(fs_e, inode_nr, pos, buf, size,
365433d6423SLionel Sambuc 			new_pos, direct, 0);
366433d6423SLionel Sambuc 	}
367433d6423SLionel Sambuc 
368433d6423SLionel Sambuc 	return r;
369433d6423SLionel Sambuc }
370433d6423SLionel Sambuc 
371433d6423SLionel Sambuc /*===========================================================================*
372433d6423SLionel Sambuc  *				req_inhibread	  			     *
373433d6423SLionel Sambuc  *===========================================================================*/
req_inhibread(endpoint_t fs_e,ino_t inode_nr)374433d6423SLionel Sambuc int req_inhibread(endpoint_t fs_e, ino_t inode_nr)
375433d6423SLionel Sambuc {
376433d6423SLionel Sambuc   message m;
377433d6423SLionel Sambuc 
378433d6423SLionel Sambuc   /* Fill in request message */
379433d6423SLionel Sambuc   m.m_type = REQ_INHIBREAD;
380433d6423SLionel Sambuc   m.m_vfs_fs_inhibread.inode = inode_nr;
381433d6423SLionel Sambuc 
382433d6423SLionel Sambuc   /* Send/rec request */
383433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
384433d6423SLionel Sambuc }
385433d6423SLionel Sambuc 
386433d6423SLionel Sambuc 
387433d6423SLionel Sambuc /*===========================================================================*
388433d6423SLionel Sambuc  *				req_link	       			     *
389433d6423SLionel Sambuc  *===========================================================================*/
req_link(endpoint_t fs_e,ino_t link_parent,char * lastc,ino_t linked_file)390433d6423SLionel Sambuc int req_link(
391433d6423SLionel Sambuc   endpoint_t fs_e,
392433d6423SLionel Sambuc   ino_t link_parent,
393433d6423SLionel Sambuc   char *lastc,
394433d6423SLionel Sambuc   ino_t linked_file
395433d6423SLionel Sambuc )
396433d6423SLionel Sambuc {
397433d6423SLionel Sambuc   int r;
398433d6423SLionel Sambuc   cp_grant_id_t grant_id;
399433d6423SLionel Sambuc   const size_t len = strlen(lastc) + 1;
400433d6423SLionel Sambuc   message m;
401433d6423SLionel Sambuc 
402433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
403433d6423SLionel Sambuc   if(grant_id == -1)
404433d6423SLionel Sambuc 	  panic("req_link: cpf_grant_direct failed");
405433d6423SLionel Sambuc 
406433d6423SLionel Sambuc   /* Fill in request message */
407433d6423SLionel Sambuc   m.m_type = REQ_LINK;
408433d6423SLionel Sambuc   m.m_vfs_fs_link.inode = linked_file;
409433d6423SLionel Sambuc   m.m_vfs_fs_link.dir_ino = link_parent;
410433d6423SLionel Sambuc   m.m_vfs_fs_link.grant = grant_id;
411433d6423SLionel Sambuc   m.m_vfs_fs_link.path_len = len;
412433d6423SLionel Sambuc 
413433d6423SLionel Sambuc   /* Send/rec request */
414433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
415433d6423SLionel Sambuc   cpf_revoke(grant_id);
416433d6423SLionel Sambuc 
417433d6423SLionel Sambuc   return(r);
418433d6423SLionel Sambuc }
419433d6423SLionel Sambuc 
420433d6423SLionel Sambuc 
421433d6423SLionel Sambuc /*===========================================================================*
422433d6423SLionel Sambuc  *				req_lookup	                   	     *
423433d6423SLionel Sambuc  *===========================================================================*/
req_lookup(endpoint_t fs_e,ino_t dir_ino,ino_t root_ino,uid_t uid,gid_t gid,struct lookup * resolve,lookup_res_t * res,struct fproc * rfp)424433d6423SLionel Sambuc int req_lookup(
425433d6423SLionel Sambuc   endpoint_t fs_e,
426433d6423SLionel Sambuc   ino_t dir_ino,
427433d6423SLionel Sambuc   ino_t root_ino,
428433d6423SLionel Sambuc   uid_t uid,
429433d6423SLionel Sambuc   gid_t gid,
430433d6423SLionel Sambuc   struct lookup *resolve,
431433d6423SLionel Sambuc   lookup_res_t *res,
432433d6423SLionel Sambuc   struct fproc *rfp
433433d6423SLionel Sambuc )
434433d6423SLionel Sambuc {
435433d6423SLionel Sambuc   message m;
436433d6423SLionel Sambuc   vfs_ucred_t credentials;
437433d6423SLionel Sambuc   int r, flags;
438433d6423SLionel Sambuc   size_t len;
4390a6a1f1dSLionel Sambuc //  struct vmnt *vmp;
440433d6423SLionel Sambuc   cp_grant_id_t grant_id=0, grant_id2=0;
441433d6423SLionel Sambuc 
4420a6a1f1dSLionel Sambuc //  vmp = find_vmnt(fs_e);
443433d6423SLionel Sambuc 
444433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX,
445433d6423SLionel Sambuc 			      CPF_READ | CPF_WRITE);
446433d6423SLionel Sambuc   if(grant_id == -1)
447433d6423SLionel Sambuc 	  panic("req_lookup: cpf_grant_direct failed");
448433d6423SLionel Sambuc 
449433d6423SLionel Sambuc   flags = resolve->l_flags;
450433d6423SLionel Sambuc   len = strlen(resolve->l_path) + 1;
451433d6423SLionel Sambuc 
452433d6423SLionel Sambuc   m.m_type			= REQ_LOOKUP;
453433d6423SLionel Sambuc   m.m_vfs_fs_lookup.grant_path	= grant_id;
454433d6423SLionel Sambuc   m.m_vfs_fs_lookup.path_len 	= len;
455433d6423SLionel Sambuc   m.m_vfs_fs_lookup.path_size 	= PATH_MAX + 1;
456433d6423SLionel Sambuc   m.m_vfs_fs_lookup.dir_ino 	= dir_ino;
457433d6423SLionel Sambuc   m.m_vfs_fs_lookup.root_ino 	= root_ino;
458433d6423SLionel Sambuc 
459433d6423SLionel Sambuc   if(rfp->fp_ngroups > 0) { /* Is the process member of multiple groups? */
460433d6423SLionel Sambuc 	/* In that case the FS has to copy the uid/gid credentials */
461433d6423SLionel Sambuc 	int i;
462433d6423SLionel Sambuc 
463433d6423SLionel Sambuc 	/* Set credentials */
464433d6423SLionel Sambuc 	credentials.vu_uid = rfp->fp_effuid;
465433d6423SLionel Sambuc 	credentials.vu_gid = rfp->fp_effgid;
466433d6423SLionel Sambuc 	credentials.vu_ngroups = rfp->fp_ngroups;
467433d6423SLionel Sambuc 	for (i = 0; i < rfp->fp_ngroups; i++)
468433d6423SLionel Sambuc 		credentials.vu_sgroups[i] = rfp->fp_sgroups[i];
469433d6423SLionel Sambuc 
470433d6423SLionel Sambuc 	grant_id2 = cpf_grant_direct(fs_e, (vir_bytes) &credentials,
471433d6423SLionel Sambuc 				     sizeof(credentials), CPF_READ);
472433d6423SLionel Sambuc 	if(grant_id2 == -1)
473433d6423SLionel Sambuc 		panic("req_lookup: cpf_grant_direct failed");
474433d6423SLionel Sambuc 
475433d6423SLionel Sambuc 	m.m_vfs_fs_lookup.grant_ucred	= grant_id2;
476433d6423SLionel Sambuc 	m.m_vfs_fs_lookup.ucred_size	= sizeof(credentials);
477433d6423SLionel Sambuc 	flags		|= PATH_GET_UCRED;
478433d6423SLionel Sambuc   } else {
479433d6423SLionel Sambuc 	/* When there's only one gid, we can send it directly */
480433d6423SLionel Sambuc 	m.m_vfs_fs_lookup.uid = uid;
481433d6423SLionel Sambuc 	m.m_vfs_fs_lookup.gid = gid;
482433d6423SLionel Sambuc 	flags		&= ~PATH_GET_UCRED;
483433d6423SLionel Sambuc   }
484433d6423SLionel Sambuc 
485433d6423SLionel Sambuc   m.m_vfs_fs_lookup.flags = flags;
486433d6423SLionel Sambuc 
487433d6423SLionel Sambuc   /* Send/rec request */
488433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
489433d6423SLionel Sambuc   cpf_revoke(grant_id);
490433d6423SLionel Sambuc   if(rfp->fp_ngroups > 0) cpf_revoke(grant_id2);
491433d6423SLionel Sambuc 
492433d6423SLionel Sambuc   /* Fill in response according to the return value */
493433d6423SLionel Sambuc   res->fs_e = m.m_source;
494433d6423SLionel Sambuc 
495433d6423SLionel Sambuc   switch (r) {
496433d6423SLionel Sambuc   case OK:
497433d6423SLionel Sambuc 	res->inode_nr = m.m_fs_vfs_lookup.inode;
498433d6423SLionel Sambuc 	res->fmode = m.m_fs_vfs_lookup.mode;
499433d6423SLionel Sambuc 	res->fsize = m.m_fs_vfs_lookup.file_size;
500433d6423SLionel Sambuc 	res->dev = m.m_fs_vfs_lookup.device;
501433d6423SLionel Sambuc 	res->uid = m.m_fs_vfs_lookup.uid;
502433d6423SLionel Sambuc 	res->gid = m.m_fs_vfs_lookup.gid;
503433d6423SLionel Sambuc 	break;
504433d6423SLionel Sambuc   case EENTERMOUNT:
505433d6423SLionel Sambuc 	res->inode_nr = m.m_fs_vfs_lookup.inode;
506433d6423SLionel Sambuc 	res->char_processed = m.m_fs_vfs_lookup.offset;
507433d6423SLionel Sambuc 	res->symloop = m.m_fs_vfs_lookup.symloop;
508433d6423SLionel Sambuc 	break;
509433d6423SLionel Sambuc   case ELEAVEMOUNT:
510433d6423SLionel Sambuc 	res->char_processed = m.m_fs_vfs_lookup.offset;
511433d6423SLionel Sambuc 	res->symloop = m.m_fs_vfs_lookup.symloop;
512433d6423SLionel Sambuc 	break;
513433d6423SLionel Sambuc   case ESYMLINK:
514433d6423SLionel Sambuc 	res->char_processed = m.m_fs_vfs_lookup.offset;
515433d6423SLionel Sambuc 	res->symloop = m.m_fs_vfs_lookup.symloop;
516433d6423SLionel Sambuc 	break;
517433d6423SLionel Sambuc   default:
518433d6423SLionel Sambuc 	break;
519433d6423SLionel Sambuc   }
520433d6423SLionel Sambuc 
521433d6423SLionel Sambuc   return(r);
522433d6423SLionel Sambuc }
523433d6423SLionel Sambuc 
524433d6423SLionel Sambuc 
525433d6423SLionel Sambuc /*===========================================================================*
526433d6423SLionel Sambuc  *				req_mkdir	      			     *
527433d6423SLionel Sambuc  *===========================================================================*/
req_mkdir(endpoint_t fs_e,ino_t inode_nr,char * lastc,uid_t uid,gid_t gid,mode_t dmode)528433d6423SLionel Sambuc int req_mkdir(
529433d6423SLionel Sambuc   endpoint_t fs_e,
530433d6423SLionel Sambuc   ino_t inode_nr,
531433d6423SLionel Sambuc   char *lastc,
532433d6423SLionel Sambuc   uid_t uid,
533433d6423SLionel Sambuc   gid_t gid,
534433d6423SLionel Sambuc   mode_t dmode
535433d6423SLionel Sambuc )
536433d6423SLionel Sambuc {
537433d6423SLionel Sambuc   int r;
538433d6423SLionel Sambuc   cp_grant_id_t grant_id;
539433d6423SLionel Sambuc   size_t len;
540433d6423SLionel Sambuc   message m;
541433d6423SLionel Sambuc 
542433d6423SLionel Sambuc   len = strlen(lastc) + 1;
543433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
544433d6423SLionel Sambuc   if(grant_id == -1)
545433d6423SLionel Sambuc 	  panic("req_mkdir: cpf_grant_direct failed");
546433d6423SLionel Sambuc 
547433d6423SLionel Sambuc   /* Fill in request message */
548433d6423SLionel Sambuc   m.m_type = REQ_MKDIR;
549433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.inode = inode_nr;
550433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.mode = dmode;
551433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.uid = uid;
552433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.gid = gid;
553433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.grant = grant_id;
554433d6423SLionel Sambuc   m.m_vfs_fs_mkdir.path_len = len;
555433d6423SLionel Sambuc 
556433d6423SLionel Sambuc   /* Send/rec request */
557433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
558433d6423SLionel Sambuc   cpf_revoke(grant_id);
559433d6423SLionel Sambuc 
560433d6423SLionel Sambuc   return(r);
561433d6423SLionel Sambuc }
562433d6423SLionel Sambuc 
563433d6423SLionel Sambuc 
564433d6423SLionel Sambuc /*===========================================================================*
565433d6423SLionel Sambuc  *				req_mknod	      			     *
566433d6423SLionel Sambuc  *===========================================================================*/
req_mknod(endpoint_t fs_e,ino_t inode_nr,char * lastc,uid_t uid,gid_t gid,mode_t dmode,dev_t dev)567433d6423SLionel Sambuc int req_mknod(
568433d6423SLionel Sambuc   endpoint_t fs_e,
569433d6423SLionel Sambuc   ino_t inode_nr,
570433d6423SLionel Sambuc   char *lastc,
571433d6423SLionel Sambuc   uid_t uid,
572433d6423SLionel Sambuc   gid_t gid,
573433d6423SLionel Sambuc   mode_t dmode,
574433d6423SLionel Sambuc   dev_t dev
575433d6423SLionel Sambuc )
576433d6423SLionel Sambuc {
577433d6423SLionel Sambuc   int r;
578433d6423SLionel Sambuc   size_t len;
579433d6423SLionel Sambuc   cp_grant_id_t grant_id;
580433d6423SLionel Sambuc   message m;
581433d6423SLionel Sambuc 
582433d6423SLionel Sambuc   len = strlen(lastc) + 1;
583433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
584433d6423SLionel Sambuc   if(grant_id == -1)
585433d6423SLionel Sambuc 	  panic("req_mknod: cpf_grant_direct failed");
586433d6423SLionel Sambuc 
587433d6423SLionel Sambuc   /* Fill in request message */
588433d6423SLionel Sambuc   m.m_type = REQ_MKNOD;
589433d6423SLionel Sambuc   m.m_vfs_fs_mknod.inode = inode_nr;
590433d6423SLionel Sambuc   m.m_vfs_fs_mknod.mode = dmode;
591433d6423SLionel Sambuc   m.m_vfs_fs_mknod.device = dev;
592433d6423SLionel Sambuc   m.m_vfs_fs_mknod.uid = uid;
593433d6423SLionel Sambuc   m.m_vfs_fs_mknod.gid = gid;
594433d6423SLionel Sambuc   m.m_vfs_fs_mknod.grant = grant_id;
595433d6423SLionel Sambuc   m.m_vfs_fs_mknod.path_len = len;
596433d6423SLionel Sambuc 
597433d6423SLionel Sambuc   /* Send/rec request */
598433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
599433d6423SLionel Sambuc   cpf_revoke(grant_id);
600433d6423SLionel Sambuc 
601433d6423SLionel Sambuc   return(r);
602433d6423SLionel Sambuc }
603433d6423SLionel Sambuc 
604433d6423SLionel Sambuc 
605433d6423SLionel Sambuc /*===========================================================================*
606433d6423SLionel Sambuc  *				req_mountpoint	                 	     *
607433d6423SLionel Sambuc  *===========================================================================*/
req_mountpoint(endpoint_t fs_e,ino_t inode_nr)608433d6423SLionel Sambuc int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
609433d6423SLionel Sambuc {
610433d6423SLionel Sambuc   message m;
611433d6423SLionel Sambuc 
612433d6423SLionel Sambuc   /* Fill in request message */
613433d6423SLionel Sambuc   m.m_type = REQ_MOUNTPOINT;
614433d6423SLionel Sambuc   m.m_vfs_fs_mountpoint.inode = inode_nr;
615433d6423SLionel Sambuc 
616433d6423SLionel Sambuc   /* Send/rec request */
617433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
618433d6423SLionel Sambuc }
619433d6423SLionel Sambuc 
620433d6423SLionel Sambuc 
621433d6423SLionel Sambuc /*===========================================================================*
622433d6423SLionel Sambuc  *				req_newnode	      			     *
623433d6423SLionel Sambuc  *===========================================================================*/
req_newnode(endpoint_t fs_e,uid_t uid,gid_t gid,mode_t dmode,dev_t dev,struct node_details * res)624433d6423SLionel Sambuc int req_newnode(
625433d6423SLionel Sambuc   endpoint_t fs_e,
626433d6423SLionel Sambuc   uid_t uid,
627433d6423SLionel Sambuc   gid_t gid,
628433d6423SLionel Sambuc   mode_t dmode,
629433d6423SLionel Sambuc   dev_t dev,
630433d6423SLionel Sambuc   struct node_details *res
631433d6423SLionel Sambuc )
632433d6423SLionel Sambuc {
6330a6a1f1dSLionel Sambuc //  struct vmnt *vmp;
634433d6423SLionel Sambuc   int r;
635433d6423SLionel Sambuc   message m;
636433d6423SLionel Sambuc 
6370a6a1f1dSLionel Sambuc //  vmp = find_vmnt(fs_e);
638433d6423SLionel Sambuc 
639433d6423SLionel Sambuc   /* Fill in request message */
640433d6423SLionel Sambuc   m.m_type = REQ_NEWNODE;
641433d6423SLionel Sambuc   m.m_vfs_fs_newnode.mode = dmode;
642433d6423SLionel Sambuc   m.m_vfs_fs_newnode.device = dev;
643433d6423SLionel Sambuc   m.m_vfs_fs_newnode.uid = uid;
644433d6423SLionel Sambuc   m.m_vfs_fs_newnode.gid = gid;
645433d6423SLionel Sambuc 
646433d6423SLionel Sambuc   /* Send/rec request */
647433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
648433d6423SLionel Sambuc 
649433d6423SLionel Sambuc   res->fs_e	= m.m_source;
650433d6423SLionel Sambuc   res->inode_nr = m.m_fs_vfs_newnode.inode;
651433d6423SLionel Sambuc   res->fmode	= m.m_fs_vfs_newnode.mode;
652433d6423SLionel Sambuc   res->fsize    = m.m_fs_vfs_newnode.file_size;
653433d6423SLionel Sambuc   res->dev	= m.m_fs_vfs_newnode.device;
654433d6423SLionel Sambuc   res->uid	= m.m_fs_vfs_newnode.uid;
655433d6423SLionel Sambuc   res->gid	= m.m_fs_vfs_newnode.gid;
656433d6423SLionel Sambuc 
657433d6423SLionel Sambuc   return(r);
658433d6423SLionel Sambuc }
659433d6423SLionel Sambuc 
660433d6423SLionel Sambuc 
661433d6423SLionel Sambuc /*===========================================================================*
662433d6423SLionel Sambuc  *				req_newdriver          			     *
663433d6423SLionel Sambuc  *===========================================================================*/
req_newdriver(endpoint_t fs_e,dev_t dev,char * label)664433d6423SLionel Sambuc int req_newdriver(
665433d6423SLionel Sambuc   endpoint_t fs_e,
666433d6423SLionel Sambuc   dev_t dev,
667433d6423SLionel Sambuc   char *label
668433d6423SLionel Sambuc )
669433d6423SLionel Sambuc {
670433d6423SLionel Sambuc   cp_grant_id_t grant_id;
671433d6423SLionel Sambuc   size_t len;
672433d6423SLionel Sambuc   message m;
673433d6423SLionel Sambuc   int r;
674433d6423SLionel Sambuc 
675433d6423SLionel Sambuc   /* Grant access to label */
676433d6423SLionel Sambuc   len = strlen(label) + 1;
677433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
678433d6423SLionel Sambuc   if (grant_id == -1)
679433d6423SLionel Sambuc 	panic("req_newdriver: cpf_grant_direct failed");
680433d6423SLionel Sambuc 
681433d6423SLionel Sambuc   /* Fill in request message */
682433d6423SLionel Sambuc   m.m_type = REQ_NEW_DRIVER;
683433d6423SLionel Sambuc   m.m_vfs_fs_new_driver.device = dev;
684433d6423SLionel Sambuc   m.m_vfs_fs_new_driver.grant = grant_id;
685433d6423SLionel Sambuc   m.m_vfs_fs_new_driver.path_len = len;
686433d6423SLionel Sambuc 
687433d6423SLionel Sambuc   /* Issue request */
688433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
689433d6423SLionel Sambuc 
690433d6423SLionel Sambuc   cpf_revoke(grant_id);
691433d6423SLionel Sambuc 
692433d6423SLionel Sambuc   return(r);
693433d6423SLionel Sambuc }
694433d6423SLionel Sambuc 
695433d6423SLionel Sambuc 
696433d6423SLionel Sambuc /*===========================================================================*
697433d6423SLionel Sambuc  *				req_putnode				     *
698433d6423SLionel Sambuc  *===========================================================================*/
699*a0814afbSRichard Sailer int
req_putnode(int fs_e,ino_t inode_nr,int count)700*a0814afbSRichard Sailer req_putnode(int fs_e, ino_t inode_nr, int count)
701433d6423SLionel Sambuc {
702433d6423SLionel Sambuc   message m;
703433d6423SLionel Sambuc 
704433d6423SLionel Sambuc   /* Fill in request message */
705433d6423SLionel Sambuc   m.m_type = REQ_PUTNODE;
706433d6423SLionel Sambuc   m.m_vfs_fs_putnode.inode = inode_nr;
707433d6423SLionel Sambuc   m.m_vfs_fs_putnode.count = count;
708433d6423SLionel Sambuc 
709433d6423SLionel Sambuc   /* Send/rec request */
710433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
711433d6423SLionel Sambuc }
712433d6423SLionel Sambuc 
713433d6423SLionel Sambuc 
714433d6423SLionel Sambuc /*===========================================================================*
715433d6423SLionel Sambuc  *				req_rdlink_actual     			     *
716433d6423SLionel Sambuc  *===========================================================================*/
req_rdlink_actual(endpoint_t fs_e,ino_t inode_nr,endpoint_t proc_e,vir_bytes buf,size_t len,int direct,int cpflag)717433d6423SLionel Sambuc static int req_rdlink_actual(endpoint_t fs_e, ino_t inode_nr,
718433d6423SLionel Sambuc 	endpoint_t proc_e, vir_bytes buf, size_t len,
719433d6423SLionel Sambuc 	int direct, /* set to 1 to use direct grants instead of magic grants */
720433d6423SLionel Sambuc 	int cpflag)
721433d6423SLionel Sambuc {
722433d6423SLionel Sambuc   message m;
723433d6423SLionel Sambuc   int r;
724433d6423SLionel Sambuc   cp_grant_id_t grant_id;
725433d6423SLionel Sambuc 
726433d6423SLionel Sambuc   if (direct) {
727433d6423SLionel Sambuc 	grant_id = cpf_grant_direct(fs_e, buf, len, CPF_WRITE);
728433d6423SLionel Sambuc   } else {
729433d6423SLionel Sambuc 	grant_id = cpf_grant_magic(fs_e, proc_e, buf, len, CPF_WRITE | cpflag);
730433d6423SLionel Sambuc   }
731433d6423SLionel Sambuc   if (grant_id == -1)
732433d6423SLionel Sambuc 	  panic("req_rdlink: cpf_grant_magic failed");
733433d6423SLionel Sambuc 
734433d6423SLionel Sambuc   /* Fill in request message */
735433d6423SLionel Sambuc   m.m_type = REQ_RDLINK;
736433d6423SLionel Sambuc   m.m_vfs_fs_rdlink.inode = inode_nr;
737433d6423SLionel Sambuc   m.m_vfs_fs_rdlink.grant = grant_id;
738433d6423SLionel Sambuc   m.m_vfs_fs_rdlink.mem_size = len;
739433d6423SLionel Sambuc 
740433d6423SLionel Sambuc   /* Send/rec request */
741433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
74210b7016bSDavid van Moolenbroek 
74310b7016bSDavid van Moolenbroek   if (cpf_revoke(grant_id) == GRANT_FAULTED) return(ERESTART);
744433d6423SLionel Sambuc 
745433d6423SLionel Sambuc   if (r == OK) r = m.m_fs_vfs_rdlink.nbytes;
746433d6423SLionel Sambuc 
747433d6423SLionel Sambuc   return(r);
748433d6423SLionel Sambuc }
749433d6423SLionel Sambuc 
750433d6423SLionel Sambuc /*===========================================================================*
751433d6423SLionel Sambuc  *				req_rdlink	     			     *
752433d6423SLionel Sambuc  *===========================================================================*/
req_rdlink(endpoint_t fs_e,ino_t inode_nr,endpoint_t proc_e,vir_bytes buf,size_t len,int direct)753433d6423SLionel Sambuc int req_rdlink(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
754433d6423SLionel Sambuc 	vir_bytes buf, size_t len,
755433d6423SLionel Sambuc 	int direct /* set to 1 to use direct grants instead of magic grants */
756433d6423SLionel Sambuc )
757433d6423SLionel Sambuc {
758433d6423SLionel Sambuc 	int r;
759433d6423SLionel Sambuc 
760433d6423SLionel Sambuc 	r = req_rdlink_actual(fs_e, inode_nr, proc_e, buf, len, direct,
761433d6423SLionel Sambuc 		CPF_TRY);
762433d6423SLionel Sambuc 
76310b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
76410b7016bSDavid van Moolenbroek 		assert(!direct);
76510b7016bSDavid van Moolenbroek 
766433d6423SLionel Sambuc 		if((r=vm_vfs_procctl_handlemem(proc_e, buf, len, 1)) != OK) {
767433d6423SLionel Sambuc 			return r;
768433d6423SLionel Sambuc 		}
769433d6423SLionel Sambuc 
770433d6423SLionel Sambuc 		r = req_rdlink_actual(fs_e, inode_nr, proc_e, buf, len,
771433d6423SLionel Sambuc 			direct, 0);
772433d6423SLionel Sambuc 	}
773433d6423SLionel Sambuc 
774433d6423SLionel Sambuc 	return r;
775433d6423SLionel Sambuc }
776433d6423SLionel Sambuc 
777433d6423SLionel Sambuc /*===========================================================================*
778433d6423SLionel Sambuc  *				req_readsuper	                  	     *
779433d6423SLionel Sambuc  *===========================================================================*/
req_readsuper(struct vmnt * vmp,char * label,dev_t dev,int readonly,int isroot,struct node_details * res,unsigned int * fs_flags)780433d6423SLionel Sambuc int req_readsuper(
781433d6423SLionel Sambuc   struct vmnt *vmp,
782433d6423SLionel Sambuc   char *label,
783433d6423SLionel Sambuc   dev_t dev,
784433d6423SLionel Sambuc   int readonly,
785433d6423SLionel Sambuc   int isroot,
786433d6423SLionel Sambuc   struct node_details *res,
787433d6423SLionel Sambuc   unsigned int *fs_flags
788433d6423SLionel Sambuc )
789433d6423SLionel Sambuc {
790433d6423SLionel Sambuc   int r;
791433d6423SLionel Sambuc   cp_grant_id_t grant_id;
792433d6423SLionel Sambuc   size_t len;
793433d6423SLionel Sambuc   message m;
794433d6423SLionel Sambuc   endpoint_t fs_e;
795433d6423SLionel Sambuc 
796433d6423SLionel Sambuc   fs_e = vmp->m_fs_e;
797433d6423SLionel Sambuc 
798433d6423SLionel Sambuc   len = strlen(label)+1;
799433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
800433d6423SLionel Sambuc   if (grant_id == -1)
801433d6423SLionel Sambuc 	  panic("req_readsuper: cpf_grant_direct failed");
802433d6423SLionel Sambuc 
803433d6423SLionel Sambuc   /* Fill in request message */
804433d6423SLionel Sambuc   m.m_type = REQ_READSUPER;
805433d6423SLionel Sambuc   m.m_vfs_fs_readsuper.flags = 0;
806433d6423SLionel Sambuc   if(readonly) m.m_vfs_fs_readsuper.flags |= REQ_RDONLY;
807433d6423SLionel Sambuc   if(isroot)   m.m_vfs_fs_readsuper.flags |= REQ_ISROOT;
808433d6423SLionel Sambuc   m.m_vfs_fs_readsuper.grant = grant_id;
809433d6423SLionel Sambuc   m.m_vfs_fs_readsuper.device = dev;
810433d6423SLionel Sambuc   m.m_vfs_fs_readsuper.path_len = len;
811433d6423SLionel Sambuc 
812433d6423SLionel Sambuc   /* Send/rec request */
813433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
814433d6423SLionel Sambuc   cpf_revoke(grant_id);
815433d6423SLionel Sambuc 
816433d6423SLionel Sambuc   if(r == OK) {
817433d6423SLionel Sambuc 	/* Fill in response structure */
818433d6423SLionel Sambuc 	res->fs_e = m.m_source;
819433d6423SLionel Sambuc 	res->inode_nr = m.m_fs_vfs_readsuper.inode;
820433d6423SLionel Sambuc 	res->fmode = m.m_fs_vfs_readsuper.mode;
821433d6423SLionel Sambuc 	res->fsize = m.m_fs_vfs_readsuper.file_size;
822433d6423SLionel Sambuc 	res->uid = m.m_fs_vfs_readsuper.uid;
823433d6423SLionel Sambuc 	res->gid = m.m_fs_vfs_readsuper.gid;
824433d6423SLionel Sambuc 	*fs_flags = m.m_fs_vfs_readsuper.flags;
825433d6423SLionel Sambuc   }
826433d6423SLionel Sambuc 
827433d6423SLionel Sambuc   return(r);
828433d6423SLionel Sambuc }
829433d6423SLionel Sambuc 
830433d6423SLionel Sambuc 
831433d6423SLionel Sambuc /*===========================================================================*
832433d6423SLionel Sambuc  *				req_readwrite_actual			     *
833433d6423SLionel Sambuc  *===========================================================================*/
req_readwrite_actual(endpoint_t fs_e,ino_t inode_nr,off_t pos,int rw_flag,endpoint_t user_e,vir_bytes user_addr,unsigned int num_of_bytes,off_t * new_posp,size_t * cum_iop,int cpflag)834433d6423SLionel Sambuc static int req_readwrite_actual(endpoint_t fs_e, ino_t inode_nr, off_t pos,
835433d6423SLionel Sambuc 	int rw_flag, endpoint_t user_e, vir_bytes user_addr,
836433d6423SLionel Sambuc 	unsigned int num_of_bytes, off_t *new_posp, size_t *cum_iop,
837433d6423SLionel Sambuc 	int cpflag)
838433d6423SLionel Sambuc {
839433d6423SLionel Sambuc   struct vmnt *vmp;
840433d6423SLionel Sambuc   int r;
841433d6423SLionel Sambuc   cp_grant_id_t grant_id;
842433d6423SLionel Sambuc   message m;
843433d6423SLionel Sambuc 
844433d6423SLionel Sambuc   vmp = find_vmnt(fs_e);
845433d6423SLionel Sambuc 
846433d6423SLionel Sambuc   grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
847433d6423SLionel Sambuc 			     (rw_flag==READING ? CPF_WRITE:CPF_READ) | cpflag);
848433d6423SLionel Sambuc   if (grant_id == -1)
849433d6423SLionel Sambuc 	  panic("req_readwrite: cpf_grant_magic failed");
850433d6423SLionel Sambuc 
851433d6423SLionel Sambuc   /* Fill in request message */
852433d6423SLionel Sambuc   m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
853433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.inode = inode_nr;
854433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.grant = grant_id;
855433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.seek_pos = pos;
856433d6423SLionel Sambuc   if ((!(vmp->m_fs_flags & RES_64BIT)) && (pos > INT_MAX)) {
857433d6423SLionel Sambuc 	return EINVAL;
858433d6423SLionel Sambuc   }
859433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.nbytes = num_of_bytes;
860433d6423SLionel Sambuc 
861433d6423SLionel Sambuc   /* Send/rec request */
862433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
86310b7016bSDavid van Moolenbroek 
86410b7016bSDavid van Moolenbroek   if (cpf_revoke(grant_id) == GRANT_FAULTED) return(ERESTART);
865433d6423SLionel Sambuc 
866433d6423SLionel Sambuc   if (r == OK) {
867433d6423SLionel Sambuc 	/* Fill in response structure */
868433d6423SLionel Sambuc 	*new_posp = m.m_fs_vfs_readwrite.seek_pos;
869433d6423SLionel Sambuc 	*cum_iop = m.m_fs_vfs_readwrite.nbytes;
870433d6423SLionel Sambuc   }
871433d6423SLionel Sambuc 
872433d6423SLionel Sambuc   return(r);
873433d6423SLionel Sambuc }
874433d6423SLionel Sambuc 
875433d6423SLionel Sambuc /*===========================================================================*
876433d6423SLionel Sambuc  *				req_readwrite				     *
877433d6423SLionel Sambuc  *===========================================================================*/
req_readwrite(endpoint_t fs_e,ino_t inode_nr,off_t pos,int rw_flag,endpoint_t user_e,vir_bytes user_addr,unsigned int num_of_bytes,off_t * new_posp,size_t * cum_iop)878433d6423SLionel Sambuc int req_readwrite(endpoint_t fs_e, ino_t inode_nr, off_t pos,
879433d6423SLionel Sambuc 	int rw_flag, endpoint_t user_e, vir_bytes user_addr,
8803c8950ccSBen Gras 	unsigned int num_of_bytes, off_t *new_posp, size_t *cum_iop)
881433d6423SLionel Sambuc {
882433d6423SLionel Sambuc 	int r;
883433d6423SLionel Sambuc 
884433d6423SLionel Sambuc 	r = req_readwrite_actual(fs_e, inode_nr, pos, rw_flag, user_e,
885433d6423SLionel Sambuc 		user_addr, num_of_bytes, new_posp, cum_iop, CPF_TRY);
886433d6423SLionel Sambuc 
88710b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
88810b7016bSDavid van Moolenbroek 		if ((r=vm_vfs_procctl_handlemem(user_e, (vir_bytes) user_addr,
88910b7016bSDavid van Moolenbroek 		    num_of_bytes, rw_flag == READING)) != OK) {
890433d6423SLionel Sambuc 			return r;
891433d6423SLionel Sambuc 		}
892433d6423SLionel Sambuc 
893433d6423SLionel Sambuc 		r = req_readwrite_actual(fs_e, inode_nr, pos, rw_flag, user_e,
894433d6423SLionel Sambuc 			user_addr, num_of_bytes, new_posp, cum_iop, 0);
895433d6423SLionel Sambuc 	}
896433d6423SLionel Sambuc 
897433d6423SLionel Sambuc 	return r;
898433d6423SLionel Sambuc }
899433d6423SLionel Sambuc 
900433d6423SLionel Sambuc /*===========================================================================*
901433d6423SLionel Sambuc  *				req_peek				     *
902433d6423SLionel Sambuc  *===========================================================================*/
req_peek(endpoint_t fs_e,ino_t inode_nr,off_t pos,unsigned int bytes)903433d6423SLionel Sambuc int req_peek(endpoint_t fs_e, ino_t inode_nr, off_t pos, unsigned int bytes)
904433d6423SLionel Sambuc {
905433d6423SLionel Sambuc   message m;
906433d6423SLionel Sambuc 
907433d6423SLionel Sambuc   memset(&m, 0, sizeof(m));
908433d6423SLionel Sambuc 
909433d6423SLionel Sambuc   if (ex64hi(pos) != 0)
910433d6423SLionel Sambuc 	  panic("req_peek: pos too large");
911433d6423SLionel Sambuc 
912433d6423SLionel Sambuc   /* Fill in request message */
913433d6423SLionel Sambuc   m.m_type = REQ_PEEK;
914433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.inode = inode_nr;
915433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.grant = -1;
916433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.seek_pos = pos;
917433d6423SLionel Sambuc   m.m_vfs_fs_readwrite.nbytes = bytes;
918433d6423SLionel Sambuc 
919433d6423SLionel Sambuc   /* Send/rec request */
920433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
921433d6423SLionel Sambuc }
922433d6423SLionel Sambuc 
923433d6423SLionel Sambuc /*===========================================================================*
924433d6423SLionel Sambuc  *				req_rename	     			     *
925433d6423SLionel Sambuc  *===========================================================================*/
926*a0814afbSRichard Sailer int
req_rename(endpoint_t fs_e,ino_t old_dir,char * old_name,ino_t new_dir,char * new_name)927*a0814afbSRichard Sailer req_rename(endpoint_t fs_e, ino_t old_dir, char *old_name, ino_t new_dir, char *new_name)
928433d6423SLionel Sambuc {
929433d6423SLionel Sambuc   int r;
930433d6423SLionel Sambuc   cp_grant_id_t gid_old, gid_new;
931433d6423SLionel Sambuc   size_t len_old, len_new;
932433d6423SLionel Sambuc   message m;
933433d6423SLionel Sambuc 
934433d6423SLionel Sambuc   len_old = strlen(old_name) + 1;
935433d6423SLionel Sambuc   gid_old = cpf_grant_direct(fs_e, (vir_bytes) old_name, len_old, CPF_READ);
936433d6423SLionel Sambuc   if(gid_old == -1)
937433d6423SLionel Sambuc 	  panic("req_rename: cpf_grant_direct failed");
938433d6423SLionel Sambuc 
939433d6423SLionel Sambuc   len_new = strlen(new_name) + 1;
940433d6423SLionel Sambuc   gid_new = cpf_grant_direct(fs_e, (vir_bytes) new_name, len_new, CPF_READ);
941433d6423SLionel Sambuc   if(gid_new == -1)
942433d6423SLionel Sambuc 	  panic("req_rename: cpf_grant_direct failed");
943433d6423SLionel Sambuc 
944433d6423SLionel Sambuc   /* Fill in request message */
945433d6423SLionel Sambuc   m.m_type = REQ_RENAME;
946433d6423SLionel Sambuc   m.m_vfs_fs_rename.dir_old = old_dir;
947433d6423SLionel Sambuc   m.m_vfs_fs_rename.grant_old = gid_old;
948433d6423SLionel Sambuc   m.m_vfs_fs_rename.len_old = len_old;
949433d6423SLionel Sambuc 
950433d6423SLionel Sambuc   m.m_vfs_fs_rename.dir_new = new_dir;
951433d6423SLionel Sambuc   m.m_vfs_fs_rename.grant_new = gid_new;
952433d6423SLionel Sambuc   m.m_vfs_fs_rename.len_new = len_new;
953433d6423SLionel Sambuc 
954433d6423SLionel Sambuc   /* Send/rec request */
955433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
956433d6423SLionel Sambuc   cpf_revoke(gid_old);
957433d6423SLionel Sambuc   cpf_revoke(gid_new);
958433d6423SLionel Sambuc 
959433d6423SLionel Sambuc   return(r);
960433d6423SLionel Sambuc }
961433d6423SLionel Sambuc 
962433d6423SLionel Sambuc 
963433d6423SLionel Sambuc /*===========================================================================*
964433d6423SLionel Sambuc  *				req_rmdir	      			     *
965433d6423SLionel Sambuc  *===========================================================================*/
966*a0814afbSRichard Sailer int
req_rmdir(endpoint_t fs_e,ino_t inode_nr,char * lastc)967*a0814afbSRichard Sailer req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc)
968433d6423SLionel Sambuc {
969433d6423SLionel Sambuc   int r;
970433d6423SLionel Sambuc   cp_grant_id_t grant_id;
971433d6423SLionel Sambuc   size_t len;
972433d6423SLionel Sambuc   message m;
973433d6423SLionel Sambuc 
974433d6423SLionel Sambuc   len = strlen(lastc) + 1;
975433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
976433d6423SLionel Sambuc   if(grant_id == -1)
977433d6423SLionel Sambuc 	  panic("req_rmdir: cpf_grant_direct failed");
978433d6423SLionel Sambuc 
979433d6423SLionel Sambuc   /* Fill in request message */
980433d6423SLionel Sambuc   m.m_type = REQ_RMDIR;
981433d6423SLionel Sambuc   m.m_vfs_fs_unlink.inode = inode_nr;
982433d6423SLionel Sambuc   m.m_vfs_fs_unlink.grant = grant_id;
983433d6423SLionel Sambuc   m.m_vfs_fs_unlink.path_len = len;
984433d6423SLionel Sambuc 
985433d6423SLionel Sambuc   /* Send/rec request */
986433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
987433d6423SLionel Sambuc   cpf_revoke(grant_id);
988433d6423SLionel Sambuc 
989433d6423SLionel Sambuc   return(r);
990433d6423SLionel Sambuc }
991433d6423SLionel Sambuc 
992433d6423SLionel Sambuc 
993433d6423SLionel Sambuc /*===========================================================================*
994433d6423SLionel Sambuc  *				req_slink_actual      			     *
995433d6423SLionel Sambuc  *===========================================================================*/
req_slink_actual(endpoint_t fs_e,ino_t inode_nr,char * lastc,endpoint_t proc_e,vir_bytes path_addr,size_t path_length,uid_t uid,gid_t gid,int cpflag)996433d6423SLionel Sambuc static int req_slink_actual(
997433d6423SLionel Sambuc   endpoint_t fs_e,
998433d6423SLionel Sambuc   ino_t inode_nr,
999433d6423SLionel Sambuc   char *lastc,
1000433d6423SLionel Sambuc   endpoint_t proc_e,
1001433d6423SLionel Sambuc   vir_bytes path_addr,
1002433d6423SLionel Sambuc   size_t path_length,
1003433d6423SLionel Sambuc   uid_t uid,
1004433d6423SLionel Sambuc   gid_t gid,
1005433d6423SLionel Sambuc   int cpflag
1006433d6423SLionel Sambuc )
1007433d6423SLionel Sambuc {
1008433d6423SLionel Sambuc   int r;
1009433d6423SLionel Sambuc   size_t len;
1010433d6423SLionel Sambuc   cp_grant_id_t gid_name, gid_buf;
1011433d6423SLionel Sambuc   message m;
1012433d6423SLionel Sambuc 
1013433d6423SLionel Sambuc   len = strlen(lastc) + 1;
1014433d6423SLionel Sambuc   gid_name = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
1015433d6423SLionel Sambuc   if (gid_name == GRANT_INVALID)
1016433d6423SLionel Sambuc 	  panic("req_slink: cpf_grant_direct failed");
1017433d6423SLionel Sambuc 
1018433d6423SLionel Sambuc   gid_buf = cpf_grant_magic(fs_e, proc_e, path_addr, path_length,
1019433d6423SLionel Sambuc 	CPF_READ | cpflag);
1020433d6423SLionel Sambuc 
1021433d6423SLionel Sambuc   if (gid_buf == GRANT_INVALID) {
1022433d6423SLionel Sambuc 	  cpf_revoke(gid_name);
1023433d6423SLionel Sambuc 	  panic("req_slink: cpf_grant_magic failed");
1024433d6423SLionel Sambuc   }
1025433d6423SLionel Sambuc 
1026433d6423SLionel Sambuc   /* Fill in request message */
1027433d6423SLionel Sambuc   m.m_type = REQ_SLINK;
1028433d6423SLionel Sambuc   m.m_vfs_fs_slink.inode = inode_nr;
1029433d6423SLionel Sambuc   m.m_vfs_fs_slink.uid = uid;
1030433d6423SLionel Sambuc   m.m_vfs_fs_slink.gid = gid;
1031433d6423SLionel Sambuc   m.m_vfs_fs_slink.grant_path = gid_name;
1032433d6423SLionel Sambuc   m.m_vfs_fs_slink.path_len = len;
1033433d6423SLionel Sambuc   m.m_vfs_fs_slink.grant_target = gid_buf;
1034433d6423SLionel Sambuc   m.m_vfs_fs_slink.mem_size = path_length;
1035433d6423SLionel Sambuc 
1036433d6423SLionel Sambuc   /* Send/rec request */
1037433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
103810b7016bSDavid van Moolenbroek 
1039433d6423SLionel Sambuc   cpf_revoke(gid_name);
104010b7016bSDavid van Moolenbroek   if (cpf_revoke(gid_buf) == GRANT_FAULTED) return(ERESTART);
1041433d6423SLionel Sambuc 
1042433d6423SLionel Sambuc   return(r);
1043433d6423SLionel Sambuc }
1044433d6423SLionel Sambuc 
1045433d6423SLionel Sambuc /*===========================================================================*
1046433d6423SLionel Sambuc  *				req_slink	      			     *
1047433d6423SLionel Sambuc  *===========================================================================*/
req_slink(endpoint_t fs_e,ino_t inode_nr,char * lastc,endpoint_t proc_e,vir_bytes path_addr,size_t path_length,uid_t uid,gid_t gid)1048433d6423SLionel Sambuc int req_slink(
1049433d6423SLionel Sambuc   endpoint_t fs_e,
1050433d6423SLionel Sambuc   ino_t inode_nr,
1051433d6423SLionel Sambuc   char *lastc,
1052433d6423SLionel Sambuc   endpoint_t proc_e,
1053433d6423SLionel Sambuc   vir_bytes path_addr,
1054433d6423SLionel Sambuc   size_t path_length,
1055433d6423SLionel Sambuc   uid_t uid,
1056433d6423SLionel Sambuc   gid_t gid
1057433d6423SLionel Sambuc )
1058433d6423SLionel Sambuc {
1059433d6423SLionel Sambuc 	int r;
1060433d6423SLionel Sambuc 
1061433d6423SLionel Sambuc 	r = req_slink_actual(fs_e, inode_nr, lastc, proc_e, path_addr,
1062433d6423SLionel Sambuc 		path_length, uid, gid, CPF_TRY);
1063433d6423SLionel Sambuc 
106410b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
1065433d6423SLionel Sambuc 		if((r=vm_vfs_procctl_handlemem(proc_e, (vir_bytes) path_addr,
1066433d6423SLionel Sambuc 			path_length, 0)) != OK) {
1067433d6423SLionel Sambuc 			return r;
1068433d6423SLionel Sambuc 		}
1069433d6423SLionel Sambuc 
1070433d6423SLionel Sambuc 		r = req_slink_actual(fs_e, inode_nr, lastc, proc_e, path_addr,
1071433d6423SLionel Sambuc 			path_length, uid, gid, 0);
1072433d6423SLionel Sambuc 	}
1073433d6423SLionel Sambuc 
1074433d6423SLionel Sambuc 	return r;
1075433d6423SLionel Sambuc }
1076433d6423SLionel Sambuc 
1077433d6423SLionel Sambuc /*===========================================================================*
1078433d6423SLionel Sambuc  *				req_stat_actual	       			     *
1079433d6423SLionel Sambuc  *===========================================================================*/
req_stat_actual(endpoint_t fs_e,ino_t inode_nr,endpoint_t proc_e,vir_bytes buf,int cpflag)1080433d6423SLionel Sambuc int req_stat_actual(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
1081433d6423SLionel Sambuc 	vir_bytes buf, int cpflag)
1082433d6423SLionel Sambuc {
1083433d6423SLionel Sambuc   cp_grant_id_t grant_id;
1084433d6423SLionel Sambuc   int r;
1085433d6423SLionel Sambuc   message m;
1086433d6423SLionel Sambuc 
1087433d6423SLionel Sambuc   /* Grant FS access to copy straight into user provided buffer */
1088433d6423SLionel Sambuc   grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct stat),
1089433d6423SLionel Sambuc 	CPF_WRITE | cpflag);
1090433d6423SLionel Sambuc 
1091433d6423SLionel Sambuc   if (grant_id < 0)
1092433d6423SLionel Sambuc 	panic("req_stat: cpf_grant_* failed");
1093433d6423SLionel Sambuc 
1094433d6423SLionel Sambuc   /* Fill in request message */
1095433d6423SLionel Sambuc   m.m_type = REQ_STAT;
1096433d6423SLionel Sambuc   m.m_vfs_fs_stat.inode = inode_nr;
1097433d6423SLionel Sambuc   m.m_vfs_fs_stat.grant = grant_id;
1098433d6423SLionel Sambuc 
1099433d6423SLionel Sambuc   /* Send/rec request */
1100433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
110110b7016bSDavid van Moolenbroek 
110210b7016bSDavid van Moolenbroek   if (cpf_revoke(grant_id) == GRANT_FAULTED) return(ERESTART);
1103433d6423SLionel Sambuc 
1104433d6423SLionel Sambuc   return(r);
1105433d6423SLionel Sambuc }
1106433d6423SLionel Sambuc 
1107433d6423SLionel Sambuc 
1108433d6423SLionel Sambuc /*===========================================================================*
1109433d6423SLionel Sambuc  *				req_stat	       			     *
1110433d6423SLionel Sambuc  *===========================================================================*/
req_stat(endpoint_t fs_e,ino_t inode_nr,endpoint_t proc_e,vir_bytes buf)1111433d6423SLionel Sambuc int req_stat(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
1112433d6423SLionel Sambuc 	vir_bytes buf)
1113433d6423SLionel Sambuc {
1114433d6423SLionel Sambuc 	int r;
1115433d6423SLionel Sambuc 
1116433d6423SLionel Sambuc 	r = req_stat_actual(fs_e, inode_nr, proc_e, buf, CPF_TRY);
1117433d6423SLionel Sambuc 
111810b7016bSDavid van Moolenbroek 	if (r == ERESTART) {
1119433d6423SLionel Sambuc 		if((r=vm_vfs_procctl_handlemem(proc_e, (vir_bytes) buf,
1120433d6423SLionel Sambuc 			sizeof(struct stat), 1)) != OK) {
1121433d6423SLionel Sambuc 			return r;
1122433d6423SLionel Sambuc 		}
1123433d6423SLionel Sambuc 
1124433d6423SLionel Sambuc 		r = req_stat_actual(fs_e, inode_nr, proc_e, buf, 0);
1125433d6423SLionel Sambuc 	}
1126433d6423SLionel Sambuc 
1127433d6423SLionel Sambuc 	return r;
1128433d6423SLionel Sambuc }
1129433d6423SLionel Sambuc 
1130433d6423SLionel Sambuc /*===========================================================================*
1131433d6423SLionel Sambuc  *				req_sync	       			     *
1132433d6423SLionel Sambuc  *===========================================================================*/
1133*a0814afbSRichard Sailer int
req_sync(endpoint_t fs_e)1134*a0814afbSRichard Sailer req_sync(endpoint_t fs_e)
1135433d6423SLionel Sambuc {
1136433d6423SLionel Sambuc   message m;
1137433d6423SLionel Sambuc 
1138433d6423SLionel Sambuc   /* Fill in request message */
1139433d6423SLionel Sambuc   m.m_type = REQ_SYNC;
1140433d6423SLionel Sambuc 
1141433d6423SLionel Sambuc   /* Send/rec request */
1142433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
1143433d6423SLionel Sambuc }
1144433d6423SLionel Sambuc 
1145433d6423SLionel Sambuc 
1146433d6423SLionel Sambuc /*===========================================================================*
1147433d6423SLionel Sambuc  *				req_unlink	     			     *
1148433d6423SLionel Sambuc  *===========================================================================*/
1149*a0814afbSRichard Sailer int
req_unlink(endpoint_t fs_e,ino_t inode_nr,char * lastc)1150*a0814afbSRichard Sailer req_unlink(endpoint_t fs_e, ino_t inode_nr, char *lastc)
1151433d6423SLionel Sambuc {
1152433d6423SLionel Sambuc   cp_grant_id_t grant_id;
1153433d6423SLionel Sambuc   size_t len;
1154433d6423SLionel Sambuc   int r;
1155433d6423SLionel Sambuc   message m;
1156433d6423SLionel Sambuc 
1157433d6423SLionel Sambuc   len = strlen(lastc) + 1;
1158433d6423SLionel Sambuc   grant_id = cpf_grant_direct(fs_e, (vir_bytes) lastc, len, CPF_READ);
1159433d6423SLionel Sambuc   if(grant_id == -1)
1160433d6423SLionel Sambuc 	  panic("req_unlink: cpf_grant_direct failed");
1161433d6423SLionel Sambuc 
1162433d6423SLionel Sambuc   /* Fill in request message */
1163433d6423SLionel Sambuc   m.m_type = REQ_UNLINK;
1164433d6423SLionel Sambuc   m.m_vfs_fs_unlink.inode = inode_nr;
1165433d6423SLionel Sambuc   m.m_vfs_fs_unlink.grant = grant_id;
1166433d6423SLionel Sambuc   m.m_vfs_fs_unlink.path_len = len;
1167433d6423SLionel Sambuc 
1168433d6423SLionel Sambuc   /* Send/rec request */
1169433d6423SLionel Sambuc   r = fs_sendrec(fs_e, &m);
1170433d6423SLionel Sambuc   cpf_revoke(grant_id);
1171433d6423SLionel Sambuc 
1172433d6423SLionel Sambuc   return(r);
1173433d6423SLionel Sambuc }
1174433d6423SLionel Sambuc 
1175433d6423SLionel Sambuc 
1176433d6423SLionel Sambuc /*===========================================================================*
1177433d6423SLionel Sambuc  *				req_unmount	    			     *
1178433d6423SLionel Sambuc  *===========================================================================*/
1179*a0814afbSRichard Sailer int
req_unmount(endpoint_t fs_e)1180*a0814afbSRichard Sailer req_unmount(endpoint_t fs_e)
1181433d6423SLionel Sambuc {
1182433d6423SLionel Sambuc   message m;
1183433d6423SLionel Sambuc 
1184433d6423SLionel Sambuc   /* Fill in request message */
1185433d6423SLionel Sambuc   m.m_type = REQ_UNMOUNT;
1186433d6423SLionel Sambuc 
1187433d6423SLionel Sambuc   /* Send/rec request */
1188433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
1189433d6423SLionel Sambuc }
1190433d6423SLionel Sambuc 
1191433d6423SLionel Sambuc 
1192433d6423SLionel Sambuc /*===========================================================================*
1193433d6423SLionel Sambuc  *				req_utime	      			     *
1194433d6423SLionel Sambuc  *===========================================================================*/
req_utime(endpoint_t fs_e,ino_t inode_nr,struct timespec * actimespec,struct timespec * modtimespec)1195433d6423SLionel Sambuc int req_utime(endpoint_t fs_e, ino_t inode_nr, struct timespec * actimespec,
1196433d6423SLionel Sambuc 	struct timespec * modtimespec)
1197433d6423SLionel Sambuc {
1198433d6423SLionel Sambuc   message m;
1199433d6423SLionel Sambuc 
1200433d6423SLionel Sambuc   assert(actimespec != NULL);
1201433d6423SLionel Sambuc   assert(modtimespec != NULL);
1202433d6423SLionel Sambuc 
1203433d6423SLionel Sambuc   /* Fill in request message */
1204433d6423SLionel Sambuc   m.m_type = REQ_UTIME;
1205433d6423SLionel Sambuc   m.m_vfs_fs_utime.inode = inode_nr;
1206433d6423SLionel Sambuc   m.m_vfs_fs_utime.actime = actimespec->tv_sec;
1207433d6423SLionel Sambuc   m.m_vfs_fs_utime.modtime = modtimespec->tv_sec;
1208433d6423SLionel Sambuc   m.m_vfs_fs_utime.acnsec = actimespec->tv_nsec;
1209433d6423SLionel Sambuc   m.m_vfs_fs_utime.modnsec = modtimespec->tv_nsec;
1210433d6423SLionel Sambuc 
1211433d6423SLionel Sambuc   /* Send/rec request */
1212433d6423SLionel Sambuc   return fs_sendrec(fs_e, &m);
1213433d6423SLionel Sambuc }
1214