* 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> | ||||
|  | ||||
| 	* 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; | ||||
|   if (flags & O_DIROPEN) | ||||
|     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) | ||||
|     file_attributes |= FILE_FLAG_OVERLAPPED; | ||||
|  | ||||
| @@ -599,18 +603,16 @@ fhandler_base::open (int flags, mode_t mode) | ||||
| 	break; | ||||
|       default: | ||||
| 	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) | ||||
| 	  access = GENERIC_READ; | ||||
| 	else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY) | ||||
| 	  access = GENERIC_WRITE | FILE_READ_ATTRIBUTES; | ||||
| 	else | ||||
| 	  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) | ||||
| 	  { | ||||
| 	    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 | ||||
|      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 | ||||
|      buffer sizes by default. */ | ||||
|   devbufsiz = 61440L; | ||||
|      As default buffer size, we're using some value which is a multiple of | ||||
|      the typical tar and cpio buffer sizes, Except O_DIRECT is set, in which | ||||
|      case we're not buffering at all. */ | ||||
|   devbufsiz = (flags & O_DIRECT) ? 0L : 61440L; | ||||
|   int ret =  fhandler_dev_raw::open (flags); | ||||
|  | ||||
|   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)) | ||||
| 				 || 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: | ||||
| 	         - If there's still data in the current buffer, it must | ||||
| 		   fit in the new buffer. | ||||
| 		 - 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; | ||||
| 	    else if (!devbuf || op->rd_parm != devbufsiz) | ||||
| 	      { | ||||
| @@ -198,7 +200,7 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) | ||||
|       if (!get) | ||||
| 	ret = ERROR_INVALID_PARAMETER; | ||||
|       else | ||||
| 	get->bufsiz = devbufsiz ?: 1L; | ||||
| 	get->bufsiz = devbufsiz; | ||||
|     } | ||||
|   else | ||||
|     return fhandler_base::ioctl (cmd, buf); | ||||
|   | ||||
| @@ -1216,11 +1216,16 @@ fhandler_dev_tape::open (int flags, mode_t) | ||||
|       __seterrno (); | ||||
|       return 0; | ||||
|     } | ||||
|   /* The O_TEXT flag is used to indicate write-through (non buffered writes) | ||||
|      to the underlying fhandler_dev_raw::open call. */ | ||||
|   flags &= ~O_TEXT; | ||||
|  | ||||
|   /* The O_SYNC flag is not supported by the tape driver.  Use the | ||||
|      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 ()) | ||||
|     flags |= O_TEXT; | ||||
|     flags |= O_SYNC; | ||||
|  | ||||
|   ret = fhandler_dev_raw::open (flags); | ||||
|   if (ret) | ||||
|     { | ||||
| @@ -1231,8 +1236,11 @@ fhandler_dev_tape::open (int flags, mode_t) | ||||
| 	mt->drive (driveno ())->set_pos (get_handle (), | ||||
| 					 TAPE_SPACE_FILEMARKS, 1, true); | ||||
|  | ||||
|       if (!(flags & O_DIRECT)) | ||||
|         { | ||||
| 	  devbufsiz = mt->drive (driveno ())->dp ()->MaximumBlockSize; | ||||
| 	  devbuf = new char [devbufsiz]; | ||||
| 	} | ||||
|       devbufstart = devbufend = 0; | ||||
|     } | ||||
|   else | ||||
| @@ -1283,6 +1291,8 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) | ||||
|       return; | ||||
|     } | ||||
|   block_size = mt->drive (driveno ())->mp ()->BlockSize; | ||||
|   if (devbuf) | ||||
|     { | ||||
|       if (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); | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   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); | ||||
|   unlock (); | ||||
| } | ||||
|   | ||||
| @@ -282,12 +282,13 @@ details. */ | ||||
|            for this? | ||||
|       147: Eliminate problematic d_ino from dirent structure.  unsetenv now returns | ||||
|            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 */ | ||||
|  | ||||
| #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 | ||||
| 	shared memory regions.  It is incremented when incompatible | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* fcntl.h | ||||
|  | ||||
|    Copyright 1996, 1998, 2001 Red Hat, Inc. | ||||
|    Copyright 1996, 1998, 2001, 2005 Red Hat, Inc. | ||||
|  | ||||
| This file is part of Cygwin. | ||||
|  | ||||
| @@ -14,4 +14,11 @@ details. */ | ||||
| #include <sys/fcntl.h> | ||||
| #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 */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user