geom.h revision 114495
1169691Skan/*-
2169691Skan * Copyright (c) 2002 Poul-Henning Kamp
3169691Skan * Copyright (c) 2002 Networks Associates Technology, Inc.
4169691Skan * All rights reserved.
5169691Skan *
6169691Skan * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7169691Skan * and NAI Labs, the Security Research Division of Network Associates, Inc.
8169691Skan * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9169691Skan * DARPA CHATS research program.
10169691Skan *
11169691Skan * Redistribution and use in source and binary forms, with or without
12169691Skan * modification, are permitted provided that the following conditions
13169691Skan * are met:
14169691Skan * 1. Redistributions of source code must retain the above copyright
15169691Skan *    notice, this list of conditions and the following disclaimer.
16169691Skan * 2. Redistributions in binary form must reproduce the above copyright
17169691Skan *    notice, this list of conditions and the following disclaimer in the
18169691Skan *    documentation and/or other materials provided with the distribution.
19169691Skan * 3. The names of the authors may not be used to endorse or promote
20169691Skan *    products derived from this software without specific prior written
21169691Skan *    permission.
22169691Skan *
23169691Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24169691Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25169691Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26169691Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27169691Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28169691Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29169691Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30169691Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31169691Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32169691Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33169691Skan * SUCH DAMAGE.
34169691Skan *
35169691Skan * $FreeBSD: head/sys/geom/geom.h 114495 2003-05-02 06:15:27Z phk $
36169691Skan */
37169691Skan
38169691Skan#ifndef _GEOM_GEOM_H_
39169691Skan#define _GEOM_GEOM_H_
40169691Skan
41169691Skan#include <sys/lock.h>
42169691Skan#include <sys/mutex.h>
43169691Skan#include <sys/sx.h>
44169691Skan#include <sys/queue.h>
45169691Skan#include <sys/ioccom.h>
46169691Skan#include <sys/sbuf.h>
47169691Skan
48169691Skanstruct g_class;
49169691Skanstruct g_geom;
50169691Skanstruct g_consumer;
51169691Skanstruct g_provider;
52169691Skanstruct g_stat;
53169691Skanstruct thread;
54169691Skanstruct bio;
55169691Skanstruct sbuf;
56169691Skanstruct gctl_req;
57169691Skanstruct g_configargs;
58169691Skan
59169691Skantypedef int g_config_t (struct g_configargs *ca);
60169691Skantypedef int g_ctl_create_geom_t (struct gctl_req *, struct g_class *cp, struct g_provider *pp);
61169691Skantypedef int g_ctl_destroy_geom_t (struct gctl_req *, struct g_class *cp, struct g_geom *gp);
62169691Skantypedef int g_ctl_config_geom_t (struct gctl_req *, struct g_geom *gp, const char *verb);
63169691Skantypedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *,
64169691Skan    int flags);
65169691Skan#define G_TF_NORMAL		0
66169691Skan#define G_TF_INSIST		1
67169691Skan#define G_TF_TRANSPARENT	2
68169691Skantypedef int g_access_t (struct g_provider *, int, int, int);
69169691Skan/* XXX: not sure about the thread arg */
70169691Skantypedef void g_orphan_t (struct g_consumer *);
71169691Skan
72169691Skantypedef void g_start_t (struct bio *);
73169691Skantypedef void g_spoiled_t (struct g_consumer *);
74169691Skantypedef void g_dumpconf_t (struct sbuf *, const char *indent, struct g_geom *,
75169691Skan    struct g_consumer *, struct g_provider *);
76169691Skan
77169691Skan/*
78169691Skan * The g_class structure describes a transformation class.  In other words
79169691Skan * all BSD disklabel handlers share one g_class, all MBR handlers share
80169691Skan * one common g_class and so on.
81169691Skan * Certain operations are instantiated on the class, most notably the
82169691Skan * taste and config_geom functions.
83169691Skan */
84169691Skanstruct g_class {
85169691Skan	const char		*name;
86169691Skan	g_taste_t		*taste;
87169691Skan	g_config_t		*config;
88169691Skan	g_ctl_create_geom_t	*create_geom;
89169691Skan	g_ctl_destroy_geom_t	*destroy_geom;
90169691Skan	g_ctl_config_geom_t	*config_geom;
91169691Skan	/*
92169691Skan	 * The remaning elements are private and classes should use
93169691Skan	 * the G_CLASS_INITIALIZER macro to initialize them.
94169691Skan         */
95169691Skan	LIST_ENTRY(g_class)	class;
96169691Skan	LIST_HEAD(,g_geom)	geom;
97169691Skan	u_int			protect;
98169691Skan};
99169691Skan
100169691Skan#define G_CLASS_INITIALIZER 	\
101169691Skan	.class = { 0, 0 },	\
102169691Skan	.geom = { 0 },		\
103169691Skan	.protect = 0
104169691Skan
105169691Skan/*
106169691Skan * The g_geom is an instance of a g_class.
107169691Skan */
108169691Skanstruct g_geom {
109169691Skan	u_int			protect;
110169691Skan	char			*name;
111169691Skan	struct g_class		*class;
112169691Skan	LIST_ENTRY(g_geom)	geom;
113169691Skan	LIST_HEAD(,g_consumer)	consumer;
114169691Skan	LIST_HEAD(,g_provider)	provider;
115169691Skan	TAILQ_ENTRY(g_geom)	geoms;	/* XXX: better name */
116169691Skan	int			rank;
117169691Skan	g_start_t		*start;
118169691Skan	g_spoiled_t		*spoiled;
119169691Skan	g_dumpconf_t		*dumpconf;
120169691Skan	g_access_t		*access;
121169691Skan	g_orphan_t		*orphan;
122169691Skan	void			*softc;
123169691Skan	unsigned		flags;
124169691Skan#define	G_GEOM_WITHER		1
125169691Skan};
126169691Skan
127169691Skan/*
128169691Skan * The g_bioq is a queue of struct bio's.
129169691Skan * XXX: possibly collection point for statistics.
130169691Skan * XXX: should (possibly) be collapsed with sys/bio.h::bio_queue_head.
131169691Skan */
132169691Skanstruct g_bioq {
133169691Skan	TAILQ_HEAD(, bio)	bio_queue;
134169691Skan	struct mtx		bio_queue_lock;
135169691Skan	int			bio_queue_length;
136169691Skan};
137169691Skan
138169691Skan/*
139169691Skan * A g_consumer is an attachment point for a g_provider.  One g_consumer
140169691Skan * can only be attached to one g_provider, but multiple g_consumers
141169691Skan * can be attached to one g_provider.
142169691Skan */
143169691Skan
144169691Skanstruct g_consumer {
145169691Skan	u_int			protect;
146169691Skan	struct g_geom		*geom;
147169691Skan	LIST_ENTRY(g_consumer)	consumer;
148169691Skan	struct g_provider	*provider;
149169691Skan	LIST_ENTRY(g_consumer)	consumers;	/* XXX: better name */
150169691Skan	int			acr, acw, ace;
151169691Skan	int			spoiled;
152169691Skan	struct devstat		*stat;
153169691Skan	u_int			nstart, nend;
154169691Skan};
155169691Skan
156169691Skan/*
157169691Skan * A g_provider is a "logical disk".
158169691Skan */
159169691Skanstruct g_provider {
160169691Skan	u_int			protect;
161169691Skan	char			*name;
162169691Skan	LIST_ENTRY(g_provider)	provider;
163169691Skan	struct g_geom		*geom;
164169691Skan	LIST_HEAD(,g_consumer)	consumers;
165169691Skan	int			acr, acw, ace;
166169691Skan	int			error;
167169691Skan	TAILQ_ENTRY(g_provider)	orphan;
168169691Skan	u_int			index;
169169691Skan	off_t			mediasize;
170169691Skan	u_int			sectorsize;
171169691Skan	u_int			stripesize;
172169691Skan	u_int			stripeoffset;
173169691Skan	struct devstat		*stat;
174169691Skan	u_int			nstart, nend;
175169691Skan	u_int			flags;
176169691Skan#define G_PF_CANDELETE		0x1
177169691Skan};
178169691Skan
179169691Skan/* geom_dev.c */
180169691Skanint g_dev_print(void);
181169691Skan
182169691Skan/* geom_dump.c */
183169691Skanvoid g_hexdump(void *ptr, int length);
184169691Skanvoid g_trace(int level, const char *, ...);
185169691Skan#	define G_T_TOPOLOGY	1
186169691Skan#	define G_T_BIO		2
187169691Skan#	define G_T_ACCESS	4
188169691Skan
189169691Skan
190169691Skan/* geom_event.c */
191169691Skantypedef void g_event_t(void *, int flag);
192169691Skan#define EV_CANCEL	1
193169691Skanint g_post_event(g_event_t *func, void *arg, int flag, ...);
194169691Skanint g_waitfor_event(g_event_t *func, void *arg, int flag, ...);
195169691Skanvoid g_cancel_event(void *ref);
196169691Skanvoid g_orphan_provider(struct g_provider *pp, int error);
197169691Skanvoid g_waitidle(void);
198169691Skan
199169691Skan/* geom_subr.c */
200169691Skanint g_access_abs(struct g_consumer *cp, int nread, int nwrite, int nexcl);
201169691Skanint g_access_rel(struct g_consumer *cp, int nread, int nwrite, int nexcl);
202169691Skanvoid g_add_class(struct g_class *mp);
203169691Skanint g_attach(struct g_consumer *cp, struct g_provider *pp);
204169691Skanvoid g_destroy_consumer(struct g_consumer *cp);
205169691Skanvoid g_destroy_geom(struct g_geom *pp);
206169691Skanvoid g_destroy_provider(struct g_provider *pp);
207169691Skanvoid g_detach(struct g_consumer *cp);
208169691Skanvoid g_error_provider(struct g_provider *pp, int error);
209169691Skanint g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len);
210169691Skan#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v))
211169691Skanint g_handleattr(struct bio *bp, const char *attribute, void *val, int len);
212169691Skanint g_handleattr_int(struct bio *bp, const char *attribute, int val);
213169691Skanint g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val);
214169691Skanstruct g_consumer * g_new_consumer(struct g_geom *gp);
215169691Skanstruct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
216169691Skanstruct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
217169691Skanvoid g_sanity(void *ptr);
218169691Skanvoid g_spoil(struct g_provider *pp, struct g_consumer *cp);
219169691Skanint g_std_access(struct g_provider *pp, int dr, int dw, int de);
220169691Skanvoid g_std_done(struct bio *bp);
221169691Skanvoid g_std_spoiled(struct g_consumer *cp);
222169691Skanvoid g_wither_geom(struct g_geom *gp, int error);
223169691Skan
224169691Skan/* geom_io.c */
225169691Skanstruct bio * g_clone_bio(struct bio *);
226169691Skanvoid g_destroy_bio(struct bio *);
227169691Skanvoid g_io_deliver(struct bio *bp, int error);
228169691Skanint g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr);
229169691Skanvoid g_io_request(struct bio *bp, struct g_consumer *cp);
230169691Skanstruct bio *g_new_bio(void);
231169691Skanvoid * g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error);
232169691Skanint g_write_data(struct g_consumer *cp, off_t offset, void *ptr, off_t length);
233169691Skan
234169691Skan/* geom_kern.c / geom_kernsim.c */
235169691Skan
236169691Skan#ifndef _SYS_CONF_H_
237169691Skantypedef int d_ioctl_t(dev_t dev, u_long cmd, caddr_t data,
238169691Skan		      int fflag, struct thread *td);
239169691Skan#endif
240169691Skan
241169691Skanstruct g_ioctl {
242169691Skan	u_long		cmd;
243169691Skan	void		*data;
244169691Skan	int		fflag;
245169691Skan	struct thread	*td;
246169691Skan	d_ioctl_t	*func;
247169691Skan	void		*dev;
248169691Skan};
249169691Skan
250169691Skan#ifdef _KERNEL
251169691Skan
252169691Skanstruct g_kerneldump {
253169691Skan	off_t		offset;
254169691Skan	off_t		length;
255169691Skan};
256169691Skan
257169691SkanMALLOC_DECLARE(M_GEOM);
258169691Skan
259169691Skanstatic __inline void *
260169691Skang_malloc(int size, int flags)
261169691Skan{
262169691Skan	void *p;
263169691Skan
264169691Skan	p = malloc(size, M_GEOM, flags);
265169691Skan	g_sanity(p);
266169691Skan	/* printf("malloc(%d, %x) -> %p\n", size, flags, p); */
267169691Skan	return (p);
268169691Skan}
269169691Skan
270169691Skanstatic __inline void
271169691Skang_free(void *ptr)
272169691Skan{
273169691Skan	g_sanity(ptr);
274169691Skan	/* printf("free(%p)\n", ptr); */
275169691Skan	free(ptr, M_GEOM);
276169691Skan}
277169691Skan
278169691Skanextern struct sx topology_lock;
279169691Skan
280169691Skan#define g_topology_lock() 					\
281169691Skan	do {							\
282169691Skan		mtx_assert(&Giant, MA_NOTOWNED);		\
283169691Skan		sx_xlock(&topology_lock);			\
284169691Skan	} while (0)
285169691Skan
286169691Skan#define g_topology_unlock()					\
287169691Skan	do {							\
288169691Skan		g_sanity(NULL);					\
289169691Skan		sx_xunlock(&topology_lock);			\
290169691Skan	} while (0)
291169691Skan
292169691Skan#define g_topology_assert()					\
293169691Skan	do {							\
294169691Skan		g_sanity(NULL);					\
295169691Skan		sx_assert(&topology_lock, SX_XLOCKED);		\
296169691Skan	} while (0)
297169691Skan
298169691Skan#define DECLARE_GEOM_CLASS_INIT(class, name, init) 	\
299169691Skan	SYSINIT(name, SI_SUB_DRIVERS, SI_ORDER_FIRST, init, NULL);
300169691Skan
301169691Skan#define DECLARE_GEOM_CLASS(class, name) 	\
302169691Skan	static void				\
303169691Skan	name##init(void)			\
304169691Skan	{					\
305169691Skan		mtx_unlock(&Giant);		\
306169691Skan		g_add_class(&class);		\
307169691Skan		mtx_lock(&Giant);		\
308169691Skan	}					\
309169691Skan	DECLARE_GEOM_CLASS_INIT(class, name, name##init);
310169691Skan
311169691Skan#endif /* _KERNEL */
312169691Skan
313169691Skan/* geom_ctl.c */
314169691Skanvoid *gctl_get_param(struct gctl_req *req, const char *param, int *len);
315169691Skanvoid *gctl_get_paraml(struct gctl_req *req, const char *param, int len);
316169691Skanint gctl_error(struct gctl_req *req, const char *fmt, ...);
317169691Skan
318169691Skan#endif /* _GEOM_GEOM_H_ */
319169691Skan