mount -o loop with truncated dosdisk.img uses 100% cpu and can't be killed
Hello,
I was trying to create a bootdisk to update my BIOS, and accidentially made a 512byte image with only the FreeDOS header in it.
( Linux 3.4.4 )
# mount -o loop dosdisk.img /tmp ^C^C^C It uses 100% CPU and doesn't listen to me when I do ^C, kill -9 etc. I think this means it's stuck in the kernel?
Here is the base64 encoded image (use base64 -d command to unpack it). 6zyQRnJlZURPUyAAAgEBAALgAEAL8AkAEgACAAAAAAAAAAAAAAApOATF6E5PIE5BTUUgICAgRkFU MTIgICD6/DHAjti9AHy44B+OwInuie+5AAHzpepefOAfAABgAI7YjtCNZqD7gH4k/3UDiFYkx0bA EADHRsIBAOjpAEZyZWVET1MAi3Yci34eA3YOg9cAiXbSiX7UikYQmPdmFgHGEdeJdtaJftiLXgux BdPri0YRMdL384lG0AHGg9cAiXbaiX7ci0bWi1bYi37QxF5a6JsAci/Eflq5CwC+8X1X86ZfJotF GnQLg8cgJoA9AHXncllQxF5ai34Wi0bSi1bU6GsAWHJGHgeOXly/ACCricYB9gHG0e6tcwSxBNPo gOQPPfgPcugxwKsOH8ReWr4AIK0JwHQkSEiLfg2B5/8A9+cDRtoTVtzoJABz5egXACBlcnIAMOTN Fs0Zil4k/25aMdu0Ds0QXqxWPAB188NWiUbIiVbKjEbGiV7EtEG7qlWKViSE0nQZzRNyFdHpgdtU qnUNjXbAiV7MiV7OtELrLItOyItWyopGGPZmGpH38ZL2dhiJ0YjGhunQydDJikYYKOD+xAjhxF7E uAECilYkzRNzBjDkzRProotGC/Z2wAFGxoNGyAGDVsoAT3XqjkbGXsNLRVJORUwgIFNZUwAAVao=
--
Stevie Trujillo
Quoted 10 lines · Stevie Trujillo
Hello,
I was trying to create a bootdisk to update my BIOS, and accidentially made a 512byte image with only the FreeDOS header in it.
( Linux 3.4.4 )
# mount -o loop dosdisk.img /tmp ^C^C^C It uses 100% CPU and doesn't listen to me when I do ^C, kill -9 etc. I think this means it's stuck in the kernel?
Here is the stack trace I get for the mount process:
[root@telezart smagnani]# cat /proc/1334/stack
[<ffffffff81077a5a>] __cond_resched+0x2a/0x40 [<ffffffff8110c4bb>] find_lock_page+0x3b/0x80 [<ffffffff8110cbaf>] find_or_create_page+0x3f/0xb0 [<ffffffff8119a692>] __getblk+0xf2/0x2a0 [<ffffffff8119a893>] __bread+0x13/0xb0 [<ffffffffa00fd1fe>] fat__get_entry+0x14e/0x220 [fat] [<ffffffffa00fd596>] fat_get_short_entry+0x66/0xc0 [fat] [<ffffffffa00ff765>] fat_subdirs+0x55/0x80 [fat] [<ffffffffa0103d30>] fat_fill_super+0x810/0xa80 [fat] [<ffffffffa00e821a>] vfat_fill_super+0x1a/0x20 [vfat] [<ffffffff8116d61b>] mount_bdev+0x1cb/0x210 [<ffffffffa00e81f5>] vfat_mount+0x15/0x20 [vfat] [<ffffffff8116e410>] mount_fs+0x20/0xd0 [<ffffffff81186e4f>] vfs_kern_mount+0x6f/0x100 [<ffffffff81187804>] do_kern_mount+0x54/0x110 [<ffffffff811891d6>] do_mount+0x306/0x8b0 [<ffffffff811898cd>] sys_mount+0x8d/0xe0 [<ffffffff81583629>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff
I would think this is more likely a bug in the loopback driver than the FAT filesystem...
------------------------------------------------------------------------
Steven J. Magnani "I claim this network for MARS!
www.digidescorp.com Earthling, return my space modulator!"
#include <standard.disclaimer>
Quoted 33 lines · Steven J. Magnani
Quoted 10 lines · Stevie Trujillo
Hello,
I was trying to create a bootdisk to update my BIOS, and accidentially made a 512byte image with only the FreeDOS header in it.
( Linux 3.4.4 )
# mount -o loop dosdisk.img /tmp ^C^C^C It uses 100% CPU and doesn't listen to me when I do ^C, kill -9 etc. I think this means it's stuck in the kernel?Here is the stack trace I get for the mount process:
[root@telezart smagnani]# cat
/proc/1334/stack[<ffffffff81077a5a>] __cond_resched+0x2a/0x40 [<ffffffff8110c4bb>] find_lock_page+0x3b/0x80 [<ffffffff8110cbaf>] find_or_create_page+0x3f/0xb0 [<ffffffff8119a692>] __getblk+0xf2/0x2a0 [<ffffffff8119a893>] __bread+0x13/0xb0 [<ffffffffa00fd1fe>] fat__get_entry+0x14e/0x220 [fat] [<ffffffffa00fd596>] fat_get_short_entry+0x66/0xc0 [fat] [<ffffffffa00ff765>] fat_subdirs+0x55/0x80 [fat] [<ffffffffa0103d30>] fat_fill_super+0x810/0xa80 [fat] [<ffffffffa00e821a>] vfat_fill_super+0x1a/0x20 [vfat] [<ffffffff8116d61b>] mount_bdev+0x1cb/0x210 [<ffffffffa00e81f5>] vfat_mount+0x15/0x20 [vfat] [<ffffffff8116e410>] mount_fs+0x20/0xd0 [<ffffffff81186e4f>] vfs_kern_mount+0x6f/0x100 [<ffffffff81187804>] do_kern_mount+0x54/0x110 [<ffffffff811891d6>] do_mount+0x306/0x8b0 [<ffffffff811898cd>] sys_mount+0x8d/0xe0 [<ffffffff81583629>] system_call_fastpath+0x16/0x1b
Quoted 4 lines
[<ffffffffffffffff>]
0xffffffffffffffffI would think this is more likely a bug in the loopback driver than the FAT filesystem...
It looks like the bug of __getblk_slow(). If requested block was beyond end of device, __find_get_block() will find buffer_mapped()'s buffer, but block >= end_block is unmapped. So, it can be loop.
The following patch fixes it? If it fix, there are some options to check it.
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it in init_page_buffers() and return -EIO or such
Well, anyway, Cc to Jens.
---
fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/buffer.c renamed from fs/buffer.c~debug +7 -0
@@ -1055,6 +1055,13 @@ __getblk_slow(struct block_device *bdev,dump_stack ();return NULL ; } +if (block >=blkdev_max_block (I_BDEV (bdev->bd_inode))) { +printk (KERN_ERR "getblk(): block %llu, end_block %llu\n" , + (unsigned long long )block, + (unsigned long long )blkdev_max_block (I_BDEV (bdev->bd_inode))); +dump_stack (); +return NULL ; + }for (;;) {struct buffer_head * bh;
_
Signature · 1 line
OGAWA Hirofumi <[email protected]>
Quoted 47 lines · OGAWA Hirofumi
Quoted 11 lines · Stevie Trujillo
Quoted 10 lines
Hello,
I was trying to create a bootdisk to update my BIOS, and accidentially made a 512byte image with only the FreeDOS header in it.
( Linux 3.4.4 )
# mount -o loop dosdisk.img /tmp ^C^C^C It uses 100% CPU and doesn't listen to me when I do ^C, kill -9 etc. I think this means it's stuck in the kernel?It looks like the bug of
__getblk_slow(). If requested block was beyond end of device,__find_get_block()will find buffer_mapped()'s buffer, but block >=end_blockis unmapped. So, it can be loop.The following patch fixes it? If it fix, there are some options to check it.
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it ininit_page_buffers()and return-EIOor suchWell, anyway, Cc to Jens.
Signed-off-by OGAWA Hirofumi <[email protected]>---
fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+)diff -puN
fs/buffer.c~debugfs/buffer.cfs/buffer.c renamed from fs/buffer.c~debug +7
-0@@ -1055,6 +1055,13 @@ __getblk_slow(struct block_device *bdev,dump_stack ();return NULL ; } +if (block >=blkdev_max_block (I_BDEV (bdev->bd_inode))) { +printk (KERN_ERR "getblk(): block %llu, end_block %llu\n" , + (unsigned long long )block, + (unsigned long long )blkdev_max_block (I_BDEV (bdev->bd_inode))); +dump_stack (); +return NULL ; + }for (;;) {struct buffer_head * bh;
Quoted 1 line
_
This fixes the hang, but I'm not sure dump_stack() is a good idea. I get almost 100 lines of stack dumps and error messages in my kernel log. Also, I was a little surprised to see that mount completes successfully.
------------------------------------------------------------------------
Steven J. Magnani "I claim this network for MARS!
www.digidescorp.com Earthling, return my space modulator!"
#include <standard.disclaimer>
Quoted 30 lines · Steven J. Magnani
Quoted 30 lines
The following patch fixes it? If it fix, there are some options to check it.
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it ininit_page_buffers()and return-EIOor suchWell, anyway, Cc to Jens.
Signed-off-by OGAWA Hirofumi <[email protected]>---
fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+)diff -puN
fs/buffer.c~debugfs/buffer.cfs/buffer.c renamed from fs/buffer.c~debug +7
-0@@ -1055,6 +1055,13 @@ __getblk_slow(struct block_device *bdev,dump_stack ();return NULL ; } +if (block >=blkdev_max_block (I_BDEV (bdev->bd_inode))) { +printk (KERN_ERR "getblk(): block %llu, end_block %llu\n" , + (unsigned long long )block, + (unsigned long long )blkdev_max_block (I_BDEV (bdev->bd_inode))); +dump_stack (); +return NULL ; + }
Quoted 7 lines
Quoted 3 lines
fs/buffer.c renamed from fs/buffer.c~debug +0
-0for (;;) {struct buffer_head * bh;_
This fixes the hang, but I'm not sure
dump_stack()is a good idea. I get almost 100 lines of stack dumps and error messages in my kernel log. Also, I was a little surprised to see that mount completes successfully.
So, it sounds like the good choice would be (b) or (c). Well, I guess Jens would choose what to do.
Signature · 1 line
OGAWA Hirofumi <[email protected]>
Jan Kara
reviewerQuoted 47 lines · OGAWA Hirofumi
Quoted 33 lines · Steven J. Magnani
Quoted 10 lines · Stevie Trujillo
Hello,
I was trying to create a bootdisk to update my BIOS, and accidentially made a 512byte image with only the FreeDOS header in it.
( Linux 3.4.4 )
# mount -o loop dosdisk.img /tmp ^C^C^C It uses 100% CPU and doesn't listen to me when I do ^C, kill -9 etc. I think this means it's stuck in the kernel?Here is the stack trace I get for the mount process:
[root@telezart smagnani]# cat
/proc/1334/stack[<ffffffff81077a5a>] __cond_resched+0x2a/0x40 [<ffffffff8110c4bb>] find_lock_page+0x3b/0x80 [<ffffffff8110cbaf>] find_or_create_page+0x3f/0xb0 [<ffffffff8119a692>] __getblk+0xf2/0x2a0 [<ffffffff8119a893>] __bread+0x13/0xb0 [<ffffffffa00fd1fe>] fat__get_entry+0x14e/0x220 [fat] [<ffffffffa00fd596>] fat_get_short_entry+0x66/0xc0 [fat] [<ffffffffa00ff765>] fat_subdirs+0x55/0x80 [fat] [<ffffffffa0103d30>] fat_fill_super+0x810/0xa80 [fat] [<ffffffffa00e821a>] vfat_fill_super+0x1a/0x20 [vfat] [<ffffffff8116d61b>] mount_bdev+0x1cb/0x210 [<ffffffffa00e81f5>] vfat_mount+0x15/0x20 [vfat] [<ffffffff8116e410>] mount_fs+0x20/0xd0 [<ffffffff81186e4f>] vfs_kern_mount+0x6f/0x100 [<ffffffff81187804>] do_kern_mount+0x54/0x110 [<ffffffff811891d6>] do_mount+0x306/0x8b0 [<ffffffff811898cd>] sys_mount+0x8d/0xe0 [<ffffffff81583629>] system_call_fastpath+0x16/0x1bQuoted 4 lines
[<ffffffffffffffff>]
0xffffffffffffffffI would think this is more likely a bug in the loopback driver than the FAT filesystem...
It looks like the bug of
__getblk_slow(). If requested block was beyond end of device,__find_get_block()will find buffer_mapped()'s buffer, but block >=end_blockis unmapped. So, it can be loop.The following patch fixes it? If it fix, there are some options to check it.
Quoted 7 lines
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it ininit_page_buffers()and return-EIOor suchWell, anyway, Cc to Jens.
Signed-off-by OGAWA Hirofumi <[email protected]>
I think Jeff Moyer has sent a similar fix recently. It may even be
already queued in Jens' tree. Jeff?
Honza
Quoted 31 lines
---
fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+)diff -puN
fs/buffer.c~debugfs/buffer.cfs/buffer.c renamed from fs/buffer.c~debug +7
-0@@ -1055,6 +1055,13 @@ __getblk_slow(struct block_device *bdev,dump_stack ();return NULL ; } +if (block >=blkdev_max_block (I_BDEV (bdev->bd_inode))) { +printk (KERN_ERR "getblk(): block %llu, end_block %llu\n" , + (unsigned long long )block, + (unsigned long long )blkdev_max_block (I_BDEV (bdev->bd_inode))); +dump_stack (); +return NULL ; + }for (;;) {struct buffer_head * bh;_
Signature · 6 lines
OGAWA Hirofumi <[email protected]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Quoted 11 lines · Jan Kara
Quoted 11 lines
It looks like the bug of
__getblk_slow(). If requested block was beyond end of device,__find_get_block()will find buffer_mapped()'s buffer, but block >=end_blockis unmapped. So, it can be loop.The following patch fixes it? If it fix, there are some options to check it.
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it ininit_page_buffers()and return-EIOor such
Quoted 5 lines
Quoted 3 lines
Well, anyway, Cc to Jens.
Signed-off-by OGAWA Hirofumi <[email protected]>I think Jeff Moyer has sent a similar fix recently. It may even be
already queued in Jens' tree. Jeff?
I haven't heard a peep from Jens (I believe he's been on vacation), so I forwarded the patch along to Linus (but haven't heard anything from him, either).
See my email with Subject: [patch] block: fix infinite loop in __getblk_slow
https://lkml.org/lkml/2012/6/26/252
Cheers,
Jeff
Quoted 11 lines · Jan Kara
Quoted 11 lines
It looks like the bug of
__getblk_slow(). If requested block was beyond end of device,__find_get_block()will find buffer_mapped()'s buffer, but block >=end_blockis unmapped. So, it can be loop.The following patch fixes it? If it fix, there are some options to check it.
a) Check it like this patch and warn.
b) (a), but without warn.
c) Check it ininit_page_buffers()and return-EIOor such
Quoted 5 lines
Quoted 3 lines
Well, anyway, Cc to Jens.
Signed-off-by OGAWA Hirofumi <[email protected]>I think Jeff Moyer has sent a similar fix recently. It may even be
already queued in Jens' tree. Jeff?
A fix for this has now been committed in Linus' tree:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=91f68c89d8f35fe98ea04159b9a3b42d0149478f
Cheers,
Jeff