<commit_before>/* $Id$ */
/*
 * %PSC_START_COPYRIGHT%
 * -----------------------------------------------------------------------------
 * Copyright (c) 2011-2012, Pittsburgh Supercomputing Center (PSC).
 *
 * Permission to use, copy, and modify this software and its documentation
 * without fee for personal use or non-commercial use within your organization
 * is hereby granted, provided that the above copyright notice is preserved in
 * all copies and that the copyright and this permission notice appear in
 * supporting documentation.  Permission to redistribute this software to other
 * organizations or individuals is not permitted without the written permission
 * of the Pittsburgh Supercomputing Center.  PSC makes no representations about
 * the suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 * -----------------------------------------------------------------------------
 * %PSC_END_COPYRIGHT%
 */

#define PSC_SUBSYS SLSS_FCMH
#include "slsubsys.h"

#include "pfl/cdefs.h"
#include "pfl/fs.h"

#include "bmap_mds.h"
#include "fidc_mds.h"
#include "inode.h"
#include "journal_mds.h"
#include "mdsio.h"
#include "mdslog.h"
#include "slashd.h"
#include "slerr.h"

#include "zfs-fuse/zfs_slashlib.h"

int
mds_inode_dump(int vfsid, struct sl_ino_compat *sic,
    struct slash_inode_handle *ih, void *readh)
{
	struct fidc_membh *f;
	struct bmapc_memb *b;
	sl_bmapno_t i;
	int rc, fl;
	void *th;

	f = ih->inoh_fcmh;
	th = inoh_2_mdsio_data(ih);

	fl = BMAPGETF_LOAD | BMAPGETF_NOAUTOINST;
	if (sic)
		fl |= BMAPGETF_NORETRIEVE;

	for (i = 0; ; i++) {
		inoh_2_mdsio_data(ih) = readh;
		rc = bmap_getf(f, i, SL_WRITE, fl, &b);
		inoh_2_mdsio_data(ih) = th;

		if (rc == SLERR_BMAP_INVALID) {
			(void)INOH_RLOCK(ih);
			break;
		}

		if (rc)
			return (rc);

		if (sic) {
			rc = sic->sic_read_bmap(b, readh);
			if (rc) {
				bmap_op_done(b);
				(void)INOH_RLOCK(ih);
				if (rc == SLERR_BMAP_INVALID)
					break;
				return (rc);
			}
		}

		rc = mds_bmap_write(b, 0, NULL, NULL);
		bmap_op_done(b);
		(void)INOH_RLOCK(ih);
		if (rc)
			return (rc);
	}

	rc = mds_inox_write(vfsid, ih, NULL, NULL);
	if (rc)
		return (rc);

	rc = mds_inode_write(vfsid, ih, NULL, NULL);
	if (rc)
		return (rc);

	mdsio_fsync(vfsid, &rootcreds, 1, th);
	return (0);
}

int
mds_inode_update(int vfsid, struct slash_inode_handle *ih,
    int old_version)
{
	char fn[NAME_MAX + 1];
	struct sl_ino_compat *sic;
	struct fidc_membh *f;
	struct srt_stat sstb;
	void *h = NULL, *th;
	int rc;

	sic = &sl_ino_compat_table[old_version];
	rc = sic->sic_read_ino(ih);
	if (rc)
		return (rc);
	DEBUG_INOH(PLL_INFO, ih, "updating old inode (v %d)",
	    old_version);

	f = ih->inoh_fcmh;
	snprintf(fn, sizeof(fn), "%016"PRIx64".update", fcmh_2_fid(f));
	rc = mdsio_opencreatef(vfsid, mds_tmpdir_inum[vfsid],
	    &rootcreds, O_RDWR | O_CREAT | O_TRUNC,
	    MDSIO_OPENCRF_NOLINK, 0644, fn, NULL, NULL, &h, NULL, NULL,
	    0);
	if (rc)
		PFL_GOTOERR(out, rc);

	psc_assert(ih->inoh_extras == NULL);
	ih->inoh_extras = PSCALLOC(INOX_SZ);
	ih->inoh_flags |= INOH_HAVE_EXTRAS;

	/* convert old structures into new into temp file */
	rc = sic->sic_read_inox(ih);
	if (rc)
		PFL_GOTOERR(out, rc);

	th = inoh_2_mdsio_data(ih);
	inoh_2_mdsio_data(ih) = h;
	rc = mds_inode_dump(vfsid, sic, ih, th);
	inoh_2_mdsio_data(ih) = th;
	if (rc)
		PFL_GOTOERR(out, rc);

	/* move new structures to inode meta file */
	memset(&sstb, 0, sizeof(sstb));
	rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE,
	    &rootcreds, NULL, th, NULL);
	if (rc)
		PFL_GOTOERR(out, rc);

//	mdsio_rename(mds_tmpdir_inum, NULL, fn, &rootcreds, NULL);
	rc = mds_inode_dump(vfsid, NULL, ih, h);
	if (rc)
		PFL_GOTOERR(out, rc);

	mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
	    &rootcreds, NULL, NULL);

 out:
	if (h)
		mdsio_release(vfsid, &rootcreds, h);
	if (rc) {
		mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
		    &rootcreds, NULL, NULL);
		DEBUG_INOH(PLL_ERROR, ih, "error updating old inode "
		    "rc=%d", rc);
	}
	return (rc);
}

int
mds_inode_update_interrupted(int vfsid, struct slash_inode_handle *ih,
    int *rc)
{
	char fn[NAME_MAX + 1];
	struct fidc_membh *f;
	struct srt_stat sstb;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	void *h = NULL, *th;
	mdsio_fid_t inum;
	int exists = 0;
	size_t nb;

	f = ih->inoh_fcmh;
	th = inoh_2_mdsio_data(ih);

	snprintf(fn, sizeof(fn), "%016"PRIx64".update",
	    fcmh_2_fid(ih->inoh_fcmh));

	*rc = mdsio_lookup(vfsid, mds_tmpdir_inum[vfsid], fn, &inum,
	    &rootcreds, NULL);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	*rc = mdsio_opencreatef(vfsid, inum, &rootcreds, O_RDONLY,
	    MDSIO_OPENCRF_NOLINK, 0644, NULL, NULL, NULL, &h, NULL,
	    NULL, 0);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	iovs[0].iov_base = &ih->inoh_ino;
	iovs[0].iov_len = sizeof(ih->inoh_ino);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);
	*rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0, h);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	psc_crc64_calc(&crc, &ih->inoh_ino, sizeof(ih->inoh_ino));
	if (crc != od_crc) {
		*rc = SLERR_BADCRC;
		PFL_GOTOERR(out, *rc);
	}

	exists = 1;

	psc_assert(ih->inoh_extras == NULL);
	ih->inoh_extras = PSCALLOC(INOX_SZ);
	ih->inoh_flags |= INOH_HAVE_EXTRAS;

	inoh_2_mdsio_data(ih) = h;
	*rc = mds_inox_ensure_loaded(ih);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	inoh_2_mdsio_data(ih) = th;

	memset(&sstb, 0, sizeof(sstb));
	*rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE,
	    &rootcreds, NULL, th, NULL);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	*rc = mds_inode_dump(vfsid, NULL, ih, h);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
	    &rootcreds, NULL, NULL);

 out:
	if (h)
		mdsio_release(vfsid, &rootcreds, h);
	if (*rc)
		mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
		    &rootcreds, NULL, NULL);
	inoh_2_mdsio_data(ih) = th;
	return (exists);
}

int
mds_ino_read_v1(struct slash_inode_handle *ih)
{
	struct {
		uint16_t	version;
		uint16_t	flags;
		uint32_t	bsz;
		uint32_t	nrepls;
		uint32_t	replpol;
		sl_replica_t	repls[4];
	} ino;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb;

	iovs[0].iov_base = &ino;
	iovs[0].iov_len = sizeof(ino);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);

	f = ih->inoh_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0,
	    inoh_2_mdsio_data(ih));

	if (rc)
		return (rc);
	if (nb != sizeof(ino) + sizeof(od_crc))
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &ino, sizeof(ino));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	ih->inoh_ino.ino_version = INO_VERSION;
	ih->inoh_ino.ino_bsz = ino.bsz;
	ih->inoh_ino.ino_nrepls = ino.nrepls;
	ih->inoh_ino.ino_replpol = ino.replpol;
	for (i = 0; i < 4; i++)
		ih->inoh_ino.ino_repls[i] = ino.repls[i];
	return (0);
}

int
mds_inox_read_v1(struct slash_inode_handle *ih)
{
	struct {
		sl_snap_t	snaps[1];
		sl_replica_t	repls[60];
	} inox;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb;

	memset(&inox, 0, sizeof(inox));

	iovs[0].iov_base = &inox;
	iovs[0].iov_len = sizeof(inox);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);

	f = ih->inoh_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb,
	    0x400, inoh_2_mdsio_data(ih));

	if (rc)
		return (rc);
	if (pfl_memchk(&inox, 0, sizeof(inox)) && od_crc == 0)
		return (0);
	if (nb != sizeof(inox) + sizeof(od_crc))
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &inox, sizeof(inox));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	for (i = 0; i < 60; i++)
		ih->inoh_extras->inox_repls[i] = inox.repls[i];
	return (0);
}

