From: J. Bruce Fields Date: Wed, 12 Sep 2007 22:56:12 +0000 (-0400) Subject: knfsd: let nfsd manage timing out its own leases X-Git-Tag: v2.6.24-rc1~1293^2~3 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0272e1fd9f4fa8a43357c168e081744f99e67195;p=linux-2.6 knfsd: let nfsd manage timing out its own leases Currently there's a race that can cause an oops in generic_setlease. (In detail: nfsd, when it removes a lease, does so by calling vfs_setlease() with F_UNLCK and a pointer to the fl_flock field, which in turn points to nfsd's existing lease; but the first thing the setlease code does is call time_out_leases(). If the lease happens to already be beyond the lease break time, that will free the lease and (in nfsd's release_private callback) set fl_flock to NULL, leading to a NULL deference soon after in vfs_setlease().) There are probably other things to fix here too, but it seems inherently racy to allow either locks.c or nfsd to time out this lease. Instead just set the fl_break_time to 0 (preventing locks.c from ever timing out this lock) and leave it up to nfsd's laundromat thread to deal with it. Signed-off-by: J. Bruce Fields --- diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 6256492b23..48fbdac33c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1354,8 +1354,12 @@ void nfsd_break_deleg_cb(struct file_lock *fl) /* only place dl_time is set. protected by lock_kernel*/ dp->dl_time = get_seconds(); - /* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */ - fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ; + /* + * We don't want the locks code to timeout the lease for us; + * we'll remove it ourself if the delegation isn't returned + * in time. + */ + fl->fl_break_time = 0; t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall"); if (IS_ERR(t)) {