Re: [PATCH 09/11] mount.cc: Implement poor-man's cache

2021-02-03 Thread Ben



On 18-01-2021 12:51, Corinna Vinschen via Cygwin-patches wrote:
> Ok, so hash_prefix reduces the path to a drive letter or the UNC path
> prefix and hashes it.  However, what about partitions mounted to a
> subdir of, say, drive C?  In that case the hashing goes awry, because
> you're comparing with the hash of drive C while the path is actually
> pointing to another partition.
> 
How can I mount a partition as a subdir of drive C?
For some reason I can't:
$ mount /cygdrive/e/Temp/dummy /cygdrive/c/Temp/dummy/dummyone
mount: /cygdrive/c/Temp/dummy/dummyone: Invalid argument


Re: [PATCH v2 4/8] syscalls.cc: Implement non-path_conv dependent _unlink_nt

2021-02-03 Thread Ben



On 26-01-2021 12:34, Corinna Vinschen via Cygwin-patches wrote:
> 
> First of all, the new function should better get a new name.  The _nt
> postfix is pretty much historical anyway to differentiate between the
> function using Win32 API and the function using NT API.  This is kind
> of moot these days sine we're using the NT API almost exclusively for
> file access anyway.
> 
> So stick to unlink_nt/_unlink_nt for the existing functions, and name
> the new function accorind to it's  doings, like, say, unlink_path or
> whatever.
> 
Sure, I will rename them.


>> +  static bool has_posix_unlink_semantics =
>> +  wincap.has_posix_unlink_semantics ();
>> +  static bool has_posix_unlink_semantics_with_ignore_readonly =
>> +  wincap.has_posix_unlink_semantics_with_ignore_readonly ();
> 
> Did you mean `const' rather than `static', by any chance?  Either way, I
> don't think these local vars are required, given that the wincap
> accessors are already marked as const.  The compiler should know how to
> opimize this sufficiently.
> 
I do mean static.
With each instantiation these are initialized to the wincap value.
Then later on, we might disable the behavior if we encounter a driver
which returns: STATUS_INVALID_PARAMETER

Assuming most files will reside on the same fs, (ie through the same driver)
this will save use from the system call which we know isn't supported.


>> +
>> +  HANDLE fh;
>> +  ACCESS_MASK access = DELETE;
>> +  IO_STATUS_BLOCK io;
>> +  ULONG flags = FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT
>> +  | FILE_DELETE_ON_CLOSE | eflags;
> 
> This looks like a dangerous assumption.  So far we don't open unknown
> reparse points as reparse points deliberately.  No one knows what a
> unknown reparse point is good for or supposed to do, so we don't even
> know if we are allowed to handle it analogue to a symlink.
> 
When opening these, you are correct.
However, when a request is made to delete a reparse point, it's safe
- even for an unknown reparse point - to assume that it is the reparse point
itself which is to be deleted. Ofcourse: That's my theory.


> Consequentially we open unknown reparse points just as normal files, so
> that the reparse point's automatisms may kick in.  By omitting this
> step, we're moving on thin ice.
> 
This would mean an unknown reparse point can never be deleted.
I'm just not sure if that's what we should want.


>> +{
>> +  //Step 2
>> +  //Reopen with all sharing flags, will set delete flag ourselves.
>> +  access |= FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES;
>> +  flags &= ~FILE_DELETE_ON_CLOSE;
>> +  fstatus = NtOpenFile (, access, attr, , FILE_SHARE_VALID_FLAGS, 
>> flags);
>> +  debug_printf ("NtOpenFile %S: %y", attr->ObjectName, fstatus);
>> +
>> +  if (NT_SUCCESS (fstatus))
>> +{
>> +  if (has_posix_unlink_semantics_with_ignore_readonly)
>> +{
>> +  //Step 3
>> +  //Remove the file with POSIX unlink semantics, ignore 
>> readonly flags.
> 
> No check for NTFS?  Posix semantics are not supported on any other FS.
> No check for remote?  Just because you support POSIX semantics on
> *this* machine, doesn't mean the remote machine supports it at all...
> 
Indeed no checks.
If the driver correctly returns STATUS_INVALID_PARAMETER we will not try again 
(by
resetting the has_posix_unlink_semantics_with_ignore_readonly flag and then 
fallback to
usual trickery. If the driver returns error (but not STATUS_INVALID_PARAMETER) 
that
driver pays a single kernel call, which I deem acceptable.


>> +  FILE_DISPOSITION_INFORMATION_EX fdie =
>> +{ FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS
>> +| FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE };
>> +  istatus = NtSetInformationFile (fh, , , sizeof fdie,
>> +  FileDispositionInformationEx);
>> +  debug_printf ("NtSetInformation %S: %y", attr->ObjectName, 
>> istatus);
>> +
>> +  if(istatus == STATUS_INVALID_PARAMETER)
>> +has_posix_unlink_semantics_with_ignore_readonly = false;
>> +}
>> +
>> +  if (!has_posix_unlink_semantics_with_ignore_readonly
>> +  || !NT_SUCCESS (istatus))
>> +{
>> +  //Step 4
>> +  //Check if we must clear the READONLY flag
>> +  FILE_BASIC_INFORMATION qfbi = { 0 };
>> +  istatus = NtQueryInformationFile (fh, , , sizeof qfbi,
>> +FileBasicInformation);
>> +  debug_printf ("NtQueryFileBasicInformation %S: %y",
>> +attr->ObjectName, istatus);
>> +
>> +  if (NT_SUCCESS (istatus))
>> +{
>> +  if (qfbi.FileAttributes & FILE_ATTRIBUTE_READONLY)
>> +{
>> +  //Step 5
>> +