mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 10:31:33 -04:00
nfsd: fix clock domain mismatch in clients_still_reclaiming()
clients_still_reclaiming() computes a deadline from nn->boot_time
(CLOCK_REALTIME, ~1.7 billion) but compares it against
ktime_get_boottime_seconds() (CLOCK_BOOTTIME, seconds since boot).
The comparison is always false — it would take ~54 years of uptime
for BOOTTIME to exceed the REALTIME-derived deadline.
This means any client can hold the server in grace indefinitely by
sending CLAIM_PREVIOUS OPEN requests, blocking all non-reclaim
operations for all other clients.
Add boot_time_bt (CLOCK_BOOTTIME) alongside the existing boot_time
and use it for the deadline computation. boot_time (CLOCK_REALTIME)
is preserved for its cl_boot clientid-nonce role.
Fixes: 20b7d86f29 ("nfsd: use boottime for lease expiry calculation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-12-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
@@ -78,6 +78,7 @@ struct nfsd_net {
|
||||
struct lock_manager nfsd4_manager;
|
||||
unsigned long flags;
|
||||
time64_t boot_time;
|
||||
time64_t boot_time_bt; /* same instant in CLOCK_BOOTTIME */
|
||||
|
||||
struct dentry *nfsd_client_dir;
|
||||
|
||||
|
||||
@@ -6870,7 +6870,7 @@ bool nfsd4_force_end_grace(struct nfsd_net *nn)
|
||||
*/
|
||||
static bool clients_still_reclaiming(struct nfsd_net *nn)
|
||||
{
|
||||
time64_t double_grace_period_end = nn->boot_time +
|
||||
time64_t double_grace_period_end = nn->boot_time_bt +
|
||||
2 * nn->nfsd4_lease;
|
||||
|
||||
if (test_bit(NFSD_NET_GRACE_END_FORCED, &nn->flags))
|
||||
@@ -9245,6 +9245,7 @@ static int nfs4_state_create_net(struct net *net)
|
||||
nn->conf_name_tree = RB_ROOT;
|
||||
nn->unconf_name_tree = RB_ROOT;
|
||||
nn->boot_time = ktime_get_real_seconds();
|
||||
nn->boot_time_bt = ktime_get_boottime_seconds();
|
||||
clear_bit(NFSD_NET_GRACE_ENDED, &nn->flags);
|
||||
clear_bit(NFSD_NET_GRACE_END_FORCED, &nn->flags);
|
||||
nn->nfsd4_manager.block_opens = true;
|
||||
|
||||
Reference in New Issue
Block a user