Ken Thomases : ntdll: Avoid one of the calls to getattrlist() when read_directory_getattrlist() checks the case sensitivity of the file system.

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 22 04:48:24 CDT 2015


Module: wine
Branch: master
Commit: 5514df9d4e4c14cafcc4284e12d26ad6c74709fe
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5514df9d4e4c14cafcc4284e12d26ad6c74709fe

Author: Ken Thomases <ken at codeweavers.com>
Date:   Thu May 21 11:13:35 2015 -0500

ntdll: Avoid one of the calls to getattrlist() when read_directory_getattrlist() checks the case sensitivity of the file system.

Extract a new function, get_dir_case_sensitivity_attr_by_id(), from
get_dir_case_sensitivity_attr().  Call that instead of get_dir_case_sensitivity()
from read_directory_getattrlist().  We get the device and file system IDs from
the same getattrlist() call we're already doing, so that avoids an extra call.

---

 dlls/ntdll/directory.c | 62 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 22 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 8e4db83..cd9fdb0 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -983,43 +983,35 @@ static void add_fs_cache( dev_t dev, fsid_t fsid, BOOLEAN case_sensitive )
 }
 
 /***********************************************************************
- *           get_dir_case_sensitivity_attr
+ *           get_dir_case_sensitivity_attr_by_id
  *
- * Checks if the volume containing the specified directory is case
- * sensitive or not. Uses getattrlist(2).
+ * Checks if the volume with the specified device and file system IDs
+ * is case sensitive or not. Uses getattrlist(2).
  */
-static int get_dir_case_sensitivity_attr( const char *dir )
+static int get_dir_case_sensitivity_attr_by_id( dev_t dev, fsid_t fsid )
 {
     char *mntpoint = NULL;
     struct attrlist attr;
     struct vol_caps caps;
-    struct get_fsid get_fsid;
     struct fs_cache *entry;
 
-    /* First get the FS ID of the volume */
-    attr.bitmapcount = ATTR_BIT_MAP_COUNT;
-    attr.reserved = 0;
-    attr.commonattr = ATTR_CMN_DEVID|ATTR_CMN_FSID;
-    attr.volattr = attr.dirattr = attr.fileattr = attr.forkattr = 0;
-    get_fsid.size = 0;
-    if (getattrlist( dir, &attr, &get_fsid, sizeof(get_fsid), 0 ) != 0 ||
-        get_fsid.size != sizeof(get_fsid))
-        return -1;
     /* Try to look it up in the cache */
-    entry = look_up_fs_cache( get_fsid.dev );
-    if (entry && !memcmp( &entry->fsid, &get_fsid.fsid, sizeof(fsid_t) ))
+    entry = look_up_fs_cache( dev );
+    if (entry && !memcmp( &entry->fsid, &fsid, sizeof(fsid_t) ))
         /* Cache lookup succeeded */
         return entry->case_sensitive;
     /* Cache is stale at this point, we have to update it */
 
-    mntpoint = get_device_mount_point( get_fsid.dev );
+    mntpoint = get_device_mount_point( dev );
     /* Now look up the case-sensitivity */
-    attr.commonattr = 0;
+    attr.bitmapcount = ATTR_BIT_MAP_COUNT;
+    attr.reserved = attr.commonattr = 0;
     attr.volattr = ATTR_VOL_INFO|ATTR_VOL_CAPABILITIES;
+    attr.dirattr = attr.fileattr = attr.forkattr = 0;
     if (getattrlist( mntpoint, &attr, &caps, sizeof(caps), 0 ) < 0)
     {
         RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
-        add_fs_cache( get_fsid.dev, get_fsid.fsid, TRUE );
+        add_fs_cache( dev, fsid, TRUE );
         return TRUE;
     }
     RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
@@ -1036,11 +1028,34 @@ static int get_dir_case_sensitivity_attr( const char *dir )
         else
             ret = TRUE;
         /* Update the cache */
-        add_fs_cache( get_fsid.dev, get_fsid.fsid, ret );
+        add_fs_cache( dev, fsid, ret );
         return ret;
     }
     return FALSE;
 }
+
+/***********************************************************************
+ *           get_dir_case_sensitivity_attr
+ *
+ * Checks if the volume containing the specified directory is case
+ * sensitive or not. Uses getattrlist(2).
+ */
+static int get_dir_case_sensitivity_attr( const char *dir )
+{
+    struct attrlist attr;
+    struct get_fsid get_fsid;
+
+    /* First get the FS ID of the volume */
+    attr.bitmapcount = ATTR_BIT_MAP_COUNT;
+    attr.reserved = 0;
+    attr.commonattr = ATTR_CMN_DEVID|ATTR_CMN_FSID;
+    attr.volattr = attr.dirattr = attr.fileattr = attr.forkattr = 0;
+    get_fsid.size = 0;
+    if (getattrlist( dir, &attr, &get_fsid, sizeof(get_fsid), 0 ) != 0 ||
+        get_fsid.size != sizeof(get_fsid))
+        return -1;
+    return get_dir_case_sensitivity_attr_by_id( get_fsid.dev, get_fsid.fsid );
+}
 #endif
 
 /***********************************************************************
@@ -2148,6 +2163,8 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
     {
         u_int32_t length;
         struct attrreference name_reference;
+        dev_t devid;
+        fsid_t fsid;
         fsobj_type_t type;
         char name[NAME_MAX * 3 + 1];
     } attrlist_buffer;
@@ -2179,7 +2196,7 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
 
         memset( &attrlist, 0, sizeof(attrlist) );
         attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
-        attrlist.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJTYPE;
+        attrlist.commonattr = ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_FSID | ATTR_CMN_OBJTYPE;
         ret = getattrlist( unix_name, &attrlist, &attrlist_buffer, sizeof(attrlist_buffer), FSOPT_NOFOLLOW );
         /* If unix_name named a symlink, the above may have succeeded even if the symlink is broken.
            Check that with another call without FSOPT_NOFOLLOW.  We don't ask for any attributes. */
@@ -2199,7 +2216,8 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
             }
             else io->u.Status = STATUS_NO_MORE_FILES;
         }
-        else if ((errno == ENOENT || errno == ENOTDIR) && !get_dir_case_sensitivity("."))
+        else if ((errno == ENOENT || errno == ENOTDIR) &&
+                 !get_dir_case_sensitivity_attr_by_id( attrlist_buffer.devid, attrlist_buffer.fsid ))
         {
             io->u.Status = STATUS_NO_MORE_FILES;
             ret = 0;




More information about the wine-cvs mailing list