symlink: open handles embedded symlinks

returns symlink_embedded=TRUE when the symlink isn't the last component, which gets passed to RxPrepareToReparseSymbolicLink()

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2010-09-29 13:11:27 -04:00 committed by unknown
parent a92fb8930e
commit e27299d066
3 changed files with 22 additions and 4 deletions

View file

@ -236,6 +236,17 @@ int handle_open(nfs41_upcall *upcall)
status = nfs41_lookup(args->root, nfs41_root_session(args->root), status = nfs41_lookup(args->root, nfs41_root_session(args->root),
&state->path, &state->parent, &state->file, &info, &state->session); &state->path, &state->parent, &state->file, &info, &state->session);
if (status == ERROR_REPARSE) {
/* one of the parent components was a symlink */
upcall->last_error = ERROR_REPARSE;
args->symlink_embedded = TRUE;
/* replace the path with the symlink target */
status = nfs41_symlink_follow(state->session,
&state->parent, &args->symlink);
goto out_free_state;
}
// now if file/dir exists, use type returned by lookup // now if file/dir exists, use type returned by lookup
if (status == NO_ERROR) { if (status == NO_ERROR) {
if (info.type == NF4DIR) { if (info.type == NF4DIR) {
@ -263,10 +274,11 @@ int handle_open(nfs41_upcall *upcall)
} else { } else {
/* tell the driver to call RxPrepareToReparseSymbolicLink() */ /* tell the driver to call RxPrepareToReparseSymbolicLink() */
upcall->last_error = ERROR_REPARSE; upcall->last_error = ERROR_REPARSE;
args->symlink_embedded = FALSE;
/* replace the path with the symlink target */ /* replace the path with the symlink target */
status = nfs41_symlink_follow(state->session, status = nfs41_symlink_follow(state->session,
&state->parent, &state->file, &args->symlink); &state->file, &args->symlink);
goto out_free_state; goto out_free_state;
} }
} else } else
@ -375,6 +387,8 @@ int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
if (status) goto out; if (status) goto out;
if (upcall->last_error == ERROR_REPARSE) { if (upcall->last_error == ERROR_REPARSE) {
unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR); unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR);
status = safe_write(&buffer, length, &args->symlink_embedded, sizeof(BOOLEAN));
if (status) goto out;
status = safe_write(&buffer, length, &len, sizeof(len)); status = safe_write(&buffer, length, &len, sizeof(len));
if (status) goto out; if (status) goto out;
/* convert args->symlink to wchar */ /* convert args->symlink to wchar */

View file

@ -55,6 +55,7 @@ typedef struct __open_upcall_args {
DWORD mode; DWORD mode;
LONGLONG changeattr; LONGLONG changeattr;
BOOLEAN created; BOOLEAN created;
BOOLEAN symlink_embedded;
} open_upcall_args; } open_upcall_args;
typedef struct __close_upcall_args { typedef struct __close_upcall_args {

View file

@ -162,6 +162,7 @@ typedef struct _updowncall_entry {
ULONG open_owner_id; ULONG open_owner_id;
DWORD mode; DWORD mode;
LONGLONG changeattr; LONGLONG changeattr;
BOOLEAN symlink_embedded;
} Open; } Open;
struct { struct {
HANDLE open_state; HANDLE open_state;
@ -1398,6 +1399,8 @@ nfs41_downcall (
RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(LONGLONG)); RtlCopyMemory(&cur->u.Open.changeattr, buf, sizeof(LONGLONG));
buf += sizeof(LONGLONG); buf += sizeof(LONGLONG);
if (tmp->errno == ERROR_REPARSE) { if (tmp->errno == ERROR_REPARSE) {
RtlCopyMemory(&cur->u.Open.symlink_embedded, buf, sizeof(BOOLEAN));
buf += sizeof(BOOLEAN);
RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, buf, sizeof(USHORT)); RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, buf, sizeof(USHORT));
buf += sizeof(USHORT); buf += sizeof(USHORT);
cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength - sizeof(WCHAR); cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength - sizeof(WCHAR);
@ -2666,9 +2669,9 @@ NTSTATUS nfs41_Create(
RtlCopyMemory(buf, entry->u.Open.symlink.Buffer, entry->u.Open.symlink.Length); RtlCopyMemory(buf, entry->u.Open.symlink.Buffer, entry->u.Open.symlink.Length);
status = RxPrepareToReparseSymbolicLink(RxContext, status = RxPrepareToReparseSymbolicLink(RxContext,
FALSE, &AbsPath, TRUE, &ReparseRequired); entry->u.Open.symlink_embedded, &AbsPath, TRUE, &ReparseRequired);
DbgP("RxPrepareToReparseSymbolicLink('%wZ') returned %08lX, " DbgP("RxPrepareToReparseSymbolicLink(%u, '%wZ') returned %08lX, "
"FileName is '%wZ'\n", "FileName is '%wZ'\n", entry->u.Open.symlink_embedded,
&AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName); &AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS)
status = ReparseRequired ? STATUS_REPARSE : status = ReparseRequired ? STATUS_REPARSE :