aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-12-29 21:20:19 -0500
committerFrederic Weisbecker <fweisbec@gmail.com>2010-01-01 19:54:37 -0500
commitc4a62ca362258d98f42efb282cfbf9b61caffdbe (patch)
tree017484107efa26789ddd96579fcef09d874333c0
parent0719d3434747889b314a1e8add776418c4148bcf (diff)
reiserfs: Warn on lock relax if taken recursively
When we relax the reiserfs lock to avoid creating unwanted dependencies against others locks while grabbing these, we want to ensure it has not been taken recursively, otherwise the lock won't be really relaxed. Only its depth will be decreased. The unwanted dependency would then actually happen. To prevent from that, add a reiserfs_lock_check_recursive() call in the places that need it. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Alexander Beregalov <a.beregalov@gmail.com> Cc: Chris Mason <chris.mason@oracle.com> Cc: Ingo Molnar <mingo@elte.hu>
-rw-r--r--fs/reiserfs/lock.c9
-rw-r--r--include/linux/reiserfs_fs.h9
2 files changed, 18 insertions, 0 deletions
diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c
index ee2cfc0fd8a7..b87aa2c1afc1 100644
--- a/fs/reiserfs/lock.c
+++ b/fs/reiserfs/lock.c
@@ -86,3 +86,12 @@ void reiserfs_check_lock_depth(struct super_block *sb, char *caller)
86 reiserfs_panic(sb, "%s called without kernel lock held %d", 86 reiserfs_panic(sb, "%s called without kernel lock held %d",
87 caller); 87 caller);
88} 88}
89
90#ifdef CONFIG_REISERFS_CHECK
91void reiserfs_lock_check_recursive(struct super_block *sb)
92{
93 struct reiserfs_sb_info *sb_i = REISERFS_SB(sb);
94
95 WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock!\n");
96}
97#endif
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 35d3f459b0ac..793bf8351ab8 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -62,6 +62,12 @@ void reiserfs_write_unlock(struct super_block *s);
62int reiserfs_write_lock_once(struct super_block *s); 62int reiserfs_write_lock_once(struct super_block *s);
63void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); 63void reiserfs_write_unlock_once(struct super_block *s, int lock_depth);
64 64
65#ifdef CONFIG_REISERFS_CHECK
66void reiserfs_lock_check_recursive(struct super_block *s);
67#else
68static inline void reiserfs_lock_check_recursive(struct super_block *s) { }
69#endif
70
65/* 71/*
66 * Several mutexes depend on the write lock. 72 * Several mutexes depend on the write lock.
67 * However sometimes we want to relax the write lock while we hold 73 * However sometimes we want to relax the write lock while we hold
@@ -92,6 +98,7 @@ void reiserfs_write_unlock_once(struct super_block *s, int lock_depth);
92static inline void reiserfs_mutex_lock_safe(struct mutex *m, 98static inline void reiserfs_mutex_lock_safe(struct mutex *m,
93 struct super_block *s) 99 struct super_block *s)
94{ 100{
101 reiserfs_lock_check_recursive(s);
95 reiserfs_write_unlock(s); 102 reiserfs_write_unlock(s);
96 mutex_lock(m); 103 mutex_lock(m);
97 reiserfs_write_lock(s); 104 reiserfs_write_lock(s);
@@ -101,6 +108,7 @@ static inline void
101reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, 108reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass,
102 struct super_block *s) 109 struct super_block *s)
103{ 110{
111 reiserfs_lock_check_recursive(s);
104 reiserfs_write_unlock(s); 112 reiserfs_write_unlock(s);
105 mutex_lock_nested(m, subclass); 113 mutex_lock_nested(m, subclass);
106 reiserfs_write_lock(s); 114 reiserfs_write_lock(s);
@@ -109,6 +117,7 @@ reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass,
109static inline void 117static inline void
110reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) 118reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s)
111{ 119{
120 reiserfs_lock_check_recursive(s);
112 reiserfs_write_unlock(s); 121 reiserfs_write_unlock(s);
113 down_read(sem); 122 down_read(sem);
114 reiserfs_write_lock(s); 123 reiserfs_write_lock(s);