Example #1
0
/*
 * Reserve enough credits to update a record in a quota index file.
 *
 * \param env - is the environment passed by the caller
 * \param th  - is the transaction to use for disk writes
 * \param obj - is the on-disk index where quota settings are stored.
 * \param id  - is the key to be updated
 *
 * \retval    - 0 on success, appropriate error on failure
 */
int lquota_disk_declare_write(const struct lu_env *env, struct thandle *th,
			      struct dt_object *obj, union lquota_id *id)
{
	struct lquota_thread_info	*qti = lquota_info(env);
	struct dt_key			*key = (struct dt_key *)&id->qid_uid;
	int				 rc;
	ENTRY;

	LASSERT(dt_object_exists(obj));
	LASSERT(obj->do_index_ops != NULL);

	/* speculative delete declaration in case there is already an existing
	 * record in the index */
	rc = dt_declare_delete(env, obj, key, th);
	if (rc)
		RETURN(rc);

	/* declare insertion of updated record */
	rc = dt_declare_insert(env, obj, (struct dt_rec *)&qti->qti_rec, key,
			       th);
	if (rc)
		RETURN(rc);

	/* we might have to update the version of the global index too */
	rc = dt_declare_version_set(env, obj, th);

	RETURN(rc);
}
Example #2
0
/*
 * Write a global record
 *
 * \param env - is the environment passed by the caller
 * \param obj - is the on-disk global index to be updated
 * \param id  - index to be updated
 * \param rec - record to be written
 */
int lquota_disk_write_glb(const struct lu_env *env, struct dt_object *obj,
			  __u64 id, struct lquota_glb_rec *rec)
{
	struct dt_device	*dev = lu2dt_dev(obj->do_lu.lo_dev);
	struct thandle		*th;
	struct dt_key		*key = (struct dt_key *)&id;
	int			 rc;
	ENTRY;

	th = dt_trans_create(env, dev);
	if (IS_ERR(th))
		RETURN(PTR_ERR(th));

	/* the entry with 0 key can always be found in IAM file. */
	if (id == 0) {
		rc = dt_declare_delete(env, obj, key, th);
		if (rc)
			GOTO(out, rc);
	}

	rc = dt_declare_insert(env, obj, (struct dt_rec *)rec, key, th);
	if (rc)
		GOTO(out, rc);

	rc = dt_trans_start_local(env, dev, th);
	if (rc)
		GOTO(out, rc);

	dt_write_lock(env, obj, 0);

	if (id == 0) {
		struct lquota_glb_rec *tmp;

		OBD_ALLOC_PTR(tmp);
		if (tmp == NULL)
			GOTO(out_lock, rc = -ENOMEM);

		rc = dt_lookup(env, obj, (struct dt_rec *)tmp, key,
			       BYPASS_CAPA);

		OBD_FREE_PTR(tmp);
		if (rc == 0) {
			rc = dt_delete(env, obj, key, th, BYPASS_CAPA);
			if (rc)
				GOTO(out_lock, rc);
		}
		rc = 0;
	}

	rc = dt_insert(env, obj, (struct dt_rec *)rec, key, th, BYPASS_CAPA, 1);
out_lock:
	dt_write_unlock(env, obj);
out:
	dt_trans_stop(env, dev, th);
	RETURN(rc);
}
Example #3
0
int fld_declare_index_create(const struct lu_env *env,
			     struct lu_server_fld *fld,
			     const struct lu_seq_range *new_range,
			     struct thandle *th)
{
	struct lu_seq_range	*tmp;
	struct lu_seq_range	*range;
	struct fld_thread_info	*info;
	int			rc = 0;

	ENTRY;

	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
	range = &info->fti_lrange;
	tmp = &info->fti_irange;
	memset(range, 0, sizeof(*range));

	rc = fld_index_lookup(env, fld, new_range->lsr_start, range);
	if (rc == 0) {
		/* In case of duplicate entry, the location must be same */
		LASSERT((range_compare_loc(new_range, range) == 0));
		GOTO(out, rc = -EEXIST);
	}

	if (rc != -ENOENT) {
		CERROR("%s: lookup range "DRANGE" error: rc = %d\n",
			fld->lsf_name, PRANGE(range), rc);
		GOTO(out, rc);
	}

	/* Check for merge case, since the fld entry can only be increamental,
	 * so we will only check whether it can be merged from the left. */
	if (new_range->lsr_start == range->lsr_end && range->lsr_end != 0 &&
	    range_compare_loc(new_range, range) == 0) {
		range_cpu_to_be(tmp, range);
		rc = dt_declare_delete(env, fld->lsf_obj,
				       (struct dt_key *)&tmp->lsr_start, th);
		if (rc) {
			CERROR("%s: declare record "DRANGE" failed: rc = %d\n",
			       fld->lsf_name, PRANGE(range), rc);
			GOTO(out, rc);
		}
		memcpy(tmp, new_range, sizeof(*new_range));
		tmp->lsr_start = range->lsr_start;
	} else {
		memcpy(tmp, new_range, sizeof(*new_range));
	}

