geom.h revision 104602
1178355Ssam/*-
2178355Ssam * Copyright (c) 2002 Poul-Henning Kamp
3178355Ssam * Copyright (c) 2002 Networks Associates Technology, Inc.
4208060Sdougb * All rights reserved.
5178355Ssam *
6178355Ssam * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7178355Ssam * and NAI Labs, the Security Research Division of Network Associates, Inc.
8178355Ssam * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9178355Ssam * DARPA CHATS research program.
10178355Ssam *
11178355Ssam * Redistribution and use in source and binary forms, with or without
12178355Ssam * modification, are permitted provided that the following conditions
13208060Sdougb * are met:
14178355Ssam * 1. Redistributions of source code must retain the above copyright
15178355Ssam *    notice, this list of conditions and the following disclaimer.
16178355Ssam * 2. Redistributions in binary form must reproduce the above copyright
17178355Ssam *    notice, this list of conditions and the following disclaimer in the
18178355Ssam *    documentation and/or other materials provided with the distribution.
19178355Ssam * 3. The names of the authors may not be used to endorse or promote
20178355Ssam *    products derived from this software without specific prior written
21178355Ssam *    permission.
22178355Ssam *
23178355Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24208060Sdougb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25178355Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26178355Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27178355Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28178355Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29178355Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30178355Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31178355Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32178355Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33178355Ssam * SUCH DAMAGE.
34178355Ssam *
35178355Ssam * $FreeBSD: head/sys/geom/geom.h 104602 2002-10-07 06:25:26Z phk $
36178355Ssam */
37178355Ssam
38178355Ssam#ifndef _GEOM_GEOM_H_
39178355Ssam#define _GEOM_GEOM_H_
40178355Ssam
41178355Ssam#include <sys/lock.h>
42186106Ssam#include <sys/mutex.h>
43178355Ssam#include <sys/sx.h>
44178355Ssam#include <sys/queue.h>
45178355Ssam#include <sys/ioccom.h>
46178355Ssam#include <sys/sbuf.h>
47178355Ssam
48178355Ssam#ifdef KERNELSIM
49178355Ssam/*
50178355Ssam * The GEOM subsystem makes a few concessions in order to be able to run as a
51178355Ssam * user-land simulation as well as a kernel component.
52178355Ssam */
53178355Ssam#include <geom_sim.h>
54178355Ssam#endif
55178355Ssam
56178355Ssamstruct g_class;
57178355Ssamstruct g_geom;
58178355Ssamstruct g_consumer;
59178355Ssamstruct g_provider;
60178355Ssamstruct g_event;
61178355Ssamstruct thread;
62178355Ssamstruct bio;
63178355Ssamstruct sbuf;
64178355Ssam
65178355Ssamtypedef struct g_geom * g_create_geom_t (struct g_class *mp,
66178355Ssam    struct g_provider *pp, char *name);
67178355Ssamtypedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *,
68178355Ssam    int flags);
69178355Ssam#define G_TF_NORMAL		0
70178355Ssam#define G_TF_INSIST		1
71178355Ssam#define G_TF_TRANSPARENT	2
72178355Ssamtypedef int g_access_t (struct g_provider *, int, int, int);
73178355Ssam/* XXX: not sure about the thread arg */
74178355Ssamtypedef void g_orphan_t (struct g_consumer *);
75178355Ssam
76178355Ssamtypedef void g_start_t (struct bio *);
77178355Ssamtypedef void g_spoiled_t (struct g_consumer *);
78178355Ssamtypedef void g_dumpconf_t (struct sbuf *, char *indent, struct g_geom *,
79178355Ssam    struct g_consumer *, struct g_provider *);
80178355Ssam
81178355Ssam/*
82178355Ssam * The g_class structure describes a transformation class.  In other words
83178355Ssam * all BSD disklabel handlers share one g_class, all MBR handlers share
84178355Ssam * one common g_class and so on.
85178355Ssam * Certain operations are instantiated on the class, most notably the
86223497Sadrian * taste and create_geom functions.
87178355Ssam */
88178355Ssamstruct g_class {
89178355Ssam	char			*name;
90178355Ssam	g_taste_t		*taste;
91178355Ssam	g_create_geom_t		*create_geom;
92178355Ssam	/*
93178355Ssam	 * The remaning elements are private and classes should use
94178355Ssam	 * the G_CLASS_INITIALIZER macro to initialize them.
95178355Ssam         */
96178355Ssam	LIST_ENTRY(g_class)	class;
97178355Ssam	LIST_HEAD(,g_geom)	geom;
98178355Ssam	struct g_event		*event;
99223498Sadrian	u_int			protect;
100178355Ssam};
101178355Ssam
102178355Ssam#define G_CLASS_INITIALIZER { 0, 0 }, { 0 }, 0, 0
103178355Ssam
104178355Ssam/*
105178355Ssam * The g_geom is an instance of a g_class.
106178355Ssam */
107178355Ssamstruct g_geom {
108178355Ssam	u_int			protect;
109223498Sadrian	char			*name;
110178355Ssam	struct g_class		*class;
111178355Ssam	LIST_ENTRY(g_geom)	geom;
112178355Ssam	LIST_HEAD(,g_consumer)	consumer;
113178355Ssam	LIST_HEAD(,g_provider)	provider;
114178355Ssam	TAILQ_ENTRY(g_geom)	geoms;	/* XXX: better name */
115178355Ssam	int			rank;
116178355Ssam	g_start_t		*start;
117178355Ssam	g_spoiled_t		*spoiled;
118178355Ssam	g_dumpconf_t		*dumpconf;
119178355Ssam	g_access_t		*access;
120178355Ssam	g_orphan_t		*orphan;
121178355Ssam	void			*softc;
122178355Ssam	struct g_event		*event;
123178355Ssam	unsigned		flags;
124178355Ssam#define	G_GEOM_WITHER		1
125178355Ssam};
126178355Ssam
127178355Ssam/*
128178355Ssam * The g_bioq is a queue of struct bio's.
129178355Ssam * XXX: possibly collection point for statistics.
130178355Ssam * XXX: should (possibly) be collapsed with sys/bio.h::bio_queue_head.
131178355Ssam */
132178355Ssamstruct g_bioq {
133178355Ssam	TAILQ_HEAD(, bio)	bio_queue;
134178355Ssam	struct mtx		bio_queue_lock;
135178355Ssam	int			bio_queue_length;
136178355Ssam};
137178355Ssam
138178355Ssam/*
139178355Ssam * A g_consumer is an attachment point for a g_provider.  One g_consumer
140178355Ssam * can only be attached to one g_provider, but multiple g_consumers
141223496Sadrian * can be attached to one g_provider.
142223564Sadrian */
143223496Sadrian
144223496Sadrianstruct g_consumer {
145223496Sadrian	u_int			protect;
146223496Sadrian	struct g_geom		*geom;
147223563Sadrian	LIST_ENTRY(g_consumer)	consumer;
148223564Sadrian	struct g_provider	*provider;
149223563Sadrian	LIST_ENTRY(g_consumer)	consumers;	/* XXX: better name */
150223563Sadrian	int			acr, acw, ace;
151223563Sadrian	struct g_event		*event;
152223563Sadrian
153223563Sadrian	int			biocount;
154223564Sadrian	int			spoiled;
155223563Sadrian};
156223563Sadrian
157223563Sadrian/*
158223563Sadrian * A g_provider is a "logical disk".
159178355Ssam */
160178355Ssamstruct g_provider {
161178355Ssam	u_int			protect;
162178355Ssam	char			*name;
163178355Ssam	LIST_ENTRY(g_provider)	provider;
164178355Ssam	struct g_geom		*geom;
165178355Ssam	LIST_HEAD(,g_consumer)	consumers;
166178355Ssam	int			acr, acw, ace;
167178355Ssam	int			error;
168178355Ssam	struct g_event		*event;
169178355Ssam	TAILQ_ENTRY(g_provider)	orphan;
170178355Ssam	int			index;
171178355Ssam	off_t			mediasize;
172178355Ssam};
173178355Ssam
174178355Ssam/* geom_dump.c */
175178355Ssamvoid g_hexdump(void *ptr, int length);
176178355Ssamvoid g_trace(int level, char *, ...);
177178355Ssam#	define G_T_TOPOLOGY	1
178178355Ssam#	define G_T_BIO		2
179178355Ssam#	define G_T_ACCESS	4
180178355Ssam
181178355Ssam
182178355Ssam/* geom_event.c */
183178355Ssamtypedef void g_call_me_t(void *);
184178355Ssamint g_call_me(g_call_me_t *func, void *arg);
185178355Ssamvoid g_orphan_provider(struct g_provider *pp, int error);
186178355Ssamvoid g_silence(void);
187178355Ssamvoid g_waitidle(void);
188178355Ssam
189178355Ssam/* geom_subr.c */
190178355Ssamint g_access_abs(struct g_consumer *cp, int read, int write, int exclusive);
191178355Ssamint g_access_rel(struct g_consumer *cp, int read, int write, int exclusive);
192178355Ssamvoid g_add_class(struct g_class *mp);
193178355Ssamint g_attach(struct g_consumer *cp, struct g_provider *pp);
194178355Ssamstruct g_geom *g_create_geomf(char *class, struct g_provider *, char *fmt, ...);
195178355Ssamvoid g_destroy_consumer(struct g_consumer *cp);
196178355Ssamvoid g_destroy_geom(struct g_geom *pp);
197223496Sadrianvoid g_destroy_provider(struct g_provider *pp);
198223564Sadrianvoid g_detach(struct g_consumer *cp);
199223496Sadrianvoid g_error_provider(struct g_provider *pp, int error);
200223496Sadrianint g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len);
201223496Sadrian#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v))
202223496Sadrianint g_handleattr(struct bio *bp, char *attribute, void *val, int len);
203223496Sadrianint g_handleattr_int(struct bio *bp, char *attribute, int val);
204223496Sadrianint g_handleattr_off_t(struct bio *bp, char *attribute, off_t val);
205223564Sadrianstruct g_geom * g_insert_geom(char *class, struct g_consumer *cp);
206223496Sadrianstruct g_consumer * g_new_consumer(struct g_geom *gp);
207223496Sadrianstruct g_geom * g_new_geomf(struct g_class *mp, char *fmt, ...);
208223496Sadrianstruct g_provider * g_new_providerf(struct g_geom *gp, char *fmt, ...);
209223496Sadrianvoid g_sanity(void *ptr);
210223496Sadrianvoid g_spoil(struct g_provider *pp, struct g_consumer *cp);
211223563Sadrianint g_std_access(struct g_provider *pp, int dr, int dw, int de);
212223564Sadrianvoid g_std_done(struct bio *bp);
213223563Sadrianvoid g_std_spoiled(struct g_consumer *cp);
214223563Sadrian
215223563Sadrian/* geom_io.c */
216223563Sadrianstruct bio * g_clone_bio(struct bio *);
217223563Sadrianvoid g_destroy_bio(struct bio *);
218223563Sadrianvoid g_io_deliver(struct bio *bp, int error);
219223564Sadrianint g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr);
220223563Sadrianvoid g_io_request(struct bio *bp, struct g_consumer *cp);
221223563Sadrianint g_io_setattr(const char *attr, struct g_consumer *cp, int len, void *ptr);
222223563Sadrianstruct bio *g_new_bio(void);
223223563Sadrianvoid * g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error);
224223563Sadrianint g_write_data(struct g_consumer *cp, off_t offset, void *ptr, off_t length);
225223563Sadrian
226223564Sadrian/* geom_kern.c / geom_kernsim.c */
227223563Sadrian
228223563Sadrian#ifndef _SYS_CONF_H_
229223563Sadriantypedef int d_ioctl_t(dev_t dev, u_long cmd, caddr_t data,
230223563Sadrian		      int fflag, struct thread *td);
231223563Sadrian#endif
232223563Sadrian
233223564Sadrianstruct g_ioctl {
234223563Sadrian	u_long		cmd;
235223563Sadrian	void		*data;
236223563Sadrian	int		fflag;
237223563Sadrian	struct thread	*td;
238223563Sadrian	d_ioctl_t	*func;
239178355Ssam	dev_t		dev;
240178355Ssam};
241178355Ssam
242178355Ssam#ifdef _KERNEL
243178355Ssam
244178355Ssamstruct g_kerneldump {
245178355Ssam	off_t		offset;
246178355Ssam	off_t		length;
247178355Ssam};
248178355Ssam
249178355SsamMALLOC_DECLARE(M_GEOM);
250178355Ssam
251178355Ssamstatic __inline void *
252178355Ssamg_malloc(int size, int flags)
253187343Ssam{
254187343Ssam	void *p;
255187343Ssam
256187343Ssam	p = malloc(size, M_GEOM, flags);
257187343Ssam	g_sanity(p);
258187343Ssam	/* printf("malloc(%d, %x) -> %p\n", size, flags, p); */
259187343Ssam	return (p);
260187343Ssam}
261187343Ssam
262187343Ssamstatic __inline void
263187343Ssamg_free(void *ptr)
264187343Ssam{
265187343Ssam	g_sanity(ptr);
266187343Ssam	/* printf("free(%p)\n", ptr); */
267187343Ssam	free(ptr, M_GEOM);
268187343Ssam}
269187343Ssam
270187343Ssamextern struct sx topology_lock;
271187343Ssam
272187343Ssam#define g_topology_lock() 					\
273187343Ssam	do {							\
274187343Ssam		mtx_assert(&Giant, MA_NOTOWNED);		\
275187343Ssam		sx_xlock(&topology_lock);			\
276187343Ssam	} while (0)
277187343Ssam
278187343Ssam#define g_topology_unlock()					\
279187343Ssam	do {							\
280187343Ssam		g_sanity(NULL);					\
281187343Ssam		sx_xunlock(&topology_lock);			\
282187343Ssam	} while (0)
283187343Ssam
284187343Ssam#define g_topology_assert()					\
285187343Ssam	do {							\
286187343Ssam		g_sanity(NULL);					\
287187343Ssam		sx_assert(&topology_lock, SX_XLOCKED);		\
288187343Ssam	} while (0)
289187343Ssam
290187343Ssam#define DECLARE_GEOM_CLASS(class, name) 	\
291187343Ssam	static void				\
292187343Ssam	name##init(void)			\
293187343Ssam	{					\
294223504Sadrian		mtx_unlock(&Giant);		\
295187343Ssam		g_add_class(&class);		\
296187343Ssam		mtx_lock(&Giant);		\
297187343Ssam	}					\
298187343Ssam	SYSINIT(name, SI_SUB_PSEUDO, SI_ORDER_FIRST, name##init, NULL);
299187343Ssam
300187343Ssam#endif /* _KERNEL */
301187343Ssam
302178355Ssam#define GEOMGETCONF _IOWR('G',  0, struct sbuf)
303178355Ssam
304178355Ssam/* geom_enc.c */
305178355Ssamuint16_t g_dec_be2(u_char *p);
306178355Ssamuint32_t g_dec_be4(u_char *p);
307178355Ssamuint16_t g_dec_le2(u_char *p);
308178355Ssamuint32_t g_dec_le4(u_char *p);
309178355Ssamuint64_t g_dec_le8(u_char *p);
310178355Ssamvoid g_enc_le2(u_char *p, uint16_t u);
311178355Ssamvoid g_enc_le4(u_char *p, uint32_t u);
312178355Ssamvoid g_enc_le8(u_char *p, uint64_t u);
313178355Ssam
314178355Ssam#endif /* _GEOM_GEOM_H_ */
315178355Ssam