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>

+18
+9
fs/reiserfs/lock.c
··· 86 reiserfs_panic(sb, "%s called without kernel lock held %d", 87 caller); 88 }
··· 86 reiserfs_panic(sb, "%s called without kernel lock held %d", 87 caller); 88 } 89 + 90 + #ifdef CONFIG_REISERFS_CHECK 91 + void 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
+9
include/linux/reiserfs_fs.h
··· 62 int reiserfs_write_lock_once(struct super_block *s); 63 void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); 64 65 /* 66 * Several mutexes depend on the write lock. 67 * However sometimes we want to relax the write lock while we hold ··· 98 static inline void reiserfs_mutex_lock_safe(struct mutex *m, 99 struct super_block *s) 100 { 101 reiserfs_write_unlock(s); 102 mutex_lock(m); 103 reiserfs_write_lock(s); ··· 108 reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, 109 struct super_block *s) 110 { 111 reiserfs_write_unlock(s); 112 mutex_lock_nested(m, subclass); 113 reiserfs_write_lock(s); ··· 117 static inline void 118 reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) 119 { 120 reiserfs_write_unlock(s); 121 down_read(sem); 122 reiserfs_write_lock(s);
··· 62 int reiserfs_write_lock_once(struct super_block *s); 63 void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); 64 65 + #ifdef CONFIG_REISERFS_CHECK 66 + void reiserfs_lock_check_recursive(struct super_block *s); 67 + #else 68 + static inline void reiserfs_lock_check_recursive(struct super_block *s) { } 69 + #endif 70 + 71 /* 72 * Several mutexes depend on the write lock. 73 * However sometimes we want to relax the write lock while we hold ··· 92 static inline void reiserfs_mutex_lock_safe(struct mutex *m, 93 struct super_block *s) 94 { 95 + reiserfs_lock_check_recursive(s); 96 reiserfs_write_unlock(s); 97 mutex_lock(m); 98 reiserfs_write_lock(s); ··· 101 reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, 102 struct super_block *s) 103 { 104 + reiserfs_lock_check_recursive(s); 105 reiserfs_write_unlock(s); 106 mutex_lock_nested(m, subclass); 107 reiserfs_write_lock(s); ··· 109 static inline void 110 reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) 111 { 112 + reiserfs_lock_check_recursive(s); 113 reiserfs_write_unlock(s); 114 down_read(sem); 115 reiserfs_write_lock(s);