symlink: rename and link handle ERROR_REPARSE
when rename or link call nfs41_lookup() for the destination directory, they need to be able to handle ERROR_REPARSE and find the real dest dir open now does the same thing when it sees ERROR_REPARSE; previously, it was only replacing the first symlink in the path, and could require multiple reparses on a path modified nfs41_symlink_target() to support the case where the source and destination paths are the same (used by rename/link) Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
e37b33a4df
commit
1ad1c0f262
3 changed files with 49 additions and 19 deletions
|
|
@ -113,29 +113,31 @@ int nfs41_symlink_target(
|
|||
|
||||
dprintf(2, "--> nfs41_symlink_target('%s', '%s')\n", path->path, link);
|
||||
|
||||
/* append any components after the symlink */
|
||||
if (FAILED(StringCchCatA(link, NFS41_MAX_PATH_LEN,
|
||||
file->name.name + file->name.len))) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
link_len = (uint32_t)strlen(link);
|
||||
|
||||
/* overwrite the last component of the path; get the starting offset */
|
||||
path_offset = file->name.name - path->path;
|
||||
|
||||
/* copy the path and update it with the results from link */
|
||||
target->len = path->len;
|
||||
if (FAILED(StringCchCopyNA(target->path, NFS41_MAX_PATH_LEN,
|
||||
path->path, path->len))) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out;
|
||||
if (target != path) {
|
||||
target->len = path->len;
|
||||
if (FAILED(StringCchCopyNA(target->path, NFS41_MAX_PATH_LEN,
|
||||
path->path, path->len))) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
status = abs_path_link(target, target->path + path_offset, link, link_len);
|
||||
if (status) {
|
||||
eprintf("abs_path_link() failed with %d\n", status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* append any components after the symlink */
|
||||
if (FAILED(StringCchCopyA(target->path + target->len,
|
||||
NFS41_MAX_PATH_LEN - target->len, file->name.name + file->name.len))) {
|
||||
status = ERROR_BUFFER_OVERFLOW;
|
||||
goto out;
|
||||
}
|
||||
target->len = (unsigned short)strlen(target->path);
|
||||
out:
|
||||
dprintf(2, "<-- nfs41_symlink_target('%s') returning %d\n",
|
||||
target->path, status);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue