]> err.no Git - linux-2.6/blobdiff - fs/ocfs2/dlm/dlmcommon.h
ocfs2/dlm: Fix lockname in lockres print function
[linux-2.6] / fs / ocfs2 / dlm / dlmcommon.h
index 6b6ff76538c59212d453385858612a2663f83b51..d5a86fb81a4902adff4426b552cd3ae19a5d926d 100644 (file)
 /* Intended to make it easier for us to switch out hash functions */
 #define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l)
 
+enum dlm_mle_type {
+       DLM_MLE_BLOCK,
+       DLM_MLE_MASTER,
+       DLM_MLE_MIGRATION
+};
+
+struct dlm_lock_name {
+       u8 len;
+       u8 name[DLM_LOCKID_NAME_MAX];
+};
+
+struct dlm_master_list_entry {
+       struct list_head list;
+       struct list_head hb_events;
+       struct dlm_ctxt *dlm;
+       spinlock_t spinlock;
+       wait_queue_head_t wq;
+       atomic_t woken;
+       struct kref mle_refs;
+       int inuse;
+       unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       u8 master;
+       u8 new_master;
+       enum dlm_mle_type type;
+       struct o2hb_callback_func mle_hb_up;
+       struct o2hb_callback_func mle_hb_down;
+       union {
+               struct dlm_lock_resource *res;
+               struct dlm_lock_name name;
+       } u;
+};
+
 enum dlm_ast_type {
        DLM_AST = 0,
        DLM_BAST,
@@ -101,6 +136,7 @@ struct dlm_ctxt
        struct list_head purge_list;
        struct list_head pending_asts;
        struct list_head pending_basts;
+       struct list_head tracking_list;
        unsigned int purge_count;
        spinlock_t spinlock;
        spinlock_t ast_lock;
@@ -122,6 +158,9 @@ struct dlm_ctxt
        atomic_t remote_resources;
        atomic_t unknown_resources;
 
+       struct dlm_debug_ctxt *dlm_debug_ctxt;
+       struct dentry *dlm_debugfs_subroot;
+
        /* NOTE: Next three are protected by dlm_domain_lock */
        struct kref dlm_refs;
        enum dlm_ctxt_state dlm_state;
@@ -142,6 +181,12 @@ struct dlm_ctxt
        spinlock_t work_lock;
        struct list_head dlm_domain_handlers;
        struct list_head        dlm_eviction_callbacks;
+
+       /* The filesystem specifies this at domain registration.  We
+        * cache it here to know what to tell other nodes. */
+       struct dlm_protocol_version fs_locking_proto;
+       /* This is the inter-dlm communication version */
+       struct dlm_protocol_version dlm_locking_proto;
 };
 
 static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned i)
@@ -170,6 +215,7 @@ struct dlm_mig_lockres_priv
 {
        struct dlm_lock_resource *lockres;
        u8 real_master;
+       u8 extra_ref;
 };
 
 struct dlm_assert_master_priv
@@ -180,6 +226,11 @@ struct dlm_assert_master_priv
        unsigned ignore_higher:1;
 };
 
+struct dlm_deref_lockres_priv
+{
+       struct dlm_lock_resource *deref_res;
+       u8 deref_node;
+};
 
 struct dlm_work_item
 {
@@ -191,6 +242,7 @@ struct dlm_work_item
                struct dlm_request_all_locks_priv ral;
                struct dlm_mig_lockres_priv ml;
                struct dlm_assert_master_priv am;
+               struct dlm_deref_lockres_priv dl;
        } u;
 };
 
@@ -222,6 +274,9 @@ static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm,
 #define DLM_LOCK_RES_DIRTY                0x00000008
 #define DLM_LOCK_RES_IN_PROGRESS          0x00000010
 #define DLM_LOCK_RES_MIGRATING            0x00000020
+#define DLM_LOCK_RES_DROPPING_REF         0x00000040
+#define DLM_LOCK_RES_BLOCK_DIRTY          0x00001000
+#define DLM_LOCK_RES_SETREF_INPROG        0x00002000
 
 /* max milliseconds to wait to sync up a network failure with a node death */
 #define DLM_NODE_DEATH_WAIT_MAX (5 * 1000)
@@ -254,6 +309,9 @@ struct dlm_lock_resource
        struct list_head dirty;
        struct list_head recovering; // dlm_recovery_ctxt.resources list
 
+       /* Added during init and removed during release */
+       struct list_head tracking;      /* dlm->tracking_list */
+
        /* unused lock resources have their last_used stamped and are
         * put on a list for the dlm thread to run. */
        unsigned long    last_used;
