Commit graph

33 commits

Author SHA1 Message Date
Olga Kornievskaia
54c11cd84b ensuring exactly once semantics for open
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.
2011-05-24 12:33:58 -04:00
Olga Kornievskaia
529d7ce6db moving session and open_state in upcall header
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.
2011-04-13 20:07:37 -04:00
Casey Bodley
c9585d937f pnfs: readwrite uses pnfs_layout_state
nfs41_lock_stateid_arg() is now called only once in handle_read()/handle_write(), and pnfs_read()/pnfs_write() no longer depend on nfs41_open_state

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2011-03-22 14:49:24 -04:00
Olga Kornievskaia
3a60f23c91 cosmetic changing printouts in check_execute_access
adding the filename to the printouts and changing eprintf back to dprintf as it it happens too often.
2011-01-13 11:41:49 -05:00
Casey Bodley
eb60a1ee6d check_execute_access() prints errors with eprintf()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2011-01-10 15:16:18 -05:00
unknown
2ae743efe7 tracking open state in setattr for reboot recovery 2010-12-10 11:25:01 -05:00
Casey Bodley
0a309c4350 recovery: use normal OPEN/LOCK on ERR_NO_GRACE
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>
2010-12-06 14:29:32 -05:00
Casey Bodley
222c1bf020 recovery: remember byte-range locks and reclaim during recovery
nfs41_open_state maintains a list of outstanding byte-range locks by calling open_lock_add() and open_lock_remove() in lock.c

during client state recovery, after reclaiming each OPEN stateid, send LOCK requests with reclaim=TRUE for each lock it owns, and update the open's lock stateid with the result

added 'bool_t reclaim' argument to nfs41_lock(); when set, compound_encode_send_decode() is called with try_recovery=FALSE to avoid recursive recovery

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-12-06 14:29:25 -05:00
Casey Bodley
3ecd38e414 recovery: operations take stateid_arg instead of stateid4
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>
2010-12-06 14:21:28 -05:00
Casey Bodley
d59d17c3b4 recovery: reclaim opens on client renewal
after the client and session have been recovered, loop through the client's list of open state, calling nfs41_open_reclaim() and updating the stateid on success

nfs41_open_state saves the share_access and share_deny fields from the initial open, for use with nfs41_open_reclaim()

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-12-06 14:21:22 -05:00
Casey Bodley
7240c69b5d recovery: client keeps list of associated open state
open state is added to the client's list on a successful call to nfs41_open(), and removed from the list on nfs41_close() regardless of success

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-12-06 14:21:16 -05:00
unknown
a57e7a78f1 removed unnecessary free_open_state() function 2010-11-02 14:31:12 -04:00
Casey Bodley
bcc707d3b8 ref counting for nfs41_root
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>
2010-10-27 16:18:23 -04:00
Olga Kornievskaia
006bdfa47a ref counting for nfs41_open_state 2010-10-27 16:18:12 -04:00
Casey Bodley
ae4c67c21e upcall: added upcall_cleanup() to interface
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>
2010-10-27 16:16:17 -04:00
Olga Kornievskaia
a7e2d6ad2a checking functions return values
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.
2010-10-19 12:14:40 -04:00
Casey Bodley
f8885dbad0 warnings from WDK 6000
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>
2010-10-19 11:17:29 -04:00
Casey Bodley
64480d0aca symlink: on open for mklink, only check for FILE_EXISTS
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>
2010-10-15 17:24:10 -04:00
Casey Bodley
870b389e8f symlink: limit symlink depth to avoid following cyclical links
/* 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>
2010-10-15 17:24:04 -04:00
Casey Bodley
1ad1c0f262 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>
2010-10-15 14:56:06 -04:00
Casey Bodley
eb9d9bbd4c symlink: nfs41_symlink_follow() for readdir and open
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>
2010-10-14 16:57:53 -04:00
Casey Bodley
e27299d066 symlink: open handles embedded symlinks
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>
2010-10-14 12:42:38 -04:00
Casey Bodley
ccdaa169eb symlink: handle_open() detects symlink creation
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>
2010-10-14 12:42:36 -04:00
Casey Bodley
8c4c98b669 symlink: nfs41_create() can create symlinks
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>
2010-10-14 12:42:35 -04:00
Casey Bodley
8ea0ca1893 symlink: generalized follow_link()
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>
2010-10-14 12:42:34 -04:00
Casey Bodley
dd48ca17c3 symlink: moved follow_link() to symlink.c [cosmetic]
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-10-14 12:42:33 -04:00
Casey Bodley
66d4ea8e0b max_path: static buffer for symlink path
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>
2010-10-12 10:36:11 -04:00
Casey Bodley
f727a1e4b4 max_path: get_name() avoids copying from upcall buffer
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>
2010-10-12 10:36:10 -04:00
Casey Bodley
95361423f3 upcall: set upcall.status on parse failure
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>
2010-10-12 10:36:08 -04:00
Casey Bodley
74a704120b symlink: open calls READLINK and updates the path
when handle_open() encounters a file of type NF4LNK and the FILE_OPEN_REPARSE_POINT flag is not present, it calls READLINK for the symlink's target path.  it then calls abs_path_link() to update the filename (args->path), whether the symlink target is an absolute or relative path.  abs_path_link() also takes into account the special characters . and .., though it doesn't allow traversing .. entries below the root of the server's namespace

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-10-12 10:36:07 -04:00
Casey Bodley
45a14a17ff symlink: open downcall passes symlink target
on last_error == ERROR_REPARSE, the daemon converts args->path back to wchar and passes it down to the driver

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-10-12 10:36:06 -04:00
Casey Bodley
5dc1b43191 rmdir: use normal delete upcall instead of close
caused memory leaks of nfs41_open_state.  we have the FileDispositionInformation upcall for exactly this, so there's no need to complicate the close code path

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-10-12 10:36:04 -04:00
Casey Bodley
0ad4db4fad fresh git tree for public release
we regretfully had to remove our git history for licensing reasons

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-10-12 10:15:48 -04:00