diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.de> | 2014-01-21 18:48:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 19:19:41 -0500 |
commit | 415036303319c0a46caf9059711710bfa34e3bf3 (patch) | |
tree | 50cd3b7f3fb4948eaae3114f00b0a682cad1447f | |
parent | 3e8341516409d026636be4d7534b84e6e90bef37 (diff) |
ocfs2: framework for version LVB
Use the native DLM locks for version control negotiation. Most of the
framework is taken from gfs2/lock_dlm.c
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/ocfs2/stack_user.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index 22b95acc2a82..d3867100aca8 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c | |||
@@ -102,6 +102,7 @@ | |||
102 | #define OCFS2_TEXT_UUID_LEN 32 | 102 | #define OCFS2_TEXT_UUID_LEN 32 |
103 | #define OCFS2_CONTROL_MESSAGE_VERNUM_LEN 2 | 103 | #define OCFS2_CONTROL_MESSAGE_VERNUM_LEN 2 |
104 | #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8 | 104 | #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8 |
105 | #define VERSION_LOCK "version_lock" | ||
105 | 106 | ||
106 | enum ocfs2_connection_type { | 107 | enum ocfs2_connection_type { |
107 | WITH_CONTROLD, | 108 | WITH_CONTROLD, |
@@ -118,6 +119,9 @@ struct ocfs2_live_connection { | |||
118 | enum ocfs2_connection_type oc_type; | 119 | enum ocfs2_connection_type oc_type; |
119 | atomic_t oc_this_node; | 120 | atomic_t oc_this_node; |
120 | int oc_our_slot; | 121 | int oc_our_slot; |
122 | struct dlm_lksb oc_version_lksb; | ||
123 | char oc_lvb[DLM_LVB_LEN]; | ||
124 | struct completion oc_sync_wait; | ||
121 | }; | 125 | }; |
122 | 126 | ||
123 | struct ocfs2_control_private { | 127 | struct ocfs2_control_private { |
@@ -796,6 +800,103 @@ static int fs_protocol_compare(struct ocfs2_protocol_version *existing, | |||
796 | return 0; | 800 | return 0; |
797 | } | 801 | } |
798 | 802 | ||
803 | static void lvb_to_version(char *lvb, struct ocfs2_protocol_version *ver) | ||
804 | { | ||
805 | struct ocfs2_protocol_version *pv = | ||
806 | (struct ocfs2_protocol_version *)lvb; | ||
807 | /* | ||
808 | * ocfs2_protocol_version has two u8 variables, so we don't | ||
809 | * need any endian conversion. | ||
810 | */ | ||
811 | ver->pv_major = pv->pv_major; | ||
812 | ver->pv_minor = pv->pv_minor; | ||
813 | } | ||
814 | |||
815 | static void version_to_lvb(struct ocfs2_protocol_version *ver, char *lvb) | ||
816 | { | ||
817 | struct ocfs2_protocol_version *pv = | ||
818 | (struct ocfs2_protocol_version *)lvb; | ||
819 | /* | ||
820 | * ocfs2_protocol_version has two u8 variables, so we don't | ||
821 | * need any endian conversion. | ||
822 | */ | ||
823 | pv->pv_major = ver->pv_major; | ||
824 | pv->pv_minor = ver->pv_minor; | ||
825 | } | ||
826 | |||
827 | static void sync_wait_cb(void *arg) | ||
828 | { | ||
829 | struct ocfs2_cluster_connection *conn = arg; | ||
830 | struct ocfs2_live_connection *lc = conn->cc_private; | ||
831 | complete(&lc->oc_sync_wait); | ||
832 | } | ||
833 | |||
834 | static int sync_unlock(struct ocfs2_cluster_connection *conn, | ||
835 | struct dlm_lksb *lksb, char *name) | ||
836 | { | ||
837 | int error; | ||
838 | struct ocfs2_live_connection *lc = conn->cc_private; | ||
839 | |||
840 | error = dlm_unlock(conn->cc_lockspace, lksb->sb_lkid, 0, lksb, conn); | ||
841 | if (error) { | ||
842 | printk(KERN_ERR "%s lkid %x error %d\n", | ||
843 | name, lksb->sb_lkid, error); | ||
844 | return error; | ||
845 | } | ||
846 | |||
847 | wait_for_completion(&lc->oc_sync_wait); | ||
848 | |||
849 | if (lksb->sb_status != -DLM_EUNLOCK) { | ||
850 | printk(KERN_ERR "%s lkid %x status %d\n", | ||
851 | name, lksb->sb_lkid, lksb->sb_status); | ||
852 | return -1; | ||
853 | } | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | static int sync_lock(struct ocfs2_cluster_connection *conn, | ||
858 | int mode, uint32_t flags, | ||
859 | struct dlm_lksb *lksb, char *name) | ||
860 | { | ||
861 | int error, status; | ||
862 | struct ocfs2_live_connection *lc = conn->cc_private; | ||
863 | |||
864 | error = dlm_lock(conn->cc_lockspace, mode, lksb, flags, | ||
865 | name, strlen(name), | ||
866 | 0, sync_wait_cb, conn, NULL); | ||
867 | if (error) { | ||
868 | printk(KERN_ERR "%s lkid %x flags %x mode %d error %d\n", | ||
869 | name, lksb->sb_lkid, flags, mode, error); | ||
870 | return error; | ||
871 | } | ||
872 | |||
873 | wait_for_completion(&lc->oc_sync_wait); | ||
874 | |||
875 | status = lksb->sb_status; | ||
876 | |||
877 | if (status && status != -EAGAIN) { | ||
878 | printk(KERN_ERR "%s lkid %x flags %x mode %d status %d\n", | ||
879 | name, lksb->sb_lkid, flags, mode, status); | ||
880 | } | ||
881 | |||
882 | return status; | ||
883 | } | ||
884 | |||
885 | |||
886 | static int version_lock(struct ocfs2_cluster_connection *conn, int mode, | ||
887 | int flags) | ||
888 | { | ||
889 | struct ocfs2_live_connection *lc = conn->cc_private; | ||
890 | return sync_lock(conn, mode, flags, | ||
891 | &lc->oc_version_lksb, VERSION_LOCK); | ||
892 | } | ||
893 | |||
894 | static int version_unlock(struct ocfs2_cluster_connection *conn) | ||
895 | { | ||
896 | struct ocfs2_live_connection *lc = conn->cc_private; | ||
897 | return sync_unlock(conn, &lc->oc_version_lksb, VERSION_LOCK); | ||
898 | } | ||
899 | |||
799 | static void user_recover_prep(void *arg) | 900 | static void user_recover_prep(void *arg) |
800 | { | 901 | { |
801 | } | 902 | } |