summary refs log tree commit diff
path: root/drivers/md/bcache
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-09-10 14:27:42 -0700
committerKent Overstreet <kmo@daterainc.com>2013-11-10 21:56:43 -0800
commit5ceaaad7047745c1c02150c39d3fb623b7948d48 (patch)
treec03201ceda61314a0ec4b521e5d2d4d89bb1f0c2 /drivers/md/bcache
parent098fb25498214069e6bbf908515f2952dd7654d0 (diff)
downloadlinux-5ceaaad7047745c1c02150c39d3fb623b7948d48.tar.gz
bcache: Bypass torture test
More testing ftw! Also, now verify mode doesn't break if you read dirty
data.

Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Diffstat (limited to 'drivers/md/bcache')
-rw-r--r--drivers/md/bcache/bcache.h1
-rw-r--r--drivers/md/bcache/debug.c15
-rw-r--r--drivers/md/bcache/debug.h2
-rw-r--r--drivers/md/bcache/request.c14
-rw-r--r--drivers/md/bcache/sysfs.c4
5 files changed, 28 insertions, 8 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 97ef126b68bb..4beb55a0ff30 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -364,6 +364,7 @@ struct cached_dev {
 	unsigned		readahead;
 
 	unsigned		verify:1;
+	unsigned		bypass_torture_test:1;
 
 	unsigned		partial_stripes_expensive:1;
 	unsigned		writeback_metadata:1;
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
index e99e6b8852b2..264fcfbd6290 100644
--- a/drivers/md/bcache/debug.c
+++ b/drivers/md/bcache/debug.c
@@ -189,13 +189,14 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
 		void *p1 = kmap_atomic(bv->bv_page);
 		void *p2 = page_address(check->bi_io_vec[i].bv_page);
 
-		if (memcmp(p1 + bv->bv_offset,
-			   p2 + bv->bv_offset,
-			   bv->bv_len))
-			printk(KERN_ERR
-			       "bcache (%s): verify failed at sector %llu\n",
-			       bdevname(dc->bdev, name),
-			       (uint64_t) bio->bi_sector);
+		cache_set_err_on(memcmp(p1 + bv->bv_offset,
+					p2 + bv->bv_offset,
+					bv->bv_len),
+				 dc->disk.c,
+				 "verify failed at dev %s sector %llu",
+				 bdevname(dc->bdev, name),
+				 (uint64_t) bio->bi_sector);
+
 		kunmap_atomic(p1);
 	}
 
diff --git a/drivers/md/bcache/debug.h b/drivers/md/bcache/debug.h
index 7914ba0ff316..2ede60e31874 100644
--- a/drivers/md/bcache/debug.h
+++ b/drivers/md/bcache/debug.h
@@ -16,6 +16,7 @@ void bch_btree_iter_next_check(struct btree_iter *);
 #define EBUG_ON(cond)			BUG_ON(cond)
 #define expensive_debug_checks(c)	((c)->expensive_debug_checks)
 #define key_merging_disabled(c)		((c)->key_merging_disabled)
+#define bypass_torture_test(d)		((d)->bypass_torture_test)
 
 #else /* DEBUG */
 
@@ -28,6 +29,7 @@ static inline void bch_btree_iter_next_check(struct btree_iter *iter) {}
 #define EBUG_ON(cond)			do { if (cond); } while (0)
 #define expensive_debug_checks(c)	0
 #define key_merging_disabled(c)		0
+#define bypass_torture_test(d)		0
 
 #endif
 
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 9f5a1386f77a..fbcc851ed5a5 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -528,6 +528,13 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 		goto skip;
 	}
 
+	if (bypass_torture_test(dc)) {
+		if ((get_random_int() & 3) == 3)
+			goto skip;
+		else
+			goto rescale;
+	}
+
 	if (!congested && !dc->sequential_cutoff)
 		goto rescale;
 
@@ -601,6 +608,7 @@ struct search {
 	unsigned		recoverable:1;
 	unsigned		unaligned_bvec:1;
 	unsigned		write:1;
+	unsigned		read_dirty_data:1;
 
 	unsigned long		start_time;
 
@@ -669,6 +677,9 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k)
 
 	PTR_BUCKET(b->c, k, ptr)->prio = INITIAL_PRIO;
 
+	if (KEY_DIRTY(k))
+		s->read_dirty_data = true;
+
 	n = bch_bio_split(bio, min_t(uint64_t, INT_MAX,
 				     KEY_OFFSET(k) - bio->bi_sector),
 			  GFP_NOIO, s->d->bio_split);
@@ -894,7 +905,8 @@ static void cached_dev_read_done(struct closure *cl)
 		s->cache_miss = NULL;
 	}
 
-	if (verify(dc, &s->bio.bio) && s->recoverable && !s->unaligned_bvec)
+	if (verify(dc, &s->bio.bio) && s->recoverable &&
+	    !s->unaligned_bvec && !s->read_dirty_data)
 		bch_data_verify(dc, s->orig_bio);
 
 	bio_complete(s);
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 194d43782ea4..80d4c2bee18a 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -99,6 +99,7 @@ rw_attribute(errors);
 rw_attribute(io_error_limit);
 rw_attribute(io_error_halflife);
 rw_attribute(verify);
+rw_attribute(bypass_torture_test);
 rw_attribute(key_merging_disabled);
 rw_attribute(gc_always_rewrite);
 rw_attribute(expensive_debug_checks);
@@ -123,6 +124,7 @@ SHOW(__bch_cached_dev)
 
 	sysfs_printf(data_csum,		"%i", dc->disk.data_csum);
 	var_printf(verify,		"%i");
+	var_printf(bypass_torture_test,	"%i");
 	var_printf(writeback_metadata,	"%i");
 	var_printf(writeback_running,	"%i");
 	var_print(writeback_delay);
@@ -191,6 +193,7 @@ STORE(__cached_dev)
 
 	sysfs_strtoul(data_csum,	dc->disk.data_csum);
 	d_strtoul(verify);
+	d_strtoul(bypass_torture_test);
 	d_strtoul(writeback_metadata);
 	d_strtoul(writeback_running);
 	d_strtoul(writeback_delay);
@@ -323,6 +326,7 @@ static struct attribute *bch_cached_dev_files[] = {
 	&sysfs_readahead,
 #ifdef CONFIG_BCACHE_DEBUG
 	&sysfs_verify,
+	&sysfs_bypass_torture_test,
 #endif
 	NULL
 };