when processing new layout segments from a LAYOUTGET response, layout_update_range() first attempts to merge each new segment into existing segments before calling layout_ordered_insert(). two segments are eligible for merging if their ranges overlap, and all other relevant fields (iomode, stripe unit, deviceid, filehandles, etc) match
when a new segment is merged with an existing segment, the existing segment's extended range may cause it to overlap with another existing segment; additional merging may then be necessary. but merging an existing segment with another existing segment results in the the first segment being removed/freed, so this type of merging can -only- be performed when no io threads are referencing the layout. pnfs_layout_io_finished() calls layout_state_merge() to finish any merging that was delayed during io
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
pnfs_layout_state now stores a list instead of a single pnfs_file_layout entry. when new segments are acquired through LAYOUTGET, they are inserted into the list in order of increasing offset
functions related to pnfs_layout_state_prepare() now operate on the list to find missing layout ranges and segments missing devices
pattern_init() in pnfs_io.c now allocates and initializes io threads for each layout segment in the range
new function pattern_join() will call WaitForMultipleObjects() in a loop, to support io patterns with more than 64 threads. if pattern_fork() is called with a thread count of 1, the thread function is called directly instead of spawning a new thread
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
struct pnfs_io_pattern, pnfs_io_thread, and pnfs_io_unit are not referenced outside of pnfs_io.c, so they don't need to be in pnfs.h
also grouped the inline helper functions together at the bottom of pnfs.h
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
added stripe_next_unit() in pnfs_io.c, removed pnfs_file_device_io_unit() from pnfs_device.c
moved get_sparse_fh()/get_dense_fh() to pnfs_io.c, now only called once on pattern_init()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when starting io, both pnfs_read() and pnfs_write() need a guarantee that their range is covered by layout segments. because we have to drop the lock for LAYOUTGET and GETDEVICEINFO, earlier layout segments may be recalled during this process. to avoid this, new function pnfs_layout_state_prepare() gets called repeatedly until it can verify under a single lock that 1) the entire desired range is covered with layouts and 2) each of these layouts has an associated device. whenever pnfs_layout_state_prepare() has to drop its lock for LAYOUTGET or GETDEVICEINFO, it returns PNFS_PENDING
on PNFS_SUCCESS, the caller knows that all segments in the range are valid and can dispatch io to those segments without worrying about recalls, because it still holds the pnfs_layout_state lock
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
nfs41_open_state stores current ea index, and increments it for each successful entry returned. index is set to 0 when the 'restart' argument is given. cached directory listing is freed after the listing is complete
QueryEaInfo now sends up its output buffer size, and the daemon uses this to limit its results. added checks for buffer overflows, which required changes to the downcall structure
updated driver error mappings for map_setea_error()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when given a null for FILE_GET_EA_INFORMATION, use READDIR to construct one with
the full named attribute directory listing
new function read_entire_dir() allocates an initial buffer for readdir entries a
nd calls nfs41_readdir() repeatedly to fill it. the buffer is realloc()ed as mo
re space is required, allowing the function to return a complete listing in a si
ngle buffer
new function calculate_ea_list_length() calculates the exact length of the FILE_
GET_EA_INFORMATION buffer required to hold all of the names from the directory l
isting
once the FILE_GET_EA_INFORMATION buffer is allocated, it is filled by populate_e
a_list() and cached with nfs41_open_state
handle_getexattr() remains largely unchanged
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
check_nfs41_queryea_args() will now accept EaList == NULL, unless EAs are unsupported
moved handling of cygwin EAs to new function QueryCygwinEA()
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when open is given an ea buffer, pass it to new function nfs41_ea_set() after successful file creation. matches NTFS behavior on all dispositions: sets EAs on FILE_CREATE, FILE_OVERWRITE, FILE_OVERWRITE_IF, FILE_SUPERSEDE. does not set EAs on FILE_OPEN. only sets EAs on FILE_OPEN_IF if file did not previously exist. see new function create_with_ea()
nfs41_ea_set() returns nfs error codes. uses NFS4ERR_FBIG when the EaValueLength exceeds NFS4_EASIZE (256). this gets mapped to windows error ERROR_FILE_TOO_LARGE, which the driver now converts to STATUS_EA_TOO_LARGE
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if an EA buffer is given on create, map it to use space and pass
it to the daemon
removed check for FILE_WRITE_EA permission; it isn't required on ntfs
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
adds a critical section to nfs41_open_state. this lock is taken before generating the stateid/seqid, and released after updated stateid is saved to nfs41_open_state
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
fileio tests 214,215 does lots of renames with the same source and target filename. nfs41_name_cache_rename() would operate on the same pointer for both src and existing, and accidentally turn both into a negative entry
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
struct NFS41_V_NET_ROOT_EXTENSION now stores only the FILE_FS_ATTRIBUTE_INFORMATION (without the extra buffer space for a name). on QueryVolumeInfo() for FileFsAttributeInformation on the root directory, the FILE_FS_ATTRIBUTE_INFORMATION is copied into the output buffer, and the name is added there. QueryVolumeInfo() only makes upcalls when FileFsAttributeInformation queries are not for the root directory
new function is_root_directory() uses the logic from Set/GetReparsePoint() to determine whether it's operating on the root directory
moved logic from volume.c:handle_volume_attributes() to superblock.c:nfs41_superblock_fs_attributes(). the mount downcall copies the FILE_FS_ATTRIBUTE_INFORMATION buffer down to the driver. the driver reads this buffer directly into VNetRootContext->FsAttrs
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
if non-cygwin EAs are given to Create, SetEaInfo, or QueryEaInfo and the server does not support named attributes, fail with STATUS_EAS_NOT_SUPPORTED. also adds access checks for FILE_READ_EA and FILE_WRITE_EA
Create will accept all 3 cygwin EAs: NfsV3Attributes, NfsActOnLink, and NfsSymlinkTargetName. it now handles NfsActOnLink by adding FILE_OPEN_REPARSE_POINT to the create options
SetEaInfo will only accept NfsV3Attributes for setting the file mode. the other two will fail with STATUS_INVALID_PARAMETER. removed handling of NfsActOnLink in setattr.c
QueryEaInfo will accept all 3 cygwin EAs
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
adds a new function nfs41_superblock_getattr(), which adds an OPENATTR call with createdir=0 after the GETATTR to check for named attribute support. OPENATTR will either return ERR_NOTSUPP if not supported, or OK/ERR_NOENT depending on whether named attributes are present on the given file. we can't query for the 'named_attr' attribute, because it only tells us whether the given file contains named attributes
if named attributes are supported on a superblock, it will return FILE_SUPPORTS_EXTENDED_ATTRIBUTES for associated volume queries
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
zero-initialize the paths for named attrs, and initialize the file.name instead of using a temporary dst_name
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
reverting patch 4d18cf9ce7.
it was wrong to append the timestamp to create a silly renamed name
because it was not a reproducable name.
instead, take an fh and md5(fh) then append as before.
assign a superblock to named attribute files on nfs41_open(), to prevent crashing in nfs41_write()
also avoid updating the attribute cache with named attribute files on close and write
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
on creation of a new superblock, construct a bitmap for the default attribute mask to be used for GETATTR and READDIR requests on that filesystem. mask out any unsupported attributes, and store the bitmap in the field nfs41_superblock.default_getattr
replaced function init_getattr_request() with nfs41_superblock_getattr_mask(), which returns a copy of superblock->default_getattr
removed the locking in nfs41_superblock_supported_attrs() and nfs41_superblock_supported_attrs_exclcreat(), as the supported_attrs and suppattr_exclcreat fields are read-only after the superblock is first initialized. also factored out their common code into a bitmap_intersect() function in util.h
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
the upcall to set an EA was crashing in nfs41_open() on a null superblock, because nfs41_rpc_openattr() was returning a filehandle without a superblock. copy the parent file's superblock to the returned filehandle
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
allow callers of nfs41_open() and nfs41_create() to pass arbitrary attributes fo
r use with open_args.openhow.how.createattrs and create_args.createattrs
instead of appending a fh value when creating a silly rename name,
we'll append a timestamp. using fh value was problematic because
it was creating a filename longer than 64char long which is
currently out max_filename_size.
removing notepad opens file as a directory ifdef
for volume query notepad supplies insufficient buffer space but
doesn't like buffer_too_small error code. it seems to be fine
with partial buffer filled and buffer_overflow error.
windows can send a create irp with dispostion representing creation
of the file and specify DesiredAccess of 0.
we were treating no data access as lookup but in this case, we still
need to create a file. so send an open with a read access and
request no delegation to be returned.