From f5a8f1bcf5563f96cf6ba0e5de5a99a1ea524cc6 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. Signed-off-by: Alex Zhuravlev Change-Id: Ied59f1a95458e8890249b92d4efc38e258a7e3cf Reviewed-on: https://review.whamcloud.com/38385 Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- 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 0c71b26..2684966 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 ac1554a..7f00ec1 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); @@ -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. */ diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index 8e8b1ad..5fb55bf 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -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) { -- 1.8.3.1