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