If the discard block size is larger than the cache block size we will
not properly quiesce IO to a region that is about to be discarded. This
results in a race between a cache migration where no copy is needed, and
a write to an adjacent cache block that's within the same large discard
block.
Workaround this by limiting the discard_block_size to cache_block_size.
Also limit the max_discard_sectors to cache_block_size.
A more comprehensive fix that introduces range locking support in the
bio_prison and proper quiescing of a discard range that spans multiple
cache blocks is already in development.
Reported-by: Morgan Mears <Morgan.Mears@netapp.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Acked-by: Joe Thornber <ejt@redhat.com>
Acked-by: Heinz Mauelshagen <heinzm@redhat.com>
Cc: stable@vger.kernel.org
static sector_t calculate_discard_block_size(sector_t cache_block_size,
sector_t origin_size)
{
+#if 0
sector_t discard_block_size;
discard_block_size = roundup_pow_of_two(cache_block_size);
discard_block_size *= 2;
return discard_block_size;
+#else
+ /*
+ * FIXME: stop-gap workaround for corruption that is
+ * induced by discard_block_size > cache_block_size.
+ */
+ return cache_block_size;
+#endif
}
#define DEFAULT_MIGRATION_THRESHOLD 2048
/*
* FIXME: these limits may be incompatible with the cache device
*/
- limits->max_discard_sectors = cache->discard_block_size * 1024;
+ limits->max_discard_sectors = cache->discard_block_size;
limits->discard_granularity = cache->discard_block_size << SECTOR_SHIFT;
}