Module: wine Branch: master Commit: 5514df9d4e4c14cafcc4284e12d26ad6c74709fe URL: http://source.winehq.org/git/wine.git/?a=commit;h=5514df9d4e4c14cafcc4284e12...
Author: Ken Thomases ken@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;