|
@@ -28,6 +28,7 @@
|
|
|
#include <linux/interrupt.h>
|
|
|
#include <linux/cpu.h>
|
|
|
#include <linux/blktrace_api.h>
|
|
|
+#include <linux/fault-inject.h>
|
|
|
|
|
|
/*
|
|
|
* for max sense size
|
|
@@ -3056,6 +3057,42 @@ static void handle_bad_sector(struct bio *bio)
|
|
|
set_bit(BIO_EOF, &bio->bi_flags);
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_FAIL_MAKE_REQUEST
|
|
|
+
|
|
|
+static DECLARE_FAULT_ATTR(fail_make_request);
|
|
|
+
|
|
|
+static int __init setup_fail_make_request(char *str)
|
|
|
+{
|
|
|
+ return setup_fault_attr(&fail_make_request, str);
|
|
|
+}
|
|
|
+__setup("fail_make_request=", setup_fail_make_request);
|
|
|
+
|
|
|
+static int should_fail_request(struct bio *bio)
|
|
|
+{
|
|
|
+ if ((bio->bi_bdev->bd_disk->flags & GENHD_FL_FAIL) ||
|
|
|
+ (bio->bi_bdev->bd_part && bio->bi_bdev->bd_part->make_it_fail))
|
|
|
+ return should_fail(&fail_make_request, bio->bi_size);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int __init fail_make_request_debugfs(void)
|
|
|
+{
|
|
|
+ return init_fault_attr_dentries(&fail_make_request,
|
|
|
+ "fail_make_request");
|
|
|
+}
|
|
|
+
|
|
|
+late_initcall(fail_make_request_debugfs);
|
|
|
+
|
|
|
+#else /* CONFIG_FAIL_MAKE_REQUEST */
|
|
|
+
|
|
|
+static inline int should_fail_request(struct bio *bio)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* CONFIG_FAIL_MAKE_REQUEST */
|
|
|
+
|
|
|
/**
|
|
|
* generic_make_request: hand a buffer to its device driver for I/O
|
|
|
* @bio: The bio describing the location in memory and on the device.
|
|
@@ -3141,6 +3178,9 @@ end_io:
|
|
|
if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
|
|
|
goto end_io;
|
|
|
|
|
|
+ if (should_fail_request(bio))
|
|
|
+ goto end_io;
|
|
|
+
|
|
|
/*
|
|
|
* If this device has partitions, remap block n
|
|
|
* of partition p to block n+start(p) of the disk.
|