コード例 #1
0
ファイル: lov_object.c プロジェクト: KnightKu/lustre-stable
static struct cl_object *lov_find_subobj(const struct lu_env *env,
					 struct lov_object *lov,
					 struct lov_stripe_md *lsm,
					 int stripe_idx)
{
	struct lov_device	*dev = lu2lov_dev(lov2lu(lov)->lo_dev);
	struct lov_oinfo	*oinfo = lsm->lsm_oinfo[stripe_idx];
	struct lov_thread_info  *lti = lov_env_info(env);
	struct lu_fid		*ofid = &lti->lti_fid;
	struct cl_device	*subdev;
	int			ost_idx;
	int			rc;
	struct cl_object	*result;

	if (lov->lo_type != LLT_RAID0)
		GOTO(out, result = NULL);

	ost_idx = oinfo->loi_ost_idx;
	rc = ostid_to_fid(ofid, &oinfo->loi_oi, ost_idx);
	if (rc != 0)
		GOTO(out, result = NULL);

	subdev = lovsub2cl_dev(dev->ld_target[ost_idx]);
	result = lov_sub_find(env, subdev, ofid, NULL);
out:
	if (result == NULL)
		result = ERR_PTR(-EINVAL);
	return result;
}
コード例 #2
0
static void lov_subobject_kill(const struct lu_env *env, struct lov_object *lov,
			       struct lovsub_object *los, int idx)
{
	struct cl_object	*sub;
	struct lov_layout_raid0 *r0;
	struct lu_site	  *site;
	struct lu_site_bkt_data *bkt;
	wait_queue_t	  *waiter;

	r0  = &lov->u.raid0;
	LASSERT(r0->lo_sub[idx] == los);

	sub  = lovsub2cl(los);
	site = sub->co_lu.lo_dev->ld_site;
	bkt  = lu_site_bkt_from_fid(site, &sub->co_lu.lo_header->loh_fid);

	cl_object_kill(env, sub);
	/* release a reference to the sub-object and ... */
	lu_object_ref_del(&sub->co_lu, "lov-parent", lov);
	cl_object_put(env, sub);

	/* ... wait until it is actually destroyed---sub-object clears its
	 * ->lo_sub[] slot in lovsub_object_fini()
	 */
	if (r0->lo_sub[idx] == los) {
		waiter = &lov_env_info(env)->lti_waiter;
		init_waitqueue_entry(waiter, current);
		add_wait_queue(&bkt->lsb_marche_funebre, waiter);
		set_current_state(TASK_UNINTERRUPTIBLE);
		while (1) {
			/* this wait-queue is signaled at the end of
			 * lu_object_free().
			 */
			set_current_state(TASK_UNINTERRUPTIBLE);
			spin_lock(&r0->lo_sub_lock);
			if (r0->lo_sub[idx] == los) {
				spin_unlock(&r0->lo_sub_lock);
				schedule();
			} else {
				spin_unlock(&r0->lo_sub_lock);
				set_current_state(TASK_RUNNING);
				break;
			}
		}
		remove_wait_queue(&bkt->lsb_marche_funebre, waiter);
	}
	LASSERT(!r0->lo_sub[idx]);
}
コード例 #3
0
ファイル: lov_object.c プロジェクト: 383530895/linux
static int lov_attr_get_raid0(const struct lu_env *env, struct cl_object *obj,
			      struct cl_attr *attr)
{
	struct lov_object	*lov = cl2lov(obj);
	struct lov_layout_raid0 *r0 = lov_r0(lov);
	struct cl_attr		*lov_attr = &r0->lo_attr;
	int			 result = 0;

	/* this is called w/o holding type guard mutex, so it must be inside
	 * an on going IO otherwise lsm may be replaced.
	 * LU-2117: it turns out there exists one exception. For mmaped files,
	 * the lock of those files may be requested in the other file's IO
	 * context, and this function is called in ccc_lock_state(), it will
	 * hit this assertion.
	 * Anyway, it's still okay to call attr_get w/o type guard as layout
	 * can't go if locks exist. */
	/* LASSERT(atomic_read(&lsm->lsm_refc) > 1); */

