diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 1841bbb49cb6..110bb57c46ab 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -92,6 +92,9 @@ struct ocfs2_unblock_ctl { | |||
92 | enum ocfs2_unblock_action unblock_action; | 92 | enum ocfs2_unblock_action unblock_action; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* Lockdep class keys */ | ||
96 | struct lock_class_key lockdep_keys[OCFS2_NUM_LOCK_TYPES]; | ||
97 | |||
95 | static int ocfs2_check_meta_downconvert(struct ocfs2_lock_res *lockres, | 98 | static int ocfs2_check_meta_downconvert(struct ocfs2_lock_res *lockres, |
96 | int new_level); | 99 | int new_level); |
97 | static void ocfs2_set_meta_lvb(struct ocfs2_lock_res *lockres); | 100 | static void ocfs2_set_meta_lvb(struct ocfs2_lock_res *lockres); |
@@ -317,9 +320,16 @@ static int ocfs2_lock_create(struct ocfs2_super *osb, | |||
317 | u32 dlm_flags); | 320 | u32 dlm_flags); |
318 | static inline int ocfs2_may_continue_on_blocked_lock(struct ocfs2_lock_res *lockres, | 321 | static inline int ocfs2_may_continue_on_blocked_lock(struct ocfs2_lock_res *lockres, |
319 | int wanted); | 322 | int wanted); |
320 | static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | 323 | static void __ocfs2_cluster_unlock(struct ocfs2_super *osb, |
321 | struct ocfs2_lock_res *lockres, | 324 | struct ocfs2_lock_res *lockres, |
322 | int level); | 325 | int level, unsigned long caller_ip); |
326 | static inline void ocfs2_cluster_unlock(struct ocfs2_super *osb, | ||
327 | struct ocfs2_lock_res *lockres, | ||
328 | int level) | ||
329 | { | ||
330 | __ocfs2_cluster_unlock(osb, lockres, level, _RET_IP_); | ||
331 | } | ||
332 | |||
323 | static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres); | 333 | static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres); |
324 | static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres); | 334 | static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres); |
325 | static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres); | 335 | static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres); |
@@ -489,6 +499,13 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, | |||
489 | ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); | 499 | ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); |
490 | 500 | ||
491 | ocfs2_init_lock_stats(res); | 501 | ocfs2_init_lock_stats(res); |
502 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
503 | if (type != OCFS2_LOCK_TYPE_OPEN) | ||
504 | lockdep_init_map(&res->l_lockdep_map, ocfs2_lock_type_strings[type], | ||
505 | &lockdep_keys[type], 0); | ||
506 | else | ||
507 | res->l_lockdep_map.key = NULL; | ||
508 | #endif | ||
492 | } | 509 | } |
493 | 510 | ||
494 | void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) | 511 | void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) |
@@ -1252,11 +1269,13 @@ static int ocfs2_wait_for_mask_interruptible(struct ocfs2_mask_waiter *mw, | |||
1252 | return ret; | 1269 | return ret; |
1253 | } | 1270 | } |
1254 | 1271 | ||
1255 | static int ocfs2_cluster_lock(struct ocfs2_super *osb, | 1272 | static int __ocfs2_cluster_lock(struct ocfs2_super *osb, |
1256 | struct ocfs2_lock_res *lockres, | 1273 | struct ocfs2_lock_res *lockres, |
1257 | int level, | 1274 | int level, |
1258 | u32 lkm_flags, | 1275 | u32 lkm_flags, |
1259 | int arg_flags) | 1276 | int arg_flags, |
1277 | int l_subclass, | ||
1278 | unsigned long caller_ip) | ||
1260 | { | 1279 | { |
1261 | struct ocfs2_mask_waiter mw; | 1280 | struct ocfs2_mask_waiter mw; |
1262 | int wait, catch_signals = !(osb->s_mount_opt & OCFS2_MOUNT_NOINTR); | 1281 | int wait, catch_signals = !(osb->s_mount_opt & OCFS2_MOUNT_NOINTR); |
@@ -1399,13 +1418,37 @@ out: | |||
1399 | } | 1418 | } |
1400 | ocfs2_update_lock_stats(lockres, level, &mw, ret); | 1419 | ocfs2_update_lock_stats(lockres, level, &mw, ret); |
1401 | 1420 | ||
1421 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
1422 | if (!ret && lockres->l_lockdep_map.key != NULL) { | ||
1423 | if (level == DLM_LOCK_PR) | ||
1424 | rwsem_acquire_read(&lockres->l_lockdep_map, l_subclass, | ||
1425 | !!(arg_flags & OCFS2_META_LOCK_NOQUEUE), | ||
1426 | caller_ip); | ||
1427 | else | ||
1428 | rwsem_acquire(&lockres->l_lockdep_map, l_subclass, | ||
1429 | !!(arg_flags & OCFS2_META_LOCK_NOQUEUE), | ||
1430 | caller_ip); | ||
1431 | } | ||
1432 | #endif | ||
1402 | mlog_exit(ret); | 1433 | mlog_exit(ret); |
1403 | return ret; | 1434 | return ret; |
1404 | } | 1435 | } |
1405 | 1436 | ||
1406 | static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | 1437 | static inline int ocfs2_cluster_lock(struct ocfs2_super *osb, |
1407 | struct ocfs2_lock_res *lockres, | 1438 | struct ocfs2_lock_res *lockres, |
1408 | int level) | 1439 | int level, |
1440 | u32 lkm_flags, | ||
1441 | int arg_flags) | ||
1442 | { | ||
1443 | return __ocfs2_cluster_lock(osb, lockres, level, lkm_flags, arg_flags, | ||
1444 | 0, _RET_IP_); | ||
1445 | } | ||
1446 | |||
1447 | |||
1448 | static void __ocfs2_cluster_unlock(struct ocfs2_super *osb, | ||
1449 | struct ocfs2_lock_res *lockres, | ||
1450 | int level, | ||
1451 | unsigned long caller_ip) | ||
1409 | { | 1452 | { |
1410 | unsigned long flags; | 1453 | unsigned long flags; |
1411 | 1454 | ||
@@ -1414,6 +1457,10 @@ static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | |||
1414 | ocfs2_dec_holders(lockres, level); | 1457 | ocfs2_dec_holders(lockres, level); |
1415 | ocfs2_downconvert_on_unlock(osb, lockres); | 1458 | ocfs2_downconvert_on_unlock(osb, lockres); |
1416 | spin_unlock_irqrestore(&lockres->l_lock, flags); | 1459 | spin_unlock_irqrestore(&lockres->l_lock, flags); |
1460 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
1461 | if (lockres->l_lockdep_map.key != NULL) | ||
1462 | rwsem_release(&lockres->l_lockdep_map, 1, caller_ip); | ||
1463 | #endif | ||
1417 | mlog_exit_void(); | 1464 | mlog_exit_void(); |
1418 | } | 1465 | } |
1419 | 1466 | ||
@@ -2159,10 +2206,11 @@ static int ocfs2_assign_bh(struct inode *inode, | |||
2159 | * returns < 0 error if the callback will never be called, otherwise | 2206 | * returns < 0 error if the callback will never be called, otherwise |
2160 | * the result of the lock will be communicated via the callback. | 2207 | * the result of the lock will be communicated via the callback. |
2161 | */ | 2208 | */ |
2162 | int ocfs2_inode_lock_full(struct inode *inode, | 2209 | int ocfs2_inode_lock_full_nested(struct inode *inode, |
2163 | struct buffer_head **ret_bh, | 2210 | struct buffer_head **ret_bh, |
2164 | int ex, | 2211 | int ex, |
2165 | int arg_flags) | 2212 | int arg_flags, |
2213 | int subclass) | ||
2166 | { | 2214 | { |
2167 | int status, level, acquired; | 2215 | int status, level, acquired; |
2168 | u32 dlm_flags; | 2216 | u32 dlm_flags; |
@@ -2200,7 +2248,8 @@ int ocfs2_inode_lock_full(struct inode *inode, | |||
2200 | if (arg_flags & OCFS2_META_LOCK_NOQUEUE) | 2248 | if (arg_flags & OCFS2_META_LOCK_NOQUEUE) |
2201 | dlm_flags |= DLM_LKF_NOQUEUE; | 2249 | dlm_flags |= DLM_LKF_NOQUEUE; |
2202 | 2250 | ||
2203 | status = ocfs2_cluster_lock(osb, lockres, level, dlm_flags, arg_flags); | 2251 | status = __ocfs2_cluster_lock(osb, lockres, level, dlm_flags, |
2252 | arg_flags, subclass, _RET_IP_); | ||
2204 | if (status < 0) { | 2253 | if (status < 0) { |
2205 | if (status != -EAGAIN && status != -EIOCBRETRY) | 2254 | if (status != -EAGAIN && status != -EIOCBRETRY) |
2206 | mlog_errno(status); | 2255 | mlog_errno(status); |