Whamcloud - gitweb
LU-7988 hsm: run HSM coordinator once per second at most
[fs/lustre-release.git] / lustre / mdt / mdt_internal.h
index 68750e0..c67d090 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -48,9 +44,9 @@
 #ifndef _MDT_INTERNAL_H
 #define _MDT_INTERNAL_H
 
-
-#include <libcfs/lucache.h>
-#include <lustre_net.h>
+#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_hash.h>
+#include <upcall_cache.h>
 #include <lustre/lustre_idl.h>
 #include <obd_class.h>
 #include <lustre_disk.h>
 #include <lustre_quota.h>
 #include <lustre_linkea.h>
 
-/* check if request's xid is equal to last one or not*/
-static inline int req_xid_is_last(struct ptlrpc_request *req)
-{
-        struct lsd_client_data *lcd = req->rq_export->exp_target_data.ted_lcd;
-        return (req->rq_xid == lcd->lcd_last_xid ||
-                req->rq_xid == lcd->lcd_last_close_xid);
-}
-
 struct mdt_object;
 
 /* file data for open files on MDS */
@@ -103,11 +91,33 @@ struct mdt_file_data {
  */
 #define CDT_DEFAULT_POLICY             CDT_NORETRY_ACTION
 
+/* Coordinator states. Keep the cdt_transition table in sync. */
 enum cdt_states { CDT_STOPPED = 0,
                  CDT_INIT,
                  CDT_RUNNING,
                  CDT_DISABLE,
-                 CDT_STOPPING };
+                 CDT_STOPPING,
+
+                 CDT_STATES_COUNT
+};
+
+static inline char *cdt_mdt_state2str(int state)
+{
+       switch (state) {
+       case CDT_INIT:
+               return "init";
+       case CDT_RUNNING:
+               return "enabled";
+       case CDT_STOPPING:
+               return "stopping";
+       case CDT_STOPPED:
+               return "stopped";
+       case CDT_DISABLE:
+               return "disabled";
+       default:
+               return "unknown";
+       }
+}
 
 /* when multiple lock are needed, the lock order is
  * cdt_llog_lock
@@ -117,18 +127,21 @@ enum cdt_states { CDT_STOPPED = 0,
  * cdt_request_lock
  */
 struct coordinator {
-       struct ptlrpc_thread     cdt_thread;         /**< coordinator thread */
+       wait_queue_head_t        cdt_waitq;          /**< cdt wait queue */
+       bool                     cdt_event;          /**< coordinator event */
+       struct task_struct      *cdt_task;           /**< cdt thread handle */
        struct lu_env            cdt_env;            /**< coordinator lustre
                                                      * env */
        struct lu_context        cdt_session;        /** session for lu_ucred */
        struct proc_dir_entry   *cdt_proc_dir;       /**< cdt /proc directory */
        __u64                    cdt_policy;         /**< policy flags */
        enum cdt_states          cdt_state;           /**< state */
+       spinlock_t               cdt_state_lock;      /**< cdt_state lock */
        atomic_t                 cdt_compound_id;     /**< compound id
                                                       * counter */
        __u64                    cdt_last_cookie;     /**< last cookie
                                                       * allocated */
-       struct mutex             cdt_llog_lock;       /**< protect llog
+       struct rw_semaphore      cdt_llog_lock;       /**< protect llog
                                                       * access */
        struct rw_semaphore      cdt_agent_lock;      /**< protect agent list */
        struct rw_semaphore      cdt_request_lock;    /**< protect request
@@ -146,16 +159,27 @@ struct coordinator {
                                                       * requests */
        atomic_t                 cdt_request_count;   /**< current count of
                                                       * started requests */
-       struct list_head         cdt_requests;        /**< list of started
-                                                      * requests */
+       /* started requests (struct cdt_agent_req:car_cookie_hash)
+        * indexed by cookie */
+       struct cfs_hash         *cdt_request_cookie_hash;
+       /* started requests (struct cdt_agent_req:car_request_list) */
+       struct list_head         cdt_request_list;
        struct list_head         cdt_agents;          /**< list of register
                                                       * agents */
        struct list_head         cdt_restore_hdl;     /**< list of restore lock
                                                       * handles */
+
+       /* Hash of cookies to locations of record locations in agent
+        * request log. */
+       struct cfs_hash         *cdt_agent_record_hash;
+
        /* Bitmasks indexed by the HSMA_XXX constants. */
        __u64                    cdt_user_request_mask;
        __u64                    cdt_group_request_mask;
        __u64                    cdt_other_request_mask;
+
+       /* Remove archive on last unlink policy */
+       bool                     cdt_remove_archive_on_last_unlink;
 };
 
 /* mdt state flag bits */
