Any process attempting to write to a frozen filesystem uninterruptibly and unkillably waits for the filesystem to be thawed. This wait is of unbounded length. Ignore such waits in the hung_task detector. Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Jan Kara <jack@xxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Signed-off-by: Fernando Luis Vazquez Cao <fernando@xxxxxxxxxxxxx> --- diff -urNp linux-3.6.1-orig/fs/super.c linux-3.6.1/fs/super.c --- linux-3.6.1-orig/fs/super.c 2012-10-01 08:47:46.000000000 +0900 +++ linux-3.6.1/fs/super.c 2012-10-12 18:01:56.881255168 +0900 @@ -46,6 +46,13 @@ static char *sb_writers_name[SB_FREEZE_L "sb_internal", }; +static inline void wait_thaw(struct super_block *sb, int level) +{ + current->flags |= PF_FSFROZEN; + wait_event(sb->s_writers.wait_unfrozen, sb->s_writers.frozen < level); + current->flags &= ~ PF_FSFROZEN; +} + /* * One thing we have to be careful of with a per-sb shrinker is that we don't * drop the last active reference to the superblock from within the shrinker. @@ -663,8 +670,7 @@ struct super_block *get_super_thawed(str if (!s || s->s_writers.frozen == SB_UNFROZEN) return s; up_read(&s->s_umount); - wait_event(s->s_writers.wait_unfrozen, - s->s_writers.frozen == SB_UNFROZEN); + wait_thaw(s, SB_FREEZE_WRITE); put_super(s); } } @@ -1227,8 +1233,7 @@ retry: if (unlikely(sb->s_writers.frozen >= level)) { if (!wait) return 0; - wait_event(sb->s_writers.wait_unfrozen, - sb->s_writers.frozen < level); + wait_thaw(sb, level); } #ifdef CONFIG_LOCKDEP diff -urNp linux-3.6.1-orig/include/linux/sched.h linux-3.6.1/include/linux/sched.h --- linux-3.6.1-orig/include/linux/sched.h 2012-10-01 08:47:46.000000000 +0900 +++ linux-3.6.1/include/linux/sched.h 2012-10-12 17:46:48.909249791 +0900 @@ -1803,6 +1803,7 @@ extern void thread_group_times(struct ta #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ +#define PF_FSFROZEN 0x80000000 /* Waiting filesystem thaw */ /* * Only the _current_ task can read/write to tsk->flags, but other diff -urNp linux-3.6.1-orig/kernel/hung_task.c linux-3.6.1/kernel/hung_task.c --- linux-3.6.1-orig/kernel/hung_task.c 2012-10-01 08:47:46.000000000 +0900 +++ linux-3.6.1/kernel/hung_task.c 2012-10-12 18:04:02.465256245 +0900 @@ -73,10 +73,11 @@ static void check_hung_task(struct task_ unsigned long switch_count = t->nvcsw + t->nivcsw; /* - * Ensure the task is not frozen. - * Also, skip vfork and any other user process that freezer should skip. + * Ensure the task is not frozen or waiting for a filesystem to be + * thawed to proceed with a write. Also, skip vfork and any other user + * process that freezer should skip. */ - if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP))) + if (unlikely(t->flags & (PF_FROZEN | PF_FSFROZEN | PF_FREEZER_SKIP))) return; /* -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html