moved recovery of lock stateids from recover_open() to new function recover_locks()
split nfs41_recover_stateid() into recover_stateid_open() and recover_stateid_lock()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
nfs41_open() in open.c is no longer used for recovery, so made static and renamed to do_open(). renamed nfs41_rpc_open() back to nfs41_open()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
recovery.h exposes the following functions for nfs41_compound.c:
nfs41_recovery_start_or_wait()
nfs41_recovery_finish()
nfs41_recover_client_state()
nfs41_recover_stateid()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
previously we'd query owner and group file attributes on all getattrs and
storing that in nfs41_file_info structure which was caused a problem for
readdirs.
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>
when a delegation is granted by OPEN, its delegation type is passed to nfs41_name_cache_insert(). as long as the delegation is held, its name_cache_entry is kept out of the cache.exp_entries list to prevent it from expiring. an extra reference is held on the attr_cache_entry as well, so it sticks around even if the name_cache_entry is removed (a parent expires, for example). new function nfs41_name_cache_delegreturn() adds the name_cache_entry back to the list, and releases the extra attr_cache_entry reference
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>
moved thread creation from callback_server.c to nfs41_delegation_recall() in delegation.c
nfs41_delegation_recall() first searches for the delegation, and returns NFS4ERR_BADHANDLE if not found. otherwise, it spawns a thread to handle the recall and returns NFS4_OK
delegation_return() calls nfs41_delegation_to_open() for each nfs41_open_state associated with the delegation
nfs41_delegation_to_open() sends OPEN with CLAIM_DELEGATE_CUR to reclaim an open stateid, and uses a condition variable in nfs41_open_state to prevent multiple threads from attempting reclaim
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added delegation.c and .h
nfs41_client stores a list of nfs41_delegation_state
new function nfs41_delegate_open() to look for a compatible delegation before calling nfs41_open()
if nfs41_open() is granted a delegation, call nfs41_delegation_granted() to register it with the client
client calls nfs41_client_delegation_free() on unmount to free list of delegations
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
combined nfs41_open() and nfs41_open_reclaim() into nfs41_rpc_open() by factoring out the open_claim4 argument. new function nfs41_open() in open.c deals with the nfs41_open_state, adding it to the client's list, and handles any delegations granted
added xdr for OPEN CLAIM types CLAIM_DELEGATE_CUR, CLAIM_DELEG_CUR_FH, CLAIM_DELEGATE_PREV, CLAIM_DELEG_PREV_FH (the _FH types are new to 4.1, and not supported by linux server)
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
in create_session we were sending auth_none as available security types
for the callback channel. Adding auth_sys to the list. No enforcement of
these creds happens.
instead of updating the attribute cache with the values given to SETATTR, add a GETATTR to the compound; this will capture changes to time_modify and change that the client could otherwise miss, and get the server's value of timestamps sent with SET_TO_SERVER_TIME4
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
handling receiving WRONGSEC error in compound_encode_decode function by
sending either SECINFO or SECINFO_NONAME op to find out available
security flavors from the server. then try to establish new security
context given the ordered list returned by the server.
Not handling if parent directory doesn't permit a security flavor of
its child directory. Example "/" exported with only auth_sys and
"/sec" exported with only "gss".
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
nfs41_name_cache_lookup() was returning FILE_NOT_FOUND on negative entries, but still copying the target filehandle
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
zero-length ranges: valid on windows, but nfs servers MUST return NFS4ERR_INVAL for LOCK with length=0. use MRxIsLockRealizable() to return STATUS_NOT_SUPPORTED for zero-length ranges (avoiding the lock upcall and rpc)
ranges that extend past UINT64_MAX: not valid on windows. NFS expects length=UINT64_MAX for locking to end-of-file. use length=UINT64_MAX if length >= UINT64_MAX-offset (making lock ranges consistent with linux client)
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if during recv we received an error, then propagate that to the caller.
otherwise, do time out check. also do timeout check if the thread's xid
didn't match received xid (making sure we'll timeout if we have a starving
thread that will never receive a reply)
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.
if we receive an rpc_autherr, just recreate a new rpc client as well
as the rpc auth structure. as it ties into the recovery and handles
that only one thread recovers and reestablishes the rpc auth context.
in theory, reestablishing rpc client does not necessitate new rpc auth
context. we really need to restablish one only if we get rpc autherr. however,
it simplifies the code not to introduce a different synchronization
mechanism for rpc auth in addition to the rpc one.
once libtirpc blocking recv was changed to a polling receive,
we no longer had a timeout mechanims on waiting for a reply.
solution: save a timestamp before the recv call, on each async recv return
check if the time lapsed does not exceed the timeout value. when timeout
is reach, return TIMEDOUT rpc error.
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.
reformated some of the old functions.
finalized mapping functions for windows to nfs4 access mask bits.
satisfying nfs41_acl_query for dacl.
when doing setacl and creating "who" field of the format user@nfs4domain,
use dns domain name of the windows client machine
instead of passing sids for the owner and group, create a security
descriptor and pass that back. this way we can add all the security
information that was queried in the daemon and pass a fully formed
security descriptor back to the kernel.
notice: irp_mj_query_security provides a pointer to the buffer that
suppose to hold the security descriptor. that memory is valid only
in the context of the process doing the security irp. we can't use
this pointer in then upcall entry and try to write the security
descriptor directly there as we process the downcall. that leads
to kernel oops.
thus we have to first allocate memory to hold the security descriptor
then copy bytes passed to us from the daemon. then do another copy
with the context of the security irp.
this commit does NOT have correct windows to nfs4 acl mappings but
rather has the wrapper functions defined for mapping them.
cthon tests still work with these mappings.