Example #1
0
void
slm_fcmh_dtor(struct fidc_membh *f)
{
	struct fcmh_mds_info *fmi;
	int rc, vfsid;

	fmi = fcmh_2_fmi(f);

	if (fcmh_isreg(f)) {
		psc_assert(psc_dynarray_len(&fmi->fmi_ptrunc_clients) == 0);
		psc_dynarray_free(&fmi->fmi_ptrunc_clients);
	}

	if (fcmh_isreg(f) || fcmh_isdir(f)) {
		/* XXX Need to worry about other modes here */
		if (!fmi->fmi_ctor_rc) {
			slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
			rc = mdsio_release(vfsid, &rootcreds,
			    fcmh_2_mfh(f));
			psc_assert(rc == 0);
		}
	}

	if (fcmh_isdir(f)) {
		slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
		rc = mdsio_release(vfsid, &rootcreds,
		    fcmh_2_dino_mfh(f));
		psc_assert(rc == 0);
	}

	if (fmi->fmi_inodeh.inoh_extras)
		PSCFREE(fmi->fmi_inodeh.inoh_extras);
}
Example #2
0
int
slc_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	struct fcmh_cli_info *fci;
	struct sl_resource *res;
	struct sl_site *s;
	sl_siteid_t siteid;
	int i;

	fci = fcmh_get_pri(f);
	slc_fcmh_refresh_age(f);
	INIT_PSC_LISTENTRY(&fci->fci_lentry);
	siteid = FID_GET_SITEID(fcmh_2_fid(f));

	psc_assert(f->fcmh_flags & FCMH_INITING);

	if (fcmh_2_fid(f) != SLFID_ROOT &&
	    siteid != msl_rmc_resm->resm_siteid) {
		s = libsl_siteid2site(siteid);
		if (s == NULL) {
			psclog_errorx("fid "SLPRI_FID" has "
			    "invalid site ID %d",
			    fcmh_2_fid(f), siteid);
			return (ESTALE);
		}
		SITE_FOREACH_RES(s, res, i)
			if (res->res_type == SLREST_MDS) {
				fci->fci_resm = psc_dynarray_getpos(
				    &res->res_members, 0);
				return (0);
			}
		psclog_errorx("fid "SLPRI_FID" has invalid site ID %d",
		    fcmh_2_fid(f), siteid);
		return (ESTALE);
	}
