From: Manjunath Patil Date: Thu, 10 Dec 2015 00:05:54 +0000 (-0500) Subject: logging errors that get masked to EIO inside drivers/block/loop.c X-Git-Tag: v4.1.12-92~189^2~368 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e86d378ad145c5d3e848774252c0f5bd2cabf651;p=users%2Fjedix%2Flinux-maple.git logging errors that get masked to EIO inside drivers/block/loop.c Currently, some loop driver functions mask all errors to EIO. This patch is intended to log actual error prior to returning EIO to guest. ENOSPC and EDQUOT are handled specially as they are common in dom0 Orabug: 22505557 Signed-off-by: Manjunath Patil Acked-by: Srinivas Eeda --- diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b967126d28e20..58696da97649e 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -86,6 +86,41 @@ static DEFINE_MUTEX(loop_index_mutex); static int max_part; static int part_shift; +static void __lo_print_error(struct bio *bio, int error, + const char *func, int line) +{ + char b[BDEVNAME_SIZE]; + char dev_info[64]; + char err_buf[64]; + struct block_device *bdev; + + if (bio) { + bdev = bio->bi_bdev; + snprintf(dev_info, sizeof(dev_info), + "Device %s MAJOR:%d MINOR:%d", + bdevname(bdev, b), MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); + } else + snprintf(dev_info, sizeof(dev_info), "%s", + "Device Info Unavailable"); + + /* Special ENOSPC and EDQUOT as they are common in Dom0 */ + if (error == -ENOSPC) + snprintf(err_buf, sizeof(err_buf), "ERROR:%d - %s.", + error, "No space left on device"); + else if (error == -EDQUOT) + snprintf(err_buf, sizeof(err_buf), "ERROR:%d - %s.", + error, "Quota exceeded"); + else + snprintf(err_buf, sizeof(err_buf), "ERROR:%d received.", + error); + + printk_ratelimited(KERN_INFO "%s:%d:%s %s\n", func, line, + err_buf, dev_info); +} + +#define lo_print_error(bio, error) \ + __lo_print_error(bio, error, __func__, __LINE__) + static int transfer_xor(struct loop_device *lo, int cmd, struct page *raw_page, unsigned raw_off, struct page *loop_page, unsigned loop_off, @@ -217,8 +252,8 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) return 0; printk_ratelimited(KERN_ERR - "loop: Write error at byte offset %llu, length %i.\n", - (unsigned long long)*ppos, bvec->bv_len); + "loop: Write error %zd at byte offset %llu, length %i.\n", + bw, (unsigned long long)*ppos, bvec->bv_len); if (bw >= 0) bw = -EIO; return bw; @@ -373,8 +408,10 @@ static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos) } ret = file->f_op->fallocate(file, mode, pos, blk_rq_bytes(rq)); - if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP)) + if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP)) { + lo_print_error(rq->bio, ret); ret = -EIO; + } out: return ret; } @@ -383,8 +420,10 @@ static int lo_req_flush(struct loop_device *lo, struct request *rq) { struct file *file = lo->lo_backing_file; int ret = vfs_fsync(file, 0); - if (unlikely(ret && ret != -EINVAL)) + if (unlikely(ret && ret != -EINVAL)) { + lo_print_error(rq->bio, ret); ret = -EIO; + } return ret; } @@ -411,8 +450,10 @@ static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2) if (ret > 0) ret = 0; - else if (ret < 0) + else if (ret < 0) { + lo_print_error(rq->bio, ret); ret = -EIO; + } rq->errors = ret; blk_mq_complete_request(rq);