From 2dd9885b222dfd6c9ef4dd70149830b697a08808 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Thu, 13 Sep 2012 22:42:38 +0800 Subject: [PATCH] LU-1881 mdd: cleanup partial modification Usually, the modification triggered by client will be split into several sub-operations in MDD layer and processed one by one. If some step failed, we should rollback the former sub-operation(s) to avoid partial modification the target(s) in RAM or on disk. Signed-off-by: Fan Yong Change-Id: I02559618d252f65cd3ae3b26bd186b77c9f42dcc Reviewed-on: http://review.whamcloud.com/3981 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Niu Yawei --- lustre/mdd/mdd_dir.c | 61 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 7e666eb..e3c8fb5 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -896,7 +896,12 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, if (rc) GOTO(out_unlock, rc); - mdo_ref_add(env, mdd_sobj, handle); + rc = mdo_ref_add(env, mdd_sobj, handle); + if (rc != 0) { + __mdd_index_delete_only(env, mdd_tobj, name, handle, + mdd_object_capa(env, mdd_tobj)); + GOTO(out_unlock, rc); + } LASSERT(ma->ma_attr.la_valid & LA_CTIME); la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; @@ -1110,7 +1115,14 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, if (rc) GOTO(cleanup, rc); - mdo_ref_del(env, mdd_cobj, handle); + rc = mdo_ref_del(env, mdd_cobj, handle); + if (rc != 0) { + __mdd_index_insert_only(env, mdd_pobj, mdo2fid(mdd_cobj), + name, handle, + mdd_object_capa(env, mdd_pobj)); + GOTO(cleanup, rc); + } + if (is_dir) /* unlink dot */ mdo_ref_del(env, mdd_cobj, handle); @@ -2232,25 +2244,36 @@ static int mdd_create(const struct lu_env *env, rc = mdd_attr_get_internal_locked(env, son, ma); EXIT; cleanup: - if (rc && created) { - int rc2 = 0; + if (rc != 0 && created != 0) { + int rc2; + + if (inserted != 0) { + rc2 = __mdd_index_delete(env, mdd_pobj, name, + S_ISDIR(attr->la_mode), + handle, BYPASS_CAPA); + if (rc2 != 0) + goto out_stop; + } - if (inserted) { - rc2 = __mdd_index_delete(env, mdd_pobj, name, - S_ISDIR(attr->la_mode), - handle, BYPASS_CAPA); - if (rc2) - CERROR("error can not cleanup destroy %d\n", - rc2); - } + mdd_write_lock(env, son, MOR_TGT_CHILD); + if (initialized != 0 && S_ISDIR(attr->la_mode)) { + /* Drop the reference, no need to delete "."/"..", + * because the object to be destroied directly. */ + rc2 = mdo_ref_del(env, son, handle); + if (rc2 != 0) { + mdd_write_unlock(env, son); + goto out_stop; + } + } - if (rc2 == 0) { - mdd_write_lock(env, son, MOR_TGT_CHILD); - mdo_ref_del(env, son, handle); - if (initialized && S_ISDIR(attr->la_mode)) - mdo_ref_del(env, son, handle); - mdd_write_unlock(env, son); - } + rc2 = mdo_ref_del(env, son, handle); + if (rc2 != 0) { + mdd_write_unlock(env, son); + goto out_stop; + } + + mdo_destroy(env, son, handle); + mdd_write_unlock(env, son); } /* update lov_objid data, must be before transaction stop! */ -- 1.8.3.1