public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH]lockd: fix handling of grace period after long periods of inactivity
@ 2008-08-14 11:08 NAKANO Hiroaki
  2008-08-14 19:06 ` J. Bruce Fields
  0 siblings, 1 reply; 7+ messages in thread
From: NAKANO Hiroaki @ 2008-08-14 11:08 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: bfields, neilb, linux-nfs, linux-kernel

lockd uses time_before() to determine whether the grace period has
expired. This would seem to be enough to avoid timer wrap-around issues,
but, unfortunately, that is not the case. The time_* family of
comparison functions can be safely used to compare jiffies relatively
close in time, but they stop working after approximately LONG_MAX/2
ticks. nfsd can suffer this problem because the time_before() comparison
in lockd() is not performed until the first request comes in, which
means that if there is no lockd traffic for more than LONG_MAX/2 ticks
we are screwed.

The implication of this is that once time_before() starts misbehaving
any attempt from a NFS client to execute fcntl() will be received with a
NLM_LCK_DENIED_GRACE_PERIOD message for 25 days (assuming HZ=1000). In
other words, the 50 seconds grace period could turn into a grace period
of 50 days or more.

This patch corrects this behavior by implementing grace period with a
(retriggerable) timer.

Note: This bug was analyzed independently by Oda-san <oda@valinux.co.jp>
and myself.

Signed-off-by: Nakano Hiroaki <nakano.hiroaki@oss.ntt.co.jp>
---

diff -Nrup linux-2.6.27-rc3/fs/lockd/svc.c b/fs/lockd/svc.c
--- linux-2.6.27-rc3/fs/lockd/svc.c	2008-08-14 16:54:24.000000000 +0900
+++ b/fs/lockd/svc.c	2008-08-14 17:04:15.000000000 +0900
@@ -53,6 +53,7 @@ static struct task_struct	*nlmsvc_task;
 static struct svc_rqst		*nlmsvc_rqst;
 int				nlmsvc_grace_period;
 unsigned long			nlmsvc_timeout;
+static struct timer_list        nlm_period_timer;

 /*
  * These can be set at insmod time (useful for NFS as root filesystem),
@@ -141,6 +142,12 @@ lockd(void *vrqstp)

 	grace_period_expire = set_grace_period();

+	init_timer(&nlm_period_timer);
+	nlm_period_timer.function = clear_grace_period;
+	nlm_period_timer.expires = grace_period_expire;
+
+	add_timer(&nlm_period_timer);
+
 	/*
 	 * The main request loop. We don't terminate until the last
 	 * NFS mount or NFS daemon has gone away.
@@ -154,6 +161,7 @@ lockd(void *vrqstp)
 			if (nlmsvc_ops) {
 				nlmsvc_invalidate_all();
 				grace_period_expire = set_grace_period();
+				mod_timer(&nlm_period_timer, grace_period_expire);
 			}
 			continue;
 		}
@@ -164,10 +172,8 @@ lockd(void *vrqstp)
 		 * (Theoretically, there shouldn't even be blocked locks
 		 * during grace period).
 		 */
-		if (!nlmsvc_grace_period) {
+		if (!nlmsvc_grace_period)
 			timeout = nlmsvc_retry_blocked();
-		} else if (time_before(grace_period_expire, jiffies))
-			clear_grace_period();

 		/*
 		 * Find a socket with data available and call its
@@ -195,6 +201,7 @@ lockd(void *vrqstp)
 		svc_process(rqstp);
 	}
 	flush_signals(current);
+	del_timer(&nlm_period_timer);
 	if (nlmsvc_ops)
 		nlmsvc_invalidate_all();
 	nlm_shutdown_hosts();

-- 
(NAKANO, Hiroaki) <nakano.hiroaki@oss.ntt.co.jp>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-08-20  1:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-14 11:08 [PATCH]lockd: fix handling of grace period after long periods of inactivity NAKANO Hiroaki
2008-08-14 19:06 ` J. Bruce Fields
2008-08-15  1:32   ` Fernando Luis Vázquez Cao
2008-08-19 22:12     ` J. Bruce Fields
2008-08-19 22:12       ` [PATCH 1/2] locks: allow lockd to process blocked locks during grace period J. Bruce Fields
2008-08-19 22:12         ` [PATCH 2/2] lockd: don't depend on lockd main loop to end grace J. Bruce Fields
2008-08-20  1:31       ` [PATCH]lockd: fix handling of grace period after long periods of inactivity Fernando Luis Vázquez Cao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox