<commit_before>/*-
 * Copyright (c) 2004 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/bio.h>
#include <sys/conf.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>

#include <geom/geom.h>
#include <geom/vinum/geom_vinum_var.h>
#include <geom/vinum/geom_vinum_raid5.h>
#include <geom/vinum/geom_vinum.h>

int	gv_raid5_parity(struct gv_raid5_packet *);
int	gv_stripe_active(struct gv_raid5_packet *, struct gv_plex *);

struct gv_raid5_bit *
gv_new_raid5_bit(void)
{
	struct gv_raid5_bit *r;
	r = g_malloc(sizeof(*r), M_NOWAIT | M_ZERO);
	KASSERT(r != NULL, ("gv_new_raid5_bit: NULL r"));
	return (r);
}

struct gv_raid5_packet *
gv_new_raid5_packet(void)
{
	struct gv_raid5_packet *wp;

	wp = g_malloc(sizeof(*wp), M_NOWAIT | M_ZERO);
	KASSERT(wp != NULL, ("gv_new_raid5_packet: NULL wp"));
	wp->state = SETUP;
	wp->type = JUNK;
	TAILQ_INIT(&wp->bits);

	return (wp);
}

/*
 * Check if the stripe that the work packet wants is already being used by
 * some other work packet.
 */
int
gv_stripe_active(struct gv_raid5_packet *wp, struct gv_plex *sc)
{
	struct gv_raid5_packet *wpa;

	TAILQ_FOREACH(wpa, &sc->worklist, list) {
		if (wpa->lockbase == wp->lockbase) {
			if (wpa->bio == wp->bio)
				return (0);
			return (1);
		}
	}
	return (0);
}

/*
 * The "worker" thread that runs through the worklist and fires off the
 * "subrequests" needed to fulfill a RAID5 read or write request.
 */
void
gv_raid5_worker(void *arg)
{
	struct bio *bp;
	struct g_geom *gp;
	struct gv_plex *p;
	struct gv_raid5_packet *wp, *wpt;
	struct gv_raid5_bit *rbp, *rbpt;
	int error, restart;

	gp = arg;
	p = gp->softc;

	mtx_lock(&p->worklist_mtx);
	for (;;) {
		restart = 0;
		g_trace(G_T_TOPOLOGY, "gv_raid5_worker scan");
		TAILQ_FOREACH_SAFE(wp, &p->worklist, list, wpt) {
			/* This request packet is already being processed. */
			if (wp->state == IO)
				continue;
			/* This request packet is ready for processing. */
			if (wp->state == VALID) {
				/* Couldn't get the lock, try again. */
				if ((wp->lockbase != -1) &&
				    gv_stripe_active(wp, p))
					continue;

				wp->state = IO;
				mtx_unlock(&p->worklist_mtx);
				TAILQ_FOREACH_SAFE(rbp, &wp->bits, list, rbpt)
					g_io_request(rbp->bio, rbp->consumer);
				mtx_lock(&p->worklist_mtx);
				continue;
			}
			if (wp->state == FINISH) {
				bp = wp->bio;
				bp->bio_completed += wp->length;
				/*
				 * Deliver the original request if we have
				 * finished.
				 */
				if (bp->bio_completed == bp->bio_length) {
					mtx_unlock(&p->worklist_mtx);
					g_io_deliver(bp, 0);
					mtx_lock(&p->worklist_mtx);
				}
				TAILQ_REMOVE(&p->worklist, wp, list);
				if (wp->bufmalloc == 1)
					g_free(wp->buf);
				g_free(wp);
				restart++;
				/*break;*/
			}
		}
		if (!restart) {
			/* Self-destruct. */
			if (p->flags & GV_PLEX_THREAD_DIE)
				break;
			g_trace(G_T_TOPOLOGY, "gv_raid5_worker sleep");
			error = msleep(p, &p->worklist_mtx, PRIBIO, "-",
			    hz/100);
		}
	}
	mtx_unlock(&p->worklist_mtx);

	g_trace(G_T_TOPOLOGY, "gv_raid5_worker die");

	/* Signal our plex that we are dead. */
	p->flags |= GV_PLEX_THREAD_DEAD;
	wakeup(p);
	kthread_exit(0);
}

