Whamcloud - gitweb
LU-3884 lfsck: LFSCK should NOT hold root object 43/7643/3
authorFan Yong <fan.yong@intel.com>
Tue, 20 Aug 2013 15:10:04 +0000 (23:10 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 20 Sep 2013 21:29:05 +0000 (21:29 +0000)
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 <fan.yong@intel.com>
Change-Id: I068c442ae808bb2f018e93e0a584a35dcf4c2f9c
Reviewed-on: http://review.whamcloud.com/7643
Tested-by: Hudson
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lfsck/lfsck_bookmark.c
lustre/lfsck/lfsck_internal.h
lustre/lfsck/lfsck_lib.c
lustre/lfsck/lfsck_namespace.c

index 204caa8..d56d5fd 100644 (file)
@@ -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)
 {
 int lfsck_bookmark_setup(const struct lu_env *env,
                         struct lfsck_instance *lfsck)
 {
+       struct dt_object *root;
        struct dt_object *obj;
        int               rc;
        ENTRY;
 
        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);
                                        lfsck_bookmark_name,
                                        S_IFREG | S_IRUGO | S_IWUSR);
+       lu_object_put(env, &root->do_lu);
        if (IS_ERR(obj))
                RETURN(PTR_ERR(obj));
 
        if (IS_ERR(obj))
                RETURN(PTR_ERR(obj));
 
index f3694a7..56cdff0 100644 (file)
@@ -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_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;
        struct lu_fid             li_global_root_fid; /* /ROOT */
        struct dt_object         *li_bookmark_obj;
        struct lfsck_bookmark     li_bookmark_ram;
index 337bd8c..dbd9485 100644 (file)
@@ -206,11 +206,6 @@ static void lfsck_instance_cleanup(const struct lu_env *env,
                lfsck->li_los = NULL;
        }
 
                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);
 }
 
        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 (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);
                        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_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;
        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));
 
        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;
         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:
 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;
        if (rc != 0)
                lfsck_instance_cleanup(env, lfsck);
        return rc;
index 3f49e3c..a93baed 100644 (file)
@@ -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 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;
 
        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));
        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;
 
        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;
                                 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);
                                         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);
 
 out:
        up_write(&com->lc_sem);
+       lu_object_put(env, &root->do_lu);
        return rc;
 }
 
        return rc;
 }
 
@@ -1524,6 +1532,7 @@ int lfsck_namespace_setup(const struct lu_env *env,
 {
        struct lfsck_component  *com;
        struct lfsck_namespace  *ns;
 {
        struct lfsck_component  *com;
        struct lfsck_namespace  *ns;
+       struct dt_object        *root = NULL;
        struct dt_object        *obj;
        int                      rc;
        ENTRY;
        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);
 
        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);
                                         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:
        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;
        if (rc != 0)
                lfsck_component_cleanup(env, com);
        return rc;