+static int mdd_declare_rename(const struct lu_env *env,
+ struct mdd_device *mdd,
+ struct mdd_object *mdd_spobj,
+ struct mdd_object *mdd_tpobj,
+ struct mdd_object *mdd_sobj,
+ struct mdd_object *mdd_tobj,
+ const struct lu_name *sname,
+ const struct lu_name *tname,
+ struct md_attr *ma,
+ struct thandle *handle)
+{
+ int rc;
+
+ LASSERT(mdd_spobj);
+ LASSERT(mdd_tpobj);
+ LASSERT(mdd_sobj);
+
+ /* name from source dir */
+ rc = mdo_declare_index_delete(env, mdd_spobj, sname->ln_name, handle);
+ if (rc)
+ return rc;
+
+ /* .. from source child */
+ if (S_ISDIR(mdd_object_type(mdd_sobj))) {
+ /* source child can be directory,
+ * counted by source dir's nlink */
+ rc = mdo_declare_ref_del(env, mdd_spobj, handle);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_index_delete(env, mdd_sobj, dotdot, handle);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_index_insert(env, mdd_sobj, mdo2fid(mdd_tpobj),
+ dotdot, handle);
+ if (rc)
+ return rc;
+
+ /* new target child can be directory,
+ * counted by target dir's nlink */
+ rc = mdo_declare_ref_add(env, mdd_tpobj, handle);
+ if (rc)
+ return rc;
+
+ }
+
+ rc = mdo_declare_attr_set(env, mdd_spobj, NULL, handle);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_attr_set(env, mdd_sobj, NULL, handle);
+ if (rc)
+ return rc;
+ mdd_declare_links_add(env, mdd_sobj, handle);
+ if (rc)
+ return rc;
+
+ rc = mdo_declare_attr_set(env, mdd_tpobj, NULL, handle);
+ if (rc)
+ return rc;
+
+ /* new name */
+ rc = mdo_declare_index_insert(env, mdd_tpobj, mdo2fid(mdd_sobj),
+ tname->ln_name, handle);
+ if (rc)
+ return rc;
+
+ /* name from target dir (old name), we declare it unconditionally
+ * as mdd_rename() calls delete unconditionally as well. so just
+ * to balance declarations vs calls to change ... */
+ rc = mdo_declare_index_delete(env, mdd_tpobj, tname->ln_name, handle);
+ if (rc)
+ return rc;
+
+ if (mdd_tobj && mdd_object_exists(mdd_tobj)) {
+ /* delete target child in target parent directory */
+ rc = mdo_declare_ref_del(env, mdd_tobj, handle);
+ if (rc)
+ return rc;
+
+ if (S_ISDIR(mdd_object_type(mdd_tobj))) {
+ /* target child can be directory,
+ * delete "." reference in target child directory */
+ rc = mdo_declare_ref_del(env, mdd_tobj, handle);
+ if (rc)
+ return rc;
+
+ /* delete ".." reference in target parent directory */
+ rc = mdo_declare_ref_del(env, mdd_tpobj, handle);
+ if (rc)
+ return rc;
+ }
+
+ rc = mdo_declare_attr_set(env, mdd_tobj, NULL, handle);
+ if (rc)
+ return rc;
+
+ mdd_declare_links_add(env, mdd_tobj, handle);
+ if (rc)
+ return rc;
+
+ rc = mdd_declare_finish_unlink(env, mdd_tobj, ma, handle);
+ if (rc)
+ return rc;
+ }
+
+ rc = mdd_declare_changelog_store(env, mdd, tname, handle);
+ if (rc)
+ return rc;
+
+ rc = mdd_declare_changelog_store(env, mdd, sname, handle);
+ if (rc)
+ return rc;
+
+ return rc;
+}
+