Whamcloud - gitweb
LU-7713 osd: osd-zfs should serialize destroy vs. others
[fs/lustre-release.git] / lustre / mdd / mdd_dir.c
index 6f7f17c..eab1629 100644 (file)
@@ -1467,10 +1467,6 @@ int mdd_finish_unlink(const struct lu_env *env,
                 * will be deleted during mdd_close() */
                obj->mod_flags |= DEAD_OBJ;
                if (obj->mod_count) {
-                       rc = mdd_mark_orphan_object(env, obj, th, false);
-                       if (rc != 0)
-                               RETURN(rc);
-
                        rc = __mdd_orphan_add(env, obj, th);
                        if (rc == 0)
                                CDEBUG(D_HA, "Object "DFID" is inserted into "
@@ -1483,6 +1479,12 @@ int mdd_finish_unlink(const struct lu_env *env,
                                       "open replay\n",
                                        PFID(mdd_object_fid(obj)),
                                        obj->mod_count);
+
+                       /* mark object as an orphan here, not
+                        * before __mdd_orphan_add() as racing
+                        * mdd_la_get() may propagate ORPHAN_OBJ
+                        * causing the asserition */
+                       rc = mdd_mark_orphan_object(env, obj, th, false);
                } else {
                        rc = mdo_destroy(env, obj, th);
                }
@@ -1591,7 +1593,7 @@ static bool mdd_hsm_archive_exists(const struct lu_env *env,
                if (rc < 0)
                        RETURN(false);
 
-               ma->ma_valid = MA_HSM;
+               ma->ma_valid |= MA_HSM;
        }
        if (ma->ma_hsm.mh_flags & HS_EXISTS)
                RETURN(true);
@@ -1619,7 +1621,7 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
        struct mdd_object *mdd_cobj = NULL;
        struct mdd_device *mdd = mdo2mdd(pobj);
        struct thandle    *handle;
-       int rc, is_dir = 0;
+       int rc, is_dir = 0, cl_flags = 0;
        ENTRY;
 
        /* cobj == NULL means only delete name entry */
@@ -1640,6 +1642,11 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
                        RETURN(rc);
 
                is_dir = S_ISDIR(cattr->la_mode);
+               /* search for an existing archive.
+                * we should check ahead as the object
+                * can be destroyed in this transaction */
+               if (mdd_hsm_archive_exists(env, mdd_cobj, ma))
+                       cl_flags |= CLF_UNLINK_HSM_EXISTS;
        }
 
        rc = mdd_unlink_sanity_check(env, mdd_pobj, pattr, mdd_cobj, cattr);
@@ -1717,11 +1724,10 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
        ma->ma_attr = *cattr;
        ma->ma_valid |= MA_INODE;
        rc = mdd_finish_unlink(env, mdd_cobj, ma, mdd_pobj, lname, handle);
-
-       /* fetch updated nlink */
        if (rc != 0)
                GOTO(cleanup, rc);
 
+       /* fetch updated nlink */
        rc = mdd_la_get(env, mdd_cobj, cattr);
        /* if object is removed then we can't get its attrs,
         * use last get */
@@ -1741,14 +1747,10 @@ cleanup:
                mdd_write_unlock(env, mdd_cobj);
 
        if (rc == 0) {
-               int cl_flags = 0;
-
-               if (cattr->la_nlink == 0) {
+               if (cattr->la_nlink == 0)
                        cl_flags |= CLF_UNLINK_LAST;
-                       /* search for an existing archive */
-                       if (mdd_hsm_archive_exists(env, mdd_cobj, ma))
-                               cl_flags |= CLF_UNLINK_HSM_EXISTS;
-               }
+               else
+                       cl_flags &= ~CLF_UNLINK_HSM_EXISTS;
 
                rc = mdd_changelog_ns_store(env, mdd,
                        is_dir ? CL_RMDIR : CL_UNLINK, cl_flags,
@@ -2802,6 +2804,11 @@ static int mdd_rename(const struct lu_env *env,
                rc = mdd_la_get(env, mdd_tobj, tattr);
                if (rc)
                        GOTO(out_pending, rc);
+               /* search for an existing archive.
+                * we should check ahead as the object
+                * can be destroyed in this transaction */
+               if (mdd_hsm_archive_exists(env, mdd_tobj, ma))
+                       cl_flags |= CLF_RENAME_LAST_EXISTS;
        }
 
        rc = mdd_la_get(env, mdd_tpobj, tpattr);
@@ -2965,11 +2972,10 @@ static int mdd_rename(const struct lu_env *env,
                ma->ma_attr = *tattr;
                ma->ma_valid |= MA_INODE;
 
-               if (tattr->la_nlink == 0) {
+               if (tattr->la_nlink == 0)
                        cl_flags |= CLF_RENAME_LAST;
-                       if (mdd_hsm_archive_exists(env, mdd_tobj, ma))
-                               cl_flags |= CLF_RENAME_LAST_EXISTS;
-               }
+               else
+                       cl_flags &= ~CLF_RENAME_LAST_EXISTS;
         }
 
        la->la_valid = LA_CTIME | LA_MTIME;