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 2004 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  * Source file for the cfsd_kmod class.
  31  */
  32 
  33 #include <stdio.h>
  34 #include <stdlib.h>
  35 #include <stddef.h>
  36 #include <string.h>
  37 #include <errno.h>
  38 #include <unistd.h>
  39 #include <fcntl.h>
  40 #include <sys/param.h>
  41 #include <sys/types.h>
  42 #include <sys/fcntl.h>
  43 #include <sys/cred.h>
  44 #include <sys/vnode.h>
  45 #include <sys/vfs.h>
  46 #include <sys/fs/cachefs_fs.h>
  47 #include <sys/fs/cachefs_dlog.h>
  48 #include <sys/fs/cachefs_ioctl.h>
  49 #include <mdbug/mdbug.h>
  50 #include "cfsd.h"
  51 #include "cfsd_kmod.h"
  52 
  53 /*
  54  * copy_cred (copy dl_cred_t followed by a list of gid_t)
  55  */
  56 
  57 static void
  58 copy_cred(dl_cred_t *dst, const dl_cred_t *src)
  59 {
  60         int n = src->cr_ngroups;
  61 
  62         if (n > NGROUPS_MAX_DEFAULT)
  63                 n = NGROUPS_MAX_DEFAULT;
  64 
  65         (void) memcpy(dst, src, sizeof (*dst) + (n - 1) * sizeof (gid_t));
  66         dst->cr_ngroups = n;
  67 }
  68 
  69 /*
  70  * ------------------------------------------------------------
  71  *                      cfsd_kmod_create
  72  *
  73  * Description:
  74  * Arguments:
  75  * Returns:
  76  * Preconditions:
  77  */
  78 
  79 cfsd_kmod_object_t *
  80 cfsd_kmod_create(void)
  81 {
  82         cfsd_kmod_object_t *kmod_object_p;
  83 
  84         dbug_enter("cfsd_kmod_create");
  85         kmod_object_p = cfsd_calloc(sizeof (cfsd_kmod_object_t));
  86 
  87         kmod_object_p->i_fd = -1;
  88 
  89         dbug_leave("cfsd_kmod_create");
  90         return (kmod_object_p);
  91 }
  92 
  93 /*
  94  * ------------------------------------------------------------
  95  *                      cfsd_kmod_destory
  96  *
  97  * Description:
  98  * Arguments:
  99  * Returns:
 100  * Preconditions:
 101  */
 102 
 103 
 104 void
 105 cfsd_kmod_destroy(cfsd_kmod_object_t *kmod_object_p)
 106 {
 107         dbug_enter("cfsd_kmod_destroy");
 108         dbug_precond(kmod_object_p);
 109 
 110         /* clean up old stuff */
 111         kmod_shutdown(kmod_object_p);
 112 
 113         cfsd_free(kmod_object_p);
 114         dbug_leave("cfsd_kmod_destroy");
 115 }
 116 
 117 /*
 118  * ------------------------------------------------------------
 119  *                      kmod_setup
 120  *
 121  * Description:
 122  * Arguments:
 123  *      path
 124  * Returns:
 125  *      Returns ...
 126  * Preconditions:
 127  *      precond(path)
 128  */
 129 int
 130 kmod_setup(cfsd_kmod_object_t *kmod_object_p, const char *path)
 131 {
 132         int xx;
 133         int error;
 134 
 135         dbug_enter("kmod_setup");
 136         dbug_precond(kmod_object_p);
 137         dbug_precond(path);
 138 
 139         /* clean up old stuff */
 140         kmod_shutdown(kmod_object_p);
 141 
 142         /* try to open the file */
 143         dbug_assert(kmod_object_p->i_fd == -1);
 144         kmod_object_p->i_fd = open(path, O_RDONLY);
 145 
 146         /* return result */
 147         if (kmod_object_p->i_fd == -1) {
 148                 xx = errno;
 149                 dbug_print(("err", "open of %s failed %d", path, xx));
 150         } else {
 151                 xx = 0;
 152                 strlcpy(kmod_object_p->i_path, path,
 153                     sizeof (kmod_object_p->i_path));
 154                 dbug_print(("info", "opened %s on fd %d", path,
 155                     kmod_object_p->i_fd));
 156 
 157                 /* tell the cachefs kmod we are here */
 158                 xx = kmod_doioctl(kmod_object_p, CFSDCMD_DAEMONID,
 159                     NULL, 0, NULL, 0);
 160                 if (xx) {
 161                         error = errno;
 162                         dbug_print(("ioctl", "daemonid error %d", error));
 163                 }
 164         }
 165 
 166         dbug_leave("kmod_setup");
 167         return (xx);
 168 }
 169 
 170 /*
 171  *                      kmod_shutdown
 172  *
 173  * Description:
 174  * Arguments:
 175  * Returns:
 176  * Preconditions:
 177  */
 178 void
 179 kmod_shutdown(cfsd_kmod_object_t *kmod_object_p)
 180 {
 181         dbug_enter("kmod_shutdown");
 182         dbug_precond(kmod_object_p);
 183 
 184         /* close down the old fd if necessary */
 185         if (kmod_object_p->i_fd >= 0) {
 186                 if (close(kmod_object_p->i_fd))
 187                         dbug_print(("err", "cannot close kmod fd, %d", errno));
 188         }
 189         kmod_object_p->i_fd = -1;
 190         dbug_leave("kmod_shutdown");
 191 }
 192 
 193 /*
 194  * ------------------------------------------------------------
 195  *                      kmod_xwait
 196  *
 197  * Description:
 198  * Arguments:
 199  * Returns:
 200  *      Returns ...
 201  * Preconditions:
 202  */
 203 int
 204 kmod_xwait(cfsd_kmod_object_t *kmod_object_p)
 205 {
 206         int xx;
 207         int error = 0;
 208 
 209         dbug_enter("kmod_xwait");
 210         dbug_precond(kmod_object_p);
 211 
 212         xx = kmod_doioctl(kmod_object_p, CFSDCMD_XWAIT, NULL, 0, NULL, 0);
 213         if (xx)
 214                 error = errno;
 215         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 216         dbug_leave("kmod_xwait");
 217         return (error);
 218 }
 219 
 220 /*
 221  * ------------------------------------------------------------
 222  *                      kmod_stateget
 223  *
 224  * Description:
 225  * Arguments:
 226  * Returns:
 227  *      Returns ...
 228  * Preconditions:
 229  */
 230 int
 231 kmod_stateget(cfsd_kmod_object_t *kmod_object_p)
 232 {
 233         int state;
 234         int xx;
 235 
 236         dbug_enter("kmod_stateget");
 237         dbug_precond(kmod_object_p);
 238 
 239         xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATEGET, NULL, 0, &state,
 240             sizeof (state));
 241         dbug_print(("ioctl", "returns %d, state %d", xx, state));
 242         if (xx == -1) {
 243                 /* XXX do what? */
 244                 dbug_assert(0);
 245         }
 246         dbug_leave("kmod_stateget");
 247         return (state);
 248 }
 249 
 250 /*
 251  * ------------------------------------------------------------
 252  *                      kmod_stateset
 253  *
 254  * Description:
 255  * Arguments:
 256  *      state
 257  * Returns:
 258  *      Returns ...
 259  * Preconditions:
 260  */
 261 int
 262 kmod_stateset(cfsd_kmod_object_t *kmod_object_p, int state)
 263 {
 264         int xx;
 265         int error = 0;
 266 
 267         dbug_enter("kmod_stateset");
 268         dbug_precond(kmod_object_p);
 269 
 270         xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATESET, &state,
 271             sizeof (state), NULL, 0);
 272         if (xx)
 273                 error = errno;
 274         dbug_print(("ioctl", "returns %d, state set to %d", xx, state));
 275         dbug_leave("kmod_stateset");
 276         return (error);
 277 }
 278 
 279 /*
 280  * ------------------------------------------------------------
 281  *                      kmod_exists
 282  *
 283  * Description:
 284  * Arguments:
 285  *      cidp
 286  * Returns:
 287  *      Returns ...
 288  * Preconditions:
 289  *      precond(cidp)
 290  */
 291 int
 292 kmod_exists(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp)
 293 {
 294         int xx;
 295         int error = 0;
 296 
 297         dbug_enter("kmod_exists");
 298         dbug_precond(kmod_object_p);
 299         dbug_precond(cidp);
 300 
 301         xx = kmod_doioctl(kmod_object_p, CFSDCMD_EXISTS, cidp,
 302             sizeof (cfs_cid_t), NULL, 0);
 303         if (xx)
 304                 error = errno;
 305         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 306         dbug_print(("ioctl", "   cid %08x", cidp->cid_fileno));
 307         dbug_leave("kmod_exists");
 308         return (error);
 309 }
 310 
 311 /*
 312  * ------------------------------------------------------------
 313  *                      kmod_lostfound
 314  *
 315  * Description:
 316  * Arguments:
 317  *      cidp
 318  * Returns:
 319  *      Returns ...
 320  * Preconditions:
 321  *      precond(cidp)
 322  */
 323 int
 324 kmod_lostfound(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp,
 325         const char *namep, char *newnamep)
 326 {
 327         cachefsio_lostfound_arg_t info;
 328         cachefsio_lostfound_return_t ret;
 329         int error = 0;
 330         int xx;
 331 
 332         dbug_enter("kmod_lostfound");
 333         dbug_precond(kmod_object_p);
 334         dbug_precond(cidp);
 335         dbug_precond(namep);
 336         dbug_precond(newnamep);
 337         dbug_precond(strlen(namep) < (size_t)MAXNAMELEN);
 338 
 339         info.lf_cid = *cidp;
 340         strlcpy(info.lf_name, namep, sizeof (info.lf_name));
 341 
 342         xx = kmod_doioctl(kmod_object_p, CFSDCMD_LOSTFOUND, &info,
 343             sizeof (info), &ret, sizeof (ret));
 344         if (xx)
 345                 error = errno;
 346         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 347         dbug_print(("ioctl", "   cid %08x", cidp->cid_fileno));
 348         dbug_print(("ioctl", "   suggested name '%s'", namep));
 349         if (xx == 0) {
 350                 dbug_print(("ioctl", "   new name '%s'", ret.lf_name));
 351                 dbug_assert(strlen(ret.lf_name) < (size_t)MAXNAMELEN);
 352                 if (newnamep)
 353                         strlcpy(newnamep, ret.lf_name, MAXNAMELEN);
 354         }
 355         dbug_leave("kmod_lostfound");
 356         return (error);
 357 }
 358 
 359 #if 0
 360 /*
 361  * ------------------------------------------------------------
 362  *                      kmod_lostfoundall
 363  *
 364  * Description:
 365  * Arguments:
 366  * Returns:
 367  *      Returns ...
 368  * Preconditions:
 369  */
 370 int
 371 kmod_lostfoundall(cfsd_kmod_object_t *kmod_object_p)
 372 {
 373         int error = 0;
 374         int xx = -1;
 375 
 376         dbug_enter("kmod_lostfoundall");
 377         dbug_precond(kmod_object_p);
 378 
 379         /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_LOSTFOUNDALL, 0); */
 380         if (xx)
 381                 error = errno;
 382         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 383         dbug_leave("kmod_lostfoundall");
 384         return (error);
 385 }
 386 /*
 387  *                      kmod_rofs
 388  *
 389  * Description:
 390  * Arguments:
 391  * Returns:
 392  *      Returns ...
 393  * Preconditions:
 394  */
 395 int
 396 kmod_rofs(cfsd_kmod_object_t *kmod_object_p)
 397 {
 398         int error = 0;
 399         int xx = -1;
 400 
 401         dbug_enter("kmod_rofs");
 402         dbug_precond(kmod_object_p);
 403 
 404         /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_ROFS, 0); */
 405         if (xx)
 406                 error = errno;
 407         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 408         dbug_leave("kmod_rofs");
 409         return (error);
 410 }
 411 #endif
 412 
 413 /*
 414  *                      kmod_rootfid
 415  *
 416  * Description:
 417  *      Fills in fidp with the fid of the root of the file system.
 418  * Arguments:
 419  *      fidp
 420  * Returns:
 421  *      Returns 0 for success, errno value for an error
 422  * Preconditions:
 423  *      precond(fidp)
 424  */
 425 int
 426 kmod_rootfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp)
 427 {
 428         int error = 0;
 429         int xx;
 430 
 431         dbug_enter("kmod_rootfid");
 432         dbug_precond(kmod_object_p);
 433         dbug_precond(fidp);
 434 
 435         xx = kmod_doioctl(kmod_object_p, CFSDCMD_ROOTFID, NULL, 0, fidp,
 436             sizeof (*fidp));
 437         if (xx)
 438                 error = errno;
 439         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 440         dbug_leave("kmod_rootfid");
 441         return (error);
 442 }
 443 
 444 
 445 /*
 446  *                      kmod_getstats
 447  *
 448  * Description:
 449  * Arguments:
 450  *      gsp
 451  * Returns:
 452  *      Returns ...
 453  * Preconditions:
 454  *      precond(gsp)
 455  */
 456 int
 457 kmod_getstats(cfsd_kmod_object_t *kmod_object_p, cachefsio_getstats_t *gsp)
 458 {
 459         int error = 0;
 460         int xx;
 461 
 462         dbug_enter("kmod_getstats");
 463         dbug_precond(kmod_object_p);
 464 
 465         dbug_precond(gsp);
 466 
 467         xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETSTATS, NULL, 0, gsp,
 468             sizeof (*gsp));
 469         if (xx)
 470                 error = errno;
 471         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 472         dbug_print(("ioctl", "total blocks %d", gsp->gs_total));
 473         dbug_print(("ioctl", "gc blocks %d", gsp->gs_gc));
 474         dbug_print(("ioctl", "active blocks %d", gsp->gs_active));
 475         dbug_print(("ioctl", "packed blocks %d", gsp->gs_packed));
 476         dbug_print(("ioctl", "free blocks %d", gsp->gs_free));
 477         dbug_print(("ioctl", "gctime %x", gsp->gs_gctime));
 478         dbug_leave("kmod_getstats");
 479         return (error);
 480 }
 481 
 482 /*
 483  * ------------------------------------------------------------
 484  *                      kmod_getinfo
 485  *
 486  * Description:
 487  * Arguments:
 488  *      filep
 489  * Returns:
 490  *      Returns ...
 491  * Preconditions:
 492  *      precond(filep)
 493  *      precond(infop)
 494  */
 495 int
 496 kmod_getinfo(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep,
 497         cachefsio_getinfo_t *infop)
 498 {
 499         int error = 0;
 500         int xx;
 501 
 502         dbug_enter("kmod_getinfo");
 503         dbug_precond(kmod_object_p);
 504 
 505         dbug_precond(filep);
 506         dbug_precond(infop);
 507 
 508         xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETINFO, filep,
 509             sizeof (*filep), infop, sizeof (*infop));
 510         if (xx)
 511                 error = errno;
 512 
 513         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 514         dbug_print(("ioctl", "   file cid %08x", filep->cid_fileno));
 515         if (xx == 0) {
 516                 dbug_print(("ioctl", "   modified %d  seq %d",
 517                     infop->gi_modified, infop->gi_seq));
 518                 dbug_print(("ioctl", "   name \"%s\"", infop->gi_name));
 519                 dbug_print(("ioctl", "   parent cid %08x",
 520                     infop->gi_pcid.cid_fileno));
 521                 infop->gi_attr.va_mask = AT_ALL;
 522                 kmod_print_attr(&infop->gi_attr);
 523         }
 524         dbug_leave("kmod_getinfo");
 525         return (error);
 526 }
 527 
 528 /*
 529  * ------------------------------------------------------------
 530  *                      kmod_cidtofid
 531  *
 532  * Description:
 533  * Arguments:
 534  *      cidp
 535  *      fidp
 536  * Returns:
 537  *      Returns ...
 538  * Preconditions:
 539  *      precond(cidp)
 540  *      precond(fidp)
 541  */
 542 int
 543 kmod_cidtofid(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp,
 544                 cfs_fid_t *fidp)
 545 {
 546         int error = 0;
 547         int xx;
 548 
 549         dbug_enter("kmod_cidtofid");
 550         dbug_precond(kmod_object_p);
 551 
 552         dbug_precond(cidp);
 553         dbug_precond(fidp);
 554 
 555         xx = kmod_doioctl(kmod_object_p, CFSDCMD_CIDTOFID, cidp, sizeof (*cidp),
 556             fidp, sizeof (*fidp));
 557         if (xx)
 558                 error = errno;
 559 
 560         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 561         dbug_print(("ioctl", "   cid %08x", cidp->cid_fileno));
 562         if (xx == 0) {
 563                 kmod_format_fid(kmod_object_p, fidp);
 564                 dbug_print(("ioctl", "   fid \"%s\"", kmod_object_p->i_fidbuf));
 565         }
 566         dbug_leave("kmod_cidtofid");
 567         return (error);
 568 }
 569 
 570 /*
 571  * ------------------------------------------------------------
 572  *                      kmod_getattrfid
 573  *
 574  * Description:
 575  * Arguments:
 576  *      fidp
 577  *      credp
 578  *      vattrp
 579  * Returns:
 580  *      Returns ...
 581  * Preconditions:
 582  *      precond(fidp)
 583  *      precond(credp)
 584  *      precond(vattrp)
 585  */
 586 int
 587 kmod_getattrfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp,
 588         dl_cred_t *credp, vattr_t *vattrp)
 589 {
 590         int error = 0;
 591         int xx;
 592         cachefsio_getattrfid_t info;
 593 
 594         dbug_enter("kmod_getattrfid");
 595         dbug_precond(kmod_object_p);
 596 
 597         dbug_precond(fidp);
 598         dbug_precond(credp);
 599         dbug_precond(vattrp);
 600 
 601         info.cg_backfid = *fidp;
 602 
 603         copy_cred(&info.cg_cred, credp);
 604 
 605         xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRFID, &info,
 606             sizeof (info), vattrp, sizeof (*vattrp));
 607         if (xx)
 608                 error = errno;
 609 
 610         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 611         kmod_format_fid(kmod_object_p, fidp);
 612         dbug_print(("ioctl", "   fid \"%s\"", kmod_object_p->i_fidbuf));
 613         kmod_print_cred(credp);
 614         if (xx == 0) {
 615                 vattrp->va_mask = AT_ALL;
 616                 kmod_print_attr(vattrp);
 617         }
 618         dbug_leave("kmod_getattrfid");
 619         return (error);
 620 }
 621 
 622 /*
 623  * ------------------------------------------------------------
 624  *                      kmod_getattrname
 625  *
 626  * Description:
 627  * Arguments:
 628  *      dirp
 629  *      name
 630  *      credp
 631  *      vattrp
 632  *      filep
 633  * Returns:
 634  *      Returns ...
 635  * Preconditions:
 636  *      precond(dirp)
 637  *      precond(name)
 638  *      precond(credp)
 639  */
 640 int
 641 kmod_getattrname(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp,
 642         const char *name, dl_cred_t *credp, vattr_t *vattrp, cfs_fid_t *filep)
 643 {
 644         cachefsio_getattrname_arg_t info;
 645         cachefsio_getattrname_return_t ret;
 646         int error = 0;
 647         int xx;
 648 
 649         dbug_enter("kmod_getattrname");
 650         dbug_precond(kmod_object_p);
 651 
 652         dbug_precond(dirp);
 653         dbug_precond(name);
 654         dbug_precond(credp);
 655 
 656         info.cg_dir = *dirp;
 657         dbug_assert(strlen(name) < (size_t)MAXNAMELEN);
 658         strlcpy(info.cg_name, name, sizeof (info.cg_name));
 659         copy_cred(&info.cg_cred, credp);
 660 
 661         xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRNAME, &info,
 662             sizeof (info), &ret, sizeof (ret));
 663         if (xx)
 664                 error = errno;
 665 
 666         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 667         kmod_format_fid(kmod_object_p, dirp);
 668         dbug_print(("ioctl", "   dir fid \"%s\"", kmod_object_p->i_fidbuf));
 669         dbug_print(("ioctl", "   name '%s'", info.cg_name));
 670         kmod_print_cred(credp);
 671         if (xx == 0) {
 672                 ret.cg_attr.va_mask = AT_ALL;
 673                 kmod_print_attr(&ret.cg_attr);
 674                 kmod_format_fid(kmod_object_p, &ret.cg_fid);
 675                 dbug_print(("ioctl", "   file fid \"%s\"",
 676                     kmod_object_p->i_fidbuf));
 677                 if (vattrp)
 678                         *vattrp = ret.cg_attr;
 679                 if (filep)
 680                         *filep = ret.cg_fid;
 681         }
 682         dbug_leave("kmod_getattrname");
 683         return (error);
 684 }
 685 
 686 /*
 687  * ------------------------------------------------------------
 688  *                      kmod_create
 689  *
 690  * Description:
 691  * Arguments:
 692  *      dirp
 693  *      namep
 694  *      vattrp
 695  *      exclusive
 696  *      mode
 697  *      credp
 698  *      newfidp
 699  *      mtimep
 700  *      ctimep
 701  * Returns:
 702  *      Returns ...
 703  * Preconditions:
 704  *      precond(dirp)
 705  *      precond(namep)
 706  *      precond(vattrp)
 707  *      precond(credp)
 708  */
 709 int
 710 kmod_create(cfsd_kmod_object_t *kmod_object_p,
 711         cfs_fid_t *dirp,
 712         const char *namep,
 713         const cfs_cid_t *cidp,
 714         vattr_t *vattrp,
 715         int exclusive,
 716         int mode,
 717         dl_cred_t *credp,
 718         cfs_fid_t *newfidp,
 719         cfs_timestruc_t *ctimep,
 720         cfs_timestruc_t *mtimep)
 721 {
 722         cachefsio_create_arg_t info;
 723         cachefsio_create_return_t ret;
 724         int error = 0;
 725         int xx;
 726 
 727         dbug_enter("kmod_create");
 728         dbug_precond(kmod_object_p);
 729 
 730         dbug_precond(dirp);
 731         dbug_precond(namep);
 732         dbug_precond(vattrp);
 733         dbug_precond(credp);
 734 
 735         info.cr_backfid = *dirp;
 736         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
 737         strlcpy(info.cr_name, namep, sizeof (info.cr_name));
 738         if (cidp) {
 739                 info.cr_cid = *cidp;
 740         } else {
 741                 info.cr_cid.cid_fileno = 0;
 742                 info.cr_cid.cid_flags = 0;
 743         }
 744         info.cr_va = *vattrp;
 745         info.cr_exclusive = exclusive;
 746         info.cr_mode = mode;
 747         copy_cred(&info.cr_cred, credp);
 748 
 749         xx = kmod_doioctl(kmod_object_p, CFSDCMD_CREATE, &info, sizeof (info),
 750             &ret, sizeof (ret));
 751         if (xx)
 752                 error = errno;
 753 
 754         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 755         kmod_format_fid(kmod_object_p, dirp);
 756         dbug_print(("ioctl", "   dir fid \"%s\"", kmod_object_p->i_fidbuf));
 757         dbug_print(("ioctl", "   name '%s', exclusive %d, mode 0%o",
 758             namep, exclusive, mode));
 759         kmod_print_attr(vattrp);
 760         kmod_print_cred(credp);
 761         if (xx == 0) {
 762                 if (newfidp)
 763                         *newfidp = ret.cr_newfid;
 764                 if (ctimep)
 765                         *ctimep = ret.cr_ctime;
 766                 if (mtimep)
 767                         *mtimep = ret.cr_mtime;
 768                 kmod_format_fid(kmod_object_p, &ret.cr_newfid);
 769                 dbug_print(("ioctl", "   created file fid \"%s\"",
 770                     kmod_object_p->i_fidbuf));
 771                 dbug_print(("ioctl", "   ctime %x %x",
 772                     ret.cr_ctime.tv_sec, ret.cr_ctime.tv_nsec));
 773                 dbug_print(("ioctl", "   mtime %x %x",
 774                     ret.cr_mtime.tv_sec, ret.cr_mtime.tv_nsec));
 775         }
 776         dbug_leave("kmod_create");
 777         return (error);
 778 }
 779 
 780 /*
 781  * ------------------------------------------------------------
 782  *                      kmod_pushback
 783  *
 784  * Description:
 785  * Arguments:
 786  *      filep
 787  *      fidp
 788  *      credp
 789  * Returns:
 790  *      Returns ...
 791  * Preconditions:
 792  *      precond(filep)
 793  *      precond(fidp)
 794  *      precond(credp)
 795  */
 796 int
 797 kmod_pushback(cfsd_kmod_object_t *kmod_object_p,
 798         cfs_cid_t *filep,
 799         cfs_fid_t *fidp,
 800         dl_cred_t *credp,
 801         cfs_timestruc_t *ctimep,
 802         cfs_timestruc_t *mtimep,
 803         int update)
 804 {
 805         cachefsio_pushback_arg_t info;
 806         cachefsio_pushback_return_t ret;
 807         int error = 0;
 808         int xx;
 809 
 810         dbug_enter("kmod_pushback");
 811         dbug_precond(kmod_object_p);
 812 
 813         dbug_precond(filep);
 814         dbug_precond(fidp);
 815         dbug_precond(credp);
 816 
 817         /* note: update is no longer used */
 818 
 819         info.pb_cid = *filep;
 820         info.pb_fid = *fidp;
 821         copy_cred(&info.pb_cred, credp);
 822 
 823         xx = kmod_doioctl(kmod_object_p, CFSDCMD_PUSHBACK, &info, sizeof (info),
 824             &ret, sizeof (ret));
 825         if (xx)
 826                 error = errno;
 827 
 828         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 829         dbug_print(("ioctl", "   cid %08x", filep->cid_fileno));
 830         kmod_format_fid(kmod_object_p, fidp);
 831         dbug_print(("ioctl", "   fid \"%s\"", kmod_object_p->i_fidbuf));
 832         kmod_print_cred(credp);
 833         if (xx == 0) {
 834                 if (ctimep)
 835                         *ctimep = ret.pb_ctime;
 836                 if (mtimep)
 837                         *mtimep = ret.pb_mtime;
 838                 dbug_print(("ioctl", "   ctime %x %x",
 839                     ret.pb_ctime.tv_sec, ret.pb_ctime.tv_nsec));
 840                 dbug_print(("ioctl", "   mtime %x %x",
 841                     ret.pb_mtime.tv_sec, ret.pb_mtime.tv_nsec));
 842         }
 843         dbug_leave("kmod_pushback");
 844         return (error);
 845 }
 846 
 847 
 848 /*
 849  * ------------------------------------------------------------
 850  *                      kmod_rename
 851  *
 852  * Description:
 853  * Arguments:
 854  *      olddir
 855  *      oldname
 856  *      newdir
 857  *      newname
 858  *      credp
 859  * Returns:
 860  *      Returns ...
 861  * Preconditions:
 862  *      precond(olddir)
 863  *      precond(oldname)
 864  *      precond(newdir)
 865  *      precond(newname)
 866  *      precond(credp)
 867  */
 868 int
 869 kmod_rename(cfsd_kmod_object_t *kmod_object_p,
 870         cfs_fid_t *olddir,
 871         const char *oldname,
 872         cfs_fid_t *newdir,
 873         const char *newname,
 874         const cfs_cid_t *cidp,
 875         dl_cred_t *credp,
 876         cfs_timestruc_t *ctimep,
 877         cfs_timestruc_t *delctimep,
 878         const cfs_cid_t *delcidp)
 879 {
 880         cachefsio_rename_arg_t info;
 881         cachefsio_rename_return_t ret;
 882         int error = 0;
 883         int xx;
 884 
 885         dbug_enter("kmod_rename");
 886         dbug_precond(kmod_object_p);
 887 
 888         dbug_precond(olddir);
 889         dbug_precond(oldname);
 890         dbug_precond(newdir);
 891         dbug_precond(newname);
 892         dbug_precond(credp);
 893         dbug_precond(ctimep);
 894 
 895         info.rn_olddir = *olddir;
 896         dbug_assert(strlen(oldname) < (size_t)MAXNAMELEN);
 897         strlcpy(info.rn_oldname, oldname, sizeof (info.rn_oldname));
 898         info.rn_newdir = *newdir;
 899         dbug_assert(strlen(newname) < (size_t)MAXNAMELEN);
 900         strlcpy(info.rn_newname, newname, sizeof (info.rn_newname));
 901         info.rn_cid = *cidp;
 902         copy_cred(&info.rn_cred, credp);
 903         info.rn_del_getctime = delctimep ? 1 : 0;
 904         info.rn_del_cid = *delcidp;
 905 
 906         xx = kmod_doioctl(kmod_object_p, CFSDCMD_RENAME, &info, sizeof (info),
 907             &ret, sizeof (ret));
 908         if (xx)
 909                 error = errno;
 910 
 911         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 912         kmod_format_fid(kmod_object_p, olddir);
 913         dbug_print(("ioctl", "   old dir fid \"%s\"", kmod_object_p->i_fidbuf));
 914         kmod_format_fid(kmod_object_p, newdir);
 915         dbug_print(("ioctl", "   new dir fid \"%s\"", kmod_object_p->i_fidbuf));
 916         dbug_print(("ioctl", "   old name '%s'  new name '%s'",
 917             oldname, newname));
 918         kmod_print_cred(credp);
 919         if (xx == 0) {
 920                 *ctimep = ret.rn_ctime;
 921                 dbug_print(("ioctl", "   ctime %x %x",
 922                     ctimep->tv_sec, ctimep->tv_nsec));
 923                 if (delctimep) {
 924                         *delctimep = ret.rn_del_ctime;
 925                         dbug_print(("ioctl", "   del ctime %x %x",
 926                             delctimep->tv_sec, delctimep->tv_nsec));
 927                 }
 928         }
 929         dbug_leave("kmod_rename");
 930         return (error);
 931 }
 932 
 933 /*
 934  * ------------------------------------------------------------
 935  *                      kmod_setattr
 936  *
 937  * Description:
 938  * Arguments:
 939  *      fidp
 940  *      vattrp
 941  *      flags
 942  *      credp
 943  * Returns:
 944  *      Returns ...
 945  * Preconditions:
 946  *      precond(fidp)
 947  *      precond(vattrp)
 948  *      precond(credp)
 949  */
 950 int
 951 kmod_setattr(cfsd_kmod_object_t *kmod_object_p,
 952         cfs_fid_t *fidp,
 953         const cfs_cid_t *cidp,
 954         vattr_t *vattrp,
 955         int flags,
 956         dl_cred_t *credp,
 957         cfs_timestruc_t *ctimep,
 958         cfs_timestruc_t *mtimep)
 959 {
 960         cachefsio_setattr_arg_t info;
 961         cachefsio_setattr_return_t ret;
 962         int error = 0;
 963         int xx;
 964 
 965         dbug_enter("kmod_setattr");
 966         dbug_precond(kmod_object_p);
 967 
 968         dbug_precond(fidp);
 969         dbug_precond(cidp);
 970         dbug_precond(vattrp);
 971         dbug_precond(credp);
 972         dbug_precond(ctimep);
 973         dbug_precond(mtimep);
 974 
 975         info.sa_backfid = *fidp;
 976         info.sa_cid = *cidp;
 977         info.sa_vattr = *vattrp;
 978         info.sa_flags = flags;
 979         copy_cred(&info.sa_cred, credp);
 980 
 981         xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETATTR, &info, sizeof (info),
 982             &ret, sizeof (ret));
 983         if (xx)
 984                 error = errno;
 985 
 986         dbug_print(("ioctl", "returns %d, error %d", xx, error));
 987         dbug_print(("ioctl", "   flags 0x%x", flags));
 988         kmod_format_fid(kmod_object_p, fidp);
 989         dbug_print(("ioctl", "   fid \"%s\"", kmod_object_p->i_fidbuf));
 990         kmod_print_attr(vattrp);
 991         kmod_print_cred(credp);
 992         if (xx == 0) {
 993                 *ctimep = ret.sa_ctime;
 994                 *mtimep = ret.sa_mtime;
 995                 dbug_print(("ioctl", "   ctime %x %x", ctimep->tv_sec,
 996                     ctimep->tv_nsec));
 997                 dbug_print(("ioctl", "   mtime %x %x", mtimep->tv_sec,
 998                     mtimep->tv_nsec));
 999         }
