aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bcache/super.c
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-10-31 18:43:22 -0400
committerKent Overstreet <kmo@daterainc.com>2013-11-11 00:56:41 -0500
commit48a915a87f0bd98c3d68d029acf223a2e5116f07 (patch)
treed821604169acc801b655b04c1de1cc5672169ec4 /drivers/md/bcache/super.c
parent17e21a9f248d3d330acdfb2405c23b8d84c9c23a (diff)
bcache: Better full stripe scanning
The old scanning-by-stripe code burned too much CPU, this should be better. Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md/bcache/super.c')
-rw-r--r--drivers/md/bcache/super.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 4813ef67cef5..43fcfe38be11 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -738,6 +738,10 @@ static void bcache_device_free(struct bcache_device *d)
738 mempool_destroy(d->unaligned_bvec); 738 mempool_destroy(d->unaligned_bvec);
739 if (d->bio_split) 739 if (d->bio_split)
740 bioset_free(d->bio_split); 740 bioset_free(d->bio_split);
741 if (is_vmalloc_addr(d->full_dirty_stripes))
742 vfree(d->full_dirty_stripes);
743 else
744 kfree(d->full_dirty_stripes);
741 if (is_vmalloc_addr(d->stripe_sectors_dirty)) 745 if (is_vmalloc_addr(d->stripe_sectors_dirty))
742 vfree(d->stripe_sectors_dirty); 746 vfree(d->stripe_sectors_dirty);
743 else 747 else
@@ -757,8 +761,12 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
757 761
758 d->nr_stripes = DIV_ROUND_UP_ULL(sectors, d->stripe_size); 762 d->nr_stripes = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
759 763
760 if (!d->nr_stripes || d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) 764 if (!d->nr_stripes ||
765 d->nr_stripes > INT_MAX ||
766 d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) {
767 pr_err("nr_stripes too large");
761 return -ENOMEM; 768 return -ENOMEM;
769 }
762 770
763 n = d->nr_stripes * sizeof(atomic_t); 771 n = d->nr_stripes * sizeof(atomic_t);
764 d->stripe_sectors_dirty = n < PAGE_SIZE << 6 772 d->stripe_sectors_dirty = n < PAGE_SIZE << 6
@@ -767,6 +775,13 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
767 if (!d->stripe_sectors_dirty) 775 if (!d->stripe_sectors_dirty)
768 return -ENOMEM; 776 return -ENOMEM;
769 777
778 n = BITS_TO_LONGS(d->nr_stripes) * sizeof(unsigned long);
779 d->full_dirty_stripes = n < PAGE_SIZE << 6
780 ? kzalloc(n, GFP_KERNEL)
781 : vzalloc(n);
782 if (!d->full_dirty_stripes)
783 return -ENOMEM;
784
770 if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) || 785 if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) ||
771 !(d->unaligned_bvec = mempool_create_kmalloc_pool(1, 786 !(d->unaligned_bvec = mempool_create_kmalloc_pool(1,
772 sizeof(struct bio_vec) * BIO_MAX_PAGES)) || 787 sizeof(struct bio_vec) * BIO_MAX_PAGES)) ||