Example #3
0
int
_mds_fcmh_setattr(int vfsid, struct fidc_membh *f, int to_set,
    const struct srt_stat *sstb, int log)
{
	struct srt_stat sstb_out;
	int rc;

	FCMH_LOCK_ENSURE(f);
	FCMH_BUSY_ENSURE(f);
	FCMH_ULOCK(f);

	if (log)
		mds_reserve_slot(1);
	rc = mdsio_setattr(vfsid, fcmh_2_mfid(f), sstb, to_set,
	    &rootcreds, &sstb_out, fcmh_2_mfh(f),
	    log ? mdslog_namespace : NULL);
	if (log)
		mds_unreserve_slot(1);

	if (!rc) {
		psc_assert(sstb_out.sst_fid == fcmh_2_fid(f));

		FCMH_LOCK(f);
		f->fcmh_sstb = sstb_out;
		FCMH_ULOCK(f);
	}

	return (rc);
}
Example #4
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);
}
Example #5
0
int
mdsio_fcmh_refreshattr(struct fidc_membh *f, struct srt_stat *out_sstb)
{
	int locked, rc, vfsid;
	pthread_t pthr;

	pthr = pthread_self();
	locked = FCMH_RLOCK(f);
	fcmh_wait_locked(f, (f->fcmh_flags & FCMH_BUSY) &&
	    f->fcmh_owner != pthr);
	rc = slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
	psc_assert(rc == 0);
	rc = mdsio_getattr(vfsid, fcmh_2_mfid(f),
	    fcmh_2_mfh(f), &rootcreds, &f->fcmh_sstb);
	if (out_sstb)
		*out_sstb = f->fcmh_sstb;
	FCMH_URLOCK(f, locked);
	return (rc);
}
Example #6
0
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 = inoh_2_fcmh(ih);
	slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb, 0,
	    inoh_2_mfh(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 (PFLERR_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);
}
Example #7
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 = inoh_2_fcmh(ih);
	slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
	rc = mdsio_preadv(vfsid, &rootcreds, iovs, nitems(iovs), &nb,
	    0x400, inoh_2_mfh(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 (PFLERR_BADCRC);
	for (i = 0; i < 60; i++)
		ih->inoh_extras->inox_repls[i] = inox.repls[i];
	return (0);
}
Example #8
0
int
slm_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	struct fcmh_mds_info *fmi;
	struct mio_fh *ino_mfh;
	struct slm_inoh *ih;
	mio_fid_t ino_mfid;
	int rc, vfsid;

	DEBUG_FCMH(PLL_DIAG, f, "ctor");

	rc = slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
	if (rc) {
		DEBUG_FCMH(PLL_WARN, f, "invalid file system ID; "
		    "rc=%d", rc);
		return (rc);
	}
	fmi = fcmh_2_fmi(f);
	memset(fmi, 0, sizeof(*fmi));

	rc = mdsio_lookup_slfid(vfsid, fcmh_2_fid(f), &rootcreds,
	    &f->fcmh_sstb, &fcmh_2_mfid(f));
	if (rc) {
		fmi->fmi_ctor_rc = rc;
		DEBUG_FCMH(PLL_WARN, f, "mdsio_lookup_slfid failed; "
		    "fid="SLPRI_FID" rc=%d",
		    fcmh_2_fid(f), rc);
		return (rc);
	}

	ih = &fmi->fmi_inodeh;
	ih->inoh_flags = INOH_INO_NOTLOADED;

	ino_mfid = fcmh_2_mfid(f);
	ino_mfh = fcmh_2_mfhp(f);

	if (fcmh_isdir(f)) {
		mio_fid_t pmfid;
		char fn[24];

		rc = mdsio_opendir(vfsid, fcmh_2_mfid(f), &rootcreds,
		    NULL, &fcmh_2_mfh(f));
		if (rc) {
			DEBUG_FCMH(PLL_WARN, f, "mdsio_opendir failed; "
			    "mio_fid=%"PRIx64" rc=%d", fcmh_2_mfid(f),
			    rc);
			return (rc);
		}

		snprintf(fn, sizeof(fn), "%016"PRIx64".ino",
		    fcmh_2_fid(f));

		pmfid = mdsio_getfidlinkdir(fcmh_2_fid(f));
		rc = mdsio_lookup(vfsid, pmfid, fn,
		    &fcmh_2_dino_mfid(f), &rootcreds, NULL);
		if (rc == ENOENT) {
			struct slm_inox_od inox;

			rc = mdsio_opencreatef(vfsid, pmfid, &rootcreds,
			    O_CREAT | O_EXCL | O_RDWR,
			    MDSIO_OPENCRF_NOLINK, 0644, fn,
			    &fcmh_2_dino_mfid(f), NULL,
			    &fcmh_2_dino_mfh(f), NULL, NULL, 0);
			psc_assert(rc == 0);

			INOH_LOCK(ih);

			rc = mds_inode_write(vfsid, ih, NULL, NULL);
			psc_assert(rc == 0);

			memset(&inox, 0, sizeof(inox));
			ih->inoh_extras = &inox;
			rc = mds_inox_write(vfsid, ih, NULL, NULL);
			ih->inoh_extras = NULL;

			INOH_ULOCK(ih);

			psc_assert(rc == 0);

			mdsio_release(vfsid, &rootcreds,
			    fcmh_2_dino_mfh(f));
		} else if (rc) {
			fmi->fmi_ctor_rc = rc;
			DEBUG_FCMH(PLL_WARN, f,
			    "mdsio_lookup failed; rc=%d", rc);
			return (rc);
		}

		ino_mfid = fcmh_2_dino_mfid(f);
		ino_mfh = fcmh_2_dino_mfhp(f);
	}

	if (fcmh_isreg(f))
		psc_dynarray_init(&fmi->fmi_ptrunc_clients);

	if (fcmh_isdir(f) || fcmh_isreg(f)) {
		/*
		 * We shouldn't need O_LARGEFILE because SLASH2
		 * metafiles are small.
		 *
		 * I created a file with size of 8070450532247928832
		 * using dd by seeking to a large offset and writing one
		 * byte.  Somehow, the ZFS size becomes 5119601018368.
		 * Without O_LARGEFILE, I got EOVERFLOW (75) here.  The
		 * SLASH2 size is correct though.
		 */
		rc = mdsio_opencreate(vfsid, ino_mfid, &rootcreds,
		    O_RDWR, 0, NULL, NULL, NULL, &ino_mfh->fh, NULL,
		    NULL, 0);
		if (rc == 0) {
			rc = mds_inode_read(&fmi->fmi_inodeh);
			if (rc)
				DEBUG_FCMH(PLL_WARN, f,
				    "could not load inode; "
				    "mfid=%"PRIx64" rc=%d",
				    ino_mfid, rc);
		} else {
			fmi->fmi_ctor_rc = rc;
			DEBUG_FCMH(PLL_WARN, f,
			    "mdsio_opencreate failed; "
			    "mfid=%"PRIx64" rc=%d",
			    ino_mfid, rc);
		}
	} else
		DEBUG_FCMH(PLL_DIAG, f, "special file, no zfs obj");

	return (rc);
}
Example #9
0
/*
 * Update the high-level app stat(2)-like attribute buffer for a FID
 * cache member.
 * @f: FID cache member to update.
 * @sstb: incoming stat attributes.
 * @flags: behavioral flags.
 * Notes:
 *     (1) if SAVELOCAL has been specified, save local field values:
 *		(o) file size
 *		(o) mtime
 *     (2) This function should only be used by a client.
 */