@@ -184,13 +208,10 @@ struct mdt_device {
                unsigned int       mo_user_xattr:1,
                                   mo_acl:1,
                                   mo_cos:1,
-                                  mo_coordinator:1;
+                                  mo_evict_tgt_nids:1;
        } mdt_opts;
         /* mdt state flags */
         unsigned long              mdt_state;
-        /* lock to protect IOepoch */
-       spinlock_t                 mdt_ioepoch_lock;
-        __u64                      mdt_ioepoch;
 
         /* transaction callbacks */
         struct dt_txn_callback     mdt_txn_cb;
@@ -203,25 +224,19 @@ struct mdt_device {
 
         struct upcall_cache        *mdt_identity_cache;
 
-       /* capability keys */
-       unsigned long              mdt_capa_timeout;
-       __u32                      mdt_capa_alg;
-       struct dt_object          *mdt_ck_obj;
-       unsigned long              mdt_ck_timeout;
-       unsigned long              mdt_ck_expiry;
-       struct timer_list          mdt_ck_timer;
-       struct ptlrpc_thread       mdt_ck_thread;
-       struct lustre_capa_key     mdt_capa_keys[2];
        unsigned int               mdt_capa_conf:1,
-                                  mdt_som_conf:1,
                                   /* Enable remote dir on non-MDT0 */
-                                  mdt_enable_remote_dir:1;
+                                  mdt_enable_remote_dir:1,
+                                  mdt_skip_lfsck:1;
 
        gid_t                      mdt_enable_remote_dir_gid;
+
+       /* lock for osfs and md_root */
+       spinlock_t                 mdt_lock;
+
        /* statfs optimization: we cache a bit  */
        struct obd_statfs          mdt_osfs;
        __u64                      mdt_osfs_age;
-       spinlock_t                 mdt_osfs_lock;
 
         /* root squash */
        struct root_squash_info    mdt_squash;
@@ -235,6 +250,14 @@ struct mdt_device {
        struct lu_device          *mdt_qmt_dev;
 
        struct coordinator         mdt_coordinator;
+
+       /* inter-MDT connection count */
+       atomic_t                   mdt_mds_mds_conns;
+
+       /* MDT device async commit count, used for debug and sanity test */
+       atomic_t                   mdt_async_commit_count;
+
+       struct mdt_object         *mdt_md_root;
 };
 
 #define MDT_SERVICE_WATCHDOG_FACTOR    (2)
@@ -243,12 +266,11 @@ struct mdt_device {
 struct mdt_object {
        struct lu_object_header mot_header;
        struct lu_object        mot_obj;
-        __u64                   mot_ioepoch;
-        __u64                   mot_flags;
-        int                     mot_ioepoch_count;
-        int                     mot_writecount;
-        /* Lock to protect object's IO epoch. */
-       struct mutex            mot_ioepoch_mutex;
+       unsigned int            mot_lov_created:1,  /* lov object created */
+                               mot_cache_attr:1;   /* enable remote object
+                                                    * attribute cache */
+       int                     mot_write_count;
+       spinlock_t              mot_write_lock;
         /* Lock to protect create_data */
        struct mutex            mot_lov_mutex;
        /* Lock to protect lease open.
@@ -258,42 +280,22 @@ struct mdt_object {
        atomic_t                mot_open_count;
 };
 
-enum mdt_object_flags {
-        /** SOM attributes are changed. */
-        MOF_SOM_CHANGE  = (1 << 0),
-        /**
-         * The SOM recovery state for mdt object.
-         * This state is an in-memory equivalent of an absent SOM EA, used
-         * instead of invalidating SOM EA while IOEpoch is still opened when
-         * a client eviction occurs or a client fails to obtain SOM attributes.
-         * It indicates that the last IOEpoch holder will need to obtain SOM
-         * attributes under [0;EOF] extent lock to flush all the client's
-         * cached of evicted from MDS clients (but not necessary evicted from
-         * OST) before taking ost attributes.
-         */
-        MOF_SOM_RECOV   = (1 << 1),
-        /** File has been just created. */
-        MOF_SOM_CREATED = (1 << 2),
-        /** lov object has been created. */
-        MOF_LOV_CREATED = (1 << 3),
-};
-
 struct mdt_lock_handle {
-        /* Lock type, reg for cross-ref use or pdo lock. */
-        mdl_type_t              mlh_type;
+       /* Lock type, reg for cross-ref use or pdo lock. */
+       mdl_type_t              mlh_type;
 
-        /* Regular lock */
-        struct lustre_handle    mlh_reg_lh;
-        ldlm_mode_t             mlh_reg_mode;
+       /* Regular lock */
+       struct lustre_handle    mlh_reg_lh;
+       enum ldlm_mode          mlh_reg_mode;
 
-        /* Pdirops lock */
-        struct lustre_handle    mlh_pdo_lh;
-        ldlm_mode_t             mlh_pdo_mode;
-        unsigned int            mlh_pdo_hash;
+       /* Pdirops lock */
+       struct lustre_handle    mlh_pdo_lh;
+       enum ldlm_mode          mlh_pdo_mode;
+       unsigned int            mlh_pdo_hash;
 
        /* Remote regular lock */
-       struct lustre_handle    mlh_rreg_lh;
-       ldlm_mode_t          mlh_rreg_mode;
+       struct lustre_handle    mlh_rreg_lh;
+       enum ldlm_mode          mlh_rreg_mode;
 };
 
 enum {
@@ -390,7 +392,10 @@ struct mdt_thread_info {
         const struct ldlm_request *mti_dlm_req;
 
         __u32                      mti_has_trans:1, /* has txn already? */
-                                   mti_cross_ref:1;
+                                  mti_cross_ref:1,
+       /* big_lmm buffer was used and must be used in reply */
+                                  mti_big_lmm_used:1,
+                                  mti_big_acl_used:1;
 
         /* opdata for mdt_reint_open(), has the same as
          * ldlm_reply:lock_policy_res1.  mdt_update_last_rcvd() stores this
@@ -423,50 +428,43 @@ struct mdt_thread_info {
          * They should be initialized explicitly by the user themselves.
          */
 
-         /* XXX: If something is in a union, make sure they do not conflict */
-
-        struct lu_fid              mti_tmp_fid1;
-        struct lu_fid              mti_tmp_fid2;
-        ldlm_policy_data_t         mti_policy;    /* for mdt_object_lock() and
-                                                   * mdt_rename_lock() */
-        struct ldlm_res_id         mti_res_id;    /* for mdt_object_lock() and
-                                                     mdt_rename_lock()   */
-        union {
-                struct obd_uuid    uuid[2];       /* for mdt_seq_init_cli()  */
-                char               ns_name[48];   /* for mdt_init0()         */
-                struct lustre_cfg_bufs bufs;      /* for mdt_stack_fini()    */
-               struct obd_statfs  osfs;          /* for mdt_statfs()        */
+       /* XXX: If something is in a union, make sure they do not conflict */
+       struct lu_fid                   mti_tmp_fid1;
+       struct lu_fid                   mti_tmp_fid2;
+       union ldlm_policy_data          mti_policy; /* for mdt_object_lock() */
+       struct ldlm_res_id              mti_res_id; /* and mdt_rename_lock() */
+       union {
+               struct obd_uuid         uuid[2];    /* for mdt_seq_init_cli() */
+               char                    ns_name[48];/* for mdt_init0()        */
+               struct lustre_cfg_bufs  bufs;       /* for mdt_stack_fini()   */
+               struct obd_statfs       osfs;       /* for mdt_statfs()       */
                 struct {
                         /* for mdt_readpage()      */
                         struct lu_rdpg     mti_rdpg;
                         /* for mdt_sendpage()      */
                         struct l_wait_info mti_wait_info;
                 } rdpg;
-                struct {
-                        struct md_attr attr;
-                        struct md_som_data data;
-                } som;
+               struct {
+                       struct md_attr attr;
+               } hsm;
         } mti_u;
 
-        /* IO epoch related stuff. */
-        struct mdt_ioepoch        *mti_ioepoch;
-        __u64                      mti_replayepoch;
-
+       struct lustre_handle       mti_close_handle;
        loff_t                     mti_off;
        struct lu_buf              mti_buf;
        struct lu_buf              mti_big_buf;
-       struct lustre_capa_key     mti_capa_key;
 
         /* Ops object filename */
         struct lu_name             mti_name;
-       /* per-thread values, can be re-used */
+       /* per-thread values, can be re-used, may be vmalloc'd */
        void                      *mti_big_lmm;
+       void                      *mti_big_acl;
        int                        mti_big_lmmsize;
-       /* big_lmm buffer was used and must be used in reply */
-       int                        mti_big_lmm_used;
+       int                        mti_big_aclsize;
        /* should be enough to fit lustre_mdt_attrs */
        char                       mti_xattr_buf[128];
        struct ldlm_enqueue_info   mti_einfo;
+       struct tg_reply_data      *mti_reply_data;
 };
 
 extern struct lu_context_key mdt_thread_key;
@@ -493,6 +491,7 @@ struct cdt_req_progress {
 };
 
 struct cdt_agent_req {
+       struct hlist_node        car_cookie_hash;  /**< find req by cookie */
        struct list_head         car_request_list; /**< to chain all the req. */
        atomic_t                 car_refcount;     /**< reference counter */
        __u64                    car_compound_id;  /**< compound id */
@@ -596,7 +595,6 @@ static inline struct seq_server_site *mdt_seq_site(struct mdt_device *mdt)
 static inline void mdt_export_evict(struct obd_export *exp)
 {
         class_fail_export(exp);
-        class_export_put(exp);
 }
 
 /* Here we use LVB_TYPE to check dne client, because it is
@@ -611,43 +609,38 @@ static inline bool mdt_is_striped_client(struct obd_export *exp)
        return exp_connect_flags(exp) & OBD_CONNECT_DIR_STRIPE;
 }
 
-int mdt_get_disposition(struct ldlm_reply *rep, int flag);
+__u64 mdt_get_disposition(struct ldlm_reply *rep, __u64 op_flag);
 void mdt_set_disposition(struct mdt_thread_info *info,
-                        struct ldlm_reply *rep, int flag);
+                        struct ldlm_reply *rep, __u64 op_flag);
 void mdt_clear_disposition(struct mdt_thread_info *info,
-                        struct ldlm_reply *rep, int flag);
+                          struct ldlm_reply *rep, __u64 op_flag);
 
-void mdt_lock_pdo_init(struct mdt_lock_handle *lh,
-                      ldlm_mode_t lock_mode,
+void mdt_lock_pdo_init(struct mdt_lock_handle *lh, enum ldlm_mode lock_mode,
                       const struct lu_name *lname);
 
-void mdt_lock_reg_init(struct mdt_lock_handle *lh,
-                       ldlm_mode_t lm);
+void mdt_lock_reg_init(struct mdt_lock_handle *lh, enum ldlm_mode lm);
 
-int mdt_lock_setup(struct mdt_thread_info *info,
-                   struct mdt_object *o,
-                   struct mdt_lock_handle *lh);
+int mdt_lock_setup(struct mdt_thread_info *info, struct mdt_object *mo,
+                  struct mdt_lock_handle *lh);
 
-int mdt_check_resent_lock(struct mdt_thread_info *info,
-                         struct mdt_object *mo,
+int mdt_check_resent_lock(struct mdt_thread_info *info, struct mdt_object *mo,
                          struct mdt_lock_handle *lhc);
 
-int mdt_object_lock(struct mdt_thread_info *,
-                    struct mdt_object *,
-                    struct mdt_lock_handle *,
-                    __u64, int);
+int mdt_object_lock(struct mdt_thread_info *info, struct mdt_object *mo,
+                   struct mdt_lock_handle *lh, __u64 ibits);
+
+int mdt_reint_object_lock(struct mdt_thread_info *info, struct mdt_object *o,
+                         struct mdt_lock_handle *lh, __u64 ibits,
+                         bool cos_incompat);
 
-int mdt_object_lock_try(struct mdt_thread_info *,
-                       struct mdt_object *,
-                       struct mdt_lock_handle *,
-                       __u64, int);
+int mdt_object_lock_try(struct mdt_thread_info *info, struct mdt_object *mo,
+                       struct mdt_lock_handle *lh, __u64 *ibits,
+                       __u64 trybits, bool cos_incompat);
 
-void mdt_object_unlock(struct mdt_thread_info *,
-                       struct mdt_object *,
-                       struct mdt_lock_handle *,
-                       int decref);
+void mdt_object_unlock(struct mdt_thread_info *info, struct mdt_object *mo,
+                      struct mdt_lock_handle *lh, int decref);
 
-struct mdt_object *mdt_object_new(const struct lu_env *,
+struct mdt_object *mdt_object_new(const struct lu_env *env,
                                  struct mdt_device *,
                                  const struct lu_fid *);
 struct mdt_object *mdt_object_find(const struct lu_env *,
@@ -667,7 +660,7 @@ void mdt_client_compatibility(struct mdt_thread_info *info);
 int mdt_remote_object_lock(struct mdt_thread_info *mti,
                           struct mdt_object *o, const struct lu_fid *fid,
                           struct lustre_handle *lh,
-                          ldlm_mode_t mode, __u64 ibits);
+                          enum ldlm_mode mode, __u64 ibits, bool cache);
 
 enum mdt_name_flags {
        MNF_FIX_ANON = 1,
@@ -679,7 +672,12 @@ int mdt_name_unpack(struct req_capsule *pill,
                    enum mdt_name_flags flags);
 int mdt_close_unpack(struct mdt_thread_info *info);
 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op);
+void mdt_fix_lov_magic(struct mdt_thread_info *info, void *eadata);
 int mdt_reint_rec(struct mdt_thread_info *, struct mdt_lock_handle *);
+#ifdef CONFIG_FS_POSIX_ACL
+int mdt_pack_acl2body(struct mdt_thread_info *info, struct mdt_body *repbody,
+                     struct mdt_object *o, struct lu_nodemap *nodemap);
+#endif
 void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b,
                         const struct lu_attr *attr, const struct lu_fid *fid);
 
@@ -719,17 +717,6 @@ struct mdt_file_data *mdt_handle2mfd(struct mdt_export_data *med,
                                     const struct lustre_handle *handle,
                                     bool is_replay);
 
-enum {
-        MDT_IOEPOCH_CLOSED  = 0,
-        MDT_IOEPOCH_OPENED  = 1,
-        MDT_IOEPOCH_GETATTR = 2,
-};
-
-enum {
-        MDT_SOM_DISABLE = 0,
-        MDT_SOM_ENABLE  = 1,
-};
-
 int mdt_get_info(struct tgt_session_info *tsi);
 int mdt_attr_get_complex(struct mdt_thread_info *info,
                         struct mdt_object *o, struct md_attr *ma);
@@ -737,9 +724,6 @@ int mdt_big_xattr_get(struct mdt_thread_info *info, struct mdt_object *o,
                      const char *name);
 int mdt_stripe_get(struct mdt_thread_info *info, struct mdt_object *o,
                   struct md_attr *ma, const char *name);
-int mdt_ioepoch_open(struct mdt_thread_info *info, struct mdt_object *o,
-                     int created);
-int mdt_object_is_som_enabled(struct mdt_object *mo);
 int mdt_write_get(struct mdt_object *o);
 void mdt_write_put(struct mdt_object *o);
 int mdt_write_read(struct mdt_object *o);
@@ -749,10 +733,9 @@ void mdt_mfd_free(struct mdt_file_data *mfd);
 int mdt_close(struct tgt_session_info *tsi);
 int mdt_add_dirty_flag(struct mdt_thread_info *info, struct mdt_object *mo,
                        struct md_attr *ma);
-int mdt_done_writing(struct tgt_session_info *tsi);
 int mdt_fix_reply(struct mdt_thread_info *info);
 int mdt_handle_last_unlink(struct mdt_thread_info *, struct mdt_object *,
-                           const struct md_attr *);
+                          struct md_attr *);
 void mdt_reconstruct_open(struct mdt_thread_info *, struct mdt_lock_handle *);
 
 struct lu_buf *mdt_buf(const struct lu_env *env, void *area, ssize_t len);
@@ -762,8 +745,10 @@ const struct lu_buf *mdt_buf_const(const struct lu_env *env,
 void mdt_dump_lmm(int level, const struct lov_mds_md *lmm, __u64 valid);
 void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv);
 
+bool allow_client_chgrp(struct mdt_thread_info *info, struct lu_ucred *uc);
 int mdt_check_ucred(struct mdt_thread_info *);
 int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *);
+int mdt_init_ucred_intent_getattr(struct mdt_thread_info *, struct mdt_body *);
 int mdt_init_ucred_reint(struct mdt_thread_info *);
 void mdt_exit_ucred(struct mdt_thread_info *);
 int mdt_version_get_check(struct mdt_thread_info *, struct mdt_object *, int);
@@ -783,17 +768,8 @@ int mdt_remote_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
 int mdt_links_read(struct mdt_thread_info *info,
                   struct mdt_object *mdt_obj,
                   struct linkea_data *ldata);
-/* mdt_idmap.c */
-int mdt_init_idmap(struct tgt_session_info *tsi);
-void mdt_cleanup_idmap(struct mdt_export_data *);
-int mdt_handle_idmap(struct tgt_session_info *tsi);
-int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *,
-                              struct ptlrpc_user_desc *);
-void mdt_body_reverse_idmap(struct mdt_thread_info *,
-                            struct mdt_body *);
-int mdt_remote_perm_reverse_idmap(struct ptlrpc_request *,
-                                  struct mdt_remote_perm *);
-int mdt_fix_attr_ucred(struct mdt_thread_info *, __u32);
+int mdt_close_internal(struct mdt_thread_info *info, struct ptlrpc_request *req,
+                      struct mdt_body *repbody);
 
 static inline struct mdt_device *mdt_dev(struct lu_device *d)
 {
@@ -816,6 +792,12 @@ static inline struct dt_object *mdt_obj2dt(struct mdt_object *mo)
        return lu2dt(lo);
 }
 
+static inline bool agent_req_in_final_state(enum agent_req_status ars)
+{
+       return ((ars == ARS_SUCCEED) || (ars == ARS_FAILED) ||
+               (ars == ARS_CANCELED));
+}
+
 /* mdt/mdt_identity.c */
 #define MDT_IDENTITY_UPCALL_PATH        "/usr/sbin/l_getidentity"
 
@@ -827,9 +809,10 @@ void mdt_identity_put(struct upcall_cache *, struct md_identity *);
 
 void mdt_flush_identity(struct upcall_cache *, int);
 
-__u32 mdt_identity_get_perm(struct md_identity *, __u32, lnet_nid_t);
+__u32 mdt_identity_get_perm(struct md_identity *, lnet_nid_t);
 
-int mdt_pack_remote_perm(struct mdt_thread_info *, struct mdt_object *, void *);
+/* mdt/mdt_recovery.c */
+__u64 mdt_req_from_lrd(struct ptlrpc_request *req, struct tg_reply_data *trd);
 
 /* mdt/mdt_hsm.c */
 int mdt_hsm_state_get(struct tgt_session_info *tsi);
@@ -845,16 +828,19 @@ extern const struct file_operations mdt_hsm_actions_fops;
 void dump_llog_agent_req_rec(const char *prefix,
                             const struct llog_agent_req_rec *larr);
 int cdt_llog_process(const struct lu_env *env, struct mdt_device *mdt,
-                    llog_cb_t cb, void *data);
+                    llog_cb_t cb, void *data, u32 start_cat_idx,
+                    u32 start_rec_idx, int rw);
 int mdt_agent_record_add(const struct lu_env *env, struct mdt_device *mdt,
                         __u64 compound_id, __u32 archive_id,
                         __u64 flags, struct hsm_action_item *hai);
 int mdt_agent_record_update(const struct lu_env *env,
                            struct mdt_device *mdt, __u64 *cookies,
                            int cookies_count, enum agent_req_status status);
-int mdt_agent_llog_update_rec(const struct lu_env *env, struct mdt_device *mdt,
-                             struct llog_handle *llh,
-                             struct llog_agent_req_rec *larr);
+void cdt_agent_record_hash_add(struct coordinator *cdt, u64 cookie, u32 cat_idt,
+                              u32 rec_idx);
+void cdt_agent_record_hash_lookup(struct coordinator *cdt, u64 cookie,
+                                 u32 *cat_idt, u32 *rec_idx);
+void cdt_agent_record_hash_del(struct coordinator *cdt, u64 cookie);
 
 /* mdt/mdt_hsm_cdt_agent.c */
 extern const struct file_operations mdt_hsm_agent_fops;
@@ -877,14 +863,14 @@ int mdt_hsm_coordinator_update(struct mdt_thread_info *mti,
                               struct hsm_progress_kernel *pgs);
 /* mdt/mdt_hsm_cdt_client.c */
 int mdt_hsm_add_actions(struct mdt_thread_info *info,
-                       struct hsm_action_list *hal, __u64 *compound_id);
-int mdt_hsm_get_actions(struct mdt_thread_info *mti,
                        struct hsm_action_list *hal);
-int mdt_hsm_get_running(struct mdt_thread_info *mti,
+int mdt_hsm_get_actions(struct mdt_thread_info *mti,
                        struct hsm_action_list *hal);
 bool mdt_hsm_restore_is_running(struct mdt_thread_info *mti,
                                const struct lu_fid *fid);
 /* mdt/mdt_hsm_cdt_requests.c */
+extern struct cfs_hash_ops cdt_request_cookie_hash_ops;
+extern struct cfs_hash_ops cdt_agent_record_hash_ops;
 extern const struct file_operations mdt_hsm_active_requests_fops;
 void dump_requests(char *prefix, struct coordinator *cdt);
 struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id,
@@ -892,9 +878,7 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id,
                                            struct hsm_action_item *hai);
 void mdt_cdt_free_request(struct cdt_agent_req *car);
 int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car);
-struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt,
-                                          const __u64 cookie,
-                                          const struct lu_fid *fid);
+struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie);
 void mdt_cdt_get_work_done(struct cdt_agent_req *car, __u64 *done_sz);
 void mdt_cdt_get_request(struct cdt_agent_req *car);
 void mdt_cdt_put_request(struct cdt_agent_req *car);
