/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Source file for the cfsd_kmod class. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cfsd.h" #include "cfsd_kmod.h" /* * copy_cred (copy dl_cred_t followed by a list of gid_t) */ static void copy_cred(dl_cred_t *dst, const dl_cred_t *src) { int n = src->cr_ngroups; if (n > NGROUPS_MAX_DEFAULT) n = NGROUPS_MAX_DEFAULT; (void) memcpy(dst, src, sizeof (*dst) + (n - 1) * sizeof (gid_t)); dst->cr_ngroups = n; } /* * ------------------------------------------------------------ * cfsd_kmod_create * * Description: * Arguments: * Returns: * Preconditions: */ cfsd_kmod_object_t * cfsd_kmod_create(void) { cfsd_kmod_object_t *kmod_object_p; dbug_enter("cfsd_kmod_create"); kmod_object_p = cfsd_calloc(sizeof (cfsd_kmod_object_t)); kmod_object_p->i_fd = -1; dbug_leave("cfsd_kmod_create"); return (kmod_object_p); } /* * ------------------------------------------------------------ * cfsd_kmod_destory * * Description: * Arguments: * Returns: * Preconditions: */ void cfsd_kmod_destroy(cfsd_kmod_object_t *kmod_object_p) { dbug_enter("cfsd_kmod_destroy"); dbug_precond(kmod_object_p); /* clean up old stuff */ kmod_shutdown(kmod_object_p); cfsd_free(kmod_object_p); dbug_leave("cfsd_kmod_destroy"); } /* * ------------------------------------------------------------ * kmod_setup * * Description: * Arguments: * path * Returns: * Returns ... * Preconditions: * precond(path) */ int kmod_setup(cfsd_kmod_object_t *kmod_object_p, const char *path) { int xx; int error; dbug_enter("kmod_setup"); dbug_precond(kmod_object_p); dbug_precond(path); /* clean up old stuff */ kmod_shutdown(kmod_object_p); /* try to open the file */ dbug_assert(kmod_object_p->i_fd == -1); kmod_object_p->i_fd = open(path, O_RDONLY); /* return result */ if (kmod_object_p->i_fd == -1) { xx = errno; dbug_print(("err", "open of %s failed %d", path, xx)); } else { xx = 0; strlcpy(kmod_object_p->i_path, path, sizeof (kmod_object_p->i_path)); dbug_print(("info", "opened %s on fd %d", path, kmod_object_p->i_fd)); /* tell the cachefs kmod we are here */ xx = kmod_doioctl(kmod_object_p, CFSDCMD_DAEMONID, NULL, 0, NULL, 0); if (xx) { error = errno; dbug_print(("ioctl", "daemonid error %d", error)); } } dbug_leave("kmod_setup"); return (xx); } /* * kmod_shutdown * * Description: * Arguments: * Returns: * Preconditions: */ void kmod_shutdown(cfsd_kmod_object_t *kmod_object_p) { dbug_enter("kmod_shutdown"); dbug_precond(kmod_object_p); /* close down the old fd if necessary */ if (kmod_object_p->i_fd >= 0) { if (close(kmod_object_p->i_fd)) dbug_print(("err", "cannot close kmod fd, %d", errno)); } kmod_object_p->i_fd = -1; dbug_leave("kmod_shutdown"); } /* * ------------------------------------------------------------ * kmod_xwait * * Description: * Arguments: * Returns: * Returns ... * Preconditions: */ int kmod_xwait(cfsd_kmod_object_t *kmod_object_p) { int xx; int error = 0; dbug_enter("kmod_xwait"); dbug_precond(kmod_object_p); xx = kmod_doioctl(kmod_object_p, CFSDCMD_XWAIT, NULL, 0, NULL, 0); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_leave("kmod_xwait"); return (error); } /* * ------------------------------------------------------------ * kmod_stateget * * Description: * Arguments: * Returns: * Returns ... * Preconditions: */ int kmod_stateget(cfsd_kmod_object_t *kmod_object_p) { int state; int xx; dbug_enter("kmod_stateget"); dbug_precond(kmod_object_p); xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATEGET, NULL, 0, &state, sizeof (state)); dbug_print(("ioctl", "returns %d, state %d", xx, state)); if (xx == -1) { /* XXX do what? */ dbug_assert(0); } dbug_leave("kmod_stateget"); return (state); } /* * ------------------------------------------------------------ * kmod_stateset * * Description: * Arguments: * state * Returns: * Returns ... * Preconditions: */ int kmod_stateset(cfsd_kmod_object_t *kmod_object_p, int state) { int xx; int error = 0; dbug_enter("kmod_stateset"); dbug_precond(kmod_object_p); xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATESET, &state, sizeof (state), NULL, 0); if (xx) error = errno; dbug_print(("ioctl", "returns %d, state set to %d", xx, state)); dbug_leave("kmod_stateset"); return (error); } /* * ------------------------------------------------------------ * kmod_exists * * Description: * Arguments: * cidp * Returns: * Returns ... * Preconditions: * precond(cidp) */ int kmod_exists(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp) { int xx; int error = 0; dbug_enter("kmod_exists"); dbug_precond(kmod_object_p); dbug_precond(cidp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_EXISTS, cidp, sizeof (cfs_cid_t), NULL, 0); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " cid %08x", cidp->cid_fileno)); dbug_leave("kmod_exists"); return (error); } /* * ------------------------------------------------------------ * kmod_lostfound * * Description: * Arguments: * cidp * Returns: * Returns ... * Preconditions: * precond(cidp) */ int kmod_lostfound(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp, const char *namep, char *newnamep) { cachefsio_lostfound_arg_t info; cachefsio_lostfound_return_t ret; int error = 0; int xx; dbug_enter("kmod_lostfound"); dbug_precond(kmod_object_p); dbug_precond(cidp); dbug_precond(namep); dbug_precond(newnamep); dbug_precond(strlen(namep) < (size_t)MAXNAMELEN); info.lf_cid = *cidp; strlcpy(info.lf_name, namep, sizeof (info.lf_name)); xx = kmod_doioctl(kmod_object_p, CFSDCMD_LOSTFOUND, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " cid %08x", cidp->cid_fileno)); dbug_print(("ioctl", " suggested name '%s'", namep)); if (xx == 0) { dbug_print(("ioctl", " new name '%s'", ret.lf_name)); dbug_assert(strlen(ret.lf_name) < (size_t)MAXNAMELEN); if (newnamep) strlcpy(newnamep, ret.lf_name, MAXNAMELEN); } dbug_leave("kmod_lostfound"); return (error); } #if 0 /* * ------------------------------------------------------------ * kmod_lostfoundall * * Description: * Arguments: * Returns: * Returns ... * Preconditions: */ int kmod_lostfoundall(cfsd_kmod_object_t *kmod_object_p) { int error = 0; int xx = -1; dbug_enter("kmod_lostfoundall"); dbug_precond(kmod_object_p); /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_LOSTFOUNDALL, 0); */ if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_leave("kmod_lostfoundall"); return (error); } /* * kmod_rofs * * Description: * Arguments: * Returns: * Returns ... * Preconditions: */ int kmod_rofs(cfsd_kmod_object_t *kmod_object_p) { int error = 0; int xx = -1; dbug_enter("kmod_rofs"); dbug_precond(kmod_object_p); /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_ROFS, 0); */ if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_leave("kmod_rofs"); return (error); } #endif /* * kmod_rootfid * * Description: * Fills in fidp with the fid of the root of the file system. * Arguments: * fidp * Returns: * Returns 0 for success, errno value for an error * Preconditions: * precond(fidp) */ int kmod_rootfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp) { int error = 0; int xx; dbug_enter("kmod_rootfid"); dbug_precond(kmod_object_p); dbug_precond(fidp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_ROOTFID, NULL, 0, fidp, sizeof (*fidp)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_leave("kmod_rootfid"); return (error); } /* * kmod_getstats * * Description: * Arguments: * gsp * Returns: * Returns ... * Preconditions: * precond(gsp) */ int kmod_getstats(cfsd_kmod_object_t *kmod_object_p, cachefsio_getstats_t *gsp) { int error = 0; int xx; dbug_enter("kmod_getstats"); dbug_precond(kmod_object_p); dbug_precond(gsp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETSTATS, NULL, 0, gsp, sizeof (*gsp)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", "total blocks %d", gsp->gs_total)); dbug_print(("ioctl", "gc blocks %d", gsp->gs_gc)); dbug_print(("ioctl", "active blocks %d", gsp->gs_active)); dbug_print(("ioctl", "packed blocks %d", gsp->gs_packed)); dbug_print(("ioctl", "free blocks %d", gsp->gs_free)); dbug_print(("ioctl", "gctime %x", gsp->gs_gctime)); dbug_leave("kmod_getstats"); return (error); } /* * ------------------------------------------------------------ * kmod_getinfo * * Description: * Arguments: * filep * Returns: * Returns ... * Preconditions: * precond(filep) * precond(infop) */ int kmod_getinfo(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep, cachefsio_getinfo_t *infop) { int error = 0; int xx; dbug_enter("kmod_getinfo"); dbug_precond(kmod_object_p); dbug_precond(filep); dbug_precond(infop); xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETINFO, filep, sizeof (*filep), infop, sizeof (*infop)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " file cid %08x", filep->cid_fileno)); if (xx == 0) { dbug_print(("ioctl", " modified %d seq %d", infop->gi_modified, infop->gi_seq)); dbug_print(("ioctl", " name \"%s\"", infop->gi_name)); dbug_print(("ioctl", " parent cid %08x", infop->gi_pcid.cid_fileno)); infop->gi_attr.va_mask = AT_ALL; kmod_print_attr(&infop->gi_attr); } dbug_leave("kmod_getinfo"); return (error); } /* * ------------------------------------------------------------ * kmod_cidtofid * * Description: * Arguments: * cidp * fidp * Returns: * Returns ... * Preconditions: * precond(cidp) * precond(fidp) */ int kmod_cidtofid(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp, cfs_fid_t *fidp) { int error = 0; int xx; dbug_enter("kmod_cidtofid"); dbug_precond(kmod_object_p); dbug_precond(cidp); dbug_precond(fidp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_CIDTOFID, cidp, sizeof (*cidp), fidp, sizeof (*fidp)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " cid %08x", cidp->cid_fileno)); if (xx == 0) { kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf)); } dbug_leave("kmod_cidtofid"); return (error); } /* * ------------------------------------------------------------ * kmod_getattrfid * * Description: * Arguments: * fidp * credp * vattrp * Returns: * Returns ... * Preconditions: * precond(fidp) * precond(credp) * precond(vattrp) */ int kmod_getattrfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp, dl_cred_t *credp, vattr_t *vattrp) { int error = 0; int xx; cachefsio_getattrfid_t info; dbug_enter("kmod_getattrfid"); dbug_precond(kmod_object_p); dbug_precond(fidp); dbug_precond(credp); dbug_precond(vattrp); info.cg_backfid = *fidp; copy_cred(&info.cg_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRFID, &info, sizeof (info), vattrp, sizeof (*vattrp)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf)); kmod_print_cred(credp); if (xx == 0) { vattrp->va_mask = AT_ALL; kmod_print_attr(vattrp); } dbug_leave("kmod_getattrfid"); return (error); } /* * ------------------------------------------------------------ * kmod_getattrname * * Description: * Arguments: * dirp * name * credp * vattrp * filep * Returns: * Returns ... * Preconditions: * precond(dirp) * precond(name) * precond(credp) */ int kmod_getattrname(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp, const char *name, dl_cred_t *credp, vattr_t *vattrp, cfs_fid_t *filep) { cachefsio_getattrname_arg_t info; cachefsio_getattrname_return_t ret; int error = 0; int xx; dbug_enter("kmod_getattrname"); dbug_precond(kmod_object_p); dbug_precond(dirp); dbug_precond(name); dbug_precond(credp); info.cg_dir = *dirp; dbug_assert(strlen(name) < (size_t)MAXNAMELEN); strlcpy(info.cg_name, name, sizeof (info.cg_name)); copy_cred(&info.cg_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRNAME, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirp); dbug_print(("ioctl", " dir fid \"%s\"", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", info.cg_name)); kmod_print_cred(credp); if (xx == 0) { ret.cg_attr.va_mask = AT_ALL; kmod_print_attr(&ret.cg_attr); kmod_format_fid(kmod_object_p, &ret.cg_fid); dbug_print(("ioctl", " file fid \"%s\"", kmod_object_p->i_fidbuf)); if (vattrp) *vattrp = ret.cg_attr; if (filep) *filep = ret.cg_fid; } dbug_leave("kmod_getattrname"); return (error); } /* * ------------------------------------------------------------ * kmod_create * * Description: * Arguments: * dirp * namep * vattrp * exclusive * mode * credp * newfidp * mtimep * ctimep * Returns: * Returns ... * Preconditions: * precond(dirp) * precond(namep) * precond(vattrp) * precond(credp) */ int kmod_create(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp, const char *namep, const cfs_cid_t *cidp, vattr_t *vattrp, int exclusive, int mode, dl_cred_t *credp, cfs_fid_t *newfidp, cfs_timestruc_t *ctimep, cfs_timestruc_t *mtimep) { cachefsio_create_arg_t info; cachefsio_create_return_t ret; int error = 0; int xx; dbug_enter("kmod_create"); dbug_precond(kmod_object_p); dbug_precond(dirp); dbug_precond(namep); dbug_precond(vattrp); dbug_precond(credp); info.cr_backfid = *dirp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.cr_name, namep, sizeof (info.cr_name)); if (cidp) { info.cr_cid = *cidp; } else { info.cr_cid.cid_fileno = 0; info.cr_cid.cid_flags = 0; } info.cr_va = *vattrp; info.cr_exclusive = exclusive; info.cr_mode = mode; copy_cred(&info.cr_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_CREATE, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirp); dbug_print(("ioctl", " dir fid \"%s\"", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s', exclusive %d, mode 0%o", namep, exclusive, mode)); kmod_print_attr(vattrp); kmod_print_cred(credp); if (xx == 0) { if (newfidp) *newfidp = ret.cr_newfid; if (ctimep) *ctimep = ret.cr_ctime; if (mtimep) *mtimep = ret.cr_mtime; kmod_format_fid(kmod_object_p, &ret.cr_newfid); dbug_print(("ioctl", " created file fid \"%s\"", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " ctime %x %x", ret.cr_ctime.tv_sec, ret.cr_ctime.tv_nsec)); dbug_print(("ioctl", " mtime %x %x", ret.cr_mtime.tv_sec, ret.cr_mtime.tv_nsec)); } dbug_leave("kmod_create"); return (error); } /* * ------------------------------------------------------------ * kmod_pushback * * Description: * Arguments: * filep * fidp * credp * Returns: * Returns ... * Preconditions: * precond(filep) * precond(fidp) * precond(credp) */ int kmod_pushback(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep, cfs_fid_t *fidp, dl_cred_t *credp, cfs_timestruc_t *ctimep, cfs_timestruc_t *mtimep, int update) { cachefsio_pushback_arg_t info; cachefsio_pushback_return_t ret; int error = 0; int xx; dbug_enter("kmod_pushback"); dbug_precond(kmod_object_p); dbug_precond(filep); dbug_precond(fidp); dbug_precond(credp); /* note: update is no longer used */ info.pb_cid = *filep; info.pb_fid = *fidp; copy_cred(&info.pb_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_PUSHBACK, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " cid %08x", filep->cid_fileno)); kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf)); kmod_print_cred(credp); if (xx == 0) { if (ctimep) *ctimep = ret.pb_ctime; if (mtimep) *mtimep = ret.pb_mtime; dbug_print(("ioctl", " ctime %x %x", ret.pb_ctime.tv_sec, ret.pb_ctime.tv_nsec)); dbug_print(("ioctl", " mtime %x %x", ret.pb_mtime.tv_sec, ret.pb_mtime.tv_nsec)); } dbug_leave("kmod_pushback"); return (error); } /* * ------------------------------------------------------------ * kmod_rename * * Description: * Arguments: * olddir * oldname * newdir * newname * credp * Returns: * Returns ... * Preconditions: * precond(olddir) * precond(oldname) * precond(newdir) * precond(newname) * precond(credp) */ int kmod_rename(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *olddir, const char *oldname, cfs_fid_t *newdir, const char *newname, const cfs_cid_t *cidp, dl_cred_t *credp, cfs_timestruc_t *ctimep, cfs_timestruc_t *delctimep, const cfs_cid_t *delcidp) { cachefsio_rename_arg_t info; cachefsio_rename_return_t ret; int error = 0; int xx; dbug_enter("kmod_rename"); dbug_precond(kmod_object_p); dbug_precond(olddir); dbug_precond(oldname); dbug_precond(newdir); dbug_precond(newname); dbug_precond(credp); dbug_precond(ctimep); info.rn_olddir = *olddir; dbug_assert(strlen(oldname) < (size_t)MAXNAMELEN); strlcpy(info.rn_oldname, oldname, sizeof (info.rn_oldname)); info.rn_newdir = *newdir; dbug_assert(strlen(newname) < (size_t)MAXNAMELEN); strlcpy(info.rn_newname, newname, sizeof (info.rn_newname)); info.rn_cid = *cidp; copy_cred(&info.rn_cred, credp); info.rn_del_getctime = delctimep ? 1 : 0; info.rn_del_cid = *delcidp; xx = kmod_doioctl(kmod_object_p, CFSDCMD_RENAME, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, olddir); dbug_print(("ioctl", " old dir fid \"%s\"", kmod_object_p->i_fidbuf)); kmod_format_fid(kmod_object_p, newdir); dbug_print(("ioctl", " new dir fid \"%s\"", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " old name '%s' new name '%s'", oldname, newname)); kmod_print_cred(credp); if (xx == 0) { *ctimep = ret.rn_ctime; dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); if (delctimep) { *delctimep = ret.rn_del_ctime; dbug_print(("ioctl", " del ctime %x %x", delctimep->tv_sec, delctimep->tv_nsec)); } } dbug_leave("kmod_rename"); return (error); } /* * ------------------------------------------------------------ * kmod_setattr * * Description: * Arguments: * fidp * vattrp * flags * credp * Returns: * Returns ... * Preconditions: * precond(fidp) * precond(vattrp) * precond(credp) */ int kmod_setattr(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp, const cfs_cid_t *cidp, vattr_t *vattrp, int flags, dl_cred_t *credp, cfs_timestruc_t *ctimep, cfs_timestruc_t *mtimep) { cachefsio_setattr_arg_t info; cachefsio_setattr_return_t ret; int error = 0; int xx; dbug_enter("kmod_setattr"); dbug_precond(kmod_object_p); dbug_precond(fidp); dbug_precond(cidp); dbug_precond(vattrp); dbug_precond(credp); dbug_precond(ctimep); dbug_precond(mtimep); info.sa_backfid = *fidp; info.sa_cid = *cidp; info.sa_vattr = *vattrp; info.sa_flags = flags; copy_cred(&info.sa_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETATTR, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); dbug_print(("ioctl", " flags 0x%x", flags)); kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf)); kmod_print_attr(vattrp); kmod_print_cred(credp); if (xx == 0) { *ctimep = ret.sa_ctime; *mtimep = ret.sa_mtime; dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec, mtimep->tv_nsec)); } dbug_leave("kmod_setattr"); return (error); } /* * ------------------------------------------------------------ * kmod_setsecattr * * Description: * Arguments: * fidp * aclcnt * dfaclcnt * acl * flags * credp * Returns: * Returns ... * Preconditions: * precond(fidp) * precond(acl) * precond(credp) * precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES) */ int kmod_setsecattr(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp, const cfs_cid_t *cidp, ulong_t mask, int aclcnt, int dfaclcnt, const aclent_t *acl, dl_cred_t *credp, cfs_timestruc_t *ctimep, cfs_timestruc_t *mtimep) { cachefsio_setsecattr_arg_t info; cachefsio_setsecattr_return_t ret; int error = 0; int xx; dbug_enter("kmod_setsecattr"); dbug_precond(kmod_object_p); dbug_precond(fidp); dbug_precond(cidp); dbug_precond(acl); dbug_precond(credp); dbug_precond(ctimep); dbug_precond(mtimep); dbug_precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES); info.sc_backfid = *fidp; info.sc_cid = *cidp; info.sc_mask = mask; info.sc_aclcnt = aclcnt; info.sc_dfaclcnt = dfaclcnt; memcpy(&info.sc_acl, acl, (aclcnt + dfaclcnt) * sizeof (aclent_t)); copy_cred(&info.sc_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETSECATTR, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " aclcnt %d dfaclcnt %d", aclcnt, dfaclcnt)); kmod_print_cred(credp); if (xx == 0) { *ctimep = ret.sc_ctime; *mtimep = ret.sc_mtime; dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec, mtimep->tv_nsec)); } dbug_leave("kmod_setsecattr"); return (error); } /* * ------------------------------------------------------------ * kmod_remove * * Description: * Arguments: * fidp * namep * credp * ctimep * Returns: * Returns ... * Preconditions: * precond(fidp) * precond(namep) * precond(credp) */ int kmod_remove(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp, const cfs_cid_t *cidp, const char *namep, const dl_cred_t *credp, cfs_timestruc_t *ctimep) { cachefsio_remove_t info; int len; int error = 0; int xx; dbug_enter("kmod_remove"); dbug_precond(kmod_object_p); dbug_precond(fidp); dbug_precond(cidp); dbug_precond(namep); dbug_precond(credp); info.rm_fid = *fidp; info.rm_cid = *cidp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.rm_name, namep, sizeof (info.rm_name)); copy_cred(&info.rm_cred, credp); info.rm_getctime = ctimep ? 1 : 0; if (ctimep) len = sizeof (*ctimep); else len = 0; xx = kmod_doioctl(kmod_object_p, CFSDCMD_REMOVE, &info, sizeof (info), ctimep, len); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, fidp); dbug_print(("ioctl", " fid '%s'", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", namep)); kmod_print_cred(credp); if ((xx == 0) && ctimep) { dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); } dbug_leave("kmod_remove"); return (error); } /* * ------------------------------------------------------------ * kmod_link * * Description: * Arguments: * dirfidp * namep * filefidp * credp * ctimep * Returns: * Returns ... * Preconditions: * precond(dirfidp) * precond(namep) * precond(filefidp) * precond(credp) */ int kmod_link(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp, const char *namep, const cfs_fid_t *filefidp, const cfs_cid_t *cidp, const dl_cred_t *credp, cfs_timestruc_t *ctimep) { cachefsio_link_t info; int error = 0; int xx; dbug_enter("kmod_link"); dbug_precond(kmod_object_p); dbug_precond(dirfidp); dbug_precond(namep); dbug_precond(filefidp); dbug_precond(cidp); dbug_precond(credp); dbug_precond(ctimep); info.ln_dirfid = *dirfidp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.ln_name, namep, sizeof (info.ln_name)); info.ln_filefid = *filefidp; info.ln_cid = *cidp; copy_cred(&info.ln_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_LINK, &info, sizeof (info), ctimep, sizeof (*ctimep)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirfidp); dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", namep)); kmod_format_fid(kmod_object_p, filefidp); dbug_print(("ioctl", " file fid '%s'", kmod_object_p->i_fidbuf)); kmod_print_cred(credp); if (xx == 0) { dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); } dbug_leave("kmod_link"); return (error); } /* * ------------------------------------------------------------ * kmod_mkdir * * Description: * Arguments: * dirfidp * namep * vattrp * credp * newfidp * Returns: * Returns ... * Preconditions: * precond(dirfidp) * precond(namep) * precond(vattrp) * precond(credp) * precond(newfidp) */ int kmod_mkdir(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp, const char *namep, const cfs_cid_t *cidp, const vattr_t *vattrp, const dl_cred_t *credp, cfs_fid_t *newfidp) { cachefsio_mkdir_t info; int error = 0; int xx; dbug_enter("kmod_mkdir"); dbug_precond(kmod_object_p); dbug_precond(dirfidp); dbug_precond(namep); dbug_precond(cidp); dbug_precond(vattrp); dbug_precond(credp); dbug_precond(newfidp); info.md_dirfid = *dirfidp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.md_name, namep, sizeof (info.md_name)); info.md_cid = *cidp; info.md_vattr = *vattrp; copy_cred(&info.md_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_MKDIR, &info, sizeof (info), newfidp, sizeof (*newfidp)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirfidp); dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", namep)); kmod_print_attr(vattrp); kmod_print_cred(credp); if (xx == 0) { kmod_format_fid(kmod_object_p, newfidp); dbug_print(("ioctl", " file fid '%s'", kmod_object_p->i_fidbuf)); } dbug_leave("kmod_mkdir"); return (error); } /* * ------------------------------------------------------------ * kmod_rmdir * * Description: * Arguments: * dirfidp * namep * credp * Returns: * Returns ... * Preconditions: * precond(dirfidp) * precond(namep) * precond(credp) */ int kmod_rmdir(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp, const char *namep, const dl_cred_t *credp) { cachefsio_rmdir_t info; int error = 0; int xx; dbug_enter("kmod_rmdir"); dbug_precond(kmod_object_p); dbug_precond(dirfidp); dbug_precond(namep); dbug_precond(credp); info.rd_dirfid = *dirfidp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.rd_name, namep, sizeof (info.rd_name)); copy_cred(&info.rd_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_RMDIR, &info, sizeof (info), NULL, 0); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirfidp); dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", namep)); kmod_print_cred(credp); dbug_leave("kmod_rmdir"); return (error); } /* * ------------------------------------------------------------ * kmod_symlink * * Description: * Arguments: * dirfidp * namep * linkvalp * vattrp * credp * ctimep * mtimep * Returns: * Returns ... * Preconditions: * precond(dirfidp) * precond(namep) * precond(linkvalp) * precond(vattrp) * precond(credp) * precond(ctimep) * precond(mtimep) */ int kmod_symlink(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp, const char *namep, const cfs_cid_t *cidp, const char *linkvalp, const vattr_t *vattrp, const dl_cred_t *credp, cfs_fid_t *newfidp, cfs_timestruc_t *ctimep, cfs_timestruc_t *mtimep) { cachefsio_symlink_arg_t info; cachefsio_symlink_return_t ret; int error = 0; int xx; dbug_enter("kmod_symlink"); dbug_precond(kmod_object_p); dbug_precond(dirfidp); dbug_precond(namep); dbug_precond(cidp); dbug_precond(linkvalp); dbug_precond(vattrp); dbug_precond(credp); dbug_precond(newfidp); dbug_precond(ctimep); dbug_precond(mtimep); info.sy_dirfid = *dirfidp; dbug_assert(strlen(namep) < (size_t)MAXNAMELEN); strlcpy(info.sy_name, namep, sizeof (info.sy_name)); dbug_assert(strlen(linkvalp) < (size_t)MAXPATHLEN); info.sy_cid = *cidp; strlcpy(info.sy_link, linkvalp, sizeof (info.sy_link)); info.sy_vattr = *vattrp; copy_cred(&info.sy_cred, credp); xx = kmod_doioctl(kmod_object_p, CFSDCMD_SYMLINK, &info, sizeof (info), &ret, sizeof (ret)); if (xx) error = errno; dbug_print(("ioctl", "returns %d, error %d", xx, error)); kmod_format_fid(kmod_object_p, dirfidp); dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf)); dbug_print(("ioctl", " name '%s'", namep)); dbug_print(("ioctl", " link '%s'", linkvalp)); kmod_print_attr(vattrp); kmod_print_cred(credp); if (xx == 0) { *ctimep = ret.sy_ctime; *mtimep = ret.sy_mtime; *newfidp = ret.sy_newfid; dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec, ctimep->tv_nsec)); dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec, mtimep->tv_nsec)); kmod_format_fid(kmod_object_p, newfidp); dbug_print(("ioctl", " child fid '%s'", kmod_object_p->i_fidbuf)); } dbug_leave("kmod_symlink"); return (error); } #ifndef DBUG_OFF /* * ------------------------------------------------------------ * kmod_format_fid * * Description: * Arguments: * fidp * Returns: * Preconditions: * precond(fidp) */ void kmod_format_fid(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp) { uint_t val; int index; char format[10]; kmod_object_p->i_fidbuf[0] = '\0'; for (index = 0; index < (int)fidp->fid_len; index += sizeof (uint_t)) { memcpy(&val, &fidp->fid_data[index], sizeof (uint_t)); snprintf(format, sizeof (format), "%08x ", val); strlcat(kmod_object_p->i_fidbuf, format, sizeof (kmod_object_p->i_fidbuf)); } } /* * ------------------------------------------------------------ * kmod_print_cred * * Description: * Arguments: * credp * Returns: * Preconditions: * precond(credp) */ void kmod_print_cred(const dl_cred_t *credp) { char buf[100]; char format[10]; int xx; dbug_enter("kmod_print_cred"); dbug_precond(credp); buf[0] = '\0'; dbug_print(("ioctl", "credentials")); dbug_print(("ioctl", " uid %d, gid %d", credp->cr_uid, credp->cr_gid)); dbug_print(("ioctl", " ruid %d, rgid %d, suid %d, sgid %d", credp->cr_ruid, credp->cr_rgid, credp->cr_suid, credp->cr_sgid)); for (xx = 0; xx < credp->cr_ngroups; xx++) { snprintf(format, sizeof (format), " %d", credp->cr_groups[xx]); strlcat(buf, format, sizeof (buf)); } dbug_print(("ioctl", " ngroups %d, %s", credp->cr_ngroups, buf)); dbug_leave("kmod_print_cred"); } /* * ------------------------------------------------------------ * kmod_print_attr * * Description: * Arguments: * vattrp * Returns: * Preconditions: * precond(vattrp) */ void kmod_print_attr(const vattr_t *vp) { dbug_enter("kmod_print_attr"); dbug_precond(vp); dbug_print(("ioctl", "attributes")); dbug_print(("ioctl", " mask 0x%x", vp->va_mask)); if (vp->va_mask & AT_TYPE) dbug_print(("ioctl", " type %d", vp->va_type)); if (vp->va_mask & AT_MODE) dbug_print(("ioctl", " mode 0%o", vp->va_mode)); if (vp->va_mask & AT_UID) dbug_print(("ioctl", " uid %d", vp->va_uid)); if (vp->va_mask & AT_GID) dbug_print(("ioctl", " gid %d", vp->va_gid)); if (vp->va_mask & AT_FSID) dbug_print(("ioctl", " fsid %08x", vp->va_fsid)); if (vp->va_mask & AT_NODEID) dbug_print(("ioctl", " nodeid %08x", vp->va_nodeid)); if (vp->va_mask & AT_NLINK) dbug_print(("ioctl", " nlink %d", vp->va_nlink)); if (vp->va_mask & AT_SIZE) dbug_print(("ioctl", " size %d", vp->va_size)); if (vp->va_mask & AT_ATIME) dbug_print(("ioctl", " atime %08x %08x", vp->va_atime.tv_sec, vp->va_atime.tv_nsec)); if (vp->va_mask & AT_MTIME) dbug_print(("ioctl", " mtime %08x %08x", vp->va_mtime.tv_sec, vp->va_mtime.tv_nsec)); if (vp->va_mask & AT_CTIME) dbug_print(("ioctl", " ctime %08x %08x", vp->va_ctime.tv_sec, vp->va_ctime.tv_nsec)); if (vp->va_mask & AT_RDEV) dbug_print(("ioctl", " rdev %08x", vp->va_rdev)); if (vp->va_mask & AT_BLKSIZE) dbug_print(("ioctl", " blksize %08x", vp->va_blksize)); if (vp->va_mask & AT_NBLOCKS) dbug_print(("ioctl", " nblocks %d", vp->va_nblocks)); if (vp->va_mask & AT_SEQ) dbug_print(("ioctl", " seq %d", vp->va_seq)); dbug_leave("kmod_print_attr"); } #endif /* DBUG_OFF */ /* * kmod_doioctl * * Description: * Helper routine for others in this file. Just packages up * arguments and does the ioctl operation. * Arguments: * cmd * sdata * slen * rdata * rlen * Returns: * Returns the result of the ioctl operation. * Preconditions: */ int kmod_doioctl(cfsd_kmod_object_t *kmod_object_p, enum cfsdcmd_cmds cmd, void *sdata, int slen, void *rdata, int rlen) { cachefsio_dcmd_t dcmd; int xx; dbug_enter("kmod_doioctl"); dbug_precond(kmod_object_p); dcmd.d_cmd = cmd; dcmd.d_sdata = sdata; dcmd.d_slen = slen; dcmd.d_rdata = rdata; dcmd.d_rlen = rlen; dbug_print(("ioctl", "about to do cmd = %d", cmd)); xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_DCMD, &dcmd); if (xx) { dbug_print(("ioctl", "ioctl errno = %d", errno)); } dbug_leave("kmod_doioctl"); return (xx); }