예제 #1
0
파일: fld_handler.c 프로젝트: Lezval/lustre
/**
 *  Lookup MDT/OST by seq, returns a range for given seq.
 *
 *  If that entry is not cached in fld cache, request is sent to super
 *  sequence controller node (MDT0). All other MDT[1...N] and client
 *  cache fld entries, but this cache is not persistent.
 */
int fld_server_lookup(const struct lu_env *env, struct lu_server_fld *fld,
		      seqno_t seq, struct lu_seq_range *range)
{
	__u32 index;
	int rc;
	ENTRY;

	rc = fld_local_lookup(env, fld, seq, range);
	if (likely(rc == 0))
		RETURN(rc);

	rc = fld_name_to_index(fld->lsf_name, &index);
	if (rc < 0)
		RETURN(rc);
	else
		rc = 0;

	if (index == 0) {
		/* On server side, all entries should be in cache.
		 * If we can not find it in cache, just return error */
		CERROR("%s: Cannot find sequence "LPX64": rc = %d\n",
		       fld->lsf_name, seq, -EIO);
		RETURN(-EIO);
	} else {
		if (fld->lsf_control_exp == NULL) {
			CERROR("%s: lookup "LPX64", but not connects to MDT0"
			       "yet: rc = %d.\n", fld->lsf_name, seq, -EIO);
			RETURN(-EIO);
		}
		/* send request to mdt0 i.e. super seq. controller.
		 * This is temporary solution, long term solution is fld
		 * replication on all mdt servers.
		 */
		range->lsr_start = seq;
		rc = fld_client_rpc(fld->lsf_control_exp,
				    range, FLD_QUERY, NULL);
		if (rc == 0)
			fld_cache_insert(fld->lsf_cache, range);
	}
	RETURN(rc);
}
예제 #2
0
/**
 * Retrieve fldb entry from MDT0 and add to local FLDB and cache.
 **/
int fld_update_from_controller(const struct lu_env *env,
			       struct lu_server_fld *fld)
{
	struct fld_thread_info	  *info;
	struct lu_seq_range	  *range;
	struct lu_seq_range_array *lsra;
	__u32			  index;
	struct ptlrpc_request	  *req;
	int			  rc;
	int			  i;
	ENTRY;

	/* Update only happens during initalization, i.e. local FLDB
	 * does not exist yet */
	if (!fld->lsf_new)
		RETURN(0);

	rc = fld_name_to_index(fld->lsf_name, &index);
	if (rc < 0)
		RETURN(rc);

	/* No need update fldb for MDT0 */
	if (index == 0)
		RETURN(0);

	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
	LASSERT(info != NULL);
	range = &info->fti_lrange;
	memset(range, 0, sizeof(*range));
	range->lsr_index = index;
	fld_range_set_mdt(range);

	do {
		rc = fld_client_rpc(fld->lsf_control_exp, range, FLD_READ,
				    &req);
		if (rc != 0 && rc != -EAGAIN)
			GOTO(out, rc);

		LASSERT(req != NULL);
		lsra = (struct lu_seq_range_array *)req_capsule_server_get(
					  &req->rq_pill, &RMF_GENERIC_DATA);
		if (lsra == NULL)
			GOTO(out, rc = -EPROTO);

		range_array_le_to_cpu(lsra, lsra);
		for (i = 0; i < lsra->lsra_count; i++) {
			int rc1;

			if (lsra->lsra_lsr[i].lsr_flags != LU_SEQ_RANGE_MDT)
				GOTO(out, rc = -EINVAL);

			if (lsra->lsra_lsr[i].lsr_index != index)
				GOTO(out, rc = -EINVAL);

			mutex_lock(&fld->lsf_lock);
			rc1 = fld_insert_entry(env, fld, &lsra->lsra_lsr[i]);
			mutex_unlock(&fld->lsf_lock);

			if (rc1 != 0)
				GOTO(out, rc = rc1);
		}
		if (rc == -EAGAIN)
			*range = lsra->lsra_lsr[lsra->lsra_count - 1];
	} while (rc == -EAGAIN);

	fld->lsf_new = 1;
out:
	if (req != NULL)
		ptlrpc_req_finished(req);

