aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-29 10:05:57 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:55:22 -0400
commit634554dc0acfc8753c05e432b2fdb34b0be89c78 (patch)
tree824cb5efa227ea42c325b2138e5b5c9dd0918b97 /fs
parent3650860b90cc2a06cb9d7e37df005736c46ce87e (diff)
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>
Diffstat (limited to 'fs')
-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,
2986 if (wait) { 2986 if (wait) {
2987 bh = __find_get_block(device->bdev, bytenr / 4096, 2987 bh = __find_get_block(device->bdev, bytenr / 4096,
2988 BTRFS_SUPER_INFO_SIZE); 2988 BTRFS_SUPER_INFO_SIZE);
2989 BUG_ON(!bh); 2989 if (!bh) {
2990 errors++;
2991 continue;
2992 }
2990 wait_on_buffer(bh); 2993 wait_on_buffer(bh);
2991 if (!buffer_uptodate(bh)) 2994 if (!buffer_uptodate(bh))
2992 errors++; 2995 errors++;
@@ -3013,6 +3016,13 @@ static int write_dev_supers(struct btrfs_device *device,
3013 */ 3016 */
3014 bh = __getblk(device->bdev, bytenr / 4096, 3017 bh = __getblk(device->bdev, bytenr / 4096,
3015 BTRFS_SUPER_INFO_SIZE); 3018 BTRFS_SUPER_INFO_SIZE);
3019 if (!bh) {
3020 printk(KERN_ERR "btrfs: couldn't get super "
3021 "buffer head for bytenr %Lu\n", bytenr);
3022 errors++;
3023 continue;
3024 }
3025
3016 memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); 3026 memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE);
3017 3027
3018 /* one reference for submit_bh */ 3028 /* one reference for submit_bh */