summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-29 16:05:57 +0200
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 21:55:22 +0200
commit634554dc0acfc8753c05e432b2fdb34b0be89c78 (patch)
tree824cb5efa227ea42c325b2138e5b5c9dd0918b97
parentBtrfs: remove almost all of the BUG()'s from tree-log.c (diff)
downloadlinux-634554dc0acfc8753c05e432b2fdb34b0be89c78.tar.xz
linux-634554dc0acfc8753c05e432b2fdb34b0be89c78.zip
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: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/disk-io.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d96305e5cc93..f651a37c7e0a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2986,7 +2986,10 @@ static int write_dev_supers(struct btrfs_device *device,
if (wait) {
bh = __find_get_block(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE);
- BUG_ON(!bh);
+ if (!bh) {
+ errors++;
+ continue;
+ }
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
errors++;
@@ -3013,6 +3016,13 @@ static int write_dev_supers(struct btrfs_device *device,
*/
bh = __getblk(device->bdev, bytenr / 4096,
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);
/* one reference for submit_bh */