]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/geom/cache/g_cache.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / geom / cache / g_cache.h
1 /*-
2  * Copyright (c) 2006 Ruslan Ermilov <ru@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #ifndef _G_CACHE_H_
30 #define _G_CACHE_H_
31
32 #include <sys/endian.h>
33
34 #define G_CACHE_CLASS_NAME      "CACHE"
35 #define G_CACHE_MAGIC           "GEOM::CACHE"
36 #define G_CACHE_VERSION         1
37
38 #ifdef _KERNEL
39 #define G_CACHE_TYPE_MANUAL     0
40 #define G_CACHE_TYPE_AUTOMATIC  1
41
42 #define G_CACHE_DEBUG(lvl, ...) do {                                    \
43         if (g_cache_debug >= (lvl)) {                                   \
44                 printf("GEOM_CACHE");                                   \
45                 if (g_cache_debug > 0)                                  \
46                         printf("[%u]", lvl);                            \
47                 printf(": ");                                           \
48                 printf(__VA_ARGS__);                                    \
49                 printf("\n");                                           \
50         }                                                               \
51 } while (0)
52 #define G_CACHE_LOGREQ(bp, ...) do {                                    \
53         if (g_cache_debug >= 2) {                                       \
54                 printf("GEOM_CACHE[2]: ");                              \
55                 printf(__VA_ARGS__);                                    \
56                 printf(" ");                                            \
57                 g_print_bio(bp);                                        \
58                 printf("\n");                                           \
59         }                                                               \
60 } while (0)
61
62 #define G_CACHE_BUCKETS         (1 << 3)
63 #define G_CACHE_BUCKET(bno)     ((bno) & (G_CACHE_BUCKETS - 1))
64
65 struct g_cache_softc {
66         struct g_geom   *sc_geom;
67         int             sc_type;
68         u_int           sc_bshift;
69         u_int           sc_bsize;
70         off_t           sc_tail;
71         struct mtx      sc_mtx;
72         struct callout  sc_callout;
73         LIST_HEAD(, g_cache_desc) sc_desclist[G_CACHE_BUCKETS];
74         TAILQ_HEAD(, g_cache_desc) sc_usedlist;
75         uma_zone_t      sc_zone;
76
77         u_int           sc_maxent;              /* max entries */
78         u_int           sc_nent;                /* allocated entries */
79         u_int           sc_nused;               /* re-useable entries */
80         u_int           sc_invalid;             /* invalid entries */
81
82         uintmax_t       sc_reads;               /* #reads */
83         uintmax_t       sc_readbytes;           /* bytes read */
84         uintmax_t       sc_cachereads;          /* #reads from cache */
85         uintmax_t       sc_cachereadbytes;      /* bytes read from cache */
86         uintmax_t       sc_cachehits;           /* cache hits */
87         uintmax_t       sc_cachemisses;         /* cache misses */
88         uintmax_t       sc_cachefull;           /* #times a cache was full */
89         uintmax_t       sc_writes;              /* #writes */
90         uintmax_t       sc_wrotebytes;          /* bytes written */
91 };
92 #define sc_name sc_geom->name
93
94 struct g_cache_desc {
95         off_t           d_bno;                  /* block number */
96         caddr_t         d_data;                 /* data area */
97         struct bio      *d_biolist;             /* waiters */
98         time_t          d_atime;                /* access time */
99         int             d_flags;                /* flags */
100 #define D_FLAG_USED     (1 << 0)                        /* can be reused */
101 #define D_FLAG_INVALID  (1 << 1)                        /* invalid */
102         LIST_ENTRY(g_cache_desc) d_next;        /* list */
103         TAILQ_ENTRY(g_cache_desc) d_used;       /* used list */
104 };
105
106 #define G_CACHE_NEXT_BIO1(bp)   (bp)->bio_driver1
107 #define G_CACHE_NEXT_BIO2(bp)   (bp)->bio_driver2
108 #define G_CACHE_DESC1(bp)       (bp)->bio_caller1
109 #define G_CACHE_DESC2(bp)       (bp)->bio_caller2
110
111 #endif  /* _KERNEL */
112
113 struct g_cache_metadata {
114         char            md_magic[16];           /* Magic value. */
115         uint32_t        md_version;             /* Version number. */
116         char            md_name[16];            /* Cache value. */
117         uint32_t        md_bsize;               /* Cache block size. */
118         uint32_t        md_size;                /* Cache size. */
119         uint64_t        md_provsize;            /* Provider's size. */
120 };
121
122 static __inline void
123 cache_metadata_encode(const struct g_cache_metadata *md, u_char *data)
124 {
125
126         bcopy(md->md_magic, data, sizeof(md->md_magic));
127         le32enc(data + 16, md->md_version);
128         bcopy(md->md_name, data + 20, sizeof(md->md_name));
129         le32enc(data + 36, md->md_bsize);
130         le32enc(data + 40, md->md_size);
131         le64enc(data + 44, md->md_provsize);
132 }
133
134 static __inline void
135 cache_metadata_decode(const u_char *data, struct g_cache_metadata *md)
136 {
137
138         bcopy(data, md->md_magic, sizeof(md->md_magic));
139         md->md_version = le32dec(data + 16);
140         bcopy(data + 20, md->md_name, sizeof(md->md_name));
141         md->md_bsize = le32dec(data + 36);
142         md->md_size = le32dec(data + 40);
143         md->md_provsize = le64dec(data + 44);
144 }
145
146 #endif  /* _G_CACHE_H_ */