Whamcloud - gitweb
LU-13195 osp: track destroyed OSP object 85/38385/11
authorAlex Zhuravlev <bzzz@whamcloud.com>
Mon, 27 Apr 2020 04:52:01 +0000 (07:52 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 17 Sep 2021 14:06:42 +0000 (14:06 +0000)
retain destroyed OSP objects in memory to prevent races when
in-flight destroyed is passed by read or attr_get leading to
incorrect local states.
also block operations to such an object with -ENOENT.

Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Change-Id: Ied59f1a95458e8890249b92d4efc38e258a7e3cf
Reviewed-on: https://review.whamcloud.com/38385
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/osp/osp_internal.h
lustre/osp/osp_md_object.c
lustre/osp/osp_object.c

index 0c71b26..2684966 100644 (file)
@@ -311,7 +311,8 @@ struct osp_object {
        struct dt_object        opo_obj;
        unsigned int            opo_reserved:1,
                                opo_non_exist:1,
-                               opo_stale:1;
+                               opo_stale:1,
+                               opo_destroyed:1;
 
        /* read/write lock for md osp object */
        struct rw_semaphore     opo_sem;
index ac1554a..7f00ec1 100644 (file)
@@ -1024,6 +1024,15 @@ int osp_md_declare_destroy(const struct lu_env *env, struct dt_object *dt,
        return osp_trans_update_request_create(th);
 }
 
+static int osp_destroy_interpreter(const struct lu_env *env,
+                                  struct object_update_reply *reply,
+                                  struct ptlrpc_request *req,
+                                  struct osp_object *obj,
+                                  void *data, int index, int rc)
+{
+       return 0;
+}
+
 /**
  * Implement OSP layer dt_object_operations::do_destroy() interface.
  *
@@ -1046,9 +1055,10 @@ int osp_md_destroy(const struct lu_env *env, struct dt_object *dt,
        struct osp_device *osp = lu2osp_dev(dt->do_lu.lo_dev);
        struct osp_update_request *update;
        int rc = 0;
-
        ENTRY;
+
        o->opo_non_exist = 1;
+       o->opo_destroyed = 1;
 
        LASSERT(osp->opd_connect_mdt);
        update = thandle_to_osp_update_request(th);
@@ -1059,6 +1069,12 @@ int osp_md_destroy(const struct lu_env *env, struct dt_object *dt,
        if (rc != 0)
                RETURN(rc);
 
+       /* retain the object and it's status until it's destroyed on remote */
+       rc = osp_insert_update_callback(env, update, o, NULL,
+                                       osp_destroy_interpreter);
+       if (rc != 0)
+               RETURN(rc);
+
        set_bit(LU_OBJECT_HEARD_BANSHEE, &dt->do_lu.lo_header->loh_flags);
        rc = osp_insert_update_callback(env, update, dt2osp_obj(dt), NULL,
                                        NULL);
@@ -1120,6 +1136,9 @@ static ssize_t osp_md_declare_write(const struct lu_env *env,
        struct osp_device *osp = dt2osp_dev(th->th_dev);
        int rc;
 
+       if (dt2osp_obj(dt)->opo_destroyed)
+               return -ENOENT;
+
        rc = osp_trans_update_request_create(th);
        if (rc != 0)
                return rc;
@@ -1176,6 +1195,9 @@ static ssize_t osp_md_write(const struct lu_env *env, struct dt_object *dt,
        ssize_t                   rc;
        ENTRY;
 
+       if (obj->opo_destroyed)
+               RETURN(-ENOENT);
+
        update = thandle_to_osp_update_request(th);
        LASSERT(update != NULL);
 
@@ -1241,6 +1263,9 @@ static ssize_t osp_md_read(const struct lu_env *env, struct dt_object *dt,
        int rc;
        ENTRY;
 
+       if (dt2osp_obj(dt)->opo_destroyed)
+               RETURN(-ENOENT);
+
        /* Because it needs send the update buffer right away,
         * just create an update buffer, instead of attaching the
         * update_remote list of the thandle.  */
index 8e8b1ad..5fb55bf 100644 (file)
@@ -582,6 +582,8 @@ int osp_attr_get(const struct lu_env *env, struct dt_object *dt,
 
        if (is_ost_obj(&dt->do_lu) && obj->opo_non_exist)
                RETURN(-ENOENT);
+       if (obj->opo_destroyed)
+               RETURN(-ENOENT);
 
        spin_lock(&obj->opo_lock);
        if (obj->opo_attr.la_valid != 0 && !obj->opo_stale) {