	range_cpu_to_be(tmp, tmp);
	rc = dt_declare_insert(env, fld->lsf_obj, (struct dt_rec *)tmp,
			       (struct dt_key *)&tmp->lsr_start, th);
out:
	RETURN(rc);
}
Example #4
0
/**
 * Implementation of the llog_operations::lop_declare_create
 *
 * This function declares the llog create. It declares also name insert
 * into llog directory in case of named llog.
 *
 * \param[in] env	execution environment
 * \param[in] res	llog handle of the current llog
 * \param[in] th	current transaction handle
 *
 * \retval		0 on successful create declaration
 * \retval		negative value on error
 */
static int llog_osd_declare_create(const struct lu_env *env,
				   struct llog_handle *res, struct thandle *th)
{
	struct llog_thread_info		*lgi = llog_info(env);
	struct dt_insert_rec		*rec = &lgi->lgi_dt_rec;
	struct local_oid_storage	*los;
	struct dt_object		*o;
	int				 rc;

	ENTRY;

	LASSERT(res->lgh_obj);
	LASSERT(th);

	/* object can be created by another thread */
	o = res->lgh_obj;
	if (dt_object_exists(o))
		RETURN(0);

	los = res->private_data;
	LASSERT(los);

	rc = llog_osd_declare_new_object(env, los, o, th);
	if (rc)
		RETURN(rc);

	/* do not declare header initialization here as it's declared
	 * in llog_osd_declare_write_rec() which is always called */

	if (res->lgh_name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, res->lgh_ctxt);
		if (IS_ERR(llog_dir))
			RETURN(PTR_ERR(llog_dir));
		logid_to_fid(&res->lgh_id, &lgi->lgi_fid);
		rec->rec_fid = &lgi->lgi_fid;
		rec->rec_type = S_IFREG;
		rc = dt_declare_insert(env, llog_dir,
				       (struct dt_rec *)rec,
				       (struct dt_key *)res->lgh_name, th);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc)
			CERROR("%s: can't declare named llog %s: rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       res->lgh_name, rc);
	}
	RETURN(rc);
}
Example #5
0
static int llog_osd_declare_create(const struct lu_env *env,
				   struct llog_handle *res, struct thandle *th)
{
	struct llog_thread_info		*lgi = llog_info(env);
	struct local_oid_storage	*los;
	struct dt_object		*o;
	int				 rc;

	ENTRY;

	LASSERT(res->lgh_obj);
	LASSERT(th);

	/* object can be created by another thread */
	o = res->lgh_obj;
	if (dt_object_exists(o))
		RETURN(0);

	los = res->private_data;
	LASSERT(los);

	rc = llog_osd_declare_new_object(env, los, o, th);
	if (rc)
		RETURN(rc);

	rc = dt_declare_record_write(env, o, LLOG_CHUNK_SIZE, 0, th);
	if (rc)
		RETURN(rc);

