* fhandler.cc (fhandler_base::open_9x): Handle O_SYNC and O_DIRECT
flags. (fhandler_base::open): Ditto. * fhandler_floppy.cc (fhandler_dev_floppy::open): Don't allocate devbuf in O_DIRECT case. * fhandler_raw.cc (fhandler_dev_raw::ioctl): Don't allow buffer changes in O_DIRECT case. Allow returning a buffer size 0, which indicates O_DIRECT. * fhandler_tape.cc (fhandler_dev_tape::open): Use O_SYNC flag to hand down the !buffer_writes case. Don't allocate devbuf in O_DIRECT case. (fhandler_dev_tape::raw_read): Don't mess with devbuf if it's NULL. * include/fcntl.h: Define _FDIRECT, O_DIRECT, O_DSYNC and O_RSYNC. * include/cygwin/version.h: Bump API minor version.
This commit is contained in:
		| @@ -1,3 +1,20 @@ | |||||||
|  | 2005-12-14  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler.cc (fhandler_base::open_9x): Handle O_SYNC and O_DIRECT | ||||||
|  | 	flags. | ||||||
|  | 	(fhandler_base::open): Ditto. | ||||||
|  | 	* fhandler_floppy.cc (fhandler_dev_floppy::open): Don't allocate devbuf | ||||||
|  | 	in O_DIRECT case. | ||||||
|  | 	* fhandler_raw.cc (fhandler_dev_raw::ioctl): Don't allow buffer | ||||||
|  | 	changes in O_DIRECT case.  Allow returning a buffer size 0, which | ||||||
|  | 	indicates O_DIRECT. | ||||||
|  | 	* fhandler_tape.cc (fhandler_dev_tape::open): Use O_SYNC flag to | ||||||
|  | 	hand down the !buffer_writes case.  Don't allocate devbuf in O_DIRECT | ||||||
|  | 	case. | ||||||
|  | 	(fhandler_dev_tape::raw_read): Don't mess with devbuf if it's NULL. | ||||||
|  | 	* include/fcntl.h: Define _FDIRECT, O_DIRECT, O_DSYNC and O_RSYNC. | ||||||
|  | 	* include/cygwin/version.h: Bump API minor version. | ||||||
|  |  | ||||||
| 2005-12-13  Christopher Faylor  <cgf@timesys.com> | 2005-12-13  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
| 	* cygtls.cc (_cygtls::remove): Don't bother if we're exiting. | 	* cygtls.cc (_cygtls::remove): Don't bother if we're exiting. | ||||||
|   | |||||||
| @@ -492,6 +492,10 @@ fhandler_base::open_9x (int flags, mode_t mode) | |||||||
|   file_attributes = FILE_ATTRIBUTE_NORMAL; |   file_attributes = FILE_ATTRIBUTE_NORMAL; | ||||||
|   if (flags & O_DIROPEN) |   if (flags & O_DIROPEN) | ||||||
|     file_attributes |= FILE_FLAG_BACKUP_SEMANTICS; |     file_attributes |= FILE_FLAG_BACKUP_SEMANTICS; | ||||||
|  |   if (flags & O_SYNC) | ||||||
|  |     file_attributes |= FILE_FLAG_WRITE_THROUGH; | ||||||
|  |   if (flags & O_DIRECT) | ||||||
|  |     file_attributes |= FILE_FLAG_NO_BUFFERING; | ||||||
|   if (get_major () == DEV_SERIAL_MAJOR) |   if (get_major () == DEV_SERIAL_MAJOR) | ||||||
|     file_attributes |= FILE_FLAG_OVERLAPPED; |     file_attributes |= FILE_FLAG_OVERLAPPED; | ||||||
|  |  | ||||||
| @@ -599,18 +603,16 @@ fhandler_base::open (int flags, mode_t mode) | |||||||
| 	break; | 	break; | ||||||
|       default: |       default: | ||||||
| 	create_options = 0; | 	create_options = 0; | ||||||
| 	if (get_major () == DEV_TAPE_MAJOR && (flags & O_TEXT)) |  | ||||||
| 	  { |  | ||||||
| 	    /* O_TEXT is used to indicate write-through on tape devices */ |  | ||||||
| 	    create_options |= FILE_WRITE_THROUGH; |  | ||||||
| 	    flags &= ~O_TEXT; |  | ||||||
| 	  } |  | ||||||
| 	if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY) | 	if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY) | ||||||
| 	  access = GENERIC_READ; | 	  access = GENERIC_READ; | ||||||
| 	else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY) | 	else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY) | ||||||
| 	  access = GENERIC_WRITE | FILE_READ_ATTRIBUTES; | 	  access = GENERIC_WRITE | FILE_READ_ATTRIBUTES; | ||||||
| 	else | 	else | ||||||
| 	  access = GENERIC_READ | GENERIC_WRITE; | 	  access = GENERIC_READ | GENERIC_WRITE; | ||||||
|  | 	if (flags & O_SYNC) | ||||||
|  | 	  create_options |= FILE_WRITE_THROUGH; | ||||||
|  | 	if (flags & O_DIRECT) | ||||||
|  | 	  create_options |= FILE_NO_INTERMEDIATE_BUFFERING; | ||||||
| 	if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR) | 	if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR) | ||||||
| 	  { | 	  { | ||||||
| 	    create_options |= FILE_SYNCHRONOUS_IO_NONALERT; | 	    create_options |= FILE_SYNCHRONOUS_IO_NONALERT; | ||||||
|   | |||||||
| @@ -161,9 +161,10 @@ fhandler_dev_floppy::open (int flags, mode_t) | |||||||
|      relatively big value increases performance by means.  The new ioctl call |      relatively big value increases performance by means.  The new ioctl call | ||||||
|      with 'rdevio.h' header file supports changing this value. |      with 'rdevio.h' header file supports changing this value. | ||||||
|  |  | ||||||
|      Let's try to be smart: Let's take a multiple of typical tar and cpio |      As default buffer size, we're using some value which is a multiple of | ||||||
|      buffer sizes by default. */ |      the typical tar and cpio buffer sizes, Except O_DIRECT is set, in which | ||||||
|   devbufsiz = 61440L; |      case we're not buffering at all. */ | ||||||
|  |   devbufsiz = (flags & O_DIRECT) ? 0L : 61440L; | ||||||
|   int ret =  fhandler_dev_raw::open (flags); |   int ret =  fhandler_dev_raw::open (flags); | ||||||
|  |  | ||||||
|   if (ret && get_drive_info (NULL)) |   if (ret && get_drive_info (NULL)) | ||||||
|   | |||||||
| @@ -159,12 +159,14 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) | |||||||
| 	      } | 	      } | ||||||
| 	    else if ((devbuf && ((op->rd_parm <= 1 && (devbufend - devbufstart)) | 	    else if ((devbuf && ((op->rd_parm <= 1 && (devbufend - devbufstart)) | ||||||
| 				 || op->rd_parm < devbufend - devbufstart)) | 				 || op->rd_parm < devbufend - devbufstart)) | ||||||
| 		     || (op->rd_parm > 1 && (op->rd_parm % 512))) | 		     || (op->rd_parm > 1 && (op->rd_parm % 512)) | ||||||
|  | 		     || (get_flags () & O_DIRECT)) | ||||||
| 	      /* The conditions for a *valid* parameter are these: | 	      /* The conditions for a *valid* parameter are these: | ||||||
| 	         - If there's still data in the current buffer, it must | 	         - If there's still data in the current buffer, it must | ||||||
| 		   fit in the new buffer. | 		   fit in the new buffer. | ||||||
| 		 - The new size is either 0 or 1, both indicating unbufferd | 		 - The new size is either 0 or 1, both indicating unbufferd | ||||||
| 		   I/O, or the new buffersize must be a multiple of 512. */ | 		   I/O, or the new buffersize must be a multiple of 512. | ||||||
|  | 		 - In the O_DIRECT case, the whole request is invalid. */ | ||||||
| 	      ret = ERROR_INVALID_PARAMETER; | 	      ret = ERROR_INVALID_PARAMETER; | ||||||
| 	    else if (!devbuf || op->rd_parm != devbufsiz) | 	    else if (!devbuf || op->rd_parm != devbufsiz) | ||||||
| 	      { | 	      { | ||||||
| @@ -198,7 +200,7 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) | |||||||
|       if (!get) |       if (!get) | ||||||
| 	ret = ERROR_INVALID_PARAMETER; | 	ret = ERROR_INVALID_PARAMETER; | ||||||
|       else |       else | ||||||
| 	get->bufsiz = devbufsiz ?: 1L; | 	get->bufsiz = devbufsiz; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|     return fhandler_base::ioctl (cmd, buf); |     return fhandler_base::ioctl (cmd, buf); | ||||||
|   | |||||||
| @@ -1216,11 +1216,16 @@ fhandler_dev_tape::open (int flags, mode_t) | |||||||
|       __seterrno (); |       __seterrno (); | ||||||
|       return 0; |       return 0; | ||||||
|     } |     } | ||||||
|   /* The O_TEXT flag is used to indicate write-through (non buffered writes) |  | ||||||
|      to the underlying fhandler_dev_raw::open call. */ |   /* The O_SYNC flag is not supported by the tape driver.  Use the | ||||||
|   flags &= ~O_TEXT; |      MT_ST_BUFFER_WRITES and MT_ST_ASYNC_WRITES flags in the drive | ||||||
|  |      settings instead.  In turn, the MT_ST_BUFFER_WRITES is translated | ||||||
|  |      into O_SYNC, which controls the FILE_WRITE_THROUGH flag in the | ||||||
|  |      NtCreateFile call in fhandler_base::open. */ | ||||||
|  |   flags &= ~O_SYNC; | ||||||
|   if (!mt->drive (driveno ())->buffer_writes ()) |   if (!mt->drive (driveno ())->buffer_writes ()) | ||||||
|     flags |= O_TEXT; |     flags |= O_SYNC; | ||||||
|  |  | ||||||
|   ret = fhandler_dev_raw::open (flags); |   ret = fhandler_dev_raw::open (flags); | ||||||
|   if (ret) |   if (ret) | ||||||
|     { |     { | ||||||
| @@ -1231,8 +1236,11 @@ fhandler_dev_tape::open (int flags, mode_t) | |||||||
| 	mt->drive (driveno ())->set_pos (get_handle (), | 	mt->drive (driveno ())->set_pos (get_handle (), | ||||||
| 					 TAPE_SPACE_FILEMARKS, 1, true); | 					 TAPE_SPACE_FILEMARKS, 1, true); | ||||||
|  |  | ||||||
|  |       if (!(flags & O_DIRECT)) | ||||||
|  |         { | ||||||
| 	  devbufsiz = mt->drive (driveno ())->dp ()->MaximumBlockSize; | 	  devbufsiz = mt->drive (driveno ())->dp ()->MaximumBlockSize; | ||||||
| 	  devbuf = new char [devbufsiz]; | 	  devbuf = new char [devbufsiz]; | ||||||
|  | 	} | ||||||
|       devbufstart = devbufend = 0; |       devbufstart = devbufend = 0; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
| @@ -1283,6 +1291,8 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   block_size = mt->drive (driveno ())->mp ()->BlockSize; |   block_size = mt->drive (driveno ())->mp ()->BlockSize; | ||||||
|  |   if (devbuf) | ||||||
|  |     { | ||||||
|       if (devbufend > devbufstart) |       if (devbufend > devbufstart) | ||||||
| 	{ | 	{ | ||||||
| 	  bytes_to_read = min (len, devbufend - devbufstart); | 	  bytes_to_read = min (len, devbufend - devbufstart); | ||||||
| @@ -1347,6 +1357,15 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) | |||||||
| 		lastblk_to_read (true); | 		lastblk_to_read (true); | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL))) | ||||||
|  | 	debug_printf ("Creating event failed, %E"); | ||||||
|  |       bytes_read = ulen; | ||||||
|  |       ret = mt->drive (driveno ())->read (get_handle (), mt_evt, ptr, | ||||||
|  | 					  bytes_read); | ||||||
|  |     } | ||||||
|   ulen = (ret ? (size_t) -1 : bytes_read); |   ulen = (ret ? (size_t) -1 : bytes_read); | ||||||
|   unlock (); |   unlock (); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -282,12 +282,13 @@ details. */ | |||||||
|            for this? |            for this? | ||||||
|       147: Eliminate problematic d_ino from dirent structure.  unsetenv now returns |       147: Eliminate problematic d_ino from dirent structure.  unsetenv now returns | ||||||
|            int, as per linux. |            int, as per linux. | ||||||
|  |       148: Add open(2) flags O_SYNC, O_RSYNC, O_DSYNC and O_DIRECT. | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ |      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ | ||||||
|  |  | ||||||
| #define CYGWIN_VERSION_API_MAJOR 0 | #define CYGWIN_VERSION_API_MAJOR 0 | ||||||
| #define CYGWIN_VERSION_API_MINOR 147 | #define CYGWIN_VERSION_API_MINOR 148 | ||||||
|  |  | ||||||
|      /* There is also a compatibity version number associated with the |      /* There is also a compatibity version number associated with the | ||||||
| 	shared memory regions.  It is incremented when incompatible | 	shared memory regions.  It is incremented when incompatible | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* fcntl.h | /* fcntl.h | ||||||
|  |  | ||||||
|    Copyright 1996, 1998, 2001 Red Hat, Inc. |    Copyright 1996, 1998, 2001, 2005 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -14,4 +14,11 @@ details. */ | |||||||
| #include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||||
| #define O_NDELAY	_FNDELAY | #define O_NDELAY	_FNDELAY | ||||||
|  |  | ||||||
|  | /* sys/fcntl defines values up to 0x40000 (O_NOINHERIT). */ | ||||||
|  | #define _FDIRECT	0x80000 | ||||||
|  |  | ||||||
|  | #define O_DIRECT	_FDIRECT | ||||||
|  | #define O_DSYNC		_FSYNC | ||||||
|  | #define O_RSYNC		_FSYNC | ||||||
|  |  | ||||||
| #endif /* _FCNTL_H */ | #endif /* _FCNTL_H */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user