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:
Casey Bodley 2012-05-09 12:48:32 -04:00 committed by Olga Kornievskaia
parent 1a5f3cb3a1
commit f841d14eac

View file

@ -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;
} }