int
mds_bmap_read_v1(struct bmapc_memb *b, void *readh)
{
	struct {
		uint8_t		crcstates[128];
		uint8_t		repls[24];
		uint64_t	crcs[128];
		uint32_t	gen;
		uint32_t	replpol;
	} bod;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb, bsz;

	bsz = sizeof(bod) + sizeof(crc);

	iovs[0].iov_base = &bod;
	iovs[0].iov_len = sizeof(bod);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);
	f = b->bcm_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb,
	    bsz * b->bcm_bmapno + 0x1000, readh);

	if (rc)
		return (rc);
	if (nb == 0)
		return (SLERR_BMAP_INVALID);
	if (nb != bsz)
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &bod, sizeof(bod));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	for (i = 0; i < 128; i++)
		b->bcm_crcstates[i] = bod.crcstates[i];
	for (i = 0; i < 24; i++)
		b->bcm_repls[i] = bod.repls[i];
	for (i = 0; i < 128; i++)
		bmap_2_crcs(b, i) = bod.crcs[i];
	bmap_2_bgen(b) = bod.gen;
	bmap_2_replpol(b) = bod.replpol;
	return (0);
}

struct sl_ino_compat sl_ino_compat_table[] = {
/* 0 */	{ NULL, NULL, NULL },
/* 1 */	{ mds_ino_read_v1, mds_inox_read_v1, mds_bmap_read_v1 },
/* 2 */	{ NULL, NULL, NULL }
};
<commit_msg>unused<commit_after>/* $Id$ */
/*
 * %PSC_START_COPYRIGHT%
 * -----------------------------------------------------------------------------
 * Copyright (c) 2011-2012, Pittsburgh Supercomputing Center (PSC).
 *
 * Permission to use, copy, and modify this software and its documentation
 * without fee for personal use or non-commercial use within your organization
 * is hereby granted, provided that the above copyright notice is preserved in
 * all copies and that the copyright and this permission notice appear in
 * supporting documentation.  Permission to redistribute this software to other
 * organizations or individuals is not permitted without the written permission
 * of the Pittsburgh Supercomputing Center.  PSC makes no representations about
 * the suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 * -----------------------------------------------------------------------------
 * %PSC_END_COPYRIGHT%
 */

#define PSC_SUBSYS SLSS_FCMH
#include "slsubsys.h"

#include "pfl/cdefs.h"
#include "pfl/fs.h"

#include "bmap_mds.h"
#include "fidc_mds.h"
#include "inode.h"
#include "journal_mds.h"
#include "mdsio.h"
#include "mdslog.h"
#include "slashd.h"
#include "slerr.h"

#include "zfs-fuse/zfs_slashlib.h"

int
mds_inode_dump(int vfsid, struct sl_ino_compat *sic,
    struct slash_inode_handle *ih, void *readh)
{
	struct fidc_membh *f;
	struct bmapc_memb *b;
	sl_bmapno_t i;
	int rc, fl;
	void *th;

	f = ih->inoh_fcmh;
	th = inoh_2_mdsio_data(ih);

	fl = BMAPGETF_LOAD | BMAPGETF_NOAUTOINST;
	if (sic)
		fl |= BMAPGETF_NORETRIEVE;

	for (i = 0; ; i++) {
		inoh_2_mdsio_data(ih) = readh;
		rc = bmap_getf(f, i, SL_WRITE, fl, &b);
		inoh_2_mdsio_data(ih) = th;

		if (rc == SLERR_BMAP_INVALID) {
			(void)INOH_RLOCK(ih);
			break;
		}

		if (rc)
			return (rc);

		if (sic) {
			rc = sic->sic_read_bmap(b, readh);
			if (rc) {
				bmap_op_done(b);
				(void)INOH_RLOCK(ih);
				if (rc == SLERR_BMAP_INVALID)
					break;
				return (rc);
			}
		}

		rc = mds_bmap_write(b, 0, NULL, NULL);
		bmap_op_done(b);
		(void)INOH_RLOCK(ih);
		if (rc)
			return (rc);
	}

	rc = mds_inox_write(vfsid, ih, NULL, NULL);
	if (rc)
		return (rc);

