/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_MD_TRANS_H #define _SYS_MD_TRANS_H #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define LDL_META_SBLK (16) #define LDL_MINLOGSIZE (1024*1024) #define LDL_MAXLOGSIZE (1024*1024*1024) #define LDL_MINBUFSIZE (32*1024) #define LDL_USABLE_BSIZE (DEV_BSIZE - sizeof (sect_trailer_t)) #define NB_LEFT_IN_SECTOR(off) (LDL_USABLE_BSIZE - ((off) - dbtob(btodb(off)))) typedef struct cirbuf32 { caddr32_t xx_cb_bp; /* buf's with space in circular buf */ caddr32_t xx_cb_dirty; /* filling this buffer for log write */ caddr32_t xx_cb_free; /* free bufs list */ caddr32_t xx_cb_va; /* address of circular buffer */ uint_t xx_cb_nb; /* size of circular buffer */ uint_t xx_cb_rwlock[3]; /* r/w lock to protect list mgmt. */ } cirbuf32_t; typedef struct cirbuf_ic { buf_t *cb_bp; /* buf's with space in circular buf */ buf_t *cb_dirty; /* filling this buffer for log write */ buf_t *cb_free; /* free bufs list */ caddr_t cb_va; /* address of circular buffer */ size_t cb_nb; /* size of circular buffer */ md_krwlock_t cb_rwlock; /* r/w lock to protect list mgmt. */ } cirbuf_ic_t; typedef struct ml_unit { uint_t un_revision; /* revision number */ /* * mdd infrastructure stuff */ mddb_recid_t un_recid; /* db record id */ mdkey_t un_key; /* namespace key */ md_dev64_t un_dev; /* device number */ uint_t un_opencnt; /* open count */ /* * metatrans infrastructure stuff */ uint_t un_transcnt; /* #open metatrans devices */ /* * log specific stuff */ off32_t un_head_lof; /* byte offset of head */ uint_t un_head_ident; /* head sector id # */ off32_t un_tail_lof; /* byte offset of tail */ uint_t un_tail_ident; /* tail sector id # */ off32_t un_bol_lof; /* byte offset of begin of log */ off32_t un_eol_lof; /* byte offset of end of log */ daddr32_t un_nblks; /* total blocks of log space */ daddr32_t un_tblks; /* total blocks in log device */ uint_t un_maxtransfer; /* max transfer in bytes */ uint_t un_status; /* status bits */ uint_t un_maxresv; /* maximum reservable space */ daddr32_t un_pwsblk; /* block number of prewrite area */ ulong_t un_devbsize; /* device bsize */ uint_t un_resv; /* reserved byte count for this trans */ uint_t un_resv_wantin; /* reserved byte count for next trans */ mt_l_error_t un_error; /* error state */ uint_t un_tid; /* used during logscan */ uint_t un_head_tid; /* used for logscan; set at sethead */ struct timeval32 un_timestamp; /* time of last state change */ /* * spares */ uint_t un_spare[16]; /* * following are incore only elements. * Incore elements must always be at the end * of this data struture. */ struct ml_unit *un_next; struct mt_unit *un_utlist; struct mt_map *un_logmap; cirbuf_ic_t un_rdbuf; cirbuf_ic_t un_wrbuf; kmutex_t un_log_mutex; } ml_unit_t; #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 #pragma pack(4) #endif typedef struct ml_unit32_od { uint_t un_revision; /* revision number */ /* * mdd infrastructure stuff */ caddr32_t xx_un_next; /* next log unit struct */ mddb_recid_t un_recid; /* db record id */ mdkey_t un_key; /* namespace key */ dev32_t un_dev; /* device number */ uint_t un_opencnt; /* open count */ /* * metatrans infrastructure stuff */ uint_t un_transcnt; /* #open metatrans devices */ caddr32_t xx_un_utlist; /* list of metatrans devices */ caddr32_t xx_un_logmap; /* address of logmap */ /* * log specific stuff */ off32_t un_head_lof; /* byte offset of head */ uint_t un_head_ident; /* head sector id # */ off32_t un_tail_lof; /* byte offset of tail */ uint_t un_tail_ident; /* tail sector id # */ off32_t un_bol_lof; /* byte offset of begin of log */ off32_t un_eol_lof; /* byte offset of end of log */ daddr32_t un_nblks; /* total blocks of log space */ daddr32_t un_tblks; /* total blocks in log device */ uint_t un_maxtransfer; /* max transfer in bytes */ uint_t un_status; /* status bits */ uint_t un_maxresv; /* maximum reservable space */ daddr32_t un_pwsblk; /* block number of prewrite area */ uint_t un_devbsize; /* device bsize */ uint_t un_resv; /* reserved byte count for this trans */ uint_t un_resv_wantin; /* reserved byte count for next trans */ mt_l_error_t un_error; /* error state */ uint_t un_tid; /* used during logscan */ uint_t un_head_tid; /* used for logscan; set at sethead */ cirbuf32_t xx_un_rdbuf; /* read buffer space */ cirbuf32_t xx_un_wrbuf; /* write buffer space */ int xx_un_log_mutex[2]; /* allows one log write at a time */ struct timeval32 un_timestamp; /* time of last state change */ /* * spares */ uint_t un_spare[16]; } ml_unit32_od_t; #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 #pragma pack() #endif #define ML_UNIT_ONDSZ ((size_t)((caddr_t)&((ml_unit_t *)0)->un_spare[15] +\ sizeof (uint_t))) /* * un_status */ #define LDL_BEING_RESET 0x0001 /* delete the log record at snarf */ #define LDL_FIND_TAIL 0x0002 /* find tail of the log */ #define LDL_SCAN_ACTIVE 0x0004 /* log scan in progress */ #define LDL_METADEVICE 0x0008 /* underlying device is metadevice */ #define LDL_PWVALID 0x0010 /* prewrite area is valid */ #define LDL_INFO 0x0020 /* prewrite state is valid */ typedef struct sect_trailer { uint_t st_tid; /* transaction id */ uint_t st_ident; /* unique sector id */ } sect_trailer_t; /* * ioctls */ #define MD_IOCGET_LOG (MDIOC_MISC|0) #define MD_IOC_DEBUG (MDIOC_MISC|4) #define MD_IOCGET_TRANSSTATS (MDIOC_MISC|5) #define MD_IOC_TSD (MDIOC_MISC|6) #define MD_IOC_TRYGETBLK (MDIOC_MISC|7) #define MD_IOC_TRYPAGE (MDIOC_MISC|8) #define MD_IOC_SETSHADOW (MDIOC_MISC|11) #define MD_IOC_INJECTERRORS (MDIOC_MISC|13) #define MD_IOC_STOPERRORS (MDIOC_MISC|14) #define MD_IOC_UFSERROR (MDIOC_MISC|15) #define MD_IOC_ISDEBUG (MDIOC_MISC|17) #define MD_IOC_TRANS_DETACH (MDIOC_MISC|32) /* * following bits are used in status word in the common section * of unit structure */ #define MD_UN_LOG_DELETED (0x00010000) /* don't need to del @snarf */ /* * map block */ #define MAPBLOCKSIZE (8192) #define MAPBLOCKSHIFT (13) #define MAPBLOCKOFF (MAPBLOCKSIZE-1) #define MAPBLOCKMASK (~MAPBLOCKOFF) /* * delta header */ struct delta { offset_t d_mof; off32_t d_nb; dev32_t d_dev; delta_t d_typ; }; /* * common map entry */ typedef struct mapentry mapentry_t; struct mapentry { /* * doubly linked list of all mapentries in map -- MUST BE FIRST */ mapentry_t *me_next; mapentry_t *me_prev; mapentry_t *me_hash; mapentry_t *me_agenext; mapentry_t *me_cancel; int (*me_func)(); uintptr_t me_arg; off_t me_lof; uint_t me_flags; uint_t me_tid; uint_t me_age; struct delta me_delta; }; #define me_mof me_delta.d_mof #define me_nb me_delta.d_nb #define me_dt me_delta.d_typ #define me_dev me_delta.d_dev /* * me_flags */ #define ME_FREE (0x0001) /* on free list */ #define ME_HASH (0x0002) /* on hash list */ #define ME_CANCEL (0x0004) /* on cancel list */ #define ME_AGE (0x0008) /* on age list */ #define ME_LIST (0x0010) /* on list list */ #define ME_ROLL (0x0020) /* on pseudo-roll list */ /* * TRANSACTION OPS STATS * mt_top_size_* should be 64bit but that would * require test recompilations. It does not hurt the kernel * so leave as 32 bit for now. */ struct topstats { uint_t mtm_top_num[TOP_MAX]; uint_t mtm_top_size_etot[TOP_MAX]; uint_t mtm_top_size_rtot[TOP_MAX]; uint_t mtm_top_size_max[TOP_MAX]; uint_t mtm_top_size_min[TOP_MAX]; uint_t mtm_delta_num[DT_MAX]; }; /* * MAP STATS (global struct that is not updated if compiled w/o ASSERTs) * some members of transstats need to be 64bit. See the comment above. */ struct transstats { /* trans.c */ uint_t ts_trans_zalloc; uint_t ts_trans_zalloc_nosleep; uint_t ts_trans_alloc; uint_t ts_trans_alloc_nosleep; uint_t ts_trans_free; uint_t ts_trans_alloced; uint_t ts_trans_freed; uint_t ts_trans_write; uint_t ts_trans_write_roll; /* trans_delta.c */ uint_t ts_mapentry_alloc; uint_t ts_mapentry_alloc_list; uint_t ts_mapentry_free; uint_t ts_delta_add; uint_t ts_delta_add_scan; uint_t ts_delta_add_hit; uint_t ts_delta_remove; uint_t ts_delta_remove_scan; uint_t ts_delta_remove_hit; uint_t ts_delta_del; uint_t ts_delta_del_scan; uint_t ts_delta_push; uint_t ts_overlap; uint_t ts_overlap_scan; uint_t ts_overlap_hit; uint_t ts_remove_roll; uint_t ts_remove_roll_scan; uint_t ts_remove_roll_hit; uint_t ts_remove_roll_dolock; uint_t ts_remove_roll_sud; uint_t ts_next_roll; uint_t ts_next_roll_scan; uint_t ts_next_roll_hit; uint_t ts_list_age; uint_t ts_list_age_scan; uint_t ts_list_get; uint_t ts_list_get_scan; uint_t ts_list_get_hit; uint_t ts_list_get_again; uint_t ts_list_put; uint_t ts_list_put_scan; uint_t ts_read_mstr; uint_t ts_logmap_secmap_roll; uint_t ts_read_log; uint_t ts_logmap_abort; uint_t ts_logmap_abort_hit; uint_t ts_list_add; uint_t ts_list_add_scan; uint_t ts_list_add_cancel; uint_t ts_list_add_unhash; uint_t ts_free_cancel; uint_t ts_free_cancel_again; uint_t ts_free_cancel_scan; uint_t ts_free_cancel_hit; uint_t ts_commit; uint_t ts_commit_hit; uint_t ts_logmap_roll_dev; uint_t ts_logmap_roll_dev_scan; uint_t ts_logmap_roll_dev_hit; uint_t ts_logmap_roll_sud; uint_t ts_logmap_roll_sud_hit; uint_t ts_logmap_ud_done; uint_t ts_logmap_ud_done_scan; uint_t ts_logmap_ud_wait; uint_t ts_logmap_ud_wait_hit; uint_t ts_logmap_ud_commit; uint_t ts_logmap_ud_commit_scan; uint_t ts_logmap_cancel; uint_t ts_logmap_cancel_scan; uint_t ts_logmap_cancel_hit; uint_t ts_logmap_iscancel; uint_t ts_logmap_iscancel_scan; uint_t ts_logmap_iscancel_hit; uint_t ts_logscan; uint_t ts_logscan_ud; uint_t ts_logscan_delta; uint_t ts_logscan_cancel; uint_t ts_logscan_commit; /* trans_thread.c */ uint_t ts_prewrite; uint_t ts_prewrite_read; uint_t ts_prewrite_write; uint_t ts_trans_roll; uint_t ts_trans_roll_wait; uint_t ts_trans_roll_wait_nada; uint_t ts_trans_roll_wait_slow; uint_t ts_trans_roll_force; uint_t ts_trans_roll_nsud; uint_t ts_trans_roll_ref; uint_t ts_trans_roll_full; uint_t ts_trans_roll_logmap; uint_t ts_trans_roll_read; uint_t ts_trans_roll_reread; uint_t ts_trans_roll_wait_inuse; uint_t ts_trans_roll_prewrite; uint_t ts_trans_roll_write; /* trans_top.c */ uint_t ts_delta; uint_t ts_ud_delta; uint_t ts_ud_delta_log; uint_t ts_cancel; uint_t ts_iscancel; uint_t ts_error; uint_t ts_iserror; uint_t ts_beginsync; uint_t ts_active; uint_t ts_activesync; uint_t ts_beginasync; uint_t ts_endsync; uint_t ts_wantin; uint_t ts_endasync; uint_t ts_read; uint_t ts_read_roll; uint_t ts_readmt; uint_t ts_write; uint_t ts_writemt; uint_t ts_writemt_done; uint_t ts_log; /* trans_log.c */ uint_t ts_logcommitdb; uint_t ts_push_dirty_bp; uint_t ts_push_dirty_bp_extra; uint_t ts_push_dirty_bp_fail; uint_t ts_alloc_bp; uint_t ts_alloc_bp_free; uint_t ts_find_bp; uint_t ts_find_bp_scan; uint_t ts_find_bp_hit; uint_t ts_find_read_lof; uint_t ts_find_read_lof_scan; uint_t ts_find_read_lof_hit; uint_t ts_get_read_bp; uint_t ts_get_read_bp_wr; uint_t ts_get_read_bp_rd; uint_t ts_extend_write_bp; uint_t ts_extend_write_bp_hit; uint_t ts_storebuf; uint_t ts_fetchbuf; uint_t ts_round_commit; uint_t ts_push_commit; uint_t ts_inval_range; uint_t ts_inval_range_scan; uint_t ts_inval_range_hit; uint_t ts_writelog; uint_t ts_writelog_max; uint_t ts_readlog; uint_t ts_readlog_max; uint_t ts_get_write_bp; uint_t ts_get_write_bp_steal; uint_t ts_writesync; uint_t ts_writesync_log; uint_t ts_writesync_nolog; uint_t ts_longmof_cnt; } transstats; #ifdef DEBUG #define TRANSSTATS(f) (transstats.f++) #define TRANSSTATSADD(f, n) (transstats.f += (n)) #define TRANSSTATSMAX(m, v) \ if ((v) > transstats.m)\ transstats.m = (v); #else #define TRANSSTATS(f) #define TRANSSTATSADD(f, n) #define TRANSSTATSMAX(m, v) #endif /* DEBUG */ /* * MAP TYPES */ enum maptypes { deltamaptype, udmaptype, logmaptype, matamaptype, shadowmaptype }; /* * MAP */ #define DELTAMAP_NHASH (512) #define LOGMAP_NHASH (2048) #define MAP_INDEX(dev, mof, mtm) \ ((((mof) >> MAPBLOCKSHIFT) + (dev)) & ((mtm)->mtm_nhash-1)) #define MAP_HASH(dev, mof, mtm) \ (mtm->mtm_hash + MAP_INDEX(dev, mof, mtm)) typedef struct mt_map { /* * anchor doubly linked list this map's entries -- MUST BE FIRST */ mapentry_t *mtm_next; mapentry_t *mtm_prev; int mtm_flags; /* generic flags */ int mtm_ref; /* PTE like ref bit */ uint_t mtm_debug; /* set at create time */ uint_t mtm_age; /* mono-inc; tags mapentries */ mapentry_t *mtm_cancel; /* to be canceled at commit */ uint_t mtm_nhash; /* # of hash anchors */ mapentry_t **mtm_hash; /* array of singly linked lists */ struct topstats *mtm_tops; /* trans ops - enabled by an ioctl */ int mtm_nme; /* # of mapentries */ int mtm_nmet; /* # of mapentries this transaction */ int mtm_nud; /* # of active userdata writes */ int mtm_nsud; /* # of userdata scanned deltas */ md_dev64_t mtm_dev; /* device identifying map */ /* * the following are protected by the global map_mutex */ struct mt_map *mtm_mapnext; /* singly linked list of all maps */ uint_t mtm_refcnt; /* reference count to this map */ enum maptypes mtm_type; /* type of map */ /* * used after logscan to set the log's tail */ off_t mtm_tail_lof; size_t mtm_tail_nb; /* * debug field for Scan test */ off_t mtm_trimlof; /* log was trimmed to this lof */ off_t mtm_trimtail; /* tail lof before trimming */ off_t mtm_trimalof; /* lof of last allocation delta */ off_t mtm_trimclof; /* lof of last commit delta */ off_t mtm_trimrlof; /* lof of last rolled delta */ struct ml_unit *mtm_ul; /* log unit for this map */ /* * moby trans stuff */ uint_t mtm_tid; uint_t mtm_committid; ushort_t mtm_closed; ushort_t mtm_seq; int mtm_wantin; int mtm_active; int mtm_activesync; uint_t mtm_dirty; kmutex_t mtm_lock; kcondvar_t mtm_cv_commit; kcondvar_t mtm_cv_next; kcondvar_t mtm_cv_eot; /* * mutex that protects all the fields in mt_map except * mtm_mapnext and mtm_refcnt */ kmutex_t mtm_mutex; kcondvar_t mtm_cv; /* generic conditional */ /* * rw lock for the mapentry fields agenext and locnext */ md_krwlock_t mtm_rwlock; /* * DEBUG: runtestscan */ kmutex_t mtm_scan_mutex; } mt_map_t; /* * mtm_flags */ #define MTM_ROLL_EXIT (0x00000001) #define MTM_ROLL_RUNNING (0x00000002) #define MTM_FORCE_ROLL (0x00000004) /* * Generic range checking macros */ #define OVERLAP(sof, snb, dof, dnb) \ ((sof >= dof && sof < (dof + dnb)) || \ (dof >= sof && dof < (sof + snb))) #define WITHIN(sof, snb, dof, dnb) ((sof >= dof) && ((sof+snb) <= (dof+dnb))) #define DATAoverlapME(mof, hnb, me) (OVERLAP(mof, hnb, me->me_mof, me->me_nb)) #define MEwithinDATA(me, mof, hnb) (WITHIN(me->me_mof, me->me_nb, mof, hnb)) #define DATAwithinME(mof, hnb, me) (WITHIN(mof, hnb, me->me_mof, me->me_nb)) typedef struct mt_unit { struct mdc_unit c; /* common stuff */ /* * infrastructure */ mt_flags_t un_flags; /* * log and master device */ mdkey_t un_m_key; md_dev64_t un_m_dev; mdkey_t un_l_key; md_dev64_t un_l_dev; daddr32_t un_l_sblk; /* start block */ daddr32_t un_l_pwsblk; /* prewrite start block */ daddr32_t un_l_nblks; /* # of usable log blocks */ daddr32_t un_l_tblks; /* total log blocks */ daddr32_t un_l_head; /* sector offset of log head */ daddr32_t un_l_tail; /* sector offset of log tail */ uint_t un_l_resv; /* current log reservations */ uint_t un_l_maxresv; /* max log reservations */ uint_t un_l_maxtransfer; /* maximum transfer at init */ mddb_recid_t un_l_recid; /* database id */ mt_l_error_t un_l_error; /* error state */ struct timeval32 un_l_timestamp; /* time of last log state chg */ md_dev64_t un_s_dev; /* shadow device for testing only */ mt_debug_t un_debug; /* debug flags; set at create */ md_dev64_t un_dev; /* this metatrans device */ int un_logreset; /* part of _FIOLOGRESET ioctl stuff */ struct timeval32 un_timestamp; /* time of last trans state change */ /* * spares */ ulong_t un_spare[16]; /* * following are incore only elements. * Incore elements must always be at the end * of this data struture. */ struct mt_unit *un_next; struct ml_unit *un_l_unit; struct ufstrans *un_ut; mt_map_t *un_deltamap; mt_map_t *un_udmap; mt_map_t *un_logmap; mt_map_t *un_matamap; mt_map_t *un_shadowmap; } mt_unit_t; typedef struct mt_unit32_od { mdc_unit32_od_t c; /* common stuff */ /* * infrastructure */ mt_flags_t un_flags; caddr32_t xx_un_next; /* anchored in log unit */ /* * log and master device */ mdkey_t un_m_key; dev32_t un_m_dev; mdkey_t un_l_key; dev32_t un_l_dev; daddr32_t un_l_sblk; /* start block */ daddr32_t un_l_pwsblk; /* prewrite start block */ daddr32_t un_l_nblks; /* # of usable log blocks */ daddr32_t un_l_tblks; /* total log blocks */ daddr32_t un_l_head; /* sector offset of log head */ daddr32_t un_l_tail; /* sector offset of log tail */ uint_t un_l_resv; /* current log reservations */ uint_t un_l_maxresv; /* max log reservations */ uint_t un_l_maxtransfer; /* maximum transfer at init */ mddb_recid_t un_l_recid; /* database id */ caddr32_t xx_un_l_unit; /* log device unit struct */ mt_l_error_t un_l_error; /* error state */ struct timeval32 un_l_timestamp; /* time of last log state chg */ dev32_t un_s_dev; /* shadow device for testing only */ mt_debug_t un_debug; /* debug flags; set at create */ caddr32_t xx_un_ut; /* ufstrans struct */ dev32_t un_dev; /* this metatrans device */ caddr32_t xx_un_deltamap; /* deltamap */ caddr32_t xx_un_udmap; /* userdata map */ caddr32_t xx_un_logmap; /* logmap includes moby trans stuff */ caddr32_t xx_un_matamap; /* optional - matamap */ caddr32_t xx_un_shadowmap; /* optional - shadowmap */ int un_logreset; /* part of _FIOLOGRESET ioctl stuff */ struct timeval32 un_timestamp; /* time of last trans state change */ /* * spares */ uint_t un_spare[16]; } mt_unit32_od_t; /* * prewrite info (per buf); stored as array at beginning of prewrite area */ struct prewrite { int pw_bufsize; /* every buffer is this size */ daddr32_t pw_blkno; /* block number */ dev32_t pw_dev; /* device to write to */ ushort_t pw_secmap; /* bitmap */ /* 1's write this sector in the buf */ ushort_t pw_flags; }; /* * pw_flags */ #define PW_INUSE 0x0001 /* this prewrite buf is in use */ #define PW_WAIT 0x0002 /* write in progress; wait for completion */ #define PW_REM 0x0004 /* remove deltas */ /* * log state */ struct logstate { off32_t ls_head_lof; /* log head */ uint_t ls_head_ident; /* log head ident */ uint_t ls_head_tid; /* log head tid */ uint_t ls_chksum; /* checksum of structure */ off32_t ls_bol_lof; /* needed for TS_Tools/dumplog.c */ off32_t ls_eol_lof; /* needed for TS_Tools/dumplog.c */ uint_t ls_maxtransfer; /* needed for TS_Tools/dumplog.c */ daddr32_t ls_pwsblk; /* needed for TS_Tools/dumplog.c */ }; /* * log state defines */ #define LS_SECTORS (2) /* number of sectors used by state area */ /* * un_debug * MT_TRANSACT - keep per thread accounting of tranactions * MT_MATAMAP - double check deltas and ops against matamap * MT_WRITE_CHECK - check master+deltas against metadata write * MT_LOG_WRITE_CHECK - read after write for log writes * MT_CHECK_MAP - check map after every insert/delete * MT_TRACE - trace transactions (used with MT_TRANSACT) * MT_SIZE - fail on size errors (used with MT_TRANSACT) * MT_NOASYNC - force every op to be sync * MT_FORCEROLL - forcibly roll the log after every commit * MT_SCAN - running runtestscan; special case as needed * MT_SHADOW - copy metatrans device writes to shadow dev. * MT_PREWRITE - process prewrite area every roll */ #define MT_TRANSACT (0x00000001) #define MT_MATAMAP (0x00000002) #define MT_WRITE_CHECK (0x00000004) #define MT_LOG_WRITE_CHECK (0x00000008) #define MT_CHECK_MAP (0x00000010) #define MT_TRACE (0x00000020) #define MT_SIZE (0x00000040) #define MT_NOASYNC (0x00000080) #define MT_FORCEROLL (0x00000100) #define MT_SCAN (0x00000200) #define MT_SHADOW (0x00000400) #define MT_PREWRITE (0x00000800) /* Type 2 trans records */ #define TRANS_REC 1 #define LOG_REC 2 #ifdef _KERNEL typedef struct md_tps { /* trans parent save */ DAEMON_QUEUE struct mt_unit *ps_un; mdi_unit_t *ps_ui; buf_t *ps_bp; size_t ps_count; /* Used for testing only. */ kmutex_t ps_mx; /* protects ps_count. */ } md_tps_t; /* * Log layer protos -- trans_log.c */ extern void _init_ldl(void); extern void _fini_ldl(void); extern void md_ldl_round_commit(mt_unit_t *); extern void md_ldl_push_commit(mt_unit_t *); extern int md_ldl_need_commit(ml_unit_t *); extern int md_ldl_has_space(ml_unit_t *, mapentry_t *); extern void md_ldl_write(mt_unit_t *, caddr_t, offset_t, mapentry_t *); extern void md_ldl_waito(ml_unit_t *); extern int md_ldl_read(ml_unit_t *, caddr_t, offset_t, off_t, mapentry_t *); extern void md_ldl_sethead(ml_unit_t *, off_t, uint_t, struct buf *); extern void md_ldl_settail(ml_unit_t *, off_t, off_t, struct buf *); extern void ldl_setpwvalid(ml_unit_t *); extern int ldl_build_incore(ml_unit_t *, int); extern ml_unit_t *ldl_findlog(mddb_recid_t); extern mddb_recid_t ldl_create(mdkey_t, mt_unit_t *); extern void ldl_utadd(mt_unit_t *); extern int ldl_open_dev(mt_unit_t *, ml_unit_t *); extern void ldl_close_dev(ml_unit_t *); extern int ldl_snarf(void); extern void ldl_logscan_seterror(ml_unit_t *); extern void ldl_logscan_saverror(ml_unit_t *); extern size_t md_ldl_logscan_nbcommit(off_t); extern int md_ldl_logscan_read(ml_unit_t *, off_t *, size_t, caddr_t); extern void md_ldl_logscan_begin(ml_unit_t *, daddr_t); extern void md_ldl_logscan_end(ml_unit_t *); extern int md_ldl_need_roll(ml_unit_t *); extern int md_ldl_empty(ml_unit_t *); extern int ldl_pwvalid(ml_unit_t *); extern void ldl_waitscan(ml_unit_t *); extern void ldl_errorbp(set_t, buf_t *, char *); extern void md_ldl_seterror(ml_unit_t *); extern int ldl_isherror(ml_unit_t *); extern int ldl_iserror(ml_unit_t *); extern int ldl_isanyerror(ml_unit_t *); extern void ldl_start_scan(mt_unit_t *); extern void ldl_opened_trans(mt_unit_t *, int); extern void ldl_open_trans(mt_unit_t *, int); extern int ldl_logreset(mt_unit_t *, buf_t *); extern void ldl_close_trans(mt_unit_t *); extern size_t md_ldl_bufsize(ml_unit_t *); extern void ldl_open_underlying(mt_unit_t *); extern void ldl_snarf_done(); extern int ldl_reset(mt_unit_t *, int, int); extern void ldl_cleanup(ml_unit_t *); /* * trans driver layer -- mdtrans.c */ extern kmem_cache_t *trans_child_cache; extern void *md_trans_zalloc(size_t); extern void *md_trans_zalloc_nosleep(size_t); extern void *md_trans_alloc(size_t); extern void *md_trans_alloc_nosleep(size_t); extern void md_trans_free(void *, size_t); extern int md_trans_not_wait(struct buf *cb); extern int md_trans_not_done(struct buf *cb); extern int md_trans_wait(struct buf *cb); extern int trans_done(struct buf *cb); extern int trans_done_shadow(struct buf *cb); extern void trans_child_init(struct buf *bp); extern void trans_close_all_devs(mt_unit_t *); extern int trans_open_all_devs(mt_unit_t *); extern int trans_build_incore(void *, int); extern void trans_commit(mt_unit_t *, int); extern int trans_detach(mt_unit_t *, int); extern void trans_attach(mt_unit_t *, int); extern int trans_reset(mt_unit_t *, minor_t, int, int); /* * transaction ioctl -- trans_ioctl.c */ /* rename named service functions */ md_ren_list_svc_t trans_rename_listkids; md_ren_svc_t trans_rename_check; md_ren_roleswap_svc_t trans_renexch_update_kids; md_ren_roleswap_svc_t trans_rename_update_self; md_ren_roleswap_svc_t trans_exchange_parent_update_to; md_ren_roleswap_svc_t trans_exchange_self_update_from_down; /* * transaction op layer -- trans_top.c */ extern void _init_md_top(void); extern void _fini_top(void); extern void top_read(struct buf *, char *, mt_unit_t *, int, void *); extern void md_top_read_roll(struct buf *, mt_unit_t *, ushort_t *); extern void top_build_incore(mt_unit_t *); extern void top_reset(mt_unit_t *, int, int); extern void top_write(struct buf *, char *, mt_unit_t *, int, void *); /* * map layer -- trans_delta.c */ extern void md_map_free_entries(mt_map_t *); extern int md_matamap_overlap(mt_map_t *, offset_t, off_t); extern int md_matamap_within(mt_map_t *, offset_t, off_t); extern int md_deltamap_need_commit(mt_map_t *); extern void md_deltamap_add(mt_map_t *, offset_t, off_t, delta_t, int (*)(), uintptr_t); extern mapentry_t *md_deltamap_remove(mt_map_t *, offset_t, off_t); extern void md_deltamap_del(mt_map_t *, offset_t, off_t); extern void md_deltamap_push(mt_unit_t *); extern int md_logmap_need_commit(mt_map_t *); extern int md_logmap_need_roll_async(mt_map_t *); extern int md_logmap_need_roll_sync(mt_map_t *); extern int md_logmap_need_roll(mt_map_t *); extern void md_logmap_start_roll(mt_unit_t *); extern void md_logmap_kill_roll(mt_map_t *); extern void md_logmap_forceroll(mt_map_t *); extern int md_logmap_overlap(mt_map_t *, md_dev64_t, offset_t, off_t); extern void md_logmap_remove_roll(mt_map_t *, md_dev64_t, offset_t, off_t); extern int md_logmap_next_roll(mt_map_t *, offset_t *, md_dev64_t *); extern void md_logmap_list_get(mt_map_t *, md_dev64_t, offset_t, off_t, mapentry_t **); extern void md_logmap_list_get_roll(mt_map_t *, md_dev64_t, offset_t, off_t, mapentry_t **); extern void md_logmap_list_put(mt_map_t *, mapentry_t *); extern void md_logmap_read_mstr(ml_unit_t *, struct buf *, int, void *); extern void md_logmap_secmap_roll(mapentry_t *, offset_t, ushort_t *); extern int logmap_read_log(ml_unit_t *, char *, offset_t, off_t, mapentry_t *); extern void md_logmap_make_space(mt_map_t *, ml_unit_t *, mapentry_t *); extern void md_logmap_add(mt_unit_t *, md_dev64_t, char *, offset_t, mapentry_t *); extern void md_logmap_add_ud(mt_unit_t *, md_dev64_t, char *, offset_t, mapentry_t *); extern void md_logmap_commit(mt_unit_t *); extern void md_logmap_sethead(mt_map_t *, ml_unit_t *, struct buf *); extern void md_logmap_roll_dev(mt_map_t *, ml_unit_t *ul, md_dev64_t); extern void md_logmap_roll_sud(mt_map_t *, ml_unit_t *ul, md_dev64_t, offset_t, off_t); extern int md_logmap_ud_done(struct buf *); extern void md_logmap_ud_wait(); extern void md_logmap_cancel(mt_unit_t *, md_dev64_t, offset_t, off_t); extern int md_logmap_iscancel(mt_map_t *, md_dev64_t, offset_t, off_t); extern void md_logmap_logscan(mt_unit_t *, daddr_t); extern void map_build_incore(mt_unit_t *); extern void map_reset(mt_unit_t *, int, int); extern void _init_md_map(void); extern void _fini_map(void); /* * scan and roll threads -- trans_thread.c */ extern void md_trans_roll(ml_unit_t *); extern void trans_scan(mt_unit_t *); extern void trans_roll_prewrite(ml_unit_t *); #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _SYS_MD_TRANS_H */