Whamcloud - gitweb
LU-3677 mdt: Set HSM dirty open-for-write file when evicted.
[fs/lustre-release.git] / lustre / mdt / mdt_handler.c
index d997413..4ceb146 100644 (file)
@@ -100,6 +100,12 @@ static const struct lu_object_operations mdt_obj_ops;
 /* Slab for MDT object allocation */
 static struct kmem_cache *mdt_object_kmem;
 
+/* For HSM restore handles */
+struct kmem_cache *mdt_hsm_cdt_kmem;
+
+/* For HSM request handles */
+struct kmem_cache *mdt_hsm_car_kmem;
+
 static struct lu_kmem_descr mdt_caches[] = {
        {
                .ckd_cache = &mdt_object_kmem,
@@ -107,6 +113,16 @@ static struct lu_kmem_descr mdt_caches[] = {
                .ckd_size  = sizeof(struct mdt_object)
        },
        {
+               .ckd_cache      = &mdt_hsm_cdt_kmem,
+               .ckd_name       = "mdt_cdt_restore_handle",
+               .ckd_size       = sizeof(struct cdt_restore_handle)
+       },
+       {
+               .ckd_cache      = &mdt_hsm_car_kmem,
+               .ckd_name       = "mdt_cdt_agent_req",
+               .ckd_size       = sizeof(struct cdt_agent_req)
+       },
+       {
                .ckd_cache = NULL
        }
 };
@@ -4957,13 +4973,15 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
         cfs_timer_init(&m->mdt_ck_timer, mdt_ck_timer_callback, m);
 
        rc = mdt_hsm_cdt_init(m);
-       if (rc != 0)
-               CERROR("%s: Cannot init coordinator, rc %d\n",
+       if (rc != 0) {
+               CERROR("%s: error initializing coordinator, rc %d\n",
                       mdt_obd_name(m), rc);
+                GOTO(err_free_ns, rc);
+       }
 
         rc = mdt_ck_thread_start(m);
         if (rc)
-                GOTO(err_free_ns, rc);
+                GOTO(err_free_hsm, rc);
 
        rc = tgt_init(env, &m->mdt_lut, obd, m->mdt_bottom, mdt_common_slice,
                      OBD_FAIL_MDS_ALL_REQUEST_NET,
@@ -5053,6 +5071,8 @@ err_tgt:
 err_capa:
        cfs_timer_disarm(&m->mdt_ck_timer);
        mdt_ck_thread_stop(m);
+err_free_hsm:
+       mdt_hsm_cdt_fini(m);
 err_free_ns:
        ldlm_namespace_free(m->mdt_namespace, NULL, 0);
        obd->obd_namespace = m->mdt_namespace = NULL;
@@ -5548,6 +5568,31 @@ static int mdt_obd_reconnect(const struct lu_env *env,
         RETURN(rc);
 }
 
+static int mdt_ctxt_add_dirty_flag(struct lu_env *env,
+                                  struct mdt_thread_info *info,
+                                  struct mdt_file_data *mfd)
+{
+       struct lu_context ses;
+       int rc;
+       ENTRY;
+
+       rc = lu_context_init(&ses, LCT_SESSION);
+       if (rc)
+               RETURN(rc);
+
+       env->le_ses = &ses;
+       lu_context_enter(&ses);
+
+       mdt_ucred(info)->uc_valid = UCRED_OLD;
+       rc = mdt_add_dirty_flag(info, mfd->mfd_object, &info->mti_attr);
+
+       lu_context_exit(&ses);
+       lu_context_fini(&ses);
+       env->le_ses = NULL;
+
+       RETURN(rc);
+}
+
 static int mdt_export_cleanup(struct obd_export *exp)
 {
         struct mdt_export_data *med = &exp->exp_mdt_data;
@@ -5592,6 +5637,24 @@ static int mdt_export_cleanup(struct obd_export *exp)
                 cfs_list_for_each_entry_safe(mfd, n, &closing_list, mfd_list) {
                         cfs_list_del_init(&mfd->mfd_list);
                        ma->ma_need = ma->ma_valid = 0;
+
+                       /* This file is being closed due to an eviction, it
+                        * could have been modified and now dirty regarding to
+                        * HSM archive, check this!
+                        * The logic here is to mark a file dirty if there's a
+                        * chance it was dirtied before the client was evicted,
+                        * so that we don't have to wait for a release attempt
+                        * before finding out the file was actually dirty and
+                        * fail the release. Aggressively marking it dirty here
+                        * will cause the policy engine to attempt to
+                        * re-archive it; when rearchiving, we can compare the
+                        * current version to the HSM data_version and make the
+                        * archive request into a noop if it's not actually
+                        * dirty.
+                        */
+                       if (mfd->mfd_mode & (FMODE_WRITE|MDS_FMODE_TRUNC))
+                               rc = mdt_ctxt_add_dirty_flag(&env, info, mfd);
+
                        /* Don't unlink orphan on failover umount, LU-184 */
                        if (exp->exp_flags & OBD_OPT_FAILOVER) {
                                ma->ma_valid = MA_FLAGS;