void cl_env_unplant (struct lu_env *env, int *refcheck);
unsigned cl_env_cache_purge(unsigned nr);
-void cl_set_ctx_tags(__u32 tags);
-void cl_set_ses_tags(__u32 tags);
/** @} cl_env */
/*
void lu_context_key_revive_many (struct lu_context_key *k, ...);
void lu_context_key_quiesce_many (struct lu_context_key *k, ...);
+/*
+ * update/clear ctx/ses tags.
+ */
+void lu_context_tags_update(__u32 tags);
+void lu_context_tags_clear(__u32 tags);
+void lu_session_tags_update(__u32 tags);
+void lu_session_tags_clear(__u32 tags);
+
/**
* Environment.
*/
int lu_env_init (struct lu_env *env, __u32 tags);
void lu_env_fini (struct lu_env *env);
int lu_env_refill(struct lu_env *env);
+int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, __u32 stags);
/** @} lu_context */
/** Lock class of cl_object_header::coh_attr_guard */
static cfs_lock_class_key_t cl_attr_guard_class;
-static __u32 cl_ctx_tags;
-static __u32 cl_ses_tags;
+extern __u32 lu_context_tags_default;
+extern __u32 lu_session_tags_default;
/**
* Initialize cl_object_header.
*/
OBD_SLAB_FREE_PTR(cle, cl_env_kmem);
}
-void cl_set_ctx_tags(__u32 tags)
-{
- cl_ctx_tags = tags;
-}
-EXPORT_SYMBOL(cl_set_ctx_tags);
-
-void cl_set_ses_tags(__u32 tags)
-{
- cl_ses_tags = tags;
-}
-EXPORT_SYMBOL(cl_set_ses_tags);
-
static struct lu_env *cl_env_obtain(void *debug)
{
struct cl_env *cle;
}
} else {
cfs_spin_unlock(&cl_envs_guard);
- env = cl_env_new(cl_ctx_tags, cl_ses_tags, debug);
+ env = cl_env_new(lu_context_tags_default,
+ lu_session_tags_default, debug);
}
RETURN(env);
}
}
EXPORT_SYMBOL(lu_context_refill);
+/**
+ * lu_ctx_tags/lu_ses_tags will be updated if there are new types of
+ * obd being added. Currently, this is only used on client side, specifically
+ * for echo device client, for other stack (like ptlrpc threads), context are
+ * predefined when the lu_device type are registered, during the module probe
+ * phase.
+ */
+__u32 lu_context_tags_default = 0;
+__u32 lu_session_tags_default = 0;
+
+void lu_context_tags_update(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_context_tags_default |= tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_context_tags_update);
+
+void lu_context_tags_clear(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_context_tags_default &= ~tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_context_tags_clear);
+
+void lu_session_tags_update(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_session_tags_default |= tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_session_tags_update);
+
+void lu_session_tags_clear(__u32 tags)
+{
+ cfs_spin_lock(&lu_keys_guard);
+ lu_session_tags_default &= ~tags;
+ key_set_version ++;
+ cfs_spin_unlock(&lu_keys_guard);
+}
+EXPORT_SYMBOL(lu_session_tags_clear);
+
int lu_env_init(struct lu_env *env, __u32 tags)
{
int result;
}
EXPORT_SYMBOL(lu_env_refill);
+/**
+ * Currently, this API will only be used by echo client.
+ * Because echo client and normal lustre client will share
+ * same cl_env cache. So echo client needs to refresh
+ * the env context after it get one from the cache, especially
+ * when normal client and echo client co-exist in the same client.
+ */
+int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags,
+ __u32 stags)
+{
+ int result;
+
+ if ((env->le_ctx.lc_tags & ctags) != ctags) {
+ env->le_ctx.lc_version = 0;
+ env->le_ctx.lc_tags |= ctags;
+ }
+
+ if (env->le_ses && (env->le_ses->lc_tags & stags) != stags) {
+ env->le_ses->lc_version = 0;
+ env->le_ses->lc_tags |= stags;
+ }
+
+ result = lu_env_refill(env);
+
+ return result;
+}
+EXPORT_SYMBOL(lu_env_refill_by_tags);
+
static struct cfs_shrinker *lu_site_shrinker = NULL;
typedef struct lu_site_stats{
echo_client_cleanup(d->ld_obd);
echo_fid_fini(d->ld_obd);
-
while (next && !ed->ed_next_ismd)
next = next->ld_type->ldt_ops->ldto_device_free(env, next);
RETURN(parent);
}
+#define ECHO_MD_CTX_TAG (LCT_REMEMBER | LCT_NOREF | LCT_MD_THREAD)
+#define ECHO_MD_SES_TAG (LCT_SESSION | LCT_REMEMBER | LCT_NOREF)
+
static int echo_md_handler(struct echo_device *ed, int command,
char *path, int path_len, int id, int count,
struct obd_ioctl_data *data)
struct lu_object *parent;
char *name = NULL;
int namelen = data->ioc_plen2;
- int rc = 0;
+ int rc = 0;
ENTRY;
if (ld == NULL) {
env = cl_env_get(&refcheck);
if (IS_ERR(env))
RETURN(PTR_ERR(env));
- lu_env_refill(env);
+
+ rc = lu_env_refill_by_tags(env, ECHO_MD_CTX_TAG, ECHO_MD_SES_TAG);
+ if (rc != 0) {
+ cl_env_put(env, &refcheck);
+ RETURN(rc);
+ }
parent = echo_resolve_path(env, ed, path, path_len);
if (IS_ERR(parent)) {
env = cl_env_get(&refcheck);
if (IS_ERR(env))
GOTO(out, rc = PTR_ERR(env));
- lu_env_refill(env);
+
+ rc = lu_env_refill_by_tags(env, ECHO_MD_CTX_TAG,
+ ECHO_MD_SES_TAG);
+ if (rc != 0) {
+ cl_env_put(env, &refcheck);
+ GOTO(out, rc);
+ }
+
rc = seq_client_get_seq(env, ed->ed_cl_seq, &seq);
cl_env_put(env, &refcheck);
if (rc < 0) {
ec->ec_nstripes = 0;
if (!strcmp(tgt->obd_type->typ_name, LUSTRE_MDT_NAME)) {
- cl_set_ctx_tags(LCT_REMEMBER | LCT_NOREF | LCT_MD_THREAD);
- cl_set_ses_tags(LCT_SESSION | LCT_REMEMBER | LCT_NOREF);
+ lu_context_tags_update(ECHO_MD_CTX_TAG);
+ lu_session_tags_update(ECHO_MD_SES_TAG);
RETURN(0);
}
ENTRY;
/*Do nothing for Metadata echo client*/
- if (!ed || ed->ed_next_ismd)
+ if (ed == NULL )
RETURN(0);
+ if (ed->ed_next_ismd) {
+ lu_context_tags_clear(ECHO_MD_CTX_TAG);
+ lu_session_tags_clear(ECHO_MD_SES_TAG);
+ RETURN(0);
+ }
+
if (!cfs_list_empty(&obddev->obd_exports)) {
CERROR("still has clients!\n");
RETURN(-EBUSY);