static int out_tx_xattr_set_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; CDEBUG(D_INFO, "%s: set xattr buf %p name %s flag %d\n", dt_obd_name(th->th_dev), arg->u.xattr_set.buf.lb_buf, arg->u.xattr_set.name, arg->u.xattr_set.flags); dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_xattr_set(env, dt_obj, &arg->u.xattr_set.buf, arg->u.xattr_set.name, arg->u.xattr_set.flags, th, NULL); dt_write_unlock(env, dt_obj); /** * Ignore errors if this is LINK EA **/ if (unlikely(rc && !strncmp(arg->u.xattr_set.name, XATTR_NAME_LINK, strlen(XATTR_NAME_LINK)))) rc = 0; CDEBUG(D_INFO, "%s: insert xattr set reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); update_insert_reply(arg->reply, NULL, 0, arg->index, rc); return rc; }
int out_tx_create_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; CDEBUG(D_OTHER, "%s: create "DFID": dof %u, mode %o\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&arg->object->do_lu)), arg->u.create.dof.dof_type, arg->u.create.attr.la_mode & S_IFMT); dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_create(env, dt_obj, &arg->u.create.attr, &arg->u.create.hint, &arg->u.create.dof, th); dt_write_unlock(env, dt_obj); CDEBUG(D_INFO, "%s: insert create reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); update_insert_reply(arg->reply, NULL, 0, arg->index, rc); return rc; }
int out_tx_end(const struct lu_env *env, struct thandle_exec_args *ta) { struct tgt_session_info *tsi = tgt_ses_info(env); int i = 0, rc; LASSERT(ta->ta_dev); LASSERT(ta->ta_handle); if (ta->ta_err != 0 || ta->ta_argno == 0) GOTO(stop, rc = ta->ta_err); rc = out_trans_start(env, ta); if (unlikely(rc)) GOTO(stop, rc); for (i = 0; i < ta->ta_argno; i++) { rc = ta->ta_args[i].exec_fn(env, ta->ta_handle, &ta->ta_args[i]); if (unlikely(rc != 0)) { CDEBUG(D_INFO, "error during execution of #%u from" " %s:%d: rc = %d\n", i, ta->ta_args[i].file, ta->ta_args[i].line, rc); while (--i >= 0) { if (ta->ta_args[i].undo_fn != NULL) ta->ta_args[i].undo_fn(env, ta->ta_handle, &ta->ta_args[i]); else CERROR("%s: undo for %s:%d: rc = %d\n", dt_obd_name(ta->ta_dev), ta->ta_args[i].file, ta->ta_args[i].line, -ENOTSUPP); } break; } } /* Only fail for real update */ tsi->tsi_reply_fail_id = OBD_FAIL_OUT_UPDATE_NET_REP; stop: CDEBUG(D_INFO, "%s: executed %u/%u: rc = %d\n", dt_obd_name(ta->ta_dev), i, ta->ta_argno, rc); out_trans_stop(env, ta, rc); ta->ta_handle = NULL; ta->ta_argno = 0; ta->ta_err = 0; RETURN(rc); }
static int out_tx_destroy_undo(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { CERROR("%s: not support destroy undo yet!: rc = %d\n", dt_obd_name(th->th_dev), -ENOTSUPP); return -ENOTSUPP; }
static int out_tx_index_delete_undo(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { CERROR("%s: Oops, can not rollback index_delete yet: rc = %d\n", dt_obd_name(th->th_dev), -ENOTSUPP); return -ENOTSUPP; }
static int out_tx_attr_set_undo(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { CERROR("%s: attr set undo "DFID" unimplemented yet!: rc = %d\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&arg->object->do_lu)), -ENOTSUPP); return -ENOTSUPP; }
static void out_reconstruct(const struct lu_env *env, struct dt_device *dt, struct dt_object *obj, struct update_reply *reply, int index) { CDEBUG(D_INFO, "%s: fork reply reply %p index %d: rc = %d\n", dt_obd_name(dt), reply, index, 0); update_insert_reply(reply, NULL, 0, index, 0); return; }
static int out_tx_attr_set_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; CDEBUG(D_OTHER, "%s: attr set "DFID"\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&dt_obj->do_lu))); dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_attr_set(env, dt_obj, &arg->u.attr_set.attr, th, NULL); dt_write_unlock(env, dt_obj); CDEBUG(D_INFO, "%s: insert attr_set reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); update_insert_reply(arg->reply, NULL, 0, arg->index, rc); return rc; }
/** * All of the xxx_undo will be used once execution failed, * But because all of the required resource has been reserved in * declare phase, i.e. if declare succeed, it should make sure * the following executing phase succeed in anyway, so these undo * should be useless for most of the time in Phase I */ int out_tx_create_undo(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { int rc; rc = out_obj_destroy(env, arg->object, th); if (rc != 0) CERROR("%s: undo failure, we are doomed!: rc = %d\n", dt_obd_name(th->th_dev), rc); return rc; }
static int out_obj_destroy(const struct lu_env *env, struct dt_object *dt_obj, struct thandle *th) { int rc; CDEBUG(D_INFO, "%s: destroy "DFID"\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&dt_obj->do_lu))); dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_destroy(env, dt_obj, th); dt_write_unlock(env, dt_obj); return rc; }
static int out_tx_ref_add_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; rc = out_obj_ref_add(env, dt_obj, th); CDEBUG(D_INFO, "%s: insert ref_add reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); update_insert_reply(arg->reply, NULL, 0, arg->index, rc); return rc; }
static int out_tx_index_delete_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { int rc; rc = out_obj_index_delete(env, arg->object, arg->u.insert.key, th); CDEBUG(D_INFO, "%s: insert idx insert reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); update_insert_reply(arg->reply, NULL, 0, arg->index, rc); return rc; }
static int out_tx_start(const struct lu_env *env, struct dt_device *dt, struct thandle_exec_args *ta) { memset(ta, 0, sizeof(*ta)); ta->ta_handle = dt_trans_create(env, dt); if (IS_ERR(ta->ta_handle)) { CERROR("%s: start handle error: rc = %ld\n", dt_obd_name(dt), PTR_ERR(ta->ta_handle)); return PTR_ERR(ta->ta_handle); } ta->ta_dev = dt; /*For phase I, sync for cross-ref operation*/ ta->ta_handle->th_sync = 1; return 0; }
static int out_tx_destroy_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; rc = out_obj_destroy(env, dt_obj, th); CDEBUG(D_INFO, "%s: insert destroy reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); object_update_result_insert(arg->reply, NULL, 0, arg->index, rc); RETURN(rc); }
static int out_tx_index_insert_exec(const struct lu_env *env, struct thandle *th, struct tx_arg *arg) { struct dt_object *dt_obj = arg->object; int rc; rc = out_obj_index_insert(env, dt_obj, arg->u.insert.rec, arg->u.insert.key, th); CDEBUG(D_INFO, "%s: insert idx insert reply %p index %d: rc = %d\n", dt_obd_name(th->th_dev), arg->reply, arg->index, rc); object_update_result_insert(arg->reply, NULL, 0, arg->index, rc); return rc; }
static int out_tx_start(const struct lu_env *env, struct dt_device *dt, struct thandle_exec_args *ta, struct obd_export *exp) { ta->ta_argno = 0; ta->ta_handle = dt_trans_create(env, dt); if (IS_ERR(ta->ta_handle)) { int rc; rc = PTR_ERR(ta->ta_handle); ta->ta_handle = NULL; CERROR("%s: start handle error: rc = %d\n", dt_obd_name(dt), rc); return rc; } if (exp->exp_need_sync) ta->ta_handle->th_sync = 1; return 0; }
static int out_obj_index_delete(const struct lu_env *env, struct dt_object *dt_obj, const struct dt_key *key, struct thandle *th) { int rc; CDEBUG(D_INFO, "%s: index delete "DFID" name: %s\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&dt_obj->do_lu)), (char *)key); if (dt_try_as_dir(env, dt_obj) == 0) return -ENOTDIR; dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_delete(env, dt_obj, key, th, NULL); dt_write_unlock(env, dt_obj); return rc; }
static int out_obj_index_insert(const struct lu_env *env, struct dt_object *dt_obj, const struct dt_rec *rec, const struct dt_key *key, struct thandle *th) { int rc; CDEBUG(D_INFO, "%s: index insert "DFID" name: %s fid "DFID"\n", dt_obd_name(th->th_dev), PFID(lu_object_fid(&dt_obj->do_lu)), (char *)key, PFID((struct lu_fid *)rec)); if (dt_try_as_dir(env, dt_obj) == 0) return -ENOTDIR; dt_write_lock(env, dt_obj, MOR_TGT_CHILD); rc = dt_insert(env, dt_obj, rec, key, th, NULL, 0); dt_write_unlock(env, dt_obj); return rc; }
static int out_tx_end(const struct lu_env *env, struct thandle_exec_args *ta, int declare_ret) { struct tgt_session_info *tsi = tgt_ses_info(env); int i; int rc; int rc1; ENTRY; if (ta->ta_handle == NULL) RETURN(0); if (declare_ret != 0 || ta->ta_argno == 0) GOTO(stop, rc = declare_ret); LASSERT(ta->ta_handle->th_dev != NULL); rc = out_trans_start(env, ta); if (unlikely(rc != 0)) GOTO(stop, rc); for (i = 0; i < ta->ta_argno; i++) { rc = ta->ta_args[i]->exec_fn(env, ta->ta_handle, ta->ta_args[i]); if (unlikely(rc != 0)) { CDEBUG(D_INFO, "error during execution of #%u from" " %s:%d: rc = %d\n", i, ta->ta_args[i]->file, ta->ta_args[i]->line, rc); while (--i >= 0) { if (ta->ta_args[i]->undo_fn != NULL) ta->ta_args[i]->undo_fn(env, ta->ta_handle, ta->ta_args[i]); else CERROR("%s: undo for %s:%d: rc = %d\n", dt_obd_name(ta->ta_handle->th_dev), ta->ta_args[i]->file, ta->ta_args[i]->line, -ENOTSUPP); } break; } CDEBUG(D_INFO, "%s: executed %u/%u: rc = %d\n", dt_obd_name(ta->ta_handle->th_dev), i, ta->ta_argno, rc); } /* Only fail for real updates, XXX right now llog updates will be * ignore, whose updates count is usually 1, so failover test * case will spot this FAIL_UPDATE_NET_REP precisely, and it will * be removed after async update patch is landed. */ if (ta->ta_argno > 1) tsi->tsi_reply_fail_id = OBD_FAIL_OUT_UPDATE_NET_REP; stop: rc1 = out_trans_stop(env, ta, rc); if (rc == 0) rc = rc1; ta->ta_handle = NULL; ta->ta_argno = 0; RETURN(rc); }