This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Segfault on unaligned lseek() on /dev/sdX (was: [ITP] ddrescue 1.3)


fhandler_dev_floppy::lseek() always clears the 60KB pre-read buffer, even on lseek(fd, 0, SEEK_CUR);
If a programm (like ddrescue) always calls lseek() before each read(), performance is poor, because the same block is read several times.


With this new version of the patch, the buffer is only cleared if necessary.

Christian

--- cygwin-1.5.24-2.orig/winsup/cygwin/fhandler_floppy.cc	2006-07-18 14:56:37.001000000 +0200
+++ cygwin-1.5.24-2/winsup/cygwin/fhandler_floppy.cc	2007-05-20 16:25:35.063800100 +0200
@@ -12,6 +12,7 @@ details. */
 #include "winsup.h"
 #include <sys/termios.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <winioctl.h>
 #include <asm/socket.h>
 #include <cygwin/rdevio.h>
@@ -408,8 +409,8 @@ fhandler_dev_floppy::raw_write (const vo
 _off64_t
 fhandler_dev_floppy::lseek (_off64_t offset, int whence)
 {
-  char buf[512];
   _off64_t lloffset = offset;
+  _off64_t current_pos = (_off64_t)-1;
   LARGE_INTEGER sector_aligned_offset;
   _off64_t bytes_left;
 
@@ -420,7 +421,8 @@ fhandler_dev_floppy::lseek (_off64_t off
     }
   else if (whence == SEEK_CUR)
     {
-      lloffset += get_current_position () - (devbufend - devbufstart);
+      current_pos = get_current_position ();
+      lloffset += current_pos - (devbufend - devbufstart);
       whence = SEEK_SET;
     }
 
@@ -430,6 +432,18 @@ fhandler_dev_floppy::lseek (_off64_t off
       return -1;
     }
 
+  /* If new position is in buffered range, adjust buffer and return */
+  if (devbufstart < devbufend)
+    {
+      if (current_pos == (_off64_t)-1)
+	current_pos = get_current_position ();
+      if (current_pos - devbufend <= lloffset && lloffset <= current_pos)
+	{
+	  devbufstart = devbufend - (current_pos - lloffset);
+	  return lloffset;
+	}
+    }
+
   sector_aligned_offset.QuadPart = (lloffset / bytes_per_sector)
 				   * bytes_per_sector;
   bytes_left = lloffset - sector_aligned_offset.QuadPart;
@@ -454,7 +468,9 @@ fhandler_dev_floppy::lseek (_off64_t off
   if (bytes_left)
     {
       size_t len = bytes_left;
+      char *buf = (char *) alloca (len);
       raw_read (buf, len);
+      /* TODO: return -1 on read errors ? */
     }
   return sector_aligned_offset.QuadPart + bytes_left;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]