1 /* $NetBSD: coda_venus.c,v 1.13 2002/11/02 07:18:36 perry 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.13 2002/11/02 07:18:36 perry 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 #define DECL_NO_IN(name) \ 52 struct coda_in_hdr *inp; \ 53 struct name ## _out *outp; \ 54 int name ## _size = sizeof (struct coda_in_hdr); \ 55 int Isize = sizeof (struct coda_in_hdr); \ 56 int Osize = sizeof (struct name ## _out); \ 57 int error 58 59 #define DECL(name) \ 60 struct name ## _in *inp; \ 61 struct name ## _out *outp; \ 62 int name ## _size = sizeof (struct name ## _in); \ 63 int Isize = sizeof (struct name ## _in); \ 64 int Osize = sizeof (struct name ## _out); \ 65 int error 66 67 #define DECL_NO_OUT(name) \ 68 struct name ## _in *inp; \ 69 struct coda_out_hdr *outp; \ 70 int name ## _size = sizeof (struct name ## _in); \ 71 int Isize = sizeof (struct name ## _in); \ 72 int Osize = sizeof (struct coda_out_hdr); \ 73 int error 74 75 #define ALLOC_NO_IN(name) \ 76 if (Osize > name ## _size) \ 77 name ## _size = Osize; \ 78 CODA_ALLOC(inp, struct coda_in_hdr *, name ## _size);\ 79 outp = (struct name ## _out *) inp 80 81 #define ALLOC(name) \ 82 if (Osize > name ## _size) \ 83 name ## _size = Osize; \ 84 CODA_ALLOC(inp, struct name ## _in *, name ## _size);\ 85 outp = (struct name ## _out *) inp 86 87 #define ALLOC_NO_OUT(name) \ 88 if (Osize > name ## _size) \ 89 name ## _size = Osize; \ 90 CODA_ALLOC(inp, struct name ## _in *, name ## _size);\ 91 outp = (struct coda_out_hdr *) inp 92 93 #define STRCPY(struc, name, len) \ 94 bcopy(name, (char *)inp + (int)inp->struc, len); \ 95 ((char*)inp + (int)inp->struc)[len++] = 0; \ 96 Isize += len 97 98 #define INIT_IN(in, op, ident, p) \ 99 (in)->opcode = (op); \ 100 (in)->pid = p ? p->p_pid : -1; \ 101 (in)->pgid = p ? p->p_pgid : -1; \ 102 (in)->sid = (p && p->p_session && p->p_session->s_leader) ? (p->p_session->s_leader->p_pid) : -1; \ 103 if (ident != NOCRED) { \ 104 (in)->cred.cr_uid = ident->cr_uid; \ 105 (in)->cred.cr_groupid = ident->cr_gid; \ 106 } else { \ 107 memset(&((in)->cred), 0, sizeof(struct coda_cred)); \ 108 (in)->cred.cr_uid = -1; \ 109 (in)->cred.cr_groupid = -1; \ 110 } \ 111 112 #define CNV_OFLAG(to, from) \ 113 do { \ 114 to = 0; \ 115 if (from & FREAD) to |= C_O_READ; \ 116 if (from & FWRITE) to |= C_O_WRITE; \ 117 if (from & O_TRUNC) to |= C_O_TRUNC; \ 118 if (from & O_EXCL) to |= C_O_EXCL; \ 119 if (from & O_CREAT) to |= C_O_CREAT; \ 120 } while (/*CONSTCOND*/ 0) 121 122 #define CNV_VV2V_ATTR(top, fromp) \ 123 do { \ 124 (top)->va_type = (fromp)->va_type; \ 125 (top)->va_mode = (fromp)->va_mode; \ 126 (top)->va_nlink = (fromp)->va_nlink; \ 127 (top)->va_uid = (fromp)->va_uid; \ 128 (top)->va_gid = (fromp)->va_gid; \ 129 (top)->va_fsid = VNOVAL; \ 130 (top)->va_fileid = (fromp)->va_fileid; \ 131 (top)->va_size = (fromp)->va_size; \ 132 (top)->va_blocksize = (fromp)->va_blocksize; \ 133 (top)->va_atime = (fromp)->va_atime; \ 134 (top)->va_mtime = (fromp)->va_mtime; \ 135 (top)->va_ctime = (fromp)->va_ctime; \ 136 (top)->va_gen = (fromp)->va_gen; \ 137 (top)->va_flags = (fromp)->va_flags; \ 138 (top)->va_rdev = (fromp)->va_rdev; \ 139 (top)->va_bytes = (fromp)->va_bytes; \ 140 (top)->va_filerev = (fromp)->va_filerev; \ 141 (top)->va_vaflags = VNOVAL; \ 142 (top)->va_spare = VNOVAL; \ 143 } while (/*CONSTCOND*/ 0) 144 145 #define CNV_V2VV_ATTR(top, fromp) \ 146 do { \ 147 (top)->va_type = (fromp)->va_type; \ 148 (top)->va_mode = (fromp)->va_mode; \ 149 (top)->va_nlink = (fromp)->va_nlink; \ 150 (top)->va_uid = (fromp)->va_uid; \ 151 (top)->va_gid = (fromp)->va_gid; \ 152 (top)->va_fileid = (fromp)->va_fileid; \ 153 (top)->va_size = (fromp)->va_size; \ 154 (top)->va_blocksize = (fromp)->va_blocksize; \ 155 (top)->va_atime = (fromp)->va_atime; \ 156 (top)->va_mtime = (fromp)->va_mtime; \ 157 (top)->va_ctime = (fromp)->va_ctime; \ 158 (top)->va_gen = (fromp)->va_gen; \ 159 (top)->va_flags = (fromp)->va_flags; \ 160 (top)->va_rdev = (fromp)->va_rdev; \ 161 (top)->va_bytes = (fromp)->va_bytes; \ 162 (top)->va_filerev = (fromp)->va_filerev; \ 163 } while (/*CONSTCOND*/ 0) 164 165 166 int coda_kernel_version = CODA_KERNEL_VERSION; 167 168 int 169 venus_root(void *mdp, 170 struct ucred *cred, struct proc *p, 171 /*out*/ ViceFid *VFid) 172 { 173 DECL_NO_IN(coda_root); /* sets Isize & Osize */ 174 ALLOC_NO_IN(coda_root); /* sets inp & outp */ 175 176 /* send the open to venus. */ 177 INIT_IN(inp, CODA_ROOT, cred, p); 178 179 error = coda_call(mdp, Isize, &Osize, (char *)inp); 180 if (!error) 181 *VFid = outp->VFid; 182 183 CODA_FREE(inp, coda_root_size); 184 return error; 185 } 186 187 int 188 venus_open(void *mdp, ViceFid *fid, int flag, 189 struct ucred *cred, struct proc *p, 190 /*out*/ dev_t *dev, ino_t *inode) 191 { 192 int cflag; 193 DECL(coda_open); /* sets Isize & Osize */ 194 ALLOC(coda_open); /* sets inp & outp */ 195 196 /* send the open to venus. */ 197 INIT_IN(&inp->ih, CODA_OPEN, cred, p); 198 inp->VFid = *fid; 199 CNV_OFLAG(cflag, flag); 200 inp->flags = cflag; 201 202 error = coda_call(mdp, Isize, &Osize, (char *)inp); 203 if (!error) { 204 *dev = outp->dev; 205 *inode = outp->inode; 206 } 207 208 CODA_FREE(inp, coda_open_size); 209 return error; 210 } 211 212 int 213 venus_close(void *mdp, ViceFid *fid, int flag, 214 struct ucred *cred, struct proc *p) 215 { 216 int cflag; 217 DECL_NO_OUT(coda_close); /* sets Isize & Osize */ 218 ALLOC_NO_OUT(coda_close); /* sets inp & outp */ 219 220 INIT_IN(&inp->ih, CODA_CLOSE, cred, p); 221 inp->VFid = *fid; 222 CNV_OFLAG(cflag, flag); 223 inp->flags = cflag; 224 225 error = coda_call(mdp, Isize, &Osize, (char *)inp); 226 227 CODA_FREE(inp, coda_close_size); 228 return error; 229 } 230 231 /* 232 * these two calls will not exist!!! the container file is read/written 233 * directly. 234 */ 235 void 236 venus_read(void) 237 { 238 } 239 240 void 241 venus_write(void) 242 { 243 } 244 245 /* 246 * this is a bit sad too. the ioctl's are for the control file, not for 247 * normal files. 248 */ 249 int 250 venus_ioctl(void *mdp, ViceFid *fid, 251 int com, int flag, caddr_t data, 252 struct ucred *cred, struct proc *p) 253 { 254 DECL(coda_ioctl); /* sets Isize & Osize */ 255 struct PioctlData *iap = (struct PioctlData *)data; 256 int tmp; 257 258 coda_ioctl_size = VC_MAXMSGSIZE; 259 ALLOC(coda_ioctl); /* sets inp & outp */ 260 261 INIT_IN(&inp->ih, CODA_IOCTL, cred, p); 262 inp->VFid = *fid; 263 264 /* command was mutated by increasing its size field to reflect the 265 * path and follow args. we need to subtract that out before sending 266 * the command to venus. 267 */ 268 inp->cmd = (com & ~(IOCPARM_MASK << 16)); 269 tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int); 270 inp->cmd |= (tmp & IOCPARM_MASK) << 16; 271 272 if (iap->vi.in_size < 0 || iap->vi.in_size > VC_MAXMSGSIZE) 273 return (EINVAL); 274 275 inp->rwflag = flag; 276 inp->len = iap->vi.in_size; 277 inp->data = (char *)(sizeof (struct coda_ioctl_in)); 278 279 error = copyin(iap->vi.in, (char*)inp + (int)(long)inp->data, 280 iap->vi.in_size); 281 if (error) { 282 CODA_FREE(inp, coda_ioctl_size); 283 return(error); 284 } 285 286 Osize = VC_MAXMSGSIZE; 287 error = coda_call(mdp, Isize + iap->vi.in_size, &Osize, (char *)inp); 288 289 /* copy out the out buffer. */ 290 if (!error) { 291 if (outp->len > iap->vi.out_size) { 292 error = EINVAL; 293 } else { 294 error = copyout((char *)outp + (int)(long)outp->data, 295 iap->vi.out, iap->vi.out_size); 296 } 297 } 298 299 CODA_FREE(inp, coda_ioctl_size); 300 return error; 301 } 302 303 int 304 venus_getattr(void *mdp, ViceFid *fid, 305 struct ucred *cred, struct proc *p, 306 /*out*/ struct vattr *vap) 307 { 308 DECL(coda_getattr); /* sets Isize & Osize */ 309 ALLOC(coda_getattr); /* sets inp & outp */ 310 311 /* send the open to venus. */ 312 INIT_IN(&inp->ih, CODA_GETATTR, cred, p); 313 inp->VFid = *fid; 314 315 error = coda_call(mdp, Isize, &Osize, (char *)inp); 316 if (!error) { 317 CNV_VV2V_ATTR(vap, &outp->attr); 318 } 319 320 CODA_FREE(inp, coda_getattr_size); 321 return error; 322 } 323 324 int 325 venus_setattr(void *mdp, ViceFid *fid, struct vattr *vap, 326 struct ucred *cred, struct proc *p) 327 { 328 DECL_NO_OUT(coda_setattr); /* sets Isize & Osize */ 329 ALLOC_NO_OUT(coda_setattr); /* sets inp & outp */ 330 331 /* send the open to venus. */ 332 INIT_IN(&inp->ih, CODA_SETATTR, cred, p); 333 inp->VFid = *fid; 334 CNV_V2VV_ATTR(&inp->attr, vap); 335 336 error = coda_call(mdp, Isize, &Osize, (char *)inp); 337 338 CODA_FREE(inp, coda_setattr_size); 339 return error; 340 } 341 342 int 343 venus_access(void *mdp, ViceFid *fid, int mode, 344 struct ucred *cred, struct proc *p) 345 { 346 DECL_NO_OUT(coda_access); /* sets Isize & Osize */ 347 ALLOC_NO_OUT(coda_access); /* sets inp & outp */ 348 349 /* send the open to venus. */ 350 INIT_IN(&inp->ih, CODA_ACCESS, cred, p); 351 inp->VFid = *fid; 352 inp->flags = mode; 353 354 error = coda_call(mdp, Isize, &Osize, (char *)inp); 355 356 CODA_FREE(inp, coda_access_size); 357 return error; 358 } 359 360 int 361 venus_readlink(void *mdp, ViceFid *fid, 362 struct ucred *cred, struct proc *p, 363 /*out*/ char **str, int *len) 364 { 365 DECL(coda_readlink); /* sets Isize & Osize */ 366 coda_readlink_size += CODA_MAXPATHLEN; 367 ALLOC(coda_readlink); /* sets inp & outp */ 368 369 /* send the open to venus. */ 370 INIT_IN(&inp->ih, CODA_READLINK, cred, p); 371 inp->VFid = *fid; 372 373 Osize += CODA_MAXPATHLEN; 374 error = coda_call(mdp, Isize, &Osize, (char *)inp); 375 if (!error) { 376 CODA_ALLOC(*str, char *, outp->count); 377 *len = outp->count; 378 bcopy((char *)outp + (int)(long)outp->data, *str, *len); 379 } 380 381 CODA_FREE(inp, coda_readlink_size); 382 return error; 383 } 384 385 int 386 venus_fsync(void *mdp, ViceFid *fid, 387 struct ucred *cred, struct proc *p) 388 { 389 DECL_NO_OUT(coda_fsync); /* sets Isize & Osize */ 390 ALLOC_NO_OUT(coda_fsync); /* sets inp & outp */ 391 392 /* send the open to venus. */ 393 INIT_IN(&inp->ih, CODA_FSYNC, cred, p); 394 inp->VFid = *fid; 395 396 error = coda_call(mdp, Isize, &Osize, (char *)inp); 397 398 CODA_FREE(inp, coda_fsync_size); 399 return error; 400 } 401 402 int 403 venus_lookup(void *mdp, ViceFid *fid, 404 const char *nm, int len, 405 struct ucred *cred, struct proc *p, 406 /*out*/ ViceFid *VFid, int *vtype) 407 { 408 DECL(coda_lookup); /* sets Isize & Osize */ 409 coda_lookup_size += len + 1; 410 ALLOC(coda_lookup); /* sets inp & outp */ 411 412 /* send the open to venus. */ 413 INIT_IN(&inp->ih, CODA_LOOKUP, cred, p); 414 inp->VFid = *fid; 415 416 /* NOTE: 417 * Between version 1 and version 2 we have added an extra flag field 418 * to this structure. But because the string was at the end and because 419 * of the weird way we represent strings by having the slot point to 420 * where the string characters are in the "heap", we can just slip the 421 * flag parameter in after the string slot pointer and veni that don't 422 * know better won't see this new flag field ... 423 * Otherwise we'd need two different venus_lookup functions. 424 */ 425 inp->name = Isize; 426 inp->flags = CLU_CASE_SENSITIVE; /* doesn't really matter for BSD */ 427 STRCPY(name, nm, len); /* increments Isize */ 428 429 error = coda_call(mdp, Isize, &Osize, (char *)inp); 430 if (!error) { 431 *VFid = outp->VFid; 432 *vtype = outp->vtype; 433 } 434 435 CODA_FREE(inp, coda_lookup_size); 436 return error; 437 } 438 439 int 440 venus_create(void *mdp, ViceFid *fid, 441 const char *nm, int len, int exclusive, int mode, struct vattr *va, 442 struct ucred *cred, struct proc *p, 443 /*out*/ ViceFid *VFid, struct vattr *attr) 444 { 445 DECL(coda_create); /* sets Isize & Osize */ 446 coda_create_size += len + 1; 447 ALLOC(coda_create); /* sets inp & outp */ 448 449 /* send the open to venus. */ 450 INIT_IN(&inp->ih, CODA_CREATE, cred, p); 451 inp->VFid = *fid; 452 inp->excl = exclusive ? C_O_EXCL : 0; 453 inp->mode = mode<<6; 454 CNV_V2VV_ATTR(&inp->attr, va); 455 456 inp->name = Isize; 457 STRCPY(name, nm, len); /* increments Isize */ 458 459 error = coda_call(mdp, Isize, &Osize, (char *)inp); 460 if (!error) { 461 *VFid = outp->VFid; 462 CNV_VV2V_ATTR(attr, &outp->attr); 463 } 464 465 CODA_FREE(inp, coda_create_size); 466 return error; 467 } 468 469 int 470 venus_remove(void *mdp, ViceFid *fid, 471 const char *nm, int len, 472 struct ucred *cred, struct proc *p) 473 { 474 DECL_NO_OUT(coda_remove); /* sets Isize & Osize */ 475 coda_remove_size += len + 1; 476 ALLOC_NO_OUT(coda_remove); /* sets inp & outp */ 477 478 /* send the open to venus. */ 479 INIT_IN(&inp->ih, CODA_REMOVE, cred, p); 480 inp->VFid = *fid; 481 482 inp->name = Isize; 483 STRCPY(name, nm, len); /* increments Isize */ 484 485 error = coda_call(mdp, Isize, &Osize, (char *)inp); 486 487 CODA_FREE(inp, coda_remove_size); 488 return error; 489 } 490 491 int 492 venus_link(void *mdp, ViceFid *fid, ViceFid *tfid, 493 const char *nm, int len, 494 struct ucred *cred, struct proc *p) 495 { 496 DECL_NO_OUT(coda_link); /* sets Isize & Osize */ 497 coda_link_size += len + 1; 498 ALLOC_NO_OUT(coda_link); /* sets inp & outp */ 499 500 /* send the open to venus. */ 501 INIT_IN(&inp->ih, CODA_LINK, cred, p); 502 inp->sourceFid = *fid; 503 inp->destFid = *tfid; 504 505 inp->tname = Isize; 506 STRCPY(tname, nm, len); /* increments Isize */ 507 508 error = coda_call(mdp, Isize, &Osize, (char *)inp); 509 510 CODA_FREE(inp, coda_link_size); 511 return error; 512 } 513 514 int 515 venus_rename(void *mdp, ViceFid *fid, ViceFid *tfid, 516 const char *nm, int len, const char *tnm, int tlen, 517 struct ucred *cred, struct proc *p) 518 { 519 DECL_NO_OUT(coda_rename); /* sets Isize & Osize */ 520 coda_rename_size += len + 1 + tlen + 1; 521 ALLOC_NO_OUT(coda_rename); /* sets inp & outp */ 522 523 /* send the open to venus. */ 524 INIT_IN(&inp->ih, CODA_RENAME, cred, p); 525 inp->sourceFid = *fid; 526 inp->destFid = *tfid; 527 528 inp->srcname = Isize; 529 STRCPY(srcname, nm, len); /* increments Isize */ 530 531 inp->destname = Isize; 532 STRCPY(destname, tnm, tlen); /* increments Isize */ 533 534 error = coda_call(mdp, Isize, &Osize, (char *)inp); 535 536 CODA_FREE(inp, coda_rename_size); 537 return error; 538 } 539 540 int 541 venus_mkdir(void *mdp, ViceFid *fid, 542 const char *nm, int len, struct vattr *va, 543 struct ucred *cred, struct proc *p, 544 /*out*/ ViceFid *VFid, struct vattr *ova) 545 { 546 DECL(coda_mkdir); /* sets Isize & Osize */ 547 coda_mkdir_size += len + 1; 548 ALLOC(coda_mkdir); /* sets inp & outp */ 549 550 /* send the open to venus. */ 551 INIT_IN(&inp->ih, CODA_MKDIR, cred, p); 552 inp->VFid = *fid; 553 CNV_V2VV_ATTR(&inp->attr, va); 554 555 inp->name = Isize; 556 STRCPY(name, nm, len); /* increments Isize */ 557 558 error = coda_call(mdp, Isize, &Osize, (char *)inp); 559 if (!error) { 560 *VFid = outp->VFid; 561 CNV_VV2V_ATTR(ova, &outp->attr); 562 } 563 564 CODA_FREE(inp, coda_mkdir_size); 565 return error; 566 } 567 568 int 569 venus_rmdir(void *mdp, ViceFid *fid, 570 const char *nm, int len, 571 struct ucred *cred, struct proc *p) 572 { 573 DECL_NO_OUT(coda_rmdir); /* sets Isize & Osize */ 574 coda_rmdir_size += len + 1; 575 ALLOC_NO_OUT(coda_rmdir); /* sets inp & outp */ 576 577 /* send the open to venus. */ 578 INIT_IN(&inp->ih, CODA_RMDIR, cred, p); 579 inp->VFid = *fid; 580 581 inp->name = Isize; 582 STRCPY(name, nm, len); /* increments Isize */ 583 584 error = coda_call(mdp, Isize, &Osize, (char *)inp); 585 586 CODA_FREE(inp, coda_rmdir_size); 587 return error; 588 } 589 590 int 591 venus_symlink(void *mdp, ViceFid *fid, 592 const char *lnm, int llen, const char *nm, int len, struct vattr *va, 593 struct ucred *cred, struct proc *p) 594 { 595 DECL_NO_OUT(coda_symlink); /* sets Isize & Osize */ 596 coda_symlink_size += llen + 1 + len + 1; 597 ALLOC_NO_OUT(coda_symlink); /* sets inp & outp */ 598 599 /* send the open to venus. */ 600 INIT_IN(&inp->ih, CODA_SYMLINK, cred, p); 601 inp->VFid = *fid; 602 CNV_V2VV_ATTR(&inp->attr, va); 603 604 inp->srcname = Isize; 605 STRCPY(srcname, lnm, llen); /* increments Isize */ 606 607 inp->tname = Isize; 608 STRCPY(tname, nm, len); /* increments Isize */ 609 610 error = coda_call(mdp, Isize, &Osize, (char *)inp); 611 612 CODA_FREE(inp, coda_symlink_size); 613 return error; 614 } 615 616 int 617 venus_readdir(void *mdp, ViceFid *fid, 618 int count, int offset, 619 struct ucred *cred, struct proc *p, 620 /*out*/ char *buffer, int *len) 621 { 622 DECL(coda_readdir); /* sets Isize & Osize */ 623 coda_readdir_size = VC_MAXMSGSIZE; 624 ALLOC(coda_readdir); /* sets inp & outp */ 625 626 /* send the open to venus. */ 627 INIT_IN(&inp->ih, CODA_READDIR, cred, p); 628 inp->VFid = *fid; 629 inp->count = count; 630 inp->offset = offset; 631 632 Osize = VC_MAXMSGSIZE; 633 error = coda_call(mdp, Isize, &Osize, (char *)inp); 634 if (!error) { 635 bcopy((char *)outp + (int)(long)outp->data, buffer, outp->size); 636 *len = outp->size; 637 } 638 639 CODA_FREE(inp, coda_readdir_size); 640 return error; 641 } 642 643 int 644 venus_statfs(void *mdp, struct ucred *cred, struct proc *p, 645 /*out*/ struct coda_statfs *fsp) 646 { 647 DECL(coda_statfs); /* sets Isize & Osize */ 648 ALLOC(coda_statfs); /* sets inp & outp */ 649 650 /* send the open to venus. */ 651 INIT_IN(&inp->ih, CODA_STATFS, cred, p); 652 653 error = coda_call(mdp, Isize, &Osize, (char *)inp); 654 if (!error) { 655 *fsp = outp->stat; 656 } 657 658 CODA_FREE(inp, coda_statfs_size); 659 return error; 660 } 661 662 int 663 venus_fhtovp(void *mdp, ViceFid *fid, 664 struct ucred *cred, struct proc *p, 665 /*out*/ ViceFid *VFid, int *vtype) 666 { 667 DECL(coda_vget); /* sets Isize & Osize */ 668 ALLOC(coda_vget); /* sets inp & outp */ 669 670 /* Send the open to Venus. */ 671 INIT_IN(&inp->ih, CODA_VGET, cred, p); 672 inp->VFid = *fid; 673 674 error = coda_call(mdp, Isize, &Osize, (char *)inp); 675 if (!error) { 676 *VFid = outp->VFid; 677 *vtype = outp->vtype; 678 } 679 680 CODA_FREE(inp, coda_vget_size); 681 return error; 682 } 683