@@ -904,20 +888,30 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie);
 /* mdt/mdt_coordinator.c */
 void mdt_hsm_dump_hal(int level, const char *prefix,
                      struct hsm_action_list *hal);
+struct cdt_restore_handle *mdt_hsm_restore_hdl_find(struct coordinator *cdt,
+                                               const struct lu_fid *fid);
 /* coordinator management */
 int mdt_hsm_cdt_init(struct mdt_device *mdt);
-int mdt_hsm_cdt_start(struct mdt_device *mdt);
 int mdt_hsm_cdt_stop(struct mdt_device *mdt);
 int mdt_hsm_cdt_fini(struct mdt_device *mdt);
-int mdt_hsm_cdt_wakeup(struct mdt_device *mdt);
+
+/*
+ * Signal the coordinator has work to do
+ * \param cdt [IN] coordinator
+ */
+static inline void mdt_hsm_cdt_event(struct coordinator *cdt)
+{
+       cdt->cdt_event = true;
+}
 
 /* coordinator control /proc interface */
-ssize_t mdt_hsm_cdt_control_seq_write(struct file *file, const char *buffer,
-                                       size_t count, loff_t *off);
+ssize_t mdt_hsm_cdt_control_seq_write(struct file *file,
+                                     const char __user *buffer,
+                                     size_t count, loff_t *off);
 int mdt_hsm_cdt_control_seq_show(struct seq_file *m, void *data);
 int hsm_cdt_procfs_init(struct mdt_device *mdt);
 void hsm_cdt_procfs_fini(struct mdt_device *mdt);
