mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added ntdll-ext4-case-folder patchset
This commit is contained in:
parent
a49aa40ac8
commit
1d3c799e6f
@ -0,0 +1,189 @@
|
||||
From ca8e866f9653e4c045a9c59759a0d2400d4dfc2c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= <gabrielopcode@gmail.com>
|
||||
Date: Fri, 24 May 2019 15:09:34 +0300
|
||||
Subject: [PATCH 1/2] ntdll/directory: Add support for EXT4 case folding per
|
||||
directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This adds support for checking the case-insensitive attribute on ext4 with
|
||||
newer kernels so that Wine can rely on it for performance.
|
||||
|
||||
It has some conditional processing for perf reasons. Checking for the
|
||||
EXT4_CASEFOLD_FL attribute involves an ioctl, which operates on file
|
||||
descriptors, while all the former checks operated directly on the dir pathname
|
||||
(e.g. statfs).
|
||||
|
||||
Obviously, it's best to avoid looking up the directory multiple times (also
|
||||
for correctness, so it refers to the same dir). So in the case that we *do*
|
||||
have a file descriptor, then use it everywhere, with e.g. fstatfs.
|
||||
|
||||
However, to avoid a perf regression or downgrade on systems that don't
|
||||
support the EXT2_IOC_GETFLAGS ioctl (e.g. MacOS, FreeBSD), we continue
|
||||
using statfs and the like directly, this shaves off two syscalls (open/close).
|
||||
|
||||
But in the case the EXT4_CASEFOLD_FL is not supported on Linux (i.e. on
|
||||
current kernels) or the directory doesn't have it, this will unfortunately
|
||||
involve a bit more syscalls now, because it has to open() and close() the fd,
|
||||
but it shouldn't be too much of a problem. (the fstatfs and fstatat make it
|
||||
less impactful somewhat, so they won't have to lookup the directory again,
|
||||
hopefully mitigating some of it)
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47099
|
||||
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
|
||||
---
|
||||
dlls/ntdll/directory.c | 73 +++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 65 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
|
||||
index bbdbbe9781..354c00f7eb 100644
|
||||
--- a/dlls/ntdll/directory.c
|
||||
+++ b/dlls/ntdll/directory.c
|
||||
@@ -115,6 +115,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
|
||||
|
||||
/* just in case... */
|
||||
#undef VFAT_IOCTL_READDIR_BOTH
|
||||
+#undef EXT2_IOC_GETFLAGS
|
||||
+#undef EXT4_CASEFOLD_FL
|
||||
|
||||
#ifdef linux
|
||||
|
||||
@@ -130,12 +132,25 @@ typedef struct
|
||||
/* Define the VFAT ioctl to get both short and long file names */
|
||||
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, KERNEL_DIRENT [2] )
|
||||
|
||||
+/* Define the ext2 ioctl for handling extra attributes */
|
||||
+#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
|
||||
+
|
||||
+/* Case-insensitivity attribute */
|
||||
+#define EXT4_CASEFOLD_FL 0x40000000
|
||||
+
|
||||
#ifndef O_DIRECTORY
|
||||
# define O_DIRECTORY 0200000 /* must be directory */
|
||||
#endif
|
||||
|
||||
#endif /* linux */
|
||||
|
||||
+/* Use a file descriptor for the case-sensitivity check if we have to */
|
||||
+#if defined(EXT2_IOC_GETFLAGS) && defined(EXT4_CASEFOLD_FL)
|
||||
+#define GET_DIR_CASE_SENSITIVITY_USE_FD 1
|
||||
+#else
|
||||
+#define GET_DIR_CASE_SENSITIVITY_USE_FD 0
|
||||
+#endif
|
||||
+
|
||||
#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
|
||||
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
|
||||
|
||||
@@ -1109,18 +1124,35 @@ static int get_dir_case_sensitivity_attr( const char *dir )
|
||||
}
|
||||
#endif
|
||||
|
||||
+/***********************************************************************
|
||||
+ * get_dir_case_sensitivity_ioctl
|
||||
+ *
|
||||
+ * Checks if the specified directory is case sensitive or not. Uses ioctl(2).
|
||||
+ */
|
||||
+static int get_dir_case_sensitivity_ioctl(int fd)
|
||||
+{
|
||||
+#if defined(EXT2_IOC_GETFLAGS) && defined(EXT4_CASEFOLD_FL)
|
||||
+ int flags;
|
||||
+ if (ioctl(fd, EXT2_IOC_GETFLAGS, &flags) != -1 && (flags & EXT4_CASEFOLD_FL))
|
||||
+ return FALSE;
|
||||
+#endif
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* get_dir_case_sensitivity_stat
|
||||
*
|
||||
* Checks if the volume containing the specified directory is case
|
||||
- * sensitive or not. Uses statfs(2) or statvfs(2).
|
||||
+ * sensitive or not. Uses (f)statfs(2), (f)statvfs(2), or fstatat(2).
|
||||
*/
|
||||
-static BOOLEAN get_dir_case_sensitivity_stat( const char *dir )
|
||||
+static BOOLEAN get_dir_case_sensitivity_stat( const char *dir, int fd )
|
||||
{
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
struct statfs stfs;
|
||||
|
||||
- if (statfs( dir, &stfs ) == -1) return FALSE;
|
||||
+ if (fd != -1 && fstatfs( fd, &stfs ) == -1) return FALSE;
|
||||
+ if (fd == -1 && statfs( dir, &stfs ) == -1) return FALSE;
|
||||
+
|
||||
/* Assume these file systems are always case insensitive on Mac OS.
|
||||
* For FreeBSD, only assume CIOPFS is case insensitive (AFAIK, Mac OS
|
||||
* is the only UNIX that supports case-insensitive lookup).
|
||||
@@ -1157,7 +1189,9 @@ static BOOLEAN get_dir_case_sensitivity_stat( const char *dir )
|
||||
#elif defined(__NetBSD__)
|
||||
struct statvfs stfs;
|
||||
|
||||
- if (statvfs( dir, &stfs ) == -1) return FALSE;
|
||||
+ if (fd != -1 && fstatvfs( fd, &stfs ) == -1) return FALSE;
|
||||
+ if (fd == -1 && statvfs( dir, &stfs ) == -1) return FALSE;
|
||||
+
|
||||
/* Only assume CIOPFS is case insensitive. */
|
||||
if (strcmp( stfs.f_fstypename, "fusefs" ) ||
|
||||
strncmp( stfs.f_mntfromname, "ciopfs", 5 ))
|
||||
@@ -1170,7 +1204,9 @@ static BOOLEAN get_dir_case_sensitivity_stat( const char *dir )
|
||||
char *cifile;
|
||||
|
||||
/* Only assume CIOPFS is case insensitive. */
|
||||
- if (statfs( dir, &stfs ) == -1) return FALSE;
|
||||
+ if (fd != -1 && fstatfs( fd, &stfs ) == -1) return FALSE;
|
||||
+ if (fd == -1 && statfs( dir, &stfs ) == -1) return FALSE;
|
||||
+
|
||||
if (stfs.f_type != 0x65735546 /* FUSE_SUPER_MAGIC */)
|
||||
return TRUE;
|
||||
/* Normally, we'd have to parse the mtab to find out exactly what
|
||||
@@ -1180,6 +1216,13 @@ static BOOLEAN get_dir_case_sensitivity_stat( const char *dir )
|
||||
* This will break if somebody puts a file named ".ciopfs" in a non-
|
||||
* CIOPFS directory.
|
||||
*/
|
||||
+ if (fd != -1)
|
||||
+ {
|
||||
+ if (fstatat( fd, ".ciopfs", &st, AT_NO_AUTOMOUNT ) == 0)
|
||||
+ return FALSE;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+
|
||||
cifile = RtlAllocateHeap( GetProcessHeap(), 0, strlen( dir )+sizeof("/.ciopfs") );
|
||||
if (!cifile) return TRUE;
|
||||
strcpy( cifile, dir );
|
||||
@@ -1201,16 +1244,30 @@ static BOOLEAN get_dir_case_sensitivity_stat( const char *dir )
|
||||
* get_dir_case_sensitivity
|
||||
*
|
||||
* Checks if the volume containing the specified directory is case
|
||||
- * sensitive or not. Uses statfs(2) or statvfs(2).
|
||||
+ * sensitive or not. Uses multiple methods, depending on platform.
|
||||
*/
|
||||
static BOOLEAN get_dir_case_sensitivity( const char *dir )
|
||||
{
|
||||
+ int case_sensitive, fd = -1;
|
||||
+
|
||||
#if defined(HAVE_GETATTRLIST) && defined(ATTR_VOL_CAPABILITIES) && \
|
||||
defined(VOL_CAPABILITIES_FORMAT) && defined(VOL_CAP_FMT_CASE_SENSITIVE)
|
||||
- int case_sensitive = get_dir_case_sensitivity_attr( dir );
|
||||
+ case_sensitive = get_dir_case_sensitivity_attr( dir );
|
||||
if (case_sensitive != -1) return case_sensitive;
|
||||
#endif
|
||||
- return get_dir_case_sensitivity_stat( dir );
|
||||
+
|
||||
+ if (GET_DIR_CASE_SENSITIVITY_USE_FD)
|
||||
+ {
|
||||
+ if ((fd = open(dir, O_RDONLY | O_NONBLOCK | O_LARGEFILE)) == -1)
|
||||
+ return TRUE;
|
||||
+ if ((case_sensitive = get_dir_case_sensitivity_ioctl(fd)) != -1)
|
||||
+ goto end;
|
||||
+ }
|
||||
+ case_sensitive = get_dir_case_sensitivity_stat(dir, fd);
|
||||
+
|
||||
+end:
|
||||
+ if (fd != -1) close(fd);
|
||||
+ return case_sensitive;
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,94 @@
|
||||
From f794872f3ba2bd78afea1df2f353846a7f5e5788 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= <gabrielopcode@gmail.com>
|
||||
Date: Fri, 24 May 2019 15:09:35 +0300
|
||||
Subject: [PATCH] ntdll/server: Mark drive_c as case-insensitive when created
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47099
|
||||
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
|
||||
---
|
||||
dlls/ntdll/server.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 45 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index dcb355a6534..aca93509639 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -51,6 +51,12 @@
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_IOCTL_H
|
||||
+#include <sys/ioctl.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_LINUX_IOCTL_H
|
||||
+#include <linux/ioctl.h>
|
||||
+#endif
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
# include <sys/prctl.h>
|
||||
#endif
|
||||
@@ -86,6 +92,22 @@
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(server);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
+/* just in case... */
|
||||
+#undef EXT2_IOC_GETFLAGS
|
||||
+#undef EXT2_IOC_SETFLAGS
|
||||
+#undef EXT4_CASEFOLD_FL
|
||||
+
|
||||
+#ifdef __linux__
|
||||
+
|
||||
+/* Define the ext2 ioctls for handling extra attributes */
|
||||
+#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
|
||||
+#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
|
||||
+
|
||||
+/* Case-insensitivity attribute */
|
||||
+#define EXT4_CASEFOLD_FL 0x40000000
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/* Some versions of glibc don't define this */
|
||||
#ifndef SCM_RIGHTS
|
||||
#define SCM_RIGHTS 1
|
||||
@@ -1248,6 +1270,28 @@ static void start_server(void)
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * set_case_insensitive
|
||||
+ *
|
||||
+ * Make the supplied directory case insensitive, if available.
|
||||
+ */
|
||||
+static void set_case_insensitive(const char *dir)
|
||||
+{
|
||||
+#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(EXT4_CASEFOLD_FL)
|
||||
+ int flags, fd;
|
||||
+
|
||||
+ if ((fd = open(dir, O_RDONLY | O_NONBLOCK | O_LARGEFILE)) == -1)
|
||||
+ return;
|
||||
+ if (ioctl(fd, EXT2_IOC_GETFLAGS, &flags) != -1 && !(flags & EXT4_CASEFOLD_FL))
|
||||
+ {
|
||||
+ flags |= EXT4_CASEFOLD_FL;
|
||||
+ ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
|
||||
+ }
|
||||
+ close(fd);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* setup_config_dir
|
||||
*
|
||||
@@ -1291,6 +1335,7 @@ static int setup_config_dir(void)
|
||||
/* create the drive symlinks */
|
||||
|
||||
mkdir( "drive_c", 0777 );
|
||||
+ set_case_insensitive( "drive_c" );
|
||||
symlink( "../drive_c", "dosdevices/c:" );
|
||||
symlink( "/", "dosdevices/z:" );
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
1
patches/ntdll-ext4-case-folder/definition
Normal file
1
patches/ntdll-ext4-case-folder/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [47099] Support for EXT4 case folding per directory.
|
@ -221,6 +221,7 @@ patch_enable_all ()
|
||||
enable_ntdll_Wait_User_APC="$1"
|
||||
enable_ntdll_Zero_mod_name="$1"
|
||||
enable_ntdll_aarch_TEB="$1"
|
||||
enable_ntdll_ext4_case_folder="$1"
|
||||
enable_ntdll_set_full_cpu_context="$1"
|
||||
enable_ntoskrnl_Stubs="$1"
|
||||
enable_nvapi_Stub_DLL="$1"
|
||||
@ -788,6 +789,9 @@ patch_enable ()
|
||||
ntdll-aarch-TEB)
|
||||
enable_ntdll_aarch_TEB="$2"
|
||||
;;
|
||||
ntdll-ext4-case-folder)
|
||||
enable_ntdll_ext4_case_folder="$2"
|
||||
;;
|
||||
ntdll-set_full_cpu_context)
|
||||
enable_ntdll_set_full_cpu_context="$2"
|
||||
;;
|
||||
@ -4967,6 +4971,23 @@ if test "$enable_ntdll_aarch_TEB" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-ext4-case-folder
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#47099] Support for EXT4 case folding per directory.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/directory.c, dlls/ntdll/server.c
|
||||
# |
|
||||
if test "$enable_ntdll_ext4_case_folder" -eq 1; then
|
||||
patch_apply ntdll-ext4-case-folder/0001-ntdll-directory-Add-support-for-EXT4-case-folding-pe.patch
|
||||
patch_apply ntdll-ext4-case-folder/0002-ntdll-server-Mark-drive_c-as-case-insensitive-when-c.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Gabriel Ivăncescu", "ntdll/directory: Add support for EXT4 case folding per directory.", 1 },';
|
||||
printf '%s\n' '+ { "Gabriel Ivăncescu", "ntdll/server: Mark drive_c as case-insensitive when created.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-set_full_cpu_context
|
||||
# |
|
||||
# | Modified files:
|
||||
|
Loading…
Reference in New Issue
Block a user