coda_venus.c revision 1.2 1 /* $NetBSD: coda_venus.c,v 1.2 1998/09/08 17:12:47 rvb 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 * @(#) cfs/cfs_venus.c,v 1.1.1.1 1998/08/29 21:26:45 rvb Exp $
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/proc.h>
38 #include <sys/select.h>
39 #include <sys/ioctl.h>
40 /* for CNV_OFLAGS below */
41 #include <sys/fcntl.h>
42
43 #include <cfs/coda.h>
44 #include <cfs/cnode.h>
45 #include <cfs/cfs_venus.h>
46 #include <cfs/pioctl.h>
47
48 #define DECL_NO_IN(name) \
49 struct cfs_in_hdr *inp; \
50 struct name ## _out *outp; \
51 int name ## _size = sizeof (struct cfs_in_hdr); \
52 int Isize = sizeof (struct cfs_in_hdr); \
53 int Osize = sizeof (struct name ## _out); \
54 int error
55
56 #define DECL(name) \
57 struct name ## _in *inp; \
58 struct name ## _out *outp; \
59 int name ## _size = sizeof (struct name ## _in); \
60 int Isize = sizeof (struct name ## _in); \
61 int Osize = sizeof (struct name ## _out); \
62 int error
63
64 #define DECL_NO_OUT(name) \
65 struct name ## _in *inp; \
66 struct cfs_out_hdr *outp; \
67 int name ## _size = sizeof (struct name ## _in); \
68 int Isize = sizeof (struct name ## _in); \
69 int Osize = sizeof (struct cfs_out_hdr); \
70 int error
71
72 #define ALLOC_NO_IN(name) \
73 if (Osize > name ## _size) \
74 name ## _size = Osize; \
75 CFS_ALLOC(inp, struct cfs_in_hdr *, name ## _size);\
76 outp = (struct name ## _out *) inp
77
78 #define ALLOC(name) \
79 if (Osize > name ## _size) \
80 name ## _size = Osize; \
81 CFS_ALLOC(inp, struct name ## _in *, name ## _size);\
82 outp = (struct name ## _out *) inp
83
84 #define ALLOC_NO_OUT(name) \
85 if (Osize > name ## _size) \
86 name ## _size = Osize; \
87 CFS_ALLOC(inp, struct name ## _in *, name ## _size);\
88 outp = (struct cfs_out_hdr *) inp
89
90 #define STRCPY(struc, name, len) \
91 bcopy(name, (char *)inp + (int)inp->struc, len); \
92 ((char*)inp + (int)inp->struc)[len++] = 0; \
93 Isize += len
94
95 #define INIT_IN(in, op, ident, p) \
96 (in)->opcode = (op); \
97 (in)->pid = p ? p->p_pid : -1; \
98 (in)->pgid = p ? p->p_pgid : -1; \
99 (in)->sid = (p && p->p_session && p->p_session->s_leader) ? (p->p_session->s_leader->p_pid) : -1; \
100 if (ident != NOCRED) { \
101 (in)->cred.cr_uid = ident->cr_uid; \
102 (in)->cred.cr_groupid = ident->cr_gid; \
103 } else { \
104 bzero(&((in)->cred),sizeof(struct coda_cred)); \
105 (in)->cred.cr_uid = -1; \
106 (in)->cred.cr_groupid = -1; \
107 } \
108
109 #define CNV_OFLAG(to, from) \
110 do { \
111 to = 0; \
112 if (from & FREAD) to |= C_O_READ; \
113 if (from & FWRITE) to |= C_O_WRITE; \
114 if (from & O_TRUNC) to |= C_O_TRUNC; \
115 if (from & O_EXCL) to |= C_O_EXCL; \
116 } while (0)
117
118 #define CNV_VV2V_ATTR(top, fromp) \
119 do { \
120 (top)->va_type = (fromp)->va_type; \
121 (top)->va_mode = (fromp)->va_mode; \
122 (top)->va_nlink = (fromp)->va_nlink; \
123 (top)->va_uid = (fromp)->va_uid; \
124 (top)->va_gid = (fromp)->va_gid; \
125 (top)->va_fsid = VNOVAL; \
126 (top)->va_fileid = (fromp)->va_fileid; \
127 (top)->va_size = (fromp)->va_size; \
128 (top)->va_blocksize = (fromp)->va_blocksize; \
129 (top)->va_atime = (fromp)->va_atime; \
130 (top)->va_mtime = (fromp)->va_mtime; \
131 (top)->va_ctime = (fromp)->va_ctime; \
132 (top)->va_gen = (fromp)->va_gen; \
133 (top)->va_flags = (fromp)->va_flags; \
134 (top)->va_rdev = (fromp)->va_rdev; \
135 (top)->va_bytes = (fromp)->va_bytes; \
136 (top)->va_filerev = (fromp)->va_filerev; \
137 (top)->va_vaflags = VNOVAL; \
138 (top)->va_spare = VNOVAL; \
139 } while (0)
140
141 #define CNV_V2VV_ATTR(top, fromp) \
142 do { \
143 (top)->va_type = (fromp)->va_type; \
144 (top)->va_mode = (fromp)->va_mode; \
145 (top)->va_nlink = (fromp)->va_nlink; \
146 (top)->va_uid = (fromp)->va_uid; \
147 (top)->va_gid = (fromp)->va_gid; \
148 (top)->va_fileid = (fromp)->va_fileid; \
149 (top)->va_size = (fromp)->va_size; \
150 (top)->va_blocksize = (fromp)->va_blocksize; \
151 (top)->va_atime = (fromp)->va_atime; \
152 (top)->va_mtime = (fromp)->va_mtime; \
153 (top)->va_ctime = (fromp)->va_ctime; \
154 (top)->va_gen = (fromp)->va_gen; \
155 (top)->va_flags = (fromp)->va_flags; \
156 (top)->va_rdev = (fromp)->va_rdev; \
157 (top)->va_bytes = (fromp)->va_bytes; \
158 (top)->va_filerev = (fromp)->va_filerev; \
159 } while (0)
160
161
162 int
163 venus_root(void *mdp,
164 struct ucred *cred, struct proc *p,
165 /*out*/ ViceFid *VFid)
166 {
167 DECL_NO_IN(cfs_root); /* sets Isize & Osize */
168 ALLOC_NO_IN(cfs_root); /* sets inp & outp */
169
170 /* send the open to venus. */
171 INIT_IN(inp, CFS_ROOT, cred, p);
172
173 error = cfscall(mdp, Isize, &Osize, (char *)inp);
174 if (!error)
175 *VFid = outp->VFid;
176
177 CFS_FREE(inp, cfs_root_size);
178 return error;
179 }
180
181 int
182 venus_open(void *mdp, ViceFid *fid, int flag,
183 struct ucred *cred, struct proc *p,
184 /*out*/ dev_t *dev, ino_t *inode)
185 {
186 int cflag;
187 DECL(cfs_open); /* sets Isize & Osize */
188 ALLOC(cfs_open); /* sets inp & outp */
189
190 /* send the open to venus. */
191 INIT_IN(&inp->ih, CFS_OPEN, cred, p);
192 inp->VFid = *fid;
193 CNV_OFLAG(cflag, flag);
194 inp->flags = cflag;
195
196 error = cfscall(mdp, Isize, &Osize, (char *)inp);
197 if (!error) {
198 *dev = outp->dev;
199 *inode = outp->inode;
200 }
201
202 CFS_FREE(inp, cfs_open_size);
203 return error;
204 }
205
206 int
207 venus_close(void *mdp, ViceFid *fid, int flag,
208 struct ucred *cred, struct proc *p)
209 {
210 int cflag;
211 DECL_NO_OUT(cfs_close); /* sets Isize & Osize */
212 ALLOC_NO_OUT(cfs_close); /* sets inp & outp */
213
214 INIT_IN(&inp->ih, CFS_CLOSE, cred, p);
215 inp->VFid = *fid;
216 CNV_OFLAG(cflag, flag);
217 inp->flags = cflag;
218
219 error = cfscall(mdp, Isize, &Osize, (char *)inp);
220
221 CFS_FREE(inp, cfs_close_size);
222 return error;
223 }
224
225 /*
226 * these two calls will not exist!!! the container file is read/written
227 * directly.
228 */
229 void
230 venus_read(void)
231 {
232 }
233
234 void
235 venus_write(void)
236 {
237 }
238
239 /*
240 * this is a bit sad too. the ioctl's are for the control file, not for
241 * normal files.
242 */
243 int
244 venus_ioctl(void *mdp, ViceFid *fid,
245 int com, int flag, caddr_t data,
246 struct ucred *cred, struct proc *p)
247 {
248 DECL(cfs_ioctl); /* sets Isize & Osize */
249 struct PioctlData *iap = (struct PioctlData *)data;
250 int tmp;
251
252 cfs_ioctl_size = VC_MAXMSGSIZE;
253 ALLOC(cfs_ioctl); /* sets inp & outp */
254
255 INIT_IN(&inp->ih, CFS_IOCTL, cred, p);
256 inp->VFid = *fid;
257
258 /* command was mutated by increasing its size field to reflect the
259 * path and follow args. we need to subtract that out before sending
260 * the command to venus.
261 */
262 inp->cmd = (com & ~(IOCPARM_MASK << 16));
263 tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int);
264 inp->cmd |= (tmp & IOCPARM_MASK) << 16;
265
266 inp->rwflag = flag;
267 inp->len = iap->vi.in_size;
268 inp->data = (char *)(sizeof (struct cfs_ioctl_in));
269
270 error = copyin(iap->vi.in, (char*)inp + (int)inp->data,
271 iap->vi.in_size);
272 if (error) {
273 CFS_FREE(inp, cfs_ioctl_size);
274 return(error);
275 }
276
277 Osize = VC_MAXMSGSIZE;
278 error = cfscall(mdp, Isize + iap->vi.in_size, &Osize, (char *)inp);
279
280 /* copy out the out buffer. */
281 if (!error) {
282 if (outp->len > iap->vi.out_size) {
283 error = EINVAL;
284 } else {
285 error = copyout((char *)outp + (int)outp->data,
286 iap->vi.out, iap->vi.out_size);
287 }
288 }
289
290 CFS_FREE(inp, cfs_ioctl_size);
291 return error;
292 }
293
294 int
295 venus_getattr(void *mdp, ViceFid *fid,
296 struct ucred *cred, struct proc *p,
297 /*out*/ struct vattr *vap)
298 {
299 DECL(cfs_getattr); /* sets Isize & Osize */
300 ALLOC(cfs_getattr); /* sets inp & outp */
301
302 /* send the open to venus. */
303 INIT_IN(&inp->ih, CFS_GETATTR, cred, p);
304 inp->VFid = *fid;
305
306 error = cfscall(mdp, Isize, &Osize, (char *)inp);
307 if (!error) {
308 CNV_VV2V_ATTR(vap, &outp->attr);
309 }
310
311 CFS_FREE(inp, cfs_getattr_size);
312 return error;
313 }
314
315 int
316 venus_setattr(void *mdp, ViceFid *fid, struct vattr *vap,
317 struct ucred *cred, struct proc *p)
318 {
319 DECL_NO_OUT(cfs_setattr); /* sets Isize & Osize */
320 ALLOC_NO_OUT(cfs_setattr); /* sets inp & outp */
321
322 /* send the open to venus. */
323 INIT_IN(&inp->ih, CFS_SETATTR, cred, p);
324 inp->VFid = *fid;
325 CNV_V2VV_ATTR(&inp->attr, vap);
326
327 error = cfscall(mdp, Isize, &Osize, (char *)inp);
328
329 CFS_FREE(inp, cfs_setattr_size);
330 return error;
331 }
332
333 int
334 venus_access(void *mdp, ViceFid *fid, int mode,
335 struct ucred *cred, struct proc *p)
336 {
337 DECL_NO_OUT(cfs_access); /* sets Isize & Osize */
338 ALLOC_NO_OUT(cfs_access); /* sets inp & outp */
339
340 /* send the open to venus. */
341 INIT_IN(&inp->ih, CFS_ACCESS, cred, p);
342 inp->VFid = *fid;
343 inp->flags = mode;
344
345 error = cfscall(mdp, Isize, &Osize, (char *)inp);
346
347 CFS_FREE(inp, cfs_access_size);
348 return error;
349 }
350
351 int
352 venus_readlink(void *mdp, ViceFid *fid,
353 struct ucred *cred, struct proc *p,
354 /*out*/ char **str, int *len)
355 {
356 DECL(cfs_readlink); /* sets Isize & Osize */
357 cfs_readlink_size += CFS_MAXPATHLEN;
358 ALLOC(cfs_readlink); /* sets inp & outp */
359
360 /* send the open to venus. */
361 INIT_IN(&inp->ih, CFS_READLINK, cred, p);
362 inp->VFid = *fid;
363
364 Osize += CFS_MAXPATHLEN;
365 error = cfscall(mdp, Isize, &Osize, (char *)inp);
366 if (!error) {
367 CFS_ALLOC(*str, char *, outp->count);
368 *len = outp->count;
369 bcopy((char *)outp + (int)outp->data, *str, *len);
370 }
371
372 CFS_FREE(inp, cfs_readlink_size);
373 return error;
374 }
375
376 int
377 venus_fsync(void *mdp, ViceFid *fid,
378 struct ucred *cred, struct proc *p)
379 {
380 DECL_NO_OUT(cfs_fsync); /* sets Isize & Osize */
381 ALLOC_NO_OUT(cfs_fsync); /* sets inp & outp */
382
383 /* send the open to venus. */
384 INIT_IN(&inp->ih, CFS_FSYNC, cred, p);
385 inp->VFid = *fid;
386
387 error = cfscall(mdp, Isize, &Osize, (char *)inp);
388
389 CFS_FREE(inp, cfs_fsync_size);
390 return error;
391 }
392
393 int
394 venus_lookup(void *mdp, ViceFid *fid,
395 const char *nm, int len,
396 struct ucred *cred, struct proc *p,
397 /*out*/ ViceFid *VFid, int *vtype)
398 {
399 DECL(cfs_lookup); /* sets Isize & Osize */
400 cfs_lookup_size += len + 1;
401 ALLOC(cfs_lookup); /* sets inp & outp */
402
403 /* send the open to venus. */
404 INIT_IN(&inp->ih, CFS_LOOKUP, cred, p);
405 inp->VFid = *fid;
406
407 inp->name = Isize;
408 STRCPY(name, nm, len); /* increments Isize */
409
410 error = cfscall(mdp, Isize, &Osize, (char *)inp);
411 if (!error) {
412 *VFid = outp->VFid;
413 *vtype = outp->vtype;
414 }
415
416 CFS_FREE(inp, cfs_lookup_size);
417 return error;
418 }
419
420 int
421 venus_create(void *mdp, ViceFid *fid,
422 const char *nm, int len, int exclusive, int mode, struct vattr *va,
423 struct ucred *cred, struct proc *p,
424 /*out*/ ViceFid *VFid, struct vattr *attr)
425 {
426 DECL(cfs_create); /* sets Isize & Osize */
427 cfs_create_size += len + 1;
428 ALLOC(cfs_create); /* sets inp & outp */
429
430 /* send the open to venus. */
431 INIT_IN(&inp->ih, CFS_CREATE, cred, p);
432 inp->VFid = *fid;
433 inp->excl = exclusive ? C_O_EXCL : 0;
434 inp->mode = mode<<6;
435 CNV_V2VV_ATTR(&inp->attr, va);
436
437 inp->name = Isize;
438 STRCPY(name, nm, len); /* increments Isize */
439
440 error = cfscall(mdp, Isize, &Osize, (char *)inp);
441 if (!error) {
442 *VFid = outp->VFid;
443 CNV_VV2V_ATTR(attr, &outp->attr);
444 }
445
446 CFS_FREE(inp, cfs_create_size);
447 return error;
448 }
449
450 int
451 venus_remove(void *mdp, ViceFid *fid,
452 const char *nm, int len,
453 struct ucred *cred, struct proc *p)
454 {
455 DECL_NO_OUT(cfs_remove); /* sets Isize & Osize */
456 cfs_remove_size += len + 1;
457 ALLOC_NO_OUT(cfs_remove); /* sets inp & outp */
458
459 /* send the open to venus. */
460 INIT_IN(&inp->ih, CFS_REMOVE, cred, p);
461 inp->VFid = *fid;
462
463 inp->name = Isize;
464 STRCPY(name, nm, len); /* increments Isize */
465
466 error = cfscall(mdp, Isize, &Osize, (char *)inp);
467
468 CFS_FREE(inp, cfs_remove_size);
469 return error;
470 }
471
472 int
473 venus_link(void *mdp, ViceFid *fid, ViceFid *tfid,
474 const char *nm, int len,
475 struct ucred *cred, struct proc *p)
476 {
477 DECL_NO_OUT(cfs_link); /* sets Isize & Osize */
478 cfs_link_size += len + 1;
479 ALLOC_NO_OUT(cfs_link); /* sets inp & outp */
480
481 /* send the open to venus. */
482 INIT_IN(&inp->ih, CFS_LINK, cred, p);
483 inp->sourceFid = *fid;
484 inp->destFid = *tfid;
485
486 inp->tname = Isize;
487 STRCPY(tname, nm, len); /* increments Isize */
488
489 error = cfscall(mdp, Isize, &Osize, (char *)inp);
490
491 CFS_FREE(inp, cfs_link_size);
492 return error;
493 }
494
495 int
496 venus_rename(void *mdp, ViceFid *fid, ViceFid *tfid,
497 const char *nm, int len, const char *tnm, int tlen,
498 struct ucred *cred, struct proc *p)
499 {
500 DECL_NO_OUT(cfs_rename); /* sets Isize & Osize */
501 cfs_rename_size += len + 1 + tlen + 1;
502 ALLOC_NO_OUT(cfs_rename); /* sets inp & outp */
503
504 /* send the open to venus. */
505 INIT_IN(&inp->ih, CFS_RENAME, cred, p);
506 inp->sourceFid = *fid;
507 inp->destFid = *tfid;
508
509 inp->srcname = Isize;
510 STRCPY(srcname, nm, len); /* increments Isize */
511
512 inp->destname = Isize;
513 STRCPY(destname, tnm, tlen); /* increments Isize */
514
515 error = cfscall(mdp, Isize, &Osize, (char *)inp);
516
517 CFS_FREE(inp, cfs_rename_size);
518 return error;
519 }
520
521 int
522 venus_mkdir(void *mdp, ViceFid *fid,
523 const char *nm, int len, struct vattr *va,
524 struct ucred *cred, struct proc *p,
525 /*out*/ ViceFid *VFid, struct vattr *ova)
526 {
527 DECL(cfs_mkdir); /* sets Isize & Osize */
528 cfs_mkdir_size += len + 1;
529 ALLOC(cfs_mkdir); /* sets inp & outp */
530
531 /* send the open to venus. */
532 INIT_IN(&inp->ih, CFS_MKDIR, cred, p);
533 inp->VFid = *fid;
534 CNV_V2VV_ATTR(&inp->attr, va);
535
536 inp->name = Isize;
537 STRCPY(name, nm, len); /* increments Isize */
538
539 error = cfscall(mdp, Isize, &Osize, (char *)inp);
540 if (!error) {
541 *VFid = outp->VFid;
542 CNV_VV2V_ATTR(ova, &outp->attr);
543 }
544
545 CFS_FREE(inp, cfs_mkdir_size);
546 return error;
547 }
548
549 int
550 venus_rmdir(void *mdp, ViceFid *fid,
551 const char *nm, int len,
552 struct ucred *cred, struct proc *p)
553 {
554 DECL_NO_OUT(cfs_rmdir); /* sets Isize & Osize */
555 cfs_rmdir_size += len + 1;
556 ALLOC_NO_OUT(cfs_rmdir); /* sets inp & outp */
557
558 /* send the open to venus. */
559 INIT_IN(&inp->ih, CFS_RMDIR, cred, p);
560 inp->VFid = *fid;
561
562 inp->name = Isize;
563 STRCPY(name, nm, len); /* increments Isize */
564
565 error = cfscall(mdp, Isize, &Osize, (char *)inp);
566
567 CFS_FREE(inp, cfs_rmdir_size);
568 return error;
569 }
570
571 int
572 venus_symlink(void *mdp, ViceFid *fid,
573 const char *lnm, int llen, const char *nm, int len, struct vattr *va,
574 struct ucred *cred, struct proc *p)
575 {
576 DECL_NO_OUT(cfs_symlink); /* sets Isize & Osize */
577 cfs_symlink_size += llen + 1 + len + 1;
578 ALLOC_NO_OUT(cfs_symlink); /* sets inp & outp */
579
580 /* send the open to venus. */
581 INIT_IN(&inp->ih, CFS_SYMLINK, cred, p);
582 inp->VFid = *fid;
583 CNV_V2VV_ATTR(&inp->attr, va);
584
585 inp->srcname = Isize;
586 STRCPY(srcname, lnm, llen); /* increments Isize */
587
588 inp->tname = Isize;
589 STRCPY(tname, nm, len); /* increments Isize */
590
591 error = cfscall(mdp, Isize, &Osize, (char *)inp);
592
593 CFS_FREE(inp, cfs_symlink_size);
594 return error;
595 }
596
597 int
598 venus_readdir(void *mdp, ViceFid *fid,
599 int count, int offset,
600 struct ucred *cred, struct proc *p,
601 /*out*/ char *buffer, int *len)
602 {
603 DECL(cfs_readdir); /* sets Isize & Osize */
604 cfs_readdir_size = VC_MAXMSGSIZE;
605 ALLOC(cfs_readdir); /* sets inp & outp */
606
607 /* send the open to venus. */
608 INIT_IN(&inp->ih, CFS_READDIR, cred, p);
609 inp->VFid = *fid;
610 inp->count = count;
611 inp->offset = offset;
612
613 Osize = VC_MAXMSGSIZE;
614 error = cfscall(mdp, Isize, &Osize, (char *)inp);
615 if (!error) {
616 bcopy((char *)outp + (int)outp->data, buffer, outp->size);
617 *len = outp->size;
618 }
619
620 CFS_FREE(inp, cfs_readdir_size);
621 return error;
622 }
623
624 int
625 venus_fhtovp(void *mdp, ViceFid *fid,
626 struct ucred *cred, struct proc *p,
627 /*out*/ ViceFid *VFid, int *vtype)
628 {
629 DECL(cfs_vget); /* sets Isize & Osize */
630 ALLOC(cfs_vget); /* sets inp & outp */
631
632 /* Send the open to Venus. */
633 INIT_IN(&inp->ih, CFS_VGET, cred, p);
634 inp->VFid = *fid;
635
636 error = cfscall(mdp, Isize, &Osize, (char *)inp);
637 if (!error) {
638 *VFid = outp->VFid;
639 *vtype = outp->vtype;
640 }
641
642 CFS_FREE(inp, cfs_vget_size);
643 return error;
644 }
645