X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Flu_object.c;h=21dad60d4ea1789f26ee094b13563f7b108066bb;hb=4160b722833ea924d7c51a993bc455376ac88bc1;hp=387f0f2fc748b9079e288059475ce96434446937;hpb=f89a61cada93accbd02beee89f0610756ca595e9;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index 387f0f2..21dad60 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -121,6 +121,7 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env, struct list_head *layers; int clean; int result; + ENTRY; /* * Create top-level object slice. This will also create @@ -128,8 +129,8 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env, */ top = s->ls_top_dev->ld_ops->ldo_object_alloc(env, NULL, s->ls_top_dev); - if (IS_ERR(top)) - RETURN(top); + if (top == NULL) + RETURN(ERR_PTR(-ENOMEM)); /* * This is the only place where object fid is assigned. It's constant * after this point. @@ -194,7 +195,7 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o) * necessary, because lu_object_header is freed together with the * top-level slice. */ - INIT_LIST_HEAD(&splice); + CFS_INIT_LIST_HEAD(&splice); list_splice_init(&o->lo_header->loh_layers, &splice); while (!list_empty(&splice)) { o = container_of0(splice.next, struct lu_object, lo_linkage); @@ -213,7 +214,7 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr) struct lu_object_header *h; struct lu_object_header *temp; - INIT_LIST_HEAD(&dispose); + CFS_INIT_LIST_HEAD(&dispose); /* * Under LRU list lock, scan LRU list and move unreferenced objects to * the dispose list, removing them from LRU and hash table. @@ -290,6 +291,7 @@ struct lu_cdebug_data { struct lu_fid_pack lck_pack; }; +/* context key constructor/destructor: lu_global_key_init, lu_global_key_fini */ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data); /* @@ -496,7 +498,7 @@ EXPORT_SYMBOL(lu_object_find); /* * Global list of all sites on this node */ -static LIST_HEAD(lu_sites); +static CFS_LIST_HEAD(lu_sites); static DECLARE_MUTEX(lu_sites_guard); /* @@ -551,7 +553,7 @@ static int lu_htable_order(void) * * Size of lu_object is (arbitrary) taken as 1K (together with inode). */ - cache_size = nr_free_buffer_pages() / 100 * + cache_size = ll_nr_free_buffer_pages() / 100 * LU_CACHE_PERCENT * (CFS_PAGE_SIZE / 1024); for (bits = 1; (1 << bits) < cache_size; ++bits) { @@ -781,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. @@ -866,6 +913,7 @@ EXPORT_SYMBOL(lu_context_key_degister); void *lu_context_key_get(const struct lu_context *ctx, struct lu_context_key *key) { + LASSERT(ctx->lc_state == LCS_ENTERED); LASSERT(0 <= key->lct_index && key->lct_index < ARRAY_SIZE(lu_keys)); return ctx->lc_value[key->lct_index]; } @@ -933,6 +981,7 @@ static int keys_init(struct lu_context *ctx) int lu_context_init(struct lu_context *ctx, __u32 tags) { memset(ctx, 0, sizeof *ctx); + ctx->lc_state = LCS_INITIALIZED; ctx->lc_tags = tags; return keys_init(ctx); } @@ -943,6 +992,8 @@ EXPORT_SYMBOL(lu_context_init); */ void lu_context_fini(struct lu_context *ctx) { + LASSERT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT); + ctx->lc_state = LCS_FINALIZED; keys_fini(ctx); } EXPORT_SYMBOL(lu_context_fini); @@ -952,6 +1003,8 @@ EXPORT_SYMBOL(lu_context_fini); */ void lu_context_enter(struct lu_context *ctx) { + LASSERT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT); + ctx->lc_state = LCS_ENTERED; } EXPORT_SYMBOL(lu_context_enter); @@ -962,6 +1015,8 @@ void lu_context_exit(struct lu_context *ctx) { int i; + LASSERT(ctx->lc_state == LCS_ENTERED); + ctx->lc_state = LCS_LEFT; if (ctx->lc_value != NULL) { for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) { if (ctx->lc_value[i] != NULL) { @@ -1029,7 +1084,7 @@ static int lu_cache_shrink(int nr, unsigned int gfp_mask) struct lu_site *tmp; int cached = 0; int remain = nr; - LIST_HEAD(splice); + CFS_LIST_HEAD(splice); if (nr != 0 && !(gfp_mask & __GFP_FS)) return -1;