@@ -265,6 +323,8 @@ struct dlm_lock_resource
        u8  owner;              //node which owns the lock resource, or unknown
        u16 state;
        char lvb[DLM_LVB_LEN];
+       unsigned int inflight_locks;
+       unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
 };
 
 struct dlm_migratable_lock
@@ -367,7 +427,7 @@ enum {
        DLM_CONVERT_LOCK_MSG,    /* 504 */
        DLM_PROXY_AST_MSG,       /* 505 */
        DLM_UNLOCK_LOCK_MSG,     /* 506 */
-       DLM_UNUSED_MSG2,         /* 507 */
+       DLM_DEREF_LOCKRES_MSG,   /* 507 */
        DLM_MIGRATE_REQUEST_MSG, /* 508 */
        DLM_MIG_LOCKRES_MSG,     /* 509 */
        DLM_QUERY_JOIN_MSG,      /* 510 */
@@ -417,6 +477,9 @@ struct dlm_master_request
        u8 name[O2NM_MAX_NAME_LEN];
 };
 
+#define DLM_ASSERT_RESPONSE_REASSERT       0x00000001
+#define DLM_ASSERT_RESPONSE_MASTERY_REF    0x00000002
+
 #define DLM_ASSERT_MASTER_MLE_CLEANUP      0x00000001
 #define DLM_ASSERT_MASTER_REQUERY          0x00000002
 #define DLM_ASSERT_MASTER_FINISH_MIGRATION 0x00000004
@@ -430,6 +493,8 @@ struct dlm_assert_master
        u8 name[O2NM_MAX_NAME_LEN];
 };
 
+#define DLM_MIGRATE_RESPONSE_MASTERY_REF   0x00000001
+
 struct dlm_migrate_request
 {
        u8 master;
@@ -573,10 +638,26 @@ struct dlm_proxy_ast
 #define DLM_PROXY_AST_MAX_LEN  (sizeof(struct dlm_proxy_ast)+DLM_LVB_LEN)
 
 #define DLM_MOD_KEY (0x666c6172)
-enum dlm_query_join_response {
+enum dlm_query_join_response_code {
        JOIN_DISALLOW = 0,
        JOIN_OK,
        JOIN_OK_NO_MAP,
+       JOIN_PROTOCOL_MISMATCH,
+};
+
+struct dlm_query_join_packet {
+       u8 code;        /* Response code.  dlm_minor and fs_minor
+                          are only valid if this is JOIN_OK */
+       u8 dlm_minor;   /* The minor version of the protocol the
+                          dlm is speaking. */
+       u8 fs_minor;    /* The minor version of the protocol the
+                          filesystem is speaking. */
+       u8 reserved;
+};
+
+union dlm_query_join_response {
+       u32 intval;
+       struct dlm_query_join_packet packet;
 };
 
 struct dlm_lock_request
@@ -609,12 +690,18 @@ struct dlm_begin_reco
 };
 
 
+#define BITS_PER_BYTE 8
+#define BITS_TO_BYTES(bits) (((bits)+BITS_PER_BYTE-1)/BITS_PER_BYTE)
+
 struct dlm_query_join_request
 {
        u8 node_idx;
        u8 pad1[2];
        u8 name_len;
+       struct dlm_protocol_version dlm_proto;
+       struct dlm_protocol_version fs_proto;
        u8 domain[O2NM_MAX_NAME_LEN];
+       u8 node_map[BITS_TO_BYTES(O2NM_MAX_NODES)];
 };
 
 struct dlm_assert_joined
@@ -648,6 +735,16 @@ struct dlm_finalize_reco
        __be32 pad2;
 };
 
+struct dlm_deref_lockres
+{
+       u32 pad1;
+       u16 pad2;
+       u8 node_idx;
+       u8 namelen;
+
+       u8 name[O2NM_MAX_NAME_LEN];
+};
+
 static inline enum dlm_status
 __dlm_lockres_state_to_status(struct dlm_lock_resource *res)
 {
@@ -688,16 +785,20 @@ void dlm_lock_put(struct dlm_lock *lock);
 void dlm_lock_attach_lockres(struct dlm_lock *lock,
                             struct dlm_lock_resource *res);
 
-int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data,
+                           void **ret_data);
+int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data,
+                            void **ret_data);
+int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
+                         void **ret_data);
 
 void dlm_revert_pending_convert(struct dlm_lock_resource *res,
                                struct dlm_lock *lock);
 void dlm_revert_pending_lock(struct dlm_lock_resource *res,
                             struct dlm_lock *lock);
 
