[OpenAFS] cm fails to invalidate cache for deleted files in volume
root w/ fakestat
Rainer Toebbicke
rtb@pclella.cern.ch
Mon, 14 Apr 2008 11:53:44 +0200
This is a multi-part message in MIME format.
--------------050804040604030404080706
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
We ran into this over a year ago and fixed it, but I must have
forgotten to submit the fix.
It is actually the detection of a "cell" in the mount point string
which triggers the (loosely consistent) fakestat handling - it's
treated like a foreign cell and the mount point is never "completely
evaluated", i.e. logically replaced by the root directory of the
volume in question. As a result, callbacks are ignored, as they go
against the directory and not the mount point.
The attached patch takes care of that.
(Bcc'ed openafs-bugs)
Stephan Wiesand schrieb:
> If a client runs with the -fakestat[-all] option, and has a file cached
> that resides in the root directory of a volume affected by fakestat, it
> fails to invalidate its cache for this file when it's deleted:
>
> ClientA: touch x
> ClientB: ls -l x
> ... 0 Apr 10 13:10 x
>
> ClientA: echo a >> x
> ClientB: ls -l x; cat x
> ... 2 Apr 10 13:11 x
> a
>
> ClientA: rm x
> ClientB: ls -l x; cat x
> ... 2 Apr 10 13:11 x (!)
> a (!)
>
> ClientA: echo b > x
> ClientB: ls -l x; cat x
> ... 2 Apr 10 13:11 x (!)
> a (!)
>
> ClientB: fs flushv; ls -l x; cat x
> ... 2 Apr 10 13:12 x
> b
>
>
> I guess it's the same issue reported by Jack Neely on March 17th. We're
> not running with -fakestat-all, just -fakestat. The problem struck when
> mount points for local volumes were accidentally created with the -cell
> option. We can reproduce the problem with local and foreign volumes.
> Turning off fakestat eliminates it reliably.
>
> We observe this with various Linux clients. OpenAFS 1.4.6 or 1.4.7pre3,
> SL3/4/5, 32/64-bit.
>
> An SL3 client still running 1.2.13 does not exhibit this problem.
>
> Bcc to openafs-bugs.
>
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985 Fax: +41 22 767 7155
--------------050804040604030404080706
Content-Type: text/plain;
name="p_foreign_CB"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="p_foreign_CB"
--- openafs/src/afs/LINUX/osi_vnodeops.c 2006-05-09 16:30:58.000000000 +0200
+++ openafs/src/afs/LINUX/osi_vnodeops.c 2007-02-02 15:26:01.000000000 +0100
@@ -894,9 +894,16 @@
vcp = VTOAFS(dp->d_inode);
pvcp = VTOAFS(dp->d_parent->d_inode); /* dget_parent()? */
+
if (vcp == afs_globalVp)
goto good_dentry;
+ if (vcp->mvstat == 1) { /* mount point */
+ if (vcp->mvid && (vcp->states & CMValid)) {
+ /* a mount point, not yet replaced by its directory */
+ goto bad_dentry;
+ }
+ } else
if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
check_bad_parent(dp); /* check and correct mvid */
--- openafs/src/afs/VNOPS/afs_vnop_lookup.c 2006-02-18 05:09:36.000000000 +0100
+++ openafs/src/afs/VNOPS/afs_vnop_lookup.c 2007-02-02 15:04:22.000000000 +0100
@@ -1120,6 +1120,7 @@
register afs_int32 code;
register afs_int32 bulkcode = 0;
int pass = 0, hit = 0;
+ int force_eval = afs_fakestat_enable ? 0 : 1;
long dirCookie;
extern afs_int32 afs_mariner; /*Writing activity to log? */
afs_hyper_t versionNo;
@@ -1437,7 +1438,6 @@
} /* sub-block just to reduce stack usage */
if (tvc) {
- int force_eval = afs_fakestat_enable ? 0 : 1;
if (adp->states & CForeign)
tvc->states |= CForeign;
@@ -1459,6 +1459,8 @@
force_eval = 1;
ReleaseReadLock(&tvc->lock);
}
+ if (tvc->mvstat == 1 && (tvc->states & CMValid) && tvc->mvid != NULL)
+ force_eval = 1; /* This is now almost for free, get it correct */
#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
if (!(flags & AFS_LOOKUP_NOEVAL))
/* don't eval mount points */
@@ -1584,7 +1586,7 @@
* rather than the vc of the mount point itself. we can still find the
* mount point's vc in the vcache by its fid. */
#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
- if (!hit) {
+ if (!hit && force_eval) {
osi_dnlc_enter(adp, aname, tvc, &versionNo);
} else {
#ifdef AFS_LINUX20_ENV
--------------050804040604030404080706--