Beispiel #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);
}
Beispiel #2
0
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_mfh(ih);

	snprintf(fn, sizeof(fn), "%016"PRIx64".update",
	    inoh_2_fid(ih));

	*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 = PFLERR_BADCRC;
		PFL_GOTOERR(out, *rc);
	}

	exists = 1;

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

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

	inoh_2_mfh(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_mfh(ih) = th;
	return (exists);
}
Beispiel #3
0
/*
 * Handle a NAMESPACE_FORWARD request from another MDS.
 */
int
slm_rmm_handle_namespace_forward(struct pscrpc_request *rq)
{
	char *from, *to, *name, *linkname;
	struct fidc_membh *p = NULL, *op = NULL, *np = NULL;
	struct srm_forward_req *mq;
	struct srm_forward_rep *mp;
	struct slash_creds cr;
	struct srt_stat sstb;
	void *mfh;
	int vfsid;

	p = op = np = NULL;
	SL_RSX_ALLOCREP(rq, mq, mp);

	if (mq->op != SLM_FORWARD_MKDIR &&
	    mq->op != SLM_FORWARD_RMDIR &&
	    mq->op != SLM_FORWARD_CREATE &&
	    mq->op != SLM_FORWARD_UNLINK &&
	    mq->op != SLM_FORWARD_SYMLINK &&
	    mq->op != SLM_FORWARD_RENAME &&
	    mq->op != SLM_FORWARD_SETATTR) {
		mp->rc = -EINVAL;
		return (0);
	}

	psclog_info("op=%d, name=%s", mq->op, mq->req.name);

	mp->rc = slfid_to_vfsid(mq->fg.fg_fid, &vfsid);
	if (mp->rc)
		return (0);
	if (current_vfsid != vfsid) {
		mp->rc = -EINVAL;
		return (0);
	}

	cr.scr_uid = mq->creds.scr_uid;
	cr.scr_gid = mq->creds.scr_gid;

	mds_reserve_slot(2);
	switch (mq->op) {
	    case SLM_FORWARD_MKDIR:
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		sstb.sst_mode = mq->mode;
		sstb.sst_uid = mq->creds.scr_uid;
		sstb.sst_gid = mq->creds.scr_gid;
		mp->rc = -mdsio_mkdir(vfsid, fcmh_2_mfid(p),
		    mq->req.name, &sstb, 0, 0, &mp->attr, NULL,
		    mdslog_namespace, slm_get_next_slashfid, 0);
		break;
	    case SLM_FORWARD_CREATE:
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		mp->rc = mdsio_opencreate(vfsid, fcmh_2_mfid(p),
		    &cr, O_CREAT | O_EXCL | O_RDWR, mq->mode,
		    mq->req.name, NULL, &mp->attr, &mfh,
		    mdslog_namespace, slm_get_next_slashfid, 0);
		if (!mp->rc)
			mdsio_release(vfsid, &rootcreds, mfh);
		break;
	    case SLM_FORWARD_RMDIR:
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		mp->rc = mdsio_rmdir(vfsid, fcmh_2_mfid(p), NULL,
		    mq->req.name, &rootcreds, mdslog_namespace);
		break;
	    case SLM_FORWARD_UNLINK:
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		mp->rc = -mdsio_unlink(vfsid, fcmh_2_mfid(p), NULL,
		    mq->req.name, &rootcreds, mdslog_namespace,
		    &mp->attr);
		break;
	    case SLM_FORWARD_RENAME:
		mp->rc = slm_fcmh_get(&mq->fg, &op);
		if (mp->rc)
			break;
		mp->rc = slm_fcmh_get(&mq->nfg, &np);
		if (mp->rc)
			break;
		from = mq->req.name;
		to = mq->req.name + strlen(mq->req.name) + 1;
		mp->rc = mdsio_rename(vfsid, fcmh_2_mfid(op), from,
		    fcmh_2_mfid(np), to, &rootcreds,
		    mdslog_namespace, &mp->attr);
		break;
	    case SLM_FORWARD_SETATTR:
		/*
		 * This is tough because we have some logic at the fcmh
		 * layer dealing with (partial) truncates.  It is not a
		 * pure namespace operation.
		 */
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		mp->rc = -mdsio_setattr(vfsid, fcmh_2_mfid(p),
		    &mq->req.sstb, mq->to_set, &rootcreds, &mp->attr,
		    fcmh_2_mfh(p), mdslog_namespace);
		break;
	    case SLM_FORWARD_SYMLINK:
		mp->rc = slm_fcmh_get(&mq->fg, &p);
		if (mp->rc)
			break;
		name = mq->req.name;
		linkname = mq->req.name + strlen(mq->req.name) + 1;
		mp->rc = mdsio_symlink(vfsid, linkname,
		    fcmh_2_mfid(p), name, &cr, &mp->attr, NULL,
		    NULL, slm_get_next_slashfid, 0);
		break;
	}
	mds_unreserve_slot(2);
	if (p)
		fcmh_op_done(p);
	if (op)
		fcmh_op_done(op);
	if (np)
		fcmh_op_done(np);
	return (0);
}
Beispiel #4
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);
}