/* * 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); }
/* * 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); }
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); }
/** * 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); }
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); }
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; }
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; }
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; }
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; }