Пример #1
0
/*
 * Handle a NAMESPACE_UPDATE request from another MDS.
 */
int
slm_rmm_handle_namespace_update(struct pscrpc_request *rq)
{
	struct srt_update_entry *entryp;
	struct srm_update_req *mq;
	struct srm_update_rep *mp;
	struct sl_mds_peerinfo *p;
	struct sl_resource *res;
	struct sl_site *site;
	struct iovec iov;
	int i, len, count;

	SL_RSX_ALLOCREP(rq, mq, mp);

	count = mq->count;
	if (count <= 0 || mq->size > LNET_MTU) {
		mp->rc = -EINVAL;
		return (mp->rc);
	}

	iov.iov_len = mq->size;
	iov.iov_base = PSCALLOC(mq->size);

	mp->rc = slrpc_bulkserver(rq, BULK_GET_SINK, SRMM_BULK_PORTAL,
	    &iov, 1);
	if (mp->rc)
		goto out;

	/* Search for the peer information by the given site ID. */
	site = libsl_siteid2site(mq->siteid);
	p = NULL;
	if (site)
		SITE_FOREACH_RES(site, res, i)
			if (res->res_type == SLREST_MDS) {
				p = res2rpmi(res)->rpmi_info;
				break;
			}
	if (p == NULL) {
		psclog_info("fail to find site ID %d", mq->siteid);
		PFL_GOTOERR(out, mp->rc = -EINVAL);
	}

	/*
	 * Iterate through the namespace update buffer and apply updates.
	 * If we fail to apply an update, we still report success to our
	 * peer because reporting an error does not help our cause.
	 */
	entryp = iov.iov_base;
	for (i = 0; i < count; i++) {
		slm_rmm_apply_update(entryp);
		len = UPDATE_ENTRY_LEN(entryp);
		entryp = PSC_AGP(entryp, len);
	}
	zfsslash2_wait_synced(0);

 out:
	PSCFREE(iov.iov_base);
	return (mp->rc);
}
Пример #2
0
int
slm_rmc_handle_ping(struct pscrpc_request *rq)
{
	const struct srm_ping_req *mq;
	struct srm_ping_rep *mp;

	SL_RSX_ALLOCREP(rq, mq, mp);
	return (0);
}
Пример #3
0
int
slm_rmc_handle_getinode(struct pscrpc_request *rq)
{
	const struct srm_get_inode_req *mq;
	struct srm_get_inode_rep *mp;
	struct fidc_membh *f;

	SL_RSX_ALLOCREP(rq, mq, mp);
	mp->rc = -slm_fcmh_get(&mq->fg, &f);
	if (mp->rc)
		return (0);
	slm_pack_inode(f, &mp->ino);
	fcmh_op_done(f);
	return (0);
}
Пример #4
0
/*
 * Handle a BMAPCHWRMODE request to upgrade a client bmap lease from
 * READ-only to READ+WRITE.
 * @rq: RPC request.
 */
int
slm_rmc_handle_bmap_chwrmode(struct pscrpc_request *rq)
{
	struct bmap_mds_lease *bml = NULL;
	struct srm_bmap_chwrmode_req *mq;
	struct srm_bmap_chwrmode_rep *mp;
	struct fidc_membh *f = NULL;
	struct bmapc_memb *b = NULL;
	struct bmap_mds_info *bmi;

	SL_RSX_ALLOCREP(rq, mq, mp);
	mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);
	mp->rc = bmap_lookup(f, mq->sbd.sbd_bmapno, &b);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	bmi = bmap_2_bmi(b);

	bml = mds_bmap_getbml(b, mq->sbd.sbd_seq,
	    mq->sbd.sbd_nid, mq->sbd.sbd_pid);

	if (bml == NULL)
		PFL_GOTOERR(out, mp->rc = -EINVAL);

	mp->rc = mds_bmap_bml_chwrmode(bml, mq->prefios[0]);
	if (mp->rc == -PFLERR_ALREADY)
		mp->rc = 0;
	else if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	mp->sbd = mq->sbd;
	mp->sbd.sbd_seq = bml->bml_seq;
	mp->sbd.sbd_key = bmi->bmi_assign->odtr_crc;

	psc_assert(bmi->bmi_wr_ion);
	mp->sbd.sbd_ios = rmmi2resm(bmi->bmi_wr_ion)->resm_res_id;

 out:
	if (bml)
		mds_bmap_bml_release(bml);
	if (b)
		bmap_op_done(b);
	if (f)
		fcmh_op_done(f);
	return (0);
}
Пример #5
0
int
slm_rmc_handle_lookup(struct pscrpc_request *rq)
{
	struct fidc_membh *p = NULL;
	struct srm_lookup_req *mq;
	struct srm_lookup_rep *mp;
	int vfsid;

	SL_RSX_ALLOCREP(rq, mq, mp);
	mp->rc = slfid_to_vfsid(mq->pfg.fg_fid, &vfsid);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);
	mp->rc = -slm_fcmh_get(&mq->pfg, &p);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	mq->name[sizeof(mq->name) - 1] = '\0';
	psclog_diag("lookup: pfid="SLPRI_FID" name=%s", fcmh_2_mfid(p),
	    mq->name);

	if (fcmh_2_mfid(p) == SLFID_ROOT &&
	    strcmp(mq->name, SL_RPATH_META_DIR) == 0)
		PFL_GOTOERR(out, mp->rc = -EINVAL);

	if (mq->pfg.fg_fid == SLFID_ROOT && use_global_mount) {
		uint64_t fid;
		struct sl_site *site;

		mp->rc = -ENOENT;
		CONF_LOCK();
		CONF_FOREACH_SITE(site) {
			if (strcmp(mq->name, site->site_name) != 0)
				continue;

			fid = SLFID_ROOT;
			FID_SET_SITEID(fid, site->site_id);

			mp->xattrsize = 0;
			mp->attr.sst_fg.fg_fid = fid;
			mp->attr.sst_fg.fg_gen = 2;
			slm_root_attributes(&mp->attr);
			mp->rc = 0;
			break;
		}
		CONF_ULOCK();
		goto out;
	}
