#include "afs/dir.h"
#include "afs/afs_stats.h"
-#include "afs/longc_procs.h"
#include "afs/afs.h"
#ifndef BUF_TIME_MAX
/* Initialize the venus buffer system. */
register int i;
register struct buffer *tb;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
struct buf *tub; /* unix buffer for allocation */
#endif
if (dinit_flag)
return;
dinit_flag = 1;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
/* round up to next multiple of NPB, since we allocate multiple pages per chunk */
abuffers = ((abuffers - 1) | (NPB - 1)) + 1;
#endif
LOCK_INIT(&afs_bufferLock, "afs_bufferLock");
Buffers =
(struct buffer *)afs_osi_Alloc(abuffers * sizeof(struct buffer));
-#if !AFS_USEBUFFERS
+#if !defined(AFS_USEBUFFERS)
BufferData = (char *)afs_osi_Alloc(abuffers * AFS_BUFFER_PAGESIZE);
#endif
timecounter = 1;
for (i = 0; i < PHSIZE; i++)
phTable[i] = 0;
for (i = 0; i < abuffers; i++) {
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
if ((i & (NPB - 1)) == 0) {
/* time to allocate a fresh buffer */
tub = geteblk(AFS_BUFFER_PAGESIZE * NPB);
tb->inode = 0;
tb->accesstime = 0;
tb->lockers = 0;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
if ((i & (NPB - 1)) == 0)
tb->bufp = tub;
else
#endif
tb->hashIndex = 0;
tb->dirty = 0;
- RWLOCK_INIT(&tb->lock, "buffer lock");
+ AFS_RWLOCK_INIT(&tb->lock, "buffer lock");
}
return;
}
MReleaseWriteLock(&tb->lock);
return NULL;
}
+#if defined(LINUX_USE_FH)
+ tfile = afs_CFileOpen(&adc->f.fh, adc->f.fh_type);
+#else
tfile = afs_CFileOpen(adc->f.inode);
+#endif
code =
afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data,
AFS_BUFFER_PAGESIZE);
if (lp->dirty) {
/* see DFlush for rationale for not getting and locking the dcache */
- tfile = afs_CFileOpen(lp->inode);
+#if defined(LINUX_USE_FH)
+ tfile = afs_CFileOpen(&lp->fh, lp->fh_type);
+#else
+ tfile = afs_CFileOpen(lp->inode);
+#endif
afs_CFileWrite(tfile, lp->page * AFS_BUFFER_PAGESIZE, lp->data,
AFS_BUFFER_PAGESIZE);
lp->dirty = 0;
/* Now fill in the header. */
lp->fid = adc->index;
+#if defined(LINUX_USE_FH)
+ memcpy(&lp->fh, &adc->f.fh, sizeof(struct fid));
+ lp->fh_type = adc->f.fh_type;
+#else
lp->inode = adc->f.inode;
+#endif
lp->page = apage;
lp->accesstime = timecounter++;
FixupBucket(lp); /* move to the right hash bucket */
/* Release a buffer, specifying whether or not the buffer has been
* modified by the locker. */
register int index;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
register struct buffer *tp;
#endif
AFS_STATCNT(DRelease);
if (!bp)
return;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
/* look for buffer by scanning Unix buffers for appropriate address */
tp = Buffers;
for (index = 0; index < nbuffers; index += NPB, tp += NPB) {
/* Return the byte within a file represented by a buffer pointer. */
register struct buffer *bp;
register int index;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
register struct buffer *tp;
#endif
AFS_STATCNT(DVOffset);
bp = ap;
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
/* look for buffer by scanning Unix buffers for appropriate address */
tp = Buffers;
for (index = 0; index < nbuffers; index += NPB, tp += NPB) {
return AFS_BUFFER_PAGESIZE * bp->page + (int)(((char *)ap) - bp->data);
}
-/* 1/1/91 - I've modified the hash function to take the page as well
+/*!
+ * Zap one dcache entry: destroy one FID's buffers.
+ *
+ * 1/1/91 - I've modified the hash function to take the page as well
* as the *fid, so that lookup will be a bit faster. That presents some
* difficulties for Zap, which now has to have some knowledge of the nature
* of the hash function. Oh well. This should use the list traversal
* method of DRead...
+ *
+ * \param adc The dcache entry to be zapped.
*/
void
DZap(struct dcache *adc)
MReleaseReadLock(&afs_bufferLock);
}
+static void
+DFlushBuffer(struct buffer *ab) {
+ struct osi_file *tfile;
+
+#if defined(LINUX_USE_FH)
+ tfile = afs_CFileOpen(&ab->fh, ab->fh_type);
+#else
+ tfile = afs_CFileOpen(ab->inode);
+#endif
+ afs_CFileWrite(tfile, ab->page * AFS_BUFFER_PAGESIZE,
+ ab->data, AFS_BUFFER_PAGESIZE);
+ ab->dirty = 0; /* Clear the dirty flag */
+ afs_CFileClose(tfile);
+}
+
+void
+DFlushDCache(struct dcache *adc)
+{
+ int i;
+ struct buffer *tb;
+
+ ObtainReadLock(&afs_bufferLock);
+
+ for (i = 0; i <= PHPAGEMASK; i++)
+ for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext)
+ if (tb->fid == adc->index) {
+ ObtainWriteLock(&tb->lock, 702);
+ tb->lockers++;
+ ReleaseReadLock(&afs_bufferLock);
+ if (tb->dirty) {
+ DFlushBuffer(tb);
+ }
+ tb->lockers--;
+ ReleaseWriteLock(&tb->lock);
+ ObtainReadLock(&afs_bufferLock);
+ }
+
+ ReleaseReadLock(&afs_bufferLock);
+}
+
void
DFlush(void)
{
/* Flush all the modified buffers. */
register int i;
register struct buffer *tb;
- struct osi_file *tfile;
AFS_STATCNT(DFlush);
tb = Buffers;
* we cannot lock afs_xdcache). In addition, we cannot obtain
* a dcache lock while holding the tb->lock of the same file
* since that can deadlock with DRead/DNew */
- tfile = afs_CFileOpen(tb->inode);
- afs_CFileWrite(tfile, tb->page * AFS_BUFFER_PAGESIZE,
- tb->data, AFS_BUFFER_PAGESIZE);
- tb->dirty = 0; /* Clear the dirty flag */
- afs_CFileClose(tfile);
+ DFlushBuffer(tb);
}
tb->lockers--;
MReleaseWriteLock(&tb->lock);
void
shutdown_bufferpackage(void)
{
-#if AFS_USEBUFFERS
+#if defined(AFS_USEBUFFERS)
register struct buffer *tp;
#endif
int i;
- extern int afs_cold_shutdown;
AFS_STATCNT(shutdown_bufferpackage);
/* Free all allocated Buffers and associated buffer pages */
DFlush();
if (afs_cold_shutdown) {
dinit_flag = 0;
-#if !AFS_USEBUFFERS
+#if !defined(AFS_USEBUFFERS)
afs_osi_Free(BufferData, nbuffers * AFS_BUFFER_PAGESIZE);
#else
tp = Buffers;