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