	RETURN(rc);
}
예제 #3
0
int fld_index_init(const struct lu_env *env, struct lu_server_fld *fld,
		   struct dt_device *dt, int type)
{
	struct dt_object	*dt_obj = NULL;
	struct lu_fid		fid;
	struct lu_attr		*attr = NULL;
	struct lu_seq_range	*range = NULL;
	struct fld_thread_info	*info;
	struct dt_object_format	dof;
	struct dt_it		*it;
	const struct dt_it_ops	*iops;
	int			rc;
	__u32			index;
	ENTRY;

	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
	LASSERT(info != NULL);

	lu_local_obj_fid(&fid, FLD_INDEX_OID);
	OBD_ALLOC_PTR(attr);
	if (attr == NULL)
		RETURN(-ENOMEM);

	memset(attr, 0, sizeof(*attr));
	attr->la_valid = LA_MODE;
	attr->la_mode = S_IFREG | 0666;
	dof.dof_type = DFT_INDEX;
	dof.u.dof_idx.di_feat = &fld_index_features;

	dt_obj = dt_locate(env, dt, &fid);
	if (IS_ERR(dt_obj)) {
		rc = PTR_ERR(dt_obj);
		dt_obj = NULL;
		GOTO(out, rc);
	}

	LASSERT(dt_obj != NULL);
	if (!dt_object_exists(dt_obj)) {
		lu_object_put(env, &dt_obj->do_lu);
		dt_obj = dt_find_or_create(env, dt, &fid, &dof, attr);
		fld->lsf_new = 1;
		if (IS_ERR(dt_obj)) {
			rc = PTR_ERR(dt_obj);
			CERROR("%s: Can't find \"%s\" obj %d\n", fld->lsf_name,
				fld_index_name, rc);
			dt_obj = NULL;
			GOTO(out, rc);
		}
	}

	fld->lsf_obj = dt_obj;
	rc = dt_obj->do_ops->do_index_try(env, dt_obj, &fld_index_features);
	if (rc != 0) {
		CERROR("%s: File \"%s\" is not an index: rc = %d!\n",
		       fld->lsf_name, fld_index_name, rc);
		GOTO(out, rc);
	}

	range = &info->fti_rec;
	/* Load fld entry to cache */
	iops = &dt_obj->do_index_ops->dio_it;
	it = iops->init(env, dt_obj, 0);
	if (IS_ERR(it))
		GOTO(out, rc = PTR_ERR(it));

	rc = iops->load(env, it, 0);
	if (rc < 0)
		GOTO(out_it_fini, rc);

	if (rc > 0) {
		/* Load FLD entry into server cache */
		do {
			rc = iops->rec(env, it, (struct dt_rec *)range, 0);
			if (rc != 0)
				GOTO(out_it_put, rc);
			LASSERT(range != NULL);
			range_be_to_cpu(range, range);
			rc = fld_cache_insert(fld->lsf_cache, range);
			if (rc != 0)
				GOTO(out_it_put, rc);
			rc = iops->next(env, it);
		} while (rc == 0);
	} else {
		fld->lsf_new = 1;
	}

	rc = fld_name_to_index(fld->lsf_name, &index);
	if (rc < 0)
		GOTO(out_it_put, rc);
	else
		rc = 0;

	if (index == 0 && type == LU_SEQ_RANGE_MDT) {
		/* Note: fld_insert_entry will detect whether these
		 * special entries already exist inside FLDB */
		mutex_lock(&fld->lsf_lock);
		rc = fld_insert_special_entries(env, fld);
		mutex_unlock(&fld->lsf_lock);
		if (rc != 0) {
			CERROR("%s: insert special entries failed!: rc = %d\n",
			       fld->lsf_name, rc);
			GOTO(out_it_put, rc);
		}
	}
out_it_put:
	iops->put(env, it);
out_it_fini:
	iops->fini(env, it);
out:
	if (attr != NULL)
		OBD_FREE_PTR(attr);

	if (rc < 0) {
		if (dt_obj != NULL)
			lu_object_put(env, &dt_obj->do_lu);
		fld->lsf_obj = NULL;
	}
	RETURN(rc);
}