1e02d6efpjd/*-
2a82e3a8pfg * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3a82e3a8pfg *
4668a028pjd * Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
5e02d6efpjd * All rights reserved.
6e02d6efpjd *
7e02d6efpjd * Redistribution and use in source and binary forms, with or without
8e02d6efpjd * modification, are permitted provided that the following conditions
9e02d6efpjd * are met:
10e02d6efpjd * 1. Redistributions of source code must retain the above copyright
11e02d6efpjd *    notice, this list of conditions and the following disclaimer.
12e02d6efpjd * 2. Redistributions in binary form must reproduce the above copyright
13e02d6efpjd *    notice, this list of conditions and the following disclaimer in the
14e02d6efpjd *    documentation and/or other materials provided with the distribution.
156f074b6pjd *
16e02d6efpjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17e02d6efpjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18e02d6efpjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19e02d6efpjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20e02d6efpjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21e02d6efpjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22e02d6efpjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23e02d6efpjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24e02d6efpjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25e02d6efpjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26e02d6efpjd * SUCH DAMAGE.
27e02d6efpjd *
28e02d6efpjd * $FreeBSD$
29e02d6efpjd */
30e02d6efpjd
31e02d6efpjd#ifndef	_G_CONCAT_H_
32e02d6efpjd#define	_G_CONCAT_H_
33e02d6efpjd
34e02d6efpjd#include <sys/endian.h>
35e02d6efpjd
36e02d6efpjd#define	G_CONCAT_CLASS_NAME	"CONCAT"
37e02d6efpjd
38e02d6efpjd#define	G_CONCAT_MAGIC		"GEOM::CONCAT"
39a98f255pjd/*
40a98f255pjd * Version history:
41a98f255pjd * 1 - Initial version number.
42a98f255pjd * 2 - Added 'stop' command to gconcat(8).
43a98f255pjd * 3 - Added md_provider field to metadata and '-h' option to gconcat(8).
44668a028pjd * 4 - Added md_provsize field to metadata.
45a98f255pjd */
46668a028pjd#define	G_CONCAT_VERSION	4
47e02d6efpjd
48e02d6efpjd#ifdef _KERNEL
49e02d6efpjd#define	G_CONCAT_TYPE_MANUAL	0
50e02d6efpjd#define	G_CONCAT_TYPE_AUTOMATIC	1
51e02d6efpjd
5210d53fccem#define G_CONCAT_DEBUG(lvl, ...) \
5310d53fccem    _GEOM_DEBUG("GEOM_CONCAT", g_concat_debug, (lvl), NULL, __VA_ARGS__)
5410d53fccem#define G_CONCAT_LOGREQ(bp, ...) \
5510d53fccem    _GEOM_DEBUG("GEOM_CONCAT", g_concat_debug, 2, (bp), __VA_ARGS__)
56e02d6efpjd
57e02d6efpjdstruct g_concat_disk {
58e02d6efpjd	struct g_consumer	*d_consumer;
59e02d6efpjd	struct g_concat_softc	*d_softc;
60e02d6efpjd	off_t			 d_start;
61e02d6efpjd	off_t			 d_end;
62078f83cmarkj	int			 d_candelete;
63973c472mav	int			 d_removed;
64e02d6efpjd};
65e02d6efpjd
66e02d6efpjdstruct g_concat_softc {
67f44a013pjd	u_int		 sc_type;	/* provider type */
68f44a013pjd	struct g_geom	*sc_geom;
69e02d6efpjd	struct g_provider *sc_provider;
70f44a013pjd	uint32_t	 sc_id;		/* concat unique ID */
71e02d6efpjd
72e02d6efpjd	struct g_concat_disk *sc_disks;
73f44a013pjd	uint16_t	 sc_ndisks;
744219fc0mav	struct mtx	 sc_lock;
75e02d6efpjd};
76badd010pjd#define	sc_name	sc_geom->name
77e02d6efpjd#endif	/* _KERNEL */
78e02d6efpjd
79e02d6efpjdstruct g_concat_metadata {
80e02d6efpjd	char		md_magic[16];	/* Magic value. */
81e02d6efpjd	uint32_t	md_version;	/* Version number. */
82e02d6efpjd	char		md_name[16];	/* Concat name. */
83e02d6efpjd	uint32_t	md_id;		/* Unique ID. */
84e02d6efpjd	uint16_t	md_no;		/* Disk number. */
85e02d6efpjd	uint16_t	md_all;		/* Number of all disks. */
86a98f255pjd	char		md_provider[16]; /* Hardcoded provider. */
87668a028pjd	uint64_t	md_provsize;	/* Provider's size. */
88e02d6efpjd};
89e02d6efpjdstatic __inline void
90e02d6efpjdconcat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
91e02d6efpjd{
92e02d6efpjd
93e02d6efpjd	bcopy(md->md_magic, data, sizeof(md->md_magic));
94e02d6efpjd	le32enc(data + 16, md->md_version);
95e02d6efpjd	bcopy(md->md_name, data + 20, sizeof(md->md_name));
96e02d6efpjd	le32enc(data + 36, md->md_id);
97e02d6efpjd	le16enc(data + 40, md->md_no);
98e02d6efpjd	le16enc(data + 42, md->md_all);
99a98f255pjd	bcopy(md->md_provider, data + 44, sizeof(md->md_provider));
100668a028pjd	le64enc(data + 60, md->md_provsize);
101e02d6efpjd}
102e02d6efpjdstatic __inline void
103e02d6efpjdconcat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
104e02d6efpjd{
105e02d6efpjd
106e02d6efpjd	bcopy(data, md->md_magic, sizeof(md->md_magic));
107e02d6efpjd	md->md_version = le32dec(data + 16);
108e02d6efpjd	bcopy(data + 20, md->md_name, sizeof(md->md_name));
109e02d6efpjd	md->md_id = le32dec(data + 36);
110e02d6efpjd	md->md_no = le16dec(data + 40);
111e02d6efpjd	md->md_all = le16dec(data + 42);
112a98f255pjd	bcopy(data + 44, md->md_provider, sizeof(md->md_provider));
113668a028pjd	md->md_provsize = le64dec(data + 60);
114e02d6efpjd}
115e02d6efpjd#endif	/* _G_CONCAT_H_ */
116