return l;
}
-static void cmm_device_free(const struct lu_env *env, struct lu_device *d)
+static struct lu_device *cmm_device_free(const struct lu_env *env,
+ struct lu_device *d)
{
struct cmm_device *m = lu2cmm_dev(d);
+ struct lu_device *next = md2lu_dev(m->cmm_child);
+ ENTRY;
LASSERT(m->cmm_tgt_count == 0);
LASSERT(list_empty(&m->cmm_targets));
OBD_FREE_PTR(m->cmm_fld);
m->cmm_fld = NULL;
}
- md_device_fini(&m->cmm_md_dev);
+ md_device_fini(&m->cmm_md_dev);
OBD_FREE_PTR(m);
+ RETURN(next);
}
/* context key constructor/destructor: cmm_key_init, cmm_key_fini */
RETURN (NULL);
}
-struct lu_device *mdc_device_alloc(const struct lu_env *env,
- struct lu_device_type *ldt,
- struct lustre_cfg *cfg)
+static struct lu_device *mdc_device_alloc(const struct lu_env *env,
+ struct lu_device_type *ldt,
+ struct lustre_cfg *cfg)
{
struct lu_device *ld;
struct mdc_device *mc;
RETURN (ld);
}
-void mdc_device_free(const struct lu_env *env, struct lu_device *ld)
+
+static struct lu_device *mdc_device_free(const struct lu_env *env,
+ struct lu_device *ld)
{
struct mdc_device *mc = lu2mdc_dev(ld);
LASSERTF(atomic_read(&ld->ld_ref) == 0,
"Refcount = %i\n", atomic_read(&ld->ld_ref));
LASSERT(list_empty(&mc->mc_linkage));
- md_device_fini(&mc->mc_md_dev);
+ md_device_fini(&mc->mc_md_dev);
OBD_FREE_PTR(mc);
+ return NULL;
}
/* context key constructor/destructor: mdc_key_init, mdc_key_fini */
struct lu_device_type *t,
struct lustre_cfg *lcfg);
/*
- * Free device. Dual to ->ldto_device_alloc().
+ * Free device. Dual to ->ldto_device_alloc(). Returns pointer to
+ * the next device in the stack.
*/
- void (*ldto_device_free)(const struct lu_env *,
- struct lu_device *);
+ struct lu_device *(*ldto_device_free)(const struct lu_env *,
+ struct lu_device *);
/*
* Initialize the devices after allocation
return l;
}
-static void mdd_device_free(const struct lu_env *env,
- struct lu_device *lu)
+static struct lu_device *mdd_device_free(const struct lu_env *env,
+ struct lu_device *lu)
{
struct mdd_device *m = lu2mdd_dev(lu);
+ struct lu_device *next = &m->mdd_child->dd_lu_dev;
+ ENTRY;
LASSERT(atomic_read(&lu->ld_ref) == 0);
md_device_fini(&m->mdd_md_dev);
OBD_FREE_PTR(m);
+ RETURN(next);
}
static struct obd_ops mdd_obd_device_ops = {
lu_site_purge(env, top->ld_site, ~0);
while (d != NULL) {
- struct obd_type *type;
struct lu_device_type *ldt = d->ld_type;
/* each fini() returns next device in stack of layers
- * * so we can avoid the recursion */
+ * so we can avoid the recursion */
n = ldt->ldt_ops->ldto_device_fini(env, d);
lu_device_put(d);
- ldt->ldt_ops->ldto_device_free(env, 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);
mdt_stack_fini(env, m, md2lu_dev(m->mdt_child));
if (ls) {
- if (!list_empty(&ls->ls_lru) || ls->ls_total != 0) {
- /*
- * Uh-oh, objects still exist.
- */
- static DECLARE_LU_CDEBUG_PRINT_INFO(cookie, D_ERROR);
-
- lu_site_print(env, ls, &cookie, lu_cdebug_printer);
- }
-
lu_site_fini(ls);
OBD_FREE_PTR(ls);
d->ld_site = NULL;
RETURN(NULL);
}
-static void mdt_device_free(const struct lu_env *env, struct lu_device *d)
+static struct lu_device *mdt_device_free(const struct lu_env *env,
+ struct lu_device *d)
{
struct mdt_device *m = mdt_dev(d);
+ ENTRY;
OBD_FREE_PTR(m);
+ RETURN(NULL);
}
static struct lu_device *mdt_device_alloc(const struct lu_env *env,
struct lu_object *l);
static int osd_object_print (const struct lu_env *env, void *cookie,
lu_printer_t p, const struct lu_object *o);
-static void osd_device_free (const struct lu_env *env,
+static struct lu_device *osd_device_free (const struct lu_env *env,
struct lu_device *m);
static void *osd_key_init (const struct lu_context *ctx,
struct lu_context_key *key);
return l;
}
-static void osd_device_free(const struct lu_env *env, struct lu_device *d)
+static struct lu_device *osd_device_free(const struct lu_env *env,
+ struct lu_device *d)
{
struct osd_device *o = osd_dev(d);
+ ENTRY;
cleanup_capa_hash(o->od_capa_hash);
dt_device_fini(&o->od_dt_dev);
OBD_FREE_PTR(o);
+ RETURN(NULL);
}
static int osd_process_config(const struct lu_env *env,