	rc = mds_inode_write(vfsid, ih, NULL, NULL);
	if (rc)
		return (rc);

	mdsio_fsync(vfsid, &rootcreds, 1, th);
	return (0);
}

int
mds_inode_update(int vfsid, struct slash_inode_handle *ih,
    int old_version)
{
	char fn[NAME_MAX + 1];
	struct sl_ino_compat *sic;
	struct fidc_membh *f;
	struct srt_stat sstb;
	void *h = NULL, *th;
	int rc;

	sic = &sl_ino_compat_table[old_version];
	rc = sic->sic_read_ino(ih);
	if (rc)
		return (rc);
	DEBUG_INOH(PLL_INFO, ih, "updating old inode (v %d)",
	    old_version);

	f = ih->inoh_fcmh;
	snprintf(fn, sizeof(fn), "%016"PRIx64".update", fcmh_2_fid(f));
	rc = mdsio_opencreatef(vfsid, mds_tmpdir_inum[vfsid],
	    &rootcreds, O_RDWR | O_CREAT | O_TRUNC,
	    MDSIO_OPENCRF_NOLINK, 0644, fn, NULL, NULL, &h, NULL, NULL,
	    0);
	if (rc)
		PFL_GOTOERR(out, rc);

	psc_assert(ih->inoh_extras == NULL);
	ih->inoh_extras = PSCALLOC(INOX_SZ);
	ih->inoh_flags |= INOH_HAVE_EXTRAS;

	/* convert old structures into new into temp file */
	rc = sic->sic_read_inox(ih);
	if (rc)
		PFL_GOTOERR(out, rc);

	th = inoh_2_mdsio_data(ih);
	inoh_2_mdsio_data(ih) = h;
	rc = mds_inode_dump(vfsid, sic, ih, th);
	inoh_2_mdsio_data(ih) = th;
	if (rc)
		PFL_GOTOERR(out, rc);

	/* move new structures to inode meta file */
	memset(&sstb, 0, sizeof(sstb));
	rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE,
	    &rootcreds, NULL, th, NULL);
	if (rc)
		PFL_GOTOERR(out, rc);

//	mdsio_rename(mds_tmpdir_inum, NULL, fn, &rootcreds, NULL);
	rc = mds_inode_dump(vfsid, NULL, ih, h);
	if (rc)
		PFL_GOTOERR(out, rc);

	mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
	    &rootcreds, NULL, NULL);

 out:
	if (h)
		mdsio_release(vfsid, &rootcreds, h);
	if (rc) {
		mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
		    &rootcreds, NULL, NULL);
		DEBUG_INOH(PLL_ERROR, ih, "error updating old inode "
		    "rc=%d", rc);
	}
	return (rc);
}

int
mds_inode_update_interrupted(int vfsid, struct slash_inode_handle *ih,
    int *rc)
{
	char fn[NAME_MAX + 1];
	struct srt_stat sstb;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	void *h = NULL, *th;
	mdsio_fid_t inum;
	int exists = 0;
	size_t nb;

	th = inoh_2_mdsio_data(ih);

	snprintf(fn, sizeof(fn), "%016"PRIx64".update",
	    fcmh_2_fid(ih->inoh_fcmh));

	*rc = mdsio_lookup(vfsid, mds_tmpdir_inum[vfsid], fn, &inum,
	    &rootcreds, NULL);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	*rc = mdsio_opencreatef(vfsid, inum, &rootcreds, O_RDONLY,
	    MDSIO_OPENCRF_NOLINK, 0644, NULL, NULL, NULL, &h, NULL,
	    NULL, 0);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	iovs[0].iov_base = &ih->inoh_ino;
	iovs[0].iov_len = sizeof(ih->inoh_ino);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);
	*rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0, h);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	psc_crc64_calc(&crc, &ih->inoh_ino, sizeof(ih->inoh_ino));
	if (crc != od_crc) {
		*rc = SLERR_BADCRC;
		PFL_GOTOERR(out, *rc);
	}

	exists = 1;

	psc_assert(ih->inoh_extras == NULL);
	ih->inoh_extras = PSCALLOC(INOX_SZ);
	ih->inoh_flags |= INOH_HAVE_EXTRAS;

	inoh_2_mdsio_data(ih) = h;
	*rc = mds_inox_ensure_loaded(ih);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	inoh_2_mdsio_data(ih) = th;

	memset(&sstb, 0, sizeof(sstb));
	*rc = mdsio_setattr(vfsid, 0, &sstb, SL_SETATTRF_METASIZE,
	    &rootcreds, NULL, th, NULL);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	*rc = mds_inode_dump(vfsid, NULL, ih, h);
	if (*rc)
		PFL_GOTOERR(out, *rc);

	mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
	    &rootcreds, NULL, NULL);

 out:
	if (h)
		mdsio_release(vfsid, &rootcreds, h);
	if (*rc)
		mdsio_unlink(vfsid, mds_tmpdir_inum[vfsid], NULL, fn,
		    &rootcreds, NULL, NULL);
	inoh_2_mdsio_data(ih) = th;
	return (exists);
}