-struct lprocfs_seq_vars *hsm_cdt_get_proc_vars(void);
+struct lprocfs_vars *hsm_cdt_get_proc_vars(void);
 /* md_hsm helpers */
 struct mdt_object *mdt_hsm_get_md_hsm(struct mdt_thread_info *mti,
                                      const struct lu_fid *fid,
@@ -926,26 +920,29 @@ struct mdt_object *mdt_hsm_get_md_hsm(struct mdt_thread_info *mti,
 int mdt_hsm_add_hal(struct mdt_thread_info *mti,
                    struct hsm_action_list *hal, struct obd_uuid *uuid);
 bool mdt_hsm_is_action_compat(const struct hsm_action_item *hai,
-                             const int hal_an, const __u64 rq_flags,
+                             u32 archive_id, u64 rq_flags,
                              const struct md_hsm *hsm);
 int mdt_hsm_update_request_state(struct mdt_thread_info *mti,
                                 struct hsm_progress_kernel *pgs,
                                 const int update_record);
 
+int mdt_close_swap_layouts(struct mdt_thread_info *info,
+                          struct mdt_object *o, struct md_attr *ma);
+
 extern struct lu_context_key       mdt_thread_key;
 
 /* debug issues helper starts here*/
 static inline int mdt_fail_write(const struct lu_env *env,
                                  struct dt_device *dd, int id)
 {
-        if (OBD_FAIL_CHECK_ORSET(id, OBD_FAIL_ONCE)) {
-                CERROR(LUSTRE_MDT_NAME": cfs_fail_loc=%x, fail write ops\n",
-                       id);
-                return dd->dd_ops->dt_ro(env, dd);
-                /* We set FAIL_ONCE because we never "un-fail" a device */
-        }
-
-        return 0;
+       if (OBD_FAIL_CHECK_ORSET(id, OBD_FAIL_ONCE)) {
+               CERROR(LUSTRE_MDT_NAME": cfs_fail_loc=%x, fail write ops\n",
+                      id);
+               return dt_ro(env, dd);
+               /* We set FAIL_ONCE because we never "un-fail" a device */
+       }
+
+       return 0;
 }
 
 static inline struct mdt_export_data *mdt_req2med(struct ptlrpc_request *req)
@@ -958,24 +955,41 @@ static inline struct mdt_device *mdt_exp2dev(struct obd_export *exp)
        return mdt_dev(exp->exp_obd->obd_lu_dev);
 }
 
+static inline bool mdt_rdonly(struct obd_export *exp)
+{
+       if (exp_connect_flags(exp) & OBD_CONNECT_RDONLY ||
+           mdt_exp2dev(exp)->mdt_bottom->dd_rdonly)
+               return true;
+       return false;
+}
+
 typedef void (*mdt_reconstruct_t)(struct mdt_thread_info *mti,
                                   struct mdt_lock_handle *lhc);
 static inline int mdt_check_resent(struct mdt_thread_info *info,
                                    mdt_reconstruct_t reconstruct,
                                    struct mdt_lock_handle *lhc)
 {
-        struct ptlrpc_request *req = mdt_info_req(info);
-        ENTRY;
-
-        if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
-                if (req_xid_is_last(req)) {
-                        reconstruct(info, lhc);
-                        RETURN(1);
-                }
-                DEBUG_REQ(D_HA, req, "no reply for RESENT req (have "LPD64")",
-                          req->rq_export->exp_target_data.ted_lcd->lcd_last_xid);
-        }
-        RETURN(0);
+       struct ptlrpc_request *req = mdt_info_req(info);
+       int rc = 0;
+       ENTRY;
+
+       if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
+               OBD_ALLOC_PTR(info->mti_reply_data);
+               if (info->mti_reply_data == NULL)
+                       RETURN(-ENOMEM);
+
+               if (req_can_reconstruct(req, info->mti_reply_data)) {
+                       reconstruct(info, lhc);
+                       rc = 1;
+               } else {
+                       DEBUG_REQ(D_HA, req,
+                                 "no reply data found for RESENT req");
+                       rc = 0;
+               }
+               OBD_FREE_PTR(info->mti_reply_data);
+               info->mti_reply_data = NULL;
+       }
+       RETURN(rc);
 }
 
 struct lu_ucred *mdt_ucred(const struct mdt_thread_info *info);
