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