diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index d63547e0936..3bc3eaaf552 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -115,12 +115,15 @@ init_functions(IO_CACHE* info)
     DBUG_ASSERT(!(info->myflags & MY_ENCRYPT));
     info->read_function = info->share ? _my_b_cache_read_r : _my_b_cache_read;
     info->write_function = info->share ? _my_b_cache_write_r : _my_b_cache_write;
-    info->myflags&= ~MY_FULL_IO;
     break;
   case TYPE_NOT_SET:
     DBUG_ASSERT(0);
     break;
   }
+  if (type == READ_CACHE || type == WRITE_CACHE || type == SEQ_READ_APPEND)
+    info->myflags|= MY_FULL_IO;
+  else
+    info->myflags&= ~MY_FULL_IO;
 }
 
 
@@ -456,8 +459,6 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
     {
       info->read_end=info->write_pos;
       info->end_of_file=my_b_tell(info);
-      /* Ensure we will read all data */
-      info->myflags|= MY_FULL_IO;
       /*
         Trigger a new seek only if we have a valid
         file handle.
@@ -472,7 +473,6 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
 	info->seek_not_done=1;
       }
       info->end_of_file = ~(my_off_t) 0;
-      info->myflags&= ~MY_FULL_IO;
     }
     pos=info->request_pos+(seek_offset-info->pos_in_file);
     if (type == WRITE_CACHE)
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index d3524279ea9..04e0f583d08 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -47,8 +47,7 @@
 size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
                 myf MyFlags)
 {
-  size_t readbytes;
-  int error= 0;
+  size_t readbytes, save_count= 0;
 
   DBUG_ENTER("my_pread");
 
@@ -66,11 +65,10 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
 #else
     readbytes= pread(Filedes, Buffer, Count, offset);
 #endif
-    error = (readbytes != Count);
 
-    if (error)
+    if (readbytes != Count)
     {
-      my_errno= errno ? errno : -1;
+      my_errno= errno;
       if (errno == 0 || (readbytes != (size_t) -1 &&
                          (MyFlags & (MY_NABP | MY_FNABP))))
         my_errno= HA_ERR_FILE_TOO_SHORT;
@@ -82,6 +80,17 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
                              (int) readbytes));
         continue;                              /* Interrupted */
       }
+
+      /* Do a read retry if we didn't get enough data on first read */
+      if (readbytes != (size_t) -1 && readbytes != 0 &&
+          (MyFlags & MY_FULL_IO))
+      {
+        Buffer+= readbytes;
+        Count-= readbytes;
+        save_count+= readbytes;
+        continue;
+      }
+
       if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
       {
 	if (readbytes == (size_t) -1)
@@ -97,8 +106,10 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
         DBUG_RETURN(MY_FILE_ERROR);         /* Return with error */
     }
     if (MyFlags & (MY_NABP | MY_FNABP))
-      DBUG_RETURN(0);                      /* Read went ok; Return 0 */
-    DBUG_RETURN(readbytes);                /* purecov: inspected */
+      readbytes= 0;                       /* Read went ok; Return 0 */
+    else
+      readbytes+= save_count;
+    DBUG_RETURN(readbytes);
   }
 } /* my_pread */
 