void
slc_fcmh_setattrf(struct fidc_membh *f, struct srt_stat *sstb,
    int flags)
{
	uidmap_int_stat(sstb);

	if (flags & FCMH_SETATTRF_HAVELOCK)
		FCMH_LOCK_ENSURE(f);
	else
		FCMH_LOCK(f);

	if (fcmh_2_gen(f) == FGEN_ANY)
		fcmh_2_gen(f) = sstb->sst_gen;

	if ((FID_GET_INUM(fcmh_2_fid(f))) != SLFID_ROOT &&
	    fcmh_2_gen(f) > sstb->sst_gen) {
		OPSTAT_INCR("msl.generation-backwards");
		DEBUG_FCMH(PLL_DIAG, f, "attempt to set attr with "
		    "gen %"PRIu64" from old gen %"PRIu64,
		    fcmh_2_gen(f), sstb->sst_gen);
		goto out;
	}

	/*
	 * If we don't have stat attributes, how can we save our local
	 * updates?
	 */
	if ((f->fcmh_flags & FCMH_HAVE_ATTRS) == 0)
		flags |= FCMH_SETATTRF_CLOBBER;

	/*
	 * Always update for roots because we might have faked them
	 * with readdir at the super root.
	 */
	if ((FID_GET_INUM(fcmh_2_fid(f))) == SLFID_ROOT)
		flags |= FCMH_SETATTRF_CLOBBER;

	psc_assert(sstb->sst_gen != FGEN_ANY);
	psc_assert(f->fcmh_fg.fg_fid == sstb->sst_fid);

	/*
	 * The default behavior is to save st_size and st_mtim since we
	 * might have done I/O that the MDS does not know about.
	 */
	if ((flags & FCMH_SETATTRF_CLOBBER) == 0 &&
	    fcmh_isreg(f)) {
		/*
		 * If generation numbers match, take the highest of the
		 * values.  Otherwise, disregard local values and
		 * blindly accept whatever the MDS tells us.
		 */
		if (fcmh_2_ptruncgen(f) == sstb->sst_ptruncgen &&
		    fcmh_2_gen(f) == sstb->sst_gen &&
		    fcmh_2_fsz(f) > sstb->sst_size)
			sstb->sst_size = fcmh_2_fsz(f);
		if (fcmh_2_utimgen(f) == sstb->sst_utimgen)
			sstb->sst_mtim = f->fcmh_sstb.sst_mtim;
	}

	COPY_SSTB(sstb, &f->fcmh_sstb);
	f->fcmh_flags |= FCMH_HAVE_ATTRS;
	f->fcmh_flags &= ~FCMH_GETTING_ATTRS;

	if (sl_fcmh_ops.sfop_postsetattr)
		sl_fcmh_ops.sfop_postsetattr(f);

	DEBUG_FCMH(PLL_DEBUG, f, "attr set");

 out:
	if (!(flags & FCMH_SETATTRF_HAVELOCK))
		FCMH_ULOCK(f);
}
Example #10
0
/*
 * If the generation number changes, we assume a full truncation has
 * happened.  We need to open a new backing file and attach it to the
 * fcmh.
 */
