diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-05-19 05:01:18 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2009-05-19 05:01:18 -0400 |
commit | fe64d517df0970a68417184a12fcd4ba0589cc28 (patch) | |
tree | d977f214fdf6ba96254cfbf6683e8583ecebe504 /fs/gfs2/glock.c | |
parent | 9582d41135c0d362f04ed6bf3dc8d693a7eafee2 (diff) |
GFS2: Umount recovery race fix
This patch fixes a race condition where we can receive recovery
requests part way through processing a umount. This was causing
problems since the recovery thread had already gone away.
Looking in more detail at the recovery code, it was really trying
to implement a slight variation on a work queue, and that happens to
align nicely with the recently introduced slow-work subsystem. As a
result I've updated the code to use slow-work, rather than its own home
grown variety of work queue.
When using the wait_on_bit() function, I noticed that the wait function
that was supplied as an argument was appearing in the WCHAN field, so
I've updated the function names in order to produce more meaningful
output.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index ff4981090489..2bf62bcc5181 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -796,22 +796,37 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) | |||
796 | gh->gh_ip = 0; | 796 | gh->gh_ip = 0; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int just_schedule(void *word) | 799 | /** |
800 | * gfs2_glock_holder_wait | ||
801 | * @word: unused | ||
802 | * | ||
803 | * This function and gfs2_glock_demote_wait both show up in the WCHAN | ||
804 | * field. Thus I've separated these otherwise identical functions in | ||
805 | * order to be more informative to the user. | ||
806 | */ | ||
807 | |||
808 | static int gfs2_glock_holder_wait(void *word) | ||
800 | { | 809 | { |
801 | schedule(); | 810 | schedule(); |
802 | return 0; | 811 | return 0; |
803 | } | 812 | } |
804 | 813 | ||
814 | static int gfs2_glock_demote_wait(void *word) | ||
815 | { | ||
816 | schedule(); | ||
817 | return 0; | ||
818 | } | ||
819 | |||
805 | static void wait_on_holder(struct gfs2_holder *gh) | 820 | static void wait_on_holder(struct gfs2_holder *gh) |
806 | { | 821 | { |
807 | might_sleep(); | 822 | might_sleep(); |
808 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); | 823 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE); |
809 | } | 824 | } |
810 | 825 | ||
811 | static void wait_on_demote(struct gfs2_glock *gl) | 826 | static void wait_on_demote(struct gfs2_glock *gl) |
812 | { | 827 | { |
813 | might_sleep(); | 828 | might_sleep(); |
814 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); | 829 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, gfs2_glock_demote_wait, TASK_UNINTERRUPTIBLE); |
815 | } | 830 | } |
816 | 831 | ||
817 | /** | 832 | /** |