0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #include <linux/mm.h>
0042 #include <linux/pagemap.h>
0043 #include <linux/sunrpc/sched.h>
0044 #include <linux/sunrpc/clnt.h>
0045
0046 #include <linux/nfs.h>
0047 #include <linux/nfs4.h>
0048 #include <linux/nfs_fs.h>
0049 #include "nfs4_fs.h"
0050 #include "delegation.h"
0051
0052 #define NFSDBG_FACILITY NFSDBG_STATE
0053
0054 void
0055 nfs4_renew_state(struct work_struct *work)
0056 {
0057 const struct nfs4_state_maintenance_ops *ops;
0058 struct nfs_client *clp =
0059 container_of(work, struct nfs_client, cl_renewd.work);
0060 const struct cred *cred;
0061 long lease;
0062 unsigned long last, now;
0063 unsigned renew_flags = 0;
0064
0065 ops = clp->cl_mvops->state_renewal_ops;
0066 dprintk("%s: start\n", __func__);
0067
0068 if (test_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state))
0069 goto out;
0070
0071 lease = clp->cl_lease_time;
0072 last = clp->cl_last_renewal;
0073 now = jiffies;
0074
0075 if (time_after(now, last + lease/3))
0076 renew_flags |= NFS4_RENEW_TIMEOUT;
0077 if (nfs_delegations_present(clp))
0078 renew_flags |= NFS4_RENEW_DELEGATION_CB;
0079
0080 if (renew_flags != 0) {
0081 cred = ops->get_state_renewal_cred(clp);
0082 if (cred == NULL) {
0083 if (!(renew_flags & NFS4_RENEW_DELEGATION_CB)) {
0084 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
0085 goto out;
0086 }
0087 nfs_expire_all_delegations(clp);
0088 } else {
0089 int ret;
0090
0091
0092 ret = ops->sched_state_renewal(clp, cred, renew_flags);
0093 put_cred(cred);
0094 switch (ret) {
0095 default:
0096 goto out_exp;
0097 case -EAGAIN:
0098 case -ENOMEM:
0099 break;
0100 }
0101 }
0102 } else {
0103 dprintk("%s: failed to call renewd. Reason: lease not expired \n",
0104 __func__);
0105 }
0106 nfs4_schedule_state_renewal(clp);
0107 out_exp:
0108 nfs_expire_unreferenced_delegations(clp);
0109 out:
0110 dprintk("%s: done\n", __func__);
0111 }
0112
0113 void
0114 nfs4_schedule_state_renewal(struct nfs_client *clp)
0115 {
0116 long timeout;
0117
0118 spin_lock(&clp->cl_lock);
0119 timeout = (2 * clp->cl_lease_time) / 3 + (long)clp->cl_last_renewal
0120 - (long)jiffies;
0121 if (timeout < 5 * HZ)
0122 timeout = 5 * HZ;
0123 dprintk("%s: requeueing work. Lease period = %ld\n",
0124 __func__, (timeout + HZ - 1) / HZ);
0125 mod_delayed_work(system_wq, &clp->cl_renewd, timeout);
0126 set_bit(NFS_CS_RENEWD, &clp->cl_res_state);
0127 spin_unlock(&clp->cl_lock);
0128 }
0129
0130 void
0131 nfs4_kill_renewd(struct nfs_client *clp)
0132 {
0133 cancel_delayed_work_sync(&clp->cl_renewd);
0134 }
0135
0136
0137
0138
0139
0140
0141
0142 void nfs4_set_lease_period(struct nfs_client *clp,
0143 unsigned long lease)
0144 {
0145 spin_lock(&clp->cl_lock);
0146 clp->cl_lease_time = lease;
0147 spin_unlock(&clp->cl_lock);
0148
0149
0150 rpc_set_connect_timeout(clp->cl_rpcclient, lease, lease >> 1);
0151 }