@@ -990,43 +1004,48 @@ int mdt_blocking_ast(struct ldlm_lock*, struct ldlm_lock_desc*, void*, int);
 
 /* Issues dlm lock on passed @ns, @f stores it lock handle into @lh. */
 static inline int mdt_fid_lock(struct ldlm_namespace *ns,
-                               struct lustre_handle *lh,
-                               ldlm_mode_t mode,
-                               ldlm_policy_data_t *policy,
-                               const struct ldlm_res_id *res_id,
+                              struct lustre_handle *lh, enum ldlm_mode mode,
+                              union ldlm_policy_data *policy,
+                              const struct ldlm_res_id *res_id,
                               __u64 flags, const __u64 *client_cookie)
 {
-        int rc;
+       int rc;
 
-        LASSERT(ns != NULL);
-        LASSERT(lh != NULL);
+       LASSERT(ns != NULL);
+       LASSERT(lh != NULL);
 
-        rc = ldlm_cli_enqueue_local(ns, res_id, LDLM_IBITS, policy,
-                                    mode, &flags, mdt_blocking_ast,
-                                    ldlm_completion_ast, NULL, NULL, 0,
+       rc = ldlm_cli_enqueue_local(ns, res_id, LDLM_IBITS, policy,
+                                   mode, &flags, mdt_blocking_ast,
+                                   ldlm_completion_ast, NULL, NULL, 0,
                                    LVB_T_NONE, client_cookie, lh);
-        return rc == ELDLM_OK ? 0 : -EIO;
+       return rc == ELDLM_OK ? 0 : -EIO;
+}
+
+static inline void mdt_fid_unlock(struct lustre_handle *lh, enum ldlm_mode mode)
+{
+       ldlm_lock_decref(lh, mode);
 }
 
-static inline void mdt_fid_unlock(struct lustre_handle *lh,
-                                  ldlm_mode_t mode)
+static inline bool mdt_slc_is_enabled(struct mdt_device *mdt)
 {
-        ldlm_lock_decref(lh, mode);
+       return mdt->mdt_lut.lut_sync_lock_cancel == BLOCKING_SYNC_ON_CANCEL;
 }
 
 extern mdl_mode_t mdt_mdl_lock_modes[];
-extern ldlm_mode_t mdt_dlm_lock_modes[];
+extern enum ldlm_mode mdt_dlm_lock_modes[];
+
+/* LCK_MINMODE which is zero returns false for is_power_of_2 */
 
-static inline mdl_mode_t mdt_dlm_mode2mdl_mode(ldlm_mode_t mode)
+static inline mdl_mode_t mdt_dlm_mode2mdl_mode(enum ldlm_mode mode)
 {
-        LASSERT(IS_PO2(mode));
-        return mdt_mdl_lock_modes[mode];
+       LASSERT(mode == LCK_MINMODE || is_power_of_2(mode));
+       return mdt_mdl_lock_modes[mode];
 }
 
-static inline ldlm_mode_t mdt_mdl_mode2dlm_mode(mdl_mode_t mode)
+static inline enum ldlm_mode mdt_mdl_mode2dlm_mode(mdl_mode_t mode)
 {
-        LASSERT(IS_PO2(mode));
-        return mdt_dlm_lock_modes[mode];
+       LASSERT(mode == MDL_MINMODE || is_power_of_2(mode));
+       return mdt_dlm_lock_modes[mode];
 }
 
 /* mdt_lvb.c */
@@ -1068,15 +1087,6 @@ void mdt_rename_counter_tally(struct mdt_thread_info *info,
                              struct ptlrpc_request *req,
                              struct mdt_object *src, struct mdt_object *tgt);
 
-/* Capability */
-int mdt_ck_thread_start(struct mdt_device *mdt);
-void mdt_ck_thread_stop(struct mdt_device *mdt);
-void mdt_ck_timer_callback(unsigned long castmeharder);
-int mdt_capa_keys_init(const struct lu_env *env, struct mdt_device *mdt);
-void mdt_set_capainfo(struct mdt_thread_info *info, int offset,
-                     const struct lu_fid *fid, struct lustre_capa *capa);
-void mdt_dump_capainfo(struct mdt_thread_info *info);
-
 static inline struct obd_device *mdt2obd_dev(const struct mdt_device *mdt)
 {
        return mdt->mdt_lu_dev.ld_obd;