diff mbox

Btrfs: remove BUG_ON()'s in btrfs_map_block

Message ID 1460480080-27063-1-git-send-email-jbacik@fb.com (mailing list archive)
State Accepted
Headers show

Commit Message

Josef Bacik April 12, 2016, 4:54 p.m. UTC
btrfs_map_block can go horribly wrong in the face of fs corruption, lets agree
to not be assholes and panic at any possible chance things are all fucked up.

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 fs/btrfs/volumes.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

Comments

Anand Jain April 14, 2016, 2:16 a.m. UTC | #1
On 04/13/2016 12:54 AM, Josef Bacik wrote:
> btrfs_map_block can go horribly wrong in the face of fs corruption, lets agree
> to not be assholes and panic at any possible chance things are all fucked up.
>
> Signed-off-by: Josef Bacik <jbacik@fb.com>
> ---
>   fs/btrfs/volumes.c | 22 ++++++++++++++++++++--
>   1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index e2b54d5..ba8216b 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -5278,7 +5278,18 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
>   	stripe_nr = div64_u64(stripe_nr, stripe_len);
>
>   	stripe_offset = stripe_nr * stripe_len;
> -	BUG_ON(offset < stripe_offset);
> +	if (offset < stripe_offset) {
> +		btrfs_crit(fs_info, "stripe math has gone wrong, "
> +			   "stripe_offset=%llu, offset=%llu, start=%llu, "


> +			   "logical=%llu, stripe_len=%llu\n",

  btrfs_crit adds \n suffix by its own.

> +			   (unsigned long long)stripe_offset,
> +			   (unsigned long long)offset,
> +			   (unsigned long long)em->start,
> +			   (unsigned long long)logical,
> +			   (unsigned long long)stripe_len);
> +		free_extent_map(em);
> +		return -EINVAL;
> +	}
>
>   	/* stripe_offset is the offset of this block in its stripe*/
>   	stripe_offset = offset - stripe_offset;
> @@ -5519,7 +5530,14 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
>   				&stripe_index);
>   		mirror_num = stripe_index + 1;
>   	}
> -	BUG_ON(stripe_index >= map->num_stripes);
> +	if (stripe_index >= map->num_stripes) {
> +		btrfs_crit(fs_info, "stripe index math went horribly wrong, "

> +			   "got stripe_index=%lu, num_stripes=%lu\n",

  -same-

Thanks, Anand

> +			   (unsigned long)stripe_index,
> +			   (unsigned long)map->num_stripes);
> +		ret = -EINVAL;
> +		goto out;
> +	}
>
>   	num_alloc_stripes = num_stripes;
>   	if (dev_replace_is_ongoing) {
>
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Sterba April 27, 2016, 11:05 p.m. UTC | #2
On Thu, Apr 14, 2016 at 10:16:36AM +0800, Anand Jain wrote:
> > -	BUG_ON(offset < stripe_offset);
> > +	if (offset < stripe_offset) {
> > +		btrfs_crit(fs_info, "stripe math has gone wrong, "
> > +			   "stripe_offset=%llu, offset=%llu, start=%llu, "
> 
> 
> > +			   "logical=%llu, stripe_len=%llu\n",
> 
>   btrfs_crit adds \n suffix by its own.

Right,

> 
> > +			   (unsigned long long)stripe_offset,
> > +			   (unsigned long long)offset,
> > +			   (unsigned long long)em->start,
> > +			   (unsigned long long)logical,
> > +			   (unsigned long long)stripe_len);

and we don't have to cast u64 to ULL anymore.

> > +		free_extent_map(em);
> > +		return -EINVAL;
> > +	}
> >
> >   	/* stripe_offset is the offset of this block in its stripe*/
> >   	stripe_offset = offset - stripe_offset;
> > @@ -5519,7 +5530,14 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
> >   				&stripe_index);
> >   		mirror_num = stripe_index + 1;
> >   	}
> > -	BUG_ON(stripe_index >= map->num_stripes);
> > +	if (stripe_index >= map->num_stripes) {
> > +		btrfs_crit(fs_info, "stripe index math went horribly wrong, "
> 
> > +			   "got stripe_index=%lu, num_stripes=%lu\n",
> 
>   -same-
> 
> Thanks, Anand
> 
> > +			   (unsigned long)stripe_index,
> > +			   (unsigned long)map->num_stripes);

typecasts dropped and format string updated.

Fixed and added to for-next.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e2b54d5..ba8216b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5278,7 +5278,18 @@  static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
 	stripe_nr = div64_u64(stripe_nr, stripe_len);
 
 	stripe_offset = stripe_nr * stripe_len;
-	BUG_ON(offset < stripe_offset);
+	if (offset < stripe_offset) {
+		btrfs_crit(fs_info, "stripe math has gone wrong, "
+			   "stripe_offset=%llu, offset=%llu, start=%llu, "
+			   "logical=%llu, stripe_len=%llu\n",
+			   (unsigned long long)stripe_offset,
+			   (unsigned long long)offset,
+			   (unsigned long long)em->start,
+			   (unsigned long long)logical,
+			   (unsigned long long)stripe_len);
+		free_extent_map(em);
+		return -EINVAL;
+	}
 
 	/* stripe_offset is the offset of this block in its stripe*/
 	stripe_offset = offset - stripe_offset;
@@ -5519,7 +5530,14 @@  static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
 				&stripe_index);
 		mirror_num = stripe_index + 1;
 	}
-	BUG_ON(stripe_index >= map->num_stripes);
+	if (stripe_index >= map->num_stripes) {
+		btrfs_crit(fs_info, "stripe index math went horribly wrong, "
+			   "got stripe_index=%lu, num_stripes=%lu\n",
+			   (unsigned long)stripe_index,
+			   (unsigned long)map->num_stripes);
+		ret = -EINVAL;
+		goto out;
+	}
 
 	num_alloc_stripes = num_stripes;
 	if (dev_replace_is_ongoing) {