bcache: fix misleading error message in bch_count_io_errors()
authorColy Li <colyli@suse.de>
Mon, 8 Jan 2018 20:21:29 +0000 (12:21 -0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 8 Jan 2018 20:29:00 +0000 (13:29 -0700)
Bcache only does recoverable I/O for read operations by calling
cached_dev_read_error(). For write opertions there is no I/O recovery for
failed requests.

But in bch_count_io_errors() no matter read or write I/Os, before errors
counter reaches io error limit, pr_err() always prints "IO error on %,
recoverying". For write requests this information is misleading, because
there is no I/O recovery at all.

This patch adds a parameter 'is_read' to bch_count_io_errors(), and only
prints "recovering" by pr_err() when the bio direction is READ.

Signed-off-by: Coly Li <colyli@suse.de>
Reviewed-by: Michael Lyle <mlyle@lyle.org>
Reviewed-by: Tang Junhui <tang.junhui@zte.com.cn>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/bcache.h
drivers/md/bcache/io.c
drivers/md/bcache/super.c
drivers/md/bcache/writeback.c

index 9117da5f494bb495fbdfc85dfce2a456793ff62b..5e2d4e80198e596e426f05a7a902b3eff54bb3ac 100644 (file)
@@ -862,7 +862,7 @@ static inline void wake_up_allocators(struct cache_set *c)
 
 /* Forward declarations */
 
-void bch_count_io_errors(struct cache *, blk_status_t, const char *);
+void bch_count_io_errors(struct cache *, blk_status_t, int, const char *);
 void bch_bbio_count_io_errors(struct cache_set *, struct bio *,
                              blk_status_t, const char *);
 void bch_bbio_endio(struct cache_set *, struct bio *, blk_status_t,
index fac97ec2d0e2b3924f9b153cdff89ab58147f893..a783c5a41ff166a698d6bef80e6d4d22ba6b2e27 100644 (file)
@@ -51,7 +51,10 @@ void bch_submit_bbio(struct bio *bio, struct cache_set *c,
 
 /* IO errors */
 
-void bch_count_io_errors(struct cache *ca, blk_status_t error, const char *m)
+void bch_count_io_errors(struct cache *ca,
+                        blk_status_t error,
+                        int is_read,
+                        const char *m)
 {
        /*
         * The halflife of an error is:
@@ -94,8 +97,9 @@ void bch_count_io_errors(struct cache *ca, blk_status_t error, const char *m)
                errors >>= IO_ERROR_SHIFT;
 
                if (errors < ca->set->error_limit)
-                       pr_err("%s: IO error on %s, recovering",
-                              bdevname(ca->bdev, buf), m);
+                       pr_err("%s: IO error on %s%s",
+                              bdevname(ca->bdev, buf), m,
+                              is_read ? ", recovering." : ".");
                else
                        bch_cache_set_error(ca->set,
                                            "%s: too many IO errors %s",
@@ -108,6 +112,7 @@ void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
 {
        struct bbio *b = container_of(bio, struct bbio, bio);
        struct cache *ca = PTR_CACHE(c, &b->key, 0);
+       int is_read = (bio_data_dir(bio) == READ ? 1 : 0);
 
        unsigned threshold = op_is_write(bio_op(bio))
                ? c->congested_write_threshold_us
@@ -129,7 +134,7 @@ void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
                        atomic_inc(&c->congested);
        }
 
-       bch_count_io_errors(ca, error, m);
+       bch_count_io_errors(ca, error, is_read, m);
 }
 
 void bch_bbio_endio(struct cache_set *c, struct bio *bio,
index d13e4ccb30a0583355ebcfa016e1c8c03dfe2b86..133b81225ea9c6ac61934d8593e09e94749c3152 100644 (file)
@@ -274,7 +274,9 @@ static void write_super_endio(struct bio *bio)
 {
        struct cache *ca = bio->bi_private;
 
-       bch_count_io_errors(ca, bio->bi_status, "writing superblock");
+       /* is_read = 0 */
+       bch_count_io_errors(ca, bio->bi_status, 0,
+                           "writing superblock");
        closure_put(&ca->set->sb_write);
 }
 
index f82ffb2e9b9be3893068fb84980ac5f091e8dcbe..31b0a292a619253665f568f177a16913ceaf3d17 100644 (file)
@@ -244,8 +244,10 @@ static void read_dirty_endio(struct bio *bio)
        struct keybuf_key *w = bio->bi_private;
        struct dirty_io *io = w->private;
 
+       /* is_read = 1 */
        bch_count_io_errors(PTR_CACHE(io->dc->disk.c, &w->key, 0),
-                           bio->bi_status, "reading dirty data from cache");
+                           bio->bi_status, 1,
+                           "reading dirty data from cache");
 
        dirty_endio(bio);
 }