diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 123 |
1 files changed, 90 insertions, 33 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 6cdeaa76f27f..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) |
@@ -644,14 +661,10 @@ static void ocfs2_nfs_sync_lock_res_init(struct ocfs2_lock_res *res, | |||
644 | static void ocfs2_orphan_scan_lock_res_init(struct ocfs2_lock_res *res, | 661 | static void ocfs2_orphan_scan_lock_res_init(struct ocfs2_lock_res *res, |
645 | struct ocfs2_super *osb) | 662 | struct ocfs2_super *osb) |
646 | { | 663 | { |
647 | struct ocfs2_orphan_scan_lvb *lvb; | ||
648 | |||
649 | ocfs2_lock_res_init_once(res); | 664 | ocfs2_lock_res_init_once(res); |
650 | ocfs2_build_lock_name(OCFS2_LOCK_TYPE_ORPHAN_SCAN, 0, 0, res->l_name); | 665 | ocfs2_build_lock_name(OCFS2_LOCK_TYPE_ORPHAN_SCAN, 0, 0, res->l_name); |
651 | ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_ORPHAN_SCAN, | 666 | ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_ORPHAN_SCAN, |
652 | &ocfs2_orphan_scan_lops, osb); | 667 | &ocfs2_orphan_scan_lops, osb); |
653 | lvb = ocfs2_dlm_lvb(&res->l_lksb); | ||
654 | lvb->lvb_version = OCFS2_ORPHAN_LVB_VERSION; | ||
655 | } | 668 | } |
656 | 669 | ||
657 | void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres, | 670 | void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres, |
@@ -1256,11 +1269,13 @@ static int ocfs2_wait_for_mask_interruptible(struct ocfs2_mask_waiter *mw, | |||
1256 | return ret; | 1269 | return ret; |
1257 | } | 1270 | } |
1258 | 1271 | ||
1259 | static int ocfs2_cluster_lock(struct ocfs2_super *osb, | 1272 | static int __ocfs2_cluster_lock(struct ocfs2_super *osb, |
1260 | struct ocfs2_lock_res *lockres, | 1273 | struct ocfs2_lock_res *lockres, |
1261 | int level, | 1274 | int level, |
1262 | u32 lkm_flags, | 1275 | u32 lkm_flags, |
1263 | int arg_flags) | 1276 | int arg_flags, |
1277 | int l_subclass, | ||
1278 | unsigned long caller_ip) | ||
1264 | { | 1279 | { |
1265 | struct ocfs2_mask_waiter mw; | 1280 | struct ocfs2_mask_waiter mw; |
1266 | int wait, catch_signals = !(osb->s_mount_opt & OCFS2_MOUNT_NOINTR); | 1281 | int wait, catch_signals = !(osb->s_mount_opt & OCFS2_MOUNT_NOINTR); |
@@ -1403,13 +1418,37 @@ out: | |||
1403 | } | 1418 | } |
1404 | ocfs2_update_lock_stats(lockres, level, &mw, ret); | 1419 | ocfs2_update_lock_stats(lockres, level, &mw, ret); |
1405 | 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 | ||
1406 | mlog_exit(ret); | 1433 | mlog_exit(ret); |
1407 | return ret; | 1434 | return ret; |
1408 | } | 1435 | } |
1409 | 1436 | ||
1410 | static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | 1437 | static inline int ocfs2_cluster_lock(struct ocfs2_super *osb, |
1411 | struct ocfs2_lock_res *lockres, | 1438 | struct ocfs2_lock_res *lockres, |
1412 | 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) | ||
1413 | { | 1452 | { |
1414 | unsigned long flags; | 1453 | unsigned long flags; |
1415 | 1454 | ||
@@ -1418,6 +1457,10 @@ static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | |||
1418 | ocfs2_dec_holders(lockres, level); | 1457 | ocfs2_dec_holders(lockres, level); |
1419 | ocfs2_downconvert_on_unlock(osb, lockres); | 1458 | ocfs2_downconvert_on_unlock(osb, lockres); |
1420 | 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 | ||
1421 | mlog_exit_void(); | 1464 | mlog_exit_void(); |
1422 | } | 1465 | } |
1423 | 1466 | ||
@@ -1989,7 +2032,8 @@ static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode, | |||
1989 | { | 2032 | { |
1990 | struct ocfs2_meta_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | 2033 | struct ocfs2_meta_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
1991 | 2034 | ||
1992 | if (lvb->lvb_version == OCFS2_LVB_VERSION | 2035 | if (ocfs2_dlm_lvb_valid(&lockres->l_lksb) |
2036 | && lvb->lvb_version == OCFS2_LVB_VERSION | ||
1993 | && be32_to_cpu(lvb->lvb_igeneration) == inode->i_generation) | 2037 | && be32_to_cpu(lvb->lvb_igeneration) == inode->i_generation) |
1994 | return 1; | 2038 | return 1; |
1995 | return 0; | 2039 | return 0; |
@@ -2162,10 +2206,11 @@ static int ocfs2_assign_bh(struct inode *inode, | |||
2162 | * returns < 0 error if the callback will never be called, otherwise | 2206 | * returns < 0 error if the callback will never be called, otherwise |
2163 | * the result of the lock will be communicated via the callback. | 2207 | * the result of the lock will be communicated via the callback. |
2164 | */ | 2208 | */ |
2165 | int ocfs2_inode_lock_full(struct inode *inode, | 2209 | int ocfs2_inode_lock_full_nested(struct inode *inode, |
2166 | struct buffer_head **ret_bh, | 2210 | struct buffer_head **ret_bh, |
2167 | int ex, | 2211 | int ex, |
2168 | int arg_flags) | 2212 | int arg_flags, |
2213 | int subclass) | ||
2169 | { | 2214 | { |
2170 | int status, level, acquired; | 2215 | int status, level, acquired; |
2171 | u32 dlm_flags; | 2216 | u32 dlm_flags; |
@@ -2203,7 +2248,8 @@ int ocfs2_inode_lock_full(struct inode *inode, | |||
2203 | if (arg_flags & OCFS2_META_LOCK_NOQUEUE) | 2248 | if (arg_flags & OCFS2_META_LOCK_NOQUEUE) |
2204 | dlm_flags |= DLM_LKF_NOQUEUE; | 2249 | dlm_flags |= DLM_LKF_NOQUEUE; |
2205 | 2250 | ||
2206 | 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_); | ||
2207 | if (status < 0) { | 2253 | if (status < 0) { |
2208 | if (status != -EAGAIN && status != -EIOCBRETRY) | 2254 | if (status != -EAGAIN && status != -EIOCBRETRY) |
2209 | mlog_errno(status); | 2255 | mlog_errno(status); |
@@ -2369,35 +2415,45 @@ void ocfs2_inode_unlock(struct inode *inode, | |||
2369 | mlog_exit_void(); | 2415 | mlog_exit_void(); |
2370 | } | 2416 | } |
2371 | 2417 | ||
2372 | int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno, int ex) | 2418 | int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno) |
2373 | { | 2419 | { |
2374 | struct ocfs2_lock_res *lockres; | 2420 | struct ocfs2_lock_res *lockres; |
2375 | struct ocfs2_orphan_scan_lvb *lvb; | 2421 | struct ocfs2_orphan_scan_lvb *lvb; |
2376 | int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; | ||
2377 | int status = 0; | 2422 | int status = 0; |
2378 | 2423 | ||
2424 | if (ocfs2_is_hard_readonly(osb)) | ||
2425 | return -EROFS; | ||
2426 | |||
2427 | if (ocfs2_mount_local(osb)) | ||
2428 | return 0; | ||
2429 | |||
2379 | lockres = &osb->osb_orphan_scan.os_lockres; | 2430 | lockres = &osb->osb_orphan_scan.os_lockres; |
2380 | status = ocfs2_cluster_lock(osb, lockres, level, 0, 0); | 2431 | status = ocfs2_cluster_lock(osb, lockres, DLM_LOCK_EX, 0, 0); |
2381 | if (status < 0) | 2432 | if (status < 0) |
2382 | return status; | 2433 | return status; |
2383 | 2434 | ||
2384 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | 2435 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
2385 | if (lvb->lvb_version == OCFS2_ORPHAN_LVB_VERSION) | 2436 | if (ocfs2_dlm_lvb_valid(&lockres->l_lksb) && |
2437 | lvb->lvb_version == OCFS2_ORPHAN_LVB_VERSION) | ||
2386 | *seqno = be32_to_cpu(lvb->lvb_os_seqno); | 2438 | *seqno = be32_to_cpu(lvb->lvb_os_seqno); |
2439 | else | ||
2440 | *seqno = osb->osb_orphan_scan.os_seqno + 1; | ||
2441 | |||
2387 | return status; | 2442 | return status; |
2388 | } | 2443 | } |
2389 | 2444 | ||
2390 | void ocfs2_orphan_scan_unlock(struct ocfs2_super *osb, u32 seqno, int ex) | 2445 | void ocfs2_orphan_scan_unlock(struct ocfs2_super *osb, u32 seqno) |
2391 | { | 2446 | { |
2392 | struct ocfs2_lock_res *lockres; | 2447 | struct ocfs2_lock_res *lockres; |
2393 | struct ocfs2_orphan_scan_lvb *lvb; | 2448 | struct ocfs2_orphan_scan_lvb *lvb; |
2394 | int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; | ||
2395 | 2449 | ||
2396 | lockres = &osb->osb_orphan_scan.os_lockres; | 2450 | if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb)) { |
2397 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | 2451 | lockres = &osb->osb_orphan_scan.os_lockres; |
2398 | lvb->lvb_version = OCFS2_ORPHAN_LVB_VERSION; | 2452 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
2399 | lvb->lvb_os_seqno = cpu_to_be32(seqno); | 2453 | lvb->lvb_version = OCFS2_ORPHAN_LVB_VERSION; |
2400 | ocfs2_cluster_unlock(osb, lockres, level); | 2454 | lvb->lvb_os_seqno = cpu_to_be32(seqno); |
2455 | ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_EX); | ||
2456 | } | ||
2401 | } | 2457 | } |
2402 | 2458 | ||
2403 | int ocfs2_super_lock(struct ocfs2_super *osb, | 2459 | int ocfs2_super_lock(struct ocfs2_super *osb, |
@@ -3627,7 +3683,8 @@ static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo) | |||
3627 | struct ocfs2_global_disk_dqinfo *gdinfo; | 3683 | struct ocfs2_global_disk_dqinfo *gdinfo; |
3628 | int status = 0; | 3684 | int status = 0; |
3629 | 3685 | ||
3630 | if (lvb->lvb_version == OCFS2_QINFO_LVB_VERSION) { | 3686 | if (ocfs2_dlm_lvb_valid(&lockres->l_lksb) && |
3687 | lvb->lvb_version == OCFS2_QINFO_LVB_VERSION) { | ||
3631 | info->dqi_bgrace = be32_to_cpu(lvb->lvb_bgrace); | 3688 | info->dqi_bgrace = be32_to_cpu(lvb->lvb_bgrace); |
3632 | info->dqi_igrace = be32_to_cpu(lvb->lvb_igrace); | 3689 | info->dqi_igrace = be32_to_cpu(lvb->lvb_igrace); |
3633 | oinfo->dqi_syncms = be32_to_cpu(lvb->lvb_syncms); | 3690 | oinfo->dqi_syncms = be32_to_cpu(lvb->lvb_syncms); |