windows-buf-scache-interlock-20080222
[openafs.git] / src / WINNT / afsd / cm_scache.h
index fa791f0..b4b4b14 100644 (file)
 #ifndef __CM_SCACHE_H_ENV__
 #define __CM_SCACHE_H_ENV__ 1
 
-#define MOUNTPOINTLEN   1024
+#define MOUNTPOINTLEN   1024    /* max path length for symlink; same as AFSPATHMAX */
 
 typedef struct cm_fid {
-       unsigned long cell;
-        unsigned long volume;
-        unsigned long vnode;
-        unsigned long unique;
+    afs_uint32 cell;
+    afs_uint32 volume;
+    afs_uint32 vnode;
+    afs_uint32 unique;
+    afs_uint32 hash;
 } cm_fid_t;
 
+
 /* Key used for byte range locking.  Each unique key identifies a
    unique client per cm_scache_t for the purpose of locking. */
 typedef afs_uint64 cm_key_t;
@@ -85,6 +87,7 @@ typedef struct cm_scache {
     osi_queue_t q;                     /* lru queue; cm_scacheLock */
     afs_uint32      magic;
     struct cm_scache *nextp;           /* next in hash; cm_scacheLock */
+    struct cm_scache *allNextp;         /* next in all scache list; cm_scacheLock */
     cm_fid_t fid;
     afs_uint32 flags;                  /* flags; locked by mx */
 
@@ -94,7 +97,7 @@ typedef struct cm_scache {
                                          * write-locked to prevent buffers from
                                         * being created during a truncate op, etc.
                                         */
-    afs_uint32 refCount;               /* reference count; cm_scacheLock */
+    afs_int32 refCount;                        /* reference count; cm_scacheLock */
     osi_queueData_t *bufReadsp;                /* queue of buffers being read */
     osi_queueData_t *bufWritesp;       /* queue of buffers being written */
 
@@ -115,7 +118,7 @@ typedef struct cm_scache {
     cm_prefetch_t prefetch;            /* prefetch info structure */
     afs_uint32 unixModeBits;           /* unix protection mode bits */
     afs_uint32 linkCount;              /* link count */
-    afs_uint32 dataVersion;            /* data version */
+    afs_uint64 dataVersion;            /* data version */
     afs_uint32 owner;                  /* file owner */
     afs_uint32 group;                  /* file owning group */
     cm_user_t *creator;                        /* user, if new file */
@@ -160,7 +163,7 @@ typedef struct cm_scache {
                                  */
     unsigned long lastRefreshCycle; /* protected with cm_scacheLock
                                      * for all scaches. */
-    afs_uint32 lockDataVersion; /* dataVersion of the scp at the time
+    afs_uint64  lockDataVersion; /* dataVersion of the scp at the time
                                    the server lock for the scp was
                                    asserted for this lock the last
                                    time. */
@@ -188,6 +191,13 @@ typedef struct cm_scache {
     /* bulk stat progress */
     osi_hyper_t bulkStatProgress;      /* track bulk stats of large dirs */
 
+#ifdef USE_BPLUS
+    /* directory B+ tree */             /* only allocated if is directory */
+    osi_rwlock_t dirlock;               /* controls access to dirBplus */
+    afs_uint64   dirDataVersion;        /* data version represented by dirBplus */
+    struct tree *dirBplus;              /* dirBplus */
+#endif
+
     /* open state */
     afs_uint16 openReads;              /* open for reading */
     afs_uint16 openWrites;             /* open for writing */
@@ -197,6 +207,12 @@ typedef struct cm_scache {
     /* syncop state */
     afs_uint32 waitCount;           /* number of threads waiting */
     afs_uint32 waitRequests;        /* num of thread wait requests */
+    osi_queue_t * waitQueueH;       /* Queue of waiting threads.
+                                       Holds queue of
+                                       cm_scache_waiter_t
+                                       objects. Protected by
+                                       cm_cacheLock. */
+    osi_queue_t * waitQueueT;       /* locked by cm_scacheLock */
 } cm_scache_t;
 
 /* mask field - tell what has been modified */
@@ -288,6 +304,8 @@ typedef struct cm_scache {
                                                 * used to see if we're merging
                                                 * in old info.
                                                  */
+#define CM_MERGEFLAG_STOREDATA         2       /* Merge due to storedata op */
+#define CM_MERGEFLAG_DIROP              4       /* Merge due to directory op */ 
 
 /* hash define.  Must not include the cell, since the callback revocation code
  * doesn't necessarily know the cell in the case of a multihomed server
@@ -297,11 +315,20 @@ typedef struct cm_scache {
                                   ((fidp)->volume +    \
                                    (fidp)->vnode +     \
                                    (fidp)->unique))    \
-                                       % cm_data.hashTableSize)
+                                       % cm_data.scacheHashTableSize)
 
 #include "cm_conn.h"
 #include "cm_buf.h"
 
+typedef struct cm_scache_waiter {
+    osi_queue_t q;
+    afs_int32   threadId;
+
+    cm_scache_t *scp;
+    afs_int32   flags;
+    cm_buf_t    *bufp;
+} cm_scache_waiter_t;
+
 extern void cm_InitSCache(int, long);
 
 #ifdef DEBUG_REFCOUNT
@@ -316,15 +343,20 @@ extern long cm_GetSCache(cm_fid_t *, cm_scache_t **, struct cm_user *,
 
 extern cm_scache_t *cm_GetNewSCache(void);
 
-extern int cm_FidCmp(cm_fid_t *, cm_fid_t *);
+extern __inline int cm_FidCmp(cm_fid_t *, cm_fid_t *);
+
+extern void cm_SetFid(cm_fid_t *, afs_uint32 cell, afs_uint32 volume, afs_uint32 vnode, afs_uint32 unique);
 
 extern long cm_SyncOp(cm_scache_t *, struct cm_buf *, struct cm_user *,
        struct cm_req *, afs_uint32, afs_uint32);
 
 extern void cm_SyncOpDone(cm_scache_t *, struct cm_buf *, afs_uint32);
 
-extern void cm_MergeStatus(cm_scache_t *, struct AFSFetchStatus *, struct AFSVolSync *,
-       struct cm_user *, afs_uint32 flags);
+extern void cm_MergeStatus(cm_scache_t * dscp, cm_scache_t * scp, 
+                          struct AFSFetchStatus * statusp, 
+                          struct AFSVolSync * volsyncp,
+                          struct cm_user *userp, 
+                          afs_uint32 flags);
 
 extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *);
 
@@ -370,6 +402,8 @@ extern long cm_ValidateSCache(void);
 
 extern long cm_ShutdownSCache(void);
 
+extern void cm_SuspendSCache(void);
+
 extern long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags);
 
 extern void cm_RemoveSCacheFromHashTable(cm_scache_t *scp);