Lines Matching +full:- +full:gp
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
74 if (error || !req->newptr) in sysctl_handle_pct()
108 #define OFF2BNO(off, sc) ((off) >> (sc)->sc_bshift)
109 #define BNO2OFF(bno, sc) ((bno) << (sc)->sc_bshift)
116 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_alloc()
118 if (!TAILQ_EMPTY(&sc->sc_usedlist)) { in g_cache_alloc()
119 dp = TAILQ_FIRST(&sc->sc_usedlist); in g_cache_alloc()
120 TAILQ_REMOVE(&sc->sc_usedlist, dp, d_used); in g_cache_alloc()
121 sc->sc_nused--; in g_cache_alloc()
122 dp->d_flags = 0; in g_cache_alloc()
126 if (sc->sc_nent > sc->sc_maxent) { in g_cache_alloc()
127 sc->sc_cachefull++; in g_cache_alloc()
133 dp->d_data = uma_zalloc(sc->sc_zone, M_NOWAIT); in g_cache_alloc()
134 if (dp->d_data == NULL) { in g_cache_alloc()
138 sc->sc_nent++; in g_cache_alloc()
146 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_free()
148 uma_zfree(sc->sc_zone, dp->d_data); in g_cache_free()
150 sc->sc_nent--; in g_cache_free()
159 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_free_used()
161 n = g_cache_used_lo * sc->sc_maxent / 100; in g_cache_free_used()
162 while (sc->sc_nused > n) { in g_cache_free_used()
163 KASSERT(!TAILQ_EMPTY(&sc->sc_usedlist), ("used list empty")); in g_cache_free_used()
164 dp = TAILQ_FIRST(&sc->sc_usedlist); in g_cache_free_used()
165 TAILQ_REMOVE(&sc->sc_usedlist, dp, d_used); in g_cache_free_used()
166 sc->sc_nused--; in g_cache_free_used()
178 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_deliver()
179 KASSERT(OFF2BNO(bp->bio_offset, sc) <= dp->d_bno, ("wrong entry")); in g_cache_deliver()
180 KASSERT(OFF2BNO(bp->bio_offset + bp->bio_length - 1, sc) >= in g_cache_deliver()
181 dp->d_bno, ("wrong entry")); in g_cache_deliver()
183 off1 = BNO2OFF(dp->d_bno, sc); in g_cache_deliver()
184 off = MAX(bp->bio_offset, off1); in g_cache_deliver()
185 len = MIN(bp->bio_offset + bp->bio_length, off1 + sc->sc_bsize) - off; in g_cache_deliver()
187 if (bp->bio_error == 0) in g_cache_deliver()
188 bp->bio_error = error; in g_cache_deliver()
189 if (bp->bio_error == 0) { in g_cache_deliver()
190 bcopy(dp->d_data + (off - off1), in g_cache_deliver()
191 bp->bio_data + (off - bp->bio_offset), len); in g_cache_deliver()
193 bp->bio_completed += len; in g_cache_deliver()
194 KASSERT(bp->bio_completed <= bp->bio_length, ("extra data")); in g_cache_deliver()
195 if (bp->bio_completed == bp->bio_length) { in g_cache_deliver()
196 if (bp->bio_error != 0) in g_cache_deliver()
197 bp->bio_completed = 0; in g_cache_deliver()
198 g_io_deliver(bp, bp->bio_error); in g_cache_deliver()
201 if (dp->d_flags & D_FLAG_USED) { in g_cache_deliver()
202 TAILQ_REMOVE(&sc->sc_usedlist, dp, d_used); in g_cache_deliver()
203 TAILQ_INSERT_TAIL(&sc->sc_usedlist, dp, d_used); in g_cache_deliver()
204 } else if (OFF2BNO(off + len, sc) > dp->d_bno) { in g_cache_deliver()
205 TAILQ_INSERT_TAIL(&sc->sc_usedlist, dp, d_used); in g_cache_deliver()
206 sc->sc_nused++; in g_cache_deliver()
207 dp->d_flags |= D_FLAG_USED; in g_cache_deliver()
209 dp->d_atime = time_uptime; in g_cache_deliver()
219 sc = bp->bio_from->geom->softc; in g_cache_done()
222 mtx_lock(&sc->sc_mtx); in g_cache_done()
223 bp2 = dp->d_biolist; in g_cache_done()
227 g_cache_deliver(sc, bp2, dp, bp->bio_error); in g_cache_done()
230 dp->d_biolist = NULL; in g_cache_done()
231 if (dp->d_flags & D_FLAG_INVALID) { in g_cache_done()
232 sc->sc_invalid--; in g_cache_done()
234 } else if (bp->bio_error) { in g_cache_done()
236 if (dp->d_flags & D_FLAG_USED) { in g_cache_done()
237 TAILQ_REMOVE(&sc->sc_usedlist, dp, d_used); in g_cache_done()
238 sc->sc_nused--; in g_cache_done()
242 mtx_unlock(&sc->sc_mtx); in g_cache_done()
251 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_lookup()
253 LIST_FOREACH(dp, &sc->sc_desclist[G_CACHE_BUCKET(bno)], d_next) in g_cache_lookup()
254 if (dp->d_bno == bno) in g_cache_lookup()
265 mtx_lock(&sc->sc_mtx); in g_cache_read()
267 OFF2BNO(bp->bio_offset + bp->bio_completed, sc)); in g_cache_read()
270 sc->sc_cachehits++; in g_cache_read()
271 if (dp->d_biolist != NULL) { in g_cache_read()
273 G_CACHE_NEXT_BIO2(bp) = dp->d_biolist; in g_cache_read()
274 dp->d_biolist = bp; in g_cache_read()
277 mtx_unlock(&sc->sc_mtx); in g_cache_read()
282 sc->sc_cachemisses++; in g_cache_read()
285 mtx_unlock(&sc->sc_mtx); in g_cache_read()
291 mtx_unlock(&sc->sc_mtx); in g_cache_read()
295 dp->d_bno = OFF2BNO(bp->bio_offset + bp->bio_completed, sc); in g_cache_read()
298 dp->d_biolist = bp; in g_cache_read()
299 LIST_INSERT_HEAD(&sc->sc_desclist[G_CACHE_BUCKET(dp->d_bno)], in g_cache_read()
301 mtx_unlock(&sc->sc_mtx); in g_cache_read()
305 cbp->bio_done = g_cache_done; in g_cache_read()
306 cbp->bio_offset = BNO2OFF(dp->d_bno, sc); in g_cache_read()
307 cbp->bio_data = dp->d_data; in g_cache_read()
308 cbp->bio_length = sc->sc_bsize; in g_cache_read()
309 g_io_request(cbp, LIST_FIRST(&bp->bio_to->geom->consumer)); in g_cache_read()
319 mtx_lock(&sc->sc_mtx); in g_cache_invalidate()
320 bno = OFF2BNO(bp->bio_offset, sc); in g_cache_invalidate()
321 lim = OFF2BNO(bp->bio_offset + bp->bio_length - 1, sc); in g_cache_invalidate()
325 if (dp->d_flags & D_FLAG_USED) { in g_cache_invalidate()
326 TAILQ_REMOVE(&sc->sc_usedlist, dp, d_used); in g_cache_invalidate()
327 sc->sc_nused--; in g_cache_invalidate()
329 if (dp->d_biolist == NULL) in g_cache_invalidate()
332 dp->d_flags = D_FLAG_INVALID; in g_cache_invalidate()
333 sc->sc_invalid++; in g_cache_invalidate()
338 mtx_unlock(&sc->sc_mtx); in g_cache_invalidate()
345 struct g_geom *gp; in g_cache_start() local
349 gp = bp->bio_to->geom; in g_cache_start()
350 sc = gp->softc; in g_cache_start()
352 switch (bp->bio_cmd) { in g_cache_start()
354 sc->sc_reads++; in g_cache_start()
355 sc->sc_readbytes += bp->bio_length; in g_cache_start()
358 if (bp->bio_offset + bp->bio_length > sc->sc_tail) in g_cache_start()
360 if (OFF2BNO(bp->bio_offset, sc) == in g_cache_start()
361 OFF2BNO(bp->bio_offset + bp->bio_length - 1, sc)) { in g_cache_start()
362 sc->sc_cachereads++; in g_cache_start()
363 sc->sc_cachereadbytes += bp->bio_length; in g_cache_start()
366 sc->sc_cachereads--; in g_cache_start()
367 sc->sc_cachereadbytes -= bp->bio_length; in g_cache_start()
369 } else if (OFF2BNO(bp->bio_offset, sc) + 1 == in g_cache_start()
370 OFF2BNO(bp->bio_offset + bp->bio_length - 1, sc)) { in g_cache_start()
371 mtx_lock(&sc->sc_mtx); in g_cache_start()
372 dp = g_cache_lookup(sc, OFF2BNO(bp->bio_offset, sc)); in g_cache_start()
373 if (dp == NULL || dp->d_biolist != NULL) { in g_cache_start()
374 mtx_unlock(&sc->sc_mtx); in g_cache_start()
377 sc->sc_cachereads++; in g_cache_start()
378 sc->sc_cachereadbytes += bp->bio_length; in g_cache_start()
380 mtx_unlock(&sc->sc_mtx); in g_cache_start()
383 sc->sc_cachereads--; in g_cache_start()
384 sc->sc_cachereadbytes -= bp->bio_length; in g_cache_start()
389 sc->sc_writes++; in g_cache_start()
390 sc->sc_wrotebytes += bp->bio_length; in g_cache_start()
399 cbp->bio_done = g_std_done; in g_cache_start()
401 g_io_request(cbp, LIST_FIRST(&gp->consumer)); in g_cache_start()
411 mtx_assert(&sc->sc_mtx, MA_OWNED); in g_cache_go()
415 LIST_FOREACH(dp, &sc->sc_desclist[i], d_next) { in g_cache_go()
416 if (dp->d_flags & D_FLAG_USED || in g_cache_go()
417 dp->d_biolist != NULL || in g_cache_go()
418 time_uptime - dp->d_atime < g_cache_idletime) in g_cache_go()
420 TAILQ_INSERT_TAIL(&sc->sc_usedlist, dp, d_used); in g_cache_go()
421 sc->sc_nused++; in g_cache_go()
422 dp->d_flags |= D_FLAG_USED; in g_cache_go()
427 if (sc->sc_nused > g_cache_used_hi * sc->sc_maxent / 100) in g_cache_go()
430 callout_reset(&sc->sc_callout, g_cache_timeout * hz, g_cache_go, sc); in g_cache_go()
436 struct g_geom *gp; in g_cache_access() local
440 gp = pp->geom; in g_cache_access()
441 cp = LIST_FIRST(&gp->consumer); in g_cache_access()
452 g_cache_destroy(cp->geom->softc, 1); in g_cache_orphan()
458 struct g_geom *gp; in g_cache_find_device() local
460 LIST_FOREACH(gp, &mp->geom, geom) { in g_cache_find_device()
461 if (strcmp(gp->name, name) == 0) in g_cache_find_device()
462 return (gp->softc); in g_cache_find_device()
472 struct g_geom *gp; in g_cache_create() local
480 gp = NULL; in g_cache_create()
484 G_CACHE_DEBUG(1, "Creating device %s.", md->md_name); in g_cache_create()
487 if (md->md_size < 100) { in g_cache_create()
488 G_CACHE_DEBUG(0, "Invalid size for device %s.", md->md_name); in g_cache_create()
493 bshift = ffs(md->md_bsize) - 1; in g_cache_create()
494 if (md->md_bsize == 0 || md->md_bsize > maxphys || in g_cache_create()
495 md->md_bsize != 1 << bshift || in g_cache_create()
496 (md->md_bsize % pp->sectorsize) != 0) { in g_cache_create()
497 G_CACHE_DEBUG(0, "Invalid blocksize for provider %s.", pp->name); in g_cache_create()
502 if (g_cache_find_device(mp, (const char *)&md->md_name) != NULL) { in g_cache_create()
503 G_CACHE_DEBUG(0, "Provider %s already exists.", md->md_name); in g_cache_create()
507 gp = g_new_geom(mp, md->md_name); in g_cache_create()
509 sc->sc_type = type; in g_cache_create()
510 sc->sc_bshift = bshift; in g_cache_create()
511 sc->sc_bsize = 1 << bshift; in g_cache_create()
512 sc->sc_zone = uma_zcreate("gcache", sc->sc_bsize, NULL, NULL, NULL, NULL, in g_cache_create()
514 mtx_init(&sc->sc_mtx, "GEOM CACHE mutex", NULL, MTX_DEF); in g_cache_create()
516 LIST_INIT(&sc->sc_desclist[i]); in g_cache_create()
517 TAILQ_INIT(&sc->sc_usedlist); in g_cache_create()
518 sc->sc_maxent = md->md_size; in g_cache_create()
519 callout_init_mtx(&sc->sc_callout, &sc->sc_mtx, 0); in g_cache_create()
520 gp->softc = sc; in g_cache_create()
521 sc->sc_geom = gp; in g_cache_create()
522 gp->start = g_cache_start; in g_cache_create()
523 gp->orphan = g_cache_orphan; in g_cache_create()
524 gp->access = g_cache_access; in g_cache_create()
525 gp->dumpconf = g_cache_dumpconf; in g_cache_create()
527 newpp = g_new_providerf(gp, "cache/%s", gp->name); in g_cache_create()
528 newpp->sectorsize = pp->sectorsize; in g_cache_create()
529 newpp->mediasize = pp->mediasize; in g_cache_create()
531 newpp->mediasize -= pp->sectorsize; in g_cache_create()
532 sc->sc_tail = BNO2OFF(OFF2BNO(newpp->mediasize, sc), sc); in g_cache_create()
534 cp = g_new_consumer(gp); in g_cache_create()
536 G_CACHE_DEBUG(0, "Cannot attach to provider %s.", pp->name); in g_cache_create()
539 mtx_destroy(&sc->sc_mtx); in g_cache_create()
541 g_destroy_geom(gp); in g_cache_create()
546 G_CACHE_DEBUG(0, "Device %s created.", gp->name); in g_cache_create()
547 callout_reset(&sc->sc_callout, g_cache_timeout * hz, g_cache_go, sc); in g_cache_create()
548 return (gp); in g_cache_create()
554 struct g_geom *gp; in g_cache_destroy() local
562 gp = sc->sc_geom; in g_cache_destroy()
563 pp = LIST_FIRST(&gp->provider); in g_cache_destroy()
564 if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { in g_cache_destroy()
567 "can't be definitely removed.", pp->name); in g_cache_destroy()
570 pp->name, pp->acr, pp->acw, pp->ace); in g_cache_destroy()
574 G_CACHE_DEBUG(0, "Device %s removed.", gp->name); in g_cache_destroy()
576 callout_drain(&sc->sc_callout); in g_cache_destroy()
577 mtx_lock(&sc->sc_mtx); in g_cache_destroy()
579 dp = LIST_FIRST(&sc->sc_desclist[i]); in g_cache_destroy()
586 mtx_unlock(&sc->sc_mtx); in g_cache_destroy()
587 mtx_destroy(&sc->sc_mtx); in g_cache_destroy()
588 uma_zdestroy(sc->sc_zone); in g_cache_destroy()
590 gp->softc = NULL; in g_cache_destroy()
591 g_wither_geom(gp, ENXIO); in g_cache_destroy()
597 g_cache_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) in g_cache_destroy_geom() argument
600 return (g_cache_destroy(gp->softc, 0)); in g_cache_destroy_geom()
615 pp = cp->provider; in g_cache_read_metadata()
617 buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, in g_cache_read_metadata()
620 g_access(cp, -1, 0, 0); in g_cache_read_metadata()
643 pp = cp->provider; in g_cache_write_metadata()
644 buf = malloc((size_t)pp->sectorsize, M_GCACHE, M_WAITOK | M_ZERO); in g_cache_write_metadata()
647 error = g_write_data(cp, pp->mediasize - pp->sectorsize, buf, pp->sectorsize); in g_cache_write_metadata()
649 g_access(cp, 0, -1, 0); in g_cache_write_metadata()
660 struct g_geom *gp; in g_cache_taste() local
663 g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); in g_cache_taste()
666 G_CACHE_DEBUG(3, "Tasting %s.", pp->name); in g_cache_taste()
668 gp = g_new_geom(mp, "cache:taste"); in g_cache_taste()
669 gp->start = g_cache_start; in g_cache_taste()
670 gp->orphan = g_cache_orphan; in g_cache_taste()
671 gp->access = g_cache_access; in g_cache_taste()
672 cp = g_new_consumer(gp); in g_cache_taste()
673 cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; in g_cache_taste()
680 g_destroy_geom(gp); in g_cache_taste()
688 pp->name); in g_cache_taste()
691 if (md.md_provsize != pp->mediasize) in g_cache_taste()
694 gp = g_cache_create(mp, pp, &md, G_CACHE_TYPE_AUTOMATIC); in g_cache_taste()
695 if (gp == NULL) { in g_cache_taste()
699 return (gp); in g_cache_taste()
707 struct g_geom *gp; in g_cache_ctl_create() local
761 gp = g_cache_create(mp, pp, &md, G_CACHE_TYPE_MANUAL); in g_cache_ctl_create()
762 if (gp == NULL) { in g_cache_ctl_create()
812 sc->sc_maxent = (u_int)*size; in g_cache_ctl_configure()
824 if (sc->sc_type != G_CACHE_TYPE_AUTOMATIC) in g_cache_ctl_configure()
833 md.md_size = sc->sc_maxent; in g_cache_ctl_configure()
837 md.md_bsize = sc->sc_bsize; in g_cache_ctl_configure()
838 cp = LIST_FIRST(&sc->sc_geom->consumer); in g_cache_ctl_configure()
839 md.md_provsize = cp->provider->mediasize; in g_cache_ctl_configure()
842 G_CACHE_DEBUG(2, "Metadata on %s updated.", cp->provider->name); in g_cache_ctl_configure()
845 cp->provider->name, error); in g_cache_ctl_configure()
889 sc->sc_name, error); in g_cache_ctl_destroy()
928 sc->sc_reads = 0; in g_cache_ctl_reset()
929 sc->sc_readbytes = 0; in g_cache_ctl_reset()
930 sc->sc_cachereads = 0; in g_cache_ctl_reset()
931 sc->sc_cachereadbytes = 0; in g_cache_ctl_reset()
932 sc->sc_cachehits = 0; in g_cache_ctl_reset()
933 sc->sc_cachemisses = 0; in g_cache_ctl_reset()
934 sc->sc_cachefull = 0; in g_cache_ctl_reset()
935 sc->sc_writes = 0; in g_cache_ctl_reset()
936 sc->sc_wrotebytes = 0; in g_cache_ctl_reset()
976 g_cache_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, in g_cache_dumpconf() argument
983 sc = gp->softc; in g_cache_dumpconf()
984 sbuf_printf(sb, "%s<Size>%u</Size>\n", indent, sc->sc_maxent); in g_cache_dumpconf()
985 sbuf_printf(sb, "%s<BlockSize>%u</BlockSize>\n", indent, sc->sc_bsize); in g_cache_dumpconf()
987 (uintmax_t)sc->sc_tail); in g_cache_dumpconf()
988 sbuf_printf(sb, "%s<Entries>%u</Entries>\n", indent, sc->sc_nent); in g_cache_dumpconf()
990 sc->sc_nused); in g_cache_dumpconf()
992 sc->sc_invalid); in g_cache_dumpconf()
993 sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads); in g_cache_dumpconf()
995 sc->sc_readbytes); in g_cache_dumpconf()
997 sc->sc_cachereads); in g_cache_dumpconf()
999 sc->sc_cachereadbytes); in g_cache_dumpconf()
1001 sc->sc_cachehits); in g_cache_dumpconf()
1003 sc->sc_cachemisses); in g_cache_dumpconf()
1005 sc->sc_cachefull); in g_cache_dumpconf()
1006 sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes); in g_cache_dumpconf()
1008 sc->sc_wrotebytes); in g_cache_dumpconf()