coda_venus.c revision 1.20 1 /* $NetBSD: coda_venus.c,v 1.20 2006/03/15 14:30:56 gdt Exp $ */
2
3 /*
4 *
5 * Coda: an Experimental Distributed File System
6 * Release 3.1
7 *
8 * Copyright (c) 1987-1998 Carnegie Mellon University
9 * All Rights Reserved
10 *
11 * Permission to use, copy, modify and distribute this software and its
12 * documentation is hereby granted, provided that both the copyright
13 * notice and this permission notice appear in all copies of the
14 * software, derivative works or modified versions, and any portions
15 * thereof, and that both notices appear in supporting documentation, and
16 * that credit is given to Carnegie Mellon University in all documents
17 * and publicity pertaining to direct or indirect use of this code or its
18 * derivatives.
19 *
20 * CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
21 * SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
22 * FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
23 * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
24 * RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
25 * ANY DERIVATIVE WORK.
26 *
27 * Carnegie Mellon encourages users of this software to return any
28 * improvements or extensions that they make, and to grant Carnegie
29 * Mellon the rights to redistribute these changes without encumbrance.
30 *
31 * @(#) coda/coda_venus.c,v 1.1.1.1 1998/08/29 21:26:45 rvb Exp $
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: coda_venus.c,v 1.20 2006/03/15 14:30:56 gdt Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 #include <sys/proc.h>
41 #include <sys/select.h>
42 #include <sys/ioctl.h>
43 /* for CNV_OFLAGS below */
44 #include <sys/fcntl.h>
45
46 #include <coda/coda.h>
47 #include <coda/cnode.h>
48 #include <coda/coda_venus.h>
49 #include <coda/coda_pioctl.h>
50
51 #ifdef _KERNEL_OPT
52 #include "opt_coda_compat.h"
53 #endif
54
55 /*
56 * Isize and Osize are the sizes of the input and output arguments.
57 * SEMI-INVARIANT: name##_size (e.g. coda_readlink_size) is the max of
58 * the input and output. This invariant is not well maintained, but
59 * should be true after ALLOC_*. Isize is modified after allocation
60 * by STRCPY below - this is in general unsafe and needs fixing.
61 */
62
63 #define DECL_NO_IN(name) \
64 struct coda_in_hdr *inp; \
65 struct name ## _out *outp; \
66 int name ## _size = sizeof (struct coda_in_hdr); \
67 int Isize = sizeof (struct coda_in_hdr); \
68 int Osize = sizeof (struct name ## _out); \
69 int error
70
71 #define DECL(name) \
72 struct name ## _in *inp; \
73 struct name ## _out *outp; \
74 int name ## _size = sizeof (struct name ## _in); \
75 int Isize = sizeof (struct name ## _in); \
76 int Osize = sizeof (struct name ## _out); \
77 int error
78
79 #define DECL_NO_OUT(name) \
80 struct name ## _in *inp; \
81 struct coda_out_hdr *outp; \
82 int name ## _size = sizeof (struct name ## _in); \
83 int Isize = sizeof (struct name ## _in); \
84 int Osize = sizeof (struct coda_out_hdr); \
85 int error
86
87 #define ALLOC_NO_IN(name) \
88 if (Osize > name ## _size) \
89 name ## _size = Osize; \
90 CODA_ALLOC(inp, struct coda_in_hdr *, name ## _size);\
91 outp = (struct name ## _out *) inp
92
93 #define ALLOC(name) \
94 if (Osize > name ## _size) \
95 name ## _size = Osize; \
96 CODA_ALLOC(inp, struct name ## _in *, name ## _size);\
97 outp = (struct name ## _out *) inp
98
99 #define ALLOC_NO_OUT(name) \
100 if (Osize > name ## _size) \
101 name ## _size = Osize; \
102 CODA_ALLOC(inp, struct name ## _in *, name ## _size);\
103 outp = (struct coda_out_hdr *) inp
104
105 #define STRCPY(struc, name, len) \
106 bcopy(name, (char *)inp + (int)inp->struc, len); \
107 ((char*)inp + (int)inp->struc)[len++] = 0; \
108 Isize += len
109 /* XXX verify that Isize has not overrun available storage */
110
111 #ifdef CODA_COMPAT_5
112
113 #define INIT_IN(in, op, ident, p) \
114 (in)->opcode = (op); \
115 (in)->pid = p ? p->p_pid : -1; \
116 (in)->pgid = p ? p->p_pgid : -1; \
117 (in)->sid = (p && p->p_session && p->p_session->s_leader) ? \
118 (p->p_session->s_leader->p_pid) : -1; \
119 KASSERT(cred != NULL); \
120 KASSERT(cred != FSCRED); \
121 if (ident != NOCRED) { \
122 (in)->cred.cr_uid = ident->cr_uid; \
123 (in)->cred.cr_groupid = ident->cr_gid; \
124 } else { \
125 memset(&((in)->cred), 0, sizeof(struct coda_cred)); \
126 (in)->cred.cr_uid = -1; \
127 (in)->cred.cr_groupid = -1; \
128 } \
129
130 #else
131
132 #define INIT_IN(in, op, ident, p) \
133 (in)->opcode = (op); \
134 (in)->pid = p ? p->p_pid : -1; \
135 (in)->pgid = p ? p->p_pgid : -1; \
136 KASSERT(cred != NULL); \
137 KASSERT(cred != FSCRED); \
138 if (ident != NOCRED) { \
139 (in)->uid = ident->cr_uid; \
140 } else { \
141 (in)->uid = -1; \
142 } \
143
144 #endif
145
146 #define INIT_IN_L(in, op, ident, l) \
147 INIT_IN(in, op, ident, (l ? l->l_proc : NULL))
148
149 #define CNV_OFLAG(to, from) \
150 do { \
151 to = 0; \
152 if (from & FREAD) to |= C_O_READ; \
153 if (from & FWRITE) to |= C_O_WRITE; \
154 if (from & O_TRUNC) to |= C_O_TRUNC; \
155 if (from & O_EXCL) to |= C_O_EXCL; \
156 if (from & O_CREAT) to |= C_O_CREAT; \
157 } while (/*CONSTCOND*/ 0)
158
159 #define CNV_VV2V_ATTR(top, fromp) \
160 do { \
161 (top)->va_type = (fromp)->va_type; \
162 (top)->va_mode = (fromp)->va_mode; \
163 (top)->va_nlink = (fromp)->va_nlink; \
164 (top)->va_uid = (fromp)->va_uid; \
165 (top)->va_gid = (fromp)->va_gid; \
166 (top)->va_fsid = VNOVAL; \
167 (top)->va_fileid = (fromp)->va_fileid; \
168 (top)->va_size = (fromp)->va_size; \
169 (top)->va_blocksize = (fromp)->va_blocksize; \
170 (top)->va_atime = (fromp)->va_atime; \
171 (top)->va_mtime = (fromp)->va_mtime; \
172 (top)->va_ctime = (fromp)->va_ctime; \
173 (top)->va_gen = (fromp)->va_gen; \
174 (top)->va_flags = (fromp)->va_flags; \
175 (top)->va_rdev = (fromp)->va_rdev; \
176 (top)->va_bytes = (fromp)->va_bytes; \
177 (top)->va_filerev = (fromp)->va_filerev; \
178 (top)->va_vaflags = VNOVAL; \
179 (top)->va_spare = VNOVAL; \
180 } while (/*CONSTCOND*/ 0)
181
182 #define CNV_V2VV_ATTR(top, fromp) \
183 do { \
184 (top)->va_type = (fromp)->va_type; \
185 (top)->va_mode = (fromp)->va_mode; \
186 (top)->va_nlink = (fromp)->va_nlink; \
187 (top)->va_uid = (fromp)->va_uid; \
188 (top)->va_gid = (fromp)->va_gid; \
189 (top)->va_fileid = (fromp)->va_fileid; \
190 (top)->va_size = (fromp)->va_size; \
191 (top)->va_blocksize = (fromp)->va_blocksize; \
192 (top)->va_atime = (fromp)->va_atime; \
193 (top)->va_mtime = (fromp)->va_mtime; \
194 (top)->va_ctime = (fromp)->va_ctime; \
195 (top)->va_gen = (fromp)->va_gen; \
196 (top)->va_flags = (fromp)->va_flags; \
197 (top)->va_rdev = (fromp)->va_rdev; \
198 (top)->va_bytes = (fromp)->va_bytes; \
199 (top)->va_filerev = (fromp)->va_filerev; \
200 } while (/*CONSTCOND*/ 0)
201
202
203 int coda_kernel_version = CODA_KERNEL_VERSION;
204
205 int
206 venus_root(void *mdp,
207 struct ucred *cred, struct proc *p,
208 /*out*/ CodaFid *VFid)
209 {
210 DECL_NO_IN(coda_root); /* sets Isize & Osize */
211 ALLOC_NO_IN(coda_root); /* sets inp & outp */
212
213 /* send the open to venus. */
214 INIT_IN(inp, CODA_ROOT, cred, p);
215
216 error = coda_call(mdp, Isize, &Osize, (char *)inp);
217 if (!error)
218 *VFid = outp->Fid;
219
220 CODA_FREE(inp, coda_root_size);
221 return error;
222 }
223
224 int
225 venus_open(void *mdp, CodaFid *fid, int flag,
226 struct ucred *cred, struct lwp *l,
227 /*out*/ dev_t *dev, ino_t *inode)
228 {
229 int cflag;
230 DECL(coda_open); /* sets Isize & Osize */
231 ALLOC(coda_open); /* sets inp & outp */
232
233 /* send the open to venus. */
234 INIT_IN_L(&inp->ih, CODA_OPEN, cred, l);
235 inp->Fid = *fid;
236 CNV_OFLAG(cflag, flag);
237 inp->flags = cflag;
238
239 error = coda_call(mdp, Isize, &Osize, (char *)inp);
240 KASSERT(outp != NULL);
241 if (!error) {
242 *dev = outp->dev;
243 *inode = outp->inode;
244 }
245
246 CODA_FREE(inp, coda_open_size);
247 return error;
248 }
249
250 int
251 venus_close(void *mdp, CodaFid *fid, int flag,
252 struct ucred *cred, struct lwp *l)
253 {
254 int cflag;
255 DECL_NO_OUT(coda_close); /* sets Isize & Osize */
256 ALLOC_NO_OUT(coda_close); /* sets inp & outp */
257
258 INIT_IN_L(&inp->ih, CODA_CLOSE, cred, l);
259 inp->Fid = *fid;
260 CNV_OFLAG(cflag, flag);
261 inp->flags = cflag;
262
263 error = coda_call(mdp, Isize, &Osize, (char *)inp);
264
265 CODA_FREE(inp, coda_close_size);
266 return error;
267 }
268
269 /*
270 * these two calls will not exist!!! the container file is read/written
271 * directly.
272 */
273 void
274 venus_read(void)
275 {
276 }
277
278 void
279 venus_write(void)
280 {
281 }
282
283 /*
284 * this is a bit sad too. the ioctl's are for the control file, not for
285 * normal files.
286 */
287 int
288 venus_ioctl(void *mdp, CodaFid *fid,
289 int com, int flag, caddr_t data,
290 struct ucred *cred, struct lwp *l)
291 {
292 DECL(coda_ioctl); /* sets Isize & Osize */
293 struct PioctlData *iap = (struct PioctlData *)data;
294 int tmp;
295
296 coda_ioctl_size = VC_MAXMSGSIZE;
297 ALLOC(coda_ioctl); /* sets inp & outp */
298
299 INIT_IN_L(&inp->ih, CODA_IOCTL, cred, l);
300 inp->Fid = *fid;
301
302 /* command was mutated by increasing its size field to reflect the
303 * path and follow args. we need to subtract that out before sending
304 * the command to venus.
305 */
306 inp->cmd = (com & ~(IOCPARM_MASK << 16));
307 tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int);
308 inp->cmd |= (tmp & IOCPARM_MASK) << 16;
309
310 if (iap->vi.in_size < 0 || iap->vi.in_size > VC_MAXMSGSIZE)
311 return (EINVAL);
312
313 inp->rwflag = flag;
314 inp->len = iap->vi.in_size;
315 inp->data = (char *)(sizeof (struct coda_ioctl_in));
316
317 error = copyin(iap->vi.in, (char*)inp + (int)(long)inp->data,
318 iap->vi.in_size);
319 if (error) {
320 CODA_FREE(inp, coda_ioctl_size);
321 return(error);
322 }
323
324 Osize = VC_MAXMSGSIZE;
325 error = coda_call(mdp, Isize + iap->vi.in_size, &Osize, (char *)inp);
326
327 /* copy out the out buffer. */
328 if (!error) {
329 if (outp->len > iap->vi.out_size) {
330 error = EINVAL;
331 } else {
332 error = copyout((char *)outp + (int)(long)outp->data,
333 iap->vi.out, iap->vi.out_size);
334 }
335 }
336
337 CODA_FREE(inp, coda_ioctl_size);
338 return error;
339 }
340
341 int
342 venus_getattr(void *mdp, CodaFid *fid,
343 struct ucred *cred, struct lwp *l,
344 /*out*/ struct vattr *vap)
345 {
346 DECL(coda_getattr); /* sets Isize & Osize */
347 ALLOC(coda_getattr); /* sets inp & outp */
348
349 /* send the open to venus. */
350 INIT_IN_L(&inp->ih, CODA_GETATTR, cred, l);
351 inp->Fid = *fid;
352
353 error = coda_call(mdp, Isize, &Osize, (char *)inp);
354 if (!error) {
355 CNV_VV2V_ATTR(vap, &outp->attr);
356 }
357
358 CODA_FREE(inp, coda_getattr_size);
359 return error;
360 }
361
362 int
363 venus_setattr(void *mdp, CodaFid *fid, struct vattr *vap,
364 struct ucred *cred, struct lwp *l)
365 {
366 DECL_NO_OUT(coda_setattr); /* sets Isize & Osize */
367 ALLOC_NO_OUT(coda_setattr); /* sets inp & outp */
368
369 /* send the open to venus. */
370 INIT_IN_L(&inp->ih, CODA_SETATTR, cred, l);
371 inp->Fid = *fid;
372 CNV_V2VV_ATTR(&inp->attr, vap);
373
374 error = coda_call(mdp, Isize, &Osize, (char *)inp);
375
376 CODA_FREE(inp, coda_setattr_size);
377 return error;
378 }
379
380 int
381 venus_access(void *mdp, CodaFid *fid, int mode,
382 struct ucred *cred, struct lwp *l)
383 {
384 DECL_NO_OUT(coda_access); /* sets Isize & Osize */
385 ALLOC_NO_OUT(coda_access); /* sets inp & outp */
386
387 /* send the open to venus. */
388 INIT_IN_L(&inp->ih, CODA_ACCESS, cred, l);
389 inp->Fid = *fid;
390 inp->flags = mode;
391
392 error = coda_call(mdp, Isize, &Osize, (char *)inp);
393
394 CODA_FREE(inp, coda_access_size);
395 return error;
396 }
397
398 int
399 venus_readlink(void *mdp, CodaFid *fid,
400 struct ucred *cred, struct lwp *l,
401 /*out*/ char **str, int *len)
402 {
403 DECL(coda_readlink); /* sets Isize & Osize */
404 /* XXX coda_readlink_size should not be set here */
405 coda_readlink_size += CODA_MAXPATHLEN;
406 Osize += CODA_MAXPATHLEN;
407 ALLOC(coda_readlink); /* sets inp & outp */
408
409 /* send the open to venus. */
410 INIT_IN_L(&inp->ih, CODA_READLINK, cred, l);
411 inp->Fid = *fid;
412
413 error = coda_call(mdp, Isize, &Osize, (char *)inp);
414 KASSERT(outp != NULL);
415 if (!error) {
416 CODA_ALLOC(*str, char *, outp->count);
417 *len = outp->count;
418 bcopy((char *)outp + (int)(long)outp->data, *str, *len);
419 }
420
421 CODA_FREE(inp, coda_readlink_size);
422 return error;
423 }
424
425 int
426 venus_fsync(void *mdp, CodaFid *fid,
427 struct ucred *cred, struct lwp *l)
428 {
429 DECL_NO_OUT(coda_fsync); /* sets Isize & Osize */
430 ALLOC_NO_OUT(coda_fsync); /* sets inp & outp */
431
432 /* send the open to venus. */
433 INIT_IN_L(&inp->ih, CODA_FSYNC, cred, l);
434 inp->Fid = *fid;
435
436 error = coda_call(mdp, Isize, &Osize, (char *)inp);
437
438 CODA_FREE(inp, coda_fsync_size);
439 return error;
440 }
441
442 int
443 venus_lookup(void *mdp, CodaFid *fid,
444 const char *nm, int len,
445 struct ucred *cred, struct lwp *l,
446 /*out*/ CodaFid *VFid, int *vtype)
447 {
448 DECL(coda_lookup); /* sets Isize & Osize */
449 coda_lookup_size += len + 1;
450 ALLOC(coda_lookup); /* sets inp & outp */
451
452 /* send the open to venus. */
453 INIT_IN_L(&inp->ih, CODA_LOOKUP, cred, l);
454 inp->Fid = *fid;
455
456 /* NOTE:
457 * Between version 1 and version 2 we have added an extra flag field
458 * to this structure. But because the string was at the end and because
459 * of the weird way we represent strings by having the slot point to
460 * where the string characters are in the "heap", we can just slip the
461 * flag parameter in after the string slot pointer and veni that don't
462 * know better won't see this new flag field ...
463 * Otherwise we'd need two different venus_lookup functions.
464 */
465 inp->name = Isize;
466 inp->flags = CLU_CASE_SENSITIVE; /* doesn't really matter for BSD */
467 /* This is safe because we preallocated len+1 extra. */
468 STRCPY(name, nm, len); /* increments Isize */
469
470 error = coda_call(mdp, Isize, &Osize, (char *)inp);
471 KASSERT(outp != NULL);
472 if (!error) {
473 *VFid = outp->Fid;
474 *vtype = outp->vtype;
475 }
476
477 CODA_FREE(inp, coda_lookup_size);
478 return error;
479 }
480
481 int
482 venus_create(void *mdp, CodaFid *fid,
483 const char *nm, int len, int exclusive, int mode, struct vattr *va,
484 struct ucred *cred, struct lwp *l,
485 /*out*/ CodaFid *VFid, struct vattr *attr)
486 {
487 DECL(coda_create); /* sets Isize & Osize */
488 coda_create_size += len + 1;
489 ALLOC(coda_create); /* sets inp & outp */
490
491 /* send the open to venus. */
492 INIT_IN_L(&inp->ih, CODA_CREATE, cred, l);
493 inp->Fid = *fid;
494 inp->excl = exclusive ? C_O_EXCL : 0;
495 inp->mode = mode<<6;
496 CNV_V2VV_ATTR(&inp->attr, va);
497
498 inp->name = Isize;
499 STRCPY(name, nm, len); /* increments Isize */
500
501 error = coda_call(mdp, Isize, &Osize, (char *)inp);
502 KASSERT(outp != NULL);
503 if (!error) {
504 *VFid = outp->Fid;
505 CNV_VV2V_ATTR(attr, &outp->attr);
506 }
507
508 CODA_FREE(inp, coda_create_size);
509 return error;
510 }
511
512 int
513 venus_remove(void *mdp, CodaFid *fid,
514 const char *nm, int len,
515 struct ucred *cred, struct lwp *l)
516 {
517 DECL_NO_OUT(coda_remove); /* sets Isize & Osize */
518 coda_remove_size += len + 1;
519 ALLOC_NO_OUT(coda_remove); /* sets inp & outp */
520
521 /* send the open to venus. */
522 INIT_IN_L(&inp->ih, CODA_REMOVE, cred, l);
523 inp->Fid = *fid;
524
525 inp->name = Isize;
526 STRCPY(name, nm, len); /* increments Isize */
527
528 error = coda_call(mdp, Isize, &Osize, (char *)inp);
529
530 CODA_FREE(inp, coda_remove_size);
531 return error;
532 }
533
534 int
535 venus_link(void *mdp, CodaFid *fid, CodaFid *tfid,
536 const char *nm, int len,
537 struct ucred *cred, struct lwp *l)
538 {
539 DECL_NO_OUT(coda_link); /* sets Isize & Osize */
540 coda_link_size += len + 1;
541 ALLOC_NO_OUT(coda_link); /* sets inp & outp */
542
543 /* send the open to venus. */
544 INIT_IN_L(&inp->ih, CODA_LINK, cred, l);
545 inp->sourceFid = *fid;
546 inp->destFid = *tfid;
547
548 inp->tname = Isize;
549 STRCPY(tname, nm, len); /* increments Isize */
550
551 error = coda_call(mdp, Isize, &Osize, (char *)inp);
552
553 CODA_FREE(inp, coda_link_size);
554 return error;
555 }
556
557 int
558 venus_rename(void *mdp, CodaFid *fid, CodaFid *tfid,
559 const char *nm, int len, const char *tnm, int tlen,
560 struct ucred *cred, struct lwp *l)
561 {
562 DECL_NO_OUT(coda_rename); /* sets Isize & Osize */
563 coda_rename_size += len + 1 + tlen + 1;
564 ALLOC_NO_OUT(coda_rename); /* sets inp & outp */
565
566 /* send the open to venus. */
567 INIT_IN_L(&inp->ih, CODA_RENAME, cred, l);
568 inp->sourceFid = *fid;
569 inp->destFid = *tfid;
570
571 inp->srcname = Isize;
572 STRCPY(srcname, nm, len); /* increments Isize */
573
574 inp->destname = Isize;
575 STRCPY(destname, tnm, tlen); /* increments Isize */
576
577 error = coda_call(mdp, Isize, &Osize, (char *)inp);
578
579 CODA_FREE(inp, coda_rename_size);
580 return error;
581 }
582
583 int
584 venus_mkdir(void *mdp, CodaFid *fid,
585 const char *nm, int len, struct vattr *va,
586 struct ucred *cred, struct lwp *l,
587 /*out*/ CodaFid *VFid, struct vattr *ova)
588 {
589 DECL(coda_mkdir); /* sets Isize & Osize */
590 coda_mkdir_size += len + 1;
591 ALLOC(coda_mkdir); /* sets inp & outp */
592
593 /* send the open to venus. */
594 INIT_IN_L(&inp->ih, CODA_MKDIR, cred, l);
595 inp->Fid = *fid;
596 CNV_V2VV_ATTR(&inp->attr, va);
597
598 inp->name = Isize;
599 STRCPY(name, nm, len); /* increments Isize */
600
601 error = coda_call(mdp, Isize, &Osize, (char *)inp);
602 KASSERT(outp != NULL);
603 if (!error) {
604 *VFid = outp->Fid;
605 CNV_VV2V_ATTR(ova, &outp->attr);
606 }
607
608 CODA_FREE(inp, coda_mkdir_size);
609 return error;
610 }
611
612 int
613 venus_rmdir(void *mdp, CodaFid *fid,
614 const char *nm, int len,
615 struct ucred *cred, struct lwp *l)
616 {
617 DECL_NO_OUT(coda_rmdir); /* sets Isize & Osize */
618 coda_rmdir_size += len + 1;
619 ALLOC_NO_OUT(coda_rmdir); /* sets inp & outp */
620
621 /* send the open to venus. */
622 INIT_IN_L(&inp->ih, CODA_RMDIR, cred, l);
623 inp->Fid = *fid;
624
625 inp->name = Isize;
626 STRCPY(name, nm, len); /* increments Isize */
627
628 error = coda_call(mdp, Isize, &Osize, (char *)inp);
629
630 CODA_FREE(inp, coda_rmdir_size);
631 return error;
632 }
633
634 int
635 venus_symlink(void *mdp, CodaFid *fid,
636 const char *lnm, int llen, const char *nm, int len, struct vattr *va,
637 struct ucred *cred, struct lwp *l)
638 {
639 DECL_NO_OUT(coda_symlink); /* sets Isize & Osize */
640 coda_symlink_size += llen + 1 + len + 1;
641 ALLOC_NO_OUT(coda_symlink); /* sets inp & outp */
642
643 /* send the open to venus. */
644 INIT_IN_L(&inp->ih, CODA_SYMLINK, cred, l);
645 inp->Fid = *fid;
646 CNV_V2VV_ATTR(&inp->attr, va);
647
648 inp->srcname = Isize;
649 STRCPY(srcname, lnm, llen); /* increments Isize */
650
651 inp->tname = Isize;
652 STRCPY(tname, nm, len); /* increments Isize */
653
654 error = coda_call(mdp, Isize, &Osize, (char *)inp);
655
656 CODA_FREE(inp, coda_symlink_size);
657 return error;
658 }
659
660 int
661 venus_readdir(void *mdp, CodaFid *fid,
662 int count, int offset,
663 struct ucred *cred, struct lwp *l,
664 /*out*/ char *buffer, int *len)
665 {
666 DECL(coda_readdir); /* sets Isize & Osize */
667 coda_readdir_size = VC_MAXMSGSIZE;
668 ALLOC(coda_readdir); /* sets inp & outp */
669
670 /* send the open to venus. */
671 INIT_IN_L(&inp->ih, CODA_READDIR, cred, l);
672 inp->Fid = *fid;
673 inp->count = count;
674 inp->offset = offset;
675
676 Osize = VC_MAXMSGSIZE;
677 error = coda_call(mdp, Isize, &Osize, (char *)inp);
678 KASSERT(outp != NULL);
679 if (!error) {
680 bcopy((char *)outp + (int)(long)outp->data, buffer, outp->size);
681 *len = outp->size;
682 }
683
684 CODA_FREE(inp, coda_readdir_size);
685 return error;
686 }
687
688 int
689 venus_statfs(void *mdp, struct ucred *cred, struct lwp *l,
690 /*out*/ struct coda_statfs *fsp)
691 {
692 DECL(coda_statfs); /* sets Isize & Osize */
693 ALLOC(coda_statfs); /* sets inp & outp */
694
695 /* send the open to venus. */
696 INIT_IN_L(&inp->ih, CODA_STATFS, cred, l);
697
698 error = coda_call(mdp, Isize, &Osize, (char *)inp);
699 KASSERT(outp != NULL);
700 if (!error) {
701 *fsp = outp->stat;
702 }
703
704 CODA_FREE(inp, coda_statfs_size);
705 return error;
706 }
707
708 int
709 venus_fhtovp(void *mdp, CodaFid *fid,
710 struct ucred *cred, struct proc *p,
711 /*out*/ CodaFid *VFid, int *vtype)
712 {
713 DECL(coda_vget); /* sets Isize & Osize */
714 ALLOC(coda_vget); /* sets inp & outp */
715
716 /* Send the open to Venus. */
717 INIT_IN(&inp->ih, CODA_VGET, cred, p);
718 inp->Fid = *fid;
719
720 error = coda_call(mdp, Isize, &Osize, (char *)inp);
721 KASSERT(outp != NULL);
722 if (!error) {
723 *VFid = outp->Fid;
724 *vtype = outp->vtype;
725 }
726
727 CODA_FREE(inp, coda_vget_size);
728 return error;
729 }
730