aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlmglue.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-01-29 20:19:06 -0500
committerJoel Becker <joel.becker@oracle.com>2010-02-26 18:41:17 -0500
commit553b5eb91abd5f8e679d23ae547b92c589726814 (patch)
tree99b3e550a11b0d62d45bbc78d73d448acadd138a /fs/ocfs2/dlmglue.c
parente603cfb074e150736814ef093a411df32c02ba9f (diff)
ocfs2: Pass the locking protocol into ocfs2_cluster_connect().
Inside the stackglue, the locking protocol structure is hanging off of the ocfs2_cluster_connection. This takes it one further; the locking protocol is passed into ocfs2_cluster_connect(). Now different cluster connections can have different locking protocols with distinct asts. Note that all locking protocols have to keep their maximum protocol version in lock-step. With the protocol structure set in ocfs2_cluster_connect(), there is no need for the stackglue to have a static pointer to a specific protocol structure. We can change initialization to only pass in the maximum protocol version. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r--fs/ocfs2/dlmglue.c168
1 files changed, 83 insertions, 85 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 2bb868b7b44f..d009d7744d63 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1045,7 +1045,6 @@ static unsigned int lockres_set_pending(struct ocfs2_lock_res *lockres)
1045 return lockres->l_pending_gen; 1045 return lockres->l_pending_gen;
1046} 1046}
1047 1047
1048
1049static void ocfs2_blocking_ast(struct ocfs2_dlm_lksb *lksb, int level) 1048static void ocfs2_blocking_ast(struct ocfs2_dlm_lksb *lksb, int level)
1050{ 1049{
1051 struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb); 1050 struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb);
@@ -1139,6 +1138,88 @@ out:
1139 spin_unlock_irqrestore(&lockres->l_lock, flags); 1138 spin_unlock_irqrestore(&lockres->l_lock, flags);
1140} 1139}
1141 1140
1141static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error)
1142{
1143 struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb);
1144 unsigned long flags;
1145
1146 mlog_entry_void();
1147
1148 mlog(0, "UNLOCK AST called on lock %s, action = %d\n", lockres->l_name,
1149 lockres->l_unlock_action);
1150
1151 spin_lock_irqsave(&lockres->l_lock, flags);
1152 if (error) {
1153 mlog(ML_ERROR, "Dlm passes error %d for lock %s, "
1154 "unlock_action %d\n", error, lockres->l_name,
1155 lockres->l_unlock_action);
1156 spin_unlock_irqrestore(&lockres->l_lock, flags);
1157 mlog_exit_void();
1158 return;
1159 }
1160
1161 switch(lockres->l_unlock_action) {
1162 case OCFS2_UNLOCK_CANCEL_CONVERT:
1163 mlog(0, "Cancel convert success for %s\n", lockres->l_name);
1164 lockres->l_action = OCFS2_AST_INVALID;
1165 /* Downconvert thread may have requeued this lock, we
1166 * need to wake it. */
1167 if (lockres->l_flags & OCFS2_LOCK_BLOCKED)
1168 ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres));
1169 break;
1170 case OCFS2_UNLOCK_DROP_LOCK:
1171 lockres->l_level = DLM_LOCK_IV;
1172 break;
1173 default:
1174 BUG();
1175 }
1176
1177 lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
1178 lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
1179 wake_up(&lockres->l_event);
1180 spin_unlock_irqrestore(&lockres->l_lock, flags);
1181
1182 mlog_exit_void();
1183}
1184
1185/*
1186 * This is the filesystem locking protocol. It provides the lock handling
1187 * hooks for the underlying DLM. It has a maximum version number.
1188 * The version number allows interoperability with systems running at
1189 * the same major number and an equal or smaller minor number.
1190 *
1191 * Whenever the filesystem does new things with locks (adds or removes a
1192 * lock, orders them differently, does different things underneath a lock),
1193 * the version must be changed. The protocol is negotiated when joining
1194 * the dlm domain. A node may join the domain if its major version is
1195 * identical to all other nodes and its minor version is greater than
1196 * or equal to all other nodes. When its minor version is greater than
1197 * the other nodes, it will run at the minor version specified by the
1198 * other nodes.
1199 *
1200 * If a locking change is made that will not be compatible with older
1201 * versions, the major number must be increased and the minor version set
1202 * to zero. If a change merely adds a behavior that can be disabled when
1203 * speaking to older versions, the minor version must be increased. If a
1204 * change adds a fully backwards compatible change (eg, LVB changes that
1205 * are just ignored by older versions), the version does not need to be
1206 * updated.
1207 */
1208static struct ocfs2_locking_protocol lproto = {
1209 .lp_max_version = {
1210 .pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
1211 .pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
1212 },
1213 .lp_lock_ast = ocfs2_locking_ast,
1214 .lp_blocking_ast = ocfs2_blocking_ast,
1215 .lp_unlock_ast = ocfs2_unlock_ast,
1216};
1217
1218void ocfs2_set_locking_protocol(void)
1219{
1220 ocfs2_stack_glue_set_max_proto_version(&lproto.lp_max_version);
1221}
1222
1142static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, 1223static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
1143 int convert) 1224 int convert)
1144{ 1225{
@@ -2991,7 +3072,7 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
2991 status = ocfs2_cluster_connect(osb->osb_cluster_stack, 3072 status = ocfs2_cluster_connect(osb->osb_cluster_stack,
2992 osb->uuid_str, 3073 osb->uuid_str,
2993 strlen(osb->uuid_str), 3074 strlen(osb->uuid_str),
2994 ocfs2_do_node_down, osb, 3075 &lproto, ocfs2_do_node_down, osb,
2995 &conn); 3076 &conn);
2996 if (status) { 3077 if (status) {
2997 mlog_errno(status); 3078 mlog_errno(status);
@@ -3058,50 +3139,6 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb,
3058 mlog_exit_void(); 3139 mlog_exit_void();
3059} 3140}
3060 3141
3061static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error)
3062{
3063 struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb);
3064 unsigned long flags;
3065
3066 mlog_entry_void();
3067
3068 mlog(0, "UNLOCK AST called on lock %s, action = %d\n", lockres->l_name,
3069 lockres->l_unlock_action);
3070
3071 spin_lock_irqsave(&lockres->l_lock, flags);
3072 if (error) {
3073 mlog(ML_ERROR, "Dlm passes error %d for lock %s, "
3074 "unlock_action %d\n", error, lockres->l_name,
3075 lockres->l_unlock_action);
3076 spin_unlock_irqrestore(&lockres->l_lock, flags);
3077 mlog_exit_void();
3078 return;
3079 }
3080
3081 switch(lockres->l_unlock_action) {
3082 case OCFS2_UNLOCK_CANCEL_CONVERT:
3083 mlog(0, "Cancel convert success for %s\n", lockres->l_name);
3084 lockres->l_action = OCFS2_AST_INVALID;
3085 /* Downconvert thread may have requeued this lock, we
3086 * need to wake it. */
3087 if (lockres->l_flags & OCFS2_LOCK_BLOCKED)
3088 ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres));
3089 break;
3090 case OCFS2_UNLOCK_DROP_LOCK:
3091 lockres->l_level = DLM_LOCK_IV;
3092 break;
3093 default:
3094 BUG();
3095 }
3096
3097 lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
3098 lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
3099 wake_up(&lockres->l_event);
3100 spin_unlock_irqrestore(&lockres->l_lock, flags);
3101
3102 mlog_exit_void();
3103}
3104
3105static int ocfs2_drop_lock(struct ocfs2_super *osb, 3142static int ocfs2_drop_lock(struct ocfs2_super *osb,
3106 struct ocfs2_lock_res *lockres) 3143 struct ocfs2_lock_res *lockres)
3107{ 3144{
@@ -3910,45 +3947,6 @@ void ocfs2_refcount_unlock(struct ocfs2_refcount_tree *ref_tree, int ex)
3910 ocfs2_cluster_unlock(osb, lockres, level); 3947 ocfs2_cluster_unlock(osb, lockres, level);
3911} 3948}
3912 3949
3913/*
3914 * This is the filesystem locking protocol. It provides the lock handling
3915 * hooks for the underlying DLM. It has a maximum version number.
3916 * The version number allows interoperability with systems running at
3917 * the same major number and an equal or smaller minor number.
3918 *
3919 * Whenever the filesystem does new things with locks (adds or removes a
3920 * lock, orders them differently, does different things underneath a lock),
3921 * the version must be changed. The protocol is negotiated when joining
3922 * the dlm domain. A node may join the domain if its major version is
3923 * identical to all other nodes and its minor version is greater than
3924 * or equal to all other nodes. When its minor version is greater than
3925 * the other nodes, it will run at the minor version specified by the
3926 * other nodes.
3927 *
3928 * If a locking change is made that will not be compatible with older
3929 * versions, the major number must be increased and the minor version set
3930 * to zero. If a change merely adds a behavior that can be disabled when
3931 * speaking to older versions, the minor version must be increased. If a
3932 * change adds a fully backwards compatible change (eg, LVB changes that
3933 * are just ignored by older versions), the version does not need to be
3934 * updated.
3935 */
3936static struct ocfs2_locking_protocol lproto = {
3937 .lp_max_version = {
3938 .pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
3939 .pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
3940 },
3941 .lp_lock_ast = ocfs2_locking_ast,
3942 .lp_blocking_ast = ocfs2_blocking_ast,
3943 .lp_unlock_ast = ocfs2_unlock_ast,
3944};
3945
3946void ocfs2_set_locking_protocol(void)
3947{
3948 ocfs2_stack_glue_set_locking_protocol(&lproto);
3949}
3950
3951
3952static void ocfs2_process_blocked_lock(struct ocfs2_super *osb, 3950static void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
3953 struct ocfs2_lock_res *lockres) 3951 struct ocfs2_lock_res *lockres)
3954{ 3952{