diff options
author | Jeff Mahoney <jeffm@suse.com> | 2013-08-08 17:34:46 -0400 |
---|---|---|
committer | Jeff Mahoney <jeffm@suse.de> | 2013-08-08 17:34:46 -0400 |
commit | 278f6679f454bf185a07d9a4ca355b153482d17a (patch) | |
tree | ffead073e67cfdc1ddfc3949ebc93c06dcaaab8f /fs/reiserfs/reiserfs.h | |
parent | 4c05141df57f4ffc1a9a28f1925434924179bfe4 (diff) |
reiserfs: locking, handle nested locks properly
The reiserfs write lock replaced the BKL and uses similar semantics.
Frederic's locking code makes a distinction between when the lock is nested
and when it's being acquired/released, but I don't think that's the right
distinction to make.
The right distinction is between the lock being released at end-of-use and
the lock being released for a schedule. The unlock should return the depth
and the lock should restore it, rather than the other way around as it is now.
This patch implements that and adds a number of places where the lock
should be dropped.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/reiserfs/reiserfs.h')
-rw-r--r-- | fs/reiserfs/reiserfs.h | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 3df5ce6c724d..f8adaee537c2 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -630,8 +630,8 @@ static inline int __reiserfs_is_journal_aborted(struct reiserfs_journal | |||
630 | */ | 630 | */ |
631 | void reiserfs_write_lock(struct super_block *s); | 631 | void reiserfs_write_lock(struct super_block *s); |
632 | void reiserfs_write_unlock(struct super_block *s); | 632 | void reiserfs_write_unlock(struct super_block *s); |
633 | int reiserfs_write_lock_once(struct super_block *s); | 633 | int __must_check reiserfs_write_unlock_nested(struct super_block *s); |
634 | void reiserfs_write_unlock_once(struct super_block *s, int lock_depth); | 634 | void reiserfs_write_lock_nested(struct super_block *s, int depth); |
635 | 635 | ||
636 | #ifdef CONFIG_REISERFS_CHECK | 636 | #ifdef CONFIG_REISERFS_CHECK |
637 | void reiserfs_lock_check_recursive(struct super_block *s); | 637 | void reiserfs_lock_check_recursive(struct super_block *s); |
@@ -667,31 +667,33 @@ static inline void reiserfs_lock_check_recursive(struct super_block *s) { } | |||
667 | * - The inode mutex | 667 | * - The inode mutex |
668 | */ | 668 | */ |
669 | static inline void reiserfs_mutex_lock_safe(struct mutex *m, | 669 | static inline void reiserfs_mutex_lock_safe(struct mutex *m, |
670 | struct super_block *s) | 670 | struct super_block *s) |
671 | { | 671 | { |
672 | reiserfs_lock_check_recursive(s); | 672 | int depth; |
673 | reiserfs_write_unlock(s); | 673 | |
674 | depth = reiserfs_write_unlock_nested(s); | ||
674 | mutex_lock(m); | 675 | mutex_lock(m); |
675 | reiserfs_write_lock(s); | 676 | reiserfs_write_lock_nested(s, depth); |
676 | } | 677 | } |
677 | 678 | ||
678 | static inline void | 679 | static inline void |
679 | reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, | 680 | reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass, |
680 | struct super_block *s) | 681 | struct super_block *s) |
681 | { | 682 | { |
682 | reiserfs_lock_check_recursive(s); | 683 | int depth; |
683 | reiserfs_write_unlock(s); | 684 | |
685 | depth = reiserfs_write_unlock_nested(s); | ||
684 | mutex_lock_nested(m, subclass); | 686 | mutex_lock_nested(m, subclass); |
685 | reiserfs_write_lock(s); | 687 | reiserfs_write_lock_nested(s, depth); |
686 | } | 688 | } |
687 | 689 | ||
688 | static inline void | 690 | static inline void |
689 | reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) | 691 | reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) |
690 | { | 692 | { |
691 | reiserfs_lock_check_recursive(s); | 693 | int depth; |
692 | reiserfs_write_unlock(s); | 694 | depth = reiserfs_write_unlock_nested(s); |
693 | down_read(sem); | 695 | down_read(sem); |
694 | reiserfs_write_lock(s); | 696 | reiserfs_write_lock_nested(s, depth); |
695 | } | 697 | } |
696 | 698 | ||
697 | /* | 699 | /* |
@@ -701,9 +703,11 @@ reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s) | |||
701 | static inline void reiserfs_cond_resched(struct super_block *s) | 703 | static inline void reiserfs_cond_resched(struct super_block *s) |
702 | { | 704 | { |
703 | if (need_resched()) { | 705 | if (need_resched()) { |
704 | reiserfs_write_unlock(s); | 706 | int depth; |
707 | |||
708 | depth = reiserfs_write_unlock_nested(s); | ||
705 | schedule(); | 709 | schedule(); |
706 | reiserfs_write_lock(s); | 710 | reiserfs_write_lock_nested(s, depth); |
707 | } | 711 | } |
708 | } | 712 | } |
709 | 713 | ||