Exemplo n.º 1
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;
	struct bmap_mds_info *bmi = bmap_2_bmi(b);

	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;
	slfid_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 (PFLERR_BADCRC);
	for (i = 0; i < 128; i++)
		bmi->bmi_crcstates[i] = bod.crcstates[i];
	for (i = 0; i < 24; i++)
		bmi->bmi_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);
}
Exemplo n.º 2
0
/*
 * For the given bmap, change the status of all its replicas marked
 * "valid" to "invalid" except for the replica specified.
 *
 * This is a high-level convenience call provided to easily update
 * status after an ION has received some new I/O, which would make all
 * other existing copies of the bmap on any other replicas old.
 * @b: the bmap.
 * @iosidx: the index of the only ION resource in the inode replica
 *	table that should be marked "valid".
 *
 * Note: All callers must journal log these bmap replica changes
 *	themselves.  In addition, they must log any changes to the inode
 *	_before_ the bmap changes.  Otherwise, we could end up actually
 *	having bmap replicas that are not recognized by the information
 *	stored in the inode during log replay.
 */
int
mds_repl_inv_except(struct bmap *b, int iosidx)
{
	int rc, logit = 0, tract[NBREPLST], retifset[NBREPLST];
	uint32_t policy;

	/* Ensure replica on active IOS is marked valid. */
	brepls_init(tract, -1);
	tract[BREPLST_INVALID] = BREPLST_VALID;
	tract[BREPLST_GARBAGE_SCHED] = BREPLST_VALID;
	tract[BREPLST_GARBAGE_QUEUED] = BREPLST_VALID;

	/*
	 * The old state for this bmap on the given IOS is
	 * either valid or invalid.
	 */
	brepls_init_idx(retifset);
	retifset[BREPLST_INVALID] = 0;
	retifset[BREPLST_VALID] = 0;

	/*
	 * XXX on full truncate, the metafile will exist, which means
	 * the bmap states will exist, which means a new IOS will be
	 * selected which will probably be GARBAGE after truncate
	 * happens a few times.
	 */
	rc = mds_repl_bmap_walk(b, tract, retifset, 0, &iosidx, 1);
	if (rc) {
		psclog_errorx("bcs_repls has active IOS marked in a "
		    "weird state while invalidating other replicas; "
		    "fid="SLPRI_FID" bmap=%d iosidx=%d state=%d",
		    fcmh_2_fid(b->bcm_fcmh), b->bcm_bmapno, iosidx, rc);
	}

	policy = bmap_2_replpol(b);

	/*
	 * Invalidate all other replicas.
	 * Note: if the status is SCHED here, don't do anything; once
	 * the replication status update comes from the ION, we will
	 * know he copied an old bmap and mark it OLD then.
	 */
	brepls_init(tract, -1);
	tract[BREPLST_VALID] = policy == BRPOL_PERSIST ?
	    BREPLST_REPL_QUEUED : BREPLST_GARBAGE_QUEUED;
	tract[BREPLST_REPL_SCHED] = BREPLST_REPL_QUEUED;

	brepls_init(retifset, 0);
	retifset[BREPLST_VALID] = 1;
	retifset[BREPLST_REPL_SCHED] = 1;

	if (_mds_repl_bmap_walk(b, tract, retifset, REPL_WALKF_MODOTH,
	    &iosidx, 1, NULL, NULL)) {
		logit = 1;
		BHGEN_INCREMENT(b);
	}
	if (logit)
		rc = mds_bmap_write_logrepls(b);
	else
		rc = mds_bmap_write(b, NULL, NULL);

	/*
	 * If this bmap is marked for persistent replication, the repl
	 * request must exist and should be marked such that the
	 * replication monitors do not release it in the midst of
	 * processing it as this activity now means they have more to
	 * do.
	 */
	if (policy == BRPOL_PERSIST)
		upsch_enqueue(&bmap_2_bmi(b)->bmi_upd);
	return (rc);
}