/* Final bio transaction to write out the parity data. */
int
gv_raid5_parity(struct gv_raid5_packet *wp)
{<commit_msg>Remove two debugging printfs that are currently rather disturbing than helpful.<commit_after>/*-
 * Copyright (c) 2004 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/bio.h>
#include <sys/conf.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>

#include <geom/geom.h>
#include <geom/vinum/geom_vinum_var.h>
#include <geom/vinum/geom_vinum_raid5.h>
#include <geom/vinum/geom_vinum.h>

int	gv_raid5_parity(struct gv_raid5_packet *);
int	gv_stripe_active(struct gv_raid5_packet *, struct gv_plex *);

struct gv_raid5_bit *
gv_new_raid5_bit(void)
{
	struct gv_raid5_bit *r;
	r = g_malloc(sizeof(*r), M_NOWAIT | M_ZERO);
	KASSERT(r != NULL, ("gv_new_raid5_bit: NULL r"));
	return (r);
}

struct gv_raid5_packet *
gv_new_raid5_packet(void)
{
	struct gv_raid5_packet *wp;

	wp = g_malloc(sizeof(*wp), M_NOWAIT | M_ZERO);
	KASSERT(wp != NULL, ("gv_new_raid5_packet: NULL wp"));
	wp->state = SETUP;
	wp->type = JUNK;
	TAILQ_INIT(&wp->bits);

	return (wp);
}

/*
 * Check if the stripe that the work packet wants is already being used by
 * some other work packet.
 */
int
gv_stripe_active(struct gv_raid5_packet *wp, struct gv_plex *sc)
{
	struct gv_raid5_packet *wpa;

	TAILQ_FOREACH(wpa, &sc->worklist, list) {
		if (wpa->lockbase == wp->lockbase) {
			if (wpa->bio == wp->bio)
				return (0);
			return (1);
		}
	}
	return (0);
}

/*
 * The "worker" thread that runs through the worklist and fires off the
 * "subrequests" needed to fulfill a RAID5 read or write request.
 */
void
gv_raid5_worker(void *arg)
{
	struct bio *bp;
	struct g_geom *gp;
	struct gv_plex *p;
	struct gv_raid5_packet *wp, *wpt;
	struct gv_raid5_bit *rbp, *rbpt;
	int error, restart;

	gp = arg;
	p = gp->softc;

	mtx_lock(&p->worklist_mtx);
	for (;;) {
		restart = 0;
		TAILQ_FOREACH_SAFE(wp, &p->worklist, list, wpt) {
			/* This request packet is already being processed. */
			if (wp->state == IO)
				continue;
			/* This request packet is ready for processing. */
			if (wp->state == VALID) {
				/* Couldn't get the lock, try again. */
				if ((wp->lockbase != -1) &&
				    gv_stripe_active(wp, p))
					continue;

				wp->state = IO;
				mtx_unlock(&p->worklist_mtx);
				TAILQ_FOREACH_SAFE(rbp, &wp->bits, list, rbpt)
					g_io_request(rbp->bio, rbp->consumer);
				mtx_lock(&p->worklist_mtx);
				continue;
			}
			if (wp->state == FINISH) {
				bp = wp->bio;
				bp->bio_completed += wp->length;
				/*
				 * Deliver the original request if we have
				 * finished.
				 */
				if (bp->bio_completed == bp->bio_length) {
					mtx_unlock(&p->worklist_mtx);
					g_io_deliver(bp, 0);
					mtx_lock(&p->worklist_mtx);
				}
				TAILQ_REMOVE(&p->worklist, wp, list);
				if (wp->bufmalloc == 1)
					g_free(wp->buf);
				g_free(wp);
				restart++;
				/*break;*/
			}
		}
		if (!restart) {
			/* Self-destruct. */
			if (p->flags & GV_PLEX_THREAD_DIE)
				break;
			error = msleep(p, &p->worklist_mtx, PRIBIO, "-",
			    hz/100);
		}
	}
	mtx_unlock(&p->worklist_mtx);

	g_trace(G_T_TOPOLOGY, "gv_raid5_worker die");

	/* Signal our plex that we are dead. */
	p->flags |= GV_PLEX_THREAD_DEAD;
	wakeup(p);
	kthread_exit(0);
}

/* Final bio transaction to write out the parity data. */
int
gv_raid5_parity(struct gv_raid5_packet *wp)
{
{'fraction_non_alphanumeric': 0.12682462449756718, 'fraction_numerical': 0.008250475988999365, 'mean_word_length': 3.7441043652784747, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6254786', 'n_tokens_mistral': 3879, 'n_tokens_neox': 3439, 'n_words': 990}