Do not call afs_MarinerLog when afs_mariner is not set
When mariner log is not set up (afs_mariner=0), do not call afs_MarinerLog,
otherwise a osi_NetSend() to hostaddress=0 is tried, which will give you
ICMP messages in the socket error queue.
Do not call afs_AddMarinerName, when afs_mariner is not set.
Jeffrey Altman [Sat, 17 Nov 2012 05:43:00 +0000 (00:43 -0500)]
Windows: Add Hard Link support to Service
Implement Hard Link support to the redirector interface in the
service. It is implemented to support hard links across directories
even though AFS does not currently support it. cm_Link() will
check before issuing an RPC to the file server. ReplaceIfExists
functionality is implemented by cm_Unlink() followed by cm_Link()
if required.
Jeffrey Altman [Sat, 17 Nov 2012 03:27:02 +0000 (22:27 -0500)]
Windows: Add Hard Link support to AFS Redirector
Both Windows and AFS support the notion of hard links to files.
Add an implementation to the AFS redirector. The body of the
functionality and the IOCTL to the service permits the specification
of hard links to files across directory boundaries. There is a
restriction within AFSSetFileLinkInfo() which prevents cross-directory
requests. However, this can be taken out if AFS ever permits them.
Decrement object information link counts on directory entry
deletions. Do not delete object information context blocks if the
link count is greater than 0. Increment link counts when hard
links are added.
A subsequent patchset will implement the afsd_service support.
Jeffrey Altman [Thu, 22 Nov 2012 16:52:11 +0000 (11:52 -0500)]
Windows: Trend Micro QueryDirectory deadlock
Trend Micro will deadlock both itself and the AFS redirector by
calling a worker thread to generate a temporary file name during
an active FindFirst Directory Query. The Trend Micro worker will
also attempt to enumerate the directory. If the directory contains
an entry for which the data version as reported by the service is
different than the data version in the ObjectInformationCB a deadlock
will occur on the matching FileCB Resource.
To avoid this deadlock, prevent AFSValidateEntry from purging or
updating the ObjectInformationCB and FileObject information when
called from AFSQueryDirectory.
Change-Id: I8f2f7136796759eb91dadfea34a89513c1a1fff4
Reviewed-on: http://gerrit.openafs.org/8492 Reviewed-by: Peter Scott <pscott@kerneldrivers.com> Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com> Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
Jeffrey Altman [Mon, 19 Nov 2012 20:30:09 +0000 (15:30 -0500)]
Windows: AFSSetRenameInfo always set pRenameInfo
Make it easier to debug AFSSetRenameInfo by setting pRenameInfo
so that the FILE_RENAME_INFORMATION structure is visible within
the debugger on all code paths.
Jeffrey Altman [Fri, 16 Nov 2012 04:13:17 +0000 (23:13 -0500)]
Windows: SetFileRenameInfo Improve Error Handling
If a Target FileObject is not provided by the IOManager and
a Target RootDirectory Handle is provided something has gone
wrong. Return STATUS_INVALID_PARAMETER to indicate the
invalid state.
If the target directory is not specified by FileObject and a full
target path is provided return STATUS_NOT_SAME_DEVICE to force
an object Move instead of Rename.
Jeffrey Altman [Wed, 21 Nov 2012 23:08:35 +0000 (18:08 -0500)]
Windows: smb_ReceiveTran2QFileInfo Pioctl support
Similar to the QueryPathInfo support for _._AFS_IOCTL_._ the
QueryFileInfo interface must respond to pioctl queries. When
GetFileAttributes() on XP is called from the afslogon.dll the
QFileInfo path is used instead of the QPathInfo path.
Jeffrey Altman [Wed, 21 Nov 2012 23:03:10 +0000 (18:03 -0500)]
Windows: afslogon do not specify smbName for tokens
The smbName was added to the Windows ktc_SetTokens() interface
to provide a mechanism for passing the Windows account name
that the tokens should be associated with via Integrated Logon.
This was only required when the Authentication Provider did not
impersonate the user context prior to calling ktc_SetTokens().
Now that impersonation is used, the ktc_SetTokens() call will
do the right thing without the smbName. In fact, when impersonation
is used setting the smbName does the wrong thing by specifying
the AFS_PIOCTL_LOGON flag which is only valid if the SYSTEM account
is issuing the ktc_SetToken() call.
Jeffrey Altman [Tue, 20 Nov 2012 06:23:08 +0000 (01:23 -0500)]
Windows: QuerySecurity deny access to SACL
The SACL requires System Access Level. Requests for SACL by
end user applications must be denied. Permit access to Owner,
Group, DACL and Label but not SACL.
This change permits executables to be initiated from drive
letter mappings.
Jeffrey Altman [Mon, 19 Nov 2012 20:06:47 +0000 (15:06 -0500)]
Windows: Fix Redir link counting
Each object in AFS has a link count which tracks the number of
directory entries that refer to the FileId. In the redirector
there is one ObjectInformationCB per FileId and one AFSDirectoryCB
for each directory entry. When a directory entry is deleted perhaps
by delete on close it is important to ensure that the matching
ObjectInformationCB is not deleted unless the Link count drops to 0.
Jeffrey Altman [Sun, 18 Nov 2012 02:44:52 +0000 (21:44 -0500)]
Windows: buf_CleanLocked protect against NULL bp->userp
The cm_buf_t.userp field should never be NULL if the CM_BUF_DIRTY
flag is set but apparently it sometimes is. cm_BufWrite() requires
that the userp parameter be non-NULL. Otherwise, an assertion fails
and afsd_service.exe panics. If bp->userp is NULL, use cm_rootUserp.
The worst that will happen is the write will fail due to an access
denied error.
Jeffrey Altman [Sun, 18 Nov 2012 02:39:50 +0000 (21:39 -0500)]
Windows: do not adjust deleted scache LRU ordering
Instead of moving deleted scache objects so that they are next
in line to be recycled, do not move them at all. Making them
next to be recycled results in the CM_SCACHEFLAG_DELETED flag
value being lost.
Jeffrey Altman [Sun, 18 Nov 2012 02:32:44 +0000 (21:32 -0500)]
Windows: buf_CleanLocked validate cm_scache_t
If the cm_scache_t object is not passed in by the caller ensure
that the cm_scache_t has a valid callback. If the cm_scache_t
has the CM_SCACHEFLAG_DELETED flag set, clear the dirty flag on
the cm_buf_t and do not bother contacting the file server.
Simon Wilkinson [Wed, 21 Nov 2012 16:46:29 +0000 (16:46 +0000)]
opr: Don't confuse isLast and isEnd
opr_queue_IsEnd's implementation was incorrect - it would return
true when the element was the last item in the list, not when it
was the end of the list (equal to the head record)
Correct the implementation of isEnd, and add an implementation for
isLast.
This fixes a bug in RX, wher we would never notice that the last
packet in the transmit queue was acknowledged, because the loop that
iterates over the queue uses isEnd to detect when its work is done.
Andrew Deason [Thu, 15 Nov 2012 00:29:35 +0000 (18:29 -0600)]
afs: Do not skip flushing pages for dv-0 files
If the dv for a file is 0, we know the file is empty. Currently we
skip flushing pages for such files, presumably the idea being there is
no data in the file, so there should be no pages to flush.
However, Linux seems to keep empty pages around for empty files. So, a
future read can result in the application reading a page full of
zeroes, unless we flush the page here. While this has only been found
to happen on Linux 2.6.22 and later (and distribution-specific
backports, like RHEL 2.6.18-128), other platforms could in theory also
choose to do this. It would be difficult to find out when another
platform started to behave like this, so just remove this skip for
everyone so we never have to deal with this again.
Replace this code with a comment with a quick explanation, in case
anyone tries to add a similar optimization here in the future.
Marc Dionne [Thu, 15 Nov 2012 22:49:53 +0000 (17:49 -0500)]
Linux 3.7: remove use of param.h and ioctl.h
Header files param.h and ioctl.h have moved as part of the userspace
API restructuring of header files. Nothing in those files is
currently needed by the source, so just drop the includes.
Marc Dionne [Thu, 15 Nov 2012 03:12:13 +0000 (22:12 -0500)]
Linux: change test for new putname API
Replace the existing test with a more robust one that checks for
the existence of the new filename structure. Since older kernels
are expected to fail this test, we'll get the correct result even
if there is unrelated failure, for instance a missing/different
header file.
Jeffrey Altman [Wed, 14 Nov 2012 12:02:01 +0000 (07:02 -0500)]
Windows: Hold ProcessTreeLock across AFSValidateProcessEntry
AFSValidateProcessEntry() is called from AFSProcessCreate() which
holds the ProcessTree.TreeLock exclusive across the call and from
AFSCreate() and AFSRetrieveAuthGroup() where it is not held at all.
Add a parameter to AFSValidateProcessEntry() that indicates whether
or not the ProcessTree.TreeLock is held. If it is held, it must be
held exclusive. If it is not held, the lock must be acquired within
AFSValidateProcessEntry() and it must be held for the entire lifetime
of the pParentProcessCB reference. Failure to hold the TreeLock
for the lifetime of the reference permits a race with AFSProcessDestroy()
that can result in the parent ProcessCB being destroyed while its
Resource is held.
Jeffrey Altman [Tue, 13 Nov 2012 22:59:06 +0000 (17:59 -0500)]
Windows: Do not reset cm_buf.offset on error
When an error occurs the cm_buf_t is not removed from the
hash tables. Since the scacheHashTable hash is built from
the fid and the offset it is not safe to reset the offset field.
Resetting the offset field results in an assertion failure
during buffer recycling.
Andrew Deason [Thu, 1 Nov 2012 21:46:13 +0000 (16:46 -0500)]
afs: Add some comments on GetValidDSlot panics
A couple of call sites for afs_GetValidDSlot currently panic if an
error is returned, but no explanation is given. Add a few comments
helping explain why there is a panic there, instead of graceful error
handling.
Andrew Deason [Thu, 1 Nov 2012 21:33:31 +0000 (16:33 -0500)]
afs_FreeDiscardedDCache: Avoid assert on error
Currently afs_FreeDiscardedDCache will assert if it cannot read in any
discarded dcache entry to free. Return an error instead of asserting,
so the caller can figure out what to do about the error.
Adjust the callers to handle the error, or panic.
afs_MaybeFreeDiscardedDCache still just panics anyway, as making it
handle the error gracefully is beyond the scope of this commit, and is
work for another day.
This changes afs_FreeDiscardedDCache to return an int.
Andrew Deason [Thu, 1 Nov 2012 20:43:09 +0000 (15:43 -0500)]
afs: Handle afs_AllocDCache errors
Do not panic if afs_AllocDCache encounters an error and returns NULL.
Instead, go into the normal retry loop that occurs if we couldn't free
up any more free/discard dcache entries.
Andrew Deason [Thu, 1 Nov 2012 20:32:31 +0000 (15:32 -0500)]
afs_AllocDCache: return NULL instead of panic
Currently afs_AllocDCache will panic if we cannot get a valid dcache
from the free/discard lists. Instead, return NULL, so the caller can
decide how to handle the error.
Currently the caller will just panic anyway, but that will be
addressed in a future commit.
Andrew Deason [Thu, 1 Nov 2012 18:41:06 +0000 (13:41 -0500)]
afs: Traverse discard/free dslot list if errors
Currently, when we pull a dslot off of the discard or free list, we
just try to get the first entry from the list, and panic if we cannot
get it. Instead, traverse through the whole list, trying to find an
entry we can successfully get. This introduces the helper function
afs_GetDSlotFromList to do this traversal.
This does not yet address the case where we cannot get any entry on
the relevant list.
Andrew Deason [Thu, 1 Nov 2012 16:51:42 +0000 (11:51 -0500)]
afs: Handle easy GetValidDSlot errors
Many callers of GetValidDSlot currently assume they will always get
back a valid dcache, and will panic on getting NULL. However, for many
of these callers, handling the NULL case is quite easy, since the
failure to get a dcache can just result in an error directly, or
obtaining the dcache is best-effort or just an optimization.
This commit just handles the "easy" cases; some other callers require
more complex handling.
Andrew Deason [Wed, 31 Oct 2012 20:55:35 +0000 (15:55 -0500)]
afs: Never use GetNewDSlot after init
Currently there are two ways to get a dcache via a slot number:
afs_GetNewDSot and afs_GetValidDSlot. afs_GetValidDSlot assumes that
the given slot number refers to a dcache entry that is valid on disk;
with afs_GetNewDSlot, the given slot may not be valid, and if it is
not, an empty 'template' dcache is returned.
afs_GetNewDSlot is useful for initializing cache files, since if a
given dcache slot exists on disk and contains valid data, we use the
dcache like normal. If it does not already exist or does not contain
valid data, we fill in the missing data after afs_GetNewDSlot returns.
However, for all other uses, afs_GetNewDSlot is incorrect, and causes
various serious problems. After we have initialized our dcache
entries, any attempt to read a dcache by slot number should succeed,
since the number of dcache entries never changes after we are started,
and we initialized all of them during client startup.
Some code outside of afs_InitCacheFile was still using
afs_GetNewDSlot; code that reads in a dslot from the free or discard
list. In these cases, if there is any error reading the dcache slot
from disk, we will be given a dcache that has some of its fields not
filled in properly. Notably, we assume that the entry is not on the
global hash table (we set tdc->f.fid.Fid.Volume to 0), and the
tdc->f.inode field is not initialized at all, leaving it set to
whatever was in memory for that tdc before we tried to read the slot
from disk.
This can cause cache corruption, since tdc->f.inode can point to the
inoder for a different existing cache file, so writing to that dcache
modifies the data for another cached file.
To avoid this, modify the non-afs_InitCacheFile callers of
afs_GetNewDSlot to avoid afs_GetNewDSlot. Since these callers read
from the free/discard list, the contents of the dcache entries are not
valid (the cell, volume, dv, etc are not valid), though they must
exist on disk (we have a valid inode number for them). So, create a
new function, afs_GetUnusedDSlot, to get a dcache that must exist on
disk, but does not represent any valid data. Use this for callers that
must get a dslot from the free/discard list.
Add some comments to try and help explain what is going on.
Jeffrey Altman [Mon, 12 Nov 2012 03:00:07 +0000 (22:00 -0500)]
afsio: process windows file paths consistently
Windows file paths can use either '\' or '/' as a path
separator. libafscp on the other hand requires '/' and argv[0]
will always use '\'.
Introduce a new function ConvertAFSPath() which converts the
input path to '/' and converts \\afs to /afs. A future commit
should access the registry and make use of the NetbiosName and
MountRoot values to perform the conversion correctly.
Andrew Deason [Tue, 30 Oct 2012 18:30:27 +0000 (13:30 -0500)]
afs: Pass rx connection to print_internet_address
Make print_internet_address take an rx_connection, so it can print out
more information based on rx info. Currently it does not use the
connection; this commit is just for adding the connection to the
interface, and adjusting all of the callers to cope. There should be
no behavior change.
Michael Meffie [Tue, 30 Oct 2012 14:41:12 +0000 (10:41 -0400)]
fix stale volume info from vos examine (non-dafs)
A volume examine on a non-dafs volume server/fileserver can show old
information, including old volume update time, for up to about 20
minutes. The non-dafs volume server reads the volume information
from the volume headers, which are updated by the fileserver only
periodically to avoid excessive i/o.
Before dafs, when the volume server performed a volume examine, the
volume server would send a fssync command to the fileserver with the
request FSYNC_NEEDVOLUME and mode V_READONLY. The fileserver writes
the current memory contents to disk on this fssync command. The
volume server would then attach the volume, reading the current
volume data.
The dafs volume/fileserver avoids this extra i/o by using a new set
of fssync commands to retrieve the volume information from the
fileserver. However, the non-dafs volume server does not use the new
fssync commands and reads the volume headers from disk.
Revert the volume attachment processing for the non-dafs volume
server to request the volume with the V_READONLY mode. This causes
the fileserver to update the volume headers, allowing the volume
server to read the up to date volume header data.
Sadly, this adds another dafs ifdef to the already twisty maze of
passages that all look alike.
This changes the volserver to use the V_READONLY attachment mode
only for the case of getting a single volume, as that what was
done in 1.4.x.
Michael Meffie [Tue, 30 Oct 2012 14:22:40 +0000 (10:22 -0400)]
vol: allow non-dafs volume utils to attach with V_READONLY again
Allow non-fileserver, non-dafs, programs to attach volumes with the
V_READONLY mode again. This was lost during the code changes for
dafs.
The caller sends a fssync request to the fileserver, which updates the
on-disk contents of the volume headers, before the caller reads the
volume headers, allowing the caller to have the most recent info about
the volume. The fileserver still has the volume in use.
Later in the attachment process, the inUse check is skipped for the case
of a non-fileserver process which is attaching the volume using the
V_READONLY mode, otherwise the attachment would incorrectly mark the
volume as needing to be salvaged.
Note: The mode checks in VMustCheckOutVolume() are correct. We must
checkout the volume when attaching with the V_READONLY mode. This
fix updates the VShouldCheckInUse(), in which an additional
exception was added to cover the case for V_READONLY mode from a non-
fileserver process.
Note: A check is added in the dafs version of attach to avoid overwriting the
inUse field when a volume utility is attaching a volume in V_READONLY mode.
Currently, V_READONLY is not used by dafs, but this was done to avoid future
errors.
Jeffrey Altman [Thu, 8 Nov 2012 16:29:20 +0000 (11:29 -0500)]
Windows: Treat invalid AFSFetchStatus as VBUSY
Modify cm_Analyze() to accept an AFSFetchStatus parameter which
when set is verified for validity. If the status info is invalid,
then consider the response equivalent to VBUSY and attempt to
query an alternate file server (if any.) Log the invalid status
info to the Windows Application Event Log as a Warning.
When cm_Analyze() is processing the response of an RPC that returns
multiple AFSFetchStatus structures, pass in the one that corresponds
with the source object.
Jeffrey Altman [Thu, 8 Nov 2012 05:24:14 +0000 (00:24 -0500)]
Windows: cm_MergeStatus now returns an error code
cm_MergeStatus() can fail if the AFSFetchStatus InterfaceVersion
field does not have the value 0x1 as that is the only version that
is defined by the protocol. The return code will be CM_ERROR_INVAL.
cm_MergeStatus() returns 0 on success.
Andrew Deason [Wed, 31 Oct 2012 20:04:55 +0000 (15:04 -0500)]
afs: Make last_error always useful
Currently we record last_error as the last getuerror() we got when
failing to read in a slot in UFSGetDSlot. For kernels that do not have
getuerror(), this variable is currently useless, and we do not record
anywhere what the last error received was (besides logging it via
afs_warn).
So, for non-uerror, just record what 'code' we got, so we at least
have something.
Andrew Deason [Thu, 8 Nov 2012 00:46:24 +0000 (18:46 -0600)]
rx: Fix non-TSFPQ rxi_FreePackets
Actually count the number of packets we're given, so we don't bail out
early because num_pkts is 0. Without this, we effectively do not free
most packets for non-pthreads Rx, so e.g. the unix kernel module will
leak memory quite quickly and be very slow.
Jeffrey Altman [Tue, 6 Nov 2012 11:39:39 +0000 (06:39 -0500)]
Windows: call MIDL_user_allocate instead of calloc
In the RPC service routines do not call calloc() directly.
All memory will be deallocated by a call to MIDL_user_free()
so use MIDL_user_allocate() to perform the allocation.
Modify MIDL_user_allocate() to call calloc() instead of malloc()
to ensure that the memory is initialized to NUL bytes.
Ben Kaduk [Wed, 7 Nov 2012 15:08:33 +0000 (10:08 -0500)]
Catch up to FreeBSD non-MPSAFE deorbit
All filesystems must have their own locking now.
We have been MPSAFE for quite some time, but the preprocessor macro
"MPSAFE" has been removed and we must catch up in order to compile.
The MNTK_MPSAFE macro has not yet been removed, but it is toothless
now, so we can preemptively stop using it.
Jeffrey Altman [Thu, 1 Nov 2012 00:59:30 +0000 (20:59 -0400)]
Windows: Use MountRoot for Absolute Symlinks
Replace the absolute symlink processing in AFSLocateName().
Implement AFSIsAbsoluteAFSName() to test whether or not the
path is in fact an absolute /afs path by comparing the input
string to the registry MountRoot value which specifies the
case sensitive root path for all absolute symlinks stored
in the AFS cell.
If a symlink target path begins with a directory separator
and is not an absolute afs path name, return an error.
Construct the substitution string using the target path
without the MountRoot prefix.
Add functionality to AFSRedir.sys to read the MountRoot
from the registry and pass it on to AFSRedirLib.sys.
Simon Wilkinson [Mon, 29 Oct 2012 19:02:03 +0000 (19:02 +0000)]
opr: Add opr_jhash_int2 function
Add a function to jhash that can be used to hash a pair of unsigned
integers (or other stuff that can cast to them) without having to build
up an array.
Simon Wilkinson [Thu, 1 Nov 2012 17:38:45 +0000 (17:38 +0000)]
tests: Fix fallout from cleanup change
The change to cleanup temporary files after tests
(0c3670914a05c7aa33f0b1239ba9cc25f430ed04) broke all attempts
to run the tests using libwrap, as it would cause libwrap to run
the binary named "MAKECHECK=1"
Move the variable defintion before the libwrap invocation to fix this.
Jeffrey Altman [Wed, 31 Oct 2012 16:04:50 +0000 (12:04 -0400)]
Windows: cm_ConnByServer increment under lock
Incrementing the cm_conn.refCount must be performed while holding
the cm_connLock in order to prevent cm_GCConnections() from
seeing an in-use object as having a zero count.
Jeffrey Altman [Wed, 31 Oct 2012 13:53:57 +0000 (09:53 -0400)]
Windows: cm_FindVolumeByName refactoring
The cm_volume allocation within cm_FindVolumeByName() was racy.
Given how locks were obtained and dropped it was possible for two
threads to both determine that a cm_volume_t object needed to be
allocated. It might even have been possible for two threads to
attempt to allocate the same object.
This refactoring ensures that if a volume cannot be found under
a read lock that a second search is performed under the write lock
in case the object had in fact been allocated during the transition.
Once it is determined that an allocation is required, the cm_volumeLock
is not dropped until the object has been built and inserted into the
name hash table. This ensures that two threads cannot attempt to
allocate a cm_volume object for the same volume group.
InterlockedIncrement is used to manage the cm_data volume count.
Jeffrey Altman [Wed, 31 Oct 2012 13:52:23 +0000 (09:52 -0400)]
Windows: use cm_GetVolume / cm_PutVolume
Instead of locally incrementing and decrementing the cm_volume
refCount field use cm_GetVolume and cm_PutVolume. Doing so makes
it easier to see if there is an imbalance.
Andrew Deason [Tue, 23 Oct 2012 20:47:06 +0000 (15:47 -0500)]
ptserver: Avoid inet_ntoa
The ptserver uses inet_ntoa in a few places, such as for calculating
host CPS. This isn't safe in pthreaded environments, so use
afs_inet_ntoa_r instead.
Simon Wilkinson [Sun, 21 Oct 2012 19:07:44 +0000 (20:07 +0100)]
Fix mutex assertion
RX mutexes have two mechanisms for asserting ownership of a mutex:
MUTEX_ISMINE, which returns true if the caller is the owner of the
mutex in question, and osirx_AssertMutex which fires an assertion if
the calling thread doesn't own a specified mutex.
Neither of these work with pthread mutexes on all platforms, and the
kernel support for MUTEX_ISMINE is dubious in places. Because in some
implementations, MUTEX_ISMINE tries to lock the mutex in question, a
failing call to MUTEX_ISMINE can lead to the process holding an
additional, unexpected, lock.
This patch reworks all of this, and uses the new opr mutex framework
so that we can do mutex assertions in userspace, too. We remove the
unsafe MUTEX_ISMINE macro, and replace it with MUTEX_ASSERT which
simply asserts if the specified mutex is not held by the current
thread. osirx_AssertMutex is removed as it is now redundant.
MUTEX_ASSERT will always work in kernel code.
For userspace, we provide opr_mutex_assert, which is implemented using
POSIX error checking mutexes. As error checking mutexes have a runtime
overhead, this is only available when configured with
--enable-debug-locks, the rest of the time calls to opr_mutex_assert are
no-ops.
Simon Wilkinson [Sun, 21 Oct 2012 20:19:40 +0000 (21:19 +0100)]
rx: Move kernel assertion macros
Move the kernel assertion macros out of rx_prototypes.h and into
rx_kernel.h. This solves an ordering problem if these macros are to
be used from src/rx/<arch>/*.h
Simon Wilkinson [Sat, 20 Oct 2012 22:14:41 +0000 (23:14 +0100)]
Add opr/lock.h and tidy locking macros
The MUTEX_* and CV_* macros leaked from RX a while ago - they mean
that most of the pthreaded tree has a dependency on RX, as well as
further confusing the difference between userspace and kernel.
Tidy all of this up so that we have opr_mutex_* and opr_cv_* macros
to handle portable locking, and use these throughout the userspace
tree. Only kernel code should now use MUTEX_* and CV_*.
Provide opr/lockstub.h as a header that can be used by non-pthreaded
code to easily stub out these functions.
Simon Wilkinson [Fri, 26 Oct 2012 14:37:52 +0000 (15:37 +0100)]
rx: Move transmit queue clearing
When the client receives a data packet from the server, it means that
the server has completed processing the client's request. This, in turn,
implies that the transmit queue can be cleared. However, we were doing
this with every incoming data packet.
Move the transmit queue clearing to the code which handles the rest of
the data packet, and make the function only run if the transmit queue
is non-empty.
Now that there's no client specific logic in the ReceiveCall section,
clean up this code to reduce duplication.
Simon Wilkinson [Fri, 26 Oct 2012 14:23:48 +0000 (15:23 +0100)]
rx: Refactor code to acknowledge a whole TX queue
We acknowledge a whole transmit queue whenever an ACKALL packet is
received, or whenever the call changes direction. As the same logic
is used in both locations, pull it out into a common helper function.
Simon Wilkinson [Fri, 26 Oct 2012 13:55:02 +0000 (14:55 +0100)]
rx: Remove duplicate out of order ACK check
Once we've moved the congestion window, there's no going back. So
any ACK packets that attempt to move the window backwards by including
a 'firstPacket' value earlier than the current window position must
be ignored.
However, we check (and ignore) these packets twice. Once in
rxi_ReceivePacket, which only checks in the client side case, and again
in rxi_ReceiveAckPacket, which has a more complete check that runs for
both client and server connections.
Remove the identical check from rxi_ReceivePacket in a continuing effort
to clean up this bit of code.
Simon Wilkinson [Fri, 26 Oct 2012 13:52:46 +0000 (14:52 +0100)]
rx: Remove duplicate security layer check
rxi_FindConnection checks that the connection it returns has a
security layer matching that of the incoming packet. Don't duplicate
this check within the rxi_ReceivePacket code.
Simon Wilkinson [Fri, 26 Oct 2012 11:21:41 +0000 (12:21 +0100)]
rx: Don't build a call to immediately abort it
If the server is over the busy threshold, then don't create a new
call structure just to be able to send an abort on that call. Instead,
use rx_SendRawAbort to send an abort packet on the appropriate channel.
Simon Wilkinson [Thu, 25 Oct 2012 12:34:33 +0000 (13:34 +0100)]
rx: Remove unreachable debug statement
ReceivePacket has a dpf which is conditional on the packet having a
zero callnumber. However, just before we reach this debug statement,
we always return if the header doesn't have a call number included.
So, the debug statement can never run. Just remove it, as it's
potentially confusing.
Jeffrey Altman [Mon, 29 Oct 2012 16:59:14 +0000 (12:59 -0400)]
Windows: Set Server Prefs recalc immediately
When processing the set server preferences pioctl call cm_RankServer()
to update the server preference value reported by "getserverprefs"
in addition to cm_ChangeRankVolume() or cm_ChangeRankCellVLServer().
Jeffrey Altman [Mon, 29 Oct 2012 14:33:18 +0000 (10:33 -0400)]
Windows: mark server reference offline for VOFFLINE
cm_Analyze() was not marking the cm_ServerRef_t reference to
a volume instance as srv_offline in response to a VOFFLINE error.
As a result the same volume instance is tried again and again.
Returning STATUS_MEDIA_WRITE_PROTECTED in preference to
STATUS_OBJECT_NAME_COLLISION when the file results in silent
failures by some applications (ie, Firefox.exe) when the
first directory in the path below the share name is the
root of a .readonly volume.
Simon Wilkinson [Thu, 25 Oct 2012 10:49:55 +0000 (11:49 +0100)]
rx: Get rid of AFS_GLOBAL_RXLOCK_KERNEL
Get rid of the AFS_GLOBAL_RXLOCK_KERNEL #define. RX used to have a
single global lock locking mode, but none of our kernel modules use
it any more. In fact, AFS_GLOBAL_RXLOCK_KERNEL is now only defined
when RX_ENABLE_LOCKS is also defined. Simplify the code by renaming
all of the occurrences of AFS_GLOBAL_RXLOCK_KERNEL as RX_ENABLE_LOCKS,
and remove any cases where we're now doing unecessary tests
Simon Wilkinson [Thu, 25 Oct 2012 10:32:03 +0000 (11:32 +0100)]
rx: Don't have 2 different protos for rxi_CheckCall
Use a single prototype for rxi_CheckCall in both the pthread and
lwp cases. Remove the #ifdef maze at the call sites, and take advantage
of the fact that MUTEX_EXIT reduces to an empty string in the lwp
case.
Simon Wilkinson [Thu, 25 Oct 2012 10:27:33 +0000 (11:27 +0100)]
rx: Don't double check conn->call
We currently have
call = conn->call[channel]
if (call) {
...
} else {
call = conn->call[channel]
if (call) {
...
}
}
As we don't drop (or acquire) any locks between the first and the
second check of call, there's no way that the result can be different
from the first time we checked. So just get rid of the uneccessary
code, and reindent the following block to match.
Simon Wilkinson [Tue, 23 Oct 2012 18:21:09 +0000 (19:21 +0100)]
rx: Move bytesSent + bytesRcvd into app only data
The call->bytesSent and call->bytesRcvd counters are only manipulated
by the application thread in running calls. Move them into the app-only
section of the call structure so this is clear.
Simon Wilkinson [Tue, 23 Oct 2012 12:35:43 +0000 (13:35 +0100)]
rx: Don't use app-thread variable in SendXmitList
The value of call->app.mode is changed by the application thread
without taking the call lock. Instead of using this variable in
SendXmitList to determine whether the queue should be flushed, add
a new flag (RX_CALL_FLUSH) to control flushing behaviour.
As call->flags is manipulated under the call lock, its value can
be safely used by SendXmitList.
Simon Wilkinson [Tue, 23 Oct 2012 11:41:07 +0000 (12:41 +0100)]
rx: Make lock-free call data explicit
For speed, the application thread accesses a number of elements of
the call structure without holding the call lock. This is safe, as
long as the application thread is the only place in which these
items of data are accessed.
Make this distinction explicit by creating a new structure to hold
all of these fields, and include this structure within the rx_call.
This turns up one place in the code (SendXmitList) which accesses an
application private piece of data in the listener and event threads.
A forthcoming patch will fix this.
Jeffrey Altman [Mon, 6 Aug 2012 16:19:26 +0000 (12:19 -0400)]
Windows: Send all \\AFS\PIPE to afsd_service
Anytime there is a pipe service request, forward it to the
afsd_service.exe and permit the service to manage the request.
The prior implementation resulted in STATUS_FILE_NOT_FOUND errors
being delivered when an unexpected service was requested.
Jeffrey Altman [Fri, 19 Oct 2012 15:26:21 +0000 (11:26 -0400)]
Windows: ObjectInfo RefCount 0 <-> 1 transitions
When the reference count transitions from 0 <-> 1 ensure that the
ObjectInfoLock is held exclusive to prevent the current thread from
altering the state while another thread is holding the ObjectInfoLock
shared in order to conditionally perform an action based upon
the the reference count being zero.
Patchset eaad522651a81f20eac4966a55a731e0e59e39dd inadvertently
introduced a deadlock with invalidation requests from the service.
It is not safe to hold the ObjectInfoLock resource across calls
to AFSCleanupFcb(). Instead of holding the lock obtain a reference
to the ObjectInformationCB.
Jeffrey Altman [Thu, 25 Oct 2012 18:33:29 +0000 (14:33 -0400)]
Windows: AFSCleanup re-organization
Reorganize the activities of the AFSCleanup() for File FCBs
so that the Fcb Resource can be dropped prior to issuing the
cleanup request to the cache manager. The cache manager can
block for a long period of time while flushing data and holding
the Fcb resource blocks all subsequent CreateFile requests.
Jeffrey Altman [Thu, 25 Oct 2012 18:31:14 +0000 (14:31 -0400)]
Windows: AFSCleanup Flush Data decision
AFSCleanup() should instruct the cache manager to flush dirty
data when the Context Control Block indicates that the handle
being closed was opened for writing and was granted appropriate
permissions. The decision to flush should not be dependent on
the open handle count because the last handle might belong to
an authentication group that does not have write permission.
Jeffrey Altman [Tue, 23 Oct 2012 00:40:21 +0000 (20:40 -0400)]
Windows: AFSMarkDirty() require ExtentsResource held
Instead of dynamically testing if the ExtentsResource is held
and if not acquire it within AFSMarkDirty(), simply require that
it be held. AFSMarkDirty() is only called from one location.