Whamcloud - gitweb
LU-12616 obclass: fix MDS start/stop race
[fs/lustre-release.git] / lustre / mdd / mdd_device.c
index ac5ee30..1a9a8e6 100644 (file)
@@ -839,9 +839,21 @@ static int mdd_dummy_unlink(const struct lu_env *env,
        return -EPERM;
 }
 
+int mdd_create(const struct lu_env *env, struct md_object *pobj,
+                     const struct lu_name *lname, struct md_object *child,
+                     struct md_op_spec *spec, struct md_attr *ma);
+static int mdd_obf_create(const struct lu_env *env, struct md_object *pobj,
+                     const struct lu_name *lname, struct md_object *child,
+                     struct md_op_spec *spec, struct md_attr *ma)
+{
+       if (spec->sp_cr_flags & MDS_OPEN_VOLATILE)
+               return mdd_create(env, pobj, lname, child, spec, ma);
+       RETURN(-EPERM);
+}
+
 static struct md_dir_operations mdd_obf_dir_ops = {
        .mdo_lookup = obf_lookup,
-       .mdo_create = mdd_dummy_create,
+       .mdo_create = mdd_obf_create,
        .mdo_rename = mdd_dummy_rename,
        .mdo_link   = mdd_dummy_link,
        .mdo_unlink = mdd_dummy_unlink
@@ -1095,10 +1107,11 @@ static int mdd_process_config(const struct lu_env *env,
 
         switch (cfg->lcfg_command) {
        case LCFG_PARAM: {
-               struct obd_device *obd = mdd2obd_dev(m);
+               ssize_t count;
 
-               rc = class_process_proc_param(PARAM_MDD, obd->obd_vars, cfg, m);
-               if (rc > 0 || rc == -ENOSYS)
+               count = class_modify_config(cfg, PARAM_MDD, &m->mdd_kobj);
+               rc = count > 0 ? 0 : count;
+               if (rc)
                        /* we don't understand; pass it on */
                        rc = next->ld_ops->ldo_process_config(env, next, cfg);
                break;
@@ -1330,7 +1343,7 @@ static int mdd_statfs(const struct lu_env *env, struct md_device *m,
 
        ENTRY;
 
-       rc = mdd_child_ops(mdd)->dt_statfs(env, mdd->mdd_child, sfs);
+       rc = mdd_child_ops(mdd)->dt_statfs(env, mdd->mdd_child, sfs, NULL);
 
        sfs->os_namelen = min_t(__u32, sfs->os_namelen, NAME_MAX);
 
@@ -1639,6 +1652,8 @@ int mdd_changelog_user_purge(const struct lu_env *env,
                              mdd_changelog_user_purge_cb, &mcup,
                              0, 0);
 
+       OBD_FAIL_TIMEOUT(OBD_FAIL_LLOG_PURGE_DELAY, cfs_fail_val);
+
        if ((rc == 0) && (mcup.mcup_usercount == 0)) {
                spin_lock(&mdd->mdd_cl.mc_user_lock);
                if (mdd->mdd_cl.mc_users == 0) {
@@ -1886,7 +1901,15 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m,
                if (unlikely(!barrier_entry(mdd->mdd_bottom)))
                        RETURN(-EINPROGRESS);
 
-               rc = mdd_changelog_user_purge(env, mdd, data->ioc_u32_1);
+               /* explicitly clear changelog first, to protect from crash in
+                * the middle of purge that would lead to unregistered consumer
+                * but pending changelog entries
+                */
+               rc = mdd_changelog_clear(env, mdd, data->ioc_u32_1, 0);
+               if (!rc)
+                       rc = mdd_changelog_user_purge(env,
+                                                     mdd, data->ioc_u32_1);
+
                barrier_exit(mdd->mdd_bottom);
                break;
        default:
@@ -1982,7 +2005,7 @@ static int __init mdd_init(void)
        if (rc)
                return rc;
 
-       rc = class_register_type(&mdd_obd_device_ops, NULL, true, NULL,
+       rc = class_register_type(&mdd_obd_device_ops, NULL, false, NULL,
                                 LUSTRE_MDD_NAME, &mdd_device_type);
        if (rc)
                lu_kmem_fini(mdd_caches);