very similar to the issue with nfs41_open_state, an abandoned upcall could outlive its mount. to prevent their nfs41_root from being freed, upcalls need to hold a reference until they're finished. this also keeps all of its clients/sessions/rpc connections alive
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added call to upcall_cleanup() after both upcall_marshall() and upcall_cancel()
individual upcall operations define their nfs41_upcall_op structs locally, instead of putting tons of function prototypes in upcall.c
made the upcall_marshall() function optional; most marshall functions are noops
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
fixes a memory leak that occurs when a readdir loop doesn't complete, since the cookie was only freed on the last readdir upcall. by storing the cookie with nfs41_open_state, we can avoid passing the cookie to the driver and back, and not worry about having to free it separately
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>
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>
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>
because we no longer have to convert strings from unicode, we can avoid copying them out of the upcall buffer
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when open parsing fails, we were still returning upcall.status==NO_ERROR, so the driver assumed the open succeeded. other operations then sent up an open_state==NULL, and crashed the daemon. when upcall_parse() returns an error, set upcall.status to notify the driver
upcall_parse() prints a 'parsing of upcall <name> failed with <error>.' message on failure, so i removed redundant messages from the individual upcall parsing functions
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if readdir fails to look up a referred entry, set its type to NF4DIR so windows explorer shows it as a directory. when you double-click on the directory, it gives a message saying that it "refers to a location that is unavailable"
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>