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.
This commit is contained in:
parent
dec7b246f8
commit
5514df9d4e
|
@ -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
|
* Checks if the volume with the specified device and file system IDs
|
||||||
* sensitive or not. Uses getattrlist(2).
|
* 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;
|
char *mntpoint = NULL;
|
||||||
struct attrlist attr;
|
struct attrlist attr;
|
||||||
struct vol_caps caps;
|
struct vol_caps caps;
|
||||||
struct get_fsid get_fsid;
|
|
||||||
struct fs_cache *entry;
|
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 */
|
/* Try to look it up in the cache */
|
||||||
entry = look_up_fs_cache( get_fsid.dev );
|
entry = look_up_fs_cache( dev );
|
||||||
if (entry && !memcmp( &entry->fsid, &get_fsid.fsid, sizeof(fsid_t) ))
|
if (entry && !memcmp( &entry->fsid, &fsid, sizeof(fsid_t) ))
|
||||||
/* Cache lookup succeeded */
|
/* Cache lookup succeeded */
|
||||||
return entry->case_sensitive;
|
return entry->case_sensitive;
|
||||||
/* Cache is stale at this point, we have to update it */
|
/* 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 */
|
/* 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.volattr = ATTR_VOL_INFO|ATTR_VOL_CAPABILITIES;
|
||||||
|
attr.dirattr = attr.fileattr = attr.forkattr = 0;
|
||||||
if (getattrlist( mntpoint, &attr, &caps, sizeof(caps), 0 ) < 0)
|
if (getattrlist( mntpoint, &attr, &caps, sizeof(caps), 0 ) < 0)
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
|
RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
|
||||||
add_fs_cache( get_fsid.dev, get_fsid.fsid, TRUE );
|
add_fs_cache( dev, fsid, TRUE );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
|
RtlFreeHeap( GetProcessHeap(), 0, mntpoint );
|
||||||
|
@ -1036,11 +1028,34 @@ static int get_dir_case_sensitivity_attr( const char *dir )
|
||||||
else
|
else
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
/* Update the cache */
|
/* Update the cache */
|
||||||
add_fs_cache( get_fsid.dev, get_fsid.fsid, ret );
|
add_fs_cache( dev, fsid, ret );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return FALSE;
|
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
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2148,6 +2163,8 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
|
||||||
{
|
{
|
||||||
u_int32_t length;
|
u_int32_t length;
|
||||||
struct attrreference name_reference;
|
struct attrreference name_reference;
|
||||||
|
dev_t devid;
|
||||||
|
fsid_t fsid;
|
||||||
fsobj_type_t type;
|
fsobj_type_t type;
|
||||||
char name[NAME_MAX * 3 + 1];
|
char name[NAME_MAX * 3 + 1];
|
||||||
} attrlist_buffer;
|
} attrlist_buffer;
|
||||||
|
@ -2179,7 +2196,7 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
|
||||||
|
|
||||||
memset( &attrlist, 0, sizeof(attrlist) );
|
memset( &attrlist, 0, sizeof(attrlist) );
|
||||||
attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
|
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 );
|
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.
|
/* 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. */
|
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 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;
|
io->u.Status = STATUS_NO_MORE_FILES;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
Loading…
Reference in New Issue