/* represents a single buffer */
typedef struct cm_buf {
- osi_queue_t q; /* queue of all zero-refcount buffers */
- afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */
+ osi_queue_t q; /* queue: buf_freeList and buf_redirList */
+ afs_uint32 qFlags; /* queue/hash state flags - buf_globalLock */
afs_uint32 magic;
struct cm_buf *allp; /* next in all list */
struct cm_buf *hashp; /* hash bucket pointer */
afs_uint32 waitRequests; /* num of thread wait requests */
afs_uint32 dirty_offset; /* offset from beginning of buffer containing dirty bytes */
- afs_uint32 dirty_length; /* number of dirty bytes within the buffer */
+ afs_uint32 dirty_length; /* number of dirty bytes within the buffer */
#ifdef DISKCACHE95
cm_diskcache_t *dcp; /* diskcache structure */
#else
void * dummy;
#endif
+
+ /* redirector state - protected by buf_globalLock */
+ osi_queue_t redirq; /* queue: cm_scache_t redirList */
+ time_t redirLastAccess;/* last time redir accessed the buffer */
+ time_t redirReleaseRequested;
+
+ unsigned char md5cksum[16]; /* md5 checksum of the block pointed to by datap */
} cm_buf_t;
+#define redirq_to_cm_buf_t(q) ((q) ? (cm_buf_t *)((char *) (q) - offsetof(cm_buf_t, redirq)) : NULL)
+
/* values for cmFlags */
#define CM_BUF_CMFETCHING 1 /* fetching this buffer */
#define CM_BUF_CMSTORING 2 /* storing this buffer */
extern void buf_Shutdown(void);
-extern long buf_CountFreeList(void);
-
#ifdef DEBUG_REFCOUNT
extern void buf_ReleaseDbg(cm_buf_t *, char *, long);
extern long buf_CleanDirtyBuffers(cm_scache_t *scp);
+extern long buf_RDRBuffersExist(cm_fid_t *fidp);
+
+extern long buf_ClearRDRFlag(cm_scache_t *scp, char * reason);
+
extern long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion);
extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock);
+extern void buf_ComputeCheckSum(cm_buf_t *bp);
+
+extern int buf_ValidateCheckSum(cm_buf_t *bp);
+
+extern const char *buf_HexCheckSum(cm_buf_t * bp);
+
+extern afs_uint32
+buf_RDRShakeSomeExtentsFree(cm_req_t *reqp, afs_uint32 oneFid, afs_uint32 minage);
+
+extern afs_uint32
+buf_RDRShakeAnExtentFree(cm_buf_t *bufp, cm_req_t *reqp);
+
+extern afs_uint32
+buf_RDRShakeFileExtentsFree(cm_scache_t *scp, cm_req_t *reqp);
+
+extern void
+buf_InsertToRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
+
+extern void
+buf_RemoveFromRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
+
+extern void
+buf_MoveToHeadOfRedirQueue(cm_scache_t *scp, cm_buf_t *bufp);
+
+#ifdef _M_IX86
+#define buf_IncrementRedirCount() InterlockedIncrement(&cm_data.buf_redirCount)
+#define buf_DecrementRedirCount() InterlockedDecrement(&cm_data.buf_redirCount)
+#define buf_IncrementFreeCount() InterlockedIncrement(&cm_data.buf_freeCount)
+#define buf_DecrementFreeCount() InterlockedDecrement(&cm_data.buf_freeCount)
+#else
+#define buf_IncrementRedirCount() InterlockedIncrement64(&cm_data.buf_redirCount)
+#define buf_DecrementRedirCount() InterlockedDecrement64(&cm_data.buf_redirCount)
+#define buf_IncrementFreeCount() InterlockedIncrement64(&cm_data.buf_freeCount)
+#define buf_DecrementFreeCount() InterlockedDecrement64(&cm_data.buf_freeCount)
+#endif
+
/* error codes */
#define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */
+
#endif /* OPENAFS_WINNT_AFSD_BUF_H */