From 02eb3c533534741d7f90a2af92e13a4744f1c1f8 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Tue, 20 Aug 2013 23:10:04 +0800 Subject: [PATCH] LU-3884 lfsck: LFSCK should NOT hold root object The root object may be accessed via local storage stack and release the reference by lu_object_put_nocache(), then the root object will be marked as LU_OBJECT_HEARD_BANSHEE. On the other hand, the LFSCK still holds reference on the root object. Under such case, if some others want to access the root object, they have to wait the LFSCK to release the root object and re-generate the root object in RAM. But if the LFSCK does not release the reference on the root object until the device umount, then all the others will hung there. Test-Parameters: testlist=sanity-lfsck Signed-off-by: Fan Yong Change-Id: I068c442ae808bb2f018e93e0a584a35dcf4c2f9c Reviewed-on: http://review.whamcloud.com/7643 Tested-by: Hudson Reviewed-by: Niu Yawei Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/lfsck/lfsck_bookmark.c | 10 ++++++++-- lustre/lfsck/lfsck_internal.h | 2 +- lustre/lfsck/lfsck_lib.c | 14 +++++--------- lustre/lfsck/lfsck_namespace.c | 23 +++++++++++++++++++---- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/lustre/lfsck/lfsck_bookmark.c b/lustre/lfsck/lfsck_bookmark.c index 204caa8..d56d5fd 100644 --- a/lustre/lfsck/lfsck_bookmark.c +++ b/lustre/lfsck/lfsck_bookmark.c @@ -157,14 +157,20 @@ static int lfsck_bookmark_init(const struct lu_env *env, int lfsck_bookmark_setup(const struct lu_env *env, struct lfsck_instance *lfsck) { + struct dt_object *root; struct dt_object *obj; int rc; ENTRY; - obj = local_file_find_or_create(env, lfsck->li_los, - lfsck->li_local_root, + root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid); + if (IS_ERR(root)) + RETURN(PTR_ERR(root)); + + dt_try_as_dir(env, root); + obj = local_file_find_or_create(env, lfsck->li_los, root, lfsck_bookmark_name, S_IFREG | S_IRUGO | S_IWUSR); + lu_object_put(env, &root->do_lu); if (IS_ERR(obj)) RETURN(PTR_ERR(obj)); diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h index f3694a7..56cdff0 100644 --- a/lustre/lfsck/lfsck_internal.h +++ b/lustre/lfsck/lfsck_internal.h @@ -293,7 +293,7 @@ struct lfsck_instance { struct dt_device *li_bottom; struct ldlm_namespace *li_namespace; struct local_oid_storage *li_los; - struct dt_object *li_local_root; /* backend root "/" */ + struct lu_fid li_local_root_fid; /* backend root "/" */ struct lu_fid li_global_root_fid; /* /ROOT */ struct dt_object *li_bookmark_obj; struct lfsck_bookmark li_bookmark_ram; diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 337bd8c..dbd9485 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -206,11 +206,6 @@ static void lfsck_instance_cleanup(const struct lu_env *env, lfsck->li_los = NULL; } - if (lfsck->li_local_root != NULL) { - lu_object_put_nocache(env, &lfsck->li_local_root->do_lu); - lfsck->li_local_root = NULL; - } - OBD_FREE_PTR(lfsck); } @@ -481,8 +476,7 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, if (rc != 0) return rc; - if (unlikely(lu_fid_eq(fid, - lfsck_dto2fid(lfsck->li_local_root)))) + if (unlikely(lu_fid_eq(fid, &lfsck->li_local_root_fid))) return 0; obj = lfsck_object_find(env, lfsck, fid); @@ -1076,7 +1070,7 @@ int lfsck_register(const struct lu_env *env, struct dt_device *key, struct dt_device *next, bool master) { struct lfsck_instance *lfsck; - struct dt_object *root; + struct dt_object *root = NULL; struct dt_object *obj; struct lu_fid *fid = &lfsck_env_info(env)->lti_fid; int rc; @@ -1117,7 +1111,7 @@ int lfsck_register(const struct lu_env *env, struct dt_device *key, if (IS_ERR(root)) GOTO(out, rc = PTR_ERR(root)); - lfsck->li_local_root = root; + lfsck->li_local_root_fid = *fid; dt_try_as_dir(env, root); if (master) { lfsck->li_master = 1; @@ -1161,6 +1155,8 @@ int lfsck_register(const struct lu_env *env, struct dt_device *key, add: rc = lfsck_instance_add(lfsck); out: + if (root != NULL && !IS_ERR(root)) + lu_object_put(env, &root->do_lu); if (rc != 0) lfsck_instance_cleanup(env, lfsck); return rc; diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 3f49e3c..a93baed 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -652,10 +652,17 @@ static int lfsck_namespace_reset(const struct lu_env *env, struct lfsck_instance *lfsck = com->lc_lfsck; struct lfsck_namespace *ns = (struct lfsck_namespace *)com->lc_file_ram; + struct dt_object *root; struct dt_object *dto; int rc; ENTRY; + root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid); + if (IS_ERR(root)) + RETURN(PTR_ERR(root)); + + dt_try_as_dir(env, root); + down_write(&com->lc_sem); if (init) { memset(ns, 0, sizeof(*ns)); @@ -670,14 +677,14 @@ static int lfsck_namespace_reset(const struct lu_env *env, ns->ln_magic = LFSCK_NAMESPACE_MAGIC; ns->ln_status = LS_INIT; - rc = local_object_unlink(env, lfsck->li_bottom, lfsck->li_local_root, + rc = local_object_unlink(env, lfsck->li_bottom, root, lfsck_namespace_name); if (rc != 0) GOTO(out, rc); lfsck_object_put(env, com->lc_obj); com->lc_obj = NULL; - dto = local_index_find_or_create(env, lfsck->li_los, lfsck->li_local_root, + dto = local_index_find_or_create(env, lfsck->li_los, root, lfsck_namespace_name, S_IFREG | S_IRUGO | S_IWUSR, &dt_lfsck_features); @@ -695,6 +702,7 @@ static int lfsck_namespace_reset(const struct lu_env *env, out: up_write(&com->lc_sem); + lu_object_put(env, &root->do_lu); return rc; } @@ -1524,6 +1532,7 @@ int lfsck_namespace_setup(const struct lu_env *env, { struct lfsck_component *com; struct lfsck_namespace *ns; + struct dt_object *root = NULL; struct dt_object *obj; int rc; ENTRY; @@ -1550,8 +1559,12 @@ int lfsck_namespace_setup(const struct lu_env *env, if (com->lc_file_disk == NULL) GOTO(out, rc = -ENOMEM); - obj = local_index_find_or_create(env, lfsck->li_los, - lfsck->li_local_root, + root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid); + if (IS_ERR(root)) + GOTO(out, rc = PTR_ERR(root)); + + dt_try_as_dir(env, root); + obj = local_index_find_or_create(env, lfsck->li_los, root, lfsck_namespace_name, S_IFREG | S_IRUGO | S_IWUSR, &dt_lfsck_features); @@ -1600,6 +1613,8 @@ int lfsck_namespace_setup(const struct lu_env *env, GOTO(out, rc = 0); out: + if (root != NULL && !IS_ERR(root)) + lu_object_put(env, &root->do_lu); if (rc != 0) lfsck_component_cleanup(env, com); return rc; -- 1.8.3.1