diff options
author | jhb <jhb@FreeBSD.org> | 2012-01-20 20:02:01 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-01-20 20:02:01 +0000 |
commit | f75e35e4d7093d1f4cb56a1be3733e67271df618 (patch) | |
tree | d22b04598bdacdd3ec50c0e8e0490fb14fdbf8fe /sys/sys | |
parent | d337cd8b79286df5494262294a0d9559f789b64e (diff) | |
download | FreeBSD-src-f75e35e4d7093d1f4cb56a1be3733e67271df618.zip FreeBSD-src-f75e35e4d7093d1f4cb56a1be3733e67271df618.tar.gz |
Close a race in NFS lookup processing that could result in stale name cache
entries on one client when a directory was renamed on another client. The
root cause for the stale entry being trusted is that each per-vnode nfsnode
structure has a single 'n_ctime' timestamp used to validate positive name
cache entries. However, if there are multiple entries for a single vnode,
they all share a single timestamp. To fix this, extend the name cache
to allow filesystems to optionally store a timestamp value in each name
cache entry. The NFS clients now fetch the timestamp associated with
each name cache entry and use that to validate cache hits instead of the
timestamps previously stored in the nfsnode. Another part of the fix is
that the NFS clients now use timestamps from the post-op attributes of
RPCs when adding name cache entries rather than pulling the timestamps out
of the file's attribute cache. The latter is subject to races with other
lookups updating the attribute cache concurrently. Some more details:
- Add a variant of nfsm_postop_attr() to the old NFS client that can return
a vattr structure with a copy of the post-op attributes.
- Handle lookups of "." as a special case in the NFS clients since the name
cache does not store name cache entries for ".", so we cannot get a
useful timestamp. It didn't really make much sense to recheck the
attributes on the the directory to validate the namecache hit for "."
anyway.
- ABI compat shims for the name cache routines are present in this commit
so that it is safe to MFC.
MFC after: 2 weeks
Diffstat (limited to 'sys/sys')
-rw-r--r-- | sys/sys/vnode.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index c8e2105..0ef4979 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -578,10 +578,14 @@ struct vattr; struct vnode; /* cache_* may belong in namei.h. */ -void cache_enter(struct vnode *dvp, struct vnode *vp, - struct componentname *cnp); -int cache_lookup(struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp); +#define cache_enter(dvp, vp, cnp) \ + cache_enter_time(dvp, vp, cnp, NULL) +void cache_enter_time(struct vnode *dvp, struct vnode *vp, + struct componentname *cnp, struct timespec *tsp); +#define cache_lookup(dvp, vpp, cnp) \ + cache_lookup_times(dvp, vpp, cnp, NULL, NULL) +int cache_lookup_times(struct vnode *dvp, struct vnode **vpp, + struct componentname *cnp, struct timespec *tsp, int *ticksp); void cache_purge(struct vnode *vp); void cache_purge_negative(struct vnode *vp); void cache_purgevfs(struct mount *mp); |