]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
logging errors that get masked to EIO inside drivers/block/loop.c
authorManjunath Patil <manjunath.b.patil@oracle.com>
Thu, 10 Dec 2015 00:05:54 +0000 (19:05 -0500)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 10 Mar 2016 15:57:29 +0000 (07:57 -0800)
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 <manjunath.b.patil@oracle.com>
Acked-by: Srinivas Eeda <srinivas.eeda@oracle.com>
drivers/block/loop.c

index b967126d28e2076d7fca6c490408837545d60eec..58696da97649e52d3dd502199da419d5c666f05c 100644 (file)
@@ -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);