1d157d4dcSMatthew Dillon /* 2d157d4dcSMatthew Dillon * Copyright (c) 2011-2015 The DragonFly Project. All rights reserved. 3d157d4dcSMatthew Dillon * 4d157d4dcSMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5d157d4dcSMatthew Dillon * by Matthew Dillon <dillon@backplane.com> 6d157d4dcSMatthew Dillon * by Daniel Flores (GSOC 2013 - mentored by Matthew Dillon, compression) 7d157d4dcSMatthew Dillon * 8d157d4dcSMatthew Dillon * Redistribution and use in source and binary forms, with or without 9d157d4dcSMatthew Dillon * modification, are permitted provided that the following conditions 10d157d4dcSMatthew Dillon * are met: 11d157d4dcSMatthew Dillon * 12d157d4dcSMatthew Dillon * 1. Redistributions of source code must retain the above copyright 13d157d4dcSMatthew Dillon * notice, this list of conditions and the following disclaimer. 14d157d4dcSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 15d157d4dcSMatthew Dillon * notice, this list of conditions and the following disclaimer in 16d157d4dcSMatthew Dillon * the documentation and/or other materials provided with the 17d157d4dcSMatthew Dillon * distribution. 18d157d4dcSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 19d157d4dcSMatthew Dillon * contributors may be used to endorse or promote products derived 20d157d4dcSMatthew Dillon * from this software without specific, prior written permission. 21d157d4dcSMatthew Dillon * 22d157d4dcSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23d157d4dcSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24d157d4dcSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25d157d4dcSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26d157d4dcSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27d157d4dcSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28d157d4dcSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29d157d4dcSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30d157d4dcSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31d157d4dcSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32d157d4dcSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33d157d4dcSMatthew Dillon * SUCH DAMAGE. 34d157d4dcSMatthew Dillon */ 35d157d4dcSMatthew Dillon #include <sys/param.h> 36d157d4dcSMatthew Dillon #include <sys/systm.h> 37d157d4dcSMatthew Dillon #include <sys/kernel.h> 38d157d4dcSMatthew Dillon #include <sys/nlookup.h> 39d157d4dcSMatthew Dillon #include <sys/vnode.h> 40d157d4dcSMatthew Dillon #include <sys/mount.h> 41d157d4dcSMatthew Dillon #include <sys/fcntl.h> 42d157d4dcSMatthew Dillon #include <sys/buf.h> 43d157d4dcSMatthew Dillon #include <sys/uuid.h> 44d157d4dcSMatthew Dillon #include <sys/vfsops.h> 45d157d4dcSMatthew Dillon #include <sys/sysctl.h> 46d157d4dcSMatthew Dillon #include <sys/socket.h> 47d157d4dcSMatthew Dillon #include <sys/objcache.h> 48d157d4dcSMatthew Dillon 49d157d4dcSMatthew Dillon #include <sys/proc.h> 50d157d4dcSMatthew Dillon #include <sys/namei.h> 51d157d4dcSMatthew Dillon #include <sys/mountctl.h> 52d157d4dcSMatthew Dillon #include <sys/dirent.h> 53d157d4dcSMatthew Dillon #include <sys/uio.h> 54d157d4dcSMatthew Dillon 55d157d4dcSMatthew Dillon #include <sys/mutex.h> 56d157d4dcSMatthew Dillon #include <sys/mutex2.h> 57d157d4dcSMatthew Dillon 58d157d4dcSMatthew Dillon #include "hammer2.h" 59d157d4dcSMatthew Dillon #include "hammer2_disk.h" 60d157d4dcSMatthew Dillon #include "hammer2_mount.h" 61d157d4dcSMatthew Dillon 62d157d4dcSMatthew Dillon static int hammer2_rcvdmsg(kdmsg_msg_t *msg); 63d157d4dcSMatthew Dillon static void hammer2_autodmsg(kdmsg_msg_t *msg); 64d157d4dcSMatthew Dillon static int hammer2_lnk_span_reply(kdmsg_state_t *state, kdmsg_msg_t *msg); 65d157d4dcSMatthew Dillon 66d157d4dcSMatthew Dillon void 67506bd6d1SMatthew Dillon hammer2_iocom_init(hammer2_dev_t *hmp) 68d157d4dcSMatthew Dillon { 69d157d4dcSMatthew Dillon /* 70d157d4dcSMatthew Dillon * Automatic LNK_CONN 71d157d4dcSMatthew Dillon * Automatic LNK_SPAN handling 72d157d4dcSMatthew Dillon * No automatic LNK_SPAN generation (we generate multiple spans 73d157d4dcSMatthew Dillon * ourselves). 74d157d4dcSMatthew Dillon */ 75d157d4dcSMatthew Dillon kdmsg_iocom_init(&hmp->iocom, hmp, 76d157d4dcSMatthew Dillon KDMSG_IOCOMF_AUTOCONN | 77d157d4dcSMatthew Dillon KDMSG_IOCOMF_AUTORXSPAN, 78d157d4dcSMatthew Dillon hmp->mchain, hammer2_rcvdmsg); 79d157d4dcSMatthew Dillon } 80d157d4dcSMatthew Dillon 81d157d4dcSMatthew Dillon void 82506bd6d1SMatthew Dillon hammer2_iocom_uninit(hammer2_dev_t *hmp) 83d157d4dcSMatthew Dillon { 843c198419SMatthew Dillon /* XXX chain depend deadlck? */ 853c198419SMatthew Dillon if (hmp->iocom.mmsg) 863c198419SMatthew Dillon kdmsg_iocom_uninit(&hmp->iocom); 87d157d4dcSMatthew Dillon } 88d157d4dcSMatthew Dillon 89d157d4dcSMatthew Dillon /* 90d157d4dcSMatthew Dillon * Reconnect using the passed file pointer. The caller must ref the 91d157d4dcSMatthew Dillon * fp for us. 92d157d4dcSMatthew Dillon */ 93d157d4dcSMatthew Dillon void 94506bd6d1SMatthew Dillon hammer2_cluster_reconnect(hammer2_dev_t *hmp, struct file *fp) 95d157d4dcSMatthew Dillon { 96d157d4dcSMatthew Dillon /* 97d157d4dcSMatthew Dillon * Closes old comm descriptor, kills threads, cleans up 98d157d4dcSMatthew Dillon * states, then installs the new descriptor and creates 99d157d4dcSMatthew Dillon * new threads. 100d157d4dcSMatthew Dillon */ 101d157d4dcSMatthew Dillon kdmsg_iocom_reconnect(&hmp->iocom, fp, "hammer2"); 102d157d4dcSMatthew Dillon 103d157d4dcSMatthew Dillon /* 1047750fd72SMatthew Dillon * Setup LNK_CONN fields for autoinitiated state machine. LNK_CONN 1057750fd72SMatthew Dillon * does not have to be unique. peer_id can be used to filter incoming 1067750fd72SMatthew Dillon * LNK_SPANs automatically if desired (though we still need to check). 1077750fd72SMatthew Dillon * peer_label typically identifies who we are and is not a filter. 108d157d4dcSMatthew Dillon * 1097750fd72SMatthew Dillon * Since we will be initiating multiple LNK_SPANs we cannot use 1107750fd72SMatthew Dillon * AUTOTXSPAN, but we do use AUTORXSPAN so kdmsg tracks received 1117750fd72SMatthew Dillon * LNK_SPANs, and we simply monitor those messages. 112d157d4dcSMatthew Dillon */ 1137750fd72SMatthew Dillon bzero(&hmp->iocom.auto_lnk_conn.peer_id, 1147750fd72SMatthew Dillon sizeof(hmp->iocom.auto_lnk_conn.peer_id)); 1157750fd72SMatthew Dillon /* hmp->iocom.auto_lnk_conn.peer_id = hmp->voldata.fsid; */ 116d157d4dcSMatthew Dillon hmp->iocom.auto_lnk_conn.proto_version = DMSG_SPAN_PROTO_1; 117d157d4dcSMatthew Dillon #if 0 118d157d4dcSMatthew Dillon hmp->iocom.auto_lnk_conn.peer_type = hmp->voldata.peer_type; 119d157d4dcSMatthew Dillon #endif 120d157d4dcSMatthew Dillon hmp->iocom.auto_lnk_conn.peer_type = DMSG_PEER_HAMMER2; 121d157d4dcSMatthew Dillon 122d157d4dcSMatthew Dillon /* 1237750fd72SMatthew Dillon * We just want to receive LNK_SPANs related to HAMMER2 matching 1247750fd72SMatthew Dillon * peer_id. 125d157d4dcSMatthew Dillon */ 126d157d4dcSMatthew Dillon hmp->iocom.auto_lnk_conn.peer_mask = 1LLU << DMSG_PEER_HAMMER2; 127d157d4dcSMatthew Dillon 128d157d4dcSMatthew Dillon #if 0 129b0f58de8SMatthew Dillon switch (ipdata->meta.pfs_type) { 130d157d4dcSMatthew Dillon case DMSG_PFSTYPE_CLIENT: 131d157d4dcSMatthew Dillon hmp->iocom.auto_lnk_conn.peer_mask &= 132d157d4dcSMatthew Dillon ~(1LLU << DMSG_PFSTYPE_CLIENT); 133d157d4dcSMatthew Dillon break; 134d157d4dcSMatthew Dillon default: 135d157d4dcSMatthew Dillon break; 136d157d4dcSMatthew Dillon } 137d157d4dcSMatthew Dillon #endif 138d157d4dcSMatthew Dillon 1397750fd72SMatthew Dillon bzero(&hmp->iocom.auto_lnk_conn.peer_label, 1407750fd72SMatthew Dillon sizeof(hmp->iocom.auto_lnk_conn.peer_label)); 1417750fd72SMatthew Dillon ksnprintf(hmp->iocom.auto_lnk_conn.peer_label, 1427750fd72SMatthew Dillon sizeof(hmp->iocom.auto_lnk_conn.peer_label), 1437750fd72SMatthew Dillon "%s/%s", 1447750fd72SMatthew Dillon hostname, "hammer2-mount"); 145d157d4dcSMatthew Dillon kdmsg_iocom_autoinitiate(&hmp->iocom, hammer2_autodmsg); 146d157d4dcSMatthew Dillon } 147d157d4dcSMatthew Dillon 148d157d4dcSMatthew Dillon static int 149d157d4dcSMatthew Dillon hammer2_rcvdmsg(kdmsg_msg_t *msg) 150d157d4dcSMatthew Dillon { 151d157d4dcSMatthew Dillon kprintf("RCVMSG %08x\n", msg->tcmd); 152d157d4dcSMatthew Dillon 153d157d4dcSMatthew Dillon switch(msg->tcmd) { 154d157d4dcSMatthew Dillon case DMSG_DBG_SHELL: 155d157d4dcSMatthew Dillon /* 156d157d4dcSMatthew Dillon * (non-transaction) 157d157d4dcSMatthew Dillon * Execute shell command (not supported atm) 158d157d4dcSMatthew Dillon */ 159d157d4dcSMatthew Dillon kdmsg_msg_result(msg, DMSG_ERR_NOSUPP); 160d157d4dcSMatthew Dillon break; 161d157d4dcSMatthew Dillon case DMSG_DBG_SHELL | DMSGF_REPLY: 162d157d4dcSMatthew Dillon /* 163d157d4dcSMatthew Dillon * (non-transaction) 164d157d4dcSMatthew Dillon */ 165d157d4dcSMatthew Dillon if (msg->aux_data) { 166d157d4dcSMatthew Dillon msg->aux_data[msg->aux_size - 1] = 0; 167d157d4dcSMatthew Dillon kprintf("HAMMER2 DBG: %s\n", msg->aux_data); 168d157d4dcSMatthew Dillon } 169d157d4dcSMatthew Dillon break; 170d157d4dcSMatthew Dillon default: 171d157d4dcSMatthew Dillon /* 172d157d4dcSMatthew Dillon * Unsupported message received. We only need to 173d157d4dcSMatthew Dillon * reply if it's a transaction in order to close our end. 174d157d4dcSMatthew Dillon * Ignore any one-way messages or any further messages 175d157d4dcSMatthew Dillon * associated with the transaction. 176d157d4dcSMatthew Dillon * 177d157d4dcSMatthew Dillon * NOTE: This case also includes DMSG_LNK_ERROR messages 178d157d4dcSMatthew Dillon * which might be one-way, replying to those would 179d157d4dcSMatthew Dillon * cause an infinite ping-pong. 180d157d4dcSMatthew Dillon */ 181d157d4dcSMatthew Dillon if (msg->any.head.cmd & DMSGF_CREATE) 182d157d4dcSMatthew Dillon kdmsg_msg_reply(msg, DMSG_ERR_NOSUPP); 183d157d4dcSMatthew Dillon break; 184d157d4dcSMatthew Dillon } 185d157d4dcSMatthew Dillon return(0); 186d157d4dcSMatthew Dillon } 187d157d4dcSMatthew Dillon 188d157d4dcSMatthew Dillon /* 189d157d4dcSMatthew Dillon * This function is called after KDMSG has automatically handled processing 190d157d4dcSMatthew Dillon * of a LNK layer message (typically CONN or SPAN). 191d157d4dcSMatthew Dillon * 192d157d4dcSMatthew Dillon * We tag off the LNK_CONN to trigger our LNK_VOLCONF messages which 193d157d4dcSMatthew Dillon * advertises all available hammer2 super-root volumes. 194d157d4dcSMatthew Dillon * 195d157d4dcSMatthew Dillon * We collect span state 196d157d4dcSMatthew Dillon */ 197506bd6d1SMatthew Dillon static void hammer2_update_spans(hammer2_dev_t *hmp, kdmsg_state_t *state); 198d157d4dcSMatthew Dillon 199d157d4dcSMatthew Dillon static void 200d157d4dcSMatthew Dillon hammer2_autodmsg(kdmsg_msg_t *msg) 201d157d4dcSMatthew Dillon { 202506bd6d1SMatthew Dillon hammer2_dev_t *hmp = msg->state->iocom->handle; 203d157d4dcSMatthew Dillon int copyid; 204d157d4dcSMatthew Dillon 205d157d4dcSMatthew Dillon switch(msg->tcmd) { 206d157d4dcSMatthew Dillon case DMSG_LNK_CONN | DMSGF_CREATE: 207d157d4dcSMatthew Dillon case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_DELETE: 208d157d4dcSMatthew Dillon case DMSG_LNK_CONN | DMSGF_DELETE: 209d157d4dcSMatthew Dillon /* 210d157d4dcSMatthew Dillon * NOTE: kern_dmsg will automatically issue a result, 211d157d4dcSMatthew Dillon * leaving the transaction open, for CREATEs, 212d157d4dcSMatthew Dillon * and will automatically issue a terminating reply 213d157d4dcSMatthew Dillon * for DELETEs. 214d157d4dcSMatthew Dillon */ 215d157d4dcSMatthew Dillon break; 216d157d4dcSMatthew Dillon case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_REPLY: 217d157d4dcSMatthew Dillon case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_DELETE | DMSGF_REPLY: 218d157d4dcSMatthew Dillon /* 219d157d4dcSMatthew Dillon * Do a volume configuration dump when we receive a reply 220d157d4dcSMatthew Dillon * to our auto-CONN (typically leaving the transaction open). 221d157d4dcSMatthew Dillon */ 222d157d4dcSMatthew Dillon if (msg->any.head.cmd & DMSGF_CREATE) { 223d157d4dcSMatthew Dillon kprintf("HAMMER2: VOLDATA DUMP\n"); 224d157d4dcSMatthew Dillon 225d157d4dcSMatthew Dillon /* 226d157d4dcSMatthew Dillon * Dump the configuration stored in the volume header. 227d157d4dcSMatthew Dillon * This will typically be import/export access rights, 228d157d4dcSMatthew Dillon * master encryption keys (encrypted), etc. 229d157d4dcSMatthew Dillon */ 230d157d4dcSMatthew Dillon hammer2_voldata_lock(hmp); 231d157d4dcSMatthew Dillon copyid = 0; 232d157d4dcSMatthew Dillon while (copyid < HAMMER2_COPYID_COUNT) { 233d157d4dcSMatthew Dillon if (hmp->voldata.copyinfo[copyid].copyid) 234d157d4dcSMatthew Dillon hammer2_volconf_update(hmp, copyid); 235d157d4dcSMatthew Dillon ++copyid; 236d157d4dcSMatthew Dillon } 237d157d4dcSMatthew Dillon hammer2_voldata_unlock(hmp); 238d157d4dcSMatthew Dillon 239d157d4dcSMatthew Dillon kprintf("HAMMER2: INITIATE SPANs\n"); 240d157d4dcSMatthew Dillon hammer2_update_spans(hmp, msg->state); 241d157d4dcSMatthew Dillon } 242d157d4dcSMatthew Dillon if ((msg->any.head.cmd & DMSGF_DELETE) && 243d157d4dcSMatthew Dillon msg->state && (msg->state->txcmd & DMSGF_DELETE) == 0) { 244d157d4dcSMatthew Dillon kprintf("HAMMER2: CONN WAS TERMINATED\n"); 245d157d4dcSMatthew Dillon } 246d157d4dcSMatthew Dillon break; 247d157d4dcSMatthew Dillon case DMSG_LNK_SPAN | DMSGF_CREATE: 248d157d4dcSMatthew Dillon /* 249d157d4dcSMatthew Dillon * Monitor SPANs and issue a result, leaving the SPAN open 250d157d4dcSMatthew Dillon * if it is something we can use now or in the future. 251d157d4dcSMatthew Dillon */ 252d157d4dcSMatthew Dillon if (msg->any.lnk_span.peer_type != DMSG_PEER_HAMMER2) { 253d157d4dcSMatthew Dillon kdmsg_msg_reply(msg, 0); 254d157d4dcSMatthew Dillon break; 255d157d4dcSMatthew Dillon } 256d157d4dcSMatthew Dillon if (msg->any.lnk_span.proto_version != DMSG_SPAN_PROTO_1) { 257d157d4dcSMatthew Dillon kdmsg_msg_reply(msg, 0); 258d157d4dcSMatthew Dillon break; 259d157d4dcSMatthew Dillon } 2607750fd72SMatthew Dillon DMSG_TERMINATE_STRING(msg->any.lnk_span.peer_label); 261*95bf987fSMatthew Dillon if (hammer2_debug & 0x0100) { 2627750fd72SMatthew Dillon kprintf("H2 +RXSPAN cmd=%08x (%-20s) cl=", 263*95bf987fSMatthew Dillon msg->any.head.cmd, 264*95bf987fSMatthew Dillon msg->any.lnk_span.peer_label); 2657750fd72SMatthew Dillon printf_uuid(&msg->any.lnk_span.peer_id); 266d157d4dcSMatthew Dillon kprintf(" fs="); 2677750fd72SMatthew Dillon printf_uuid(&msg->any.lnk_span.pfs_id); 268d157d4dcSMatthew Dillon kprintf(" type=%d\n", msg->any.lnk_span.pfs_type); 269*95bf987fSMatthew Dillon } 270d157d4dcSMatthew Dillon kdmsg_msg_result(msg, 0); 271d157d4dcSMatthew Dillon break; 272d157d4dcSMatthew Dillon case DMSG_LNK_SPAN | DMSGF_DELETE: 273d157d4dcSMatthew Dillon /* 274d157d4dcSMatthew Dillon * NOTE: kern_dmsg will automatically reply to DELETEs. 275d157d4dcSMatthew Dillon */ 276*95bf987fSMatthew Dillon if (hammer2_debug & 0x0100) 277d157d4dcSMatthew Dillon kprintf("H2 -RXSPAN\n"); 278d157d4dcSMatthew Dillon break; 279d157d4dcSMatthew Dillon default: 280d157d4dcSMatthew Dillon break; 281d157d4dcSMatthew Dillon } 282d157d4dcSMatthew Dillon } 283d157d4dcSMatthew Dillon 284d157d4dcSMatthew Dillon /* 285d157d4dcSMatthew Dillon * Update LNK_SPAN state 286d157d4dcSMatthew Dillon */ 287d157d4dcSMatthew Dillon static void 288506bd6d1SMatthew Dillon hammer2_update_spans(hammer2_dev_t *hmp, kdmsg_state_t *state) 289d157d4dcSMatthew Dillon { 290d157d4dcSMatthew Dillon const hammer2_inode_data_t *ripdata; 29101d71aa5SMatthew Dillon hammer2_chain_t *parent; 29201d71aa5SMatthew Dillon hammer2_chain_t *chain; 293506bd6d1SMatthew Dillon hammer2_pfs_t *spmp; 294d157d4dcSMatthew Dillon hammer2_key_t key_next; 295d157d4dcSMatthew Dillon kdmsg_msg_t *rmsg; 296d157d4dcSMatthew Dillon size_t name_len; 29701d71aa5SMatthew Dillon int cache_index = -1; 298d157d4dcSMatthew Dillon 299d157d4dcSMatthew Dillon /* 300d157d4dcSMatthew Dillon * Lookup mount point under the media-localized super-root. 301d157d4dcSMatthew Dillon * 302d157d4dcSMatthew Dillon * cluster->pmp will incorrectly point to spmp and must be fixed 303d157d4dcSMatthew Dillon * up later on. 304d157d4dcSMatthew Dillon */ 305d157d4dcSMatthew Dillon spmp = hmp->spmp; 306b7add675SMatthew Dillon hammer2_inode_lock(spmp->iroot, 0); 30701d71aa5SMatthew Dillon 30801d71aa5SMatthew Dillon parent = hammer2_inode_chain(spmp->iroot, 0, HAMMER2_RESOLVE_ALWAYS); 30901d71aa5SMatthew Dillon chain = NULL; 31001d71aa5SMatthew Dillon if (parent == NULL) 31101d71aa5SMatthew Dillon goto done; 31201d71aa5SMatthew Dillon chain = hammer2_chain_lookup(&parent, &key_next, 31301d71aa5SMatthew Dillon HAMMER2_KEY_MIN, HAMMER2_KEY_MAX, 31401d71aa5SMatthew Dillon &cache_index, 315b8ba9690SMatthew Dillon 0); 31601d71aa5SMatthew Dillon while (chain) { 31701d71aa5SMatthew Dillon if (chain->bref.type != HAMMER2_BREF_TYPE_INODE) 318d157d4dcSMatthew Dillon continue; 31901d71aa5SMatthew Dillon ripdata = &chain->data->ipdata; 320d157d4dcSMatthew Dillon kprintf("UPDATE SPANS: %s\n", ripdata->filename); 321d157d4dcSMatthew Dillon 322d157d4dcSMatthew Dillon rmsg = kdmsg_msg_alloc(&hmp->iocom.state0, 323d157d4dcSMatthew Dillon DMSG_LNK_SPAN | DMSGF_CREATE, 324d157d4dcSMatthew Dillon hammer2_lnk_span_reply, NULL); 325b0f58de8SMatthew Dillon rmsg->any.lnk_span.peer_id = ripdata->meta.pfs_clid; 326b0f58de8SMatthew Dillon rmsg->any.lnk_span.pfs_id = ripdata->meta.pfs_fsid; 327b0f58de8SMatthew Dillon rmsg->any.lnk_span.pfs_type = ripdata->meta.pfs_type; 328d157d4dcSMatthew Dillon rmsg->any.lnk_span.peer_type = DMSG_PEER_HAMMER2; 329d157d4dcSMatthew Dillon rmsg->any.lnk_span.proto_version = DMSG_SPAN_PROTO_1; 330b0f58de8SMatthew Dillon name_len = ripdata->meta.name_len; 3317750fd72SMatthew Dillon if (name_len >= sizeof(rmsg->any.lnk_span.peer_label)) 3327750fd72SMatthew Dillon name_len = sizeof(rmsg->any.lnk_span.peer_label) - 1; 3337750fd72SMatthew Dillon bcopy(ripdata->filename, 3347750fd72SMatthew Dillon rmsg->any.lnk_span.peer_label, 3357750fd72SMatthew Dillon name_len); 336d157d4dcSMatthew Dillon 337d157d4dcSMatthew Dillon kdmsg_msg_write(rmsg); 338d157d4dcSMatthew Dillon 33901d71aa5SMatthew Dillon chain = hammer2_chain_next(&parent, chain, &key_next, 34001d71aa5SMatthew Dillon key_next, HAMMER2_KEY_MAX, 34101d71aa5SMatthew Dillon &cache_index, 342d157d4dcSMatthew Dillon 0); 343d157d4dcSMatthew Dillon } 344b7add675SMatthew Dillon hammer2_inode_unlock(spmp->iroot); 34501d71aa5SMatthew Dillon done: 34601d71aa5SMatthew Dillon if (chain) { 34701d71aa5SMatthew Dillon hammer2_chain_unlock(chain); 34801d71aa5SMatthew Dillon hammer2_chain_drop(chain); 34901d71aa5SMatthew Dillon } 35001d71aa5SMatthew Dillon if (parent) { 35101d71aa5SMatthew Dillon hammer2_chain_unlock(parent); 35201d71aa5SMatthew Dillon hammer2_chain_drop(parent); 353b7add675SMatthew Dillon } 354d157d4dcSMatthew Dillon } 355d157d4dcSMatthew Dillon 356d157d4dcSMatthew Dillon static 357d157d4dcSMatthew Dillon int 358d157d4dcSMatthew Dillon hammer2_lnk_span_reply(kdmsg_state_t *state, kdmsg_msg_t *msg) 359d157d4dcSMatthew Dillon { 360d157d4dcSMatthew Dillon if ((state->txcmd & DMSGF_DELETE) == 0 && 361d157d4dcSMatthew Dillon (msg->any.head.cmd & DMSGF_DELETE)) { 362d157d4dcSMatthew Dillon kdmsg_msg_reply(msg, 0); 363d157d4dcSMatthew Dillon } 364d157d4dcSMatthew Dillon return 0; 365d157d4dcSMatthew Dillon } 366d157d4dcSMatthew Dillon 367d157d4dcSMatthew Dillon /* 368d157d4dcSMatthew Dillon * Volume configuration updates are passed onto the userland service 369d157d4dcSMatthew Dillon * daemon via the open LNK_CONN transaction. 370d157d4dcSMatthew Dillon */ 371d157d4dcSMatthew Dillon void 372506bd6d1SMatthew Dillon hammer2_volconf_update(hammer2_dev_t *hmp, int index) 373d157d4dcSMatthew Dillon { 374d157d4dcSMatthew Dillon kdmsg_msg_t *msg; 375d157d4dcSMatthew Dillon 376d157d4dcSMatthew Dillon /* XXX interlock against connection state termination */ 377d157d4dcSMatthew Dillon kprintf("volconf update %p\n", hmp->iocom.conn_state); 378d157d4dcSMatthew Dillon if (hmp->iocom.conn_state) { 379d157d4dcSMatthew Dillon kprintf("TRANSMIT VOLCONF VIA OPEN CONN TRANSACTION\n"); 380d157d4dcSMatthew Dillon msg = kdmsg_msg_alloc(hmp->iocom.conn_state, 381d157d4dcSMatthew Dillon DMSG_LNK_HAMMER2_VOLCONF, 382d157d4dcSMatthew Dillon NULL, NULL); 383d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->copy = hmp->voldata.copyinfo[index]; 384d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->mediaid = hmp->voldata.fsid; 385d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->index = index; 386d157d4dcSMatthew Dillon kdmsg_msg_write(msg); 387d157d4dcSMatthew Dillon } 388d157d4dcSMatthew Dillon } 389