	if (res->lgh_name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, res->lgh_ctxt);
		if (IS_ERR(llog_dir))
			RETURN(PTR_ERR(llog_dir));
		dt_declare_ref_add(env, o, th);
		logid_to_fid(&res->lgh_id, &lgi->lgi_fid);
		rc = dt_declare_insert(env, llog_dir,
				       (struct dt_rec *)&lgi->lgi_fid,
				       (struct dt_key *)res->lgh_name, th);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc)
			CERROR("%s: can't declare named llog %s: rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       res->lgh_name, rc);
	}
	RETURN(rc);
}
Example #6
0
int orph_declare_index_insert(const struct lu_env *env,
			      struct mdd_object *obj,
			      umode_t mode, struct thandle *th)
{
	struct dt_insert_rec	*rec = &mdd_env_info(env)->mti_dt_rec;
	struct mdd_device	*mdd = mdo2mdd(&obj->mod_obj);
	struct dt_key		*key;
	int			rc;

	key = orph_key_fill(env, mdo2fid(obj), ORPH_OP_UNLINK);

	rec->rec_fid = mdo2fid(obj);
	rec->rec_type = mode;
	rc = dt_declare_insert(env, mdd->mdd_orphans,
			       (const struct dt_rec *)rec, key, th);
	if (rc != 0)
		return rc;

	rc = mdo_declare_ref_add(env, obj, th);
	if (rc)
		return rc;

	if (!S_ISDIR(mode))
		return 0;

	rc = mdo_declare_ref_add(env, obj, th);
	if (rc)
		return rc;

	rc = dt_declare_ref_add(env, mdd->mdd_orphans, th);
	if (rc)
		return rc;

	rc = mdo_declare_index_delete(env, obj, dotdot, th);
	if (rc)
		return rc;

	rc = mdo_declare_index_insert(env, obj,
				      lu_object_fid(&mdd->mdd_orphans->do_lu),
				      S_IFDIR, dotdot, th);

	return rc;
}
Example #7
0
static int __out_tx_index_insert(const struct lu_env *env,
				 struct dt_object *dt_obj,
				 char *name, struct lu_fid *fid,
				 struct thandle_exec_args *ta,
				 struct update_reply *reply,
				 int index, char *file, int line)
{
	struct tx_arg *arg;

	LASSERT(ta->ta_handle != NULL);

	if (lu_object_exists(&dt_obj->do_lu)) {
		if (dt_try_as_dir(env, dt_obj) == 0) {
			ta->ta_err = -ENOTDIR;
			return ta->ta_err;
		}
		ta->ta_err = dt_declare_insert(env, dt_obj,
					       (struct dt_rec *)fid,
					       (struct dt_key *)name,
					       ta->ta_handle);
	}

	if (ta->ta_err != 0)
		return ta->ta_err;

	arg = tx_add_exec(ta, out_tx_index_insert_exec,
			  out_tx_index_insert_undo, file,
			  line);
	LASSERT(arg);
	lu_object_get(&dt_obj->do_lu);
	arg->object = dt_obj;
	arg->reply = reply;
	arg->index = index;
	arg->u.insert.rec = (struct dt_rec *)fid;
	arg->u.insert.key = (struct dt_key *)name;

	return 0;
}
Example #8
0
int orph_declare_index_insert(const struct lu_env *env,
			      struct mdd_object *obj,
			      cfs_umode_t mode, struct thandle *th)
{
	struct mdd_device	*mdd = mdo2mdd(&obj->mod_obj);
	struct dt_key		*key;
	int			rc;

	key = orph_key_fill(env, mdo2fid(obj), ORPH_OP_UNLINK);

	rc = dt_declare_insert(env, mdd->mdd_orphans, NULL, key, th);
	if (rc)
		return rc;

	rc = mdo_declare_ref_add(env, obj, th);
	if (rc)
		return rc;

	if (!S_ISDIR(mode))
		return 0;

	rc = mdo_declare_ref_add(env, obj, th);
	if (rc)
		return rc;

	rc = dt_declare_ref_add(env, mdd->mdd_orphans, th);
	if (rc)
		return rc;

	rc = mdo_declare_index_delete(env, obj, dotdot, th);
	if (rc)
		return rc;

	rc = mdo_declare_index_insert(env, obj, NULL, dotdot, th);

	return rc;
}
Example #9
0
static int lfsck_namespace_update(const struct lu_env *env,
				  struct lfsck_component *com,
				  const struct lu_fid *fid,
				  __u8 flags, bool force)
{
	struct lfsck_instance	*lfsck  = com->lc_lfsck;
	struct lu_fid		*key    = &lfsck_env_info(env)->lti_fid;
	struct thandle		*handle;
	struct dt_object	*obj    = com->lc_obj;
	int			 rc;
	bool			 exist  = false;
	__u8			 tf;
	ENTRY;

	rc = lfsck_namespace_lookup(env, com, fid, &tf);
	if (rc != 0 && rc != -ENOENT)
		RETURN(rc);

	if (rc == 0) {
		if (!force || flags == tf)
			RETURN(0);

		exist = true;
		handle = dt_trans_create(env, lfsck->li_bottom);
		if (IS_ERR(handle))
			RETURN(PTR_ERR(handle));

		rc = dt_declare_delete(env, obj, (const struct dt_key *)fid,
				       handle);
		if (rc != 0)
			GOTO(out, rc);
	} else {
		handle = dt_trans_create(env, lfsck->li_bottom);
		if (IS_ERR(handle))
			RETURN(PTR_ERR(handle));
	}

	rc = dt_declare_insert(env, obj, (const struct dt_rec *)&flags,
			       (const struct dt_key *)fid, handle);
	if (rc != 0)
		GOTO(out, rc);

	rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
	if (rc != 0)
		GOTO(out, rc);

	fid_cpu_to_be(key, fid);
	if (exist) {
		rc = dt_delete(env, obj, (const struct dt_key *)key, handle,
			       BYPASS_CAPA);
		if (rc != 0) {
			CERROR("%s: fail to insert "DFID": rc = %d\n",
			       lfsck_lfsck2name(com->lc_lfsck), PFID(fid), rc);
			GOTO(out, rc);
		}
	}

	rc = dt_insert(env, obj, (const struct dt_rec *)&flags,
		       (const struct dt_key *)key, handle, BYPASS_CAPA, 1);

	GOTO(out, rc);

out:
	dt_trans_stop(env, lfsck->li_bottom, handle);
	return rc;
}