Пример #6
0
int
slm_rmc_handle_extendbmapls(struct pscrpc_request *rq)
{
	struct srm_leasebmapext_req *mq;
	struct srm_leasebmapext_rep *mp;
	struct fidc_membh *f;

	SL_RSX_ALLOCREP(rq, mq, mp);

	mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f);
	if (mp->rc)
		return (0);

	mp->rc = mds_lease_renew(f, &mq->sbd, &mp->sbd, rq->rq_export);
	fcmh_op_done(f);
	return (0);
}
Пример #7
0
int
slm_rmc_handle_reassignbmapls(struct pscrpc_request *rq)
{
	struct srm_reassignbmap_req *mq;
	struct srm_reassignbmap_rep *mp;
	struct fidc_membh *f;

	SL_RSX_ALLOCREP(rq, mq, mp);

	mp->rc = -slm_fcmh_get(&mq->sbd.sbd_fg, &f);
	if (mp->rc)
		return (0);

	mp->rc = mds_lease_reassign(f, &mq->sbd, mq->pios,
	    mq->prev_sliods, mq->nreassigns, &mp->sbd, rq->rq_export);

	fcmh_op_done(f);
	return (0);
}
Пример #8
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);
}
Пример #9
0
int
slm_rmc_handle_link(struct pscrpc_request *rq)
{
	struct fidc_membh *p = NULL, *c = NULL;
	struct srm_link_req *mq;
	struct srm_link_rep *mp;
	int vfsid;

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

	mp->rc = -slm_fcmh_get(&mq->pfg, &p);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);
	mp->rc = -slm_fcmh_get(&mq->fg, &c);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	mq->name[sizeof(mq->name) - 1] = '\0';
	mds_reserve_slot(1);
	mp->rc = mdsio_link(vfsid, fcmh_2_mfid(c), fcmh_2_mfid(p),
	    mq->name, &rootcreds, mdslog_namespace);
	mds_unreserve_slot(1);

	mdsio_fcmh_refreshattr(c, &mp->cattr);
	mdsio_fcmh_refreshattr(p, &mp->pattr);

 out:
	if (c)
		fcmh_op_done(c);
	if (p)
		fcmh_op_done(p);
	return (0);
}
Пример #10
0
int
slm_rmc_handle_getbmap(struct pscrpc_request *rq)
{
	const struct srm_leasebmap_req *mq;
	struct srm_leasebmap_rep *mp;
	struct fidc_membh *f;
	int rc = 0;

	SL_RSX_ALLOCREP(rq, mq, mp);

	if (mq->rw == SL_WRITE)
		OPSTAT_INCR("getbmap-lease-write");
	else if (mq->rw == SL_READ)
		OPSTAT_INCR("getbmap-lease-read");
	else {
		mp->rc = -EINVAL;
		return (0);
	}

	mp->rc = -slm_fcmh_get(&mq->fg, &f);
	if (mp->rc)
		return (0);
	mp->flags = mq->flags;

	mp->rc = mds_bmap_load_cli(f, mq->bmapno, mq->flags, mq->rw,
	    mq->prefios[0], &mp->sbd, rq->rq_export, mp->repls, 0);
	if (mp->rc)
		PFL_GOTOERR(out, mp->rc);

	if (mp->flags & SRM_LEASEBMAPF_GETINODE)
		slm_pack_inode(f, &mp->ino);

 out:
	fcmh_op_done(f);
	return (rc ? rc : mp->rc);
}
Пример #11
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);
}