-int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data,
+                           void **ret_data);
 void dlm_commit_pending_cancel(struct dlm_lock_resource *res,
                               struct dlm_lock *lock);
 void dlm_commit_pending_unlock(struct dlm_lock_resource *res,
@@ -721,8 +822,6 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
                              struct dlm_lock_resource *res);
 void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
                            struct dlm_lock_resource *res);
-void dlm_purge_lockres(struct dlm_ctxt *dlm,
-                      struct dlm_lock_resource *lockres);
 static inline void dlm_lockres_get(struct dlm_lock_resource *res)
 {
        /* This is called on every lookup, so it might be worth
@@ -733,6 +832,10 @@ void dlm_lockres_put(struct dlm_lock_resource *res);
 void __dlm_unhash_lockres(struct dlm_lock_resource *res);
 void __dlm_insert_lockres(struct dlm_ctxt *dlm,
                          struct dlm_lock_resource *res);
+struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
+                                                    const char *name,
+                                                    unsigned int len,
+                                                    unsigned int hash);
 struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
                                                const char *name,
                                                unsigned int len,
@@ -753,6 +856,47 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
                                          const char *name,
                                          unsigned int namelen);
 
+#define dlm_lockres_set_refmap_bit(bit,res)  \
+       __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
+#define dlm_lockres_clear_refmap_bit(bit,res)  \
+       __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__)
+
+static inline void __dlm_lockres_set_refmap_bit(int bit,
+                                               struct dlm_lock_resource *res,
+                                               const char *file,
+                                               int line)
+{
+       //printk("%s:%d:%.*s: setting bit %d\n", file, line,
+       //     res->lockname.len, res->lockname.name, bit);
+       set_bit(bit, res->refmap);
+}
+
+static inline void __dlm_lockres_clear_refmap_bit(int bit,
+                                                 struct dlm_lock_resource *res,
+                                                 const char *file,
+                                                 int line)
+{
+       //printk("%s:%d:%.*s: clearing bit %d\n", file, line,
+       //     res->lockname.len, res->lockname.name, bit);
+       clear_bit(bit, res->refmap);
+}
+
+void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res,
+                                  const char *file,
+                                  int line);
+void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res,
+                                  int new_lockres,
+                                  const char *file,
+                                  int line);
+#define dlm_lockres_drop_inflight_ref(d,r)  \
+       __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__)
+#define dlm_lockres_grab_inflight_ref(d,r)  \
+       __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__)
+#define dlm_lockres_grab_inflight_ref_new(d,r)  \
+       __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__)
+
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_do_local_ast(struct dlm_ctxt *dlm,
@@ -801,10 +945,7 @@ int dlm_heartbeat_init(struct dlm_ctxt *dlm);
 void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data);
 void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data);
 
-int dlm_lockres_is_dirty(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
-int dlm_migrate_lockres(struct dlm_ctxt *dlm,
-                       struct dlm_lock_resource *res,
-                       u8 target);
+int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
 int dlm_finish_migration(struct dlm_ctxt *dlm,
                         struct dlm_lock_resource *res,
                         u8 old_master);
@@ -812,15 +953,27 @@ void dlm_lockres_release_ast(struct dlm_ctxt *dlm,
                             struct dlm_lock_resource *res);
 void __dlm_lockres_reserve_ast(struct dlm_lock_resource *res);
 
-int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data);
-int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
+                              void **ret_data);
+int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
+                             void **ret_data);
+void dlm_assert_master_post_handler(int status, void *data, void *ret_data);
+int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
+                             void **ret_data);
+int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
+                               void **ret_data);
+int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
+                           void **ret_data);
+int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
+                              void **ret_data);
+int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data,
+                                 void **ret_data);
+int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data,
+                              void **ret_data);
+int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data,
+                          void **ret_data);
+int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data,
+                             void **ret_data);
 int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
                          u8 nodenum, u8 *real_master);
 
@@ -852,14 +1005,23 @@ static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
                                          DLM_LOCK_RES_MIGRATING));
 }
 
+/* create/destroy slab caches */
+int dlm_init_master_caches(void);
+void dlm_destroy_master_caches(void);
+
+int dlm_init_lock_cache(void);
+void dlm_destroy_lock_cache(void);
 
 int dlm_init_mle_cache(void);
 void dlm_destroy_mle_cache(void);
+
 void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
+int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
+                        struct dlm_lock_resource *res);
 void dlm_clean_master_list(struct dlm_ctxt *dlm,
                           u8 dead_node);
 int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
-
+int __dlm_lockres_has_locks(struct dlm_lock_resource *res);
 int __dlm_lockres_unused(struct dlm_lock_resource *res);
 
 static inline const char * dlm_lock_mode_name(int mode)