int
sli_fcmh_reopen(struct fidc_membh *f, slfgen_t fgen)
{
	int rc = 0;

	FCMH_LOCK_ENSURE(f);

	OPSTAT_INCR("reopen");

	if (fgen == FGEN_ANY) {
		OPSTAT_INCR("generation-bogus");
		return (EBADF);
	}
	if (fgen < fcmh_2_gen(f)) {
		OPSTAT_INCR("generation-stale");
		return (ESTALE);
	}

	/*
	 * If our generation number is still unknown try to set it here.
	 */
	if (fcmh_2_gen(f) == FGEN_ANY && fgen != FGEN_ANY) {
		OPSTAT_INCR("generation-fix");
		fcmh_2_gen(f) = fgen;
	}

	if (fgen > fcmh_2_gen(f)) {
		struct sl_fidgen oldfg;
		char fidfn[PATH_MAX];

		DEBUG_FCMH(PLL_DIAG, f, "reopening new backing file");
		OPSTAT_INCR("slvr-remove-reopen");
		slvr_remove_all(f);

		/*
		 * It's possible the pruning of all slivers and bmaps
		 * ended up fcmh_op_done() our fcmh so ensure it is
		 * locked upon finishing.
		 */
		FCMH_RLOCK(f);

		/*
		 * Need to reopen the backing file and possibly remove
		 * the old one.
		 */
		if (f->fcmh_flags & FCMH_IOD_BACKFILE) {
			if (close(fcmh_2_fd(f)) == -1) {
				OPSTAT_INCR("close-fail");
				DEBUG_FCMH(PLL_ERROR, f,
				    "reopen/close errno=%d", errno);
			} else {
				OPSTAT_INCR("close-succeed");
			}
			fcmh_2_fd(f) = -1;
			psc_rlim_adj(RLIMIT_NOFILE, -1);
			f->fcmh_flags &= ~FCMH_IOD_BACKFILE;
		}

		oldfg.fg_fid = fcmh_2_fid(f);
		oldfg.fg_gen = fcmh_2_gen(f);

		fcmh_2_gen(f) = fgen;

		rc = sli_open_backing_file(f);
		/* Notify upper layers that open() has failed. */
		if (!rc)
			f->fcmh_flags |= FCMH_IOD_BACKFILE;

		/* Do some upfront garbage collection. */
		sli_fg_makepath(&oldfg, fidfn);

		errno = 0;
		unlink(fidfn);
		DEBUG_FCMH(PLL_INFO, f, "upfront unlink(), errno=%d",
		    errno);

	} else if (!(f->fcmh_flags & FCMH_IOD_BACKFILE)) {

		rc = sli_open_backing_file(f);
		if (!rc)
			f->fcmh_flags |= FCMH_IOD_BACKFILE;
		OPSTAT_INCR("generation-same");
	}
	return (rc);
}
Example #11
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);
}
Example #12
0
/*
 * Apply a translation matrix of residency states to a bmap.
 * @b: bmap.
 * @tract: translation actions, indexed by current bmap state with
 *	corresponding values to the new state that should be assigned.
 *	For example, index BREPLST_VALID in the array with the value
 *	BREPLST_INVALID would render a VALID state to an INVALID.
 * @retifset: return value, indexed in the same manner as @tract.
 * @flags: behavioral flags.
 * @off: offset int bmap residency table for IOS intended to be
 *	changed/queried.
 * @scircuit: value-result for batch operations.
 * @cbf: callback routine for more detailed processing.
 * @cbarg: argument to callback.
 *
 */