int
mds_ino_read_v1(struct slash_inode_handle *ih)
{
	struct {
		uint16_t	version;
		uint16_t	flags;
		uint32_t	bsz;
		uint32_t	nrepls;
		uint32_t	replpol;
		sl_replica_t	repls[4];
	} ino;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb;

	iovs[0].iov_base = &ino;
	iovs[0].iov_len = sizeof(ino);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);

	f = ih->inoh_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0,
	    inoh_2_mdsio_data(ih));

	if (rc)
		return (rc);
	if (nb != sizeof(ino) + sizeof(od_crc))
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &ino, sizeof(ino));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	ih->inoh_ino.ino_version = INO_VERSION;
	ih->inoh_ino.ino_bsz = ino.bsz;
	ih->inoh_ino.ino_nrepls = ino.nrepls;
	ih->inoh_ino.ino_replpol = ino.replpol;
	for (i = 0; i < 4; i++)
		ih->inoh_ino.ino_repls[i] = ino.repls[i];
	return (0);
}

int
mds_inox_read_v1(struct slash_inode_handle *ih)
{
	struct {
		sl_snap_t	snaps[1];
		sl_replica_t	repls[60];
	} inox;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb;

	memset(&inox, 0, sizeof(inox));

	iovs[0].iov_base = &inox;
	iovs[0].iov_len = sizeof(inox);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);

	f = ih->inoh_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb,
	    0x400, inoh_2_mdsio_data(ih));

	if (rc)
		return (rc);
	if (pfl_memchk(&inox, 0, sizeof(inox)) && od_crc == 0)
		return (0);
	if (nb != sizeof(inox) + sizeof(od_crc))
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &inox, sizeof(inox));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	for (i = 0; i < 60; i++)
		ih->inoh_extras->inox_repls[i] = inox.repls[i];
	return (0);
}

int
mds_bmap_read_v1(struct bmapc_memb *b, void *readh)
{
	struct {
		uint8_t		crcstates[128];
		uint8_t		repls[24];
		uint64_t	crcs[128];
		uint32_t	gen;
		uint32_t	replpol;
	} bod;
	struct fidc_membh *f;
	struct iovec iovs[2];
	uint64_t crc, od_crc;
	int i, rc, vfsid;
	size_t nb, bsz;

	bsz = sizeof(bod) + sizeof(crc);

	iovs[0].iov_base = &bod;
	iovs[0].iov_len = sizeof(bod);
	iovs[1].iov_base = &od_crc;
	iovs[1].iov_len = sizeof(od_crc);
	f = b->bcm_fcmh;
	mdsio_fid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb,
	    bsz * b->bcm_bmapno + 0x1000, readh);

	if (rc)
		return (rc);
	if (nb == 0)
		return (SLERR_BMAP_INVALID);
	if (nb != bsz)
		return (SLERR_SHORTIO);

	psc_crc64_calc(&crc, &bod, sizeof(bod));
	if (crc != od_crc)
		return (SLERR_BADCRC);
	for (i = 0; i < 128; i++)
		b->bcm_crcstates[i] = bod.crcstates[i];
	for (i = 0; i < 24; i++)
		b->bcm_repls[i] = bod.repls[i];
	for (i = 0; i < 128; i++)
		bmap_2_crcs(b, i) = bod.crcs[i];
	bmap_2_bgen(b) = bod.gen;
	bmap_2_replpol(b) = bod.replpol;
	return (0);
}

struct sl_ino_compat sl_ino_compat_table[] = {
/* 0 */	{ NULL, NULL, NULL },
/* 1 */	{ mds_ino_read_v1, mds_inox_read_v1, mds_bmap_read_v1 },
/* 2 */	{ NULL, NULL, NULL }
};

{'fraction_non_alphanumeric': 0.1687796273839709, 'fraction_numerical': 0.018741042883915777, 'mean_word_length': 3.938214480130648, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 62, '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': '615437', 'n_tokens_mistral': 9231, 'n_tokens_neox': 8710, 'n_words': 1757}