Ejemplo n.º 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);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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);
}