1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * RPC service routines. 31 */ 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <errno.h> 37 #include <rpc/rpc.h> 38 #include <rpc/pmap_clnt.h> /* for pmap_unset */ 39 #include <string.h> /* strcmp */ 40 #include <signal.h> 41 #include <unistd.h> /* setsid */ 42 #include <sys/types.h> 43 #include <sys/stat.h> 44 #include <time.h> 45 #include <memory.h> 46 #include <stropts.h> 47 #include <netconfig.h> 48 #include <sys/resource.h> /* rlimit */ 49 #include <thread.h> 50 #include <synch.h> 51 #include <mdbug/mdbug.h> 52 #include <common/cachefsd.h> 53 #include <sys/fs/cachefs_fs.h> 54 #include <sys/fs/cachefs_dlog.h> 55 #include <sys/fs/cachefs_ioctl.h> 56 #include "cfsd.h" 57 #include "cfsd_kmod.h" 58 #include "cfsd_maptbl.h" 59 #include "cfsd_logfile.h" 60 #include "cfsd_fscache.h" 61 #include "cfsd_cache.h" 62 #include "cfsd_all.h" 63 #include "cfsd_subr.h" 64 65 /* declared in cfsd_main.c */ 66 extern cfsd_all_object_t *all_object_p; 67 68 /* 69 * cachefsd_null_1_svc 70 * 71 * Description: 72 * Routine to process NULLPROC command, see /usr/include/rpc/clnt.h. 73 * Arguments: 74 * inp should be NULL 75 * outp should be NULL 76 * reqp svc_req info 77 * Returns: 78 * Always returns 1, e.g. returns success result. 79 * Preconditions: 80 * precond(reqp) 81 */ 82 bool_t 83 cachefsd_null_1_svc(void *inp, void *outp, struct svc_req *reqp) 84 { 85 dbug_enter("cachefsd_null_1_svc"); 86 dbug_precond(reqp); 87 88 dbug_assert(inp == NULL); 89 dbug_assert(outp == NULL); 90 91 dbug_leave("cachefsd_null_1_svc"); 92 return (1); 93 } 94 95 /* 96 * cachefsd_caches_1_svc 97 * 98 * Description: 99 * Returns list of caches on the system. 100 * Arguments: 101 * inp should be NULL 102 * outp should point to return object 103 * reqp svc_req info 104 * Returns: 105 * Returns 1 for success 0 if an error occurs. 106 * Preconditions: 107 * precond(reqp) 108 */ 109 bool_t 110 cachefsd_caches_1_svc(void *inp, 111 cachefsd_caches_return *outp, 112 struct svc_req *reqp) 113 { 114 size_t cnt; 115 size_t index; 116 cfsd_cache_object_t *cache_object_p; 117 cachefsd_caches_id *headp, *idp; 118 119 dbug_enter("cachefsd_caches_1_svc"); 120 dbug_precond(reqp); 121 122 dbug_assert(inp == NULL); 123 dbug_assert(outp); 124 125 if (inp || (outp == NULL)) { 126 dbug_leave("cachefsd_caches_1_svc"); 127 return (0); 128 } 129 all_lock(all_object_p); 130 headp = NULL; 131 132 /* if there are any caches */ 133 cnt = all_object_p->i_cachecount; 134 if (cnt) { 135 /* allocate space for each cache information */ 136 headp = idp = cfsd_calloc(sizeof (cachefsd_caches_id) * cnt); 137 138 /* for each cache */ 139 for (index = 0; index < cnt; index++, idp++) { 140 /* get the cache */ 141 cache_object_p = all_cachelist_at(all_object_p, index); 142 dbug_assert(cache_object_p); 143 144 /* get the cache id and name */ 145 idp->cci_cacheid = cache_object_p->i_cacheid; 146 idp->cci_name = subr_strdup(cache_object_p->i_cachedir); 147 } 148 } 149 150 /* fill in the return object */ 151 outp->ccr_modify = all_object_p->i_modify; 152 outp->ccr_ids.ccr_ids_len = cnt; 153 outp->ccr_ids.ccr_ids_val = headp; 154 155 all_unlock(all_object_p); 156 157 dbug_leave("cachefsd_caches_1_svc"); 158 return (1); 159 } 160 161 /* 162 * cachefsd_cache_status_1_svc 163 * 164 * Description: 165 * Returns status about a particular cache. 166 * Arguments: 167 * inp should be ptr to cache id 168 * outp should be ptr to place to put cache status 169 * reqp svc_req info 170 * Returns: 171 * Returns 1 for success 0 if an error occurs. 172 * Preconditions: 173 * precond(reqp) 174 */ 175 bool_t 176 cachefsd_cache_status_1_svc(int *inp, struct cachefsd_cache_status *outp, 177 struct svc_req *reqp) 178 { 179 cfsd_fscache_object_t *fscache_object_p = NULL; 180 size_t cnt, index; 181 cfsd_cache_object_t *cache_object_p; 182 cfsd_kmod_object_t *kmod_object_p; 183 cachefsio_getstats_t gs; 184 int xx; 185 186 dbug_enter("cachefsd_cache_status_1_svc"); 187 dbug_precond(reqp); 188 189 dbug_assert(inp); 190 dbug_assert(outp); 191 192 if ((inp == NULL) || (outp == NULL)) { 193 dbug_leave("cachefsd_cache_status_1_svc"); 194 return (0); 195 } 196 memset(outp, 0, sizeof (*outp)); 197 198 /* find the requested cache */ 199 all_lock(all_object_p); 200 cnt = all_object_p->i_cachecount; 201 for (index = 0; index < cnt; index++) { 202 /* get the cache */ 203 cache_object_p = all_cachelist_at(all_object_p, index); 204 dbug_assert(cache_object_p); 205 206 /* if a match */ 207 if (cache_object_p->i_cacheid == *inp) { 208 cache_lock(cache_object_p); 209 cache_object_p->i_refcnt++; 210 cache_unlock(cache_object_p); 211 break; 212 } 213 } 214 all_unlock(all_object_p); 215 216 /* if no match */ 217 if (index >= cnt) { 218 dbug_leave("cachefsd_cache_status_1_svc"); 219 return (1); 220 } 221 /* find a mounted file system in the cache */ 222 cache_lock(cache_object_p); 223 cnt = cache_object_p->i_fscachecount; 224 for (index = 0; index < cnt; index++) { 225 /* get the fscache */ 226 fscache_object_p = cache_fscachelist_at(cache_object_p, index); 227 dbug_assert(fscache_object_p); 228 229 /* mounted */ 230 if (fscache_object_p->i_mounted) { 231 fscache_lock(fscache_object_p); 232 fscache_object_p->i_refcnt++; 233 fscache_unlock(fscache_object_p); 234 break; 235 } 236 fscache_object_p = NULL; 237 } 238 cache_unlock(cache_object_p); 239 240 outp->ccs_size = 0; 241 outp->ccs_lrusize = 0; 242 outp->ccs_packsize = 0; 243 outp->ccs_freesize = 0; 244 outp->ccs_lrutime = 0; 245 246 kmod_object_p = cfsd_kmod_create(); 247 if (fscache_object_p) { 248 xx = kmod_setup(kmod_object_p, fscache_object_p->i_mntpt); 249 if (xx != 0) { 250 dbug_print(("err", 251 "setup of kmod interface failed %d", xx)); 252 } else if ((xx = kmod_getstats(kmod_object_p, &gs)) != 0) { 253 dbug_print(("err", "getstat failed %d", xx)); 254 } else { 255 outp->ccs_size = gs.gs_total; 256 outp->ccs_lrusize = gs.gs_gc + gs.gs_active; 257 outp->ccs_packsize = gs.gs_packed; 258 outp->ccs_freesize = gs.gs_free; 259 outp->ccs_lrutime = gs.gs_gctime; 260 261 fscache_lock(fscache_object_p); 262 fscache_object_p->i_refcnt--; 263 fscache_unlock(fscache_object_p); 264 } 265 } 266 cfsd_kmod_destroy(kmod_object_p); 267 268 outp->ccs_id = cache_object_p->i_cacheid; 269 outp->ccs_name = subr_strdup(cache_object_p->i_cachedir); 270 outp->ccs_modify = cache_object_p->i_modify; 271 cache_lock(cache_object_p); 272 cache_object_p->i_refcnt--; 273 cache_unlock(cache_object_p); 274 275 dbug_leave("cachefsd_cache_status_1_svc"); 276 return (1); 277 } 278 279 /* 280 * cachefsd_mounts_1_svc 281 * 282 * Description: 283 * Returns the list of file systems that are in the cache. 284 * Arguments: 285 * inp should be ptr to cache id 286 * outp should be ptr to place to put mounts 287 * reqp svc_req info 288 * Returns: 289 * Returns 1 for success 0 if an internal error occurs. 290 * Preconditions: 291 * precond(reqp) 292 */ 293 bool_t 294 cachefsd_mounts_1_svc(int *inp, struct cachefsd_mount_returns *outp, 295 struct svc_req *reqp) 296 { 297 size_t cnt, index; 298 cfsd_cache_object_t *cache_object_p; 299 cfsd_fscache_object_t *fscache_object_p; 300 struct cachefsd_mount *headp, *idp; 301 302 dbug_enter("cachefsd_mounts_1_svc"); 303 dbug_precond(reqp); 304 305 dbug_assert(inp); 306 dbug_assert(outp); 307 if ((inp == NULL) || (outp == NULL)) { 308 dbug_leave("cachefsd_mounts_1_svc"); 309 return (0); 310 } 311 memset(outp, 0, sizeof (*outp)); 312 313 /* find the requested cache */ 314 all_lock(all_object_p); 315 cnt = all_object_p->i_cachecount; 316 for (index = 0; index < cnt; index++) { 317 /* get the cache */ 318 cache_object_p = all_cachelist_at(all_object_p, index); 319 dbug_assert(cache_object_p); 320 321 /* if a match */ 322 if (cache_object_p->i_cacheid == *inp) { 323 cache_lock(cache_object_p); 324 cache_object_p->i_refcnt++; 325 cache_unlock(cache_object_p); 326 break; 327 } 328 } 329 all_unlock(all_object_p); 330 331 /* if no match was found */ 332 if (index >= cnt) { 333 outp->cmr_error = ENOENT; 334 dbug_leave("cachefsd_mounts_1_svc"); 335 return (1); 336 } 337 338 cache_lock(cache_object_p); 339 headp = NULL; 340 341 /* if there are any fscaches */ 342 cnt = cache_object_p->i_fscachecount; 343 if (cnt) { 344 /* allocate space for each fscache information */ 345 headp = idp = cfsd_calloc(sizeof (cachefsd_mount) * cnt); 346 /* for each fscache */ 347 for (index = 0; index < cnt; index++, idp++) { 348 /* get the fscache */ 349 fscache_object_p = 350 cache_fscachelist_at(cache_object_p, index); 351 dbug_assert(fscache_object_p); 352 353 /* get the fscache id and name */ 354 idp->cm_fsid = fscache_object_p->i_fscacheid; 355 idp->cm_name = subr_strdup(fscache_object_p->i_name); 356 } 357 } 358 359 /* fill in the return object */ 360 outp->cmr_modify = cache_object_p->i_modify; 361 outp->cmr_error = 0; 362 outp->cmr_names.cmr_names_len = cnt; 363 outp->cmr_names.cmr_names_val = headp; 364 365 cache_object_p->i_refcnt--; 366 cache_unlock(cache_object_p); 367 368 dbug_leave("cachefsd_mounts_1_svc"); 369 return (1); 370 } 371 372 /* 373 * cachefsd_mount_stat_1_svc 374 * 375 * Description: 376 * Returns status information about a single file system 377 * in the cache. 378 * Arguments: 379 * inp should be which file system to get info for 380 * outp should be place to put mount info 381 * reqp svc_req info 382 * Returns: 383 * Returns 1 for success 0 if an error occurs. 384 * Preconditions: 385 * precond(reqp) 386 */ 387 bool_t 388 cachefsd_mount_stat_1_svc(struct cachefsd_mount_stat_args *inp, 389 struct cachefsd_mount_stat *outp, struct svc_req *reqp) 390 { 391 size_t cnt, index; 392 cfsd_cache_object_t *cache_object_p; 393 cfsd_fscache_object_t *fscache_object_p; 394 char namebuf[MAXPATHLEN]; 395 struct stat sinfo; 396 397 dbug_enter("cachefsd_mount_stat_1_svc"); 398 dbug_precond(reqp); 399 400 dbug_assert(inp); 401 dbug_assert(outp); 402 if ((inp == NULL) || (outp == NULL)) { 403 dbug_leave("cachefsd_mount_stat_1_svc"); 404 return (0); 405 } 406 memset(outp, 0, sizeof (*outp)); 407 408 /* find the requested cache */ 409 all_lock(all_object_p); 410 cnt = all_object_p->i_cachecount; 411 for (index = 0; index < cnt; index++) { 412 /* get the cache */ 413 cache_object_p = all_cachelist_at(all_object_p, index); 414 dbug_assert(cache_object_p); 415 416 /* if a match */ 417 if (cache_object_p->i_cacheid == inp->cma_cacheid) { 418 cache_lock(cache_object_p); 419 cache_object_p->i_refcnt++; 420 cache_unlock(cache_object_p); 421 break; 422 } 423 } 424 all_unlock(all_object_p); 425 426 /* if no match was found */ 427 if (index >= cnt) { 428 dbug_leave("cachefsd_mount_stat_1_svc"); 429 return (1); 430 } 431 432 /* find the requested fscache */ 433 cache_lock(cache_object_p); 434 cnt = cache_object_p->i_fscachecount; 435 for (index = 0; index < cnt; index++) { 436 /* get the fscache */ 437 fscache_object_p = cache_fscachelist_at(cache_object_p, index); 438 dbug_assert(fscache_object_p); 439 440 /* if a match */ 441 if (fscache_object_p->i_fscacheid == inp->cma_fsid) { 442 fscache_lock(fscache_object_p); 443 fscache_object_p->i_refcnt++; 444 fscache_unlock(fscache_object_p); 445 break; 446 } 447 } 448 cache_unlock(cache_object_p); 449 450 /* if no match was found */ 451 if (index >= cnt) { 452 cache_lock(cache_object_p); 453 cache_object_p->i_refcnt--; 454 cache_unlock(cache_object_p); 455 dbug_leave("cachefsd_mount_stat_1_svc"); 456 return (1); 457 } 458 459 fscache_lock(fscache_object_p); 460 461 /* see if there are changes to roll to the server */ 462 if ((fscache_object_p->i_connected == 0) && 463 (fscache_object_p->i_changes == 0)) { 464 snprintf(namebuf, sizeof (namebuf), "%s/%s/%s", 465 cache_object_p->i_cachedir, fscache_object_p->i_name, 466 CACHEFS_DLOG_FILE); 467 if (stat(namebuf, &sinfo) == 0) { 468 fscache_changes(fscache_object_p, 1); 469 } 470 } 471 472 /* fill in the return object */ 473 outp->cms_cacheid = cache_object_p->i_cacheid; 474 outp->cms_fsid = fscache_object_p->i_fscacheid; 475 outp->cms_name = subr_strdup(fscache_object_p->i_name); 476 outp->cms_backfs = subr_strdup(fscache_object_p->i_backfs); 477 outp->cms_mountpt = subr_strdup(fscache_object_p->i_mntpt); 478 outp->cms_backfstype = subr_strdup(fscache_object_p->i_backfstype); 479 outp->cms_writemode = NULL; 480 outp->cms_options = subr_strdup(fscache_object_p->i_cfsopt); 481 outp->cms_mounted = fscache_object_p->i_mounted; 482 outp->cms_connected = fscache_object_p->i_connected; 483 outp->cms_reconcile = fscache_object_p->i_reconcile; 484 outp->cms_changes = fscache_object_p->i_changes; 485 outp->cms_time_state = fscache_object_p->i_time_state; 486 outp->cms_mnttime = fscache_object_p->i_time_mnt; 487 outp->cms_modify = fscache_object_p->i_modify; 488 489 fscache_object_p->i_refcnt--; 490 fscache_unlock(fscache_object_p); 491 492 cache_lock(cache_object_p); 493 cache_object_p->i_refcnt--; 494 cache_unlock(cache_object_p); 495 496 dbug_leave("cachefsd_mount_stat_1_svc"); 497 return (1); 498 } 499 500 /* 501 * cachefsd_fs_mounted_1_svc 502 * 503 * Description: 504 * Sent by the mount command to indicate a new file system 505 * has been mounted 506 * Arguments: 507 * inp ptr to mount information 508 * outp should be null 509 * reqp svc_req info 510 * Returns: 511 * Returns 1 for success 0 if an internal error occurs. 512 * Preconditions: 513 * precond(inp) 514 */ 515 bool_t 516 cachefsd_fs_mounted_1_svc(struct cachefsd_fs_mounted *inp, void *outp, 517 struct svc_req *reqp) 518 { 519 int error = 0; 520 521 dbug_enter("cachefsd_fs_mounted_1_svc"); 522 dbug_precond(reqp); 523 524 dbug_assert(inp); 525 dbug_assert(outp == NULL); 526 if ((inp == NULL) || outp) { 527 dbug_leave("cachefsd_fs_mounted_1_svc"); 528 return (0); 529 } 530 531 if (inp->mt_cachedir == NULL) { 532 dbug_print(("error", "cachedir is null")); 533 error = 1; 534 } 535 if (inp->mt_cacheid == NULL) { 536 dbug_print(("error", "cacheid is null")); 537 error = 1; 538 } 539 540 if (error == 0) { 541 dbug_print(("info", "Mounted in %s file system %s", 542 inp->mt_cachedir, inp->mt_cacheid)); 543 subr_add_mount(all_object_p, inp->mt_cachedir, inp->mt_cacheid); 544 } 545 546 dbug_leave("cachefsd_fs_mounted_1_svc"); 547 return (1); 548 } 549 550 /* 551 * cachefsd_fs_unmounted_1_svc 552 * 553 * Description: 554 * Arguments: 555 * inp 556 * outp 557 * reqp 558 * Returns: 559 * Returns 1 for success 0 if an internal error occurs. 560 * Preconditions: 561 * precond(inp) 562 * precond(outp == NULL) 563 * precond(reqp) 564 */ 565 bool_t 566 cachefsd_fs_unmounted_1_svc(struct cachefsd_fs_unmounted *inp, int *outp, 567 struct svc_req *reqp) 568 { 569 size_t cnt1, cnt2, index1, index2; 570 cfsd_cache_object_t *cache_object_p; 571 cfsd_fscache_object_t *fscache_object_p = NULL; 572 int found = 0; 573 int flag = 0; 574 575 dbug_enter("cachefsd_fs_unmounted_1_svc"); 576 577 dbug_precond(inp); 578 dbug_precond(outp); 579 dbug_precond(reqp); 580 581 if ((inp == NULL) || (outp == NULL)) { 582 dbug_leave("cachefsd_fs_unmounted_1_svc"); 583 return (0); 584 } 585 memset(outp, 0, sizeof (*outp)); 586 587 if (inp->mntpt == NULL) { 588 dbug_print(("error", "mntpt is null")); 589 *outp = EIO; 590 dbug_leave("cachefsd_fs_unmounted_1_svc"); 591 return (1); 592 } 593 594 /* for each cache */ 595 all_lock(all_object_p); 596 cnt1 = all_object_p->i_cachecount; 597 for (index1 = 0; index1 < cnt1; index1++) { 598 /* get the cache */ 599 cache_object_p = all_cachelist_at(all_object_p, index1); 600 dbug_assert(cache_object_p); 601 602 /* for each file system in this cache */ 603 cache_lock(cache_object_p); 604 cnt2 = cache_object_p->i_fscachecount; 605 for (index2 = 0; index2 < cnt2; index2++) { 606 /* get the fscache */ 607 fscache_object_p = 608 cache_fscachelist_at(cache_object_p, index2); 609 dbug_assert(fscache_object_p); 610 611 /* skip if not mounted */ 612 if (fscache_object_p->i_mounted == 0) 613 continue; 614 615 /* if a match */ 616 if (strcmp(fscache_object_p->i_mntpt, 617 inp->mntpt) == 0) { 618 fscache_lock(fscache_object_p); 619 fscache_object_p->i_refcnt++; 620 flag = inp->flag; 621 fscache_unlock(fscache_object_p); 622 found = 1; 623 break; 624 } 625 } 626 cache_unlock(cache_object_p); 627 if (found) 628 break; 629 fscache_object_p = NULL; 630 } 631 all_unlock(all_object_p); 632 633 /* if no match */ 634 if (fscache_object_p == NULL) { 635 *outp = EIO; 636 } else { 637 *outp = fscache_unmount(fscache_object_p, flag); 638 639 fscache_lock(fscache_object_p); 640 fscache_object_p->i_refcnt--; 641 fscache_unlock(fscache_object_p); 642 } 643 dbug_leave("cachefsd_fs_unmounted_1_svc"); 644 return (1); 645 } 646 647 /* 648 * cachefsd_disconnection_1_svc 649 * 650 * Description: 651 * Arguments: 652 * inp 653 * outp 654 * reqp 655 * Returns: 656 * Returns 1 for success 0 if an internal error occurs. 657 * Preconditions: 658 * precond(inp) 659 * precond(outp) 660 * precond(reqp) 661 */ 662 bool_t 663 cachefsd_disconnection_1_svc(struct cachefsd_disconnection_args *inp, int *outp, 664 struct svc_req *reqp) 665 { 666 size_t cnt1, cnt2, index1, index2; 667 cfsd_cache_object_t *cache_object_p; 668 cfsd_fscache_object_t *fscache_object_p = NULL; 669 int found = 0; 670 671 dbug_enter("cachefsd_disconnection_1_svc"); 672 673 dbug_precond(inp); 674 dbug_precond(outp); 675 dbug_precond(reqp); 676 677 if ((inp == NULL) || (outp == NULL)) { 678 dbug_leave("cachefsd_disconnection_1_svc"); 679 return (0); 680 } 681 memset(outp, 0, sizeof (*outp)); 682 683 /* for each cache */ 684 all_lock(all_object_p); 685 cnt1 = all_object_p->i_cachecount; 686 for (index1 = 0; index1 < cnt1; index1++) { 687 /* get the cache */ 688 cache_object_p = all_cachelist_at(all_object_p, index1); 689 dbug_assert(cache_object_p); 690 691 /* for each file system in this cache */ 692 cache_lock(cache_object_p); 693 cnt2 = cache_object_p->i_fscachecount; 694 for (index2 = 0; index2 < cnt2; index2++) { 695 /* get the fscache */ 696 fscache_object_p = 697 cache_fscachelist_at(cache_object_p, index2); 698 dbug_assert(fscache_object_p); 699 700 /* if a match */ 701 if (strcmp(fscache_object_p->i_mntpt, inp->cda_mntpt) 702 == 0) { 703 fscache_lock(fscache_object_p); 704 fscache_object_p->i_refcnt++; 705 fscache_unlock(fscache_object_p); 706 found = 1; 707 break; 708 } 709 } 710 cache_unlock(cache_object_p); 711 if (found) 712 break; 713 fscache_object_p = NULL; 714 } 715 all_unlock(all_object_p); 716 717 /* if no match */ 718 if (fscache_object_p == NULL) { 719 *outp = 3; 720 } else { 721 *outp = fscache_simdisconnect(fscache_object_p, 722 inp->cda_disconnect); 723 724 fscache_lock(fscache_object_p); 725 fscache_object_p->i_refcnt--; 726 fscache_unlock(fscache_object_p); 727 } 728 dbug_leave("cachefsd_disconnection_1_svc"); 729 return (1); 730 } 731 732 /* 733 * cachefsdprog_1_freeresult 734 * 735 * Description: 736 * Arguments: 737 * transp 738 * xdr_result 739 * resultp 740 * Returns: 741 * Returns ... 742 * Preconditions: 743 * precond(transp) 744 */ 745 int 746 cachefsdprog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 747 caddr_t resultp) 748 { 749 dbug_enter("cachefsdprog_1_freeresult"); 750 751 dbug_precond(transp); 752 753 (void) xdr_free(xdr_result, resultp); 754 dbug_leave("cachefsdprog_1_freeresult"); 755 return (1); 756 } 757