static int lov_layout_change(const struct lu_env *unused,
                             struct lov_object *lov,
                             const struct cl_object_conf *conf)
{
	int result;
	enum lov_layout_type llt = LLT_EMPTY;
	union lov_layout_state *state = &lov->u;
	const struct lov_layout_operations *old_ops;
	const struct lov_layout_operations *new_ops;

	struct cl_object_header *hdr = cl_object_header(&lov->lo_cl);
	void *cookie;
	struct lu_env *env;
	int refcheck;
	ENTRY;

	LASSERT(0 <= lov->lo_type && lov->lo_type < ARRAY_SIZE(lov_dispatch));

	if (conf->u.coc_md != NULL)
		llt = lov_type(conf->u.coc_md->lsm);
	LASSERT(0 <= llt && llt < ARRAY_SIZE(lov_dispatch));

	cookie = cl_env_reenter();
	env = cl_env_get(&refcheck);
	if (IS_ERR(env)) {
		cl_env_reexit(cookie);
		RETURN(PTR_ERR(env));
	}

	old_ops = &lov_dispatch[lov->lo_type];
	new_ops = &lov_dispatch[llt];

	result = old_ops->llo_delete(env, lov, &lov->u);
	if (result == 0) {
		old_ops->llo_fini(env, lov, &lov->u);

		LASSERT(cfs_atomic_read(&lov->lo_active_ios) == 0);
		LASSERT(hdr->coh_tree.rnode == NULL);
		LASSERT(hdr->coh_pages == 0);

		lov->lo_type = LLT_EMPTY;
		result = new_ops->llo_init(env,
					lu2lov_dev(lov->lo_cl.co_lu.lo_dev),
					lov, conf, state);
		if (result == 0) {
			new_ops->llo_install(env, lov, state);
			lov->lo_type = llt;
		} else {
			new_ops->llo_delete(env, lov, state);
			new_ops->llo_fini(env, lov, state);
			/* this file becomes an EMPTY file. */
		}
	}

	cl_env_put(env, &refcheck);
	cl_env_reexit(cookie);
	RETURN(result);
}
Example #2
0
static int lov_layout_change(const struct lu_env *unused,
			     struct lov_object *lov,
			     const struct cl_object_conf *conf)
{
	int result;
	enum lov_layout_type llt = LLT_EMPTY;
	union lov_layout_state *state = &lov->u;
	const struct lov_layout_operations *old_ops;
	const struct lov_layout_operations *new_ops;

	void *cookie;
	struct lu_env *env;
	int refcheck;

	LASSERT(0 <= lov->lo_type && lov->lo_type < ARRAY_SIZE(lov_dispatch));

	if (conf->u.coc_md)
		llt = lov_type(conf->u.coc_md->lsm);
	LASSERT(0 <= llt && llt < ARRAY_SIZE(lov_dispatch));

	cookie = cl_env_reenter();
	env = cl_env_get(&refcheck);
	if (IS_ERR(env)) {
		cl_env_reexit(cookie);
		return PTR_ERR(env);
	}

	CDEBUG(D_INODE, DFID" from %s to %s\n",
	       PFID(lu_object_fid(lov2lu(lov))),
	       llt2str(lov->lo_type), llt2str(llt));

	old_ops = &lov_dispatch[lov->lo_type];
	new_ops = &lov_dispatch[llt];

	result = cl_object_prune(env, &lov->lo_cl);
	if (result != 0)
		goto out;

	result = old_ops->llo_delete(env, lov, &lov->u);
	if (result == 0) {
		old_ops->llo_fini(env, lov, &lov->u);

		LASSERT(atomic_read(&lov->lo_active_ios) == 0);

		lov->lo_type = LLT_EMPTY;
		result = new_ops->llo_init(env,
					lu2lov_dev(lov->lo_cl.co_lu.lo_dev),
					lov, conf, state);
		if (result == 0) {
			new_ops->llo_install(env, lov, state);
			lov->lo_type = llt;
		} else {
			new_ops->llo_delete(env, lov, state);
			new_ops->llo_fini(env, lov, state);
			/* this file becomes an EMPTY file. */
		}
	}

out:
	cl_env_put(env, &refcheck);
	cl_env_reexit(cookie);
	return result;
}
Example #3
0
static int lov_layout_change(const struct lu_env *unused,
			     struct lov_object *lov, struct lov_stripe_md *lsm,
			     const struct cl_object_conf *conf)
{
	enum lov_layout_type llt = lov_type(lsm);
	union lov_layout_state *state = &lov->u;
	const struct lov_layout_operations *old_ops;
	const struct lov_layout_operations *new_ops;
	void *cookie;
	struct lu_env *env;
	__u16 refcheck;
	int rc;
	ENTRY;

	LASSERT(0 <= lov->lo_type && lov->lo_type < ARRAY_SIZE(lov_dispatch));

	cookie = cl_env_reenter();
	env = cl_env_get(&refcheck);
	if (IS_ERR(env)) {
		cl_env_reexit(cookie);
		RETURN(PTR_ERR(env));
	}

	LASSERT(0 <= llt && llt < ARRAY_SIZE(lov_dispatch));

	CDEBUG(D_INODE, DFID" from %s to %s\n",
	       PFID(lu_object_fid(lov2lu(lov))),
	       llt2str(lov->lo_type), llt2str(llt));

	old_ops = &lov_dispatch[lov->lo_type];
	new_ops = &lov_dispatch[llt];

	rc = cl_object_prune(env, &lov->lo_cl);
	if (rc != 0)
		GOTO(out, rc);

	rc = old_ops->llo_delete(env, lov, &lov->u);
	if (rc != 0)
		GOTO(out, rc);

	old_ops->llo_fini(env, lov, &lov->u);

	LASSERT(atomic_read(&lov->lo_active_ios) == 0);

	lov->lo_type = LLT_EMPTY;

	/* page bufsize fixup */
	cl_object_header(&lov->lo_cl)->coh_page_bufsize -=
		lov_page_slice_fixup(lov, NULL);

	rc = new_ops->llo_init(env, lov_object_dev(lov), lov, lsm, conf, state);
	if (rc != 0) {
		new_ops->llo_delete(env, lov, state);
		new_ops->llo_fini(env, lov, state);
		/* this file becomes an EMPTY file. */
		GOTO(out, rc);
	}

	new_ops->llo_install(env, lov, state);
	lov->lo_type = llt;

out:
	cl_env_put(env, &refcheck);
	cl_env_reexit(cookie);

	RETURN(rc);
}