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 129*b0f58de8SMatthew 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); 2617750fd72SMatthew Dillon kprintf("H2 +RXSPAN cmd=%08x (%-20s) cl=", 2627750fd72SMatthew Dillon msg->any.head.cmd, msg->any.lnk_span.peer_label); 2637750fd72SMatthew Dillon printf_uuid(&msg->any.lnk_span.peer_id); 264d157d4dcSMatthew Dillon kprintf(" fs="); 2657750fd72SMatthew Dillon printf_uuid(&msg->any.lnk_span.pfs_id); 266d157d4dcSMatthew Dillon kprintf(" type=%d\n", msg->any.lnk_span.pfs_type); 267d157d4dcSMatthew Dillon kdmsg_msg_result(msg, 0); 268d157d4dcSMatthew Dillon break; 269d157d4dcSMatthew Dillon case DMSG_LNK_SPAN | DMSGF_DELETE: 270d157d4dcSMatthew Dillon /* 271d157d4dcSMatthew Dillon * NOTE: kern_dmsg will automatically reply to DELETEs. 272d157d4dcSMatthew Dillon */ 273d157d4dcSMatthew Dillon kprintf("H2 -RXSPAN\n"); 274d157d4dcSMatthew Dillon break; 275d157d4dcSMatthew Dillon default: 276d157d4dcSMatthew Dillon break; 277d157d4dcSMatthew Dillon } 278d157d4dcSMatthew Dillon } 279d157d4dcSMatthew Dillon 280d157d4dcSMatthew Dillon /* 281d157d4dcSMatthew Dillon * Update LNK_SPAN state 282d157d4dcSMatthew Dillon */ 283d157d4dcSMatthew Dillon static void 284506bd6d1SMatthew Dillon hammer2_update_spans(hammer2_dev_t *hmp, kdmsg_state_t *state) 285d157d4dcSMatthew Dillon { 286d157d4dcSMatthew Dillon const hammer2_inode_data_t *ripdata; 287d157d4dcSMatthew Dillon hammer2_cluster_t *cparent; 288d157d4dcSMatthew Dillon hammer2_cluster_t *cluster; 289506bd6d1SMatthew Dillon hammer2_pfs_t *spmp; 290d157d4dcSMatthew Dillon hammer2_key_t key_next; 291d157d4dcSMatthew Dillon kdmsg_msg_t *rmsg; 292d157d4dcSMatthew Dillon size_t name_len; 293d157d4dcSMatthew Dillon 294d157d4dcSMatthew Dillon /* 295d157d4dcSMatthew Dillon * Lookup mount point under the media-localized super-root. 296d157d4dcSMatthew Dillon * 297d157d4dcSMatthew Dillon * cluster->pmp will incorrectly point to spmp and must be fixed 298d157d4dcSMatthew Dillon * up later on. 299d157d4dcSMatthew Dillon */ 300d157d4dcSMatthew Dillon spmp = hmp->spmp; 301b93cc2e0SMatthew Dillon cparent = hammer2_inode_lock(spmp->iroot, HAMMER2_RESOLVE_ALWAYS); 302d157d4dcSMatthew Dillon cluster = hammer2_cluster_lookup(cparent, &key_next, 303d157d4dcSMatthew Dillon HAMMER2_KEY_MIN, 304d157d4dcSMatthew Dillon HAMMER2_KEY_MAX, 305b8ba9690SMatthew Dillon 0); 306d157d4dcSMatthew Dillon while (cluster) { 307d157d4dcSMatthew Dillon if (hammer2_cluster_type(cluster) != HAMMER2_BREF_TYPE_INODE) 308d157d4dcSMatthew Dillon continue; 309d157d4dcSMatthew Dillon ripdata = &hammer2_cluster_rdata(cluster)->ipdata; 310d157d4dcSMatthew Dillon kprintf("UPDATE SPANS: %s\n", ripdata->filename); 311d157d4dcSMatthew Dillon 312d157d4dcSMatthew Dillon rmsg = kdmsg_msg_alloc(&hmp->iocom.state0, 313d157d4dcSMatthew Dillon DMSG_LNK_SPAN | DMSGF_CREATE, 314d157d4dcSMatthew Dillon hammer2_lnk_span_reply, NULL); 315*b0f58de8SMatthew Dillon rmsg->any.lnk_span.peer_id = ripdata->meta.pfs_clid; 316*b0f58de8SMatthew Dillon rmsg->any.lnk_span.pfs_id = ripdata->meta.pfs_fsid; 317*b0f58de8SMatthew Dillon rmsg->any.lnk_span.pfs_type = ripdata->meta.pfs_type; 318d157d4dcSMatthew Dillon rmsg->any.lnk_span.peer_type = DMSG_PEER_HAMMER2; 319d157d4dcSMatthew Dillon rmsg->any.lnk_span.proto_version = DMSG_SPAN_PROTO_1; 320*b0f58de8SMatthew Dillon name_len = ripdata->meta.name_len; 3217750fd72SMatthew Dillon if (name_len >= sizeof(rmsg->any.lnk_span.peer_label)) 3227750fd72SMatthew Dillon name_len = sizeof(rmsg->any.lnk_span.peer_label) - 1; 3237750fd72SMatthew Dillon bcopy(ripdata->filename, 3247750fd72SMatthew Dillon rmsg->any.lnk_span.peer_label, 3257750fd72SMatthew Dillon name_len); 326d157d4dcSMatthew Dillon 327d157d4dcSMatthew Dillon kdmsg_msg_write(rmsg); 328d157d4dcSMatthew Dillon 329d157d4dcSMatthew Dillon cluster = hammer2_cluster_next(cparent, cluster, 330d157d4dcSMatthew Dillon &key_next, 331d157d4dcSMatthew Dillon key_next, 332d157d4dcSMatthew Dillon HAMMER2_KEY_MAX, 333d157d4dcSMatthew Dillon 0); 334d157d4dcSMatthew Dillon } 335b93cc2e0SMatthew Dillon hammer2_inode_unlock(spmp->iroot, cparent); 336d157d4dcSMatthew Dillon } 337d157d4dcSMatthew Dillon 338d157d4dcSMatthew Dillon static 339d157d4dcSMatthew Dillon int 340d157d4dcSMatthew Dillon hammer2_lnk_span_reply(kdmsg_state_t *state, kdmsg_msg_t *msg) 341d157d4dcSMatthew Dillon { 342d157d4dcSMatthew Dillon if ((state->txcmd & DMSGF_DELETE) == 0 && 343d157d4dcSMatthew Dillon (msg->any.head.cmd & DMSGF_DELETE)) { 344d157d4dcSMatthew Dillon kdmsg_msg_reply(msg, 0); 345d157d4dcSMatthew Dillon } 346d157d4dcSMatthew Dillon return 0; 347d157d4dcSMatthew Dillon } 348d157d4dcSMatthew Dillon 349d157d4dcSMatthew Dillon /* 350d157d4dcSMatthew Dillon * Volume configuration updates are passed onto the userland service 351d157d4dcSMatthew Dillon * daemon via the open LNK_CONN transaction. 352d157d4dcSMatthew Dillon */ 353d157d4dcSMatthew Dillon void 354506bd6d1SMatthew Dillon hammer2_volconf_update(hammer2_dev_t *hmp, int index) 355d157d4dcSMatthew Dillon { 356d157d4dcSMatthew Dillon kdmsg_msg_t *msg; 357d157d4dcSMatthew Dillon 358d157d4dcSMatthew Dillon /* XXX interlock against connection state termination */ 359d157d4dcSMatthew Dillon kprintf("volconf update %p\n", hmp->iocom.conn_state); 360d157d4dcSMatthew Dillon if (hmp->iocom.conn_state) { 361d157d4dcSMatthew Dillon kprintf("TRANSMIT VOLCONF VIA OPEN CONN TRANSACTION\n"); 362d157d4dcSMatthew Dillon msg = kdmsg_msg_alloc(hmp->iocom.conn_state, 363d157d4dcSMatthew Dillon DMSG_LNK_HAMMER2_VOLCONF, 364d157d4dcSMatthew Dillon NULL, NULL); 365d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->copy = hmp->voldata.copyinfo[index]; 366d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->mediaid = hmp->voldata.fsid; 367d157d4dcSMatthew Dillon H2_LNK_VOLCONF(msg)->index = index; 368d157d4dcSMatthew Dillon kdmsg_msg_write(msg); 369d157d4dcSMatthew Dillon } 370d157d4dcSMatthew Dillon } 371