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