aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2017-06-23 12:48:21 -0400
committerDavid Sterba <dsterba@suse.com>2017-06-29 14:17:02 -0400
commit6374e57ad8091b9c2db2eecc536c7f0166ce099e (patch)
treef4a5c584983c110e0b2ddc9e3b51c25e11801353 /fs/btrfs/ordered-data.c
parentded56184a562b925a588b6e78688e2e60757b425 (diff)
btrfs: fix integer overflow in calc_reclaim_items_nr
Dave Jones hit a WARN_ON(nr < 0) in btrfs_wait_ordered_roots() with v4.12-rc6. This was because commit 70e7af244 made it possible for calc_reclaim_items_nr() to return a negative number. It's not really a bug in that commit, it just didn't go far enough down the stack to find all the possible 64->32 bit overflows. This switches calc_reclaim_items_nr() to return a u64 and changes everyone that uses the results of that math to u64 as well. Reported-by: Dave Jones <davej@codemonkey.org.uk> Fixes: 70e7af2 ("Btrfs: fix delalloc accounting leak caused by u32 overflow") Signed-off-by: Chris Mason <clm@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 7b40e2e7292a..a3aca495e33e 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -663,7 +663,7 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
663 * wait for all the ordered extents in a root. This is done when balancing 663 * wait for all the ordered extents in a root. This is done when balancing
664 * space between drives. 664 * space between drives.
665 */ 665 */
666int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr, 666u64 btrfs_wait_ordered_extents(struct btrfs_root *root, u64 nr,
667 const u64 range_start, const u64 range_len) 667 const u64 range_start, const u64 range_len)
668{ 668{
669 struct btrfs_fs_info *fs_info = root->fs_info; 669 struct btrfs_fs_info *fs_info = root->fs_info;
@@ -671,7 +671,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr,
671 LIST_HEAD(skipped); 671 LIST_HEAD(skipped);
672 LIST_HEAD(works); 672 LIST_HEAD(works);
673 struct btrfs_ordered_extent *ordered, *next; 673 struct btrfs_ordered_extent *ordered, *next;
674 int count = 0; 674 u64 count = 0;
675 const u64 range_end = range_start + range_len; 675 const u64 range_end = range_start + range_len;
676 676
677 mutex_lock(&root->ordered_extent_mutex); 677 mutex_lock(&root->ordered_extent_mutex);
@@ -701,7 +701,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr,
701 701
702 cond_resched(); 702 cond_resched();
703 spin_lock(&root->ordered_extent_lock); 703 spin_lock(&root->ordered_extent_lock);
704 if (nr != -1) 704 if (nr != U64_MAX)
705 nr--; 705 nr--;
706 count++; 706 count++;
707 } 707 }
@@ -720,13 +720,13 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr,
720 return count; 720 return count;
721} 721}
722 722
723int btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr, 723u64 btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
724 const u64 range_start, const u64 range_len) 724 const u64 range_start, const u64 range_len)
725{ 725{
726 struct btrfs_root *root; 726 struct btrfs_root *root;
727 struct list_head splice; 727 struct list_head splice;
728 int done; 728 u64 total_done = 0;
729 int total_done = 0; 729 u64 done;
730 730
731 INIT_LIST_HEAD(&splice); 731 INIT_LIST_HEAD(&splice);
732 732
@@ -748,9 +748,8 @@ int btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr,
748 total_done += done; 748 total_done += done;
749 749
750 spin_lock(&fs_info->ordered_root_lock); 750 spin_lock(&fs_info->ordered_root_lock);
751 if (nr != -1) { 751 if (nr != U64_MAX) {
752 nr -= done; 752 nr -= done;
753 WARN_ON(nr < 0);
754 } 753 }
755 } 754 }
756 list_splice_tail(&splice, &fs_info->ordered_roots); 755 list_splice_tail(&splice, &fs_info->ordered_roots);