linux/fs/nfs
Fabio Olive Leite c7e1596111 Re: [NFS] [PATCH] Attribute timeout handling and wrapping u32 jiffies
I would like to discuss the idea that the current checks for attribute
timeout using time_after are inadequate for 32bit architectures, since
time_after works correctly only when the two timestamps being compared
are within 2^31 jiffies of each other. The signed overflow caused by
comparing values more than 2^31 jiffies apart will flip the result,
causing incorrect assumptions of validity.

2^31 jiffies is a fairly large period of time (~25 days) when compared
to the lifetime of most kernel data structures, but for long lived NFS
mounts that can sit idle for months (think that for some reason autofs
cannot be used), it is easy to compare inode attribute timestamps with
very disparate or even bogus values (as in when jiffies have wrapped
many times, where the comparison doesn't even make sense).

Currently the code tests for attribute timeout by simply adding the
desired amount of jiffies to the stored timestamp and comparing that
with the current timestamp of obtained attribute data with time_after.
This is incorrect, as it returns true for the desired timeout period
and another full 2^31 range of jiffies.

In testing with artificial jumps (several small jumps, not one big
crank) of the jiffies I was able to reproduce a problem found in a
server with very long lived NFS mounts, where attributes would not be
refreshed even after touching files and directories in the server:

Initial uptime:
03:42:01 up 6 min, 0 users, load average: 0.01, 0.12, 0.07

NFS volume is mounted and time is advanced:
03:38:09 up 25 days, 2 min, 0 users, load average: 1.22, 1.05, 1.08

# ls -l /local/A/foo/bar /nfs/A/foo/bar
-rw-r--r--  1 root root 0 Dec 17 03:38 /local/A/foo/bar
-rw-r--r--  1 root root 0 Nov 22 00:36 /nfs/A/foo/bar

# touch /local/A/foo/bar

# ls -l /local/A/foo/bar /nfs/A/foo/bar
-rw-r--r--  1 root root 0 Dec 17 03:47 /local/A/foo/bar
-rw-r--r--  1 root root 0 Nov 22 00:36 /nfs/A/foo/bar

We can see the local mtime is updated, but the NFS mount still shows
the old value. The patch below makes it work:

Initial setup...
07:11:02 up 25 days, 1 min,  0 users,  load average: 0.15, 0.03, 0.04

# ls -l /local/A/foo/bar /nfs/A/foo/bar
-rw-r--r--  1 root root 0 Jan 11 07:11 /local/A/foo/bar
-rw-r--r--  1 root root 0 Jan 11 07:11 /nfs/A/foo/bar

# touch /local/A/foo/bar

# ls -l /local/A/foo/bar /nfs/A/foo/bar
-rw-r--r--  1 root root 0 Jan 11 07:14 /local/A/foo/bar
-rw-r--r--  1 root root 0 Jan 11 07:14 /nfs/A/foo/bar

Signed-off-by: Fabio Olive Leite <fleite@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2007-10-09 17:15:33 -04:00
..
callback_proc.c [PATCH] fs/nfs/callback* passes error values big-endian 2006-10-20 10:26:40 -07:00
callback_xdr.c NFSv4: debug print ntohl(status) in nfs client callback xdr code 2007-07-19 15:21:40 -04:00
callback.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
callback.h NFS: Fix more sparse warnings 2007-05-14 19:33:46 -04:00
client.c NFS: Fix an Oops in encode_lookup() 2007-09-28 15:36:42 -07:00
delegation.c NFSv4: Don't call put_rpccred() from an rcu callback 2007-08-07 15:15:57 -04:00
delegation.h NFSv4: Use RCU to protect delegations 2007-07-10 23:40:41 -04:00
dir.c Re: [NFS] [PATCH] Attribute timeout handling and wrapping u32 jiffies 2007-10-09 17:15:33 -04:00
direct.c mm: Remove slab destructors from kmem_cache_create(). 2007-07-20 10:11:58 +09:00
file.c NFS: Fall back to synchronous writes when a background write errors... 2007-10-09 17:15:23 -04:00
getroot.c NFS: Fix an Oops in encode_lookup() 2007-09-28 15:36:42 -07:00
idmap.c NFS: use __set_current_state() 2007-05-09 17:58:01 -04:00
inode.c Re: [NFS] [PATCH] Attribute timeout handling and wrapping u32 jiffies 2007-10-09 17:15:33 -04:00
internal.h NFS: Clean-up: use correct type when converting NFS blocks to local blocks 2007-07-10 23:40:44 -04:00
iostat.h NFSv4: Fix an oops in nfs4_fill_super 2006-03-20 13:44:48 -05:00
Makefile NFS: Remake nfsroot_mount as a permanent part of NFS client 2007-07-10 23:40:46 -04:00
mount_clnt.c NFS: Improve debugging output in NFS in-kernel mount client 2007-07-10 23:40:47 -04:00
namespace.c NFS: Fix use of cancel_delayed_work_sync in nfs_release_automount_timer 2007-09-01 10:14:36 -04:00
nfs2xdr.c NFS: Introduce struct nfs_removeargs+nfs_removeres 2007-07-19 15:21:39 -04:00
nfs3acl.c NFSv3: Client-side nfsacl caching fix 2006-06-09 09:34:11 -04:00
nfs3proc.c SUNRPC: Clean up the sillyrename code 2007-07-19 15:21:39 -04:00
nfs3xdr.c NFS: Introduce struct nfs_removeargs+nfs_removeres 2007-07-19 15:21:39 -04:00
nfs4_fs.h NFSv4: 'constify' lookup arguments. 2007-07-19 15:09:03 -04:00
nfs4namespace.c NFSv4: /proc/mounts displays the wrong server name for referrals 2007-02-03 15:35:10 -08:00
nfs4proc.c 64 bit ino support for NFS client 2007-10-09 17:15:29 -04:00
nfs4renewd.c NFS: Replace flush_scheduled_work with cancel_work_sync() and friends 2007-08-07 16:12:50 -04:00
nfs4state.c NFSv4: Fix a locking regression in nfs4_set_mode_locked() 2007-08-07 15:13:18 -04:00
nfs4xdr.c NFS: Introduce struct nfs_removeargs+nfs_removeres 2007-07-19 15:21:39 -04:00
nfsroot.c NFS: Remake nfsroot_mount as a permanent part of NFS client 2007-07-10 23:40:46 -04:00
pagelist.c mm: Remove slab destructors from kmem_cache_create(). 2007-07-20 10:11:58 +09:00
proc.c SUNRPC: Clean up the sillyrename code 2007-07-19 15:21:39 -04:00
read.c mm: Remove slab destructors from kmem_cache_create(). 2007-07-20 10:11:58 +09:00
super.c nfs: fix oops re sysctls and V4 support 2007-09-19 11:24:18 -07:00
symlink.c header cleaning: don't include smp_lock.h when not used 2007-05-08 11:15:07 -07:00
sysctl.c [PATCH] nfs: fix congestion control 2007-03-16 19:25:05 -07:00
unlink.c SUNRPC: Clean up the sillyrename code 2007-07-19 15:21:39 -04:00
write.c NFS: Fall back to synchronous writes when a background write errors... 2007-10-09 17:15:23 -04:00