From 38ee91992ac8b21143234c64c22b935680439b39 Mon Sep 17 00:00:00 2001
From: huanghua <huanghua>
Date: Wed, 16 Apr 2008 03:06:48 +0000
Subject: [PATCH] Branch HEAD b=13943 i=yury.umanets i=nikita.danilov

- more generic lu_stack_fini().
---
 lustre/include/lu_object.h  |  5 +++++
 lustre/mdt/mdt_handler.c    | 42 +---------------------------------
 lustre/obdclass/lu_object.c | 45 +++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h
index ef3645dab1..cf83ef1913 100644
--- a/lustre/include/lu_object.h
+++ b/lustre/include/lu_object.h
@@ -798,6 +798,11 @@ void lu_object_print(const struct lu_env *env, void *cookie,
  */
 int lu_object_invariant(const struct lu_object *o);
 
+/*
+ * Finalize and free devices in the device stack.
+ */
+void lu_stack_fini(const struct lu_env *env, struct lu_device *top);
+
 /*
  * Returns 1 iff object @o exists on the stable storage,
  * returns -1 iff object @o is on remote server.
diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c
index 4b100bda19..61a23b2f66 100644
--- a/lustre/mdt/mdt_handler.c
+++ b/lustre/mdt/mdt_handler.c
@@ -3507,7 +3507,6 @@ err_mdt_svc:
 static void mdt_stack_fini(const struct lu_env *env,
                            struct mdt_device *m, struct lu_device *top)
 {
-        struct lu_device        *d = top, *n;
         struct obd_device       *obd = m->mdt_md_dev.md_lu_dev.ld_obd;
         struct lustre_cfg_bufs  *bufs;
         struct lustre_cfg       *lcfg;
@@ -3536,46 +3535,7 @@ static void mdt_stack_fini(const struct lu_env *env,
         top->ld_ops->ldo_process_config(env, top, lcfg);
         lustre_cfg_free(lcfg);
 
-        lu_site_purge(env, top->ld_site, ~0);
-        while (d != NULL) {
-                struct lu_device_type *ldt = d->ld_type;
-
-                /* each fini() returns next device in stack of layers
-                 * so we can avoid the recursion */
-                n = ldt->ldt_ops->ldto_device_fini(env, d);
-                lu_device_put(d);
-
-                /* switch to the next device in the layer */
-                d = n;
-        }
- 
-        /* purge again. */
-        lu_site_purge(env, top->ld_site, ~0);
-
-        if (!list_empty(&top->ld_site->ls_lru) || top->ld_site->ls_total != 0) {
-                /*
-                 * Uh-oh, objects still exist.
-                 */
-                static DECLARE_LU_CDEBUG_PRINT_INFO(cookie, D_ERROR);
-
-                lu_site_print(env, top->ld_site, &cookie, lu_cdebug_printer);
-        }
-
-        d = top;
-        while (d != NULL) {
-                struct obd_type *type;
-                struct lu_device_type *ldt = d->ld_type;
-
-                /* each free() returns next device in stack of layers
-                 * so we can avoid the recursion */
-                n = ldt->ldt_ops->ldto_device_free(env, d);
-                type = ldt->ldt_obd_type;
-                type->typ_refcnt--;
-                class_put_type(type);
-
-                /* switch to the next device in the layer */
-                d = n;
-        }
+        lu_stack_fini(env, top);
         m->mdt_child = NULL;
         m->mdt_bottom = NULL;
 }
diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c
index 4dfe1399ad..ee55b41788 100644
--- a/lustre/obdclass/lu_object.c
+++ b/lustre/obdclass/lu_object.c
@@ -783,6 +783,51 @@ struct lu_object *lu_object_locate(struct lu_object_header *h,
 }
 EXPORT_SYMBOL(lu_object_locate);
 
+
+
+/*
+ * Finalize and free devices in the device stack.
+ * 
+ * Finalize device stack by purging object cache, and calling
+ * lu_device_type_operations::ldto_device_fini() and
+ * lu_device_type_operations::ldto_device_free() on all devices in the stack.
+ */
+void lu_stack_fini(const struct lu_env *env, struct lu_device *top)
+{
+        struct lu_site   *site = top->ld_site;
+        struct lu_device *scan;
+        struct lu_device *next;
+
+        lu_site_purge(env, site, ~0);
+        for (scan = top; scan != NULL; scan = next) {
+                next = scan->ld_type->ldt_ops->ldto_device_fini(env, scan);
+                lu_device_put(scan);
+        }
+
+        /* purge again. */
+        lu_site_purge(env, site, ~0);
+
+        if (!list_empty(&site->ls_lru) || site->ls_total != 0) {
+                /*
+                 * Uh-oh, objects still exist.
+                 */
+                static DECLARE_LU_CDEBUG_PRINT_INFO(cookie, D_ERROR);
+
+                lu_site_print(env, site, &cookie, lu_cdebug_printer);
+        }
+
+        for (scan = top; scan != NULL; scan = next) {
+                const struct lu_device_type *ldt = scan->ld_type;
+                struct obd_type             *type;
+
+                next = ldt->ldt_ops->ldto_device_free(env, scan);
+                type = ldt->ldt_obd_type;
+                type->typ_refcnt--;
+                class_put_type(type);
+        }
+}
+EXPORT_SYMBOL(lu_stack_fini);
+
 enum {
         /*
          * Maximal number of tld slots.
-- 
GitLab