提交 634554dc 编写于 作者: J Josef Bacik

Btrfs: deal with errors in write_dev_supers

If you try to mount -o loop a restored file system it will panic if the file
ends up being smaller than the original disk.  This is because we go to try and
get a block for a super that may be past the EOF which makes __getblk return
NULL for a buffer head when we aren't expecting it to.  Fix this by dealing with
this case and just jacking up the errors count.  With this patch we no longer
panic when mounting a restored file system loopback.  Thanks,
Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
上级 3650860b
...@@ -2986,7 +2986,10 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -2986,7 +2986,10 @@ static int write_dev_supers(struct btrfs_device *device,
if (wait) { if (wait) {
bh = __find_get_block(device->bdev, bytenr / 4096, bh = __find_get_block(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE); BTRFS_SUPER_INFO_SIZE);
BUG_ON(!bh); if (!bh) {
errors++;
continue;
}
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) if (!buffer_uptodate(bh))
errors++; errors++;
...@@ -3013,6 +3016,13 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -3013,6 +3016,13 @@ static int write_dev_supers(struct btrfs_device *device,
*/ */
bh = __getblk(device->bdev, bytenr / 4096, bh = __getblk(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE); BTRFS_SUPER_INFO_SIZE);
if (!bh) {
printk(KERN_ERR "btrfs: couldn't get super "
"buffer head for bytenr %Lu\n", bytenr);
errors++;
continue;
}
memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE);
/* one reference for submit_bh */ /* one reference for submit_bh */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册