diff options
-rw-r--r-- | fs/ocfs2/dlm/dlmrecovery.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 57736d3ea7b5..9d67894cda6d 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -1164,6 +1164,39 @@ static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres, | |||
1164 | mres->master = master; | 1164 | mres->master = master; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static void dlm_prepare_lvb_for_migration(struct dlm_lock *lock, | ||
1168 | struct dlm_migratable_lockres *mres, | ||
1169 | int queue) | ||
1170 | { | ||
1171 | if (!lock->lksb) | ||
1172 | return; | ||
1173 | |||
1174 | /* Ignore lvb in all locks in the blocked list */ | ||
1175 | if (queue == DLM_BLOCKED_LIST) | ||
1176 | return; | ||
1177 | |||
1178 | /* Only consider lvbs in locks with granted EX or PR lock levels */ | ||
1179 | if (lock->ml.type != LKM_EXMODE && lock->ml.type != LKM_PRMODE) | ||
1180 | return; | ||
1181 | |||
1182 | if (dlm_lvb_is_empty(mres->lvb)) { | ||
1183 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); | ||
1184 | return; | ||
1185 | } | ||
1186 | |||
1187 | /* Ensure the lvb copied for migration matches in other valid locks */ | ||
1188 | if (!memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN)) | ||
1189 | return; | ||
1190 | |||
1191 | mlog(ML_ERROR, "Mismatched lvb in lock cookie=%u:%llu, name=%.*s, " | ||
1192 | "node=%u\n", | ||
1193 | dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), | ||
1194 | dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), | ||
1195 | lock->lockres->lockname.len, lock->lockres->lockname.name, | ||
1196 | lock->ml.node); | ||
1197 | dlm_print_one_lock_resource(lock->lockres); | ||
1198 | BUG(); | ||
1199 | } | ||
1167 | 1200 | ||
1168 | /* returns 1 if this lock fills the network structure, | 1201 | /* returns 1 if this lock fills the network structure, |
1169 | * 0 otherwise */ | 1202 | * 0 otherwise */ |
@@ -1181,20 +1214,7 @@ static int dlm_add_lock_to_array(struct dlm_lock *lock, | |||
1181 | ml->list = queue; | 1214 | ml->list = queue; |
1182 | if (lock->lksb) { | 1215 | if (lock->lksb) { |
1183 | ml->flags = lock->lksb->flags; | 1216 | ml->flags = lock->lksb->flags; |
1184 | /* send our current lvb */ | 1217 | dlm_prepare_lvb_for_migration(lock, mres, queue); |
1185 | if (ml->type == LKM_EXMODE || | ||
1186 | ml->type == LKM_PRMODE) { | ||
1187 | /* if it is already set, this had better be a PR | ||
1188 | * and it has to match */ | ||
1189 | if (!dlm_lvb_is_empty(mres->lvb) && | ||
1190 | (ml->type == LKM_EXMODE || | ||
1191 | memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { | ||
1192 | mlog(ML_ERROR, "mismatched lvbs!\n"); | ||
1193 | dlm_print_one_lock_resource(lock->lockres); | ||
1194 | BUG(); | ||
1195 | } | ||
1196 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); | ||
1197 | } | ||
1198 | } | 1218 | } |
1199 | ml->node = lock->ml.node; | 1219 | ml->node = lock->ml.node; |
1200 | mres->num_locks++; | 1220 | mres->num_locks++; |