mdvar.h revision 8452:89d32dfdae6e
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_MDVAR_H
28#define	_SYS_MDVAR_H
29
30#include <sys/types.h>
31#include <sys/kmem.h>
32#include <sys/mkdev.h>
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/t_lock.h>
36#include <sys/open.h>
37#include <sys/devops.h>
38#include <sys/modctl.h>
39#ifdef	DEBUG
40#include <sys/thread.h>
41#endif
42#include <sys/kstat.h>
43#include <sys/efi_partition.h>
44#include <sys/byteorder.h>
45#include <sys/door.h>
46
47#include <sys/lvm/mdmn_commd.h>
48#include <sys/lvm/mdio.h>
49#include <sys/lvm/md_mdiox.h>
50#include <sys/lvm/md_mddb.h>
51#include <sys/lvm/md_notify.h>
52
53#ifdef	__cplusplus
54extern "C" {
55#endif
56
57/*
58 * defaults
59 */
60#define	NMD_DEFAULT		128	/* number of metadevices */
61#define	MD_NOPS			25	/* number of misc modules */
62#define	MAXBOOTLIST		64
63
64/*
65 * Needed for backwards-compatibility with metadevices created under
66 * 2.6 or earlier.  Back then, a krwlock_t was twelve bytes.  More
67 * recently, it's four bytes.  Since these get included in structures
68 * written out to disk, we have to make sure we're using the largest
69 * size.  Things will get interesting if krwlock_t ever gets bigger
70 * than twelve bytes.
71 */
72
73typedef union _md_krwlock {
74	krwlock_t	lock;
75	struct {
76		void	*_opaque[3];
77	} xx;
78} md_krwlock_t;
79
80typedef struct {
81	kmutex_t	md_io_mx;		/* counter mutex */
82	kcondvar_t	md_io_cv;		/* ioctl wait on if draining */
83	long		io_cnt;			/* number of I/Os */
84	long		io_state;		/* !0 if waiting on zero */
85} md_set_io_t;
86
87typedef enum set_iostate {
88	MD_SET_ACTIVE = 1,
89	MD_SET_RELEASE = 2
90}set_iostate_t;
91
92/*
93 * for md_dev64_t translation
94 */
95struct md_xlate_table {
96	dev32_t		mini_devt;
97	dev32_t		targ_devt;
98};
99
100extern struct md_xlate_table	*md_tuple_table;
101
102/*
103 * for major number translation
104 */
105
106struct md_xlate_major_table {
107	char		*drv_name;
108	major_t		targ_maj;
109};
110
111extern struct md_xlate_major_table *md_major_tuple_table;
112
113extern int	md_tuple_length;
114extern uint_t	md_majortab_len;
115extern int	md_in_upgrade;
116
117extern md_mn_nodeid_t	md_mn_mynode_id;
118
119#define	MD_UPGRADE (md_in_upgrade == 1)
120
121/*
122 * Flags used during upgrade:
123 *
124 * md_keep_repl_state flag means that mddb should be kept in the format
125 *   that was found on disk (non-device id format vs. device id format).
126 *   This is used during the upgrade process when install is probing
127 *   for root disks so that the user can choose the one to be upgraded.
128 *
129 * md_devid_destroy flag is used to destroy device ids stored in the
130 *   metadevice state database (mddb).
131 *
132 *   The md_devid_destroy flag is to be used only in a catastrophic failure
133 *   case. An example of this would be if a user upgrades firmware on all
134 *   disks where this causes the disks to now have different device id's.
135 *   The user would not be able to boot a mirror'd root filesystem since the
136 *   system would recognize none of the device id's stored in the mddb.
137 *   This flag would destroy all device id information stored in the mddb and
138 *   if the md_keep_repl_state flag was not set, the mddb would be reconverted
139 *   to device id format on SLVM startup and all of the device id
140 *   information would be regenerated.
141 *
142 *   If the md_devid_destroy flag is set and the md_keep_repl_state flag is
143 *   set, the mddb's would have their device id information destroyed and
144 *   would be left in non-devid format since the device id information would
145 *   not be regenerated.
146 *
147 *   This flag is not documented anywhere and is only to be used as a last
148 *   resort as in the described case or if a device driver has a bug where
149 *   device id's are found to not be unique.  If device id's aren't unique,
150 *   the user could run without device id's until a patch is released for
151 *   that driver.
152 */
153extern int	md_keep_repl_state;
154extern int	md_devid_destroy;
155extern int	mdmn_door_did;
156#ifdef _KERNEL
157extern door_handle_t	mdmn_door_handle;
158#endif /* _KERNEL */
159
160/*
161 * An io_lock mechanism for raid, the MD_UL_XXXX bits are used for
162 * convenience.
163 */
164typedef struct md_io_lock {
165	ulong_t		io_readercnt;	/* number of unit readers */
166	ulong_t		io_wanabecnt;	/* # pending on becoming unit writer */
167	ulong_t		io_lock;
168	void		*io_list_front;
169	void		*io_list_back;
170	kmutex_t	io_mx;
171	kcondvar_t	io_cv;
172	kmutex_t	io_list_mutex;	/* list of waiting io */
173	kthread_id_t	io_owner;	/* writer thread */
174} md_io_lock_t;
175
176/*
177 * The following flags are in un_flag field of mdc_unit struct.
178 */
179#define	MD_LABELED	0x1	/* First sector of the metadevice is a label */
180#define	MD_EFILABEL	0x2	/* This md has an EFI label and no vtoc */
181
182/*
183 * This is the number of bytes a DKIOCGETEFI ioctl returns
184 * For now it's one time the header and once the size for a partition info
185 */
186#define	MD_EFI_LABEL_SIZE (sizeof (efi_gpt_t) + sizeof (efi_gpe_t))
187
188/* This is the number of bytes consumed by efi_gpe_PartitionName */
189#define	MD_EFI_PARTNAME_BYTES (EFI_PART_NAME_LEN * sizeof (ushort_t))
190
191typedef enum hs_cmds {
192	HS_GET, HS_FREE, HS_BAD, HSP_INCREF, HSP_DECREF, HS_MKDEV
193} hs_cmds_t;
194
195typedef struct md_link {
196	struct md_link	*ln_next;
197	set_t		ln_setno;
198	uint_t		ln_id;
199} md_link_t;
200
201typedef struct mdi_unit {
202	md_link_t	ui_link;
203	ulong_t		ui_readercnt;	/* number of unit readers */
204	ulong_t		ui_wanabecnt;	/* # pending on becoming unit writer */
205	ulong_t		ui_lock;
206	kmutex_t	ui_mx;
207	kcondvar_t	ui_cv;
208	int		ui_opsindex;
209	uint_t		ui_ocnt[OTYPCNT]; /* open counts */
210	md_io_lock_t	*ui_io_lock;	/* pointer to io lock */
211	kstat_t		*ui_kstat;	/* kernel statistics */
212	kthread_id_t	ui_owner;	/* writer thread */
213	uint_t		ui_tstate;	/* transient state bits */
214	uint_t		ui_capab;	/* Capability bits supported */
215} mdi_unit_t;
216
217/*
218 * Following are used with ui_lock
219 * which is in the unit incore structure.
220 */
221#define	MD_UL_WRITER		0x0001 /* Stall all new strategy calls */
222#define	MD_UL_WANABEWRITER	0x0002
223#define	MD_UL_OPENORCLOSE	0x0004
224
225#define	MD_UL_OPEN		0x0008	/* unit is open */
226#define	MD_UL_EXCL		0x0010	/* unit is open exclusively */
227
228/*
229 * The softpart open code may do an I/O to validate the watermarks
230 * and should hold no open locks during this I/O.  So, mark the unit
231 * as OPENINPROGRESS and drop the locks.  This will keep any other
232 * softpart open's waiting until the validate has completed.
233 */
234#define	MD_UL_OPENINPROGRESS	0x0020	/* Open in Progress */
235
236/*
237 * Following are used with ui_tstate to specify any transient states which
238 * occur during metadevice operation. These are not written to the metadb as
239 * they do not represent a failure of the underlying metadevice.
240 * Transient errors are stored in the lower 16 bits and other transient
241 * state is stored in the upper 16 bits.
242 * MD_NOTOPENABLE should contain all the states that are set prior to an
243 * open (by snarf) and that indicate that a metadevice cannot be opened.
244 */
245#define	MD_DEV_ERRORED		0x0000ffff /* ui_tstate error bits */
246#define	MD_EOF_METADEVICE	0x00000001 /* EOF'd metadevice */
247#define	MD_64MD_ON_32KERNEL	0x00000002 /* 64bit metadev on 32bit kernel */
248#define	MD_INACCESSIBLE		0x00000004 /* metadevice unavailable */
249#define	MD_RETRYING		0x00010000 /* retrying errored failfast I/O */
250#define	MD_OPENLOCKED		0x00020000 /* MN: open locked before removing */
251#define	MD_ERR_PENDING		0x00040000 /* MN: error pending */
252#define	MD_ABR_CAP		0x00080000 /* MN: Application Based Recovery */
253#define	MD_DMR_CAP		0x00100000 /* MN: Directed Mirror Read */
254#define	MD_RELEASE_IOERR_DONE	0x00200000 /* ioerr console message done */
255#define	MD_RESYNC_NOT_DONE	0x00400000 /* resync not done yet */
256
257/* A metadevice cannot be opened when these states are set */
258#define	MD_NOTOPENABLE		(MD_EOF_METADEVICE|MD_64MD_ON_32KERNEL)
259
260typedef struct md_ioctl_lock {
261	int		l_flags;	/* locks held */
262	mdi_unit_t	*l_ui;		/* unit for which lock is held */
263} md_ioctl_lock_t;
264
265#define	MD_MASTER_DROPPED	0x0001
266#define	MD_READER_HELD		0x0002
267#define	MD_WRITER_HELD		0x0004
268#define	MD_IO_HELD		0x0008
269#define	MD_ARRAY_READER		0x0010
270#define	MD_ARRAY_WRITER		0x0020
271#define	STALE_OK		0x0100
272#define	NO_OLD			0x0200
273#define	NO_LOCK			0x0400
274#define	MD_MT_IOCTL		0x80000 /* MD_GBL_IOCTL_LOCK not set */
275#define	IOLOCK	md_ioctl_lock_t
276
277#define	WR_LOCK			MD_WRITER_HELD
278#define	RD_LOCK			MD_READER_HELD | STALE_OK
279#define	ARRAY_WRITER		MD_ARRAY_WRITER
280#define	ARRAY_READER		MD_ARRAY_READER
281#define	WRITERS			MD_WRITER_HELD | MD_IO_HELD | MD_ARRAY_WRITER
282#define	READERS			RD_LOCK | MD_ARRAY_READER
283
284#define	IOLOCK_RETURN_IOCTLEND(code, lock) \
285	md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, TRUE)
286
287#define	IOLOCK_RETURN(code, lock) \
288	md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, FALSE)
289
290#define	IOLOCK_RETURN_RELEASE(code, lock) \
291	md_ioctl_releaselocks((code), (lock)->l_flags, (lock)->l_ui)
292
293#define	IOLOCK_RETURN_REACQUIRE(lock) \
294	md_ioctl_reacquirelocks((lock)->l_flags, (lock)->l_ui)
295
296#define	IOLOCK_INIT(lock)	bzero((caddr_t)(lock), sizeof (*(lock)))
297/*
298 * checks to be sure locks are held
299 */
300#define	UNIT_WRITER_HELD(un) \
301	(MDI_UNIT(MD_SID(un))->ui_lock & MD_UL_WRITER)
302#define	UNIT_READER_HELD(un) \
303	(MDI_UNIT(MD_SID(un))->ui_readercnt != 0)
304#define	IO_WRITER_HELD(un) \
305	(MDI_UNIT(MD_SID(un))->ui_io_lock->io_lock & MD_UL_WRITER)
306#define	IO_READER_HELD(un) \
307	(MDI_UNIT(MD_SID(un))->ui_io_lock->io_readercnt != 0)
308
309#ifdef  DEBUG
310#define	STAT_INC(statvar)		\
311	statvar++
312#define	STAT_DEC(statvar)		\
313	statvar--
314#define	STAT_ZERO(statvar)		\
315	statvar = 0;
316#define	STAT_MAX(statmax, statvar)	\
317	{				\
318	statvar++;			\
319	if (statvar > statmax)		\
320		statmax = statvar;	\
321	}
322#define	STAT_CHECK(statvar, value)	\
323	{				\
324	if (value)			\
325		statvar++;		\
326	}
327#else
328#define	STAT_INC(statvar)
329#define	STAT_DEC(statvar)
330#define	STAT_ZERO(statvar)
331#define	STAT_MAX(statmax, statvar)
332#define	STAT_CHECK(statvar, value)
333#endif
334/*
335 * bit map related macros
336 */
337#define	setbit(a, i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
338#define	clrbit(a, i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
339#define	isset(a, i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
340#define	isclr(a, i)	(((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
341
342typedef struct daemon_queue {
343	int	maxq_len;
344	int	qlen;
345	int	treqs;		/* total number of requests */
346	struct daemon_queue	*dq_next;
347	struct daemon_queue	*dq_prev;
348	void			(*dq_call)();
349} daemon_queue_t;
350
351#define	DAEMON_QUEUE daemon_queue_t	dq;
352
353#ifdef _KERNEL
354#include	<sys/buf.h>
355#include	<sys/dkio.h>
356#include	<sys/vtoc.h>
357
358#define	MD_DEV2SET(d)	(MD_MIN2SET(md_getminor(d)))
359
360#define	MD_UNIT(m)	(md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)])
361#define	MDI_UNIT(m)	((mdi_unit_t *) \
362			    md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)])
363#define	MD_VOIDUNIT(m)	(md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)])
364#define	MDI_VOIDUNIT(m)	(md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)])
365
366/*
367 * This is the current maximum number of real disks per Virtual Disk.
368 */
369extern	uint_t	md_mdelay;	/* md_mirror timeout delay */
370
371#define	MD_ADM_MINOR		L_MAXMIN32 /* the minor number for md_admin */
372#define	MD_MDELAY		(md_mdelay)
373#define	NUM_USEC_IN_SEC		1000000 /* 1 million usec in a second */
374
375#define	ANY_SERVICE		-1	/* md_get_named_service() wild card */
376
377/*
378 * daemon threads are used in multiple places in md. The following set of
379 * structures and routines allow a common way to create and initialize them.
380 *
381 * md_requestq_entry_t - entry of creating request queues.
382 * struct mdq_anchor - request queue header
383 *
384 * Functions associated with request queues:
385 *
386 * int init_requestq_entry -
387 * void daemon_request - put a request on the queue.
388 */
389
390typedef struct md_requestq_entry {
391	struct mdq_anchor	*dispq_headp;
392	int		*num_threadsp; /* threads servicing the queue */
393} md_requestq_entry_t;
394
395#define	NULL_REQUESTQ_ENTRY(rqp)\
396		((rqp)->dispq_headp == NULL || (rqp)->num_threadsp == NULL)
397
398/* this typedef is used to differentiate between the two call styles */
399typedef enum callstyle {
400	REQ_OLD,
401	REQ_NEW
402} callstyle_t;
403
404
405#define	daemon_request_new daemon_request
406
407typedef struct mdq_anchor {
408	DAEMON_QUEUE
409	kcondvar_t	 a_cv;		/* Request has been put on queue */
410	kmutex_t	 a_mx;
411} mdq_anchor_t;
412
413typedef struct daemon_request {
414	DAEMON_QUEUE
415	kmutex_t	dr_mx;
416	int		dr_pending;
417	timeout_id_t	dr_timeout_id;
418} daemon_request_t;
419
420typedef struct sv_dev {
421	set_t	setno;
422	side_t	side;
423	mdkey_t	key;
424} sv_dev_t;
425
426/*
427 * Types of device probes
428 */
429
430
431typedef struct probe_req {
432	DAEMON_QUEUE
433	minor_t mnum;			/* mnum of the metadevice to probe */
434	void   *private_handle;		/* private handle */
435	intptr_t (*probe_fcn)();	/* type of probeing to be done */
436} probe_req_t;
437
438/* Global flags */
439#define	MD_NO_GBL_LOCKS_HELD	0x0000	/* currently holding no global locks */
440#define	MD_GBL_DAEMONS_LIVE	0x0001	/* master daemon has been started. */
441#define	MD_GBL_DAEMONS_DIE	0x0002
442#define	MD_GBL_HALTED		0x0004	/* driver is shut down */
443
444/* Available bit was GBL_STALE	0x0008	*/
445
446#define	MD_GBL_IOCTL_LOCK	0x0010	/* single-threads ioctls */
447#define	MD_GBL_HS_LOCK		0x0020	/* single-threads hotspares */
448#define	MD_GBL_OPEN		0x0040	/* admin is open */
449#define	MD_GBL_EXCL		0x0080	/* admin is open exclusively */
450
451#define	MD_OFLG_NULL		0x0000	/* Null flag */
452#define	MD_OFLG_CONT_ERRS	0x0001	/* Continue on open errors */
453#define	MD_OFLG_PROBEDEV	0x0002  /* force a simulated open */
454#define	MD_OFLG_ISINIT		0x0004  /* raid initialization */
455#define	MD_OFLG_FROMIOCTL	0x0008  /* Called from an ioctl handler */
456
457
458typedef struct md_named_services {
459
460	intptr_t	(*md_service)();
461	char		*md_name;
462} md_named_services_t;
463
464typedef enum md_snarfcmd {MD_SNARF_CLEANUP, MD_SNARF_DOIT} md_snarfcmd_t;
465
466typedef struct md_ops {
467	int	(*md_open)(
468		    dev_t		*devp,
469		    int			flag,
470		    int			otyp,
471		    cred_t		*credp,
472		    int			md_oflags);
473	int	(*md_close)(
474		    dev_t		dev,
475		    int			flag,
476		    int			otyp,
477		    cred_t		*credp,
478		    int			md_oflags);
479	void	(*md_strategy)(
480		    buf_t		*bufp,
481		    int			flag,
482		    void		*private);
483	int	(*md_print)();		/* unused now */
484	int	(*md_dump)(
485		    dev_t		dev,
486		    caddr_t		addr,
487		    daddr_t		blkno,
488		    int			nblk);
489	int	(*md_read)(
490		    dev_t		dev,
491		    struct uio		*uiop,
492		    cred_t		*credp);
493	int	(*md_write)(
494		    dev_t		dev,
495		    struct uio		*uiop,
496		    cred_t		*credp);
497	int	(*md_ioctl)(
498		    dev_t		dev,
499		    int			cmd,
500		    void		*data,
501		    int			mode,
502		    IOLOCK		*lockp);
503	int	(*md_snarf)(
504		    md_snarfcmd_t	cmd,
505		    set_t		setno);
506	int	(*md_halt)();
507	int	(*md_aread)(
508		    dev_t		dev,
509		    struct aio_req	*aiop,
510		    cred_t		*credp);
511	int	(*md_awrite)(
512		    dev_t		dev,
513		    struct aio_req	*aiop,
514		    cred_t		*credp);
515	int	(*md_imp_set)(
516		    set_t		setno);
517	md_named_services_t	*md_services;
518	md_krwlock_t		md_link_rw;
519	md_link_t		*md_head;
520	/*
521	 * NOTE: when TSlvm s10/onnv compatibility is not an issue:
522	 *	o md_modid and md_locked should be deleted.
523	 *	o md_mod should be added
524	 *		ddi_modhandle_t		md_mod;
525	 *	  and used instead of the md_mods array (md_mods should
526	 *	  be deleted).
527	 */
528	int			md_modid;
529	int			md_locked;
530	int			md_selfindex;
531	struct md_ops		*md_next;
532	md_driver_t		md_driver;
533	/* NOTE: TSlvm depends on offsets in and sizeof this structure */
534} md_ops_t;
535
536/* macro to generate linkage for a md misc plugin module */
537#define	md_noop
538#define	MD_PLUGIN_MISC_MODULE(desc, init_init, fini_uninit)		\
539	static struct modlmisc		modlmisc = {			\
540		&mod_miscops, "Solaris Volume Manager " desc		\
541	};								\
542	static struct modlinkage	modlinkage = {			\
543		MODREV_1, (void *)&modlmisc, NULL			\
544	};								\
545	int								\
546	_init(void)							\
547	{								\
548		int	i;						\
549		init_init;						\
550		if ((i = mod_install(&modlinkage)) != 0) {		\
551			fini_uninit;					\
552		}							\
553		return (i);						\
554	}								\
555	int								\
556	_fini()								\
557	{								\
558		int	i;                                              \
559		if ((i = mod_remove(&modlinkage)) == 0) {		\
560			fini_uninit;					\
561		}							\
562		return (i);						\
563	}								\
564	int								\
565	_info(struct modinfo *modinfop)					\
566	{								\
567		return (mod_info(&modlinkage, modinfop));		\
568	}
569
570typedef enum md_haltcmd {MD_HALT_ALL, MD_HALT_CHECK, MD_HALT_DOIT,
571			MD_HALT_CLOSE, MD_HALT_OPEN, MD_HALT_UNLOAD
572} md_haltcmd_t;
573
574/*
575 * To support cpr (Energy Star) we need to know when the resync threads are
576 * running to not allow suspention.
577 */
578typedef struct md_resync_thds_cnt {
579	int md_raid_resync;	/* count of active raid resync threads */
580	int md_mirror_resync;	/* count of active mirror resync threads */
581	kmutex_t md_resync_mutex;	/* protects both resync counts */
582} md_resync_t;
583
584/*
585 * flags used with call to individual strategy routines
586 */
587#define	MD_STR_PASSEDON 0x0000ffff
588#define	MD_STR_NOTTOP	0x00000001
589#define	MD_STR_MAPPED	0x00000002	/* set when buf_t is mapped in	*/
590#define	MD_STR_ABR	0x00000004	/* use ABR to handle any recovery */
591#define	MD_STR_WMUPDATE	0x00000008	/* set if updating watermarks for sp */
592#define	MD_IO_COUNTED	0x00000400	/* io has been counted */
593#define	MD_NOBLOCK	0x00000800	/* do not block io durring release */
594
595#define	MD_STR_WAR	0x00010000	/* this write is write after read */
596#define	MD_STR_WOW	0x00020000	/* handling a write-on-write */
597#define	MD_STR_DMR	0x00040000	/* Directed Read request */
598#define	MD_STR_DIRTY_RD	0x00080000	/* Read of a dirty block */
599#define	MD_STR_FLAG_ERR	0x00100000	/* Flag any write error on this i/o */
600#define	MD_STR_BLOCK_OK	0x00200000	/* Flag if caller i/o can be blocked */
601
602/*
603 * Bits for return value of md_getdevnum
604 */
605#define	MD_TRUST_DEVT	1
606#define	MD_NOTRUST_DEVT	0
607
608/* Flag for drivers to pass to kmem_cache_alloc() */
609#define	MD_ALLOCFLAGS   (KM_PUSHPAGE | KM_SLEEP)
610
611/* Named services */
612#define	MD_CHECK_OFFLINE	"check_offline"
613#define	MD_INC_ABR_COUNT	"inc abr count"
614#define	MD_DEC_ABR_COUNT	"dec abr count"
615
616/* md_getdevname_common flags for namespace lock */
617#define	MD_WAIT_LOCK	0
618#define	MD_NOWAIT_LOCK	1
619
620/* Externals from md.c */
621extern int	md_snarf_db_set(set_t setno, md_error_t *ep);
622extern void	get_info(struct dk_cinfo *, minor_t);
623extern void	get_minfo(struct dk_minfo *, minor_t);
624extern int	mdstrategy(buf_t *);
625extern int	md_create_minor_node(set_t, minor_t);
626extern void	md_nblocks_set(minor_t mnum, uint64_t nblocks);
627
628/* External from md_subr.c */
629extern int	md_inc_iocount(set_t);
630extern void	md_inc_iocount_noblock(set_t);
631extern void	md_dec_iocount(set_t);
632extern int	md_isblock_setio(set_t);
633extern int	md_block_setio(set_t);
634extern void	md_clearblock_setio(set_t);
635extern void	md_unblock_setio(set_t);
636extern int	md_tas_block_setio(set_t);
637extern void	md_biodone(struct buf *);
638extern void	md_bioreset(struct buf *);
639extern md_dev64_t md_xlate_targ_2_mini(md_dev64_t);
640extern md_dev64_t md_xlate_mini_2_targ(md_dev64_t);
641extern void	md_xlate_free(int);
642extern major_t	md_targ_name_to_major(char *);
643extern char	*md_targ_major_to_name(major_t);
644extern void	md_majortab_free();
645extern void	md_set_status(int);
646extern void	md_clr_status(int);
647extern int	md_get_status(void);
648extern void	md_set_setstatus(set_t, int);
649extern void	md_clr_setstatus(set_t, int);
650extern uint_t	md_get_setstatus(set_t);
651extern void	*md_unit_readerlock(mdi_unit_t *);
652extern void	*md_unit_writerlock(mdi_unit_t *);
653extern void	md_unit_readerexit(mdi_unit_t *);
654extern void	md_unit_writerexit(mdi_unit_t *);
655extern void	md_ioctl_releaselocks(int, int, mdi_unit_t *);
656extern void	md_ioctl_reacquirelocks(int, mdi_unit_t *);
657extern int	md_ioctl_lock_exit(int, int, mdi_unit_t *, int);
658extern int	md_ioctl_lock_enter(void);
659extern void	*md_ioctl_readerlock(IOLOCK *, mdi_unit_t *);
660extern void	md_ioctl_readerexit(IOLOCK *);
661extern void	*md_ioctl_writerlock(IOLOCK *, mdi_unit_t *);
662extern void	md_ioctl_writerexit(IOLOCK *);
663extern void	md_ioctl_io_exit(IOLOCK *);
664extern void	*md_ioctl_io_lock(IOLOCK *, mdi_unit_t *);
665extern void	md_ioctl_droplocks(IOLOCK *);
666extern void	md_array_writer(IOLOCK *);
667extern void	md_array_reader(IOLOCK *);
668extern void	*md_ioctl_openclose_enter(IOLOCK *, mdi_unit_t *);
669extern void	md_ioctl_openclose_exit(IOLOCK *);
670extern void	md_ioctl_openclose_exit_lh(IOLOCK *);
671extern void	*md_unit_openclose_enter(mdi_unit_t *);
672extern void	md_unit_openclose_exit(mdi_unit_t *);
673extern void	md_unit_openclose_exit_lh(mdi_unit_t *);
674extern int	md_unit_isopen(mdi_unit_t *ui);
675extern int	md_unit_incopen(minor_t mnum, int flag, int otyp);
676extern int	md_unit_decopen(minor_t mnum, int otyp);
677extern void	*md_io_readerlock(mdi_unit_t *);
678extern void	*md_io_writerlock(mdi_unit_t *);
679extern void	md_io_readerexit(mdi_unit_t *);
680extern void	md_io_writerexit(mdi_unit_t *);
681extern intptr_t	(*md_get_named_service())();
682extern int	init_requestq(md_requestq_entry_t *, void (*)(),
683						caddr_t, int, int);
684extern void	daemon_request(mdq_anchor_t *, void(*)(),
685				daemon_queue_t *, callstyle_t);
686extern void	md_daemon(int, mdq_anchor_t *);
687extern void	mddb_commitrec_wrapper(mddb_recid_t);
688extern void	mddb_commitrecs_wrapper(mddb_recid_t *);
689extern void	mddb_deleterec_wrapper(mddb_recid_t);
690extern void	md_holdset_enter(set_t setno);
691extern void	md_holdset_exit(set_t setno);
692extern int	md_holdset_testandenter(set_t setno);
693extern void	md_haltsnarf_enter(set_t setno);
694extern void	md_haltsnarf_exit(set_t setno);
695extern void	md_haltsnarf_wait(set_t setno);
696extern int	md_halt_set(set_t setno, enum md_haltcmd cmd);
697extern int	md_halt(int global_lock_flag);
698extern int	md_layered_open(minor_t, md_dev64_t *, int);
699extern void	md_layered_close(md_dev64_t, int);
700extern char	*md_get_device_name(md_dev64_t);
701extern int	errdone(mdi_unit_t *, struct buf *, int);
702extern int	md_checkbuf(mdi_unit_t *, md_unit_t *, buf_t *);
703extern int	md_start_daemons(int init_queues);
704extern int	md_loadsubmod(set_t, char *, int);
705extern int	md_getmodindex(md_driver_t *, int, int);
706extern void	md_call_strategy(buf_t *, int, void *);
707extern int	md_call_ioctl(md_dev64_t, int, void *, int, IOLOCK *);
708extern void	md_rem_link(set_t, int, krwlock_t *, md_link_t **);
709extern int	md_dev_exists(md_dev64_t);
710extern md_parent_t md_get_parent(md_dev64_t);
711extern void	md_set_parent(md_dev64_t, md_parent_t);
712extern void	md_reset_parent(md_dev64_t);
713extern struct hot_spare_pool *find_hot_spare_pool(set_t, int);
714extern int	md_hot_spare_ifc(hs_cmds_t, mddb_recid_t, u_longlong_t, int,
715		    mddb_recid_t *, mdkey_t *, md_dev64_t *, diskaddr_t *);
716extern int	md_notify_interface(md_event_cmds_t cmd, md_tags_t type,
717		set_t set, md_dev64_t dev, md_event_type_t event);
718extern void	svm_gen_sysevent(char *se_class, char *se_subclass,
719		    uint32_t tag, set_t setno, md_dev64_t devid);
720extern void	md_create_unit_incore(minor_t, md_ops_t *, int);
721extern void	md_destroy_unit_incore(minor_t, md_ops_t *);
722extern void	md_rem_names(sv_dev_t *, int);
723struct uio;
724extern int	md_chk_uio(struct uio *);
725extern char	*md_shortname(minor_t mnum);
726extern char	*md_devname(set_t setno, md_dev64_t dev, char *buf,
727		size_t size);
728extern void	md_minphys(buf_t *);
729extern void	md_kstat_init(minor_t mnum);
730extern void	md_kstat_init_ui(minor_t mnum, mdi_unit_t *ui);
731extern void	md_kstat_destroy(minor_t mnum);
732extern void	md_kstat_destroy_ui(mdi_unit_t *ui);
733extern void	md_kstat_waitq_enter(mdi_unit_t *ui);
734extern void	md_kstat_waitq_to_runq(mdi_unit_t *ui);
735extern void	md_kstat_waitq_exit(mdi_unit_t *ui);
736extern void	md_kstat_runq_enter(mdi_unit_t *ui);
737extern void	md_kstat_runq_exit(mdi_unit_t *ui);
738extern void	md_kstat_done(mdi_unit_t *ui, buf_t *bp, int war);
739extern pid_t	md_getpid(void);
740extern proc_t	*md_getproc(void);
741extern int	md_checkpid(pid_t pid, proc_t *proc);
742extern char	*md_strdup(char *cp);
743extern void	freestr(char *cp);
744extern int	md_check_ioctl_against_unit(int, mdc_unit_t);
745extern mddb_recid_t md_vtoc_to_efi_record(mddb_recid_t, set_t);
746
747extern int	mdmn_ksend_message(set_t, md_mn_msgtype_t, uint_t,
748		    md_mn_nodeid_t, char *, int, md_mn_kresult_t *);
749extern void	mdmn_ksend_show_error(int, md_mn_kresult_t *, const char *);
750extern int	mdmn_send_capability_message(minor_t, volcap_t, IOLOCK *);
751extern void	mdmn_clear_all_capabilities(minor_t);
752extern int	md_init_probereq(struct md_probedev_impl *p,
753		    daemon_queue_t **hdrpp);
754extern boolean_t callb_md_mrs_cpr(void *, int);
755extern void	md_upd_set_unnext(set_t, unit_t);
756extern int	md_rem_selfname(minor_t);
757extern void	md_rem_hspname(set_t, mdkey_t);
758extern void	*md_create_taskq(set_t, minor_t);
759
760/* Externals from md_ioctl.c */
761extern int	md_mn_is_commd_present(void);
762extern int	md_mn_is_commd_present_lite(void);
763extern void	md_mn_clear_commd_present(void);
764extern int	md_admin_ioctl(md_dev64_t, int, caddr_t, int, IOLOCK *lockp);
765extern void	md_get_geom(md_unit_t *, struct dk_geom *);
766extern int	md_set_vtoc(md_unit_t *, struct vtoc *);
767extern void	md_get_vtoc(md_unit_t *, struct vtoc *);
768extern int	md_set_extvtoc(md_unit_t *, struct extvtoc *);
769extern void	md_get_extvtoc(md_unit_t *, struct extvtoc *);
770extern void	md_get_cgapart(md_unit_t *, struct dk_map *);
771extern void	md_get_efi(md_unit_t *, char *);
772extern int	md_set_efi(md_unit_t *, char *);
773extern int	md_dkiocgetefi(minor_t, void *, int);
774extern int	md_dkiocsetefi(minor_t, void *, int);
775extern int	md_dkiocpartition(minor_t, void *, int);
776extern void	md_remove_minor_node(minor_t);
777
778
779/* Externals from md_names.c */
780extern mdkey_t	md_setdevname(set_t, side_t, mdkey_t, char *, minor_t, char *,
781		    int imp_flag, ddi_devid_t devid, char *minorname,
782			set_t, md_error_t *);
783extern int	md_getdevname(set_t, side_t, mdkey_t, md_dev64_t, char *,
784		    size_t);
785extern int	md_getdevname_common(set_t, side_t, mdkey_t, md_dev64_t, char *,
786		    size_t, int);
787extern int	md_gethspinfo(set_t, side_t, mdkey_t, char *, hsp_t *,
788		    char *);
789extern int	md_getkeyfromdev(set_t, side_t, md_dev64_t, mdkey_t *, int *);
790extern int	md_devid_found(set_t, side_t, mdkey_t);
791extern int	md_getnment(set_t, side_t, mdkey_t, md_dev64_t,
792		    char *, uint_t, major_t *, minor_t *, mdkey_t *);
793extern md_dev64_t md_getdevnum(set_t, side_t, mdkey_t, int);
794extern mdkey_t	md_getnextkey(set_t, side_t, mdkey_t, uint_t *);
795extern int	md_remdevname(set_t, side_t, mdkey_t);
796extern mdkey_t	md_setshared_name(set_t, char *, int);
797extern char	*md_getshared_name(set_t, mdkey_t);
798extern int	md_remshared_name(set_t, mdkey_t);
799extern mdkey_t	md_getshared_key(set_t, char *);
800extern int	md_setshared_data(set_t, uint_t, caddr_t);
801extern caddr_t	md_getshared_data(set_t, uint_t);
802extern int	md_load_namespace(set_t, md_error_t *ep, int);
803extern void	md_unload_namespace(set_t, int);
804extern int	md_nm_did_chkspace(set_t);
805extern void	md_bioinit();
806extern buf_t	*md_bioclone(buf_t *, off_t, size_t, dev_t, diskaddr_t,
807		    int (*)(buf_t *), buf_t *, int);
808extern int	md_getdevid(set_t setno, side_t side, mdkey_t key,
809		    ddi_devid_t devid, ushort_t *did_size);
810extern int	md_getdevidminor(set_t setno, side_t side, mdkey_t key,
811		    char *minorname, size_t minorname_len);
812extern int	md_update_namespace(set_t setno, side_t side, mdkey_t key,
813		    caddr_t devname, caddr_t pathname, minor_t mnum);
814extern int	md_update_locator_namespace(set_t setno, side_t side,
815		    caddr_t devname, caddr_t pathname, md_dev64_t devt);
816extern int	md_update_namespace_did(set_t setno, side_t side, mdkey_t key,
817		    md_error_t *ep);
818extern int	md_validate_devid(set_t setno, side_t side, int *maxsz);
819extern int	md_get_invdid(set_t setno, side_t side, int cnt, int maxsz,
820		    void *didptr);
821extern md_dev64_t md_resolve_bydevid(minor_t, md_dev64_t, mdkey_t key);
822extern md_dev64_t md_expldev(md_dev64_t);
823extern dev32_t	md_cmpldev(md_dev64_t);
824extern dev_t	md_dev64_to_dev(md_dev64_t);
825extern md_dev64_t md_makedevice(major_t, minor_t);
826extern major_t	md_getmajor(md_dev64_t);
827extern minor_t	md_getminor(md_dev64_t);
828extern void	md_timeval(md_timeval32_t *);
829extern int	md_imp_snarf_set(mddb_config_t *);
830
831/* externals from md_mddb.c */
832extern int	mddb_reread_rr(set_t, mddb_recid_t);
833extern int	mddb_setowner(mddb_recid_t id, md_mn_nodeid_t owner);
834extern int	mddb_parse(mddb_parse_parm_t *mpp);
835extern int	mddb_block(mddb_block_parm_t *mpp);
836extern int	mddb_optrecfix(mddb_optrec_parm_t *mop);
837extern int	mddb_check_write_ioctl(mddb_config_t *info);
838extern int	mddb_setflags_ioctl(mddb_setflags_config_t *info);
839extern struct nm_next_hdr	*get_first_record(set_t, int, int);
840extern void	*lookup_entry(struct nm_next_hdr *, set_t,
841			side_t, mdkey_t, md_dev64_t, int);
842extern void	*lookup_shared_entry(struct nm_next_hdr *,
843		    mdkey_t key, char *, mddb_recid_t *, int);
844extern int	remove_shared_entry(struct nm_next_hdr *, mdkey_t key,
845		    char *, int);
846extern void	*alloc_entry(struct nm_next_hdr *, mddb_recid_t, size_t, int,
847		    mddb_recid_t *);
848extern void	*getshared_name(set_t, mdkey_t, int);
849
850#endif	/* _KERNEL */
851
852
853/* externals from md_revchk.c */
854extern int	revchk(uint_t my_rev, uint_t data);
855
856
857#ifdef	__cplusplus
858}
859#endif
860
861#endif	/* _SYS_MDVAR_H */
862