symlink: retry open when ReparseRequired=false
according to msdn documentation for RxPrepareToReparseSymbolicLink(), setting ReparseRequired=FALSE means that the link itself should be opened instead of its target. this shows up when cygwin attempts to delete or rename a symbolic link, because it doesn't open the file with the FILE_OPEN_REPARSE_POINT flag when RxPrepareToReparseSymbolicLink() returns success but with ReparseRequired=FALSE, set the FILE_OPEN_REPARSE_POINT flag and resend the open upcall Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
1a5f3cb3a1
commit
f841d14eac
1 changed files with 12 additions and 3 deletions
|
|
@ -3672,6 +3672,7 @@ NTSTATUS nfs41_Create(
|
||||||
entry->u.Open.symlink.Buffer = (PWCH)(ea->EaName + ea->EaNameLength + 1);
|
entry->u.Open.symlink.Buffer = (PWCH)(ea->EaName + ea->EaNameLength + 1);
|
||||||
entry->u.Open.symlink.MaximumLength = entry->u.Open.symlink.Length = ea->EaValueLength;
|
entry->u.Open.symlink.MaximumLength = entry->u.Open.symlink.Length = ea->EaValueLength;
|
||||||
}
|
}
|
||||||
|
retry_on_link:
|
||||||
if (ea && create_should_pass_ea(ea, params->Disposition)) {
|
if (ea && create_should_pass_ea(ea, params->Disposition)) {
|
||||||
/* lock the extended attribute buffer for read access in user space */
|
/* lock the extended attribute buffer for read access in user space */
|
||||||
entry->u.Open.EaMdl = IoAllocateMdl(ea,
|
entry->u.Open.EaMdl = IoAllocateMdl(ea,
|
||||||
|
|
@ -3742,9 +3743,17 @@ NTSTATUS nfs41_Create(
|
||||||
"FileName is '%wZ'\n", entry->u.Open.symlink_embedded,
|
"FileName is '%wZ'\n", entry->u.Open.symlink_embedded,
|
||||||
&AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
|
&AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
|
||||||
#endif
|
#endif
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS) {
|
||||||
status = ReparseRequired ? STATUS_REPARSE :
|
/* if a reparse is not required, reopen the link itself. this
|
||||||
STATUS_OBJECT_PATH_NOT_FOUND;
|
* happens with operations on cygwin symlinks, where the reparse
|
||||||
|
* flag is not set */
|
||||||
|
if (!ReparseRequired) {
|
||||||
|
entry->u.Open.symlink.Length = 0;
|
||||||
|
entry->u.Open.copts |= FILE_OPEN_REPARSE_POINT;
|
||||||
|
goto retry_on_link;
|
||||||
|
}
|
||||||
|
status = STATUS_REPARSE;
|
||||||
|
}
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue