#ifndef _SYS_FS_UFS_LOG_H
#define _SYS_FS_UFS_LOG_H
#include <sys/buf.h>
#include <sys/fs/ufs_trans.h>
#include <sys/fs/ufs_filio.h>
#include <sys/fs/ufs_inode.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct lufs_save {
buf_t *sv_bp;
size_t sv_nb_left;
int sv_error;
} lufs_save_t;
typedef struct lufs_buf {
buf_t lb_buf;
void *lb_ptr;
} lufs_buf_t;
#define LUFS_EXTENTS (UINT32_C(0))
#define LS_SECTORS 2
typedef struct extent {
uint32_t lbno;
uint32_t pbno;
uint32_t nbno;
} extent_t;
typedef struct ic_extent {
uint32_t ic_lbno;
uint32_t ic_nbno;
daddr_t ic_pbno;
} ic_extent_t;
typedef struct extent_block {
uint32_t type;
int32_t chksum;
uint32_t nextents;
uint32_t nbytes;
uint32_t nextbno;
extent_t extents[1];
} extent_block_t;
typedef struct ic_extent_block {
uint32_t ic_nextents;
uint32_t ic_nbytes;
uint32_t ic_nextbno;
ic_extent_t ic_extents[1];
} ic_extent_block_t;
#define LDL_MINTRANSFER (UINT32_C(32768))
#define LDL_MAXTRANSFER (UINT32_C(1048576))
#define LDL_DIVISOR 1024
#define LDL_SOFTLOGCAP (256 * 1024 * 1024)
#define LDL_MINLOGSIZE (1024 * 1024)
#define LDL_MAXLOGSIZE (512 * 1024 * 1024)
#define LDL_CGSIZEREQ(fs) \
((fs)->fs_cgsize + ((fs)->fs_cgsize >> 1))
#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 cirbuf {
buf_t *cb_bp;
buf_t *cb_dirty;
buf_t *cb_free;
caddr_t cb_va;
size_t cb_nb;
krwlock_t cb_rwlock;
} cirbuf_t;
#define LUFS_VERSION (UINT32_C(1))
#define LUFS_VERSION_LATEST LUFS_VERSION
typedef struct ml_odunit {
uint32_t od_version;
uint32_t od_badlog;
uint32_t od_unused1;
uint32_t od_maxtransfer;
uint32_t od_devbsize;
int32_t od_bol_lof;
int32_t od_eol_lof;
uint32_t od_requestsize;
uint32_t od_statesize;
uint32_t od_logsize;
int32_t od_statebno;
int32_t od_unused2;
int32_t od_head_lof;
uint32_t od_head_ident;
int32_t od_tail_lof;
uint32_t od_tail_ident;
uint32_t od_chksum;
uint32_t od_head_tid;
int32_t od_debug;
struct timeval od_timestamp;
} ml_odunit_t;
typedef struct ml_unit {
struct ml_unit *un_next;
int un_flags;
buf_t *un_bp;
struct ufsvfs *un_ufsvfs;
dev_t un_dev;
ic_extent_block_t *un_ebp;
size_t un_nbeb;
struct mt_map *un_deltamap;
struct mt_map *un_logmap;
struct mt_map *un_matamap;
uint32_t un_maxresv;
uint32_t un_resv;
uint32_t un_resv_wantin;
uint32_t un_tid;
cirbuf_t un_rdbuf;
cirbuf_t un_wrbuf;
ml_odunit_t un_ondisk;
kmutex_t un_log_mutex;
kmutex_t un_state_mutex;
} ml_unit_t;
#define un_version un_ondisk.od_version
#define un_badlog un_ondisk.od_badlog
#define un_maxtransfer un_ondisk.od_maxtransfer
#define un_devbsize un_ondisk.od_devbsize
#define un_bol_lof un_ondisk.od_bol_lof
#define un_eol_lof un_ondisk.od_eol_lof
#define un_statesize un_ondisk.od_statesize
#define un_logsize un_ondisk.od_logsize
#define un_statebno un_ondisk.od_statebno
#define un_requestsize un_ondisk.od_requestsize
#define un_head_lof un_ondisk.od_head_lof
#define un_head_ident un_ondisk.od_head_ident
#define un_tail_lof un_ondisk.od_tail_lof
#define un_tail_ident un_ondisk.od_tail_ident
#define un_chksum un_ondisk.od_chksum
#define un_head_tid un_ondisk.od_head_tid
#define un_debug un_ondisk.od_debug
#define un_timestamp un_ondisk.od_timestamp
#define LDL_SCAN 0x0001
#define LDL_ERROR 0x0002
#define LDL_NOROLL 0x0004
typedef struct sect_trailer {
uint32_t st_tid;
uint32_t st_ident;
} sect_trailer_t;
#define MAPBLOCKSIZE (8192)
#define MAPBLOCKSHIFT (13)
#define MAPBLOCKOFF (MAPBLOCKSIZE-1)
#define MAPBLOCKMASK (~MAPBLOCKOFF)
#define DEV_BMASK (DEV_BSIZE - 1)
typedef struct crb {
int64_t c_mof;
caddr_t c_buf;
uint32_t c_nb;
ushort_t c_refcnt;
uchar_t c_invalid;
} crb_t;
#define CRB_END ((crb_t *)1)
struct delta {
int64_t d_mof;
int32_t d_nb;
delta_t d_typ;
};
typedef struct mapentry mapentry_t;
struct mapentry {
mapentry_t *me_next;
mapentry_t *me_prev;
mapentry_t *me_hash;
mapentry_t *me_agenext;
mapentry_t *me_cancel;
crb_t *me_crb;
int (*me_func)();
ulong_t me_arg;
ulong_t me_age;
struct delta me_delta;
uint32_t me_tid;
off_t me_lof;
ushort_t me_flags;
};
#define me_mof me_delta.d_mof
#define me_nb me_delta.d_nb
#define me_dt me_delta.d_typ
#define ME_SCAN (0x0001)
#define ME_HASH (0x0002)
#define ME_CANCEL (0x0004)
#define ME_AGE (0x0008)
#define ME_LIST (0x0010)
#define ME_ROLL (0x0020)
#define ME_USER (0x0040)
enum maptypes {
deltamaptype, logmaptype, matamaptype
};
#define DELTAMAP_NHASH (512)
#define LOGMAP_NHASH (2048)
#define MAP_INDEX(mof, mtm) \
(((mof) >> MAPBLOCKSHIFT) & (mtm->mtm_nhash-1))
#define MAP_HASH(mof, mtm) \
((mtm)->mtm_hash + MAP_INDEX((mof), (mtm)))
typedef struct mt_map {
mapentry_t *mtm_next;
mapentry_t *mtm_prev;
enum maptypes mtm_type;
int mtm_flags;
int mtm_ref;
ulong_t mtm_debug;
ulong_t mtm_age;
mapentry_t *mtm_cancel;
ulong_t mtm_nhash;
mapentry_t **mtm_hash;
struct topstats *mtm_tops;
long mtm_nme;
long mtm_nmet;
long mtm_cfrags;
long mtm_cfragmax;
off_t mtm_tail_lof;
size_t mtm_tail_nb;
off_t mtm_trimlof;
off_t mtm_trimtail;
off_t mtm_trimalof;
off_t mtm_trimclof;
off_t mtm_trimrlof;
ml_unit_t *mtm_ul;
uint32_t mtm_tid;
uint32_t mtm_committid;
ushort_t mtm_closed;
ushort_t mtm_seq;
long mtm_wantin;
long mtm_active;
long mtm_activesync;
ulong_t mtm_dirty;
kmutex_t mtm_lock;
kcondvar_t mtm_cv_commit;
kcondvar_t mtm_cv_next;
kcondvar_t mtm_cv_eot;
kmutex_t mtm_mutex;
kcondvar_t mtm_to_roll_cv;
kcondvar_t mtm_from_roll_cv;
krwlock_t mtm_rwlock;
kmutex_t mtm_scan_mutex;
int mtm_taskq_sync_count;
kcondvar_t mtm_cv;
} mt_map_t;
#define MTM_ROLL_EXIT 0x00000001
#define MTM_ROLL_RUNNING 0x00000002
#define MTM_FORCE_ROLL 0x00000004
#define MTM_ROLLING 0x00000008
#define MTM_CANCELED 0x00000010
#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))
#define DATAwithinCRB(mof, nb, crb) \
(WITHIN((mof), (nb), (crb)->c_mof, (crb)->c_nb))
typedef struct topstats {
uint64_t mtm_top_num[TOP_MAX];
uint64_t mtm_top_size_etot[TOP_MAX];
uint64_t mtm_top_size_rtot[TOP_MAX];
uint64_t mtm_top_size_max[TOP_MAX];
uint64_t mtm_top_size_min[TOP_MAX];
uint64_t mtm_delta_num[DT_MAX];
} topstats_t;
typedef struct fio_lufs_stats {
uint32_t ls_debug;
uint32_t _ls_pad;
topstats_t ls_topstats;
} fio_lufs_stats_t;
typedef uint16_t rbsecmap_t;
typedef struct rollbuf {
buf_t rb_bh;
struct rollbuf *rb_next;
crb_t *rb_crb;
mapentry_t *rb_age;
rbsecmap_t rb_secmap;
} rollbuf_t;
#define MT_NONE (0x00000000)
#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)
struct logstats {
kstat_named_t ls_lreads;
kstat_named_t ls_lwrites;
kstat_named_t ls_lreadsinmem;
kstat_named_t ls_ldlreads;
kstat_named_t ls_ldlwrites;
kstat_named_t ls_mreads;
kstat_named_t ls_rreads;
kstat_named_t ls_rwrites;
};
#ifdef _KERNEL
typedef struct threadtrans {
ulong_t deltas_size;
uint32_t last_async_tid;
uchar_t any_deltas;
#ifdef DEBUG
uint_t topid;
ulong_t esize;
ulong_t rsize;
dev_t dev;
#endif
} threadtrans_t;
extern void ldl_strategy(ml_unit_t *, buf_t *);
extern void ldl_round_commit(ml_unit_t *);
extern void ldl_push_commit(ml_unit_t *);
extern int ldl_need_commit(ml_unit_t *);
extern int ldl_has_space(ml_unit_t *, mapentry_t *);
extern void ldl_write(ml_unit_t *, caddr_t, offset_t, mapentry_t *);
extern void ldl_waito(ml_unit_t *);
extern int ldl_read(ml_unit_t *, caddr_t, offset_t, off_t,
mapentry_t *);
extern void ldl_sethead(ml_unit_t *, off_t, uint32_t);
extern void ldl_settail(ml_unit_t *, off_t, size_t);
extern ulong_t ldl_logscan_nbcommit(off_t);
extern int ldl_logscan_read(ml_unit_t *, off_t *, size_t, caddr_t);
extern void ldl_logscan_begin(ml_unit_t *);
extern void ldl_logscan_end(ml_unit_t *);
extern int ldl_need_roll(ml_unit_t *);
extern void ldl_seterror(ml_unit_t *, char *);
extern size_t ldl_bufsize(ml_unit_t *);
extern void ldl_savestate(ml_unit_t *);
extern void free_cirbuf(cirbuf_t *);
extern void alloc_rdbuf(cirbuf_t *, size_t, size_t);
extern void alloc_wrbuf(cirbuf_t *, size_t);
extern int trans_not_wait(struct buf *cb);
extern int trans_not_done(struct buf *cb);
extern int trans_wait(struct buf *cb);
extern int trans_done(struct buf *cb);
extern void lufs_strategy(ml_unit_t *, buf_t *);
extern void lufs_read_strategy(ml_unit_t *, buf_t *);
extern void lufs_write_strategy(ml_unit_t *, buf_t *);
extern void lufs_init(void);
extern uint32_t lufs_hd_genid(const ml_unit_t *);
extern int lufs_enable(struct vnode *, struct fiolog *, cred_t *);
extern int lufs_disable(vnode_t *, struct fiolog *);
extern void _init_top(void);
extern int top_read_roll(rollbuf_t *, ml_unit_t *);
extern void map_free_entries(mt_map_t *);
extern int matamap_overlap(mt_map_t *, offset_t, off_t);
extern int matamap_within(mt_map_t *, offset_t, off_t);
extern int deltamap_need_commit(mt_map_t *);
extern void deltamap_add(mt_map_t *, offset_t, off_t, delta_t,
int (*)(), ulong_t, threadtrans_t *tp);
extern mapentry_t *deltamap_remove(mt_map_t *, offset_t, off_t);
extern void deltamap_del(mt_map_t *, offset_t, off_t);
extern void deltamap_push(ml_unit_t *);
extern void logmap_cancel_remove(mt_map_t *);
extern int logmap_need_commit(mt_map_t *);
extern int logmap_need_roll_async(mt_map_t *);
extern int logmap_need_roll_sync(mt_map_t *);
extern void logmap_start_roll(ml_unit_t *);
extern void logmap_kill_roll(ml_unit_t *);
extern void logmap_forceroll(mt_map_t *);
extern void logmap_forceroll_nowait(mt_map_t *);
extern int logmap_overlap(mt_map_t *, offset_t, off_t);
extern void logmap_remove_roll(mt_map_t *, offset_t, off_t);
extern int logmap_next_roll(mt_map_t *, offset_t *);
extern int logmap_list_get(mt_map_t *, offset_t, off_t,
mapentry_t **);
extern int logmap_list_get_roll(mt_map_t *, offset_t, rollbuf_t *);
extern void logmap_list_put(mt_map_t *, mapentry_t *);
extern void logmap_list_put_roll(mt_map_t *, mapentry_t *);
extern int logmap_setup_read(mapentry_t *, rollbuf_t *);
extern void logmap_make_space(struct mt_map *, ml_unit_t *,
mapentry_t *);
extern void logmap_add(ml_unit_t *, char *, offset_t, mapentry_t *);
extern void logmap_add_buf(ml_unit_t *, char *, offset_t,
mapentry_t *, caddr_t, uint32_t);
extern void logmap_commit(ml_unit_t *, uint32_t);
extern void logmap_sethead(mt_map_t *, ml_unit_t *);
extern void logmap_settail(mt_map_t *, ml_unit_t *);
extern void logmap_roll_dev(ml_unit_t *ul);
extern void logmap_cancel(ml_unit_t *, offset_t, off_t, int);
extern void logmap_free_cancel(mt_map_t *, mapentry_t **);
extern int logmap_iscancel(mt_map_t *, offset_t, off_t);
extern void logmap_logscan(ml_unit_t *);
extern mt_map_t *map_put(mt_map_t *);
extern mt_map_t *map_get(ml_unit_t *, enum maptypes, int);
extern void _init_map(void);
extern void trans_roll(ml_unit_t *);
#ifdef DEBUG
extern int map_put_debug(mt_map_t *);
extern int map_get_debug(ml_unit_t *, mt_map_t *);
extern int top_write_debug(ml_unit_t *, mapentry_t *, offset_t, off_t);
extern int matamap_overlap(mt_map_t *, offset_t, off_t);
extern int ldl_sethead_debug(ml_unit_t *);
extern int map_check_linkage(mt_map_t *);
extern int logmap_logscan_debug(mt_map_t *, mapentry_t *);
extern int map_check_ldl_write(ml_unit_t *, caddr_t, offset_t,
mapentry_t *);
extern int logmap_logscan_commit_debug(off_t, mt_map_t *);
extern int logmap_logscan_add_debug(struct delta *, mt_map_t *);
extern int top_delta_debug(ml_unit_t *, offset_t, off_t, delta_t);
extern int top_begin_debug(ml_unit_t *, top_t, ulong_t);
extern int top_end_debug(ml_unit_t *, mt_map_t *, top_t, ulong_t);
extern int top_roll_debug(ml_unit_t *);
extern int top_init_debug(void);
extern int lufs_initialize_debug(ml_odunit_t *);
#endif
extern uint64_t delta_stats[DT_MAX];
extern uint64_t roll_stats[DT_MAX];
extern struct logstats logstats;
extern int ufs_crb_enable;
extern uint_t topkey;
extern uint32_t ufs_ncg_log;
extern uint_t lufs_debug;
#endif
#ifdef __cplusplus
}
#endif
#endif