Not having to query file information improves unlink speed. --- winsup/cygwin/syscalls.cc | 78 ++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 26 deletions(-)
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index ab0c4c2d6..b5ab6ac5e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1272,6 +1272,28 @@ _unlink_ntpc_ (path_conv& pc, bool shareable) return status; } +NTSTATUS +unlink_nt (const char *ourname, ULONG eflags) +{ + uint32_t opt = PC_SYM_NOFOLLOW | PC_SKIP_SYM_CHECK | PC_SKIP_FS_CHECK; + if (!(eflags & FILE_NON_DIRECTORY_FILE)) + opt &= ~PC_SKIP_FS_CHECK; + + path_conv pc (ourname, opt, NULL); + if (pc.error || pc.isspecial ()) + return STATUS_CANNOT_DELETE; + + OBJECT_ATTRIBUTES attr; + PUNICODE_STRING ntpath = pc.get_nt_native_path (); + InitializeObjectAttributes(&attr, ntpath, 0, NULL, NULL); + NTSTATUS status = _unlink_nt (&attr, eflags); + + if (!(eflags & FILE_NON_DIRECTORY_FILE)) + status = _unlink_nt_post_dir_check (status, &attr, pc); + + return status; +} + NTSTATUS unlink_ntpc (path_conv &pc) { @@ -1289,37 +1311,41 @@ unlink (const char *ourname) { int res = -1; dev_t devn; - NTSTATUS status; + NTSTATUS status = unlink_nt (ourname, FILE_NON_DIRECTORY_FILE); - path_conv win32_name (ourname, PC_SYM_NOFOLLOW, stat_suffixes); + if (!NT_SUCCESS (status)) + { + path_conv win32_name (ourname, PC_SYM_NOFOLLOW, stat_suffixes); - if (win32_name.error) - { - set_errno (win32_name.error); - goto done; - } + if (win32_name.error) + { + set_errno (win32_name.error); + goto done; + } - devn = win32_name.get_device (); - if (isproc_dev (devn)) - { - set_errno (EROFS); - goto done; - } + devn = win32_name.get_device (); + if (isproc_dev (devn)) + { + set_errno (EROFS); + goto done; + } - if (!win32_name.exists ()) - { - debug_printf ("unlinking a nonexistent file"); - set_errno (ENOENT); - goto done; - } - else if (win32_name.isdir ()) - { - debug_printf ("unlinking a directory"); - set_errno (EISDIR); - goto done; - } + if (!win32_name.exists ()) + { + debug_printf ("unlinking a nonexistent file"); + set_errno (ENOENT); + goto done; + } + else if (win32_name.isdir ()) + { + debug_printf ("unlinking a directory"); + set_errno (EISDIR); + goto done; + } + + status = unlink_ntpc (win32_name); + } - status = unlink_ntpc (win32_name); if (NT_SUCCESS (status)) res = 0; else -- 2.30.0