Example #1
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 #2
0
int
sli_fcmh_getattr(struct fidc_membh *f)
{
	struct stat stb;

	if (fstat(fcmh_2_fd(f), &stb) == -1)
		return (-errno);

	FCMH_LOCK(f);
	sl_externalize_stat(&stb, &f->fcmh_sstb);
	// XXX get ptruncgen and gen
	f->fcmh_flags |= FCMH_HAVE_ATTRS;
	FCMH_ULOCK(f);
	return (0);
}
Example #3
0
/**
 * _slm_fcmh_endow - "Endow" or apply inheritance to a new directory
 *	entry from its parent directory replica layout.
 * Note: the bulk of this is empty until we have a place to store such
 * info in the SLASH2 metafile.
 */
int
_slm_fcmh_endow(int vfsid, struct fidc_membh *p, struct fidc_membh *c,
    int wr)
{
	sl_replica_t repls[SL_MAX_REPLICAS];
	int nr, rc = 0;
	uint32_t pol;

	FCMH_LOCK(p);
	pol = fcmh_2_ino(p)->ino_replpol;
	nr = fcmh_2_nrepls(p);
	memcpy(repls, fcmh_2_ino(p)->ino_repls, sizeof(repls[0]) *
	    SL_DEF_REPLICAS);
	if (nr > SL_DEF_REPLICAS) {
		mds_inox_ensure_loaded(fcmh_2_inoh(p));
		memcpy(&repls[SL_DEF_REPLICAS],
		    fcmh_2_inox(p)->inox_repls, sizeof(repls[0]) *
		    SL_INOX_NREPLICAS);
	}
	FCMH_ULOCK(p);

	FCMH_WAIT_BUSY(c);
	fcmh_2_replpol(c) = pol;
	fcmh_2_ino(c)->ino_nrepls = nr;
	memcpy(fcmh_2_ino(c)->ino_repls, repls, sizeof(repls[0]) *
	    SL_DEF_REPLICAS);
	if (nr > SL_DEF_REPLICAS) {
		mds_inox_ensure_loaded(fcmh_2_inoh(c));
		memcpy(fcmh_2_inox(c)->inox_repls,
		    &repls[SL_DEF_REPLICAS], sizeof(repls[0]) *
		    SL_INOX_NREPLICAS);
	}
	if (wr)
		mds_inodes_odsync(vfsid, c, mdslog_ino_repls);
	FCMH_UNBUSY(c);
	return (rc);
}
Example #4
0
int
slm_rmc_handle_getattr(struct pscrpc_request *rq)
{
	const struct srm_getattr_req *mq;
	struct srm_getattr_rep *mp;
	struct fidc_membh *f;
	int vfsid;

	SL_RSX_ALLOCREP(rq, mq, mp);

	psclog_diag("pfid="SLPRI_FID, mq->fg.fg_fid);

	if (mq->fg.fg_fid == SLFID_ROOT && use_global_mount) {
		mp->attr.sst_fg.fg_fid = SLFID_ROOT;
		mp->attr.sst_fg.fg_gen = FGEN_ANY-1;
		slm_root_attributes(&mp->attr);
		return (0);
	}

	mp->rc = -slm_fcmh_get(&mq->fg, &f);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);
	mp->rc = slfid_to_vfsid(mq->fg.fg_fid, &vfsid);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	mp->xattrsize = mdsio_hasxattrs(vfsid, &rootcreds,
	    fcmh_2_mfid(f));

	FCMH_LOCK(f);
	mp->attr = f->fcmh_sstb;

 out:
	if (f)
		fcmh_op_done(f);
	return (0);
}
Example #5
0
int
msl_fcmh_fetch_inode(struct fidc_membh *f)
{
	struct slrpc_cservice *csvc = NULL;
	struct pscrpc_request *rq = NULL;
	struct srm_get_inode_req *mq;
	struct srm_get_inode_rep *mp;
	struct fcmh_cli_info *fci;
	int rc;

	fci = fcmh_2_fci(f);
	rc = slc_rmc_getcsvc(fci->fci_resm, &csvc);
	if (rc)
		goto out;
	rc = SL_RSX_NEWREQ(csvc, SRMT_GET_INODE, rq, mq, mp);
	if (rc)
		goto out;

	mq->fg = f->fcmh_fg;
	rc = SL_RSX_WAITREP(csvc, rq, mp);
	if (rc == 0)
		rc = mp->rc;
	if (rc)
		goto out;

	FCMH_LOCK(f);
	msl_fcmh_stash_inode(f, &mp->ino);
	FCMH_ULOCK(f);

 out:
	if (rq)
		pscrpc_req_finished(rq);
	if (csvc)
		sl_csvc_decref(csvc);
	return (rc);
}
Example #6
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 #7
0
int
mds_repl_delrq(const struct sl_fidgen *fgp, sl_bmapno_t bmapno,
    sl_bmapno_t *nbmaps, sl_replica_t *iosv, int nios)
{
	int tract[NBREPLST], rc, iosidx[SL_MAX_REPLICAS], flags;
	sl_bmapno_t nbmaps_processed = 0;
	struct slm_repl_valid replv;
	struct fidc_membh *f = NULL;
	struct bmap *b;

	if (nios < 1 || nios > SL_MAX_REPLICAS || *nbmaps == 0)
		return (-EINVAL);

	rc = slm_fcmh_get(fgp, &f);
	if (rc)
		return (-rc);

	FCMH_LOCK(f);
	if (fcmh_isdir(f))
		flags = IOSV_LOOKUPF_DEL;
	else
		flags = IOSV_LOOKUPF_LOOKUP;

	/* Find replica IOS indexes. */
	rc = -_mds_repl_iosv_lookup(current_vfsid, fcmh_2_inoh(f), iosv,
	    iosidx, nios, flags);

	if (fcmh_isdir(f) || rc)
		PFL_GOTOERR(out, rc);

	replv.nios = nios;
	replv.idx = iosidx;

	brepls_init(tract, -1);
	tract[BREPLST_REPL_QUEUED] = BREPLST_GARBAGE_QUEUED;
	tract[BREPLST_REPL_SCHED] = BREPLST_GARBAGE_QUEUED;
	tract[BREPLST_VALID] = BREPLST_GARBAGE_QUEUED;

	/* Wildcards shouldn't result in errors on zero-length files. */
	if (*nbmaps != (sl_bmapno_t)-1)
		rc = -SLERR_BMAP_INVALID;

	/*
 	 * The following loop will bail out on the very first error. 
 	 * However,  its previous action, if any, has already taken
 	 * effect.
 	 */
	for (; *nbmaps && bmapno < fcmh_nvalidbmaps(f);
	    bmapno++, --*nbmaps, nbmaps_processed++) {
		if (nbmaps_processed >= SLM_REPLRQ_NBMAPS_MAX)
			PFL_GOTOERR(out, rc = -PFLERR_WOULDBLOCK);

		rc = -bmap_get(f, bmapno, SL_WRITE, &b);
		if (rc)
			PFL_GOTOERR(out, rc);
		/*
		 * Before blindly doing the transition, we have to check
		 * to ensure this operation would retain at least one
		 * valid replica.
		 */
		replv.n = 0;
		mds_repl_bmap_walkcb(b, NULL, NULL, 0,
		    slm_repl_countvalid_cb, &replv);

		flags = 0;
		if (replv.n == 0)
			rc = -SLERR_LASTREPL;
		else {
			rc = _mds_repl_bmap_walk(b, tract, NULL, 0, iosidx,
			    nios, slm_repl_delrq_cb, &flags);
			psc_assert(!rc);
			if (flags & FLAG_DIRTY)
				rc = mds_bmap_write_logrepls(b);
		}
		bmap_op_done_type(b, BMAP_OPCNT_LOOKUP);
		if (rc)
			PFL_GOTOERR(out, rc);
	}

 out:
	if (f)
		fcmh_op_done(f);
	*nbmaps = nbmaps_processed;
	return (rc);
}