geom.h revision 115468
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9 * DARPA CHATS research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. The names of the authors may not be used to endorse or promote
20 *    products derived from this software without specific prior written
21 *    permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * $FreeBSD: head/sys/geom/geom.h 115468 2003-05-31 16:59:27Z phk $
36 */
37
38#ifndef _GEOM_GEOM_H_
39#define _GEOM_GEOM_H_
40
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/sx.h>
44#include <sys/queue.h>
45#include <sys/ioccom.h>
46#include <sys/sbuf.h>
47
48struct g_class;
49struct g_geom;
50struct g_consumer;
51struct g_provider;
52struct g_stat;
53struct thread;
54struct bio;
55struct sbuf;
56struct gctl_req;
57struct g_configargs;
58
59typedef int g_config_t (struct g_configargs *ca);
60typedef int g_ctl_create_geom_t (struct gctl_req *, struct g_class *cp, struct g_provider *pp);
61typedef int g_ctl_destroy_geom_t (struct gctl_req *, struct g_class *cp, struct g_geom *gp);
62typedef int g_ctl_config_geom_t (struct gctl_req *, struct g_geom *gp, const char *verb);
63typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *,
64    int flags);
65#define G_TF_NORMAL		0
66#define G_TF_INSIST		1
67#define G_TF_TRANSPARENT	2
68typedef int g_access_t (struct g_provider *, int, int, int);
69/* XXX: not sure about the thread arg */
70typedef void g_orphan_t (struct g_consumer *);
71
72typedef void g_start_t (struct bio *);
73typedef void g_spoiled_t (struct g_consumer *);
74typedef void g_dumpconf_t (struct sbuf *, const char *indent, struct g_geom *,
75    struct g_consumer *, struct g_provider *);
76
77/*
78 * The g_class structure describes a transformation class.  In other words
79 * all BSD disklabel handlers share one g_class, all MBR handlers share
80 * one common g_class and so on.
81 * Certain operations are instantiated on the class, most notably the
82 * taste and config_geom functions.
83 */
84struct g_class {
85	const char		*name;
86	g_taste_t		*taste;
87	g_config_t		*config;
88	g_ctl_create_geom_t	*create_geom;
89	g_ctl_destroy_geom_t	*destroy_geom;
90	g_ctl_config_geom_t	*config_geom;
91	/*
92	 * The remaining elements are private
93	 */
94	LIST_ENTRY(g_class)	class;
95	LIST_HEAD(,g_geom)	geom;
96	u_int			protect;
97};
98
99/*
100 * The g_geom is an instance of a g_class.
101 */
102struct g_geom {
103	u_int			protect;
104	char			*name;
105	struct g_class		*class;
106	LIST_ENTRY(g_geom)	geom;
107	LIST_HEAD(,g_consumer)	consumer;
108	LIST_HEAD(,g_provider)	provider;
109	TAILQ_ENTRY(g_geom)	geoms;	/* XXX: better name */
110	int			rank;
111	g_start_t		*start;
112	g_spoiled_t		*spoiled;
113	g_dumpconf_t		*dumpconf;
114	g_access_t		*access;
115	g_orphan_t		*orphan;
116	void			*softc;
117	unsigned		flags;
118#define	G_GEOM_WITHER		1
119};
120
121/*
122 * The g_bioq is a queue of struct bio's.
123 * XXX: possibly collection point for statistics.
124 * XXX: should (possibly) be collapsed with sys/bio.h::bio_queue_head.
125 */
126struct g_bioq {
127	TAILQ_HEAD(, bio)	bio_queue;
128	struct mtx		bio_queue_lock;
129	int			bio_queue_length;
130};
131
132/*
133 * A g_consumer is an attachment point for a g_provider.  One g_consumer
134 * can only be attached to one g_provider, but multiple g_consumers
135 * can be attached to one g_provider.
136 */
137
138struct g_consumer {
139	u_int			protect;
140	struct g_geom		*geom;
141	LIST_ENTRY(g_consumer)	consumer;
142	struct g_provider	*provider;
143	LIST_ENTRY(g_consumer)	consumers;	/* XXX: better name */
144	int			acr, acw, ace;
145	int			spoiled;
146	struct devstat		*stat;
147	u_int			nstart, nend;
148};
149
150/*
151 * A g_provider is a "logical disk".
152 */
153struct g_provider {
154	u_int			protect;
155	char			*name;
156	LIST_ENTRY(g_provider)	provider;
157	struct g_geom		*geom;
158	LIST_HEAD(,g_consumer)	consumers;
159	int			acr, acw, ace;
160	int			error;
161	TAILQ_ENTRY(g_provider)	orphan;
162	u_int			index;
163	off_t			mediasize;
164	u_int			sectorsize;
165	u_int			stripesize;
166	u_int			stripeoffset;
167	struct devstat		*stat;
168	u_int			nstart, nend;
169	u_int			flags;
170#define G_PF_CANDELETE		0x1
171};
172
173/* geom_dev.c */
174int g_dev_print(void);
175
176/* geom_dump.c */
177void g_hexdump(void *ptr, int length);
178void g_trace(int level, const char *, ...);
179#	define G_T_TOPOLOGY	1
180#	define G_T_BIO		2
181#	define G_T_ACCESS	4
182
183
184/* geom_event.c */
185typedef void g_event_t(void *, int flag);
186#define EV_CANCEL	1
187int g_post_event(g_event_t *func, void *arg, int flag, ...);
188int g_waitfor_event(g_event_t *func, void *arg, int flag, ...);
189void g_cancel_event(void *ref);
190void g_orphan_provider(struct g_provider *pp, int error);
191void g_waitidle(void);
192
193/* geom_subr.c */
194int g_access_abs(struct g_consumer *cp, int nread, int nwrite, int nexcl);
195int g_access_rel(struct g_consumer *cp, int nread, int nwrite, int nexcl);
196void g_add_class(struct g_class *mp);
197int g_attach(struct g_consumer *cp, struct g_provider *pp);
198void g_destroy_consumer(struct g_consumer *cp);
199void g_destroy_geom(struct g_geom *pp);
200void g_destroy_provider(struct g_provider *pp);
201void g_detach(struct g_consumer *cp);
202void g_error_provider(struct g_provider *pp, int error);
203int g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len);
204#define g_getattr(a, c, v) g_getattr__((a), (c), (v), sizeof *(v))
205int g_handleattr(struct bio *bp, const char *attribute, void *val, int len);
206int g_handleattr_int(struct bio *bp, const char *attribute, int val);
207int g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val);
208struct g_consumer * g_new_consumer(struct g_geom *gp);
209struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...);
210struct g_provider * g_new_providerf(struct g_geom *gp, const char *fmt, ...);
211void g_sanity(void *ptr);
212void g_spoil(struct g_provider *pp, struct g_consumer *cp);
213int g_std_access(struct g_provider *pp, int dr, int dw, int de);
214void g_std_done(struct bio *bp);
215void g_std_spoiled(struct g_consumer *cp);
216void g_wither_geom(struct g_geom *gp, int error);
217
218/* geom_io.c */
219struct bio * g_clone_bio(struct bio *);
220void g_destroy_bio(struct bio *);
221void g_io_deliver(struct bio *bp, int error);
222int g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr);
223void g_io_request(struct bio *bp, struct g_consumer *cp);
224struct bio *g_new_bio(void);
225void * g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error);
226int g_write_data(struct g_consumer *cp, off_t offset, void *ptr, off_t length);
227
228/* geom_kern.c / geom_kernsim.c */
229
230#ifndef _SYS_CONF_H_
231typedef int d_ioctl_t(dev_t dev, u_long cmd, caddr_t data,
232		      int fflag, struct thread *td);
233#endif
234
235struct g_ioctl {
236	u_long		cmd;
237	void		*data;
238	int		fflag;
239	struct thread	*td;
240	d_ioctl_t	*func;
241	void		*dev;
242};
243
244#ifdef _KERNEL
245
246struct g_kerneldump {
247	off_t		offset;
248	off_t		length;
249};
250
251MALLOC_DECLARE(M_GEOM);
252
253static __inline void *
254g_malloc(int size, int flags)
255{
256	void *p;
257
258	p = malloc(size, M_GEOM, flags);
259	g_sanity(p);
260	/* printf("malloc(%d, %x) -> %p\n", size, flags, p); */
261	return (p);
262}
263
264static __inline void
265g_free(void *ptr)
266{
267	g_sanity(ptr);
268	/* printf("free(%p)\n", ptr); */
269	free(ptr, M_GEOM);
270}
271
272extern struct sx topology_lock;
273
274#define g_topology_lock() 					\
275	do {							\
276		mtx_assert(&Giant, MA_NOTOWNED);		\
277		sx_xlock(&topology_lock);			\
278	} while (0)
279
280#define g_topology_unlock()					\
281	do {							\
282		g_sanity(NULL);					\
283		sx_xunlock(&topology_lock);			\
284	} while (0)
285
286#define g_topology_assert()					\
287	do {							\
288		g_sanity(NULL);					\
289		sx_assert(&topology_lock, SX_XLOCKED);		\
290	} while (0)
291
292#define DECLARE_GEOM_CLASS_INIT(class, name, init) 	\
293	SYSINIT(name, SI_SUB_DRIVERS, SI_ORDER_FIRST, init, NULL);
294
295#define DECLARE_GEOM_CLASS(class, name) 	\
296	static void				\
297	name##init(void)			\
298	{					\
299		mtx_unlock(&Giant);		\
300		g_add_class(&class);		\
301		mtx_lock(&Giant);		\
302	}					\
303	DECLARE_GEOM_CLASS_INIT(class, name, name##init);
304
305#endif /* _KERNEL */
306
307/* geom_ctl.c */
308int gctl_set_param(struct gctl_req *req, const char *param, void *ptr, int len);
309void *gctl_get_param(struct gctl_req *req, const char *param, int *len);
310void *gctl_get_paraml(struct gctl_req *req, const char *param, int len);
311int gctl_error(struct gctl_req *req, const char *fmt, ...);
312
313#endif /* _GEOM_GEOM_H_ */
314