if the thread placing an upcall was woken up from the sleep, but have not been picked up by the daemon thread from the upcall queue, we would just cancel the upcall. thus nfsd would never see it. however, it was causing leaks in the open state. we would allocate open state but matching close would never make it to the daemon.
instead, always place an upcall to the daemon, but mark it that nobody is waiting for it if the requesting thread gets interrupted and goes away.
while following symlinks on open, after we break from the loop we need to respect that nfs41_lookup could have returned some kind of error value. thus only return error_reparse if nfs41_lookup returned success or file_not_found error.
similarly in after calling nfs41_symlink_follow() only set the reparse_error if function was successful.
fixed a few cases of warning 4242: possible loss of data
wincrypt.h appears to come with windows.h in later versions of the ddk, but nfs41_client.c fails to compile in WDK 6001 without #include <wincrypt.h>
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
nfs_install was failing to build in 'free' configurations because of warning 4711: function 'foo' selected for automatic inline expansion
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
specified requirement of 64-bit version of Windows Vista or later
clarified which commands are run from the Cygwin shell, Windows command prompt, or WinDDK build environment
adding instructions for applying patches to connectathon
added known issue regarding AUTH_SYS
added which connectathon tests have been disabled in known issues
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
avoid calling map_disposition_2_nfsopen() for this, because FILE_CREATE->ERROR_FILE_EXISTS is the only case we care about
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
/* msdn: There is a maximum of 31 reparse points (and
* therefore symbolic links) allowed in a particular path. */
#define NFS41_MAX_SYMLINK_DEPTH 31
also added checks for the return value of nfs41_symlink_target() on open/link/rename
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
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>
added nfs41_file_info.symlink_dir to replace readdir's info.cansettime hack. when nfs_file_info_to_attributes() finds info.type==NF4LNK, it adds the FILE_ATTRIBUTE_DIRECTORY flag if info.symlink_dir is set
renamed nfs41_symlink_follow() to nfs41_symlink_target()
generalized lookup_symlink() into nfs41_symlink_follow(), which is called by readdir and open (also avoids an extra lookup)
added queries for symlink target type when doing normal GETATTRs (getattr.c) and opens with OPEN_REPARSE_POINT set (open.c)
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
instead of using the netroot name, use the vnetroot name (which includes \;Y:\) so that reparse requests go to the same vnetroot. was seeing it create new vnetroots otherwise
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
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>
modified nfs41_lookup() to handle NFS4ERR_SYMLINK by setting parent=symlink and returning ERROR_REPARSE
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
windows differentiates between directory and file symlinks because a file can have both FILE_ATTRIBUTE_DIRECTORY and FILE_ATTRIBUTE_REPARSE_POINT flags. nfs can only be one of NF4REG/DIR/LNK, so we have to do a readlink and look up the target file for symlinks to know whether or not to set the directory attribute flag. this is done recursively when we encounter links to links
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added check in handle_open() to avoid calling CREATE/OPEN when we're creating a symlink:
if (args->disposition == FILE_CREATE &&
args->access_mask == (FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | DELETE) &&
args->access_mode == 0 &&
args->create_opts & FILE_OPEN_REPARSE_POINT)
these are the open arguments we get from the CreateSymbolicLink() syscall. by avoiding the call to CREATE/OPEN on handle_open(), we save ourselves from having to REMOVE the file before creating the symlink
added a check to handle_symlink() in case the file was actually created on open (an application could open the file with different arguments, and send the FSCTL_SET_REPARSE_POINT manually), and removes the file first
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
driver handles FSCTL_SET_REPARSE_POINT by sending a symlink set upcall
daemon handles symlink set upcall by calling nfs41_create()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added optional symlink argument to nfs41_create(), used when type is NF4LNK
changed createttype4.u.lnk.linkdata from char[] to const char* and updated encoding in nfs41_xdr.c
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
no longer depends on nfs41_open_state or open_upcall_args
renamed to nfs41_symlink_follow() and added prototype to nfs41_ops.h
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
new NFS41_SYMLINK upcall and associated data in nfs41_updowncall_entry.u.Symlink
supports both setting and querying the symlink target. if Symlink.set is TRUE, Symlink.target is marshalled into the upcall. if Symlink.set is FALSE, Symlink.target is read from the downcall
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
getattr upcall for FileAttributeTagInformation sets ReparseTag=IO_REPARSE_TAG_SYMLINK
readdir upcall sets EaSize=IO_REPARSE_TAG_SYMLINK; this makes the 'dir' command show files as <SYMLINK>, and causes a FSCTL_GET_REPARSE_POINT to query the symlink target
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when we fork a thread to handle the callback, the arguments we got from
parsing the callback operations in the callback thread are on the stack.
we need to allocate memory for same-size data structure and copy them,
not just copy the pointer.
/* we shouldn't ever see this, but a buggy server could
* send us into an infinite loop. return NFS4ERR_IO */
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added nfs41_abs_path symlink to struct open_upcall_args. we can't write the symlink target back to args->path anymore, since it's a pointer into the upcall buffer
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>