/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2006 Ruslan Ermilov <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#ifndef _G_CACHE_H_29#define _G_CACHE_H_3031#include <sys/endian.h>3233#define G_CACHE_CLASS_NAME "CACHE"34#define G_CACHE_MAGIC "GEOM::CACHE"35#define G_CACHE_VERSION 13637#ifdef _KERNEL38#define G_CACHE_TYPE_MANUAL 039#define G_CACHE_TYPE_AUTOMATIC 14041#define G_CACHE_DEBUG(lvl, ...) \42_GEOM_DEBUG("GEOM_CACHE", g_cache_debug, (lvl), NULL, __VA_ARGS__)43#define G_CACHE_LOGREQ(bp, ...) \44_GEOM_DEBUG("GEOM_CACHE", g_cache_debug, 2, (bp), __VA_ARGS__)4546#define G_CACHE_BUCKETS (1 << 3)47#define G_CACHE_BUCKET(bno) ((bno) & (G_CACHE_BUCKETS - 1))4849struct g_cache_softc {50struct g_geom *sc_geom;51int sc_type;52u_int sc_bshift;53u_int sc_bsize;54off_t sc_tail;55struct mtx sc_mtx;56struct callout sc_callout;57LIST_HEAD(, g_cache_desc) sc_desclist[G_CACHE_BUCKETS];58TAILQ_HEAD(, g_cache_desc) sc_usedlist;59uma_zone_t sc_zone;6061u_int sc_maxent; /* max entries */62u_int sc_nent; /* allocated entries */63u_int sc_nused; /* re-useable entries */64u_int sc_invalid; /* invalid entries */6566uintmax_t sc_reads; /* #reads */67uintmax_t sc_readbytes; /* bytes read */68uintmax_t sc_cachereads; /* #reads from cache */69uintmax_t sc_cachereadbytes; /* bytes read from cache */70uintmax_t sc_cachehits; /* cache hits */71uintmax_t sc_cachemisses; /* cache misses */72uintmax_t sc_cachefull; /* #times a cache was full */73uintmax_t sc_writes; /* #writes */74uintmax_t sc_wrotebytes; /* bytes written */75};76#define sc_name sc_geom->name7778struct g_cache_desc {79off_t d_bno; /* block number */80caddr_t d_data; /* data area */81struct bio *d_biolist; /* waiters */82time_t d_atime; /* access time */83int d_flags; /* flags */84#define D_FLAG_USED (1 << 0) /* can be reused */85#define D_FLAG_INVALID (1 << 1) /* invalid */86LIST_ENTRY(g_cache_desc) d_next; /* list */87TAILQ_ENTRY(g_cache_desc) d_used; /* used list */88};8990#define G_CACHE_NEXT_BIO1(bp) (bp)->bio_driver191#define G_CACHE_NEXT_BIO2(bp) (bp)->bio_driver292#define G_CACHE_DESC1(bp) (bp)->bio_caller193#define G_CACHE_DESC2(bp) (bp)->bio_caller29495#endif /* _KERNEL */9697struct g_cache_metadata {98char md_magic[16]; /* Magic value. */99uint32_t md_version; /* Version number. */100char md_name[16]; /* Cache value. */101uint32_t md_bsize; /* Cache block size. */102uint32_t md_size; /* Cache size. */103uint64_t md_provsize; /* Provider's size. */104};105106static __inline void107cache_metadata_encode(const struct g_cache_metadata *md, u_char *data)108{109110bcopy(md->md_magic, data, sizeof(md->md_magic));111le32enc(data + 16, md->md_version);112bcopy(md->md_name, data + 20, sizeof(md->md_name));113le32enc(data + 36, md->md_bsize);114le32enc(data + 40, md->md_size);115le64enc(data + 44, md->md_provsize);116}117118static __inline void119cache_metadata_decode(const u_char *data, struct g_cache_metadata *md)120{121122bcopy(data, md->md_magic, sizeof(md->md_magic));123md->md_version = le32dec(data + 16);124bcopy(data + 20, md->md_name, sizeof(md->md_name));125md->md_bsize = le32dec(data + 36);126md->md_size = le32dec(data + 40);127md->md_provsize = le64dec(data + 44);128}129130#endif /* _G_CACHE_H_ */131132133