added 2011 year to the copyright line
added authors info to the license
added UofM license to libtirpc files that we modified
(but i probably missed some)
prevent an OPEN with OPEN4_CREATE from breaking a write delegation by sending a SETATTR instead
moved static function remove_unsupported_attrs() from setattr.c to nfs41_superblock_supported_attrs() in nfs41_superblock.c, now used by both setattr.c and delegation.c
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
new function nfs41_delegation_return() for synchronous delegation return. uses a condition variable to wait if another thread is already returning the delegation
if nfs41_delegate_open() would conflict with a delegation, return it before sending the OPEN
return the delegation before sending LINK, RENAME, REMOVE, and SETATTR
all of this functionality is dependent on the preprocessor define DELEGATION_RETURN_ON_CONFLICT (on by default). if not defined, nfs41_delegation_return() is a noop
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
combined nfs41_lock_stateid_arg() into nfs41_open_stateid_arg(). if a delegation is present, use the delegation stateid before looking at lock/open stateids. if a delegation recall is in progress, wait on its condition variable before falling back to the open stateid
made nfs41_lock_stateid_arg() static to lock.c because of its special semantics; open_to_lock_owner4 for LOCK won't accept a delegation stateid, so nfs41_delegation_to_open() is called to convert it
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
proposes an alternate solution for attempts to set file size without an open sta
teid. instead of acquiring one by sending OPEN, fail the request with ACCESS_DE
NIED
according the MS File System Algorithms documentation for setting FileAllocation
Information and FileEndOfFileInformation [http://msdn.microsoft.com/en-us/librar
y/ff469355%28v=PROT.10%29.aspx]:
"If Open.GrantedAccess does not contain FILE_WRITE_DATA, the operation MUST be f
ailed with STATUS_ACCESS_DENIED"
-removes open_owner_id, access_mask, access_mode from setattr upcall arguments
-moves map_access_2_allowdeny() back to open.c as a static function, since handl
e_setattr() was its only other call site
if we are doing CREATE_NEW file creation, then based on whether or not
we have a persistent session, we'll send either GUARDED4 create for
persistent session and EXCLUSIVE4_1 create otherwise.
every upcall (except few) pass session and open_state pointer, so
add that to marshal_nfs41_header() in the driver. remove passing
of session and open_state elsewhere in marshal functions.
in the deamon, upcall.c now reads and stores pointers to session
and open_state in nfs41_upcall datastructure instead of having
each individual upcall store their own pointers. setattrl
and readdir args keeping pointer because the rest of the code
uses them a lot.
in upcall_parse() up refcounts on session and open_state if
valid handles were passed in. down refcounts upcall_cleanup() as
before. but need to be careful with count value for mount and open
upcalls. we need to take an extra ref because upcall_cleanup() now
will always decrement it.
adding a check to see if the destination filename is currently opened by
looking through the list of open states stored for a given client.
fail rename with ERROR_FILE_EXISTS if we find an open.
if we see NFS4ERR_NO_GRACE from recovery operations, it means we lost our state due to a lease expiration rather than a server reboot. in this case, it's possible that conflicting locks were granted to other clients, so we have to try normal OPEN/LOCK operations to recover our state. because they're sent during recovery, nfs41_open() and nfs41_lock() take a new 'bool_t try_recovery' argument so we can avoid recursion
if these operations fail due to conflicting locks, we have no choice but to return errors to the application. using a stateid that was revoked due to lease expiration results in NFS4ERR_EXPIRED, and we map this error to ERROR_FILE_INVALID: The volume for a file has been externally altered so that the opened file is no longer valid.
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
operations that require a stateid now take stateid_arg for recovery information. these operations include close, setattr, lock/unlock, layoutget, and read/write (including pnfs)
nfs41_open_stateid_arg() locks nfs41_open_state and copies its stateid into a stateid_arg
nfs41_lock_stateid_arg() locks nfs41_open_state.last_lock and copies its stateid into a stateid_arg; if there is no lock state, it falls back to nfs41_open_stateid_arg()
pnfs_read/write() now take nfs41_open_state so they can generate stateid_args
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
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>
/* 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>
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>
added time_delta argument to xdr_settime4(). if the normal 'time' argument is within time_delta of the current time (get_nfs_time()), it uses time_how=SET_TO_SERVER_TIME4. otherwise, it uses SET_TO_CLIENT_TIME4 and encodes the time as usual
handle_nfs41_setattr() ignores times if superblock->cansettime==0. otherwise, it passes in superblock->time_delta (via info.time_delta) along with the other time attributes, for use with xdr_settime4()
Signed-off-by: Casey Bodley <cbodley@umich.edu>
the link part of basic test7 was failing because LINK's target was still cached as a negative entry, leading to the error "can't stat newfile.0 after link". the solution is to replace the negative entry with the real fh and attributes of the target file
so instead of doing RESTOREFH+GETATTR on the source file and calling nfs41_attr_cache_update(), nfs41_link() uses LOOKUP+GETATTR+GETFH to get attributes for the target file and passes them to nfs41_name_cache_insert() along with dst_dir's changeinfo. because the source and target file will have the same fileid attribute, nfs41_name_cache_insert() will update the attributes of both at the same time. added the target file as an optional return parameter
Signed-off-by: Casey Bodley <cbodley@umich.edu>