4  *  Copyright (c) 2002 The Regents of the University of Michigan.
 
   7  *  Kendrick Smith <kmsmith@umich.edu>
 
   9  *  Redistribution and use in source and binary forms, with or without
 
  10  *  modification, are permitted provided that the following conditions
 
  13  *  1. Redistributions of source code must retain the above copyright
 
  14  *     notice, this list of conditions and the following disclaimer.
 
  15  *  2. Redistributions in binary form must reproduce the above copyright
 
  16  *     notice, this list of conditions and the following disclaimer in the
 
  17  *     documentation and/or other materials provided with the distribution.
 
  18  *  3. Neither the name of the University nor the names of its
 
  19  *     contributors may be used to endorse or promote products derived
 
  20  *     from this software without specific prior written permission.
 
  22  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
  23  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
  24  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
  25  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
  26  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
  27  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
  28  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 
  29  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
  30  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
  31  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
  32  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  34  * Implementation of the NFSv4 "renew daemon", which wakes up periodically to
 
  35  * send a RENEW, to keep state alive on the server.  The daemon is implemented
 
  36  * as an rpc_task, not a real kernel thread, so it always runs in rpciod's
 
  37  * context.  There is one renewd per nfs_server.
 
  39  * TODO: If the send queue gets backlogged (e.g., if the server goes down),
 
  40  * we will keep filling the queue with periodic RENEW requests.  We need a
 
  41  * mechanism for ensuring that if renewd successfully sends off a request,
 
  42  * then it only wakes up when the request is finished.  Maybe use the
 
  43  * child task framework of the RPC layer?
 
  47 #include <linux/pagemap.h>
 
  48 #include <linux/sunrpc/sched.h>
 
  49 #include <linux/sunrpc/clnt.h>
 
  51 #include <linux/nfs.h>
 
  52 #include <linux/nfs4.h>
 
  53 #include <linux/nfs_fs.h>
 
  55 #include "delegation.h"
 
  57 #define NFSDBG_FACILITY NFSDBG_PROC
 
  60 nfs4_renew_state(struct work_struct *work)
 
  62         struct nfs_client *clp =
 
  63                 container_of(work, struct nfs_client, cl_renewd.work);
 
  64         struct rpc_cred *cred;
 
  66         unsigned long last, now;
 
  68         down_read(&clp->cl_sem);
 
  69         dprintk("%s: start\n", __FUNCTION__);
 
  70         /* Are there any active superblocks? */
 
  71         if (list_empty(&clp->cl_superblocks))
 
  73         spin_lock(&clp->cl_lock);
 
  74         lease = clp->cl_lease_time;
 
  75         last = clp->cl_last_renewal;
 
  77         timeout = (2 * lease) / 3 + (long)last - (long)now;
 
  78         /* Are we close to a lease timeout? */
 
  79         if (time_after(now, last + lease/3)) {
 
  80                 cred = nfs4_get_renew_cred(clp);
 
  82                         set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
 
  83                         spin_unlock(&clp->cl_lock);
 
  84                         nfs_expire_all_delegations(clp);
 
  87                 spin_unlock(&clp->cl_lock);
 
  88                 /* Queue an asynchronous RENEW. */
 
  89                 nfs4_proc_async_renew(clp, cred);
 
  91                 timeout = (2 * lease) / 3;
 
  92                 spin_lock(&clp->cl_lock);
 
  94                 dprintk("%s: failed to call renewd. Reason: lease not expired \n",
 
  96         if (timeout < 5 * HZ)    /* safeguard */
 
  98         dprintk("%s: requeueing work. Lease period = %ld\n",
 
  99                         __FUNCTION__, (timeout + HZ - 1) / HZ);
 
 100         cancel_delayed_work(&clp->cl_renewd);
 
 101         schedule_delayed_work(&clp->cl_renewd, timeout);
 
 102         spin_unlock(&clp->cl_lock);
 
 104         up_read(&clp->cl_sem);
 
 105         dprintk("%s: done\n", __FUNCTION__);
 
 108 /* Must be called with clp->cl_sem locked for writes */
 
 110 nfs4_schedule_state_renewal(struct nfs_client *clp)
 
 114         spin_lock(&clp->cl_lock);
 
 115         timeout = (2 * clp->cl_lease_time) / 3 + (long)clp->cl_last_renewal
 
 117         if (timeout < 5 * HZ)
 
 119         dprintk("%s: requeueing work. Lease period = %ld\n",
 
 120                         __FUNCTION__, (timeout + HZ - 1) / HZ);
 
 121         cancel_delayed_work(&clp->cl_renewd);
 
 122         schedule_delayed_work(&clp->cl_renewd, timeout);
 
 123         set_bit(NFS_CS_RENEWD, &clp->cl_res_state);
 
 124         spin_unlock(&clp->cl_lock);
 
 128 nfs4_renewd_prepare_shutdown(struct nfs_server *server)
 
 130         cancel_delayed_work(&server->nfs_client->cl_renewd);
 
 134 nfs4_kill_renewd(struct nfs_client *clp)
 
 136         cancel_delayed_work_sync(&clp->cl_renewd);