1. 25 Feb, 2019 1 commit
    • David Howells's avatar
      afs: Fix manually set volume location server list · 7d762d69
      David Howells authored
      When a cell with a volume location server list is added manually by
      echoing the details into /proc/net/afs/cells, a record is added but the
      flag saying it has been looked up isn't set.
      This causes the VL server rotation code to wait forever, with the top of
      /proc/pid/stack looking like:
      with the thread stuck in afs_start_vl_iteration() waiting for
      AFS_CELL_FL_NO_LOOKUP_YET to be cleared.
      Fix this by clearing AFS_CELL_FL_NO_LOOKUP_YET when setting up a record
      if that record's details were supplied manually.
      Fixes: 0a5143f2 ("afs: Implement VL server rotation")
      Reported-by: default avatarDave Botsch <dwb7@cornell.edu>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
  2. 17 Jan, 2019 4 commits
    • David Howells's avatar
      afs: Fix race in async call refcounting · 34fa4761
      David Howells authored
      There's a race between afs_make_call() and afs_wake_up_async_call() in the
      case that an error is returned from rxrpc_kernel_send_data() after it has
      queued the final packet.
      afs_make_call() will try and clean up the mess, but the call state may have
      been moved on thereby causing afs_process_async_call() to also try and to
      delete the call.
      Fix this by:
       (1) Getting an extra ref for an asynchronous call for the call itself to
           hold.  This makes sure the call doesn't evaporate on us accidentally
           and will allow the call to be retained by the caller in a future
           patch.  The ref is released on leaving afs_make_call() or
       (2) In the event of an error from rxrpc_kernel_send_data():
           (a) Don't set the call state to AFS_CALL_COMPLETE until *after* the
           	 call has been aborted and ended.  This prevents
           	 afs_deliver_to_call() from doing anything with any notifications
           	 it gets.
           (b) Explicitly end the call immediately to prevent further callbacks.
           (c) Cancel any queued async_work and wait for the work if it's
           	 executing.  This allows us to be sure the race won't recur when we
           	 change the state.  We put the work queue's ref on the call if we
           	 managed to cancel it.
           (d) Put the call's ref that we got in (1).  This belongs to us as long
           	 as the call is in state AFS_CALL_CL_REQUESTING.
      Fixes: 341f741f ("afs: Refcount the afs_call struct")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Provide a function to get a ref on a call · 7a75b007
      David Howells authored
      Provide a function to get a reference on an afs_call struct.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Fix key refcounting in file locking code · 59d49076
      David Howells authored
      Fix the refcounting of the authentication keys in the file locking code.
      The vnode->lock_key member points to a key on which it expects to be
      holding a ref, but it isn't always given an extra ref, however.
      Fixes: 0fafdc9f ("afs: Fix file locking")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • Marc Dionne's avatar
      afs: Don't set vnode->cb_s_break in afs_validate() · 4882a27c
      Marc Dionne authored
      A cb_interest record is not necessarily attached to the vnode on entry to
      afs_validate(), which can cause an oops when we try to bring the vnode's
      cb_s_break up to date in the default case (ie. no current callback promise
      and the vnode has not been deleted).
      Fix this by simply removing the line, as vnode->cb_s_break will be set when
      needed by afs_register_server_cb_interest() when we next get a callback
      promise from RPC call.
      The oops looks something like:
          BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
          RIP: 0010:afs_validate+0x66/0x250 [kafs]
          Call Trace:
           afs_d_revalidate+0x8d/0x340 [kafs]
           ? __d_lookup+0x61/0x150
           ? lookup_dcache+0x44/0x70
      Fixes: ae3b7361 ("afs: Fix validation/callback interaction")
      Signed-off-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
  3. 10 Jan, 2019 2 commits
    • Marc Dionne's avatar
      afs: Set correct lock type for the yfs CreateFile · 5edc22cc
      Marc Dionne authored
      A lock type of 0 is "LockRead", which makes the fileserver record an
      unintentional read lock on the new file.  This will cause problems
      later on if the file is the subject of locking operations.
      The correct default value should be -1 ("LockNone").
      Fix the operation marshalling code to set the value and provide an enum to
      symbolise the values whilst we're at it.
      Fixes: 30062bd1 ("afs: Implement YFS support in the fs client")
      Signed-off-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • Gustavo A. R. Silva's avatar
      afs: Use struct_size() in kzalloc() · c2b8bd49
      Gustavo A. R. Silva authored
      One of the more common cases of allocation size calculations is finding the
      size of a structure that has a zero-sized array at the end, along with
      memory for some number of elements for that array. For example:
      struct foo {
          int stuff;
          void *entry[];
      instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
      Instead of leaving these open-coded and prone to type mistakes, we can now
      use the new struct_size() helper:
      instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL);
      This code was detected with the help of Coccinelle.
      Signed-off-by: default avatarGustavo A. R. Silva <gustavo@embeddedor.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
  4. 04 Jan, 2019 2 commits
  5. 30 Nov, 2018 3 commits
    • David Howells's avatar
      afs: Use d_instantiate() rather than d_add() and don't d_drop() · 73116df7
      David Howells authored
      Use d_instantiate() rather than d_add() and don't d_drop() in
      afs_vnode_new_inode().  The dentry shouldn't be removed as it's not
      changing its name.
      Reported-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    • David Howells's avatar
      afs: Fix missing net error handling · 4584ae96
      David Howells authored
      kAFS can be given certain network errors (EADDRNOTAVAIL, EHOSTDOWN and
      ERFKILL) that it doesn't handle in its server/address rotation algorithms.
      They cause the probing and rotation to abort immediately rather than
      Fix this by:
       (1) Abstracting out the error prioritisation from the VL and FS rotation
           algorithms into a common function and expand usage into the server
           probing code.
           When multiple errors are available, this code selects the one we'd
           prefer to return.
       (2) Add handling for EADDRNOTAVAIL, EHOSTDOWN and ERFKILL.
      Fixes: 0fafdc9f ("afs: Fix file locking")
      Fixes: 0338747d8454 ("afs: Probe multiple fileservers simultaneously")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    • David Howells's avatar
      afs: Fix validation/callback interaction · ae3b7361
      David Howells authored
      When afs_validate() is called to validate a vnode (inode), there are two
      unhandled cases in the fastpath at the top of the function:
       (1) If the vnode is promised (AFS_VNODE_CB_PROMISED is set), the break
           counters match and the data has expired, then there's an implicit case
           in which the vnode needs revalidating.
           This has no consequences since the default "valid = false" set at the
           top of the function happens to do the right thing.
       (2) If the vnode is not promised and it hasn't been deleted
           (AFS_VNODE_DELETED is not set) then there's a default case we're not
           handling in which the vnode is invalid.  If the vnode is invalid, we
           need to bring cb_s_break and cb_v_break up to date before we refetch
           the status.
           As a consequence, once the server loses track of the client
           (ie. sufficient time has passed since we last sent it an operation),
           it will send us a CB.InitCallBackState* operation when we next try to
           talk to it.  This calls afs_init_callback_state() which increments
           afs_server::cb_s_break, but this then doesn't propagate to the
           afs_vnode record.
           The result being that every afs_validate() call thereafter sends a
           status fetch operation to the server.
      Clarify and fix this by:
       (A) Setting valid in all the branches rather than initialising it at the
           top so that the compiler catches where we've missed.
       (B) Restructuring the logic in the 'promised' branch so that we set valid
           to false if the callback is due to expire (or has expired) and so that
           the final case is that the vnode is still valid.
       (C) Adding an else-statement that ups cb_s_break and cb_v_break if the
           promised and deleted cases don't match.
      Fixes: c435ee34 ("afs: Overhaul the callback handling")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
  6. 15 Nov, 2018 1 commit
    • David Howells's avatar
      rxrpc: Fix life check · 7150ceaa
      David Howells authored
      The life-checking function, which is used by kAFS to make sure that a call
      is still live in the event of a pending signal, only samples the received
      packet serial number counter; it doesn't actually provoke a change in the
      counter, rather relying on the server to happen to give us a packet in the
      time window.
      Fix this by adding a function to force a ping to be transmitted.
      kAFS then keeps track of whether there's been a stall, and if so, uses the
      new function to ping the server, resetting the timeout to allow the reply
      to come back.
      If there's a stall, a ping and the call is *still* stalled in the same
      place after another period, then the call will be aborted.
      Fixes: bc5e3a54 ("rxrpc: Use MSG_WAITALL to tell sendmsg() to temporarily ignore signals")
      Fixes: f4d15fb6 ("rxrpc: Provide functions for allowing cleaner handling of signals")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
  7. 23 Oct, 2018 22 commits
    • David Howells's avatar
      afs: Probe multiple fileservers simultaneously · 3bf0fb6f
      David Howells authored
      Send probes to all the unprobed fileservers in a fileserver list on all
      addresses simultaneously in an attempt to find out the fastest route whilst
      not getting stuck for 20s on any server or address that we don't get a
      reply from.
      This alleviates the problem whereby attempting to access a new server can
      take a long time because the rotation algorithm ends up rotating through
      all servers and addresses until it finds one that responds.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Fix callback handling · 18ac6185
      David Howells authored
      In some circumstances, the callback interest pointer is NULL, so in such a
      case we can't dereference it when checking to see if the callback is
      broken.  This causes an oops in some circumstances.
      Fix this by replacing the function that worked out the aggregate break
      counter with one that actually does the comparison, and then make that
      return true (ie. broken) if there is no callback interest as yet (ie. the
      pointer is NULL).
      Fixes: 68251f0a ("afs: Fix whole-volume callback handling")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Eliminate the address pointer from the address list cursor · 2feeaf84
      David Howells authored
      Eliminate the address pointer from the address list cursor as it's
      redundant (ac->addrs[ac->index] can be used to find the same address) and
      address lists must be replaced rather than being rearranged, so is of
      limited value.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Allow dumping of server cursor on operation failure · 744bcd71
      David Howells authored
      Provide an option to allow the file or volume location server cursor to be
      dumped if the rotation routine falls off the end without managing to
      contact a server.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Implement YFS support in the fs client · 30062bd1
      David Howells authored
      Implement support for talking to YFS-variant fileservers in the cache
      manager and the filesystem client.  These implement upgraded services on
      the same port as their AFS services.
      YFS fileservers provide expanded capabilities over AFS.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Expand data structure fields to support YFS · d4936803
      David Howells authored
      Expand fields in various data structures to support the expanded
      information that YFS is capable of returning.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Get the target vnode in afs_rmdir() and get a callback on it · f58db83f
      David Howells authored
      Get the target vnode in afs_rmdir() and validate it before we attempt the
      deletion, The vnode pointer will be passed through to the delivery function
      in a later patch so that the delivery function can mark it deleted.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Calc callback expiry in op reply delivery · 12d8e95a
      David Howells authored
      Calculate the callback expiration time at the point of operation reply
      delivery, using the reply time queried from AF_RXRPC on that call as a
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Fix FS.FetchStatus delivery from updating wrong vnode · 36bb5f49
      David Howells authored
      The FS.FetchStatus reply delivery function was updating inode of the
      directory in which a lookup had been done with the status of the looked up
      file.  This corrupts some of the directory state.
      Fixes: 5cf9dd55 ("afs: Prospectively look up extra files when doing a single lookup")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Implement the YFS cache manager service · 35dbfba3
      David Howells authored
      Implement the YFS cache manager service which gives extra capabilities on
      top of AFS.  This is done by listening for an additional service on the
      same port and indicating that anyone requesting an upgrade should be
      upgraded to the YFS port.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Remove callback details from afs_callback_break struct · 06aeb297
      David Howells authored
      Remove unnecessary details of a broken callback, such as version, expiry
      and type, from the afs_callback_break struct as they're not actually used
      and make the list take more memory.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Commit the status on a new file/dir/symlink · 00671912
      David Howells authored
      Call the function to commit the status on a new file, dir or symlink so
      that the access rights for the caller's key are cached for that object.
      Without this, the next access to the file will cause a FetchStatus
      operation to be emitted to retrieve the access rights.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Increase to 64-bit volume ID and 96-bit vnode ID for YFS · 3b6492df
      David Howells authored
      Increase the sizes of the volume ID to 64 bits and the vnode ID (inode
      number equivalent) to 96 bits to allow the support of YFS.
      This requires the iget comparator to check the vnode->fid rather than i_ino
      and i_generation as i_ino is not sufficiently capacious.  It also requires
      this data to be placed into the vnode cache key for fscache.
      For the moment, just discard the top 32 bits of the vnode ID when returning
      it though stat.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Don't invoke the server to read data beyond EOF · 2a0b4f64
      David Howells authored
      When writing a new page, clear space in the page rather than attempting to
      load it from the server if the space is beyond the EOF.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Add a couple of tracepoints to log I/O errors · f51375cd
      David Howells authored
      Add a couple of tracepoints to log the production of I/O errors within the AFS
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Handle EIO from delivery function · 4ac15ea5
      David Howells authored
      Fix afs_deliver_to_call() to handle -EIO being returned by the operation
      delivery function, indicating that the call found itself in the wrong
      state, by printing an error and aborting the call.
      Currently, an assertion failure will occur.  This can happen, say, if the
      delivery function falls off the end without calling afs_extract_data() with
      the want_more parameter set to false to collect the end of the Rx phase of
      a call.
      The assertion failure looks like:
      	AFS: Assertion failed
      	4 == 7 is false
      	0x4 == 0x7 is false
      	------------[ cut here ]------------
      	kernel BUG at fs/afs/rxrpc.c:462!
      and is matched in the trace buffer by a line like:
      kworker/7:3-3226 [007] ...1 85158.030203: afs_io_error: c=0003be0c r=-5 CM_REPLY
      Fixes: 98bf40cd ("afs: Protect call->state changes against signals")
      Reported-by: default avatarMarc Dionne <marc.dionne@auristor.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Fix TTL on VL server and address lists · ded2f4c5
      David Howells authored
      Currently the TTL on VL server and address lists isn't set in all
      circumstances and may be set to poor choices in others, since the TTL is
      derived from the SRV/AFSDB DNS record if and when available.
      Fix the TTL by limiting the range to a minimum and maximum from the current
      time.  At some point these can be made into sysctl knobs.  Further, use the
      TTL we obtained from the upcall to set the expiry on negative results too;
      in future a mechanism can be added to force reloading of such data.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Implement VL server rotation · 0a5143f2
      David Howells authored
      Track VL servers as independent entities rather than lumping all their
      addresses together into one set and implement server-level rotation by:
       (1) Add the concept of a VL server list, where each server has its own
           separate address list.  This code is similar to the FS server list.
       (2) Use the DNS resolver to retrieve a set of servers and their associated
           addresses, ports, preference and weight ratings.
       (3) In the case of a legacy DNS resolver or an address list given directly
           through /proc/net/afs/cells, create a list containing just a dummy
           server record and attach all the addresses to that.
       (4) Implement a simple rotation policy, for the moment ignoring the
           priorities and weights assigned to the servers.
       (5) Show the address list through /proc/net/afs/<cell>/vlservers.  This
           also displays the source and status of the data as indicated by the
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Improve FS server rotation error handling · e7f680f4
      David Howells authored
      Improve the error handling in FS server rotation by:
       (1) Cache the latest useful error value for the fs operation as a whole in
           struct afs_fs_cursor separately from the error cached in the
           afs_addr_cursor struct.  The one in the address cursor gets clobbered
           occasionally.  Copy over the error to the fs operation only when it's
           something we'd be interested in passing to userspace.
       (2) Make it so that EDESTADDRREQ is the default that is seen only if no
           addresses are available to be accessed.
       (3) When calling utility functions, such as checking a volume status or
           probing a fileserver, don't let a successful result clobber the cached
           error in the cursor; instead, stash the result in a temporary variable
           until it has been assessed.
       (4) Don't return ETIMEDOUT or ETIME if a better error, such as
           ENETUNREACH, is already cached.
       (5) On leaving the rotation loop, turn any remote abort code into a more
           useful error than ECONNABORTED.
      Fixes: d2ddc776 ("afs: Overhaul volume and server record caching and fileserver rotation")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Set up the iov_iter before calling afs_extract_data() · 12bdcf33
      David Howells authored
      afs_extract_data sets up a temporary iov_iter and passes it to AF_RXRPC
      each time it is called to describe the remaining buffer to be filled.
       (1) Put an iterator in the afs_call struct.
       (2) Set the iterator for each marshalling stage to load data into the
           appropriate places.  A number of convenience functions are provided to
           this end (eg. afs_extract_to_buf()).
           This iterator is then passed to afs_extract_data().
       (3) Use the new ITER_DISCARD iterator to discard any excess data provided
           by FetchData.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      afs: Better tracing of protocol errors · 160cb957
      David Howells authored
      Include the site of detection of AFS protocol errors in trace lines to
      better be able to determine what went wrong.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    • David Howells's avatar
      iov_iter: Separate type from direction and use accessor functions · aa563d7b
      David Howells authored
      In the iov_iter struct, separate the iterator type from the iterator
      direction and use accessor functions to access them in most places.
      Convert a bunch of places to use switch-statements to access them rather
      then chains of bitwise-AND statements.  This makes it easier to add further
      iterator types.  Also, this can be more efficient as to implement a switch
      of small contiguous integers, the compiler can use ~50% fewer compare
      instructions than it has to use bitwise-and instructions.
      Further, cease passing the iterator type into the iterator setup function.
      The iterator function can set that itself.  Only the direction is required.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
  8. 15 Oct, 2018 1 commit
    • David Howells's avatar
      afs: Fix clearance of reply · f0a7d188
      David Howells authored
      The recent patch to fix the afs_server struct leak didn't actually fix the
      bug, but rather fixed some of the symptoms.  The problem is that an
      asynchronous call that holds a resource pointed to by call->reply[0] will
      find the pointer cleared in the call destructor, thereby preventing the
      resource from being cleaned up.
      In the case of the server record leak, the afs_fs_get_capabilities()
      function in devel code sets up a call with reply[0] pointing at the server
      record that should be altered when the result is obtained, but this was
      being cleared before the destructor was called, so the put in the
      destructor does nothing and the record is leaked.
      Commit f014ffb0 removed the additional ref obtained by
      afs_install_server(), but the removal of this ref is actually used by the
      garbage collector to mark a server record as being defunct after the record
      has expired through lack of use.
      The offending clearance of call->reply[0] upon completion in
      afs_process_async_call() has been there from the origin of the code, but
      none of the asynchronous calls actually use that pointer currently, so it
      should be safe to remove (note that synchronous calls don't involve this
      Fix this by the following means:
       (1) Revert commit f014ffb0.
       (2) Remove the clearance of reply[0] from afs_process_async_call().
      Without this, afs_manage_servers() will suffer an assertion failure if it
      sees a server record that didn't get used because the usage count is not 1.
      Fixes: f014ffb0 ("afs: Fix afs_server struct leak")
      Fixes: 08e0e7c8 ("[AF_RXRPC]: Make the in-kernel AFS filesystem use AF_RXRPC.")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
  9. 12 Oct, 2018 2 commits
    • David Howells's avatar
      afs: Fix afs_server struct leak · f014ffb0
      David Howells authored
      Fix a leak of afs_server structs.  The routine that installs them in the
      various lookup lists and trees gets a ref on leaving the function, whether
      it added the server or a server already exists.  It shouldn't increment
      the refcount if it added the server.
      The effect of this that "rmmod kafs" will hang waiting for the leaked
      server to become unused.
      Fixes: d2ddc776 ("afs: Overhaul volume and server record caching and fileserver rotation")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    • David Howells's avatar
      afs: Fix cell proc list · 6b3944e4
      David Howells authored
      Access to the list of cells by /proc/net/afs/cells has a couple of
       (1) It should be checking against SEQ_START_TOKEN for the keying the
           header line.
       (2) It's only holding the RCU read lock, so it can't just walk over the
           list without following the proper RCU methods.
      Fix these by using an hlist instead of an ordinary list and using the
      appropriate accessor functions to follow it with RCU.
      Since the code that adds a cell to the list must also necessarily change,
      sort the list on insertion whilst we're at it.
      Fixes: 989782dc ("afs: Overhaul cell database management")
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
  10. 04 Oct, 2018 2 commits