diff options
-rw-r--r-- | Documentation/sysrq.txt | 5 | ||||
-rw-r--r-- | drivers/char/sysrq.c | 19 | ||||
-rw-r--r-- | fs/buffer.c | 33 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
4 files changed, 57 insertions, 1 deletions
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index 9e592c718afb..afa2946892da 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt | |||
@@ -81,6 +81,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.: | |||
81 | 81 | ||
82 | 'i' - Send a SIGKILL to all processes, except for init. | 82 | 'i' - Send a SIGKILL to all processes, except for init. |
83 | 83 | ||
84 | 'j' - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl. | ||
85 | |||
84 | 'k' - Secure Access Key (SAK) Kills all programs on the current virtual | 86 | 'k' - Secure Access Key (SAK) Kills all programs on the current virtual |
85 | console. NOTE: See important comments below in SAK section. | 87 | console. NOTE: See important comments below in SAK section. |
86 | 88 | ||
@@ -160,6 +162,9 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you | |||
160 | are unable to kill any other way, especially if it's spawning other | 162 | are unable to kill any other way, especially if it's spawning other |
161 | processes. | 163 | processes. |
162 | 164 | ||
165 | "'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen | ||
166 | (probably root) filesystem via the FIFREEZE ioctl. | ||
167 | |||
163 | * Sometimes SysRq seems to get 'stuck' after using it, what can I do? | 168 | * Sometimes SysRq seems to get 'stuck' after using it, what can I do? |
164 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 169 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
165 | That happens to me, also. I've found that tapping shift, alt, and control | 170 | That happens to me, also. I've found that tapping shift, alt, and control |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 33a9351c896d..5afe7316c72e 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -346,6 +346,19 @@ static struct sysrq_key_op sysrq_moom_op = { | |||
346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
347 | }; | 347 | }; |
348 | 348 | ||
349 | #ifdef CONFIG_BLOCK | ||
350 | static void sysrq_handle_thaw(int key, struct tty_struct *tty) | ||
351 | { | ||
352 | emergency_thaw_all(); | ||
353 | } | ||
354 | static struct sysrq_key_op sysrq_thaw_op = { | ||
355 | .handler = sysrq_handle_thaw, | ||
356 | .help_msg = "thaw-filesystems(J)", | ||
357 | .action_msg = "Emergency Thaw of all frozen filesystems", | ||
358 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | ||
359 | }; | ||
360 | #endif | ||
361 | |||
349 | static void sysrq_handle_kill(int key, struct tty_struct *tty) | 362 | static void sysrq_handle_kill(int key, struct tty_struct *tty) |
350 | { | 363 | { |
351 | send_sig_all(SIGKILL); | 364 | send_sig_all(SIGKILL); |
@@ -396,9 +409,13 @@ static struct sysrq_key_op *sysrq_key_table[36] = { | |||
396 | &sysrq_moom_op, /* f */ | 409 | &sysrq_moom_op, /* f */ |
397 | /* g: May be registered by ppc for kgdb */ | 410 | /* g: May be registered by ppc for kgdb */ |
398 | NULL, /* g */ | 411 | NULL, /* g */ |
399 | NULL, /* h */ | 412 | NULL, /* h - reserved for help */ |
400 | &sysrq_kill_op, /* i */ | 413 | &sysrq_kill_op, /* i */ |
414 | #ifdef CONFIG_BLOCK | ||
415 | &sysrq_thaw_op, /* j */ | ||
416 | #else | ||
401 | NULL, /* j */ | 417 | NULL, /* j */ |
418 | #endif | ||
402 | &sysrq_SAK_op, /* k */ | 419 | &sysrq_SAK_op, /* k */ |
403 | #ifdef CONFIG_SMP | 420 | #ifdef CONFIG_SMP |
404 | &sysrq_showallcpus_op, /* l */ | 421 | &sysrq_showallcpus_op, /* l */ |
diff --git a/fs/buffer.c b/fs/buffer.c index c77b848c3d43..f5f8b15a6e40 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -547,6 +547,39 @@ repeat: | |||
547 | return err; | 547 | return err; |
548 | } | 548 | } |
549 | 549 | ||
550 | void do_thaw_all(unsigned long unused) | ||
551 | { | ||
552 | struct super_block *sb; | ||
553 | char b[BDEVNAME_SIZE]; | ||
554 | |||
555 | spin_lock(&sb_lock); | ||
556 | restart: | ||
557 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
558 | sb->s_count++; | ||
559 | spin_unlock(&sb_lock); | ||
560 | down_read(&sb->s_umount); | ||
561 | while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb)) | ||
562 | printk(KERN_WARNING "Emergency Thaw on %s\n", | ||
563 | bdevname(sb->s_bdev, b)); | ||
564 | up_read(&sb->s_umount); | ||
565 | spin_lock(&sb_lock); | ||
566 | if (__put_super_and_need_restart(sb)) | ||
567 | goto restart; | ||
568 | } | ||
569 | spin_unlock(&sb_lock); | ||
570 | printk(KERN_WARNING "Emergency Thaw complete\n"); | ||
571 | } | ||
572 | |||
573 | /** | ||
574 | * emergency_thaw_all -- forcibly thaw every frozen filesystem | ||
575 | * | ||
576 | * Used for emergency unfreeze of all filesystems via SysRq | ||
577 | */ | ||
578 | void emergency_thaw_all(void) | ||
579 | { | ||
580 | pdflush_operation(do_thaw_all, 0); | ||
581 | } | ||
582 | |||
550 | /** | 583 | /** |
551 | * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers | 584 | * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers |
552 | * @mapping: the mapping which wants those buffers written | 585 | * @mapping: the mapping which wants those buffers written |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 87e7bfc5ebd7..61211ad823fe 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1878,6 +1878,7 @@ extern struct block_device *open_by_devnum(dev_t, fmode_t); | |||
1878 | extern void invalidate_bdev(struct block_device *); | 1878 | extern void invalidate_bdev(struct block_device *); |
1879 | extern int sync_blockdev(struct block_device *bdev); | 1879 | extern int sync_blockdev(struct block_device *bdev); |
1880 | extern struct super_block *freeze_bdev(struct block_device *); | 1880 | extern struct super_block *freeze_bdev(struct block_device *); |
1881 | extern void emergency_thaw_all(void); | ||
1881 | extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); | 1882 | extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); |
1882 | extern int fsync_bdev(struct block_device *); | 1883 | extern int fsync_bdev(struct block_device *); |
1883 | extern int fsync_super(struct super_block *); | 1884 | extern int fsync_super(struct super_block *); |