[9264] in Athena Bugs
afs/afs_pioctl.c
daemon@ATHENA.MIT.EDU (Richard Basch)
Sun May 3 06:47:18 1992
Date: Sun, 3 May 92 06:47:02 -0400
To: bugs@MIT.EDU, bug-afs@Athena.MIT.EDU
From: "Richard Basch" <basch@MIT.EDU>
This patch should fix the problems with "fs flushvol". Unfortunately,
the problem is far more complex with why all the flags are not being set
correctly in memory, but this code is equivalent, according to the
chains of logic in afs_cache.c. I also followed all paths by which
slots are claimed and I do make one short-cut of not testing IFFree, but
if this flag is set, the Fid part of the disk-cache entry will be zero,
so the remaining tests will fail. From what I can tell, there is at
least one path by which IFEverUsed will be incorrectly set, but to fix
that problem will take a lot more code and possibly breaking a few of
the abstractions...
Problems noted while examining kernel memory:
o IFEverUsed is not being set/reset correctly.
o The hash tables may point to invalid (freed) entries.
This patch seems to be the only one that I can think of that guarantees
that a disk-cache entry has been allocated in memory, and if one has
been allocated, then either it will match a volume, or its fid will have
been cleared (this seems to be the ONLY thing that seems to be working
properly within the cache-manager).
-R
*** /tmp/,RCSt1a21524 Sun May 3 06:38:50 1992
--- afs_pioctl.c Sun May 3 06:37:12 1992
***************
*** 1430,1436 ****
cell = avc->fid.Cell;
ObtainWriteLock(&afs_xdcache); /* needed if you're going to flush any stuff */
for(i=0;i<afs_cacheFiles;i++) {
! if (!(afs_indexFlags[i] & IFEverUsed)) continue; /* never had any data */
tdc = afs_GetDSlot(i, (struct dcache *) 0);
if (tdc->refCount <= 1) { /* too high, in use by running sys call */
if (tdc->f.fid.Fid.Volume == volume && tdc->f.fid.Cell == cell) {
--- 1430,1436 ----
cell = avc->fid.Cell;
ObtainWriteLock(&afs_xdcache); /* needed if you're going to flush any stuff */
for(i=0;i<afs_cacheFiles;i++) {
! if (!afs_indexTable[i]) continue;
tdc = afs_GetDSlot(i, (struct dcache *) 0);
if (tdc->refCount <= 1) { /* too high, in use by running sys call */
if (tdc->f.fid.Fid.Volume == volume && tdc->f.fid.Cell == cell) {