/* * ctfs_create_cdirnode * * If necessary, creates a cdirnode for the specified contract and * inserts it into the contract's list of vnodes. Returns either the * existing vnode or the new one. */ vnode_t * ctfs_create_cdirnode(vnode_t *pvp, contract_t *ct) { vnode_t *vp; ctfs_cdirnode_t *cdir; if ((vp = contract_vnode_get(ct, pvp->v_vfsp)) != NULL) return (vp); vp = gfs_dir_create(sizeof (ctfs_cdirnode_t), pvp, ctfs_ops_cdir, ctfs_ctls, ctfs_cdir_do_inode, CTFS_NAME_MAX, NULL, NULL); cdir = vp->v_data; /* * We must set the inode because this is called explicitly rather than * through GFS callbacks. */ gfs_file_set_inode(vp, CTFS_INO_CT_DIR(ct->ct_id)); cdir->ctfs_cn_contract = ct; contract_hold(ct); contract_vnode_set(ct, &cdir->ctfs_cn_linkage, vp); return (vp); }
/* * ctfs_create_symnode * * Creates and returns a symnode for the specified contract. */ vnode_t * ctfs_create_symnode(vnode_t *pvp, contract_t *ct) { ctfs_symnode_t *symnode; vnode_t *vp; size_t len; vp = gfs_file_create(sizeof (ctfs_symnode_t), pvp, ctfs_ops_sym); vp->v_type = VLNK; symnode = vp->v_data; symnode->ctfs_sn_contract = ct; symnode->ctfs_sn_size = len = snprintf(NULL, 0, "../%s/%ld", ct->ct_type->ct_type_name, (long)ct->ct_id) + 1; symnode->ctfs_sn_string = kmem_alloc(len, KM_SLEEP); VERIFY(snprintf(symnode->ctfs_sn_string, len, "../%s/%ld", ct->ct_type->ct_type_name, (long)ct->ct_id) < len); contract_hold(ct); return (vp); }