Commit d99a05ad authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds

[PATCH] knfsd: nfsd4: simplify lease changing

The only way the protocol gives to change the lease time on the fly is to
simulate a reboot.  We don't have that completely right in the current code;
among other things, we should probably put lockd in grace too while we do
this.

For now, let's just keep this simple, and wait till the next time nfsd starts
to register any changes in lease time.  If the administrator really wants to
change the lease time *now*, they can go ahead and bring nfsd down and then
back up again after changing the lease time.

Also remove the "if (reclaim_str_hashtbl_size == 0)" case, a shortcut which
skips the grace period if we know of no clients in need of recovery.  This
isn't going to work well with nlm.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 58da282b
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
/* Globals */ /* Globals */
static time_t lease_time = 90; /* default lease time */ static time_t lease_time = 90; /* default lease time */
static time_t old_lease_time = 90; /* past incarnation lease time */ static time_t user_lease_time = 90;
static u32 nfs4_reclaim_init = 0; static u32 nfs4_reclaim_init = 0;
time_t boot_time; time_t boot_time;
static time_t grace_end = 0; static time_t grace_end = 0;
...@@ -3205,10 +3205,8 @@ __nfs4_state_init(void) ...@@ -3205,10 +3205,8 @@ __nfs4_state_init(void)
INIT_LIST_HEAD(&del_recall_lru); INIT_LIST_HEAD(&del_recall_lru);
spin_lock_init(&recall_lock); spin_lock_init(&recall_lock);
boot_time = get_seconds(); boot_time = get_seconds();
grace_time = max(old_lease_time, lease_time); grace_time = max(user_lease_time, lease_time);
if (reclaim_str_hashtbl_size == 0) lease_time = user_lease_time;
grace_time = 0;
if (grace_time)
printk("NFSD: starting %ld-second grace period\n", grace_time); printk("NFSD: starting %ld-second grace period\n", grace_time);
grace_end = boot_time + grace_time; grace_end = boot_time + grace_time;
INIT_WORK(&laundromat_work,laundromat_main, NULL); INIT_WORK(&laundromat_work,laundromat_main, NULL);
...@@ -3307,53 +3305,16 @@ nfs4_state_shutdown(void) ...@@ -3307,53 +3305,16 @@ nfs4_state_shutdown(void)
/* /*
* Called when leasetime is changed. * Called when leasetime is changed.
* *
* if nfsd is not started, simply set the global lease. * The only way the protocol gives us to handle on-the-fly lease changes is to
* * simulate a reboot. Instead of doing that, we just wait till the next time
* if nfsd(s) are running, lease change requires nfsv4 state to be reset. * we start to register any changes in lease time. If the administrator
* e.g: boot_time is reset, existing nfs4_client structs are * really wants to change the lease time *now*, they can go ahead and bring
* used to fill reclaim_str_hashtbl, then all state (except for the * nfsd down and then back up again after changing the lease time.
* reclaim_str_hashtbl) is re-initialized.
*
* if the old lease time is greater than the new lease time, the grace
* period needs to be set to the old lease time to allow clients to reclaim
* their state. XXX - we may want to set the grace period == lease time
* after an initial grace period == old lease time
*
* if an error occurs in this process, the new lease is set, but the server
* will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
* which means OPEN/LOCK/READ/WRITE will fail during grace period.
*
* clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
* OPEN and LOCK reclaims.
*/ */
void void
nfs4_reset_lease(time_t leasetime) nfs4_reset_lease(time_t leasetime)
{ {
struct nfs4_client *clp; lock_kernel();
int i; user_lease_time = leasetime;
unlock_kernel();
printk("NFSD: New leasetime %ld\n",leasetime);
if (!nfs4_init)
return;
nfs4_lock_state();
old_lease_time = lease_time;
lease_time = leasetime;
nfs4_release_reclaim();
/* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
if (!nfs4_client_to_reclaim(clp->cl_name.data,
clp->cl_name.len)) {
nfs4_release_reclaim();
goto init_state;
}
}
}
init_state:
__nfs4_state_shutdown();
__nfs4_state_init();
nfs4_unlock_state();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment