diff options
| -rw-r--r-- | fs/inode.c | 17 | ||||
| -rw-r--r-- | fs/ocfs2/dlmglue.c | 123 | ||||
| -rw-r--r-- | fs/ocfs2/dlmglue.h | 24 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 6 | ||||
| -rw-r--r-- | fs/ocfs2/inode.c | 11 | ||||
| -rw-r--r-- | fs/ocfs2/journal.c | 43 | ||||
| -rw-r--r-- | fs/ocfs2/journal.h | 2 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 15 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2.h | 10 | ||||
| -rw-r--r-- | fs/ocfs2/stack_o2cb.c | 11 | ||||
| -rw-r--r-- | fs/ocfs2/stack_user.c | 8 | ||||
| -rw-r--r-- | fs/ocfs2/stackglue.c | 13 | ||||
| -rw-r--r-- | fs/ocfs2/stackglue.h | 6 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.c | 28 | ||||
| -rw-r--r-- | fs/ocfs2/super.c | 69 | ||||
| -rw-r--r-- | fs/ocfs2/sysfile.c | 19 | ||||
| -rw-r--r-- | include/linux/lockdep.h | 15 |
17 files changed, 309 insertions, 111 deletions
diff --git a/fs/inode.c b/fs/inode.c index f643be565df8..04c785bb63c3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -665,12 +665,17 @@ void unlock_new_inode(struct inode *inode) | |||
| 665 | if (inode->i_mode & S_IFDIR) { | 665 | if (inode->i_mode & S_IFDIR) { |
| 666 | struct file_system_type *type = inode->i_sb->s_type; | 666 | struct file_system_type *type = inode->i_sb->s_type; |
| 667 | 667 | ||
| 668 | /* | 668 | /* Set new key only if filesystem hasn't already changed it */ |
| 669 | * ensure nobody is actually holding i_mutex | 669 | if (!lockdep_match_class(&inode->i_mutex, |
| 670 | */ | 670 | &type->i_mutex_key)) { |
| 671 | mutex_destroy(&inode->i_mutex); | 671 | /* |
| 672 | mutex_init(&inode->i_mutex); | 672 | * ensure nobody is actually holding i_mutex |
| 673 | lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key); | 673 | */ |
| 674 | mutex_destroy(&inode->i_mutex); | ||
| 675 | mutex_init(&inode->i_mutex); | ||
| 676 | lockdep_set_class(&inode->i_mutex, | ||
| 677 | &type->i_mutex_dir_key); | ||
| 678 | } | ||
| 674 | } | 679 | } |
| 675 | #endif | 680 | #endif |
| 676 | /* | 681 | /* |
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); |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 31b90d7b8f51..7553836931de 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
| @@ -78,6 +78,14 @@ struct ocfs2_orphan_scan_lvb { | |||
| 78 | /* don't block waiting for the downconvert thread, instead return -EAGAIN */ | 78 | /* don't block waiting for the downconvert thread, instead return -EAGAIN */ |
| 79 | #define OCFS2_LOCK_NONBLOCK (0x04) | 79 | #define OCFS2_LOCK_NONBLOCK (0x04) |
| 80 | 80 | ||
| 81 | /* Locking subclasses of inode cluster lock */ | ||
| 82 | enum { | ||
| 83 | OI_LS_NORMAL = 0, | ||
| 84 | OI_LS_PARENT, | ||
| 85 | OI_LS_RENAME1, | ||
| 86 | OI_LS_RENAME2, | ||
| 87 | }; | ||
| 88 | |||
| 81 | int ocfs2_dlm_init(struct ocfs2_super *osb); | 89 | int ocfs2_dlm_init(struct ocfs2_super *osb); |
| 82 | void ocfs2_dlm_shutdown(struct ocfs2_super *osb, int hangup_pending); | 90 | void ocfs2_dlm_shutdown(struct ocfs2_super *osb, int hangup_pending); |
| 83 | void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res); | 91 | void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res); |
| @@ -104,25 +112,31 @@ void ocfs2_open_unlock(struct inode *inode); | |||
| 104 | int ocfs2_inode_lock_atime(struct inode *inode, | 112 | int ocfs2_inode_lock_atime(struct inode *inode, |
| 105 | struct vfsmount *vfsmnt, | 113 | struct vfsmount *vfsmnt, |
| 106 | int *level); | 114 | int *level); |
| 107 | int ocfs2_inode_lock_full(struct inode *inode, | 115 | int ocfs2_inode_lock_full_nested(struct inode *inode, |
| 108 | struct buffer_head **ret_bh, | 116 | struct buffer_head **ret_bh, |
| 109 | int ex, | 117 | int ex, |
| 110 | int arg_flags); | 118 | int arg_flags, |
| 119 | int subclass); | ||
| 111 | int ocfs2_inode_lock_with_page(struct inode *inode, | 120 | int ocfs2_inode_lock_with_page(struct inode *inode, |
| 112 | struct buffer_head **ret_bh, | 121 | struct buffer_head **ret_bh, |
| 113 | int ex, | 122 | int ex, |
| 114 | struct page *page); | 123 | struct page *page); |
| 124 | /* Variants without special locking class or flags */ | ||
| 125 | #define ocfs2_inode_lock_full(i, r, e, f)\ | ||
| 126 | ocfs2_inode_lock_full_nested(i, r, e, f, OI_LS_NORMAL) | ||
| 127 | #define ocfs2_inode_lock_nested(i, b, e, s)\ | ||
| 128 | ocfs2_inode_lock_full_nested(i, b, e, 0, s) | ||
| 115 | /* 99% of the time we don't want to supply any additional flags -- | 129 | /* 99% of the time we don't want to supply any additional flags -- |
| 116 | * those are for very specific cases only. */ | 130 | * those are for very specific cases only. */ |
| 117 | #define ocfs2_inode_lock(i, b, e) ocfs2_inode_lock_full(i, b, e, 0) | 131 | #define ocfs2_inode_lock(i, b, e) ocfs2_inode_lock_full_nested(i, b, e, 0, OI_LS_NORMAL) |
| 118 | void ocfs2_inode_unlock(struct inode *inode, | 132 | void ocfs2_inode_unlock(struct inode *inode, |
| 119 | int ex); | 133 | int ex); |
| 120 | int ocfs2_super_lock(struct ocfs2_super *osb, | 134 | int ocfs2_super_lock(struct ocfs2_super *osb, |
| 121 | int ex); | 135 | int ex); |
| 122 | void ocfs2_super_unlock(struct ocfs2_super *osb, | 136 | void ocfs2_super_unlock(struct ocfs2_super *osb, |
| 123 | int ex); | 137 | int ex); |
| 124 | int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno, int ex); | 138 | int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno); |
| 125 | void ocfs2_orphan_scan_unlock(struct ocfs2_super *osb, u32 seqno, int ex); | 139 | void ocfs2_orphan_scan_unlock(struct ocfs2_super *osb, u32 seqno); |
| 126 | 140 | ||
| 127 | int ocfs2_rename_lock(struct ocfs2_super *osb); | 141 | int ocfs2_rename_lock(struct ocfs2_super *osb); |
| 128 | void ocfs2_rename_unlock(struct ocfs2_super *osb); | 142 | void ocfs2_rename_unlock(struct ocfs2_super *osb); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 07267e0da909..62442e413a00 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -2026,7 +2026,7 @@ static ssize_t ocfs2_file_splice_read(struct file *in, | |||
| 2026 | size_t len, | 2026 | size_t len, |
| 2027 | unsigned int flags) | 2027 | unsigned int flags) |
| 2028 | { | 2028 | { |
| 2029 | int ret = 0; | 2029 | int ret = 0, lock_level = 0; |
| 2030 | struct inode *inode = in->f_path.dentry->d_inode; | 2030 | struct inode *inode = in->f_path.dentry->d_inode; |
| 2031 | 2031 | ||
| 2032 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe, | 2032 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe, |
| @@ -2037,12 +2037,12 @@ static ssize_t ocfs2_file_splice_read(struct file *in, | |||
| 2037 | /* | 2037 | /* |
| 2038 | * See the comment in ocfs2_file_aio_read() | 2038 | * See the comment in ocfs2_file_aio_read() |
| 2039 | */ | 2039 | */ |
| 2040 | ret = ocfs2_inode_lock(inode, NULL, 0); | 2040 | ret = ocfs2_inode_lock_atime(inode, in->f_vfsmnt, &lock_level); |
| 2041 | if (ret < 0) { | 2041 | if (ret < 0) { |
| 2042 | mlog_errno(ret); | 2042 | mlog_errno(ret); |
| 2043 | goto bail; | 2043 | goto bail; |
| 2044 | } | 2044 | } |
| 2045 | ocfs2_inode_unlock(inode, 0); | 2045 | ocfs2_inode_unlock(inode, lock_level); |
| 2046 | 2046 | ||
| 2047 | ret = generic_file_splice_read(in, ppos, pipe, len, flags); | 2047 | ret = generic_file_splice_read(in, ppos, pipe, len, flags); |
| 2048 | 2048 | ||
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 10e1fa87396a..4dc8890ba316 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -215,6 +215,8 @@ bail: | |||
| 215 | static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) | 215 | static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) |
| 216 | { | 216 | { |
| 217 | struct ocfs2_find_inode_args *args = opaque; | 217 | struct ocfs2_find_inode_args *args = opaque; |
| 218 | static struct lock_class_key ocfs2_quota_ip_alloc_sem_key, | ||
| 219 | ocfs2_file_ip_alloc_sem_key; | ||
| 218 | 220 | ||
| 219 | mlog_entry("inode = %p, opaque = %p\n", inode, opaque); | 221 | mlog_entry("inode = %p, opaque = %p\n", inode, opaque); |
| 220 | 222 | ||
| @@ -223,6 +225,15 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque) | |||
| 223 | if (args->fi_sysfile_type != 0) | 225 | if (args->fi_sysfile_type != 0) |
| 224 | lockdep_set_class(&inode->i_mutex, | 226 | lockdep_set_class(&inode->i_mutex, |
| 225 | &ocfs2_sysfile_lock_key[args->fi_sysfile_type]); | 227 | &ocfs2_sysfile_lock_key[args->fi_sysfile_type]); |
| 228 | if (args->fi_sysfile_type == USER_QUOTA_SYSTEM_INODE || | ||
| 229 | args->fi_sysfile_type == GROUP_QUOTA_SYSTEM_INODE || | ||
| 230 | args->fi_sysfile_type == LOCAL_USER_QUOTA_SYSTEM_INODE || | ||
| 231 | args->fi_sysfile_type == LOCAL_GROUP_QUOTA_SYSTEM_INODE) | ||
| 232 | lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem, | ||
| 233 | &ocfs2_quota_ip_alloc_sem_key); | ||
| 234 | else | ||
| 235 | lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem, | ||
| 236 | &ocfs2_file_ip_alloc_sem_key); | ||
| 226 | 237 | ||
| 227 | mlog_exit(0); | 238 | mlog_exit(0); |
| 228 | return 0; | 239 | return 0; |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 4a3b9e6b31ad..f033760ecbea 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -1880,13 +1880,20 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) | |||
| 1880 | 1880 | ||
| 1881 | os = &osb->osb_orphan_scan; | 1881 | os = &osb->osb_orphan_scan; |
| 1882 | 1882 | ||
| 1883 | status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX); | 1883 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE) |
| 1884 | goto out; | ||
| 1885 | |||
| 1886 | status = ocfs2_orphan_scan_lock(osb, &seqno); | ||
| 1884 | if (status < 0) { | 1887 | if (status < 0) { |
| 1885 | if (status != -EAGAIN) | 1888 | if (status != -EAGAIN) |
| 1886 | mlog_errno(status); | 1889 | mlog_errno(status); |
| 1887 | goto out; | 1890 | goto out; |
| 1888 | } | 1891 | } |
| 1889 | 1892 | ||
| 1893 | /* Do no queue the tasks if the volume is being umounted */ | ||
| 1894 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE) | ||
| 1895 | goto unlock; | ||
| 1896 | |||
| 1890 | if (os->os_seqno != seqno) { | 1897 | if (os->os_seqno != seqno) { |
| 1891 | os->os_seqno = seqno; | 1898 | os->os_seqno = seqno; |
| 1892 | goto unlock; | 1899 | goto unlock; |
| @@ -1903,7 +1910,7 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) | |||
| 1903 | os->os_count++; | 1910 | os->os_count++; |
| 1904 | os->os_scantime = CURRENT_TIME; | 1911 | os->os_scantime = CURRENT_TIME; |
| 1905 | unlock: | 1912 | unlock: |
| 1906 | ocfs2_orphan_scan_unlock(osb, seqno, DLM_LOCK_EX); | 1913 | ocfs2_orphan_scan_unlock(osb, seqno); |
| 1907 | out: | 1914 | out: |
| 1908 | return; | 1915 | return; |
| 1909 | } | 1916 | } |
| @@ -1920,8 +1927,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work) | |||
| 1920 | 1927 | ||
| 1921 | mutex_lock(&os->os_lock); | 1928 | mutex_lock(&os->os_lock); |
| 1922 | ocfs2_queue_orphan_scan(osb); | 1929 | ocfs2_queue_orphan_scan(osb); |
| 1923 | schedule_delayed_work(&os->os_orphan_scan_work, | 1930 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) |
| 1924 | ocfs2_orphan_scan_timeout()); | 1931 | schedule_delayed_work(&os->os_orphan_scan_work, |
| 1932 | ocfs2_orphan_scan_timeout()); | ||
| 1925 | mutex_unlock(&os->os_lock); | 1933 | mutex_unlock(&os->os_lock); |
| 1926 | } | 1934 | } |
| 1927 | 1935 | ||
| @@ -1930,26 +1938,33 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb) | |||
| 1930 | struct ocfs2_orphan_scan *os; | 1938 | struct ocfs2_orphan_scan *os; |
| 1931 | 1939 | ||
| 1932 | os = &osb->osb_orphan_scan; | 1940 | os = &osb->osb_orphan_scan; |
| 1933 | mutex_lock(&os->os_lock); | 1941 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) { |
| 1934 | cancel_delayed_work(&os->os_orphan_scan_work); | 1942 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); |
| 1935 | mutex_unlock(&os->os_lock); | 1943 | mutex_lock(&os->os_lock); |
| 1944 | cancel_delayed_work(&os->os_orphan_scan_work); | ||
| 1945 | mutex_unlock(&os->os_lock); | ||
| 1946 | } | ||
| 1936 | } | 1947 | } |
| 1937 | 1948 | ||
| 1938 | int ocfs2_orphan_scan_init(struct ocfs2_super *osb) | 1949 | void ocfs2_orphan_scan_init(struct ocfs2_super *osb) |
| 1939 | { | 1950 | { |
| 1940 | struct ocfs2_orphan_scan *os; | 1951 | struct ocfs2_orphan_scan *os; |
| 1941 | 1952 | ||
| 1942 | os = &osb->osb_orphan_scan; | 1953 | os = &osb->osb_orphan_scan; |
| 1943 | os->os_osb = osb; | 1954 | os->os_osb = osb; |
| 1944 | os->os_count = 0; | 1955 | os->os_count = 0; |
| 1956 | os->os_seqno = 0; | ||
| 1945 | os->os_scantime = CURRENT_TIME; | 1957 | os->os_scantime = CURRENT_TIME; |
| 1946 | mutex_init(&os->os_lock); | 1958 | mutex_init(&os->os_lock); |
| 1947 | 1959 | INIT_DELAYED_WORK(&os->os_orphan_scan_work, ocfs2_orphan_scan_work); | |
| 1948 | INIT_DELAYED_WORK(&os->os_orphan_scan_work, | 1960 | |
| 1949 | ocfs2_orphan_scan_work); | 1961 | if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb)) |
| 1950 | schedule_delayed_work(&os->os_orphan_scan_work, | 1962 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); |
| 1951 | ocfs2_orphan_scan_timeout()); | 1963 | else { |
| 1952 | return 0; | 1964 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); |
| 1965 | schedule_delayed_work(&os->os_orphan_scan_work, | ||
| 1966 | ocfs2_orphan_scan_timeout()); | ||
| 1967 | } | ||
| 1953 | } | 1968 | } |
| 1954 | 1969 | ||
| 1955 | struct ocfs2_orphan_filldir_priv { | 1970 | struct ocfs2_orphan_filldir_priv { |
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 61045eeb3f6e..5432c7f79cc6 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
| @@ -144,7 +144,7 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | /* Exported only for the journal struct init code in super.c. Do not call. */ | 146 | /* Exported only for the journal struct init code in super.c. Do not call. */ |
| 147 | int ocfs2_orphan_scan_init(struct ocfs2_super *osb); | 147 | void ocfs2_orphan_scan_init(struct ocfs2_super *osb); |
| 148 | void ocfs2_orphan_scan_stop(struct ocfs2_super *osb); | 148 | void ocfs2_orphan_scan_stop(struct ocfs2_super *osb); |
| 149 | void ocfs2_orphan_scan_exit(struct ocfs2_super *osb); | 149 | void ocfs2_orphan_scan_exit(struct ocfs2_super *osb); |
| 150 | 150 | ||
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 33464c6b60a2..8601f934010b 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -118,7 +118,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
| 118 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, | 118 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, |
| 119 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); | 119 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); |
| 120 | 120 | ||
| 121 | status = ocfs2_inode_lock(dir, NULL, 0); | 121 | status = ocfs2_inode_lock_nested(dir, NULL, 0, OI_LS_PARENT); |
| 122 | if (status < 0) { | 122 | if (status < 0) { |
| 123 | if (status != -ENOENT) | 123 | if (status != -ENOENT) |
| 124 | mlog_errno(status); | 124 | mlog_errno(status); |
| @@ -636,7 +636,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 636 | if (S_ISDIR(inode->i_mode)) | 636 | if (S_ISDIR(inode->i_mode)) |
| 637 | return -EPERM; | 637 | return -EPERM; |
| 638 | 638 | ||
| 639 | err = ocfs2_inode_lock(dir, &parent_fe_bh, 1); | 639 | err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT); |
| 640 | if (err < 0) { | 640 | if (err < 0) { |
| 641 | if (err != -ENOENT) | 641 | if (err != -ENOENT) |
| 642 | mlog_errno(err); | 642 | mlog_errno(err); |
| @@ -800,7 +800,8 @@ static int ocfs2_unlink(struct inode *dir, | |||
| 800 | return -EPERM; | 800 | return -EPERM; |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | status = ocfs2_inode_lock(dir, &parent_node_bh, 1); | 803 | status = ocfs2_inode_lock_nested(dir, &parent_node_bh, 1, |
| 804 | OI_LS_PARENT); | ||
| 804 | if (status < 0) { | 805 | if (status < 0) { |
| 805 | if (status != -ENOENT) | 806 | if (status != -ENOENT) |
| 806 | mlog_errno(status); | 807 | mlog_errno(status); |
| @@ -978,7 +979,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
| 978 | inode1 = tmpinode; | 979 | inode1 = tmpinode; |
| 979 | } | 980 | } |
| 980 | /* lock id2 */ | 981 | /* lock id2 */ |
| 981 | status = ocfs2_inode_lock(inode2, bh2, 1); | 982 | status = ocfs2_inode_lock_nested(inode2, bh2, 1, |
| 983 | OI_LS_RENAME1); | ||
| 982 | if (status < 0) { | 984 | if (status < 0) { |
| 983 | if (status != -ENOENT) | 985 | if (status != -ENOENT) |
| 984 | mlog_errno(status); | 986 | mlog_errno(status); |
| @@ -987,7 +989,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
| 987 | } | 989 | } |
| 988 | 990 | ||
| 989 | /* lock id1 */ | 991 | /* lock id1 */ |
| 990 | status = ocfs2_inode_lock(inode1, bh1, 1); | 992 | status = ocfs2_inode_lock_nested(inode1, bh1, 1, OI_LS_RENAME2); |
| 991 | if (status < 0) { | 993 | if (status < 0) { |
| 992 | /* | 994 | /* |
| 993 | * An error return must mean that no cluster locks | 995 | * An error return must mean that no cluster locks |
| @@ -1103,7 +1105,8 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1103 | * won't have to concurrently downconvert the inode and the | 1105 | * won't have to concurrently downconvert the inode and the |
| 1104 | * dentry locks. | 1106 | * dentry locks. |
| 1105 | */ | 1107 | */ |
| 1106 | status = ocfs2_inode_lock(old_inode, &old_inode_bh, 1); | 1108 | status = ocfs2_inode_lock_nested(old_inode, &old_inode_bh, 1, |
| 1109 | OI_LS_PARENT); | ||
| 1107 | if (status < 0) { | 1110 | if (status < 0) { |
| 1108 | if (status != -ENOENT) | 1111 | if (status != -ENOENT) |
| 1109 | mlog_errno(status); | 1112 | mlog_errno(status); |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 18c1d9ec1c93..c9345ebb8493 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
| 36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
| 37 | #include <linux/lockdep.h> | ||
| 37 | #ifndef CONFIG_OCFS2_COMPAT_JBD | 38 | #ifndef CONFIG_OCFS2_COMPAT_JBD |
| 38 | # include <linux/jbd2.h> | 39 | # include <linux/jbd2.h> |
| 39 | #else | 40 | #else |
| @@ -152,6 +153,14 @@ struct ocfs2_lock_res { | |||
| 152 | unsigned int l_lock_max_exmode; /* Max wait for EX */ | 153 | unsigned int l_lock_max_exmode; /* Max wait for EX */ |
| 153 | unsigned int l_lock_refresh; /* Disk refreshes */ | 154 | unsigned int l_lock_refresh; /* Disk refreshes */ |
| 154 | #endif | 155 | #endif |
| 156 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 157 | struct lockdep_map l_lockdep_map; | ||
| 158 | #endif | ||
| 159 | }; | ||
| 160 | |||
| 161 | enum ocfs2_orphan_scan_state { | ||
| 162 | ORPHAN_SCAN_ACTIVE, | ||
| 163 | ORPHAN_SCAN_INACTIVE | ||
| 155 | }; | 164 | }; |
| 156 | 165 | ||
| 157 | struct ocfs2_orphan_scan { | 166 | struct ocfs2_orphan_scan { |
| @@ -162,6 +171,7 @@ struct ocfs2_orphan_scan { | |||
| 162 | struct timespec os_scantime; /* time this node ran the scan */ | 171 | struct timespec os_scantime; /* time this node ran the scan */ |
| 163 | u32 os_count; /* tracks node specific scans */ | 172 | u32 os_count; /* tracks node specific scans */ |
| 164 | u32 os_seqno; /* tracks cluster wide scans */ | 173 | u32 os_seqno; /* tracks cluster wide scans */ |
| 174 | atomic_t os_state; /* ACTIVE or INACTIVE */ | ||
| 165 | }; | 175 | }; |
| 166 | 176 | ||
| 167 | struct ocfs2_dlm_debug { | 177 | struct ocfs2_dlm_debug { |
diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index fcd120f1493a..3f661376a2de 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c | |||
| @@ -236,6 +236,16 @@ static int o2cb_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | |||
| 236 | return dlm_status_to_errno(lksb->lksb_o2dlm.status); | 236 | return dlm_status_to_errno(lksb->lksb_o2dlm.status); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | /* | ||
| 240 | * o2dlm aways has a "valid" LVB. If the dlm loses track of the LVB | ||
| 241 | * contents, it will zero out the LVB. Thus the caller can always trust | ||
| 242 | * the contents. | ||
| 243 | */ | ||
| 244 | static int o2cb_dlm_lvb_valid(union ocfs2_dlm_lksb *lksb) | ||
| 245 | { | ||
| 246 | return 1; | ||
| 247 | } | ||
| 248 | |||
| 239 | static void *o2cb_dlm_lvb(union ocfs2_dlm_lksb *lksb) | 249 | static void *o2cb_dlm_lvb(union ocfs2_dlm_lksb *lksb) |
| 240 | { | 250 | { |
| 241 | return (void *)(lksb->lksb_o2dlm.lvb); | 251 | return (void *)(lksb->lksb_o2dlm.lvb); |
| @@ -354,6 +364,7 @@ static struct ocfs2_stack_operations o2cb_stack_ops = { | |||
| 354 | .dlm_lock = o2cb_dlm_lock, | 364 | .dlm_lock = o2cb_dlm_lock, |
| 355 | .dlm_unlock = o2cb_dlm_unlock, | 365 | .dlm_unlock = o2cb_dlm_unlock, |
| 356 | .lock_status = o2cb_dlm_lock_status, | 366 | .lock_status = o2cb_dlm_lock_status, |
| 367 | .lvb_valid = o2cb_dlm_lvb_valid, | ||
| 357 | .lock_lvb = o2cb_dlm_lvb, | 368 | .lock_lvb = o2cb_dlm_lvb, |
| 358 | .dump_lksb = o2cb_dump_lksb, | 369 | .dump_lksb = o2cb_dump_lksb, |
| 359 | }; | 370 | }; |
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index 9b76d41a8ac6..ff4c798a5635 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c | |||
| @@ -738,6 +738,13 @@ static int user_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | |||
| 738 | return lksb->lksb_fsdlm.sb_status; | 738 | return lksb->lksb_fsdlm.sb_status; |
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | static int user_dlm_lvb_valid(union ocfs2_dlm_lksb *lksb) | ||
| 742 | { | ||
| 743 | int invalid = lksb->lksb_fsdlm.sb_flags & DLM_SBF_VALNOTVALID; | ||
| 744 | |||
| 745 | return !invalid; | ||
| 746 | } | ||
| 747 | |||
| 741 | static void *user_dlm_lvb(union ocfs2_dlm_lksb *lksb) | 748 | static void *user_dlm_lvb(union ocfs2_dlm_lksb *lksb) |
| 742 | { | 749 | { |
| 743 | if (!lksb->lksb_fsdlm.sb_lvbptr) | 750 | if (!lksb->lksb_fsdlm.sb_lvbptr) |
| @@ -873,6 +880,7 @@ static struct ocfs2_stack_operations ocfs2_user_plugin_ops = { | |||
| 873 | .dlm_lock = user_dlm_lock, | 880 | .dlm_lock = user_dlm_lock, |
| 874 | .dlm_unlock = user_dlm_unlock, | 881 | .dlm_unlock = user_dlm_unlock, |
| 875 | .lock_status = user_dlm_lock_status, | 882 | .lock_status = user_dlm_lock_status, |
| 883 | .lvb_valid = user_dlm_lvb_valid, | ||
| 876 | .lock_lvb = user_dlm_lvb, | 884 | .lock_lvb = user_dlm_lvb, |
| 877 | .plock = user_plock, | 885 | .plock = user_plock, |
| 878 | .dump_lksb = user_dlm_dump_lksb, | 886 | .dump_lksb = user_dlm_dump_lksb, |
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 68b668b0e60a..3f2f1c45b7b6 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Code which implements an OCFS2 specific interface to underlying | 6 | * Code which implements an OCFS2 specific interface to underlying |
| 7 | * cluster stacks. | 7 | * cluster stacks. |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2007 Oracle. All rights reserved. | 9 | * Copyright (C) 2007, 2009 Oracle. All rights reserved. |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public | 12 | * modify it under the terms of the GNU General Public |
| @@ -271,11 +271,12 @@ int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb) | |||
| 271 | } | 271 | } |
| 272 | EXPORT_SYMBOL_GPL(ocfs2_dlm_lock_status); | 272 | EXPORT_SYMBOL_GPL(ocfs2_dlm_lock_status); |
| 273 | 273 | ||
| 274 | /* | 274 | int ocfs2_dlm_lvb_valid(union ocfs2_dlm_lksb *lksb) |
| 275 | * Why don't we cast to ocfs2_meta_lvb? The "clean" answer is that we | 275 | { |
| 276 | * don't cast at the glue level. The real answer is that the header | 276 | return active_stack->sp_ops->lvb_valid(lksb); |
| 277 | * ordering is nigh impossible. | 277 | } |
| 278 | */ | 278 | EXPORT_SYMBOL_GPL(ocfs2_dlm_lvb_valid); |
| 279 | |||
| 279 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb) | 280 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb) |
| 280 | { | 281 | { |
| 281 | return active_stack->sp_ops->lock_lvb(lksb); | 282 | return active_stack->sp_ops->lock_lvb(lksb); |
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h index c571af375ef8..03a44d60eac9 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h | |||
| @@ -186,6 +186,11 @@ struct ocfs2_stack_operations { | |||
| 186 | int (*lock_status)(union ocfs2_dlm_lksb *lksb); | 186 | int (*lock_status)(union ocfs2_dlm_lksb *lksb); |
| 187 | 187 | ||
| 188 | /* | 188 | /* |
| 189 | * Return non-zero if the LVB is valid. | ||
| 190 | */ | ||
| 191 | int (*lvb_valid)(union ocfs2_dlm_lksb *lksb); | ||
| 192 | |||
| 193 | /* | ||
| 189 | * Pull the lvb pointer off of the stack-specific lksb. | 194 | * Pull the lvb pointer off of the stack-specific lksb. |
| 190 | */ | 195 | */ |
| 191 | void *(*lock_lvb)(union ocfs2_dlm_lksb *lksb); | 196 | void *(*lock_lvb)(union ocfs2_dlm_lksb *lksb); |
| @@ -252,6 +257,7 @@ int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn, | |||
| 252 | struct ocfs2_lock_res *astarg); | 257 | struct ocfs2_lock_res *astarg); |
| 253 | 258 | ||
| 254 | int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb); | 259 | int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb); |
| 260 | int ocfs2_dlm_lvb_valid(union ocfs2_dlm_lksb *lksb); | ||
| 255 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb); | 261 | void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb); |
| 256 | void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb); | 262 | void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb); |
| 257 | 263 | ||
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 8439f6b324b9..73a16d4666dc 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -923,14 +923,23 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, | |||
| 923 | int nr) | 923 | int nr) |
| 924 | { | 924 | { |
| 925 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 925 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
| 926 | int ret; | ||
| 926 | 927 | ||
| 927 | if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap)) | 928 | if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap)) |
| 928 | return 0; | 929 | return 0; |
| 929 | if (!buffer_jbd(bg_bh) || !bh2jh(bg_bh)->b_committed_data) | 930 | |
| 931 | if (!buffer_jbd(bg_bh)) | ||
| 930 | return 1; | 932 | return 1; |
| 931 | 933 | ||
| 934 | jbd_lock_bh_state(bg_bh); | ||
| 932 | bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data; | 935 | bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data; |
| 933 | return !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap); | 936 | if (bg) |
| 937 | ret = !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap); | ||
| 938 | else | ||
| 939 | ret = 1; | ||
| 940 | jbd_unlock_bh_state(bg_bh); | ||
| 941 | |||
| 942 | return ret; | ||
| 934 | } | 943 | } |
| 935 | 944 | ||
| 936 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | 945 | static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, |
| @@ -1885,6 +1894,7 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
| 1885 | unsigned int tmp; | 1894 | unsigned int tmp; |
| 1886 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; | 1895 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; |
| 1887 | struct ocfs2_group_desc *undo_bg = NULL; | 1896 | struct ocfs2_group_desc *undo_bg = NULL; |
| 1897 | int cluster_bitmap = 0; | ||
| 1888 | 1898 | ||
| 1889 | mlog_entry_void(); | 1899 | mlog_entry_void(); |
| 1890 | 1900 | ||
| @@ -1905,18 +1915,28 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
| 1905 | } | 1915 | } |
| 1906 | 1916 | ||
| 1907 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 1917 | if (ocfs2_is_cluster_bitmap(alloc_inode)) |
| 1908 | undo_bg = (struct ocfs2_group_desc *) bh2jh(group_bh)->b_committed_data; | 1918 | cluster_bitmap = 1; |
| 1919 | |||
| 1920 | if (cluster_bitmap) { | ||
| 1921 | jbd_lock_bh_state(group_bh); | ||
| 1922 | undo_bg = (struct ocfs2_group_desc *) | ||
| 1923 | bh2jh(group_bh)->b_committed_data; | ||
| 1924 | BUG_ON(!undo_bg); | ||
| 1925 | } | ||
| 1909 | 1926 | ||
| 1910 | tmp = num_bits; | 1927 | tmp = num_bits; |
| 1911 | while(tmp--) { | 1928 | while(tmp--) { |
| 1912 | ocfs2_clear_bit((bit_off + tmp), | 1929 | ocfs2_clear_bit((bit_off + tmp), |
| 1913 | (unsigned long *) bg->bg_bitmap); | 1930 | (unsigned long *) bg->bg_bitmap); |
| 1914 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 1931 | if (cluster_bitmap) |
| 1915 | ocfs2_set_bit(bit_off + tmp, | 1932 | ocfs2_set_bit(bit_off + tmp, |
| 1916 | (unsigned long *) undo_bg->bg_bitmap); | 1933 | (unsigned long *) undo_bg->bg_bitmap); |
| 1917 | } | 1934 | } |
| 1918 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); | 1935 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); |
| 1919 | 1936 | ||
| 1937 | if (cluster_bitmap) | ||
| 1938 | jbd_unlock_bh_state(group_bh); | ||
| 1939 | |||
| 1920 | status = ocfs2_journal_dirty(handle, group_bh); | 1940 | status = ocfs2_journal_dirty(handle, group_bh); |
| 1921 | if (status < 0) | 1941 | if (status < 0) |
| 1922 | mlog_errno(status); | 1942 | mlog_errno(status); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 0d3ed7407a04..7efb349fb9bd 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -205,11 +205,10 @@ static const match_table_t tokens = { | |||
| 205 | #ifdef CONFIG_DEBUG_FS | 205 | #ifdef CONFIG_DEBUG_FS |
| 206 | static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | 206 | static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) |
| 207 | { | 207 | { |
| 208 | int out = 0; | ||
| 209 | int i; | ||
| 210 | struct ocfs2_cluster_connection *cconn = osb->cconn; | 208 | struct ocfs2_cluster_connection *cconn = osb->cconn; |
| 211 | struct ocfs2_recovery_map *rm = osb->recovery_map; | 209 | struct ocfs2_recovery_map *rm = osb->recovery_map; |
| 212 | struct ocfs2_orphan_scan *os; | 210 | struct ocfs2_orphan_scan *os = &osb->osb_orphan_scan; |
| 211 | int i, out = 0; | ||
| 213 | 212 | ||
| 214 | out += snprintf(buf + out, len - out, | 213 | out += snprintf(buf + out, len - out, |
| 215 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", | 214 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", |
| @@ -234,20 +233,24 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
| 234 | "%10s => Opts: 0x%lX AtimeQuanta: %u\n", "Mount", | 233 | "%10s => Opts: 0x%lX AtimeQuanta: %u\n", "Mount", |
| 235 | osb->s_mount_opt, osb->s_atime_quantum); | 234 | osb->s_mount_opt, osb->s_atime_quantum); |
| 236 | 235 | ||
| 237 | out += snprintf(buf + out, len - out, | 236 | if (cconn) { |
| 238 | "%10s => Stack: %s Name: %*s Version: %d.%d\n", | 237 | out += snprintf(buf + out, len - out, |
| 239 | "Cluster", | 238 | "%10s => Stack: %s Name: %*s " |
| 240 | (*osb->osb_cluster_stack == '\0' ? | 239 | "Version: %d.%d\n", "Cluster", |
| 241 | "o2cb" : osb->osb_cluster_stack), | 240 | (*osb->osb_cluster_stack == '\0' ? |
| 242 | cconn->cc_namelen, cconn->cc_name, | 241 | "o2cb" : osb->osb_cluster_stack), |
| 243 | cconn->cc_version.pv_major, cconn->cc_version.pv_minor); | 242 | cconn->cc_namelen, cconn->cc_name, |
| 243 | cconn->cc_version.pv_major, | ||
| 244 | cconn->cc_version.pv_minor); | ||
| 245 | } | ||
| 244 | 246 | ||
| 245 | spin_lock(&osb->dc_task_lock); | 247 | spin_lock(&osb->dc_task_lock); |
| 246 | out += snprintf(buf + out, len - out, | 248 | out += snprintf(buf + out, len - out, |
| 247 | "%10s => Pid: %d Count: %lu WakeSeq: %lu " | 249 | "%10s => Pid: %d Count: %lu WakeSeq: %lu " |
| 248 | "WorkSeq: %lu\n", "DownCnvt", | 250 | "WorkSeq: %lu\n", "DownCnvt", |
| 249 | task_pid_nr(osb->dc_task), osb->blocked_lock_count, | 251 | (osb->dc_task ? task_pid_nr(osb->dc_task) : -1), |
| 250 | osb->dc_wake_sequence, osb->dc_work_sequence); | 252 | osb->blocked_lock_count, osb->dc_wake_sequence, |
| 253 | osb->dc_work_sequence); | ||
| 251 | spin_unlock(&osb->dc_task_lock); | 254 | spin_unlock(&osb->dc_task_lock); |
| 252 | 255 | ||
| 253 | spin_lock(&osb->osb_lock); | 256 | spin_lock(&osb->osb_lock); |
| @@ -267,14 +270,15 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
| 267 | 270 | ||
| 268 | out += snprintf(buf + out, len - out, | 271 | out += snprintf(buf + out, len - out, |
| 269 | "%10s => Pid: %d Interval: %lu Needs: %d\n", "Commit", | 272 | "%10s => Pid: %d Interval: %lu Needs: %d\n", "Commit", |
| 270 | task_pid_nr(osb->commit_task), osb->osb_commit_interval, | 273 | (osb->commit_task ? task_pid_nr(osb->commit_task) : -1), |
| 274 | osb->osb_commit_interval, | ||
| 271 | atomic_read(&osb->needs_checkpoint)); | 275 | atomic_read(&osb->needs_checkpoint)); |
| 272 | 276 | ||
| 273 | out += snprintf(buf + out, len - out, | 277 | out += snprintf(buf + out, len - out, |
| 274 | "%10s => State: %d NumTxns: %d TxnId: %lu\n", | 278 | "%10s => State: %d TxnId: %lu NumTxns: %d\n", |
| 275 | "Journal", osb->journal->j_state, | 279 | "Journal", osb->journal->j_state, |
| 276 | atomic_read(&osb->journal->j_num_trans), | 280 | osb->journal->j_trans_id, |
| 277 | osb->journal->j_trans_id); | 281 | atomic_read(&osb->journal->j_num_trans)); |
| 278 | 282 | ||
| 279 | out += snprintf(buf + out, len - out, | 283 | out += snprintf(buf + out, len - out, |
| 280 | "%10s => GlobalAllocs: %d LocalAllocs: %d " | 284 | "%10s => GlobalAllocs: %d LocalAllocs: %d " |
| @@ -300,9 +304,18 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
| 300 | atomic_read(&osb->s_num_inodes_stolen)); | 304 | atomic_read(&osb->s_num_inodes_stolen)); |
| 301 | spin_unlock(&osb->osb_lock); | 305 | spin_unlock(&osb->osb_lock); |
| 302 | 306 | ||
| 307 | out += snprintf(buf + out, len - out, "OrphanScan => "); | ||
| 308 | out += snprintf(buf + out, len - out, "Local: %u Global: %u ", | ||
| 309 | os->os_count, os->os_seqno); | ||
| 310 | out += snprintf(buf + out, len - out, " Last Scan: "); | ||
| 311 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE) | ||
| 312 | out += snprintf(buf + out, len - out, "Disabled\n"); | ||
| 313 | else | ||
| 314 | out += snprintf(buf + out, len - out, "%lu seconds ago\n", | ||
| 315 | (get_seconds() - os->os_scantime.tv_sec)); | ||
| 316 | |||
| 303 | out += snprintf(buf + out, len - out, "%10s => %3s %10s\n", | 317 | out += snprintf(buf + out, len - out, "%10s => %3s %10s\n", |
| 304 | "Slots", "Num", "RecoGen"); | 318 | "Slots", "Num", "RecoGen"); |
| 305 | |||
| 306 | for (i = 0; i < osb->max_slots; ++i) { | 319 | for (i = 0; i < osb->max_slots; ++i) { |
| 307 | out += snprintf(buf + out, len - out, | 320 | out += snprintf(buf + out, len - out, |
| 308 | "%10s %c %3d %10d\n", | 321 | "%10s %c %3d %10d\n", |
| @@ -311,13 +324,6 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
| 311 | i, osb->slot_recovery_generations[i]); | 324 | i, osb->slot_recovery_generations[i]); |
| 312 | } | 325 | } |
| 313 | 326 | ||
| 314 | os = &osb->osb_orphan_scan; | ||
| 315 | out += snprintf(buf + out, len - out, "Orphan Scan=> "); | ||
| 316 | out += snprintf(buf + out, len - out, "Local: %u Global: %u ", | ||
| 317 | os->os_count, os->os_seqno); | ||
| 318 | out += snprintf(buf + out, len - out, " Last Scan: %lu seconds ago\n", | ||
| 319 | (get_seconds() - os->os_scantime.tv_sec)); | ||
| 320 | |||
| 321 | return out; | 327 | return out; |
| 322 | } | 328 | } |
| 323 | 329 | ||
| @@ -1175,6 +1181,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1175 | atomic_set(&osb->vol_state, VOLUME_MOUNTED_QUOTAS); | 1181 | atomic_set(&osb->vol_state, VOLUME_MOUNTED_QUOTAS); |
| 1176 | wake_up(&osb->osb_mount_event); | 1182 | wake_up(&osb->osb_mount_event); |
| 1177 | 1183 | ||
| 1184 | /* Start this when the mount is almost sure of being successful */ | ||
| 1185 | ocfs2_orphan_scan_init(osb); | ||
| 1186 | |||
| 1178 | mlog_exit(status); | 1187 | mlog_exit(status); |
| 1179 | return status; | 1188 | return status; |
| 1180 | 1189 | ||
| @@ -1810,14 +1819,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
| 1810 | 1819 | ||
| 1811 | debugfs_remove(osb->osb_ctxt); | 1820 | debugfs_remove(osb->osb_ctxt); |
| 1812 | 1821 | ||
| 1822 | /* Orphan scan should be stopped as early as possible */ | ||
| 1823 | ocfs2_orphan_scan_stop(osb); | ||
| 1824 | |||
| 1813 | ocfs2_disable_quotas(osb); | 1825 | ocfs2_disable_quotas(osb); |
| 1814 | 1826 | ||
| 1815 | ocfs2_shutdown_local_alloc(osb); | 1827 | ocfs2_shutdown_local_alloc(osb); |
| 1816 | 1828 | ||
| 1817 | ocfs2_truncate_log_shutdown(osb); | 1829 | ocfs2_truncate_log_shutdown(osb); |
| 1818 | 1830 | ||
| 1819 | ocfs2_orphan_scan_stop(osb); | ||
| 1820 | |||
| 1821 | /* This will disable recovery and flush any recovery work. */ | 1831 | /* This will disable recovery and flush any recovery work. */ |
| 1822 | ocfs2_recovery_exit(osb); | 1832 | ocfs2_recovery_exit(osb); |
| 1823 | 1833 | ||
| @@ -1978,13 +1988,6 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1978 | goto bail; | 1988 | goto bail; |
| 1979 | } | 1989 | } |
| 1980 | 1990 | ||
| 1981 | status = ocfs2_orphan_scan_init(osb); | ||
| 1982 | if (status) { | ||
| 1983 | mlog(ML_ERROR, "Unable to initialize delayed orphan scan\n"); | ||
| 1984 | mlog_errno(status); | ||
| 1985 | goto bail; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | init_waitqueue_head(&osb->checkpoint_event); | 1991 | init_waitqueue_head(&osb->checkpoint_event); |
| 1989 | atomic_set(&osb->needs_checkpoint, 0); | 1992 | atomic_set(&osb->needs_checkpoint, 0); |
| 1990 | 1993 | ||
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c index ab713ebdd546..40e53702948c 100644 --- a/fs/ocfs2/sysfile.c +++ b/fs/ocfs2/sysfile.c | |||
| @@ -50,6 +50,10 @@ static inline int is_in_system_inode_array(struct ocfs2_super *osb, | |||
| 50 | int type, | 50 | int type, |
| 51 | u32 slot); | 51 | u32 slot); |
| 52 | 52 | ||
| 53 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 54 | static struct lock_class_key ocfs2_sysfile_cluster_lock_key[NUM_SYSTEM_INODES]; | ||
| 55 | #endif | ||
| 56 | |||
| 53 | static inline int is_global_system_inode(int type) | 57 | static inline int is_global_system_inode(int type) |
| 54 | { | 58 | { |
| 55 | return type >= OCFS2_FIRST_ONLINE_SYSTEM_INODE && | 59 | return type >= OCFS2_FIRST_ONLINE_SYSTEM_INODE && |
| @@ -118,6 +122,21 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb, | |||
| 118 | inode = NULL; | 122 | inode = NULL; |
| 119 | goto bail; | 123 | goto bail; |
| 120 | } | 124 | } |
| 125 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 126 | if (type == LOCAL_USER_QUOTA_SYSTEM_INODE || | ||
| 127 | type == LOCAL_GROUP_QUOTA_SYSTEM_INODE || | ||
| 128 | type == JOURNAL_SYSTEM_INODE) { | ||
| 129 | /* Ignore inode lock on these inodes as the lock does not | ||
| 130 | * really belong to any process and lockdep cannot handle | ||
| 131 | * that */ | ||
| 132 | OCFS2_I(inode)->ip_inode_lockres.l_lockdep_map.key = NULL; | ||
| 133 | } else { | ||
| 134 | lockdep_init_map(&OCFS2_I(inode)->ip_inode_lockres. | ||
| 135 | l_lockdep_map, | ||
| 136 | ocfs2_system_inodes[type].si_name, | ||
| 137 | &ocfs2_sysfile_cluster_lock_key[type], 0); | ||
| 138 | } | ||
| 139 | #endif | ||
| 121 | bail: | 140 | bail: |
| 122 | 141 | ||
| 123 | return inode; | 142 | return inode; |
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index da5a5a1f4cd2..b25d1b53df0d 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h | |||
| @@ -258,6 +258,16 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, | |||
| 258 | #define lockdep_set_subclass(lock, sub) \ | 258 | #define lockdep_set_subclass(lock, sub) \ |
| 259 | lockdep_init_map(&(lock)->dep_map, #lock, \ | 259 | lockdep_init_map(&(lock)->dep_map, #lock, \ |
| 260 | (lock)->dep_map.key, sub) | 260 | (lock)->dep_map.key, sub) |
| 261 | /* | ||
| 262 | * Compare locking classes | ||
| 263 | */ | ||
| 264 | #define lockdep_match_class(lock, key) lockdep_match_key(&(lock)->dep_map, key) | ||
| 265 | |||
| 266 | static inline int lockdep_match_key(struct lockdep_map *lock, | ||
| 267 | struct lock_class_key *key) | ||
| 268 | { | ||
| 269 | return lock->key == key; | ||
| 270 | } | ||
| 261 | 271 | ||
| 262 | /* | 272 | /* |
| 263 | * Acquire a lock. | 273 | * Acquire a lock. |
| @@ -326,6 +336,11 @@ static inline void lockdep_on(void) | |||
| 326 | #define lockdep_set_class_and_subclass(lock, key, sub) \ | 336 | #define lockdep_set_class_and_subclass(lock, key, sub) \ |
| 327 | do { (void)(key); } while (0) | 337 | do { (void)(key); } while (0) |
| 328 | #define lockdep_set_subclass(lock, sub) do { } while (0) | 338 | #define lockdep_set_subclass(lock, sub) do { } while (0) |
| 339 | /* | ||
| 340 | * We don't define lockdep_match_class() and lockdep_match_key() for !LOCKDEP | ||
| 341 | * case since the result is not well defined and the caller should rather | ||
| 342 | * #ifdef the call himself. | ||
| 343 | */ | ||
| 329 | 344 | ||
| 330 | # define INIT_LOCKDEP | 345 | # define INIT_LOCKDEP |
| 331 | # define lockdep_reset() do { debug_locks = 1; } while (0) | 346 | # define lockdep_reset() do { debug_locks = 1; } while (0) |
