geom.h revision 93250
192108Sphk/*-
292108Sphk * Copyright (c) 2002 Poul-Henning Kamp
392108Sphk * Copyright (c) 2002 Networks Associates Technology, Inc.
492108Sphk * All rights reserved.
592108Sphk *
692108Sphk * This software was developed for the FreeBSD Project by Poul-Henning Kamp
792108Sphk * and NAI Labs, the Security Research Division of Network Associates, Inc.
892108Sphk * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
992108Sphk * DARPA CHATS research program.
1092108Sphk *
1192108Sphk * Redistribution and use in source and binary forms, with or without
1292108Sphk * modification, are permitted provided that the following conditions
1392108Sphk * are met:
1492108Sphk * 1. Redistributions of source code must retain the above copyright
1592108Sphk *    notice, this list of conditions and the following disclaimer.
1692108Sphk * 2. Redistributions in binary form must reproduce the above copyright
1792108Sphk *    notice, this list of conditions and the following disclaimer in the
1892108Sphk *    documentation and/or other materials provided with the distribution.
1992108Sphk * 3. The names of the authors may not be used to endorse or promote
2092108Sphk *    products derived from this software without specific prior written
2192108Sphk *    permission.
2292108Sphk *
2392108Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2492108Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2592108Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2692108Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2792108Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2892108Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2992108Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3092108Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3192108Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3292108Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3392108Sphk * SUCH DAMAGE.
3492108Sphk *
3592108Sphk * $FreeBSD: head/sys/geom/geom.h 93250 2002-03-26 22:07:38Z phk $
3692108Sphk */
3792108Sphk
3892108Sphk#include <sys/lock.h>
3992108Sphk#include <sys/mutex.h>
4092108Sphk#include <sys/sx.h>
4192108Sphk#include <sys/queue.h>
4292108Sphk
4392108Sphk#ifndef _KERNEL
4492108Sphk/*
4592108Sphk * The GEOM subsystem makes a few concessions in order to be able to run as a
4692108Sphk * user-land simulation as well as a kernel component.
4792108Sphk */
4892514Sphk#include <geom_sim.h>
4992108Sphk#endif
5092108Sphk
5193248Sphkstruct g_class;
5292108Sphkstruct g_geom;
5392108Sphkstruct g_consumer;
5492108Sphkstruct g_provider;
5592108Sphkstruct g_event;
5692108Sphkstruct thread;
5792108Sphkstruct bio;
5892108Sphkstruct sbuf;
5992108Sphk
6093248Sphk#define G_CLASS_INITSTUFF { 0, 0 }, { 0 }, 0
6192108Sphk
6293248Sphktypedef struct g_geom * g_create_geom_t (struct g_class *mp,
6392108Sphk    struct g_provider *pp, char *name);
6493248Sphktypedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *,
6593250Sphk    int flags);
6692108Sphk#define G_TF_NORMAL		0
6792108Sphk#define G_TF_INSIST		1
6892108Sphk#define G_TF_TRANSPARENT	2
6992108Sphktypedef int g_access_t (struct g_provider *, int, int, int);
7092108Sphk/* XXX: not sure about the thread arg */
7193250Sphktypedef void g_orphan_t (struct g_consumer *);
7292108Sphk
7392108Sphktypedef void g_start_t (struct bio *);
7492108Sphktypedef void g_spoiled_t (struct g_consumer *);
7592108Sphktypedef void g_dumpconf_t (struct sbuf *, char *indent, struct g_geom *,
7692108Sphk    struct g_consumer *, struct g_provider *);
7792108Sphk
7892108Sphk/*
7993248Sphk * The g_class structure describes a transformation class.  In other words
8093248Sphk * all BSD disklabel handlers share one g_class, all MBR handlers share
8193248Sphk * one common g_class and so on.
8293248Sphk * Certain operations are instantiated on the class, most notably the
8392108Sphk * taste and create_geom functions.
8492108Sphk * XXX: should access and orphan go into g_geom ?
8592108Sphk * XXX: would g_class be a better and less confusing name ?
8692108Sphk */
8793248Sphkstruct g_class {
8892108Sphk	char			*name;
8992108Sphk	g_taste_t		*taste;
9092108Sphk	g_access_t		*access;
9192108Sphk	g_orphan_t		*orphan;
9292108Sphk	g_create_geom_t		*create_geom;
9393248Sphk	LIST_ENTRY(g_class)	class;
9492108Sphk	LIST_HEAD(,g_geom)	geom;
9592108Sphk	struct g_event		*event;
9692108Sphk};
9792108Sphk
9892108Sphk/*
9993248Sphk * The g_geom is an instance of a g_class.
10092108Sphk */
10192108Sphkstruct g_geom {
10292108Sphk	char			*name;
10393248Sphk	struct g_class		*class;
10492108Sphk	LIST_ENTRY(g_geom)	geom;
10592108Sphk	LIST_HEAD(,g_consumer)	consumer;
10692108Sphk	LIST_HEAD(,g_provider)	provider;
10792108Sphk	TAILQ_ENTRY(g_geom)	geoms;	/* XXX: better name */
10892108Sphk	int			rank;
10992108Sphk	g_start_t		*start;
11092108Sphk	g_spoiled_t		*spoiled;
11192108Sphk	g_dumpconf_t		*dumpconf;
11292108Sphk	void			*softc;
11392108Sphk	struct g_event		*event;
11492108Sphk	unsigned		flags;
11592108Sphk#define	G_GEOM_WITHER		1
11692108Sphk};
11792108Sphk
11892108Sphk/*
11992108Sphk * The g_bioq is a queue of struct bio's.
12092108Sphk * XXX: possibly collection point for statistics.
12192108Sphk * XXX: should (possibly) be collapsed with sys/bio.h::bio_queue_head.
12292108Sphk */
12392108Sphkstruct g_bioq {
12492108Sphk	TAILQ_HEAD(, bio)	bio_queue;
12592108Sphk	struct mtx		bio_queue_lock;
12692108Sphk	int			bio_queue_length;
12792108Sphk};
12892108Sphk
12992108Sphk/*
13092108Sphk * A g_consumer is an attachment point for a g_provider.  One g_consumer
13192108Sphk * can only be attached to one g_provider, but multiple g_consumers
13292108Sphk * can be attached to one g_provider.
13392108Sphk */
13492108Sphk
13592108Sphkstruct g_consumer {
13692108Sphk	struct g_geom		*geom;
13792108Sphk	LIST_ENTRY(g_consumer)	consumer;
13892108Sphk	struct g_provider	*provider;
13992108Sphk	LIST_ENTRY(g_consumer)	consumers;	/* XXX: better name */
14092108Sphk	int			acr, acw, ace;
14192108Sphk	struct g_event		*event;
14292108Sphk
14392108Sphk	int			biocount;
14492108Sphk	int			spoiled;
14592108Sphk};
14692108Sphk
14792108Sphk/*
14892108Sphk * A g_provider is a "logical disk".
14992108Sphk */
15092108Sphkstruct g_provider {
15192108Sphk	char			*name;
15292108Sphk	LIST_ENTRY(g_provider)	provider;
15392108Sphk	struct g_geom		*geom;
15492108Sphk	LIST_HEAD(,g_consumer)	consumers;
15592108Sphk	int			acr, acw, ace;
15692108Sphk	int			error;
15792108Sphk	struct g_event		*event;
15892108Sphk	TAILQ_ENTRY(g_provider)	orphan;
15992108Sphk	int			index;
16092108Sphk};
16192108Sphk
16292108Sphk/* geom_dump.c */
16392108Sphkvoid g_hexdump(void *ptr, int length);
16492108Sphkvoid g_trace(int level, char *, ...);
16592108Sphk#	define G_T_TOPOLOGY	1
16692108Sphk#	define G_T_BIO		2
16792108Sphk#	define G_T_ACCESS	4
16892108Sphk
16993090Sphk/* geom_enc.c */
17093090Sphkuint32_t g_dec_be2(u_char *p);
17193090Sphkuint32_t g_dec_be4(u_char *p);
17293090Sphkuint32_t g_dec_le2(u_char *p);
17393090Sphkuint32_t g_dec_le4(u_char *p);
17493090Sphkvoid g_enc_le4(u_char *p, uint32_t u);
17593090Sphk
17692108Sphk/* geom_event.c */
17792108Sphkvoid g_orphan_provider(struct g_provider *pp, int error);
17892108Sphkvoid g_rattle(void);
17992108Sphkvoid g_silence(void);
18092108Sphk
18192108Sphk/* geom_subr.c */
18292108Sphkint g_access_abs(struct g_consumer *cp, int read, int write, int exclusive);
18392108Sphkint g_access_rel(struct g_consumer *cp, int read, int write, int exclusive);
18493248Sphkvoid g_add_class(struct g_class *mp);
18592108Sphkint g_attach(struct g_consumer *cp, struct g_provider *pp);
18693248Sphkstruct g_geom *g_create_geomf(char *class, struct g_provider *, char *fmt, ...);
18792108Sphkvoid g_destroy_consumer(struct g_consumer *cp);
18892108Sphkvoid g_destroy_geom(struct g_geom *pp);
18992108Sphkvoid g_destroy_provider(struct g_provider *pp);
19092108Sphkvoid g_dettach(struct g_consumer *cp);
19192108Sphkvoid g_error_provider(struct g_provider *pp, int error);
19292108Sphkint g_haveattr(struct bio *bp, char *attribute, void *val, int len);
19392108Sphkint g_haveattr_int(struct bio *bp, char *attribute, int val);
19492108Sphkint g_haveattr_off_t(struct bio *bp, char *attribute, off_t val);
19593248Sphkstruct g_geom * g_insert_geom(char *class, struct g_consumer *cp);
19692108Sphkstruct g_consumer * g_new_consumer(struct g_geom *gp);
19793248Sphkstruct g_geom * g_new_geomf(struct g_class *mp, char *fmt, ...);
19892108Sphkstruct g_provider * g_new_providerf(struct g_geom *gp, char *fmt, ...);
19992108Sphkvoid g_spoil(struct g_provider *pp, struct g_consumer *cp);
20092108Sphkint g_std_access(struct g_provider *pp, int dr, int dw, int de);
20192108Sphkvoid g_std_done(struct bio *bp);
20292108Sphkvoid g_std_spoiled(struct g_consumer *cp);
20392108Sphk
20492108Sphk/* geom_io.c */
20592108Sphkstruct bio * g_clone_bio(struct bio *);
20692108Sphkvoid g_destroy_bio(struct bio *);
20792108Sphkvoid g_io_deliver(struct bio *bp);
20893250Sphkint g_io_getattr(char *attr, struct g_consumer *cp, int *len, void *ptr);
20992108Sphkvoid g_io_request(struct bio *bp, struct g_consumer *cp);
21093250Sphkint g_io_setattr(char *attr, struct g_consumer *cp, int len, void *ptr);
21192108Sphkstruct bio *g_new_bio(void);
21292108Sphkvoid * g_read_data(struct g_consumer *cp, off_t offset, off_t length, int *error);
21392108Sphk
21492108Sphk/* geom_kern.c / geom_kernsim.c */
21592108Sphk
21692403Sphkstruct g_ioctl {
21792403Sphk	u_long		cmd;
21892403Sphk	void		*data;
21992403Sphk	int		fflag;
22092403Sphk	struct thread	*td;
22192403Sphk};
22292108Sphk
22392108Sphk#ifdef _KERNEL
22492108Sphk
22592108SphkMALLOC_DECLARE(M_GEOM);
22692108Sphk
22792108Sphkstatic __inline void *
22892108Sphkg_malloc(int size, int flags)
22992108Sphk{
23092108Sphk	void *p;
23192108Sphk
23292108Sphk	mtx_lock(&Giant);
23392108Sphk	p = malloc(size, M_GEOM, flags);
23492108Sphk	mtx_unlock(&Giant);
23592108Sphk	return (p);
23692108Sphk}
23792108Sphk
23892108Sphkstatic __inline void
23992108Sphkg_free(void *ptr)
24092108Sphk{
24192108Sphk	mtx_lock(&Giant);
24292108Sphk	free(ptr, M_GEOM);
24392108Sphk	mtx_unlock(&Giant);
24492108Sphk}
24592108Sphk
24692108Sphkextern struct sx topology_lock;
24792403Sphk#define g_topology_lock() do { mtx_assert(&Giant, MA_NOTOWNED); sx_xlock(&topology_lock); } while (0)
24892108Sphk#define g_topology_unlock() sx_xunlock(&topology_lock)
24992108Sphk#define g_topology_assert() sx_assert(&topology_lock, SX_XLOCKED)
25092108Sphk
25193248Sphk#define DECLARE_GEOM_CLASS(class, name) 	\
25292108Sphk	static void				\
25392108Sphk	name##init(void)			\
25492108Sphk	{					\
25592108Sphk		mtx_unlock(&Giant);		\
25693248Sphk		g_add_class(&class);		\
25792108Sphk		mtx_lock(&Giant);		\
25892108Sphk	}					\
25992108Sphk	SYSINIT(name, SI_SUB_PSEUDO, SI_ORDER_FIRST, name##init, NULL);
26092108Sphk
26192108Sphk#endif
26292108Sphk
263