From 705ab2859024504256a732f63c8979460a97d163 Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Mon, 27 Apr 2020 07:52:01 +0300 Subject: [PATCH] LU-13195 osp: track destroyed OSP object 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. Lustre-change: https://review.whamcloud.com/38385 Lustre-commit: f5a8f1bcf5563f96cf6ba0e5de5a99a1ea524cc6 Signed-off-by: Alex Zhuravlev Change-Id: Ied59f1a95458e8890249b92d4efc38e258a7e3cf Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Reviewed-on: https://review.whamcloud.com/46338 Tested-by: jenkins Tested-by: Maloo --- lustre/osp/osp_internal.h | 3 ++- lustre/osp/osp_md_object.c | 27 ++++++++++++++++++++++++++- lustre/osp/osp_object.c | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h index 7438355..af10f60 100644 --- a/lustre/osp/osp_internal.h +++ b/lustre/osp/osp_internal.h @@ -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; diff --git a/lustre/osp/osp_md_object.c b/lustre/osp/osp_md_object.c index 01371e8..d565f0c 100644 --- a/lustre/osp/osp_md_object.c +++ b/lustre/osp/osp_md_object.c @@ -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); @@ -1119,6 +1135,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; @@ -1174,6 +1193,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); @@ -1239,6 +1261,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. */ diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index ce3f40b..2854d23 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -549,6 +549,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) { -- 1.8.3.1