int
_mds_repl_bmap_apply(struct bmap *b, const int *tract,
    const int *retifset, int flags, int off, int *scircuit,
    brepl_walkcb_t cbf, void *cbarg)
{
	int val, rc = 0;
	struct timeval tv1, tv2, tvd;
	struct bmap_mds_info *bmi = bmap_2_bmi(b);

	BMAP_LOCK_ENSURE(b);
	if (tract) {
		/*
		 * The caller must set the flag if modifications are made.
		 */
		PFL_GETTIMEVAL(&tv1);
		bmap_wait_locked(b, b->bcm_flags & BMAPF_REPLMODWR);
		PFL_GETTIMEVAL(&tv2);
		timersub(&tv2, &tv1, &tvd);
		OPSTAT_ADD("bmap-wait-usecs", tvd.tv_sec * 1000000 + tvd.tv_usec);

		memcpy(bmi->bmi_orepls, bmi->bmi_repls,
		    sizeof(bmi->bmi_orepls));
		psc_assert((flags & REPL_WALKF_SCIRCUIT) == 0);
	}

	if (scircuit)
		*scircuit = 0;
	else
		psc_assert((flags & REPL_WALKF_SCIRCUIT) == 0);

	/* retrieve IOS status given a bit offset into the map */
	val = SL_REPL_GET_BMAP_IOS_STAT(bmi->bmi_repls, off);

	if (val >= NBREPLST)
		psc_fatalx("corrupt bmap, val = %d, bno = %d, fid="SLPRI_FID,
			 val, b->bcm_bmapno, fcmh_2_fid(b->bcm_fcmh));

	/* callback can also be used to track if we did make any changes */
	if (cbf)
		cbf(b, off / SL_BITS_PER_REPLICA, val, cbarg);

	/* check for & apply return values */
	if (retifset && retifset[val]) {
		rc = retifset[val];
		if (flags & REPL_WALKF_SCIRCUIT) {
			*scircuit = 1;
			goto out;
		}
	}

	/* apply any translations - this must be done after retifset */
	if (tract && tract[val] != -1) {
		DEBUG_BMAPOD(PLL_DEBUG, b, "before modification");
		SL_REPL_SET_BMAP_IOS_STAT(bmi->bmi_repls, off,
		    tract[val]);
		DEBUG_BMAPOD(PLL_DEBUG, b, "after modification");
	}

 out:
	return (rc);
}
Example #13
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 = inoh_2_fcmh(ih);
	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);

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

	th = inoh_2_mfhp(ih)->fh;
	inoh_2_mfhp(ih)->fh = h;
	rc = mds_inode_dump(vfsid, sic, ih, th);
	inoh_2_mfhp(ih)->fh = 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);
}