1000         dbug_leave("kmod_setattr");
1001         return (error);
1002 }
1003 
1004 /*
1005  * ------------------------------------------------------------
1006  *                      kmod_setsecattr
1007  *
1008  * Description:
1009  * Arguments:
1010  *      fidp
1011  *      aclcnt
1012  *      dfaclcnt
1013  *      acl
1014  *      flags
1015  *      credp
1016  * Returns:
1017  *      Returns ...
1018  * Preconditions:
1019  *      precond(fidp)
1020  *      precond(acl)
1021  *      precond(credp)
1022  *      precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES)
1023  */
1024 int
1025 kmod_setsecattr(cfsd_kmod_object_t *kmod_object_p,
1026         cfs_fid_t *fidp,
1027         const cfs_cid_t *cidp,
1028         ulong_t mask,
1029         int aclcnt,
1030         int dfaclcnt,
1031         const aclent_t *acl,
1032         dl_cred_t *credp,
1033         cfs_timestruc_t *ctimep,
1034         cfs_timestruc_t *mtimep)
1035 {
1036         cachefsio_setsecattr_arg_t info;
1037         cachefsio_setsecattr_return_t ret;
1038         int error = 0;
1039         int xx;
1040 
1041         dbug_enter("kmod_setsecattr");
1042         dbug_precond(kmod_object_p);
1043 
1044         dbug_precond(fidp);
1045         dbug_precond(cidp);
1046         dbug_precond(acl);
1047         dbug_precond(credp);
1048         dbug_precond(ctimep);
1049         dbug_precond(mtimep);
1050         dbug_precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES);
1051 
1052         info.sc_backfid = *fidp;
1053         info.sc_cid = *cidp;
1054         info.sc_mask = mask;
1055         info.sc_aclcnt = aclcnt;
1056         info.sc_dfaclcnt = dfaclcnt;
1057         memcpy(&info.sc_acl, acl, (aclcnt + dfaclcnt) * sizeof (aclent_t));
1058         copy_cred(&info.sc_cred, credp);
1059 
1060         xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETSECATTR, &info,
1061             sizeof (info), &ret, sizeof (ret));
1062         if (xx)
1063                 error = errno;
1064 
1065         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1066         kmod_format_fid(kmod_object_p, fidp);
1067         dbug_print(("ioctl", "   fid \"%s\"", kmod_object_p->i_fidbuf));
1068         dbug_print(("ioctl", "   aclcnt %d dfaclcnt %d", aclcnt, dfaclcnt));
1069         kmod_print_cred(credp);
1070         if (xx == 0) {
1071                 *ctimep = ret.sc_ctime;
1072                 *mtimep = ret.sc_mtime;
1073                 dbug_print(("ioctl", "   ctime %x %x", ctimep->tv_sec,
1074                     ctimep->tv_nsec));
1075                 dbug_print(("ioctl", "   mtime %x %x", mtimep->tv_sec,
1076                     mtimep->tv_nsec));
1077         }
1078         dbug_leave("kmod_setsecattr");
1079         return (error);
1080 }
1081 
1082 /*
1083  * ------------------------------------------------------------
1084  *                      kmod_remove
1085  *
1086  * Description:
1087  * Arguments:
1088  *      fidp
1089  *      namep
1090  *      credp
1091  *      ctimep
1092  * Returns:
1093  *      Returns ...
1094  * Preconditions:
1095  *      precond(fidp)
1096  *      precond(namep)
1097  *      precond(credp)
1098  */
1099 int
1100 kmod_remove(cfsd_kmod_object_t *kmod_object_p,
1101         const cfs_fid_t *fidp,
1102         const cfs_cid_t *cidp,
1103         const char *namep,
1104         const dl_cred_t *credp,
1105         cfs_timestruc_t *ctimep)
1106 {
1107         cachefsio_remove_t info;
1108         int len;
1109         int error = 0;
1110         int xx;
1111 
1112         dbug_enter("kmod_remove");
1113         dbug_precond(kmod_object_p);
1114 
1115         dbug_precond(fidp);
1116         dbug_precond(cidp);
1117         dbug_precond(namep);
1118         dbug_precond(credp);
1119 
1120         info.rm_fid = *fidp;
1121         info.rm_cid = *cidp;
1122         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
1123         strlcpy(info.rm_name, namep, sizeof (info.rm_name));
1124         copy_cred(&info.rm_cred, credp);
1125         info.rm_getctime = ctimep ? 1 : 0;
1126 
1127         if (ctimep)
1128                 len = sizeof (*ctimep);
1129         else
1130                 len = 0;
1131 
1132         xx = kmod_doioctl(kmod_object_p, CFSDCMD_REMOVE, &info, sizeof (info),
1133             ctimep, len);
1134         if (xx)
1135                 error = errno;
1136 
1137         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1138         kmod_format_fid(kmod_object_p, fidp);
1139         dbug_print(("ioctl", "   fid '%s'", kmod_object_p->i_fidbuf));
1140         dbug_print(("ioctl", "   name '%s'", namep));
1141         kmod_print_cred(credp);
1142         if ((xx == 0) && ctimep) {
1143                 dbug_print(("ioctl", "   ctime %x %x", ctimep->tv_sec,
1144                     ctimep->tv_nsec));
1145         }
1146         dbug_leave("kmod_remove");
1147         return (error);
1148 }
1149 
1150 /*
1151  * ------------------------------------------------------------
1152  *                      kmod_link
1153  *
1154  * Description:
1155  * Arguments:
1156  *      dirfidp
1157  *      namep
1158  *      filefidp
1159  *      credp
1160  *      ctimep
1161  * Returns:
1162  *      Returns ...
1163  * Preconditions:
1164  *      precond(dirfidp)
1165  *      precond(namep)
1166  *      precond(filefidp)
1167  *      precond(credp)
1168  */
1169 int
1170 kmod_link(cfsd_kmod_object_t *kmod_object_p,
1171         const cfs_fid_t *dirfidp,
1172         const char *namep,
1173         const cfs_fid_t *filefidp,
1174         const cfs_cid_t *cidp,
1175         const dl_cred_t *credp,
1176         cfs_timestruc_t *ctimep)
1177 {
1178         cachefsio_link_t info;
1179         int error = 0;
1180         int xx;
1181 
1182         dbug_enter("kmod_link");
1183         dbug_precond(kmod_object_p);
1184 
1185         dbug_precond(dirfidp);
1186         dbug_precond(namep);
1187         dbug_precond(filefidp);
1188         dbug_precond(cidp);
1189         dbug_precond(credp);
1190         dbug_precond(ctimep);
1191 
1192         info.ln_dirfid = *dirfidp;
1193         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
1194         strlcpy(info.ln_name, namep, sizeof (info.ln_name));
1195         info.ln_filefid = *filefidp;
1196         info.ln_cid = *cidp;
1197         copy_cred(&info.ln_cred, credp);
1198 
1199         xx = kmod_doioctl(kmod_object_p, CFSDCMD_LINK, &info, sizeof (info),
1200             ctimep, sizeof (*ctimep));
1201         if (xx)
1202                 error = errno;
1203 
1204         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1205         kmod_format_fid(kmod_object_p, dirfidp);
1206         dbug_print(("ioctl", "   dir fid '%s'", kmod_object_p->i_fidbuf));
1207         dbug_print(("ioctl", "   name '%s'", namep));
1208         kmod_format_fid(kmod_object_p, filefidp);
1209         dbug_print(("ioctl", "   file fid '%s'", kmod_object_p->i_fidbuf));
1210         kmod_print_cred(credp);
1211         if (xx == 0) {
1212                 dbug_print(("ioctl", "   ctime %x %x", ctimep->tv_sec,
1213                     ctimep->tv_nsec));
1214         }
1215         dbug_leave("kmod_link");
1216         return (error);
1217 }
1218 
1219 /*
1220  * ------------------------------------------------------------
1221  *                      kmod_mkdir
1222  *
1223  * Description:
1224  * Arguments:
1225  *      dirfidp
1226  *      namep
1227  *      vattrp
1228  *      credp
1229  *      newfidp
1230  * Returns:
1231  *      Returns ...
1232  * Preconditions:
1233  *      precond(dirfidp)
1234  *      precond(namep)
1235  *      precond(vattrp)
1236  *      precond(credp)
1237  *      precond(newfidp)
1238  */
1239 int
1240 kmod_mkdir(cfsd_kmod_object_t *kmod_object_p,
1241         const cfs_fid_t *dirfidp,
1242         const char *namep,
1243         const cfs_cid_t *cidp,
1244         const vattr_t *vattrp,
1245         const dl_cred_t *credp,
1246         cfs_fid_t *newfidp)
1247 {
1248         cachefsio_mkdir_t info;
1249         int error = 0;
1250         int xx;
1251 
1252         dbug_enter("kmod_mkdir");
1253         dbug_precond(kmod_object_p);
1254 
1255         dbug_precond(dirfidp);
1256         dbug_precond(namep);
1257         dbug_precond(cidp);
1258         dbug_precond(vattrp);
1259         dbug_precond(credp);
1260         dbug_precond(newfidp);
1261 
1262         info.md_dirfid = *dirfidp;
1263         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
1264         strlcpy(info.md_name, namep, sizeof (info.md_name));
1265         info.md_cid = *cidp;
1266         info.md_vattr = *vattrp;
1267         copy_cred(&info.md_cred, credp);
1268 
1269         xx = kmod_doioctl(kmod_object_p, CFSDCMD_MKDIR, &info, sizeof (info),
1270             newfidp, sizeof (*newfidp));
1271         if (xx)
1272                 error = errno;
1273 
1274         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1275         kmod_format_fid(kmod_object_p, dirfidp);
1276         dbug_print(("ioctl", "   dir fid '%s'", kmod_object_p->i_fidbuf));
1277         dbug_print(("ioctl", "   name '%s'", namep));
1278         kmod_print_attr(vattrp);
1279         kmod_print_cred(credp);
1280         if (xx == 0) {
1281                 kmod_format_fid(kmod_object_p, newfidp);
1282                 dbug_print(("ioctl", "   file fid '%s'",
1283                     kmod_object_p->i_fidbuf));
1284         }
1285         dbug_leave("kmod_mkdir");
1286         return (error);
1287 }
1288 
1289 /*
1290  * ------------------------------------------------------------
1291  *                      kmod_rmdir
1292  *
1293  * Description:
1294  * Arguments:
1295  *      dirfidp
1296  *      namep
1297  *      credp
1298  * Returns:
1299  *      Returns ...
1300  * Preconditions:
1301  *      precond(dirfidp)
1302  *      precond(namep)
1303  *      precond(credp)
1304  */
1305 int
1306 kmod_rmdir(cfsd_kmod_object_t *kmod_object_p,
1307         const cfs_fid_t *dirfidp,
1308         const char *namep,
1309         const dl_cred_t *credp)
1310 {
1311         cachefsio_rmdir_t info;
1312         int error = 0;
1313         int xx;
1314 
1315         dbug_enter("kmod_rmdir");
1316         dbug_precond(kmod_object_p);
1317 
1318         dbug_precond(dirfidp);
1319         dbug_precond(namep);
1320         dbug_precond(credp);
1321 
1322         info.rd_dirfid = *dirfidp;
1323         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
1324         strlcpy(info.rd_name, namep, sizeof (info.rd_name));
1325         copy_cred(&info.rd_cred, credp);
1326 
1327         xx = kmod_doioctl(kmod_object_p, CFSDCMD_RMDIR, &info, sizeof (info),
1328             NULL, 0);
1329         if (xx)
1330                 error = errno;
1331 
1332         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1333         kmod_format_fid(kmod_object_p, dirfidp);
1334         dbug_print(("ioctl", "   dir fid '%s'", kmod_object_p->i_fidbuf));
1335         dbug_print(("ioctl", "   name '%s'", namep));
1336         kmod_print_cred(credp);
1337         dbug_leave("kmod_rmdir");
1338         return (error);
1339 }
1340 
1341 /*
1342  * ------------------------------------------------------------
1343  *                      kmod_symlink
1344  *
1345  * Description:
1346  * Arguments:
1347  *      dirfidp
1348  *      namep
1349  *      linkvalp
1350  *      vattrp
1351  *      credp
1352  *      ctimep
1353  *      mtimep
1354  * Returns:
1355  *      Returns ...
1356  * Preconditions:
1357  *      precond(dirfidp)
1358  *      precond(namep)
1359  *      precond(linkvalp)
1360  *      precond(vattrp)
1361  *      precond(credp)
1362  *      precond(ctimep)
1363  *      precond(mtimep)
1364  */
1365 int
1366 kmod_symlink(cfsd_kmod_object_t *kmod_object_p,
1367         const cfs_fid_t *dirfidp,
1368         const char *namep,
1369         const cfs_cid_t *cidp,
1370         const char *linkvalp,
1371         const vattr_t *vattrp,
1372         const dl_cred_t *credp,
1373         cfs_fid_t *newfidp,
1374         cfs_timestruc_t *ctimep,
1375         cfs_timestruc_t *mtimep)
1376 {
1377         cachefsio_symlink_arg_t info;
1378         cachefsio_symlink_return_t ret;
1379         int error = 0;
1380         int xx;
1381 
1382         dbug_enter("kmod_symlink");
1383         dbug_precond(kmod_object_p);
1384 
1385         dbug_precond(dirfidp);
1386         dbug_precond(namep);
1387         dbug_precond(cidp);
1388         dbug_precond(linkvalp);
1389         dbug_precond(vattrp);
1390         dbug_precond(credp);
1391         dbug_precond(newfidp);
1392         dbug_precond(ctimep);
1393         dbug_precond(mtimep);
1394 
1395         info.sy_dirfid = *dirfidp;
1396         dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
1397         strlcpy(info.sy_name, namep, sizeof (info.sy_name));
1398         dbug_assert(strlen(linkvalp) < (size_t)MAXPATHLEN);
1399         info.sy_cid = *cidp;
1400         strlcpy(info.sy_link, linkvalp, sizeof (info.sy_link));
1401         info.sy_vattr = *vattrp;
1402         copy_cred(&info.sy_cred, credp);
1403 
1404         xx = kmod_doioctl(kmod_object_p, CFSDCMD_SYMLINK, &info, sizeof (info),
1405             &ret, sizeof (ret));
1406         if (xx)
1407                 error = errno;
1408 
1409         dbug_print(("ioctl", "returns %d, error %d", xx, error));
1410         kmod_format_fid(kmod_object_p, dirfidp);
1411         dbug_print(("ioctl", "   dir fid '%s'", kmod_object_p->i_fidbuf));
1412         dbug_print(("ioctl", "   name '%s'", namep));
1413         dbug_print(("ioctl", "   link '%s'", linkvalp));
1414         kmod_print_attr(vattrp);
1415         kmod_print_cred(credp);
1416         if (xx == 0) {
1417                 *ctimep = ret.sy_ctime;
1418                 *mtimep = ret.sy_mtime;
1419                 *newfidp = ret.sy_newfid;
1420                 dbug_print(("ioctl", "   ctime %x %x", ctimep->tv_sec,
1421                     ctimep->tv_nsec));
1422                 dbug_print(("ioctl", "   mtime %x %x", mtimep->tv_sec,
1423                     mtimep->tv_nsec));
1424                 kmod_format_fid(kmod_object_p, newfidp);
1425                 dbug_print(("ioctl", "   child fid '%s'",
1426                     kmod_object_p->i_fidbuf));
1427         }
1428         dbug_leave("kmod_symlink");
1429         return (error);
1430 }
1431 #ifndef DBUG_OFF
1432 /*
1433  * ------------------------------------------------------------
1434  *                      kmod_format_fid
1435  *
1436  * Description:
1437  * Arguments:
1438  *      fidp
1439  * Returns:
1440  * Preconditions:
1441  *      precond(fidp)
1442  */
1443 void
1444 kmod_format_fid(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp)
1445 {
1446         uint_t val;
1447         int index;
1448         char format[10];
1449         kmod_object_p->i_fidbuf[0] = '\0';
1450 
1451         for (index = 0; index < (int)fidp->fid_len; index += sizeof (uint_t)) {
1452                 memcpy(&val, &fidp->fid_data[index], sizeof (uint_t));
1453                 snprintf(format, sizeof (format), "%08x ", val);
1454                 strlcat(kmod_object_p->i_fidbuf, format,
1455                     sizeof (kmod_object_p->i_fidbuf));
1456         }
1457 }
1458 
1459 /*
1460  * ------------------------------------------------------------
1461  *                      kmod_print_cred
1462  *
1463  * Description:
1464  * Arguments:
1465  *      credp
1466  * Returns:
1467  * Preconditions:
1468  *      precond(credp)
1469  */
1470 void
1471 kmod_print_cred(const dl_cred_t *credp)
1472 {
1473         char buf[100];
1474         char format[10];
1475         int xx;
1476 
1477         dbug_enter("kmod_print_cred");
1478         dbug_precond(credp);
1479 
1480         buf[0] = '\0';
1481         dbug_print(("ioctl", "credentials"));
1482         dbug_print(("ioctl", "  uid %d, gid %d",
1483             credp->cr_uid, credp->cr_gid));
1484         dbug_print(("ioctl", "  ruid %d, rgid %d, suid %d, sgid %d",
1485             credp->cr_ruid, credp->cr_rgid,
1486             credp->cr_suid, credp->cr_sgid));
1487 
1488         for (xx = 0; xx < credp->cr_ngroups; xx++) {
1489                 snprintf(format, sizeof (format), " %d", credp->cr_groups[xx]);
1490                 strlcat(buf, format, sizeof (buf));
1491         }
1492 
1493         dbug_print(("ioctl", "  ngroups %d,  %s", credp->cr_ngroups, buf));
1494         dbug_leave("kmod_print_cred");
1495 }
1496 
1497 /*
1498  * ------------------------------------------------------------
1499  *                      kmod_print_attr
1500  *
1501  * Description:
1502  * Arguments:
1503  *      vattrp
1504  * Returns:
1505  * Preconditions:
1506  *      precond(vattrp)
1507  */
1508 void
1509 kmod_print_attr(const vattr_t *vp)
1510 {
1511         dbug_enter("kmod_print_attr");
1512         dbug_precond(vp);
1513 
1514         dbug_print(("ioctl", "attributes"));
1515         dbug_print(("ioctl", "  mask 0x%x", vp->va_mask));
1516         if (vp->va_mask & AT_TYPE)
1517                 dbug_print(("ioctl", "  type %d", vp->va_type));
1518         if (vp->va_mask & AT_MODE)
1519                 dbug_print(("ioctl", "  mode 0%o", vp->va_mode));
1520         if (vp->va_mask & AT_UID)
1521                 dbug_print(("ioctl", "  uid %d", vp->va_uid));
1522         if (vp->va_mask & AT_GID)
1523                 dbug_print(("ioctl", "  gid %d", vp->va_gid));
1524         if (vp->va_mask & AT_FSID)
1525                 dbug_print(("ioctl", "  fsid %08x", vp->va_fsid));
1526         if (vp->va_mask & AT_NODEID)
1527                 dbug_print(("ioctl", "  nodeid %08x", vp->va_nodeid));
1528         if (vp->va_mask & AT_NLINK)
1529                 dbug_print(("ioctl", "  nlink %d", vp->va_nlink));
1530         if (vp->va_mask & AT_SIZE)
1531                 dbug_print(("ioctl", "  size %d", vp->va_size));
1532         if (vp->va_mask & AT_ATIME)
1533                 dbug_print(("ioctl", "  atime %08x %08x",
1534                     vp->va_atime.tv_sec, vp->va_atime.tv_nsec));
1535         if (vp->va_mask & AT_MTIME)
1536                 dbug_print(("ioctl", "  mtime %08x %08x",
1537                     vp->va_mtime.tv_sec, vp->va_mtime.tv_nsec));
1538         if (vp->va_mask & AT_CTIME)
1539                 dbug_print(("ioctl", "  ctime %08x %08x",
1540                     vp->va_ctime.tv_sec, vp->va_ctime.tv_nsec));
1541         if (vp->va_mask & AT_RDEV)
1542                 dbug_print(("ioctl", "  rdev %08x", vp->va_rdev));
1543         if (vp->va_mask & AT_BLKSIZE)
1544                 dbug_print(("ioctl", "  blksize %08x", vp->va_blksize));
1545         if (vp->va_mask & AT_NBLOCKS)
1546                 dbug_print(("ioctl", "  nblocks %d", vp->va_nblocks));
1547         if (vp->va_mask & AT_SEQ)
1548                 dbug_print(("ioctl", "  seq %d", vp->va_seq));
1549         dbug_leave("kmod_print_attr");
1550 }
1551 #endif /* DBUG_OFF */
1552 /*
1553  *                      kmod_doioctl
1554  *
1555  * Description:
1556  *      Helper routine for others in this file.  Just packages up
1557  *      arguments and does the ioctl operation.
1558  * Arguments:
1559  *      cmd
1560  *      sdata
1561  *      slen
1562  *      rdata
1563  *      rlen
1564  * Returns:
1565  *      Returns the result of the ioctl operation.
1566  * Preconditions:
1567  */
1568 int
1569 kmod_doioctl(cfsd_kmod_object_t *kmod_object_p,
1570         enum cfsdcmd_cmds cmd,
1571         void *sdata,
1572         int slen,
1573         void *rdata,
1574         int rlen)
1575 {
1576         cachefsio_dcmd_t dcmd;
1577         int xx;
1578 
1579         dbug_enter("kmod_doioctl");
1580         dbug_precond(kmod_object_p);
1581         dcmd.d_cmd = cmd;
1582         dcmd.d_sdata = sdata;
1583         dcmd.d_slen = slen;
1584         dcmd.d_rdata = rdata;
1585         dcmd.d_rlen = rlen;
1586         dbug_print(("ioctl", "about to do cmd = %d", cmd));
1587         xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_DCMD, &dcmd);
1588         if (xx) {
1589                 dbug_print(("ioctl", "ioctl errno = %d", errno));
1590         }
1591         dbug_leave("kmod_doioctl");
1592         return (xx);
1593 }