All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Guthro <bguthro@virtualiron.com>
To: qemu-devel@nongnu.org
Cc: Josh Nicholas <jnicholas@virtualiron.com>
Subject: [Qemu-devel] [PATCH] Enhance raw io reliability
Date: Mon, 27 Aug 2007 16:48:57 -0400	[thread overview]
Message-ID: <46D338B9.5020409@virtualiron.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 243 bytes --]

For raw block device only : log any I/O error and perform automatic read 
retry for CDrom
(improves MediaCheck with old installers).

Signed-off-by: Ben Guthro <bguthro@virtualiron.com>
Signed-off-by: Josh Nicholas <jnicholas@virtualiron.com>

[-- Attachment #2: qemu-raw-io-reliability.patch --]
[-- Type: text/x-patch, Size: 3837 bytes --]

diff -r 808c4b54209f block-raw.c
--- a/block-raw.c	Fri Aug 10 16:30:38 2007 -0400
+++ b/block-raw.c	Fri Aug 10 16:30:38 2007 -0400
@@ -59,6 +59,13 @@
 
 //#define DEBUG_FLOPPY
 
+#define DEBUG_BLOCK
+#ifdef  DEBUG_BLOCK
+#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
+#else
+#define DEBUG_BLOCK_PRINT( formatCstr, args... )
+#endif
+
 #define FTYPE_FILE   0
 #define FTYPE_CD     1
 #define FTYPE_FD     2
@@ -70,6 +77,7 @@ typedef struct BDRVRawState {
 typedef struct BDRVRawState {
     int fd;
     int type;
+    unsigned int lseek_err_cnt;
 #if defined(__linux__)
     /* linux floppy specific */
     int fd_open_flags;
@@ -87,6 +95,8 @@ static int raw_open(BlockDriverState *bs
     BDRVRawState *s = bs->opaque;
     int fd, open_flags, ret;
 
+    s->lseek_err_cnt = 0;
+
     open_flags = O_BINARY;
     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
         open_flags |= O_RDWR;
@@ -137,8 +147,58 @@ static int raw_pread(BlockDriverState *b
     if (ret < 0)
         return ret;
 
-    lseek(s->fd, offset, SEEK_SET);
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt <= 10) {
+                DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n", 
+                        s->fd, 
+                        bs->filename, 
+                        offset, 
+                        buf, 
+                        count, 
+                        bs->total_sectors, errno, strerror(errno) );
+       }
+       return -1;
+    }
+    s->lseek_err_cnt=0;
+
     ret = read(s->fd, buf, count);
+    if (ret == count) 
+        goto label__raw_read__success;
+    
+    DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] read failed %d : %d = %s\n", 
+        s->fd, 
+        bs->filename, 
+        offset, 
+        buf, 
+        count, 
+        bs->total_sectors, 
+        ret, errno, strerror(errno) );
+    
+    if (bs->type == BDRV_TYPE_CDROM) {  // Try harder for CDrom
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count) 
+            goto label__raw_read__success;
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count)
+            goto label__raw_read__success;
+        
+        DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] retry read failed %d : %d = %s\n", 
+            s->fd, 
+            bs->filename, 
+            offset, 
+            buf, 
+            count, 
+            bs->total_sectors, 
+            ret, errno, strerror(errno) );
+    }
+    
+    return -1;
+    
+label__raw_read__success:
+
     return ret;
 }
 
@@ -152,8 +212,38 @@ static int raw_pwrite(BlockDriverState *
     if (ret < 0)
         return ret;
 
-    lseek(s->fd, offset, SEEK_SET);
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt) {
+                DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n", 
+                        s->fd, 
+                        bs->filename, 
+                        offset, 
+                        buf, 
+                        count, 
+                        bs->total_sectors, errno, strerror(errno) );
+        }
+        return -1;
+    }
+    s->lseek_err_cnt = 0;
+
     ret = write(s->fd, buf, count);
+    if (ret == count) 
+        goto label__raw_write__success;
+    
+    DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] write failed %d : %d = %s\n", 
+        s->fd, 
+        bs->filename, 
+        offset, 
+        buf, 
+        count, 
+        bs->total_sectors, 
+        ret, errno, strerror(errno) );
+    
+    return -1;
+    
+label__raw_write__success:
+
     return ret;
 }
 

                 reply	other threads:[~2007-08-27 21:10 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46D338B9.5020409@virtualiron.com \
    --to=bguthro@virtualiron.com \
    --cc=jnicholas@virtualiron.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.