Whamcloud - gitweb
LU-10680 mdd: disable changelog garbage collection by default
[fs/lustre-release.git] / lustre / mdd / mdd_device.c
index 88378b1..91ad2bd 100644 (file)
@@ -23,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2016, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <obd_class.h>
-#include <lustre_ioctl.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
 #include <lustre_mds.h>
 #include <obd_support.h>
 #include <lu_object.h>
-#include <lustre_param.h>
+#include <uapi/linux/lustre/lustre_param.h>
 #include <lustre_fid.h>
 #include <lustre_nodemap.h>
+#include <lustre_barrier.h>
 
 #include "mdd_internal.h"
 
@@ -124,6 +125,7 @@ static int mdd_init0(const struct lu_env *env, struct mdd_device *mdd,
        /* LU-8040 Set defaults here, before values configs */
        mdd->mdd_cl.mc_flags = 0; /* off by default */
        mdd->mdd_cl.mc_mask = CHANGELOG_DEFMASK;
+       mdd->mdd_cl.mc_deniednext = 60; /* 60 secs by default */
 
        dev = lustre_cfg_string(lcfg, 0);
        if (dev == NULL)
@@ -140,8 +142,18 @@ static int mdd_init0(const struct lu_env *env, struct mdd_device *mdd,
                RETURN(rc);
 
        mdd->mdd_atime_diff = MAX_ATIME_DIFF;
-        /* sync permission changes */
-        mdd->mdd_sync_permission = 1;
+       /* sync permission changes */
+       mdd->mdd_sync_permission = 1;
+       /* enable changelog garbage collection */
+       mdd->mdd_changelog_gc = 0;
+       /* with a significant amount of idle time */
+       mdd->mdd_changelog_max_idle_time = CHLOG_MAX_IDLE_TIME;
+       /* or a significant amount of late indexes */
+       mdd->mdd_changelog_max_idle_indexes = CHLOG_MAX_IDLE_INDEXES;
+       /* with a reasonable interval between each check */
+       mdd->mdd_changelog_min_gc_interval = CHLOG_MIN_GC_INTERVAL;
+       /* with a very few number of free entries */
+       mdd->mdd_changelog_min_free_cat_entries = CHLOG_MIN_FREE_CAT_ENTRIES;
 
        dt_conf_get(env, mdd->mdd_child, &mdd->mdd_dt_conf);
 
@@ -178,9 +190,9 @@ static int changelog_init_cb(const struct lu_env *env, struct llog_handle *llh,
 
        CDEBUG(D_INFO,
               "seeing record at index %d/%d/%llu t=%x %.*s in log"
-              DOSTID"\n", hdr->lrh_index, rec->cr_hdr.lrh_index,
+              DFID"\n", hdr->lrh_index, rec->cr_hdr.lrh_index,
               rec->cr.cr_index, rec->cr.cr_type, rec->cr.cr_namelen,
-              changelog_rec_name(&rec->cr), POSTID(&llh->lgh_id.lgl_oi));
+              changelog_rec_name(&rec->cr), PFID(&llh->lgh_id.lgl_oi.oi_fid));
 
        mdd->mdd_cl.mc_index = rec->cr.cr_index;
        return LLOG_PROC_BREAK;
@@ -190,16 +202,16 @@ static int changelog_user_init_cb(const struct lu_env *env,
                                  struct llog_handle *llh,
                                  struct llog_rec_hdr *hdr, void *data)
 {
-        struct mdd_device *mdd = (struct mdd_device *)data;
-        struct llog_changelog_user_rec *rec =
-                (struct llog_changelog_user_rec *)hdr;
+       struct mdd_device *mdd = (struct mdd_device *)data;
+       struct llog_changelog_user_rec *rec =
+               (struct llog_changelog_user_rec *)hdr;
 
-        LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
-        LASSERT(rec->cur_hdr.lrh_type == CHANGELOG_USER_REC);
+       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+       LASSERT(rec->cur_hdr.lrh_type == CHANGELOG_USER_REC);
 
        CDEBUG(D_INFO, "seeing user at index %d/%d id=%d endrec=%llu"
-               " in log "DOSTID"\n", hdr->lrh_index, rec->cur_hdr.lrh_index,
-               rec->cur_id, rec->cur_endrec, POSTID(&llh->lgh_id.lgl_oi));
+              " in log "DFID"\n", hdr->lrh_index, rec->cur_hdr.lrh_index,
+              rec->cur_id, rec->cur_endrec, PFID(&llh->lgh_id.lgl_oi.oi_fid));
 
        spin_lock(&mdd->mdd_cl.mc_user_lock);
        mdd->mdd_cl.mc_lastuser = rec->cur_id;
@@ -257,9 +269,9 @@ static int llog_changelog_cancel(const struct lu_env *env,
                /* 0 or 1 means we're done */
                rc = 0;
        else
-               CERROR("%s: cancel idx %u of catalog "DOSTID" rc=%d\n",
+               CERROR("%s: cancel idx %u of catalog "DFID": rc = %d\n",
                       ctxt->loc_obd->obd_name, cathandle->lgh_last_idx,
-                      POSTID(&cathandle->lgh_id.lgl_oi), rc);
+                      PFID(&cathandle->lgh_id.lgl_oi.oi_fid), rc);
 
        RETURN(rc);
 }
@@ -416,7 +428,7 @@ static int mdd_changelog_init(const struct lu_env *env, struct mdd_device *mdd)
 
        mdd->mdd_cl.mc_index = 0;
        spin_lock_init(&mdd->mdd_cl.mc_lock);
-       mdd->mdd_cl.mc_starttime = cfs_time_current_64();
+       mdd->mdd_cl.mc_starttime = ktime_get();
        spin_lock_init(&mdd->mdd_cl.mc_user_lock);
        mdd->mdd_cl.mc_lastuser = 0;
 
@@ -493,7 +505,7 @@ mdd_changelog_llog_cancel(const struct lu_env *env, struct mdd_device *mdd,
         /* Some records were purged, so reset repeat-access time (so we
            record new mtime update records, so users can see a file has been
            changed since the last purge) */
-        mdd->mdd_cl.mc_starttime = cfs_time_current_64();
+       mdd->mdd_cl.mc_starttime = ktime_get();
 
        rc = llog_cancel(env, ctxt, (struct llog_cookie *)&endrec, 0);
 out:
@@ -520,7 +532,7 @@ int mdd_changelog_write_header(const struct lu_env *env,
        ENTRY;
 
        if (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) {
-               mdd->mdd_cl.mc_starttime = cfs_time_current_64();
+               mdd->mdd_cl.mc_starttime = ktime_get();
                RETURN(0);
        }
 
@@ -553,7 +565,7 @@ int mdd_changelog_write_header(const struct lu_env *env,
        llog_ctxt_put(ctxt);
 
        /* assume on or off event; reset repeat-access time */
-       mdd->mdd_cl.mc_starttime = cfs_time_current_64();
+       mdd->mdd_cl.mc_starttime = ktime_get();
        RETURN(rc);
 }
 
@@ -874,12 +886,17 @@ static int mdd_hsm_actions_llog_fini(const struct lu_env *env,
 static void mdd_device_shutdown(const struct lu_env *env, struct mdd_device *m,
                                struct lustre_cfg *cfg)
 {
+       barrier_deregister(m->mdd_bottom);
        lfsck_degister(env, m->mdd_bottom);
        mdd_hsm_actions_llog_fini(env, m);
        mdd_changelog_fini(env, m);
-       orph_index_fini(env, m);
+       mdd_orphan_index_fini(env, m);
        mdd_dot_lustre_cleanup(env, m);
-       nm_config_file_deregister_tgt(env, mdd2obd_dev(m)->u.obt.obt_nodemap_config_file);
+       if (mdd2obd_dev(m)->u.obt.obt_nodemap_config_file) {
+               nm_config_file_deregister_tgt(env,
+                               mdd2obd_dev(m)->u.obt.obt_nodemap_config_file);
+               mdd2obd_dev(m)->u.obt.obt_nodemap_config_file = NULL;
+       }
        if (m->mdd_los != NULL) {
                local_oid_storage_fini(env, m->mdd_los);
                m->mdd_los = NULL;
@@ -917,7 +934,7 @@ static int mdd_process_config(const struct lu_env *env,
                 break;
        case LCFG_PRE_CLEANUP:
                rc = next->ld_ops->ldo_process_config(env, next, cfg);
-               mdd_generic_thread_stop(&m->mdd_orph_cleanup_thread);
+               mdd_generic_thread_stop(&m->mdd_orphan_cleanup_thread);
                break;
        case LCFG_CLEANUP:
                rc = next->ld_ops->ldo_process_config(env, next, cfg);
@@ -933,21 +950,21 @@ out:
 }
 
 static int mdd_recovery_complete(const struct lu_env *env,
-                                 struct lu_device *d)
+                                struct lu_device *d)
 {
-        struct mdd_device *mdd = lu2mdd_dev(d);
+       struct mdd_device *mdd = lu2mdd_dev(d);
        struct lu_device *next;
-        int rc;
-        ENTRY;
+       int rc;
+       ENTRY;
 
-        LASSERT(mdd != NULL);
+       LASSERT(mdd != NULL);
        next = &mdd->mdd_child->dd_lu_dev;
 
-        /* XXX: orphans handling. */
-        mdd_orphan_cleanup(env, mdd);
-        rc = next->ld_ops->ldo_recovery_complete(env, next);
+       if (!mdd->mdd_bottom->dd_rdonly)
+               mdd_orphan_cleanup(env, mdd);
+       rc = next->ld_ops->ldo_recovery_complete(env, next);
 
-        RETURN(rc);
+       RETURN(rc);
 }
 
 int mdd_local_file_create(const struct lu_env *env, struct mdd_device *mdd,
@@ -977,10 +994,10 @@ int mdd_local_file_create(const struct lu_env *env, struct mdd_device *mdd,
        *fid = *lu_object_fid(&dto->do_lu);
        /* since stack is not fully set up the local_storage uses own stack
         * and we should drop its object from cache */
-       lu_object_put_nocache(env, &dto->do_lu);
+       dt_object_put_nocache(env, dto);
        EXIT;
 out_put:
-       lu_object_put(env, &parent->do_lu);
+       dt_object_put(env, parent);
        return rc;
 }
 
@@ -997,6 +1014,7 @@ static int mdd_prepare(const struct lu_env *env,
        struct mdd_device *mdd = lu2mdd_dev(cdev);
        struct lu_device *next = &mdd->mdd_child->dd_lu_dev;
        struct nm_config_file *nodemap_config;
+       struct obd_device_target *obt = &mdd2obd_dev(mdd)->u.obt;
        struct lu_fid fid;
        int rc;
 
@@ -1043,7 +1061,7 @@ static int mdd_prepare(const struct lu_env *env,
                mdd->mdd_root_fid = fid;
        }
 
-       rc = orph_index_init(env, mdd);
+       rc = mdd_orphan_index_init(env, mdd);
        if (rc < 0)
                GOTO(out_dot, rc);
 
@@ -1060,10 +1078,13 @@ static int mdd_prepare(const struct lu_env *env,
 
        nodemap_config = nm_config_file_register_tgt(env, mdd->mdd_bottom,
                                                     mdd->mdd_los);
-       if (IS_ERR(nodemap_config))
-               GOTO(out_hsm, rc = PTR_ERR(nodemap_config));
-
-       mdd2obd_dev(mdd)->u.obt.obt_nodemap_config_file = nodemap_config;
+       if (IS_ERR(nodemap_config)) {
+               rc = PTR_ERR(nodemap_config);
+               if (rc != -EROFS)
+                       GOTO(out_hsm, rc);
+       } else {
+               obt->obt_nodemap_config_file = nodemap_config;
+       }
 
        rc = lfsck_register(env, mdd->mdd_bottom, mdd->mdd_child,
                            mdd2obd_dev(mdd), mdd_lfsck_out_notify,
@@ -1074,17 +1095,26 @@ static int mdd_prepare(const struct lu_env *env,
                GOTO(out_nodemap, rc);
        }
 
+       rc = barrier_register(mdd->mdd_bottom, mdd->mdd_child);
+       if (rc) {
+               CERROR("%s: failed to register to barrier: rc = %d\n",
+                      mdd2obd_dev(mdd)->obd_name, rc);
+               GOTO(out_lfsck, rc);
+       }
+
        RETURN(0);
 
+out_lfsck:
+       lfsck_degister(env, mdd->mdd_bottom);
 out_nodemap:
-       nm_config_file_deregister_tgt(env, mdd2obd_dev(mdd)->u.obt.obt_nodemap_config_file);
-       mdd2obd_dev(mdd)->u.obt.obt_nodemap_config_file = NULL;
+       nm_config_file_deregister_tgt(env, obt->obt_nodemap_config_file);
+       obt->obt_nodemap_config_file = NULL;
 out_hsm:
        mdd_hsm_actions_llog_fini(env, mdd);
 out_changelog:
        mdd_changelog_fini(env, mdd);
 out_orph:
-       orph_index_fini(env, mdd);
+       mdd_orphan_index_fini(env, mdd);
 out_dot:
        if (mdd_seq_site(mdd)->ss_node_id == 0)
                mdd_dot_lustre_cleanup(env, mdd);
@@ -1130,15 +1160,12 @@ static int mdd_statfs(const struct lu_env *env, struct md_device *m,
        RETURN(rc);
 }
 
-static int mdd_maxeasize_get(const struct lu_env *env, struct md_device *m,
-                               int *easize)
+static const struct dt_device_param *mdd_dtconf_get(const struct lu_env *env,
+                                                   struct md_device *m)
 {
        struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
-       ENTRY;
-
-       *easize = mdd->mdd_dt_conf.ddp_max_ea_size;
 
-       RETURN(0);
+       return &mdd->mdd_dt_conf;
 }
 
 static int mdd_llog_ctxt_get(const struct lu_env *env, struct md_device *m,
@@ -1320,6 +1347,11 @@ static int mdd_changelog_user_register(const struct lu_env *env,
        }
        *id = rec->cur_id = ++mdd->mdd_cl.mc_lastuser;
        rec->cur_endrec = mdd->mdd_cl.mc_index;
+
+       rec->cur_time = (__u32)get_seconds();
+       if (OBD_FAIL_CHECK(OBD_FAIL_TIME_IN_CHLOG_USER))
+               rec->cur_time = 0;
+
        spin_unlock(&mdd->mdd_cl.mc_user_lock);
 
        rc = llog_cat_add(env, ctxt->loc_handle, &rec->cur_hdr, NULL);
@@ -1386,8 +1418,8 @@ static int mdd_changelog_user_purge_cb(const struct lu_env *env,
        RETURN(rc);
 }
 
-static int mdd_changelog_user_purge(const struct lu_env *env,
-                                   struct mdd_device *mdd, __u32 id)
+int mdd_changelog_user_purge(const struct lu_env *env,
+                            struct mdd_device *mdd, __u32 id)
 {
        struct mdd_changelog_user_purge mcup = {
                .mcup_id = id,
@@ -1493,6 +1525,11 @@ static int mdd_changelog_clear_cb(const struct lu_env *env,
         * We now know the record to flush.
         */
        rec->cur_endrec = mcuc->mcuc_endrec;
+
+       rec->cur_time = (__u32)get_seconds();
+       if (OBD_FAIL_CHECK(OBD_FAIL_TIME_IN_CHLOG_USER))
+               rec->cur_time = 0;
+
        mcuc->mcuc_flush = true;
 
        CDEBUG(D_IOCTL, "Rewriting changelog user %u endrec to %llu\n",
@@ -1591,27 +1628,24 @@ out:
 static int mdd_iocontrol(const struct lu_env *env, struct md_device *m,
                          unsigned int cmd, int len, void *karg)
 {
-       struct mdd_device *mdd;
+       struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
        struct obd_ioctl_data *data = karg;
        int rc;
-
        ENTRY;
 
-       mdd = lu2mdd_dev(&m->md_lu_dev);
-
        /* Doesn't use obd_ioctl_data */
        switch (cmd) {
        case OBD_IOC_CHANGELOG_CLEAR: {
                struct changelog_setinfo *cs = karg;
+
+               if (unlikely(!barrier_entry(mdd->mdd_bottom)))
+                       RETURN(-EINPROGRESS);
+
                rc = mdd_changelog_clear(env, mdd, cs->cs_id,
                                         cs->cs_recno);
+               barrier_exit(mdd->mdd_bottom);
                RETURN(rc);
        }
-       case OBD_IOC_GET_MNTOPT: {
-               mntopt_t *mntopts = (mntopt_t *)karg;
-               *mntopts = mdd->mdd_dt_conf.ddp_mntopts;
-               RETURN(0);
-       }
        case OBD_IOC_START_LFSCK: {
                rc = lfsck_start(env, mdd->mdd_bottom,
                                 (struct lfsck_start_param *)karg);
@@ -1642,10 +1676,18 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m,
 
        switch (cmd) {
        case OBD_IOC_CHANGELOG_REG:
+               if (unlikely(!barrier_entry(mdd->mdd_bottom)))
+                       RETURN(-EINPROGRESS);
+
                rc = mdd_changelog_user_register(env, mdd, &data->ioc_u32_1);
+               barrier_exit(mdd->mdd_bottom);
                break;
        case OBD_IOC_CHANGELOG_DEREG:
+               if (unlikely(!barrier_entry(mdd->mdd_bottom)))
+                       RETURN(-EINPROGRESS);
+
                rc = mdd_changelog_user_purge(env, mdd, data->ioc_u32_1);
+               barrier_exit(mdd->mdd_bottom);
                break;
        default:
                rc = -ENOTTY;
@@ -1662,7 +1704,7 @@ static const struct md_device_operations mdd_ops = {
        .mdo_root_get       = mdd_root_get,
        .mdo_llog_ctxt_get  = mdd_llog_ctxt_get,
        .mdo_iocontrol      = mdd_iocontrol,
-       .mdo_maxeasize_get  = mdd_maxeasize_get,
+       .mdo_dtconf_get     = mdd_dtconf_get,
 };
 
 static struct lu_device_type_operations mdd_device_type_ops = {
@@ -1689,14 +1731,15 @@ static struct lu_device_type mdd_device_type = {
 LU_KEY_INIT(mdd, struct mdd_thread_info);
 
 static void mdd_key_fini(const struct lu_context *ctx,
-                         struct lu_context_key *key, void *data)
+                        struct lu_context_key *key, void *data)
 {
-        struct mdd_thread_info *info = data;
+       struct mdd_thread_info *info = data;
 
        lu_buf_free(&info->mti_big_buf);
        lu_buf_free(&info->mti_link_buf);
+       lu_buf_free(&info->mti_xattr_buf);
 
-        OBD_FREE_PTR(info);
+       OBD_FREE_PTR(info);
 }
 
 /* context key: mdd_thread_key */