aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
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
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')
-rw-r--r--fs/ocfs2/dlmglue.c168
-rw-r--r--fs/ocfs2/stackglue.c43
-rw-r--r--fs/ocfs2/stackglue.h3
3 files changed, 110 insertions, 104 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{
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index fc184c762700..31db2e87cfd4 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -36,7 +36,7 @@
36#define OCFS2_STACK_PLUGIN_USER "user" 36#define OCFS2_STACK_PLUGIN_USER "user"
37#define OCFS2_MAX_HB_CTL_PATH 256 37#define OCFS2_MAX_HB_CTL_PATH 256
38 38
39static struct ocfs2_locking_protocol *lproto; 39static struct ocfs2_protocol_version locking_max_version;
40static DEFINE_SPINLOCK(ocfs2_stack_lock); 40static DEFINE_SPINLOCK(ocfs2_stack_lock);
41static LIST_HEAD(ocfs2_stack_list); 41static LIST_HEAD(ocfs2_stack_list);
42static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; 42static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
@@ -176,7 +176,7 @@ int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin)
176 spin_lock(&ocfs2_stack_lock); 176 spin_lock(&ocfs2_stack_lock);
177 if (!ocfs2_stack_lookup(plugin->sp_name)) { 177 if (!ocfs2_stack_lookup(plugin->sp_name)) {
178 plugin->sp_count = 0; 178 plugin->sp_count = 0;
179 plugin->sp_max_proto = lproto->lp_max_version; 179 plugin->sp_max_proto = locking_max_version;
180 list_add(&plugin->sp_list, &ocfs2_stack_list); 180 list_add(&plugin->sp_list, &ocfs2_stack_list);
181 printk(KERN_INFO "ocfs2: Registered cluster interface %s\n", 181 printk(KERN_INFO "ocfs2: Registered cluster interface %s\n",
182 plugin->sp_name); 182 plugin->sp_name);
@@ -213,23 +213,23 @@ void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin)
213} 213}
214EXPORT_SYMBOL_GPL(ocfs2_stack_glue_unregister); 214EXPORT_SYMBOL_GPL(ocfs2_stack_glue_unregister);
215 215
216void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) 216void ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto)
217{ 217{
218 struct ocfs2_stack_plugin *p; 218 struct ocfs2_stack_plugin *p;
219 219
220 BUG_ON(proto == NULL);
221
222 spin_lock(&ocfs2_stack_lock); 220 spin_lock(&ocfs2_stack_lock);
223 BUG_ON(active_stack != NULL); 221 if (memcmp(max_proto, &locking_max_version,
222 sizeof(struct ocfs2_protocol_version))) {
223 BUG_ON(locking_max_version.pv_major != 0);
224 224
225 lproto = proto; 225 locking_max_version = *max_proto;
226 list_for_each_entry(p, &ocfs2_stack_list, sp_list) { 226 list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
227 p->sp_max_proto = lproto->lp_max_version; 227 p->sp_max_proto = locking_max_version;
228 }
228 } 229 }
229
230 spin_unlock(&ocfs2_stack_lock); 230 spin_unlock(&ocfs2_stack_lock);
231} 231}
232EXPORT_SYMBOL_GPL(ocfs2_stack_glue_set_locking_protocol); 232EXPORT_SYMBOL_GPL(ocfs2_stack_glue_set_max_proto_version);
233 233
234 234
235/* 235/*
@@ -245,8 +245,6 @@ int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
245 void *name, 245 void *name,
246 unsigned int namelen) 246 unsigned int namelen)
247{ 247{
248 BUG_ON(lproto == NULL);
249
250 if (!lksb->lksb_conn) 248 if (!lksb->lksb_conn)
251 lksb->lksb_conn = conn; 249 lksb->lksb_conn = conn;
252 else 250 else
@@ -260,7 +258,6 @@ int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
260 struct ocfs2_dlm_lksb *lksb, 258 struct ocfs2_dlm_lksb *lksb,
261 u32 flags) 259 u32 flags)
262{ 260{
263 BUG_ON(lproto == NULL);
264 BUG_ON(lksb->lksb_conn == NULL); 261 BUG_ON(lksb->lksb_conn == NULL);
265 262
266 return active_stack->sp_ops->dlm_unlock(conn, lksb, flags); 263 return active_stack->sp_ops->dlm_unlock(conn, lksb, flags);
@@ -314,6 +311,7 @@ EXPORT_SYMBOL_GPL(ocfs2_plock);
314int ocfs2_cluster_connect(const char *stack_name, 311int ocfs2_cluster_connect(const char *stack_name,
315 const char *group, 312 const char *group,
316 int grouplen, 313 int grouplen,
314 struct ocfs2_locking_protocol *lproto,
317 void (*recovery_handler)(int node_num, 315 void (*recovery_handler)(int node_num,
318 void *recovery_data), 316 void *recovery_data),
319 void *recovery_data, 317 void *recovery_data,
@@ -331,6 +329,12 @@ int ocfs2_cluster_connect(const char *stack_name,
331 goto out; 329 goto out;
332 } 330 }
333 331
332 if (memcmp(&lproto->lp_max_version, &locking_max_version,
333 sizeof(struct ocfs2_protocol_version))) {
334 rc = -EINVAL;
335 goto out;
336 }
337
334 new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection), 338 new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection),
335 GFP_KERNEL); 339 GFP_KERNEL);
336 if (!new_conn) { 340 if (!new_conn) {
@@ -456,10 +460,10 @@ static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj,
456 ssize_t ret = 0; 460 ssize_t ret = 0;
457 461
458 spin_lock(&ocfs2_stack_lock); 462 spin_lock(&ocfs2_stack_lock);
459 if (lproto) 463 if (locking_max_version.pv_major)
460 ret = snprintf(buf, PAGE_SIZE, "%u.%u\n", 464 ret = snprintf(buf, PAGE_SIZE, "%u.%u\n",
461 lproto->lp_max_version.pv_major, 465 locking_max_version.pv_major,
462 lproto->lp_max_version.pv_minor); 466 locking_max_version.pv_minor);
463 spin_unlock(&ocfs2_stack_lock); 467 spin_unlock(&ocfs2_stack_lock);
464 468
465 return ret; 469 return ret;
@@ -688,7 +692,10 @@ static int __init ocfs2_stack_glue_init(void)
688 692
689static void __exit ocfs2_stack_glue_exit(void) 693static void __exit ocfs2_stack_glue_exit(void)
690{ 694{
691 lproto = NULL; 695 memset(&locking_max_version, 0,
696 sizeof(struct ocfs2_protocol_version));
697 locking_max_version.pv_major = 0;
698 locking_max_version.pv_minor = 0;
692 ocfs2_sysfs_exit(); 699 ocfs2_sysfs_exit();
693 if (ocfs2_table_header) 700 if (ocfs2_table_header)
694 unregister_sysctl_table(ocfs2_table_header); 701 unregister_sysctl_table(ocfs2_table_header);
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h
index 77a7a9aeba73..b1981ba4c91f 100644
--- a/fs/ocfs2/stackglue.h
+++ b/fs/ocfs2/stackglue.h
@@ -241,6 +241,7 @@ struct ocfs2_stack_plugin {
241int ocfs2_cluster_connect(const char *stack_name, 241int ocfs2_cluster_connect(const char *stack_name,
242 const char *group, 242 const char *group,
243 int grouplen, 243 int grouplen,
244 struct ocfs2_locking_protocol *lproto,
244 void (*recovery_handler)(int node_num, 245 void (*recovery_handler)(int node_num,
245 void *recovery_data), 246 void *recovery_data),
246 void *recovery_data, 247 void *recovery_data,
@@ -270,7 +271,7 @@ int ocfs2_stack_supports_plocks(void);
270int ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino, 271int ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
271 struct file *file, int cmd, struct file_lock *fl); 272 struct file *file, int cmd, struct file_lock *fl);
272 273
273void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto); 274void ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto);
274 275
275 276
276/* Used by stack plugins */ 277/* Used by stack plugins */