diff options
Diffstat (limited to 'fs/ocfs2')
-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 |
15 files changed, 283 insertions, 105 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); |
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; |