	if (!r0->lo_attr_valid) {
		struct lov_stripe_md    *lsm = lov->lo_lsm;
		struct ost_lvb	  *lvb = &lov_env_info(env)->lti_lvb;
		__u64		    kms = 0;

		memset(lvb, 0, sizeof(*lvb));
		/* XXX: timestamps can be negative by sanity:test_39m,
		 * how can it be? */
		lvb->lvb_atime = LLONG_MIN;
		lvb->lvb_ctime = LLONG_MIN;
		lvb->lvb_mtime = LLONG_MIN;

		/*
		 * XXX that should be replaced with a loop over sub-objects,
		 * doing cl_object_attr_get() on them. But for now, let's
		 * reuse old lov code.
		 */

		/*
		 * XXX take lsm spin-lock to keep lov_merge_lvb_kms()
		 * happy. It's not needed, because new code uses
		 * ->coh_attr_guard spin-lock to protect consistency of
		 * sub-object attributes.
		 */
		lov_stripe_lock(lsm);
		result = lov_merge_lvb_kms(lsm, lvb, &kms);
		lov_stripe_unlock(lsm);
		if (result == 0) {
			cl_lvb2attr(lov_attr, lvb);
			lov_attr->cat_kms = kms;
			r0->lo_attr_valid = 1;
		}
	}
	if (result == 0) { /* merge results */
		attr->cat_blocks = lov_attr->cat_blocks;
		attr->cat_size = lov_attr->cat_size;
		attr->cat_kms = lov_attr->cat_kms;
		if (attr->cat_atime < lov_attr->cat_atime)
			attr->cat_atime = lov_attr->cat_atime;
		if (attr->cat_ctime < lov_attr->cat_ctime)
			attr->cat_ctime = lov_attr->cat_ctime;
		if (attr->cat_mtime < lov_attr->cat_mtime)
			attr->cat_mtime = lov_attr->cat_mtime;
	}
	return result;
}
コード例 #4
0
ファイル: lov_object.c プロジェクト: 383530895/linux
static int lov_init_raid0(const struct lu_env *env,
			  struct lov_device *dev, struct lov_object *lov,
			  const struct cl_object_conf *conf,
			  union  lov_layout_state *state)
{
	int result;
	int i;

	struct cl_object	*stripe;
	struct lov_thread_info  *lti     = lov_env_info(env);
	struct cl_object_conf   *subconf = &lti->lti_stripe_conf;
	struct lov_stripe_md    *lsm     = conf->u.coc_md->lsm;
	struct lu_fid	   *ofid    = &lti->lti_fid;
	struct lov_layout_raid0 *r0      = &state->raid0;

	if (lsm->lsm_magic != LOV_MAGIC_V1 && lsm->lsm_magic != LOV_MAGIC_V3) {
		dump_lsm(D_ERROR, lsm);
		LASSERTF(0, "magic mismatch, expected %d/%d, actual %d.\n",
			 LOV_MAGIC_V1, LOV_MAGIC_V3, lsm->lsm_magic);
	}

	LASSERT(lov->lo_lsm == NULL);
	lov->lo_lsm = lsm_addref(lsm);
	r0->lo_nr  = lsm->lsm_stripe_count;
	LASSERT(r0->lo_nr <= lov_targets_nr(dev));

	OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
	if (r0->lo_sub != NULL) {
		result = 0;
		subconf->coc_inode = conf->coc_inode;
		spin_lock_init(&r0->lo_sub_lock);
		/*
		 * Create stripe cl_objects.
		 */
		for (i = 0; i < r0->lo_nr && result == 0; ++i) {
			struct cl_device *subdev;
			struct lov_oinfo *oinfo = lsm->lsm_oinfo[i];
			int ost_idx = oinfo->loi_ost_idx;

			result = ostid_to_fid(ofid, &oinfo->loi_oi,
					      oinfo->loi_ost_idx);
			if (result != 0)
				goto out;

			subdev = lovsub2cl_dev(dev->ld_target[ost_idx]);
			subconf->u.coc_oinfo = oinfo;
			LASSERTF(subdev != NULL, "not init ost %d\n", ost_idx);
			/* In the function below, .hs_keycmp resolves to
			 * lu_obj_hop_keycmp() */
			/* coverity[overrun-buffer-val] */
			stripe = lov_sub_find(env, subdev, ofid, subconf);
			if (!IS_ERR(stripe)) {
				result = lov_init_sub(env, lov, stripe, r0, i);
				if (result == -EAGAIN) { /* try again */
					--i;
					result = 0;
				}
			} else {
				result = PTR_ERR(stripe);
			}
		}
	} else
		result = -ENOMEM;
out:
	return result;
}
コード例 #5
0
ファイル: lov_object.c プロジェクト: acton393/linux
static int lov_init_raid0(const struct lu_env *env,
			  struct lov_device *dev, struct lov_object *lov,
			  const struct cl_object_conf *conf,
			  union  lov_layout_state *state)
{
	int result;
	int i;

	struct cl_object	*stripe;
	struct lov_thread_info  *lti     = lov_env_info(env);
	struct cl_object_conf   *subconf = &lti->lti_stripe_conf;
	struct lov_stripe_md    *lsm     = conf->u.coc_md->lsm;
	struct lu_fid	   *ofid    = &lti->lti_fid;
	struct lov_layout_raid0 *r0      = &state->raid0;

	if (lsm->lsm_magic != LOV_MAGIC_V1 && lsm->lsm_magic != LOV_MAGIC_V3) {
		dump_lsm(D_ERROR, lsm);
		LASSERTF(0, "magic mismatch, expected %d/%d, actual %d.\n",
			 LOV_MAGIC_V1, LOV_MAGIC_V3, lsm->lsm_magic);
	}

	LASSERT(!lov->lo_lsm);
	lov->lo_lsm = lsm_addref(lsm);
	lov->lo_layout_invalid = true;
	r0->lo_nr  = lsm->lsm_stripe_count;
	LASSERT(r0->lo_nr <= lov_targets_nr(dev));

	r0->lo_sub = libcfs_kvzalloc(r0->lo_nr * sizeof(r0->lo_sub[0]),
				     GFP_NOFS);
	if (r0->lo_sub) {
		int psz = 0;

		result = 0;
		subconf->coc_inode = conf->coc_inode;
		spin_lock_init(&r0->lo_sub_lock);
		/*
		 * Create stripe cl_objects.
		 */
		for (i = 0; i < r0->lo_nr && result == 0; ++i) {
			struct cl_device *subdev;
			struct lov_oinfo *oinfo = lsm->lsm_oinfo[i];
			int ost_idx = oinfo->loi_ost_idx;

			if (lov_oinfo_is_dummy(oinfo))
				continue;

			result = ostid_to_fid(ofid, &oinfo->loi_oi,
					      oinfo->loi_ost_idx);
			if (result != 0)
				goto out;

			subdev = lovsub2cl_dev(dev->ld_target[ost_idx]);
			subconf->u.coc_oinfo = oinfo;
			LASSERTF(subdev, "not init ost %d\n", ost_idx);
			/* In the function below, .hs_keycmp resolves to
			 * lu_obj_hop_keycmp()
			 */
			/* coverity[overrun-buffer-val] */
			stripe = lov_sub_find(env, subdev, ofid, subconf);
			if (!IS_ERR(stripe)) {
				result = lov_init_sub(env, lov, stripe, r0, i);
				if (result == -EAGAIN) { /* try again */
					--i;
					result = 0;
					continue;
				}
			} else {
				result = PTR_ERR(stripe);
			}

			if (result == 0) {
				int sz = lov_page_slice_fixup(lov, stripe);

				LASSERT(ergo(psz > 0, psz == sz));
				psz = sz;
			}
		}
		if (result == 0)
			cl_object_header(&lov->lo_cl)->coh_page_bufsize += psz;
	} else {
		result = -ENOMEM;
	}
out:
	return result;
}