^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/nfs/nfs4renewd.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2002 The Regents of the University of Michigan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Kendrick Smith <kmsmith@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 3. Neither the name of the University nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Implementation of the NFSv4 "renew daemon", which wakes up periodically to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * send a RENEW, to keep state alive on the server. The daemon is implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * as an rpc_task, not a real kernel thread, so it always runs in rpciod's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * context. There is one renewd per nfs_server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sunrpc/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/nfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/nfs4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "nfs4_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "delegation.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define NFSDBG_FACILITY NFSDBG_STATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) nfs4_renew_state(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const struct nfs4_state_maintenance_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct nfs_client *clp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) container_of(work, struct nfs_client, cl_renewd.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) long lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned long last, now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned renew_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ops = clp->cl_mvops->state_renewal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) dprintk("%s: start\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (test_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) lease = clp->cl_lease_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) last = clp->cl_last_renewal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Are we close to a lease timeout? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (time_after(now, last + lease/3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) renew_flags |= NFS4_RENEW_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (nfs_delegations_present(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) renew_flags |= NFS4_RENEW_DELEGATION_CB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (renew_flags != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) cred = ops->get_state_renewal_cred(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (cred == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!(renew_flags & NFS4_RENEW_DELEGATION_CB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) nfs_expire_all_delegations(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Queue an asynchronous RENEW. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = ops->sched_state_renewal(clp, cred, renew_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto out_exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dprintk("%s: failed to call renewd. Reason: lease not expired \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) nfs4_schedule_state_renewal(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) out_exp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) nfs_expire_unreferenced_delegations(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) dprintk("%s: done\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) nfs4_schedule_state_renewal(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) spin_lock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) timeout = (2 * clp->cl_lease_time) / 3 + (long)clp->cl_last_renewal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) - (long)jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (timeout < 5 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) timeout = 5 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dprintk("%s: requeueing work. Lease period = %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __func__, (timeout + HZ - 1) / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mod_delayed_work(system_wq, &clp->cl_renewd, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) set_bit(NFS_CS_RENEWD, &clp->cl_res_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) spin_unlock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) nfs4_kill_renewd(struct nfs_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cancel_delayed_work_sync(&clp->cl_renewd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * nfs4_set_lease_period - Sets the lease period on a nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @clp: pointer to nfs_client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * @lease: new value for lease period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) void nfs4_set_lease_period(struct nfs_client *clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned long lease)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spin_lock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) clp->cl_lease_time = lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spin_unlock(&clp->cl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Cap maximum reconnect timeout at 1/2 lease period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) rpc_set_connect_timeout(clp->cl_rpcclient, lease, lease >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * c-basic-offset: 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */